[comp.sys.handhelds] Julian/Gregorian Conversions

akcs.kevin@hpcvbbs.UUCP (Kevin Jessup) (03/20/91)

===================================================================

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 ]==================================

Here is the "ASC encoded" directory...

[cut here]
%%HP: T(1)A(R)F(.);
"69A20FF771F000000040A464948540D9D20E16323CE223392010000000000002
49063C1AFE22D9D203F2A20DCF1DBBF13F2A25BCF1B21305DF2293632B2130C6
0003044F4753047A20C2A20110003557E6461697C2A2011000D4F6E6461697C2
A203100045575637461697C2A2071000755646E65637461697C2A20510004586
572737461697C2A2011000642796461697C2A20510003516475727461697B213
0EB00050548505444550D9D20E163278BF1D6BB1DBBF13ABB133920200000000
0000010EEDA178BF1D6BB1DBBF13ABB1339204000000000000010EEDA193632B
2130E700050340535444550D9D20E163233920400000000000001050FA1DBBF1
D6BB176BA133920200000000000001050FA1DBBF1D6BB176BA193632B2130470
00402544F47540D9D20E1632916C14B2A2AE3C1DBBF184E2050548505444584E
204074D8A4C433920000000000000051076BA1743A2D4EB1DBBF1F76C193632B
213028000403544F47540D9D20E163284E203044F475DBBF184E20402544F475
9C2A276BA16C7D193632B21300500040C405952540D9D20E16321C432D6E2010
97E1632D6E201097803A2D4EB1F88E1D6E201097339202000000000000010D4E
B1387E1D6E201097339202000000000000040D4EB1F88E1908E1EF53293632B2
1305A0004074D8A4C440D9D20E163284E2040A46494851C432D6E201046D6E20
10D6D6E201097E16323CE22D6E2010D63F2A2EBBE1AFE22D9D20D6E2010D6339
20100000000000021076BA145632D6E2010D697632DCC02D6E2010979C2A290D
A145632D6E20109797632DCC02B21305DF223CE223CE22339203000000000028
510D6E201097D5CE1AFE224B2A25BF22D9D203CE22339203000000000028510D
6E201097EBBE1AFE229C2A25BF22D9D203CE22339201000000000000010D6E20
10D6EBBE1AFE229C2A25BF22D9D203CE22339201000000000000010D6E2010D6
D5CE1AFE224B2A25BF22D9D203CE22D6E201046339201000000000000510EBBE
1AFE224B2A25BF229C2A25DF22B21305DF22B21305DF22B21305DF22B21305DF
22AFE22D9D20D6E20109733920200000000000001050FA1D6BB178BF1803A250
FA1D6BB1ED2A23F2A25BCF190DA176BA1B21305BF224B2A25DF2233920200000
0000525630D6E201097EEDA1D6BB176BA1339201000000001006030D6E2010D6
9C2A276BA1EEDA1D6BB176BA1D6E20104676BA133920600000054990271076BA
1EF53293632B21308430040A4C4D87440D9D20E1632339209990000000000050
76BA178BF1D6BB1DBBF13ABB14B2A24B2A24B2A24B2A21C432D6E201096D6E20
1066D6E201036D6E201046D6E201056D6E201076E16323CE22D6E20109633920
6000000006199220D5CE1AFE22D9D20D6E20109633920600000526127681090D
A133920400000005242563050FA1D6BB178BF1803A250FA1D6BB190DA19C2A27
6BA1D6E20109676BA1B21305BF22D6E2010965DF223392030000000000425107
6BA145632D6E20103697632DCC02D6E20103633920200000000001221090DA13
3920200000000052563050FA1D6BB145632D6E20104697632DCC02D6E2010463
39202000000000525630EEDA1D6BB145632D6E20105697632DCC02D6E201036D
6E20105690DA133920100000000100603050FA1D6BB145632D6E20107697632D
CC02D6E201036D6E20105690DA1D6E20106676BA1D6E20107633920100000000
1006030EEDA1D6BB190DA13CE22D6E20107678BF1339201000000000005310EB
BE1AFE229C2A25BF22D9D203CE22D6E201076339201000000000005310D5CE1A
FE223392010000000000003105BF224B2A25DF22B21305DF2290DA13CE2278BF
1339200000000000000520D5CE1AFE223392030000000000617405BF22D9D203
CE2278BF1339200000000000000520EBBE1AFE223392030000000000517405BF
224B2A25DF22B21305DF22D6E201046DBBF190DA184E2040A4649485EF532936
32B213023400404445D8A440D9D20E1632E3FB133920100000000000042050FA
1DBBF184E2050548505444584E2040A4649485803A25BCF1803A25BCF176BA13
F2A20DCF184E2040A464948584E204074D8A4C493632B21305A00040A4D84445
40D9D20E163284E2040A4C4D87484E2040A46494853F2A2A9CF13ABB13392010
00000000000420EEDA1E1FB1803A20DCF184E2040A464948584E205034053544
45DBBF193632B2130B900050A44414455450D9D20E16322189184E2050548505
444584E2040A46494853F2A25BCF17F791E3FB133920100000000000042050FA
176BA13F2A20DCF184E2040A464948584E204074D8A4C493632B21302A000404
4A4444540D9D20E1632C9432D9D20E1632684C1858A1C2A2091000020202A455
C49414E40278BF176BA13F2A2485A1C2A2092000020202024414455402020202
02024594D454803A2485A1C2A20910000202D2D2D2D2D2D2D2D278BF176BA1D1
3A2485A13C032218917F791299919C2A2485A184E2050A444144554339209990
00000000005090DA178BF1D6BB1B0BC13392010000000000000109C2A284E203
0051444DBBF13ABB1339204000000000004680EEDA1D6BB1B0BC1C53A29C2A28
4E203005144476BA1233A2485A1DE032378A19B6328DBF193632B213084E2080
052554355425655493632B2130DD10080052554355425655480D9D20E1632916
C11C432D6E201066E1632EB3A1D6E201066F76C1EF53293632B2130D342"
[cut here]

******************************************************
Milwaukee HP48SX BBS

Files compressed using PKZIP.
ZMODEM, YMODEM, XMODEM and KERMIT file transfers.

(414)362-2020
6PM to 7AM CST, 24 Hours Sunday
2400/1200/600/300 baud, 8 data bits, 1 Stop bit, NO Parity
*******************************************************

lnk10562@uxa.cso.uiuc.edu (Louis Koziarz) (03/20/91)

Could someone/anyone post the simple date->julian date algorithm in pseudo-code?
I don't own a HP48, but would like to use the algorithm somewhere else.
Thanks in advance..

--
Louis Koziarz      University of Illinois Urbana/Champaign     *
koziarz@uiuc.edu   We _love_ the NCAA, really!                * *
                                                             * * *
                                                            * * * *

edp@jareth.enet.dec.com (Eric Postpischil (Always mount a scratch monkey.)) (03/20/91)

In article <1991Mar20.005301.3647@ux1.cso.uiuc.edu>,
lnk10562@uxa.cso.uiuc.edu (Louis Koziarz) writes:

>Could someone/anyone post the simple date->julian date algorithm in
>pseudo-code?

    Credit for the formulas used for the date conversions goes to the PPC
    ROM User's Manual, specifically Roger Hill and Fernando Lopez-Lopez.

Calendar (year, month, day) to Julian day number:
	y' = year + (month-2.85)/12
	julian = floor(
		floor(floor(367*y')-floor(y')-.75*floor(y')) +
		d - .75*floor(y'/100)
	) + 1721115
Julian day number to Calendar:
	j' = julian-172119.2
	n' = ceiling(j'+j'/48699+.2)
	y' = floor((n'-.2)/365.25)
	n'' = n'-floor(y'*365.25) = ceiling(.2 + (n'-.2)%365.25)
	m' = floor((n''-.5)/30.6)
	day = floor(n''-30.6*m'+.5) = ceiling((m'-.5)%30.6)
	if (m' <= 9)
		month = m'+3
		year = y'
	else
		month = m'-9
		year = y'+1


				-- edp (Eric Postpischil)
				"Always mount a scratch monkey."
				edp@jareth.enet.dec.com

d7matsa@dtek.chalmers.se (Mats Ackberger) (03/21/91)

In article <27e668c5:2479comp.sys.handhelds@hpcvbbs.UUCP> akcs.kevin@hpcvbbs.UUCP (Kevin Jessup) writes:
>              
>             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.
>
I have noticed that almost all american articles where week notations are
mentioned, the week starts with Sunday. But the standard that I supposed USA
have agreed on is; that the week should start with Monday.


Mats Ackberger				  |     /|   /|    /| ------  ---
Chalmers University of Technology	  |    / |  / |   / |   /    /__
NET:   d7matsa@dtek.chalmers.se		  |   /  | /  |  /--|  /        /
VOICE: +46 31 500700 (work)		  |  /   |/   | /   | /     ___/  
       +46 303 96638 (home)		  |
SNAIL: Box 126, S-43402 Kungsbacka,SWEDEN |

akcs.joehorn@hpcvbbs.UUCP (Joseph K. Horn) (03/22/91)

Mats Ackerberger says "the week should start with Monday."

It's probably a religious thing.  "On the seventh day, God rested." And
that, we all know, was the "sabbath", or Saturday.  And "Early on the
first day of the week, Jesus rose from the dead."  And that, we all know,
was Easter Sunday.

Even though the modern concept of "weekend" is rapidly changing how we
envisage the calendar week, and surely the business week begins on Monday
in modern life, nevertheless old traditions die hard.

For this reasons, most algorithms call Sunday 0, Monday 1, and so on thru
Saturday which is 6.  Unfortunately, Jim Donnelly's DOW function calls
Sunday 7, which takes the "weekend" concept to its logical conclusion...

-Joe Horn-

akcs.kevin@hpcvbbs.UUCP (Kevin Jessup) (03/23/91)

I am employed as a full time software engineer.
Where I work, the concepts of "weekend" and "overtime pay"
are meaningless!

gt9712a@prism.gatech.edu (BoxCar Willie) (04/17/91)

What does your job and/or it's policy on "overtime pay" have to do with 
handhelds????  I don't know about the rest of the handheld readers, but I 
do wish that you would take your employment gripes elsewhere. *:^P