# hp41programs

Cyclical Calendars

# Cyclical Calendars for the HP-41

Overview

0°)  Useful Formulae
1°)  Solar Calendars
2°)  Luni-Solar Calendars

a)  Program#1
b)  2 M-Code Routines
c)  Program#2  ( with M-Code Routines )
d)  Program#3  ( without M-Code Routines )
e)  Program#4
f)  Program#5
g)  Program#6

3°)  Solar & Lunar "Calendar"

-Except in §2e) & 2f) - these programs use some of the formulae given in references [1] &[2] in the chapter "Generic Cyclical Calendars" with  dY = dM = 0
-Paragraph 1 deals with single cycle calendars whereas paragraph 2 deals with double cycle calendars
-All these calendars are arithmetic calendars.

-They are similar to the old Hindu calendars, but the formulas are simpler and there is no lost days:
-In the Solar calendar, months have 30 or 31 days
-In the Luni-Solar calendars, months have 29 or 30 days and years have 12 or 13 months.

-Moreover, we use the tropical year ( the Hindu calendars are based on the sidereal year )

0°)  Useful Formulae

-The following formulas are employed in these programs ( they are also given in "Hindu Calendars for the HP-41" ):

(x.y)  mod  b   =  [ x ( y mod b ) ] mod b       ( usefull when  x.y > 10^10 , provided  x.b < 10^10 )
(x/y) mod (a/b) = [ (bx) mod (ay) ] / (by)

floor (x/y) = ( x - x mod y ) / y
ceil   (x/y) = [ x + (-x) mod y ] / y

[ floor ( 12 x/y ) ] mod 12 = [ 12 r - ( 12 r ) mod y ] / y      with  r = x mod y

1°)  Solar Calendars

-This routine employs a mean tropical year = 292559 / 801 days ~  365.2421973  days

Formulae:     Given a date   YYYY.MNDD  in the Gregorian calendar, we first compute the number of days N since 2000/01/01:

•  Let  s = N + 1863079  ,  the date  yyyy.mndd  in the Solar Calendar is obtained as follows:

y  = FLOOR ( 801 s / 292559 )
m = 1 + [ FLOOR ( 6912 s / 292559 ) ] MOD 12
d  = 1 + FLOOR [ s mod ( 292559 / 6912 ) ]

•  Given a date   yyyy.mmdd   in the Solar calendar,

N = Number of days since 2000/01/01 = CEIL [ -1863080 + y 292559 / 801 + (m-1) 292559 / 6912 + d ]

Data Registers:  R00-R01-R02:  temp
Flags: /
Subroutines:   "J2" & "D2"  ( cf "Julian and Gregorian Calendars for the HP-41" )

 01  LBL "GR-SC"  02  XEQ "J2"  03  1863079  04  +  05  801  06  *  07  STO Y  08  292559  09  STO 00   10  MOD  11  STO 01  12  -  13  RCL 00   14  /  15  X<> 01  16  12 17  *  18  STO Y  19  RCL 00          20  MOD  21  STO 02  22  -  23  RCL 00   24  /  25  X<> 02  26  9612  27  /  28  INT  29  1  30  ST+ 02  31  ST+ Y  32  % 33  RCL 02  34  +  35  1  36  %  37  RCL 01   38  +  39  RTN  40  LBL "SC-GR"  41  INT  42  STO 01   43  LASTX  44  FRC  45   E2  46  STO 00  47  *  48  INT 49  STO 02  50  LASTX  51  FRC  52  ST* 00  53  RCL 01   54  2328  55  *  56  RCL 02          57  292559  58  ST* Y  59  -  60  +  61  ENTER^  62  CHS  63  9612  64  STO 02 65  MOD  66  +  67  RCL 02          68  /  69  RCL 01   70  365  71  *  72  +  73  RCL 00   74  +  75  1863080  76  -  77  XEQ "D2"  78  END

( 147 bytes / SIZE 003 )

 STACK INPUT1 OUTPUT1 INPUT2 OUTPUT2 X YYYY.MNDDGr yyyy.mnddSC yyyy.mnddSC YYYY.MNDDGr

Examples:

-3101.0123   XEQ "GR-SC"   >>>>      0.0101      XEQ "SC-GR"  ( or simply  R/S )  >>>> -3101.0123
1979.0716   XEQ "GR-SC"   >>>>   5080.0623   XEQ "SC-GR"  ( or simply  R/S )  >>>>   1979.0716
2013.0210   XEQ "GR-SC"   >>>>   5114.0120   XEQ "SC-GR"  ( or simply  R/S )  >>>>   2013.0210

Notes:

-The years yyyy must be non-negative.
-If you want to use another origin, change lines 03 and 75.

2°)  Luni-Solar Calendars

a)  Program#1

-This first program employs the same value for the mean tropical year:  292559 / 801 days ~  365.2421973  days
-And for the mean Lunar month:   23654 / 801 days ~  29.53058677  days

-A Full Moon occurs - theoretically - on the last day of each month.
-Of course, this is just an approximation since the duration of the lunations is not constant.

Formulae:     Given a date   YYYY.MNDD  in the Gregorian calendar, we calculate the number of days N since 2000/01/01:

•  Let  s = N + 1863079  ,  the date  yyyy.mndd  in the Luni-Solar Calendar is obtained as follows:

With  m' = FLOOR ( 801 s / 23654 ) + 1

y  = CEIL ( 23654 m' / 292559 ) - 1
m = m' - [ FLOOR ( 292559 y / 23654 ) ]
d  = s - CEIL [ ( m' - 1 ) ( 23654 / 801 ) ] + 1

•  Given a date   yyyy.mmdd   in the Luni-Solar calendar,

N = Number of days since 2000/01/01 = CEIL [ -1863080 + { FLOOR ( y 292559 / 23654 + (m-1) } 23654 / 801 + d ]

Data Registers:  R00 to R03:  temp
Flags: /
Subroutines:   "J2" & "D2"  ( cf "Julian and Gregorian Calendars for the HP-41" )

 01 LBL "GR-LS"  02 XEQ "J2"  03 1863079  04 +  05 STO Y  06 801  07 STO 01  08 *  09 RCL X  10 23654  11 STO 00  12 STO 02            13 MOD  14 -  15 ST+ 00  16 ENTER  17 CHS  18 RCL 01  19 MOD 20 +  21 RCL 01  22 /  23 -  24 1  25 ST+ Y  26 %  27 RCL 00  28 ENTER  29 CHS  30 292559  31 STO 03            32 MOD  33 +  34 RCL 03  35 -  36 ENTER  37 STO 01  38 RCL 02 39 MOD  40 -  41 RCL 00  42 -  43 RCL 02  44 /  45 -  46 1  47 %  48 RCL 01  49 SIGN  50 *  51 RCL 01            52 RCL 03  53 /  54 +  55 RTN  56 LBL "LS-GR"  57 STO 00 58 INT  59 292559  60 *  61 STO Y  62 23654  63 STO 01  64 MOD  65 -  66 RCL 00  67 ABS  68 FRC  69  E2  70 *  71 STO 00            72 INT  73 RCL 01  74 ST* Y  75 - 76 +  77 ENTER  78 CHS  79 801  80 STO 01  81 MOD  82 +  83 RCL 01  84 /  85 RCL 00            86 FRC  87  E2  88 *  89 +  90 1863080  91 -  92 XEQ "D2"  93 END

( 159 bytes / SIZE 004 )

 STACK INPUT1 OUTPUT1 INPUT2 OUTPUT2 X YYYY.MNDDGr yyyy.mnddLS yyyy.mnddLS YYYY.MNDDGr

Examples:

-3101.0123   XEQ "GR-LS"   >>>>      0.0101      XEQ "LS-GR"  ( or simply  R/S )  >>>> -3101.0123
1979.0716   XEQ "GR-LS"   >>>>   5080.0722   XEQ "LS-GR"  ( or simply  R/S )  >>>>   1979.0716
2012.1221   XEQ "GR-LS"   >>>>   5113.1308   XEQ "LS-GR"  ( or simply  R/S )  >>>>   2012.1221
2013.0210   XEQ "GR-LS"   >>>>   5114.0129   XEQ "LS-GR"  ( or simply  R/S )  >>>>   2013.0210

Notes:

-The years yyyy may be negative.
-If you want to use another origin, change lines 03 and 90.

-With different definitions, we can use "integer part" instead of "ceil": it will save bytes since the HP41 doesn't have a CEIL function.
-Here is an unorthodox version that employs the following formulae:

m' = INT ( s/M )   ;   y = INT ( m'/L )  ;  d = INT ( s MOD M ) + 1  ;  m = INT ( m' MOD L ) + 1

with  M = 51649/1749 = 29.53058891...   &  L = 12628/1021 = 12.36826641...

 01 LBL "YMD"   02 XEQ "J2"  03 1863079  04 +  05 1749  06 STO 01  07 * 08 STO 00         09 51649  10 ST/ 00  11 MOD  12 RCL 01  13 /  14 INT 15 1  16 ST+ Y  17 %  18 RCL 00         19 INT  20 1021  21 STO 01 22 *  23 STO 00         24 12628  25 ST/ 00  26 MOD  27 RCL 01   28 /  29 INT 30 +  31 1  32 ST+ Y  33 %  34 RCL 00         35 INT  36 +  37 END

( 72 bytes / SIZE 002 )

 STACK INPUT OUTPUT X YYYY.MNDDGr yyyy.mnddLS

Examples:

-3101.0123   XEQ "YMD"   >>>>         0.0101
1979.0716          R/S           >>>>   5080.0621
2012.1221          R/S           >>>>   5113.1208
2013.0210          R/S           >>>>   5113.1329
2020.0126          R/S           >>>>   5121.0101
2020.0314          R/S           >>>>   5121.0220

Notes:

>>> yyyy must be non-negative

-For current dates, these results are often about 1 month before the results given by the previous version.
-With "YMD", the New Years are often very close to the Chinese calendar New Years.

-The reverse operation employs the CEIL function:

m' = CEIL ( L.yyyy ) + mn - 1
s   = CEIL ( M.m' ) + dd - 1863080

 01 LBL "YMDR"  02 STO 00  03 INT  04 ST- 00  05 12628  06 *  07 ENTER  08 CHS 09 1021  10 STO 01          11 MOD  12 +  13 RCL 01  14 /  15 RCL 00  16  E2 17 *  18 STO 00          19 INT  20 ST- 00  21 +  22 1  23 -  24 51649 25 *  26 ENTER  27 CHS  28 1749  29 STO 01          30 MOD  31 +  32 RCL 01 33 /  34 RCL 00          35  E2  36 *  37 +  38 1863080  39 -  40 XEQ "D2"  41 END

( 77 bytes / SIZE 002 )

 STACK INPUT OUTPUT X yyyy.mnddLS YYYY.MNDDGr

Examples:

0.0101   XEQ "YMDR"   >>>> -3101.0123
5080.0621          R/S             >>>>   1979.0716
5113.1208          R/S             >>>>   2012.1221
5113.1329          R/S             >>>>   2013.0210
5121.0101          R/S             >>>>   2020.0126
5121.0220          R/S             >>>>   2020.0314

Note:

>>> yyyy must be non-negative

b)  2 M-Code-Routines

-In calendrical calculations, we often have to compute  floor(y.z/x) or ceil(y.z/x)  where  x , y , z  are integers
-We can take advantage of the 13-digit routines to use these formulas even if  y.z > E10  provided  y.z/x  remains < E10
-FMD & CMD compute these functions.

-There is no check for alpha data, overflow and underflow.

084   "D"
00D  "M"
003   "C"     Ceil (y.z/x)
108   SETF 8
02B   JNC+05
084   "D"
00D  "M"
006   "F"     Floor (y.z/x)
104   CLRF 8
2A0  SETDEC
078   C=Z
10E   A=C ALL
0B8  C=Y
135   C=
060   A*C
0F8   C=X
128   L=C
10C  ?FSET 8
013   JNC+02
2BE  C=-C
000   NOP
269   C=
060   AB/C
2EE  ?C#0 ALL
10B   JNC+ 33d
130   LDI S&X
200   200h
306   ?A<C S&X
02F   JC+05
01A  A=0 M
006  A=0 S&X
02E  B=0 ALL
073  JNC+14d
130  LDI S&X
010  010h
306  ?A<C S&X
06B  JNC+13d
0A6  A<>C S&X
106   A=C S&X
35C  PT=12
3D4  PT=PT-1
266  C=C-1 S&X
3F3  JNC-02
2CA  ?B#0 PT <-
02B  JNC+05
02A  B=0 PT <-
35E  ?A#0 MS
009   C=
061   AB-1  if carry
04E  C= 0 ALL
025  C=
060  AB+C
2EE  ?C#0 ALL
023  JNC+04
10C  ?FSET 8
013  JNC+02
2BE  C=-C
0E8  X=C
046  C
270  =
038  T
068  Z=C
0A8  Y=C
3E0   RTN

( 64 words )

 STACK INPUTS OUTPUTS T T T Z z T Y y T X x F(x,y,z) L L x

where  F(x,y,z) = Floor (y.z/x)   with  FMD
and     F(x,y,z) =  Ceil  (y.z/x)   with  CMD

Examples:

•  123456789  ENTER^
12345        ENTER^
654321       XEQ "FMD"  >>>>  FLOOR ( 123456789*12345 / 654321) = 2329245

•  123456789  ENTER^
12345        ENTER^
654321       XEQ "CMD"  >>>>  CEIL ( 123456789*12345 / 654321) = 2329246

Notes:

-These routines also work with negative arguments
-We have used  ceil(x) = - floor(-x)
-The results may be wrong if  y.z  has more than 13 digits and / or if x is too large.

c)  Program#2  ( With M-Code Routines )

-Focal programs are limited by 10-digit arithmetic, but with the 2 M-Code routines above FMD & CMD,
we can use better approximations to the mean lunar month and the mean tropical year
-In the following routine:

1 Lunar month = 334995 / 11344 days ~ 29.53058886  days
and   1 tropical year / 1 lunar month = 774439 / 62615 ~ 12.36826639
which leads to  1 tropical year ~ 365.2421896 days

Data Registers:  R00 to R03:  temp
Flags: /
Subroutines:   "J2" & "D2"  ( cf "Julian and Gregorian Calendars for the HP-41" )

 01  LBL "GR-LS"  02  XEQ "J2"  03  1863079  04  +  05  STO Y  06  11344  07  STO 01   08  334995  09  STO 02  10  FMD  11  STO 00   12  RCL 02   13  RCL 01  14  CMD  15  - 16  1  17  ST+ 00  18  ST+ Y  19  %  20  RCL 00          21  62615  22  STO 01   23  774439  24  STO 02   25  CMD  26  1  27  -  28  STO 03  29  RCL 02  30  RCL 01 31  FMD  32  RCL 00   33  X<>Y  34  -  35  +  36  1  37  %  38  RCL 03   39  SIGN  40  *  41  RCL 03  42  +  43  RTN  44  LBL "LS-GR"  45  INT 46  STO 01  47  LASTX  48  ABS  49  FRC  50   E2  51  STO 00          52  *  53  INT  54  STO 02   55  LASTX  56  FRC  57  ST* 00  58  RCL 01  59  774439  60  62615 61  FMD  62  RCL 02   63  +  64  1  65  -  66  334995  67  11344  68  CMD  69  RCL 00          70  +  71  1863080  72  -  73  XEQ "D2"  74  END

( 159 bytes / SIZE 004 )

 STACK INPUT1 OUTPUT1 INPUT2 OUTPUT2 X YYYY.MNDDGr yyyy.mnddLS yyyy.mnddLS YYYY.MNDDGr

Examples:

-3101.0123   XEQ "GR-LS"   >>>>      0.0101      XEQ "LS-GR"  ( or simply  R/S )  >>>> -3101.0123
1979.0716   XEQ "GR-LS"   >>>>   5080.0721   XEQ "LS-GR"  ( or simply  R/S )  >>>>   1979.0716
2012.1221   XEQ "GR-LS"   >>>>   5113.1308   XEQ "LS-GR"  ( or simply  R/S )  >>>>   2012.1221
2013.0210   XEQ "GR-LS"   >>>>   5114.0129   XEQ "LS-GR"  ( or simply  R/S )  >>>>   2013.0210

Notes:

-Here, the years yyyy may also be negative ( otherwise, delete lines 48-40-39-38 ).

-All these programs take the onset of the Kali-Yuga as origin i-e  -3101.0123 ( Gregorian Calendar )  -3101 = 3102 B.C.
-If you want to use another origin, change lines 03 and 71.
-For example, assuming Lord Jesus was born near the New Moon on  -1.1225 (???)  ( Gregorian ),
replace 1863079 ( line 03 ) by  730492  and replace line 71 by 730493

-With these modifications, you will have a Christian Luni-Solar Calendar and, for instance:

-1.1224     XEQ "GR-LS"   >>>>    -1.1329      XEQ "LS-GR"  ( or simply  R/S )  >>>>     -1.1224
-1.1225     XEQ "GR-LS"   >>>>      0.0101      XEQ "LS-GR"  ( or simply  R/S )  >>>>     -1.1225
2013.0210   XEQ "GR-LS"   >>>>   2013.0229   XEQ "LS-GR"  ( or simply  R/S )  >>>>   2013.0210

d)  Program#3  ( Without M-Code Routines )

-In fact, we can use the same approximations for the mean lunar months and solar years without using M-Code routines.
-We simply have to re-write some formulas and employ the RND function in FIX 0 mode.
-The "interesting formulae" given in paragraph 2°) a) are also very useful.

Formula:     Given a date   YYYY.MNDD  in the Gregorian calendar, we calculate the number of days N since 2000/01/01:

•  Let  s = N + 1863079  ,  the date  yyyy.mndd  in the Luni-Solar Calendar is obtained as follows:

With  m' = FLOOR ( 11344 s / 334995 ) + 1

d  = FLOOR [ s mod ( 334995 / 11344 ) ] + 1
m = CEIL [ m' amod ( 774439 / 62615 ) ]                         where   y amod x = y mod x  if  y mod x # 0
y  = CEIL ( 62615 m' / 774439 ) - 1                                    and    y amod x = x             if  y mod x = 0

Data Registers:  R00 to R03:  temp
Flags: /
Subroutines:   "J2" & "D2"  ( cf "Julian and Gregorian Calendars for the HP-41" )

 01  LBL "GR-LS"   02  XEQ "J2"   03  1863079   04  +   05  11344   06  STO 01    07  *   08  STO 00    09  334995   10  STO 02    11  MOD   12  ENTER^   13  ST- 00   14  RCL 01   15  MOD   16  -   17  RCL 01   18  /   19  FIX 0   20  RND   21  1   22  ST+ Y   23  % 24  RCL 00   25  RCL 02           26  /   27  RND   28  1   29  +   30  62615   31  STO 01    32  *   33  STO 00   34  774439   35  STO 02   36  MOD   37  X=0?   38  X<> L   39  ENTER^   40  CHS   41  RCL 01    42  MOD   43  +   44  RCL 01   45  /   46  RND 47  +   48  1   49  %   50  RCL 00    51  ENTER^   52  CHS   53  RCL 02    54  MOD   55  +    56  RCL 02   57  /    58  RND   59  1   60  -   61  STO Z   62  SIGN   63  *   64  +   65  FIX 4   66  RTN   67  LBL "LS-GR"   68  INT   69  STO 01 70  LASTX   71  ABS   72  FRC   73   E2   74  STO 00           75  *   76  INT   77  STO 02    78  LASTX   79  FRC   80  ST* 00   81  RCL 01   82  774439   83  *    84  STO Y   85  62615   86  STO 03   87  MOD   88  -   89  RCL 03   90  /   91  FIX 0   92  RND 93  RCL 02    94  +    95  1   96  -   97  334995    98  *   99  ENTER^ 100  CHS 101  11344 102  STO 03         103  MOD 104  + 105  RCL 03  106  / 107  RND 108  RCL 00 109 + 110  1863080 111  - 112  XEQ "D2" 113  FIX 4 114  END

( 197 bytes / SIZE 004 )

 STACK INPUT1 OUTPUT1 INPUT2 OUTPUT2 X YYYY.MNDDGr yyyy.mnddLS yyyy.mnddLS YYYY.MNDDGr

Examples:

-5724.1214   XEQ "GR-LS"   >>>>  -2623.1201   XEQ "LS-GR"  ( or simply  R/S )  >>>> -5724.1214
-3101.0123   XEQ "GR-LS"   >>>>      0.0101      XEQ "LS-GR"  ( or simply  R/S )  >>>> -3101.0123
1979.0716   XEQ "GR-LS"   >>>>   5080.0721   XEQ "LS-GR"  ( or simply  R/S )  >>>>   1979.0716
2012.1221   XEQ "GR-LS"   >>>>   5113.1308   XEQ "LS-GR"  ( or simply  R/S )  >>>>   2012.1221
2013.0210   XEQ "GR-LS"   >>>>   5114.0129   XEQ "LS-GR"  ( or simply  R/S )  >>>>   2013.0210

Notes:

-The results are of course identical to those of the previous version.
-In fact, several RND are superfluous in most cases.

e)  Program#4

-This routine also employs the formulae given in references [1] &[2] - page 167 - but with  dY = dM = 1/2
-And with  M = 51649/1749 = 29.53058891...   &  L = 12628/1021 = 12.36826641...

-With  N = number of days since  2000/01/01 ( Gregorian )

•  Let  s = N + 1863079  ,  the date  yyyy.mndd  in the Luni-Solar Calendar is obtained as follows:

With  n = N + 1/2  and   m' = FLOOR ( n / M ) + 1/2

d  = FLOOR   ( n mod M ) + 1
m =   CEIL    ( m' amod L )                         where   y amod x = y mod x  if  y mod x # 0
y  =   CEIL      ( m' / L ) - 1                           and    y amod x = x             if  y mod x = 0

•  And for the reverse conversion:

-With  m' = FLOOR ( y L + 1/2 ) + m - 1

N = CEIL ( m' M - 1/2 ) + d - 1

Data Registers:  R00 to R02:  temp
Flags: /
Subroutines:   "J2" & "D2"  ( cf "Julian and Gregorian Calendars for the HP-41" )

 01 LBL "GRLS"  02 XEQ "J2"  03 1863079  04 +  05 ST+ X  06 1749  07 STO 01  08 ST+ 01  09 ST* Y  10 +  11 STO 00  12 51649  13 STO 02  14 ST+ X  15 MOD  16 ENTER  17 ST- 00  18 RCL 01  19 MOD  20 -  21 RCL 01  22 / 23 1  24 ST+ Y  25 %  26 RCL 00         27 RCL 02  28 ST+ Y  29 ST+ X  30 /  31 2042  32 STO 01  33 *  34 STO 00  35 25256  36 STO 02  37 MOD  38 X=0?  39 X<> L  40 ENTER  41 CHS  42 RCL 01  43 MOD  44 + 45 RCL 01  46 /  47 +  48 1  49 %  50 RCL 00  51 ENTER  52 CHS  53 RCL 02  54 MOD  55 +  56 RCL 02  57 ST- Y  58 /  59 STO Z  60 SIGN  61 *  62 +  63 RTN  64 LBL "LSGR"  65 STO 00  66 INT 67 25256  68 *  69 1021  70 +  71 RCL X  72 LASTX  73 ST+ X  74 STO 01         75 MOD  76 -  77 RCL 01  78 /  79 RCL 00  80 ABS  81 FRC  82  E2  83 *  84 STO 00  85 INT  86 +  87 1  88 - 89 103298  90 *  91 1749  92 STO 01  93 ST+ 01  94 -  95 ENTER  96 CHS  97 RCL 01         98 MOD  99 + 100 RCL 01 101 / 102 RCL 00 103 FRC 104  E2 105 * 106 + 107 1863080 108 - 109 XEQ "D2" 110 END

( 189 bytes / SIZE 003 )

 STACK INPUT1 OUTPUT1 INPUT2 OUTPUT2 X YYYY.MNDDGr yyyy.mnddLS yyyy.mnddLS YYYY.MNDDGr

Examples:

-5724.1214   XEQ "GRLS"   >>>>  -2623.1202   XEQ "LSGR"  ( or simply  R/S )  >>>> -5724.1214
-3101.0123   XEQ "GRLS"   >>>>      0.0101      XEQ "LSGR"  ( or simply  R/S )  >>>> -3101.0123
1979.0716   XEQ "GRLS"   >>>>   5080.0622   XEQ "LSGR"  ( or simply  R/S )  >>>>   1979.0716
2012.1221   XEQ "GRLS"   >>>>   5113.1208   XEQ "LSGR"  ( or simply  R/S )  >>>>   2012.1221
2020.0404   XEQ "GRLS"   >>>>   5121.0311   XEQ "LSGR"  ( or simply  R/S )  >>>>   2020.0404

Notes:

-To avoid numbers > E10,  the Gregorian date should not exceed 4726/02/07
-If  yyyyLS is non-negative, lines  80-61-60-59  are superfluous and may be deleted.

f)  Program#5

-This routine also employs the formulae given in references [1] &[2] - page 167 - but with  dY = 1/2 & dM = 0
-And with  M = 51649/1749 = 29.53058891...   &  L = 12628/1021 = 12.36826641...

-With  N = number of days since  2000/01/01 ( Gregorian )

•  Let  s = N + 1863079  ,  the date  yyyy.mndd  in the Luni-Solar Calendar is obtained as follows:

With   m' = FLOOR ( s / M ) + 1/2

d  = FLOOR   ( s mod M ) + 1
m =   CEIL    ( m' amod L )                         where   y amod x = y mod x  if  y mod x # 0
y  =   CEIL      ( m' / L ) - 1                           and    y amod x = x             if  y mod x = 0

•  And for the reverse conversion:

-With  m' = FLOOR ( y L + 1/2 ) + m - 1

N = CEIL ( m' M ) + d - 1

Data Registers:  R00 to R02:  temp
Flags: /
Subroutines:   "J2" & "D2"  ( cf "Julian and Gregorian Calendars for the HP-41" )

 01 LBL "GRLS"  02 XEQ "J2"  03 1863079  04 +  05 1749  06 STO 01  07 *  08 STO 00  09 51649  10 STO 02  11 MOD  12 ENTER  13 ST- 00  14 RCL 01  15 MOD  16 -  17 RCL 01  18 /  19 1  20 ST+ Y  21 % 22 RCL 00  23 ST+ X  24 RCL 02         25 ST+ Y  26 /  27 1021  28 STO 01   29 ST+ 01  30 *  31 STO 00  32 25256  33 STO 02  34 MOD  35 X=0?  36 X<> L  37 ENTER  38 CHS  39 RCL 01  40 MOD  41 +  42 RCL 01 43 /  44 +  45 1  46 %  47 RCL 00  48 ENTER  49 CHS  50 RCL 02  51 MOD  52 +  53 RCL 02  54 ST- Y  55 /  56 STO Z  57 SIGN  58 *  59 +  60 RTN  61 LBL "LSGR"  62 STO 00  63 INT 64 25256  65 *  66 1021  67 +  68 RCL X  69 LASTX  70 ST+ X  71 STO 01         72 MOD  73 -  74 RCL 01  75 /  76 RCL 00  77 ABS  78 FRC  79  E2  80 *  81 STO 00  82 INT  83 +  84 1 85 -  86 51649  87 *  88 ENTER  89 CHS  90 1749  91 STO 01         92 MOD  93 +  94 RCL 01   95 /  96 RCL 00   97 FRC  98  E2  99 * 100 + 101 1863080 102 - 103 XEQ "D2" 104 END

( 178 bytes / SIZE 003 )

 STACK INPUT1 OUTPUT1 INPUT2 OUTPUT2 X YYYY.MNDDGr yyyy.mnddLS yyyy.mnddLS YYYY.MNDDGr

Examples:

-5724.1214   XEQ "GRLS"   >>>>  -2623.1201   XEQ "LSGR"  ( or simply  R/S )  >>>> -5724.1214
-3101.0123   XEQ "GRLS"   >>>>      0.0101      XEQ "LSGR"  ( or simply  R/S )  >>>> -3101.0123
1979.0716   XEQ "GRLS"   >>>>   5080.0621   XEQ "LSGR"  ( or simply  R/S )  >>>>   1979.0716
2012.1221   XEQ "GRLS"   >>>>   5113.1208   XEQ "LSGR"  ( or simply  R/S )  >>>>   2012.1221
2020.0404   XEQ "GRLS"   >>>>   5121.0311   XEQ "LSGR"  ( or simply  R/S )  >>>>   2020.0404

Note:

-If  yyyyLS is non-negative, lines  77-58-57-56  are superfluous and may be deleted.

g)  Program#6

-If   dY = dM = 0, the routine becomes a little simpler
-And with  M = 51649/1749 = 29.53058891...   &  L = 12628/1021 = 12.36826641...

•  Let  s = N + 1863079  ,  the date  yyyy.mndd  in the Luni-Solar Calendar is obtained as follows:

With  m' = FLOOR ( s / M ) + 1

y  = CEIL ( m' / L ) - 1
m = m' - [ FLOOR ( y L ) ]
d  = s - CEIL [ ( m' - 1 ) M ] + 1

•  Given a date   yyyy.mmdd   in the Luni-Solar calendar,

N = Number of days since 2000/01/01 = CEIL [ -1863080 + { FLOOR ( y L + (m-1) } M + d ]

Data Registers:  R00 to R03:  temp
Flags: /
Subroutines:   "J2" & "D2"  ( cf "Julian and Gregorian Calendars for the HP-41" )

 01 LBL "GRLS"  02 XEQ "J2"  03 1863079  04 +  05 STO Y  06 1749  07 STO 01  08 *  09 RCL X  10 51649  11 STO 02  12 MOD  13 -  14 STO 00  15 ENTER  16 CHS  17 RCL 01  18 MOD  19 +  20 RCL 01 21 /  22 -  23 1  24 ST+ Y  25 %  26 RCL 00         27 RCL 02  28 ST+ Y  29 /  30 STO 00  31 1021  32 STO 01  33 *  34 ENTER  35 CHS  36 12628  37 STO 02  38 MOD  39 +  40 RCL 02 41 -  42 ENTER  43 STO 03  44 RCL 01  45 MOD  46 -  47 RCL 01   48 /  49 RCL 00         50 -  51 -  52 1  53 %  54 RCL 03  55 RCL 02  56 /  57 STO Z  58 SIGN  59 *  60 + 61 RTN  62 LBL "LSGR"  63 STO 00  64 INT  65 12628  66 *  67 STO Y  68 1021  69 STO 01  70 MOD  71 -  72 RCL 01  73 /  74 RCL 00  75 ABS  76 FRC  77  E2  78 *  79 STO 00  80 INT 81 +  82 51649  83 ST* Y  84 -  85 ENTER  86 CHS  87 1749  88 STO 01  89 MOD  90 +  91 RCL 01         92 /  93 RCL 00  94 FRC  95  E2  96 *  97 +  98 1863080  99 - 100 XEQ "D2" 101 END

( 172 bytes / SIZE 004 )

 STACK INPUT1 OUTPUT1 INPUT2 OUTPUT2 X YYYY.MNDDGr yyyy.mnddLS yyyy.mnddLS YYYY.MNDDGr

Examples:

-5724.1214   XEQ "GRLS"   >>>>  -2623.1201   XEQ "LSGR"  ( or simply  R/S )  >>>> -5724.1214
-3101.0123   XEQ "GRLS"   >>>>      0.0101      XEQ "LSGR"  ( or simply  R/S )  >>>> -3101.0123
1979.0716   XEQ "GRLS"   >>>>   5080.0721   XEQ "LSGR"  ( or simply  R/S )  >>>>   1979.0716
2012.1221   XEQ "GRLS"   >>>>   5113.1308   XEQ "LSGR"  ( or simply  R/S )  >>>>   2012.1221
2020.0407   XEQ "GRLS"   >>>>   5121.0414   XEQ "LSGR"  ( or simply  R/S )  >>>>   2020.0407

Note:

-If  yyyyLS is non-negative, lines  75-59-58-57  are superfluous and may be deleted.

3°)  Solar & Lunar "Calendar"

-"YDMD" calculates the year and the day of the year + the month and the day of the month for a given date of the Gregorian calendar.

Formulae:

•  With  s = N + 1863079 >= 0    where  N =  the number of days N since 2000/01/01

YYYY =  Int ( 801.s / 292559 )  DDD1 = 1 + Int ( s Mod (292559/801) )
MM   =  Int ( 801.s / 23654 )     DD2   = 1 + Int ( s Mod (23654/801) )

Data Registers:  R00-R01-R02:  temp
Flags: /
Subroutine:   "J2"  ( cf "Julian and Gregorian Calendars for the HP-41" )

 01 LBL "YDMD"  02 XEQ "J2"  03 1863079  04 +  05 801  06 STO 01  07 *  08 STO 02 09 23654  10 STO 00          11 /  12 INT  13 RCL 02  14 RCL 00  15 MOD  16 RCL 01 17 /  18 INT  19 1  20 +  21  E2  22 /  23 +  24 RCL 02 25 292559  26 STO 00          27 /  28 INT  29 RCL 02  30 RCL 00  31 MOD  32 RCL 01 33 /  34 INT   35 1  36 +  37  E3  38 /  39 +  40 END

( 71 bytes / SIZE 003 )

 STACK INPUT OUTPUTS Y / MM.DD2 X yyyy.mnddGr YYYY.DDD1

Examples:

-3101.0123   XEQ "YMD"   >>>>        0.001   X<>Y           0.01
2000.0101          R/S           >>>>  5100.344   X<>Y   63089.24
2020.0314          R/S           >>>>  5121.052   X<>Y   63339.20

-Thus,  2020/03/14 is the 52nd day of the 5121st year  and  the 20th day of the 63339th month since  -3101/01/23

Notes:

-The day of the year is the first 3 decimals of  YYYY.DDD1  ( between 365 & 366 )
-The day of the month is the first 2 decimald of  MM.DD2        ( between 29 & 30 )

-These results are only based on the mean solar year & mean lunar month.  YYYY  must be non-negative.

References:

[1]  Nachum Dershowitz & Edward M. Reingold - "Calendrical Calculations" - Cambridge University Press - ISBN 978-0-521-70238-6
[2]  Nachum Dershowitz & Edward M. Reingold - "Indian Calendrical Calculations"