(Comp.sys.handhelds) Item: 2479 by _kevin at hpcvbbs.UUCP Author: [Kevin Jessup] Subj: Julian/Gregorian Conversions Date: Tue Mar 19 1991 =================================================================== DOCUMENTATION FILE FOR JTD (JULIAN TIME AND DATE) FUNCTIONS FOR THE HP48SX Kevin P. Jessup March 19, 1991 If you downloaded the JTD binary file successfully to your 48SX, you now should have a directory named JTD which contains the Julian time and date conversion functions. If you place 'JTD' on the stack and execute the BYTES command, you should get the following results... Checksum: # 243Dh Byte count: 1987 =================================================================== Introduction ------------ These routines are patterned after the Julian/Gregorian time and date conversion functions that I wrote for the HP28S. The end result of those programs is that they gave the HP28S time, date and alarm functions similar to what you already have built into your HP48SX. These routines are nothing more than the Julian to Gregorian and Gregorian to Julian conversion functions from that software package modified to run on the 48SX. So what do they do? ------------------- Do not confuse the term "Julian" used in this documentation with the Julian calendar developed by Julius Caesar. "Julian date" as used here refers to an absolute number of days that have elapsed since a fundamental epoch. This was developed by astronomers to facilitate astronomical observations and to correct errors in Julius Caesars calendar that did not accurately represent the time it took for the Earth to revolve around the sun. The fundamental epoch described above is 12 noon January 1st, 4713 BC. The number of days that have elapsed since that time is what these programs refer to as the "Julian date" or "Juilian day number". The Julian day number should, by strict definition, also contain the time of day as well. Therefore, these programs produce a fractional portion of the day as well where the digits after the decimal point in the Julian day represent the portion of the day that has elapsed since noon (Julian days increment by one whole digit at noon). Once the Julian date is known, it is a simple matter to determine the day of the week for that date using a simple modulus function as well as other date conversion functions such as the number of days between two dates. Generally, all computers will use some variation of these programs if they at all intend to maintain the date and time accurately over an extended period. Some computer operating systems use these conversions exactly as they are presented here. One example is the OS9 operating system of Microware Corporation for use on the Motorola 68XXX series microprocessors. The 48SX no doubt has some similar functions to convert between Julian and Gregorian format but until those SYSEVAL addresses become known, these routines will have to do. For and in-depth description of these and other time and date conversion algorithms see the book "Practical Astronomy With Your Calculator" by Peter Duffet-Smith. It is published by Cambridge University Press and is available from EduCalc in Laguna Niguel, California. =================================================================== PROGRAM DESCRIPTIONS =================================================================== Name: DOW Type: List Function: Day of week text string list. Listing: { "Sunday" "Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday" } Notes: This list is used to get a textual representation of the day of week based on a real number. ======================================================================= Name: EXPDT Type: Program Function: Convert compressed Day Month Year to expanded Day Month Year. Listing: << DUP IP SWAP FP 100 * DUP IP SWAP FP 10000 * >> If date mode is DD.MM.YYYY (flag -42 SET) ----------------------------------------- Input: Level 1: DD.MMYYYY real number Output: Level 3: DD real number Level 2: MM real number Level 1: YYYY real number Example: Level 1: 27.111956 ->DMY Level 3: 27 Level 2: 11 Level 1: 1956 If date mode is MM/DD/YYYY (flag -42 CLEAR) ------------------------------------------- Input: Level 1: MM.DDYYYY real number Output: Level 3: MM real number Level 2: DD real number Level 1: YYYY real number Example: Level 1: 11.271956 ->DMY Level 3: 11 Level 2: 27 Level 1: 1956 ====================================================================== Name: CSPDT Type: Program Function: Convert expanded Day Month Year to compressed Day Month Year. Listing: << 10000 / SWAP IP + 100 / SWAP IP + >> If date mode is DD.MM.YYYY (flag -42 SET) ----------------------------------------- Input: Level 3: DD real number Level 2: MM real number Level 1: YYYY real number Output: Level 1: DD.MMYYYY real number Example: Level 3: 27 Level 2: 11 Level 1: 1956 DMY-> Level 1: 27.111956 If date mode is MM/DD/YYYY (flag -42 CLEAR) ------------------------------------------- Input: Level 3: MM real number Level 2: DD real number Level 1: YYYY real number Output: Level 1: MM.DDYYYY real number Example: Level 3: 11 Level 2: 27 Level 1: 1956 DMY-> Level 1: 11.271956 ======================================================================== Name: JFIX Type: Program Function: Utility program used by routines below to adjust for the current date display mode. Listing: << IF -42 FC? THEN 3 ROLLD SWAP 3 ROLL END >> ========================================================================= Name: G->JL Type: Program Function: Convert Gregorian date to Julian date. Listing: << JFIX -> d m y << IF m 3 < THEN m 12 + 'm' STO y 1 - 'y' STO END IF IF 1582 y > THEN 0 ELSE IF 1582 y < THEN 1 ELSE IF 10 m < THEN 1 ELSE IF 10 m > THEN 0 ELSE IF d 15 < THEN 0 ELSE 1 END END END END END THEN y 100 / IP DUP 4 / IP 2 3 ROLL - + ELSE 0 END 365.25 y * IP + 30.6001 m 1 + * IP + d + 1720994.5 + >> >> If date mode is DD.MM.YYYY (flag -42 SET) ----------------------------------------- Input: Level 3: DD.ddddd real number Level 2: MM real number Level 1: YYYY real number Output: Level 1: DDDDDDDD.ddd real number If date mode is MM/DD/YYYY (flag -42 CLEAR) ------------------------------------------- Input: Level 3: MM real number Level 2: DD.dddd real number Level 1: YYYY real number Output: Level 1: DDDDDDDD.ddd real number Example: Find the Julian date for April 21, 1989 at 3:15:00 PM. Place 3.1500 on the stack. Then convert the time to 24 hour format by adding 12 to the time. Then convert HMS to HRS by using the function HMS-> available in the TRIG menu. Divide by 24 to get the fractional portion of the date. Add 21, the current day of the month. You now should have 21.6354166667 on the stack. Continue as shown below... Level 3: 4 Level 2: 21.6354166667 Level 1: 1989 G->JL Level 1: 2447638.13542 (the Julian date) ======================================================================== Name: JL->G Type: Program Function: Convert Julian date to Gregorian date. Listing: << .5 + DUP IP SWAP FP 0 0 0 0 -> i f c d e g << IF i 2299160 > THEN i 1867216.25 - 36524.25 / IP DUP 4 / IP - 1 + i + ELSE i END 1524 + 'c' STO c 122.1 - 365.25 / IP 'd' STO d 365.25 * IP 'e' STO c e - 30.6001 / IP 'g' STO c e - f + g 30.6001 * IP - IF g DUP 13.5 < THEN 1 ELSE IF g 13.5 > THEN 13 ELSE 0 END END - IF DUP 2.5 > THEN 4716 ELSE IF DUP 2.5 < THEN 4715 ELSE 0 END END d SWAP - JFIX >> >> If date mode is DD.MM.YYYY (flag -42 SET) ----------------------------------------- Input: Level 1: DDDDDDDD.ddd real number Output: Level 3: DD.ddddd real number Level 2: MM real number Level 1: YYYY real number If date mode is MM/DD/YYYY (flag -42 CLEAR) ------------------------------------------- Input: Level 1: DDDDDDDD.ddd real number Output: Level 3: MM real number Level 2: DD.dddd real number Level 1: YYYY real number Example: Find the Gregorian equivalent of Julian day number 2435804.5 Level 1: 2435804.5 JL->G Level 3: 11 Level 2: 27 Level 1: 1956 ===================================================================== Name: LPYR Type: Program Function: Determines if year is a leap year. Listing: << -> y << y 4 MOD NOT y 100 MOD AND y 400 MOD NOT OR >> >> Input: Level 1: yyyy real number Output: Level 1: n real number Note: Output is 1 if a leap year, else 0. Notes: None of the other programs require this routine. It is provided for your conveniance only. ===================================================================== Name: RDOW Type: Program Function: Determine day of week given Gregorian date. Listing: << RCLF 0 FIX SWAP EXPDT G->JL 1.5 + 7 MOD SWAP STOF >> If date mode is DD.MM.YYYY (flag -42 SET) ----------------------------------------- Input: Level 1: DD.MMYYYY real number Output: Level 1: n real number If date mode is MM/DD/YYYY (flag -42 CLEAR) ------------------------------------------- Input: Level 1: MM.DDYYYY real number Output: Level 1: n real number Example: Level 1: 11.271956 Nov 27, 1956 RDOW Level 1: 2 Tuesday Notes: Output ranges from 0 to 6 for Sunday to Saturday. ======================================================================== Name: SDOW Type: Program Function: Same as DOW above but output is a text string. Listing: << 'DOW' SWAP RDOW 1 + GET >> Example: Above example would return "Tuesday" to the stack. ========================================================================= Name: JDATE Type: Program Function: Return todays Julian date. Listing: << DATE EXPDT JFIX 3 ROLL TIME HMS-> 24 / + 3 ROLLD JFIX G->JL >> ======================================================================= Name: J->DT Type: Program Function: Given a Julian date, returns the time to level 1 and the Gregorian date to level 2. Listing: << JL->G JFIX 3 PICK FP 24 * ->HMS 4 ROLLD CPSDT SWAP >> ======================================================================== Name: DT->J Type: Program Function: Given Gregorian date on level 2 and time on level 1, returns the Julian date. Listing: << HMS-> 24 / SWAP EXPDT JFIX 4 ROLL 4 ROLL + 3 ROLLD JFIX G->JL >> ==========================[ END ]==================================