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"