The Museum of HP Calculators


Julian & Gregorian Calendars for the HP-41

This program is Copyright © 2007 by Jean-Marc Baillard and is used here by permission.

This program is supplied without representation or warranty of any kind. Jean-Marc Baillard and The Museum of HP Calculators therefore assume no responsibility and shall have no liability, consequential or otherwise, of any kind arising from the use of this program material or any part thereof.

Overview

 1°) Date >>> Number of days since 2000/01/01 0h

   a) Program#1
   b) Program#2
   c) Program#3 - Gregorian Calendar only - ( Time Module required )

 2°) Number of days since 2000/01/01 0h >>> Date

   a) Program#1
   b) Program#2
   c) Program#3 - Gregorian Calendar only - ( Time Module required )

 3°) Date <> Day of the Year

   a) Program#1
   b) Program#2  ( Time Module required )

 4°) Tropical Year
 

Notes:

-Programs 1°) a) & 2°) a) were previously listed in "Phases of the Moon for the HP-41"
-The "B.C." years are counted astronomically:
   year  0 = 1 B.C.
   year -1 = 2 B.C. ...etc...
-All the dates are expressed in YMD format.
 

1°) Date >>> Number of days since 2000/01/01 0h
 

     a) Program#1
 

-This program computes the number of days since 2000/01/01  0h ( i-e the Julian Day number minus 2451544.5 )
  in X-register and the day of the week in T-register.
-Registers Y and Z are saved.
-The Gregorian calendar reform is taken into account: The day following 1582/10/04 is 1582/10/15
-"J0" ( and "DT" - cf 2°)a) ) are valid at least since 4713 B.C. up to ... the next calendar reform!

-Synthetic registers M, N, O, P can be replaced by R00, R01, R02, R03.
 

Data Registers: /
Flags: /
Subroutines: /
 

01  LBL "J0"
02  STO O
03  ENTER^
04  INT
05  STO N
06  -
07  ABS
08   E2
09  *
10  ENTER^
11  INT
12  STO M
13  -
14   E2
15  *
16  X<> M
17  3
18  +
19  6
20  X>Y?
21  DSE N
22  LBL 00
23  X<=Y?
24  CHS
25  +
26  4
27  +
28  30.6
29  *
30  INT
31  730550
32  -
33  ST+ M
34  CLX
35  RCL N
36  487
37  *
38  X<0?
39  DSE X
40  LBL 00
41  .75
42  *
43  INT
44  ST+ M
45  CLX
46  RCL O
47  1582.1015
48  -
49  X<0?
50  GTO 01
51  X<> N
52   E2
53  /
54  INT
55  25
56  %
57  INT
58  -
59  2
60  -
61  ST- M
62  LBL 01
63  CLX
64  RCL M
65  1
66  -
67  7
68  MOD
69  INT
70  STO T
71  X<> O
72  SIGN
73  X<> M
74  CLA
75  END

( 123 Bytes / SIZE 000 )
 
 
        STACK          INPUTS       OUTPUTS
             T               /           dow
             Z               Z             Z
             Y               Y             Y
             X   YYYY.MNDDdd             N
             L               /   YYYY.MNDDdd

  ( dow = day of week = 0 for Sunday, 1 for Monday, ... , 6 for Saturday )

-N= the number of days between a date YYYY.MMDDdd and 2000/01/01 at 0h  = the Julian Day number minus 2451544.5

Examples:

  April 4th 2134 at 6h AM    2134.040425  XEQ "J0"  >>>     N = 49036.25   RDN  RDN   dow = 0 = Sunday

  1234.0428    R/S   >>>   N = -279651  RDN  RDN  dow = 5 = Friday

 -4123.0707   R/S   >>>   N = -2236225  RDN  RDN  dow = 1 = Monday
 

     b) Program#2
 

-The following program is only a variant of a routine listed in the PPC ROM user's manual.
-Y-register is saved in Y Z T
-Synthetic register M may be replaced by any standard register ( like R00 )
 

Data Registers: /
Flag:  F04             Set flag F04 for the Julian Calendar
                           Clear flag F04 for the Gregorian Calendar
Subroutines: /
 

01  LBL "J1"
02  ENTER^
03  INT
04  ST- Y
05  X<>Y
06   E2
07  *
08  ENTER^
09  INT
10  STO M
11  -
12   E2
13  *
14  X<> M
15  1
16  E^X
17  -
18  12
19  /
20  +
21  INT
22  ST- M
23  LASTX
24  367
25  *
26  INT
27  ST+ M
28  SIGN
29  FS? 04
30  ISG X
31  %
32  INT
33  .75
34  ST* Z
35  *
36  X<>Y
37  ST- M
38  CLX
39  X<> M
40  INT
41  X<>Y
42  -
43  INT
44  730434
45  -
46  END

( 75 bytes / SIZE 000 )
 
 
      STACK        INPUTS      OUTPUTS
           T             /            Y
           Z             /            Y
           Y            Y            Y
           X   YYYY.MNDD            N

Examples:

  CF 04  2134.0404  XEQ "J1"  >>>     N =    49036
  SF 04  1234.0428      R/S        >>>     N = -279651

Notes:

-Here, the days cannot have decimals
-You can choose the Julian Calendar after 1582/10/15
  and you can choose the Gregorian Calendar before 1582/10/04

-This program only works since 0000/03/01  ( March 1st Year 0 )

-However, it will work for all dates - including negative years - if you have programmed a FLOOR function in M-Code:

   >>>   Replace lines 43-40-32-26-21  by  FLOOR  add  CLX  after line 27  and add  ABS  after line 05

-If you don't have a  FLOOR  function, replace it by  RCL X   1  MOD  -   ( lines 43-40-32-26 )
  replace line 23 by  R^  and replace line 22 by  ENTER^   STO Z   1  MOD  -

-The day of the week may be computed by  ( N-1) MOD 7
 

     c) Program#3 - Gregorian Calendar only - TIME Module required
 

-The functions of the TIME Module work for dates between 1582/10/15 and 4320/09/10
-"J2" overcomes these limitations and it is shorter than "J0" & "J1"
 

Data Registers: /
Flags: /
Subroutines: /
 

01  LBL "J2"
02  MDY
03  ENTER^
04  FRC
05  STO N
06  -
07  RCL X
08  400
09  MOD
10  STO M
11  -
12  2 E3
13  ST+ M
14  -
15  365.2425
16  *
17  X<> M
18   E6
19  /
20  RCL N
21  ABS
22   E2
23  *
24  +
25  1.012
26  X<>Y
27  DDAYS
28  RCL M
29  +
30  DMY                    this line is only useful if you live in a DMY country
31  CLA
32  END

( 66 bytes / SIZE 000 )
 
 
      STACK        INPUTS      OUTPUTS
           T             /            Y
           Z             /            Y
           Y            Y            Y
           X   YYYY.MNDD            N

Examples:

 10234.0704  XEQ "J2"  >>>   N = 3007591
  2134.0404       R/S       >>>   N =    49036
  1234.0428       R/S       >>>   N = -279658
-4123.0707       R/S       >>>   N = -2236192
 

2°) Number of days since 2000/01/01 0h >>> Date
 

-These 3 programs are the inverses of   "J0" "J1" "J2"
 

     a) Program#1
 

Data Registers: /
Flags: /
Subroutines: /
 

01  LBL "DT"
02  STO O
03  2453069
04  +
05  ENTER^
06  FRC
07  STO M
08  -
09  STO N
10  2300685
11  -
12  X<0?
13  GTO 01
14  4
15  *
16  1727779
17  +
18  146097
19  /
20  INT
21  ST+ N
22  4
23  /
24  INT
25  ST- N
26  ISG N
27  LBL 01
28  CLX
29  RCL N
30  122.1
31  -
32  365.25
33  STO P
34  /
35  INT
36  ST* P
37  RCL P
38  INT
39  ST- N
40  CLX
41  4715
42  -
43  X<> N
44  ST+ M
45  30.61
46  STO P
47  /
48  INT
49  ST* P
50  RCL P
51  INT
52  ST- M
53  CLX
54  13
55  X<Y?
56  X=0?
57  SIGN
58  -
59   E2
60  ST/ M
61  LOG
62  X<Y?
63  DSE N
64  CLX
65  X<> M
66  +
67   E2
68  /
69  RCL N
70  SIGN
71  *
72  RCL N
73  +
74  RCL O
75  SIGN
76  RDN
77  CLA
78  END

( 151 bytes / SIZE 000 )
 
 
        STACK          INPUTS       OUTPUTS
             Z               Z             Z
             Y               Y             Y
             X               N   YYYY.MNDDdd
             L               /             N

Examples:

   N =   49036.25    XEQ "DT"  >>>   2134.040425
   N = -279651             R/S       >>>   1234.0428
   N = -2236225           R/S       >>>  -4123.0707
 

     b) Program#2
 

-Like "J1", this program is also a variant of a routine listed in the PPC ROM user's manual.
-Y-register is saved in Y Z T
-Synthetic register M may be replaced by any standard register ( like R00 )
 

Data Registers: /
Flag:  F04             Set flag F04 for the Julian Calendar
                           Clear flag F04 for the Gregorian Calendar
Subroutines: /
 

01  LBL "D1"
02  730425.8
03  +
04  RCL X
05  36524.25
06  /
07  INT
08  25
09  %
10  INT
11  -
12  2
13  FS? 04
14  X<>Y
15  RDN
16  +
17  RCL X
18  365.25
19  ST/ Y
20  X<>Y
21  INT
22  STO M
23  *
24  INT
25  -
26  .3
27  -
28  RCL X
29  30.6
30  ST/ Y
31  X<>Y
32  INT
33  *
34  ST- Y
35  ISG Y
36  X<> L
37  3
38  -
39  6
40  X<Y?
41  ISG M
42  CHS
43  -
44  X<>Y
45  INT
46   E2
47  /
48  +
49   E2
50  /
51  0
52  X<> M
53  +
54  END

( 99 bytes / SIZE 000 )
 
 
      STACK        INPUTS      OUTPUTS
           T             /            Y
           Z             /            Y
           Y            Y            Y
           X            N  YYYY.MNDD

Examples:

  CF 04  N =    49036   XEQ "D1"  >>>  2134.0404
  SF 04  N = -279651      R/S         >>>  1234.0428

Notes:

-N must be an integer.
-You can choose the Julian Calendar after 1582/10/15
 and you can choose the Gregorian Calendar before 1582/10/04

-This program only works since 0000/03/01  ( March 1st Year 0 )  [  i-e  N >= -730425 in the Gregorian Calendar  ,  N >= -730427 in the Julian Calendar  ]

-But if you have a FLOOR function, "D1" will work for all dates if you
   add  RCL M   SIGN   *         after line 50
           LBL 00   X<Y?   X=0?   after line 41
 replace lines  24-21-10-07  by FLOOR

-Otherwise, replace lines 15 to 24 by  X<> M  +  RCL X  365.25  /  RCL X  1  MOD  -  STO M  365.25  *  RCL X  1  MOD  -
                   replace lines 10 and 07 by  RCL X  1  MOD  -
              and replace line 04 by  STO M
 

     c) Program#3 - Gregorian Calendar only - TIME Module required
 

Data Registers: /
Flags: /
Subroutines: /
 

01  LBL "D2"
02  MDY
03  RCL X
04  146097
05  MOD
06  STO M
07  ST- Y
08  X<> L
09  /
10  400
11  *
12  X<> M
13  1.012
14  X<>Y
15  DATE+
16   E2
17  *
18  ENTER^
19  FRC
20  ST- Y
21   E4
22  ST/ Z
23  *
24  0
25  X<> M
26  +
27  STO Z
28  SIGN
29  *
30  +
31  DMY                    only if you live in a DMY country
32  END

( 64 bytes / SIZE 000 )
 
 
      STACK        INPUTS      OUTPUTS
           T             /            Y
           Z             /            Y
           Y            Y            Y
           X            N  YYYY.MNDD

Examples:

    1000000  XEQ "D2"  >>>        4737.1128
  -1000000       R/S       >>>         -738.0203
 

 3°) Date <> Day of the Year
 

     a) Program#1
 

Data Registers: /
Flags:  F04 & F00     Set flag F04 for the Julian Calendar                      F00 is cleared for a common year
                                Clear flag F04 for the Gregorian Calendar               F00 is set for a leap year
Subroutines: /
 

01  LBL "DOY"
02  FRC
03  LASTX
04  INT
05  XEQ 00
06  RDN
07  ABS
08   E2
09  *
10  FRC
11  LASTX
12  INT
13  RCL X
14  XEQ 02
15  X<>Y
16   E2
17  *
18  +
19  30
20  -
21  RTN
22  LBL "YN-D"
23  X<>Y
24  STO M
25  XEQ 00
26  CLX
27  32
28  RCL Y
29  X<Y?
30  ST- Z
31  RCL Z
32  2
33  FS? 00
34  SIGN
35  +
36  9
37  *
38  275
39  /
40  .98
41  +
42  INT
43  RCL M
44  SIGN
45  %
46  ST+ M
47  RDN
48  ENTER^
49  XEQ 02
50  30
51  -
52  -
53   E4
54  /
55  RCL M
56  SIGN
57  *
58  0
59  X<> M
60  +
61  RTN
62  LBL 00
63  CF 00
64  1
65  %
66  FRC
67  FC? 04
68  X#0?
69  GTO 01
70  X<> L
71  INT
72  4
73  MOD
74  ST+ Y
75  LBL 01
76  CLX
77  4
78  MOD
79  X=0?
80  SF 00
81  RTN
82  LBL 02
83  275
84  *
85  9
86  ST+ Z
87  /
88  INT
89  X<>Y
90  12
91  /
92  INT
93  FC? 00
94  ST+ X
95  -
96  END

( 151 bytes / SIZE 000 )
 

1- Date >>> Day of the Year
 
      STACK        INPUTS      OUTPUTS
           X  YYYY.MNDD         DOY

Example:

  CF 04 ( Gregorian Calendar )   2134.0707  XEQ "DOY"  >>>>  doy = 188    Flag F00 is clear:  2134 is a common year
  SF 04    ( Julian Calendar )        1248.0707  XEQ "DOY" >>>>  doy = 189     Flag F00 is set:     1248 is a leap year

2-Day of the Year >>> Date
 
      STACK        INPUTS      OUTPUTS
           Y         YYYY            N
           X            N  YYYY.MNDD

Example:

  CF 04  ( Gregorian Calendar )   2134  ENTER^  188  XEQ "YN-D" >>>  Date = 2134.0707    Flag F00 is clear:  2134 is a common year
  SF 04     ( Julian Calendar )       1248  ENTER^  189  XEQ "YN-D" >>>  Date = 1248.0707    Flag F00 is set:     1248 is a leap year
 

Notes:

-This program works for positive and negative years,
  but it doesn't work in 1582 between October 15th and December 31st ( subtract 10 to DOY )
-LBL 00  ( lines 62 to 81 ) determines whether a given year is a common year ( F00 is cleared ) or a leap year ( F00 is set )
-These lines may constitute a separate subroutine.
 

     b) Program#2 - TIME Module required
 

-Here is a shorter version if you have a TIME Module
 

Data Registers: /
Flags:  F04 & F00     Set flag F04 for the Julian Calendar                      F00 is cleared for a common year
                                Clear flag F04 for the Gregorian Calendar               F00 is set for a leap year
Subroutines: /
 

01  LBL "DOY"
02  FRC
03  LASTX
04  INT
05  XEQ 00
06  RDN
07  ABS
08   E2
09  *
10  XEQ 02
11  +
12  1.01
13  LASTX
14  +
15  X<>Y
16  DDAYS
17  1
18  +
19  DMY                   if DMY is your favorite format
20  RTN
21  LBL "YN-D"
22  X<>Y
23  STO M
24  XEQ 00
25  SIGN
26  -
27  XEQ 02
28  1.01
29  +
30  X<>Y
31  DATE+
32   E2
33  *
34  INT
35   E4
36  /
37  RCL M
38  SIGN
39  *
40  0
41  X<> M
42  +
43  DMY                   if DMY is your favorite format
44  RTN
45  LBL 00
46  MDY
47  CF 00
48  1
49  %
50  FRC
51  FC? 04
52  X#0?
53  GTO 01
54  X<> L
55  INT
56  4
57  MOD
58  ST+ Y
59  LBL 01
60  CLX
61  4
62  MOD
63  X=0?
64  SF 00
65  RTN
66  LBL 02
67  2001
68  FS? 00
69  DSE X
70   E6
71  /
72  END

( 124 bytes / SIZE 000 )
 

1- Date >>> Day of the Year
 
      STACK        INPUTS      OUTPUTS
           X  YYYY.MNDD         DOY

Example:

  CF 04 ( Gregorian Calendar )   2134.0707  XEQ "DOY"  >>>>  doy = 188    Flag F00 is clear:  2134 is a common year
  SF 04    ( Julian Calendar )        1248.0707  XEQ "DOY" >>>>  doy = 189     Flag F00 is set:     1248 is a leap year

2-Day of the Year >>> Date
 
      STACK        INPUTS      OUTPUTS
           Y         YYYY            /
           X            N  YYYY.MNDD

Example:

  CF 04  ( Gregorian Calendar )   2134  ENTER^  188  XEQ "YN-D" >>>  Date = 2134.0707    Flag F00 is clear:  2134 is a common year
  SF 04     ( Julian Calendar )       1248  ENTER^  189  XEQ "YN-D" >>>  Date = 1248.0707    Flag F00 is set:     1248 is a leap year
 

Notes:

-This program works for positive and negative years,
  but it doesn't work in 1582 between October 15th and December 31st ( subtract 10 to DOY )
-LBL 00  ( lines 45 to 65 ) determines whether a given year is a common year ( F00 is cleared ) or a leap year ( F00 is set )
 
 

4°) Tropical Year
 

-A Julian Year has 365.25 days and a Gregorian Year has 365.2425 days
-Actually, the tropical year slowly varies with time
-This short routine ( based on the VSOP 87 theory ) calculates
  the number of days of a mean tropical year.
 

01  LBL "TY"
02  2 E3
03  -
04  ENTER^
05  STO Z
06  3 E17
07  /
08  4 E13
09  1/X
10  -
11  *
12  26144 E-13
13  -
14  *
15  6 E-7
16  +
17  *
18  .60643
19  +
20  *
21  3600076975
22  +
23  13149 E8
24  X<>Y
25  /
26  END

( 73 bytes / SIZE 000 )
 
 
      STACK        INPUTS      OUTPUTS
           X         YYYY  number of days

Examples:

  -4000  XEQ "TY"  >>>   365.242506 days
  -2000            R/S             365.242420 days
      0               R/S             365.242311 days
   2000            R/S             365.242190 days
   4000            R/S             365.242069 days
   6000            R/S             365.241961 days

-So the Gregorian Calendar would have been perfect in the year  3841 B.C.
 

References:      Jean Meeus , "Astronomical Algorithms" - Willmann-Bell  -  ISBN 0-943396-35-2
                            PPC ROM user's manual
 
 

Go back to the HP-41 software library
Go back to the general software library
Go back to the main exhibit hall