Hindu Calendar

# Hindu Calendars for the HP-41

Overview

1°)  Old Hindu Solar Calendars

a)  Traditional Calendar
b)  "New-Old" Hindu Solar

2°)  Old Hindu Luni-Solar Calendars

a)  "New-Old" Hindu Luni-Solar ( program #1 )
b)  "New-Old" Hindu Luni-Solar ( program #2 )
c)  "New-Old" Hindu Luni-Solar ( program #3 )

1°)   Old Hindu Solar Calendars

a) Traditional Calendar

-The following programs use the Old Hindu Calendars
that began on -3101 January 23rd ( Gregorian ) = -3101 February 18th ( Julian ) = 0.0101 ( Kali Yuga )           ( -3101 = 3102 BC )

-It is based on a mean sidereal year = 1577917500 / 4320000 = 210389 / 576 = 365 + 149/576  ~ 365.25868 days
-A variant is suggested below to replace this value by a more accurate approximation.

-Months have 30 or 31 days.
-Mean month = (1/12) x one sidereal year = 210389 / 6912 ~  30.43822 days

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

Let  s = N + 1863079.25  ,  the date  yyyy.mndd  in the Hindu Calendar is obtained as follows:

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

Data Registers:  R00-R01-R02: temp
Flag:                    F04 if are using "J1"
Subroutine:       "J0" or "J1" or "J2" - cf "Julian & Gregorian Calendar for the HP-41"

 01  LBL "DT-KY" 02  XEQ "J0"  03  4 04  *  05  7452317 06  + 07  144  08  * 09  STO Y 10  210389 11  STO 00 12  MOD 13  STO 01          14  - 15  RCL 00 16  / 17  X<> 01 18  12 19  * 20  STO Y 21  RCL 00          22  MOD 23  STO 02  24  - 25  RCL 00 26  / 27  X<> 02 28  6912  29  / 30  INT 31  1 32  ST+ 02 33  ST+ Y 34  % 35  RCL 02          36  + 37  1 38  % 39  RCL 01          40  + 41  END

( 77 bytes / SIZE 003 )

 STACK INPUT OUTPUT X YYYY.MNDDGr/Ju YYYY.MNDDKy

Examples:

-3101.0218   XEQ "DT-KY"  >>>>       0.0101
1979.0716          R/S            >>>>    5080.0331
2009.1225          R/S            >>>>    5110.0910

Notes:

-In the Hindu calendar, the day begins at 6 a.m.
-So we also assume that a date written yyyy.mndd in the Julian or Gregorian calendar represents a time after 6 a.m. ( in fact between 6h and 30h )
-With another convention like "civil days begin at 0h" , lines 03 to 08 could be replaced by  1863079  +  576  *

-This routine does not work before  -3101.0218  ( Julian )
-Simply add  RCL 01  SIGN  *   after line 38 and it will work in this case too.

-We can create a "new-old" Hindu calendar by changing the value of the mean sidereal year:
-For instance,  1577907500 / 4320000 = 631163 / 1728 = 365 + 443 / 1728 ~ 365.2563657...  days is a better approximation.

-If you want to use this value, replace lines 07-10-28  by  432 ,  631163 ,  20736   and the 3 examples above become:

-3101.0218   XEQ "DT-KY"  >>>>       0.0101           ( of course unchanged )
1979.0716          R/S            >>>>    5080.0412
2009.1225          R/S            >>>>    5110.0922        thus a difference of about 12 days nowadays.

Reverse conversion:

Formula:     Given a date   yyyy.mmdd   in the old Hindu solar calendar,

Number of days since 2000/01/01 = CEIL [ -1863080.25 + y 210389 / 576 + (m-1) 210389 / 6912 + d ]

Data Registers:  R00-R01-R02: temp
Flag:                    F04 if are using "D1"
Subroutine:       "DT" or "D1" or "D2" - cf "Julian & Gregorian Calendar for the HP-41"

 01  LBL "KY-DT" 02  INT 03  STO 01 04  LASTX 05  FRC 06   E2 07  STO 00 08  * 09  INT 10  STO 02 11  LASTX 12  FRC 13  ST* 00 14  RCL 01          15  1788  16  * 17  RCL 02 18  210389 19  ST* Y 20  - 21  + 22  6912  23  STO 02          24  4 25  / 26  - 27  ENTER^ 28  CHS 29  RCL 02 30  MOD 31  + 32  RCL 02          33  / 34  RCL 01 35  365 36  * 37  + 38  RCL 00          39  + 40  1863080  41  - 42  XEQ "DT" 43  END

( 78 bytes / SIZE 003 )

 STACK INPUT OUTPUT X YYYY.MNDDKy YYYY.MNDDGr/Ju

Examples:

0.0101    XEQ "KY-DT"  >>>>   -3101.0218       ( or -3101.0123 Gregorian )
5080.0331          R/S            >>>>     1979.0716
5110.0910          R/S            >>>>     2009.1225

Notes:

-This routine does not work before  0.0101  ( Kali Yuga )
-Simply add  ABS  after line 04 and it will work in this case too.

-If civil days began at 0h instead of 6h, we could simplify this program:  replace line 29 by  6192  STO 02  and delete lines 22 thru 26

-If you want to use the "new-old" Hindu calendar mentioned in §1, replace lines 15-18-22  by  5316 ,  631163 ,  20736.

b) "New-Old" Hindu Solar

-The variant suggested above uses 1 sidereal year = 365 + 443 / 1728 ~ 365.2563657...  days
-Actually, in 2000, one mean sidereal year = 365.256363 days
-The following routine employs this value.

Data Registers:  R00-R03: temp
Flag:                    F04 if are using "J1"
Subroutine:       "J0" or "J1" or "J2" - cf "Julian & Gregorian Calendar for the HP-41"

 01  LBL "DT-KY" 02  XEQ "J0"  03  1863079.25 04  + 05  STO 00          06  STO 01 07  365.256363 08  STO 02 09  12 10  / 11  STO 03          12  MOD 13  ST- 01 14  INT 15  1 16  ST+ Y 17  % 18  RCL 01          19  RCL 03 20  / 21  FIX 0 22  RND 23  12 24  MOD     25  + 26  1 27  ST+ Y            28  % 29  RCL 00 30  RCL 02          31  / 32  INT 33  + 34  FIX 4 35  END

( 73 bytes / SIZE 004 )

 STACK INPUT OUTPUT X YYYY.MNDDGr/Ju YYYY.MNDDKy

Examples:

-3101.0218   XEQ "DT-KY"  >>>>       0.0101
1979.0716          R/S            >>>>    5080.0412
2009.1225          R/S            >>>>    5110.0922

Notes:

-Actually, one mean sidereal year =

365.2563630 days in 2000
365.2563607 days in 0
365.2563573 days in -3000

-This value of  365.256363  ( line 12 )  may be replaced by another approximation y,
provided  1000000 y  is an integer and a mulptiple of 3:  there will be no roundoff-error.

Reverse conversion:

Data Registers:  R00-R03: temp
Flag:                    F04 if are using "D1"
Subroutine:       "DT" or "D1" or "D2" - cf "Julian & Gregorian Calendar for the HP-41"

 01  LBL "KY-DT" 02  INT 03  STO 01 04  LASTX 05  FRC 06   E2 07  STO 00 08  * 09  INT 10  STO 02 11  LASTX 12  FRC 13  ST* 00 14  SIGN 15  ST- 02 16  RCL 01 17  5.256363  18  STO 03          19  FRC 20  * 21  INT 22  LASTX 23  FRC 24  RCL 03 25  12 26  / 27  RCL 02          28  * 29  + 30  4 31  1/X 32  - 33  ENTER^ 34  CHS 35  1 36  MOD 37  + 38  + 39  RCL 01          40  365 41  * 42  + 43  RCL 02 44  30 45  * 46  + 47  RCL 00          48  + 49  1863080  50  - 51  XEQ "DT" 52  END

( 85 bytes / SIZE 004 )

 STACK INPUT OUTPUT X YYYY.MNDDKy YYYY.MNDDGr/Ju

Examples:

0.0101    XEQ "KY-DT"  >>>>   -3101.0218       ( or -3101.0123 Gregorian )
5080.0412          R/S            >>>>     1979.0716
5110.0922          R/S            >>>>     2009.1225

2°)   Old Hindu Luni-Solar Calendars

a)  "New-Old" Hindu Luni-Solar ( program #1 )

-The Traditional Luni-Solar Calendar uses:

1 sidereal year = 365 + 149/576  ~ 365.25868 days
1  lunar month  =  29 + 2362563/4452778 ~ 29.53058181 days

-It's difficult to apply the formulae given in reference [1] with such fractions: multiprecision arithmetic would be needed.
-So, I've simplified the problem by choosing different approximations, namely:

One sidereal year = A = 346263/948 = 365.256329... days        ( not excellent but better than 365.25868... )
One Lunar month = B =  27995/948 = 29.53059072... days

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

Let  s = N + 1863079.25  ,  the year y, the month m and the day d  in the Hindu Calendar are obtained as follows:

Let  N.M. = new-moon = s - s mod B

the month is leap iff   A/12 - B >= N.M. mod ( A/12 ) > 0

m = 1 + ceil ( 12 N.M. / A ) mod 12

d = 1 + floor ( 30 s / B ) mod 30

y = -1 + ceil [ ( N.M. + A/12 ) / A ]

Data Registers:  R00-R04: temp
Flag:                    F04 if are using "J1"
Subroutine:       "J0" or "J1" or "J2" - cf "Julian & Gregorian Calendar for the HP-41"

 01  LBL "DT-HLS" 02  XEQ "J0"  03  4 04  * 05  7452317 06  + 07  STO 00 08  948 09  * 10  STO Y 11  111980 12  MOD 13  - 14  STO 01 15  1 16  STO 02 17  CLX 18  115421 19  STO 03  20  MOD 21  3441 22  X<>Y 23  X<=Y? 24  X=0? 25  DSE 02 26  CLX 27  RCL 00           28  1422 29  * 30  STO Y 31  5599 32  STO 00 33  MOD 34  - 35  RCL 00       36  / 37  FIX 0 38  RND 39  30 40  MOD 41  1 42  ST+ Y 43  % 44  RCL 02           45  + 46  10 47  / 48  RCL 01 49  ENTER^ 50  CHS 51  RCL 03  52  MOD 53  + 54  RCL 03           55  ST+ 01 56  / 57  12 58  ST* 03 59  MOD 60  + 61  1 62  ST+ Y 63  % 64  RCL 01 65  ENTER^ 66  CHS 67  RCL 03  68  MOD 69  + 70  RCL 03           71  / 72  1 73  - 74  + 75  FIX 5 76  END

( 129 bytes / SIZE 004 )

 STACK INPUT OUTPUT X YYYY.MNDDGr/Ju yyyy.mmbddHLS

where b is a boolean:

b = 1  indicates a leap month
b = 0  indicates a regular month

Examples:

-3101.0218   XEQ "DT-HLS"  >>>>       0.01001
1976.0101            R/S            >>>>    5076.10129           here, we have a leap month
1976.0103            R/S            >>>>    5076.10001
1979.0716            R/S            >>>>    5080.04022
2009.1225            R/S            >>>>    5110.10009

Notes:

-A leap-month precedes the regular month of the same name.
-Months have 29 or 30 civil days.
-Sometimes, there are lost days: one day is skipped!

-For instance,  2000.0220  gives  5100.12015
whereas       2000.0221  gives  5100.12017

-Thus,  5100.12016  is lost!

-There will be no roundoff-error for Gregorian dates < 4118.0315

Reverse conversion:

Formula:     Given a date   yyyy.mmbdd   in the old Hindu solar calendar,

Number of days since 2000/01/01 = CEIL [ -1863080.25 + lny + m' B + (d-1) B/30 ]       where

lny = lunar-new-year =  B + p - p mod B             with    p = (12y-1) A/12

m' = m-1  if   {  the month is not leap ( b = 0 ) and  ceil [ ( B - p mod B ) / ( A/12 - B ) ] <= m  }
m' = m     otherwise

Again, we apply these formulae with

One sidereal year = A = 346263/948 = 365.256329... days
One Lunar month = B =  27995/948 = 29.53059072... days

Data Registers:  R00-R05: temp
Flag:                    F04 if are using "D1"
Subroutine:       "DT" or "D1" or "D2" - cf "Julian & Gregorian Calendar for the HP-41"

 01  LBL "HLS-DT" 02  INT 03  STO 00 04  LASTX 05  FRC 06   E2 07  STO 03 08  * 09  INT 10  STO 01 11  LASTX 12  FRC 13  10 14  * 15  INT 16  STO 02 17  LASTX 18  FRC 19  ST* 03 20  RCL 00  21  12 22  * 23  1 24  - 25  115421 26  * 27  STO 04           28  111980 29  STO 05 30  STO Z 31  MOD 32  - 33  ST+ 04 34  RCL 02 35  X#0? 36  GTO 00 37  RCL 01 38  RCL Z 39  ENTER^ 40  CHS 41  3441 42  ST* T 43  MOD 44  + 45  X<=Y? 46  ISG 01 47  LBL 00 48  RCL 01           49  1 50  - 51  RCL 05 52  ST* 03 53  ST- 03 54  * 55  RCL 04 56  + 57  948 58  - 59  STO Y 60  LASTX 61  4 62  * 63  STO 01 64  MOD 65  STO 02           66  - 67  RCL 01 68  / 69  RCL 02 70  30 71  ST* 01 72  * 73  RCL 03 74  + 75  ENTER^ 76  CHS 77  RCL 01  78  MOD 79  + 80  RCL 01           81  / 82  + 83  1863079 84  - 85  XEQ "DT" 86  END

( 136 bytes / SIZE 006 )

 STACK INPUT OUTPUT X YYYY.MMbDDHLS yyyy.mnddGr/Ju

where b is a boolean:

b = 1  indicates a leap month
b = 0  indicates a regular month

Examples:

0.01001    XEQ "HLS-DT"  >>>>   -3101.0218
5076.10129            R/S             >>>>     1976.0101
5080.04022            R/S             >>>>     1979.0716
5110.10009            R/S             >>>>     2009.1225

b)  "New-Old" Hindu Luni-Solar ( program #2 )

-This variant employs:

1 sidereal year = 365.256363     days
1 lunar month  =  29.53058886  days

Data Registers:  R00-R06: temp
Flag:                    F04 if are using "J1"
Subroutine:       "J0" or "J1" or "J2" - cf "Julian & Gregorian Calendar for the HP-41"

 01  LBL "DT-HLS" 02  XEQ "J0"  03  1863079 04  + 05  STO 01 06  4 07  1/X 08  STO 02 09  + 10  STO 00 11  29.53058886 12  STO 03 13  MOD 14  ST- 02 15  SIGN 16  STO 04 17  365.256363 18  STO 05 19  12 20  / 21  STO 06 22  RCL 03 23  - 24  RCL 01  25  RCL 06 26  MOD 27  RCL 02 28  ST+ 01 29  LASTX 30  MOD 31  + 32  RCL 06           33  MOD 34  X#0? 35  X>Y? 36  DSE 04 37  CLX 38  RCL 00 39  30 40  * 41  STO Y 42  RCL 03  43  MOD 44  - 45  RCL 03           46  / 47  FIX 0 48  RND 49  30 50  MOD 51  1 52  ST+ Y 53  % 54  RCL 04 55  + 56  10 57  / 58  RCL 01  59  ENTER^ 60  CHS 61  RCL 06 62  ST+ 01 63  MOD 64  + 65  RCL 06           66  / 67  RND 68  12 69  MOD 70  + 71  1 72  ST+ Y 73  % 74  RCL 01  75  ENTER^ 76  CHS 77  RCL 05 78  MOD 79  + 80  RCL 05           81  / 82  RND 83  1 84  - 85  + 86  FIX 5 87  END

( 140 bytes / SIZE 007 )

 STACK INPUT OUTPUT X YYYY.MNDDGr/Ju yyyy.mmbddHLS

where b is a boolean:

b = 1  indicates a leap month
b = 0  indicates a regular month

Examples:

-3101.0218   XEQ "DT-HLS"  >>>>          0.01001
1979.0716            R/S            >>>>    5080.04022
2000.0503            R/S            >>>>    5101.02130         a leap month
2000.0504            R/S            >>>>    5101.02001
2009.1225            R/S            >>>>    5110.10009

Notes:

-The values of the sidereal year y ( line 17 ) and the lunar month m ( line 11 ) may be changed provided 1000000 y and 100000000 m
are integers and multiples of 3 - otherwise, roundoff-errors would be possible.
-For example, if you replace line 11 by 29.53058181 and line 17 by 365.258682, you get a calendar that is very close to the traditional old hindu lunisolar
( though probably not exactly the same )

-An example of "lost day" is 5100.12009:

2000.0213 ( Gregorian )  >>>>  5100.12008  is followed by
2000.0214 ( Gregorian )  >>>>  5100.12010

Reverse conversion:

Data Registers:  R00-R06: temp
Flag:                    F04 if are using "D1"
Subroutine:       "DT" or "D1" or "D2" - cf "Julian & Gregorian Calendar for the HP-41"

 01  LBL "HLS-DT"   02  INT   03  STO 00   04  LASTX   05  FRC   06   E2   07  STO 03   08  *   09  INT   10  STO 01   11  LASTX   12  FRC   13  10   14  *   15  INT   16  STO 02   17  LASTX   18  FRC   19  ST* 03   20  365.256363   21  STO 06   22  INT   23  RCL 00   24  *   25  30 26  -   27  STO 04    28  RCL 00   29  RCL 06   30  FRC   31  *   32  INT   33  ST+ 04   34  LASTX   35  FRC   36  RCL 06             37  12   38  /   39  STO 00   40  FRC   41  -   42  STO Y   43  29.53058886   44  STO 06   45  MOD   46  RCL 04   47  LASTX   48  MOD   49  +   50  RCL 06 51  STO Z   52  MOD   53  -   54  +   55  STO 05    56  LASTX   57  ENTER^   58  CHS   59  RCL 00   60  RCL 06   61  -   62  STO 00             63  MOD   64  +   65  RCL 00   66  /   67  FIX 0   68  RND   69  1   70  ST- 03   71  RCL 02   72  -   73  RCL 01   74  *   75  X

( 177 bytes / SIZE 007 )

 STACK INPUT OUTPUT X YYYY.MMbDDHLS yyyy.mnddGr/Ju

where b is a boolean:

b = 1  indicates a leap month
b = 0  indicates a regular month

Examples:

0.01001    XEQ "HLS-DT"  >>>>   -3101.0218
5080.04022            R/S             >>>>     1979.0716
5101.02130            R/S             >>>>     2000.0503
5101.02001            R/S             >>>>     2000.0504
5110.10009            R/S             >>>>     2009.1225

Notes:

-Like in the previous routine, line 20 may be replaced by another value y provided 106 y  is an integer and a multiple of 3
and line 43 by another value m  provided 108 m  is also an integer and a multiple of 3.

-Try for instance 365.258682 and 29.53058181 to get - almost - the traditional old Lunisolar Hindu Calendar.

c)  "New-Old" Hindu Luni-Solar ( program #3 )

-The star Spica ( alpha Virginis ) is often regarded as a fixed star in Hindu astrology.
-Since Spica has a proper motion of about  -27.5 arcseconds per millenium in longitude with respect to J2000.0,
the value of the mean sidereal year 365.256363 days could be replaced by something like 365.2563554 days for the year 2000

-The following program uses 2 rational numbers for the mean sidereal year and the mean Lunar month:

A = 172401 / 472  ~  365.2563559  days
B =  27995 /  948  ~   29.53059072  days

-Unlike the values of A and B that are used in the routine listed in §2-a)  the denominators are different.
-So, the calculation is a little more complicated, all the more that the results are correct until gregorian year 25778

Data Registers:  R00-R03: temp
Flag:                    F04 if are using "J1"
Subroutine:       "J0" or "J1" or "J2" - cf "Julian & Gregorian Calendar for the HP-41"

 01  LBL "DT-HLS" 02  XEQ "J0" 03  4 04  * 05  7452317 06  + 07  STO 00 08  237 09  * 10  STO Y 11  27995 12  MOD 13  - 14  STO 01 15  1 16  STO 02 17  CLX 18  13619679 19  STO 03 20  MOD 21  472 22  * 23  RCL 03           24  MOD 25  406039 26  X<>Y 27  X#0? 28  X>Y? 29  DSE 02 30  CLX 31  RCL 00 32  1422 33  *  34  STO Y 35  5599 36  STO 00 37  MOD 38  - 39  RCL 00           40  / 41  FIX 0 42  RND 43  30 44  MOD 45  1 46  ST+ Y 47  % 48  RCL 02 49  + 50  10 51  / 52  RCL 01 53  472 54  * 55  ENTER^ 56  STO 01           57  CHS 58  RCL 03 59  MOD 60  + 61  RCL 03 62  ST+ 01 63  / 64  RND 65  12 66  ST* 03 67  MOD 68  + 69  1 70  ST+ Y 71  % 72  RCL 01 73  ENTER^ 74  CHS 75  RCL 03 76  MOD 77  + 78  RCL 03           79  / 80  RND 81  1 82  - 83  + 84  FIX 5 85  END

( 145 bytes / SIZE 004 )

 STACK INPUT OUTPUT X YYYY.MNDDGr/Ju yyyy.mmbddHLS

where b is a boolean:

b = 1  indicates a leap month
b = 0  indicates a regular month

Examples:

-3101.0218   XEQ "DT-HLS"  >>>>          0.01001
1979.0716            R/S            >>>>    5080.04022
2000.0428            R/S            >>>>    5101.02125       ( leap-month )
2009.1225            R/S            >>>>    5110.10009
21428.1212            R/S            >>>>  24529.01012

Reverse conversion:

Data Registers:  R00-R06: temp
Flag:                    F04 if are using "D1"
Subroutine:       "DT" or "D1" or "D2" - cf "Julian & Gregorian Calendar for the HP-41"

 01  LBL "HLS-DT" 02  INT 03  STO 00 04  LASTX 05  FRC 06   E2 07  STO 03 08  * 09  INT 10  STO 01 11  LASTX 12  FRC 13  10 14  * 15  INT 16  STO 02 17  LASTX 18  FRC 19  ST* 03 20  RCL 00  21  406039 22  STO 04 23  *  24  13213640  25  STO 05 26  STO 06 27  MOD 28  12 29  * 30  RCL 04           31  - 32  RCL 05 33  MOD 34  ST- 05 35  RCL 02 36  X#0? 37  GTO 00 38  RCL 01  39  RCL 05 40  ENTER^ 41  CHS 42  RCL 04 43  ST* T 44  MOD 45  + 46  X<=Y? 47  ISG 01 48  LBL 00 49  RCL 00           50  344124 51  * 52  RCL 01 53  RCL 06 54  3 55  * 56  ST* Y 57  - 58  + 59  RCL 03           60  RCL 06 61  10 62  / 63  ST* Y 64  - 65  + 66  RCL 05 67  3 68  * 69  + 70  41194629 71  - 72  ENTER^ 73  CHS 74  1342368 75  STO 01  76  MOD 77  + 78  RCL 01 79  / 80  RCL 00           81  365 82  * 83  + 84  1863079 85  - 86  XEQ "DT" 87  END

( 150 bytes / SIZE 007 )

 STACK INPUT OUTPUT X YYYY.MMbDDHLS yyyy.mnddGr/Ju

where b is a boolean:

b = 1  indicates a leap month
b = 0  indicates a regular month

Examples:

0.01001    XEQ "HLS-DT"  >>>>   -3101.0218
5080.04022            R/S             >>>>     1979.0716
5101.02125            R/S             >>>>     2000.0428
5110.10009            R/S             >>>>     2009.1225
24529.01012           R/S             >>>>   21428.1212

Notes:

-Of course, these "new-old" calendars are somewhat artificial:  they have never been - and will be probably never - used.
-Other values can be used for the mean sidereal year and / or the mean lunar month
( cf "Sidereal Year, Tropical Year & Lunar Month for the HP-41" )

Interesting Formulae

-The following formulae have been used in the routines listed above:

(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

Reference:

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