Julian & Gregorian Calendars for the HP-41
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 versions )
d) M-Code Routine - Gregorian Calendar only
- HP41CX
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 ) ( 2 versions )
3°) Date <> Day of the Year
a) Program#1
b) Program#2 ( Time Module required
)
-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.
-The Gregorian Calendar would have been perfect in the year 3841 B.C.
( cf "Sidereal year, tropical year & lunar month for the HP-41" )
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: /
-Delete line 30 if you are living in a MDY country.
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 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
Notes:
-If the dates are between 1582/10/15 and 4320/09/10 , we can write a shorter program.
-LBL "J" employs synthetic programming
01 LBL "J" 02 FRC 03 LASTX 04 INT 05 E6 06 / 07 X<>Y 08 E2 09 * 10 + 11 1.012 12 X<>Y 13 MDY 14 DDAYS 15 DMY 16 END |
( 31 bytes / SIZE 000 )
d) M-Code Routine - Gregorian
Calendar only - HP41CX
-The same results are returned faster with the following code:
0B2 "2"
00A "J"
1B9 ?NCXQ
144 MDY
2A0 SETDEC
0F8 C=X
128 L=C
088 C
0ED =
064 Int(C)
10E A=C ALL
268 Q=C
04E C
35C
110 =
130
002 400
0E8 C
044
070 =
171
064 A mod C
070 N=C ALL
2BE C=-C
10E A=C ALL
278 C=Q
01D C=
060 A+C
0F8 C=X
35C PT=12
090 LD@PT- 2
226 C=C+1 S&X
268 Q=C
2BE C=-C
025 C=
061 AB+C
04E C
35C
0D0
190
150
090 =
110
090
150
130
002 365.2425
13D C=
060 AB*C
0F0 C<>N ALL
10E A=C ALL
278 C=Q
01D C=
060 A+C
106 A=C S&X
130 LDI S&X
006 006
246 C=A-C S&X
0E8 X=C
0B0 C=N ALL
268 Q=C
138 C=L
05E C=| C |
084 C
0ED =
064 frc(C)
226 C=C+1 S&X
226 C=C+1 S&X
10E A=C ALL
0F8 C=X
01D C=
060 A+C
0E8 X=C
2A1 C
140 =
025 number of days
170 since 1582/10/15
10E A=C ALL
this word seems superfluous, but I'm not quite sure...
278 C=Q
01D C=
060 A+C
04E C
2BE
35C
050
150
090 =
0D0
210
110
130
005 -152384
025 C=
060 AB+C
0E8 X=C
1E5 ?NCGO
Replace these 2 words by 3E0 RTN
146 DMY
if you are living in a MDY country.
( 97 words )
STACK | INPUTS | OUTPUTS |
T | T | T |
Z | Z | Z |
Y | Y | Y |
X | YYYY.MNDD | N |
L | L | YYYY.MNDD |
Examples:
10234.0704 XEQ "J2" >>> N
= 3007591
2134.0404 XEQ "J2" >>>
N = 49036
1234.0428 XEQ "J2" >>>
N = -279658
-4123.0707 XEQ "J2" >>> N
= -2236192
Notes:
-If DD has decimals, you will get DATA ERROR or ... meaningless results
!
-Synthetic register Q is used.
-The date routines are at different places in the TIME module.
-There is no check for alpha data.
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 -
replace line 04 by STO M
c) Program#3 - Gregorian Calendar
only - TIME Module required
Data Registers: /
Flags: /
Subroutines: /
-Delete line 31 if you are living in MDY country.
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 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
Notes:
-If the dates are between 1582/10/15 and 4320/09/10 , we can write a shorter
program.
-Like LBL "J" , LBL "D" employs synthetic programming
01 LBL "D" 02 1.012 03 X<>Y 04 MDY 05 DATE+ 06 DMY 07 E2 08 * 09 INT 10 LASTX 11 FRC 12 E4 13 ST/ Z 14 * 15 + 16 END |
( 32 bytes / SIZE 000 )
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: /
-Delete lines 43 & 19 if you are living in a MDY coutry.
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 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 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 )
References:
[1] Jean Meeus , "Astronomical Algorithms" - Willmann-Bell
- ISBN 0-943396-61-1
[2] PPC ROM user's manual