rjh@ihlpa.UUCP (Randolph J. Herber) (07/03/85)
Shalom! I have enclosed with this item a proposed algorithm for converting a Julian (on or before Oct 4, 1582) or Georgian (on or after Oct 15, 1582) calendar date to the coresponding Jewish calendar date. I am asking whether or not the algorithm does an accurate job. Randolph J. Herber, ...ihnp4!ihlpa!rjh, 312-979-6553 (U.S.A.) U.S.Mail address Amdahl Corp, C/O Room IH1C220, AT&T Bell Labs, Naperville, IL, 60566-1005 #include <stdio.h> #include <time.h> /* This program writes a date (to stdout) according to the Jewish Calendar. If no argument is specified, it calls a "ctime" function to use today's date. Otherwise, it may be invoked with 3 arguments -- month, day, year (4-digit negative for BC(E)). */ static char *copyright = { "(C) 1985 Randolph J. Herber Usage is unrestricted with retention of notice." }; #define TRUE 1 #define FALSE 0 static int mlen[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 }; static int jmlen[] = { 0,30,29,30,29,30,30,29,30,29,30,29,30,29 }; static char *mname[] = { "", "Tishri", "Chshvn", "Kislev", "Tebet", "Shebat", "Adar", "VeAdar", "Nisan", "Iyar", "Sivan", "Tammuz", "Ab", "Elul" }; static short mdays[] = { 0, 354, 708, 1092, 1446, 1801, 2185, 2539, 2923, 3277, 3632, 4016, 4370, 4724, 5108, 5463, 5817, 6201, 6555 }; static short mparts[] = { 0, 9516, 19032, 16381, 25897, 9493, 6842, 16358, 13703, 23223, 6819, 4168, 13684, 23200, 20549, 4145, 13661, 11010, 20526 }; static short mtype[] = { 2, 1, 0, 2, 1, 0, 3, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 3, 0 }; static long table1[4][9] = { {0,15611,38880,64800, 83855,116640,145211,168480,181440}, {0, 3444,38880,55284,107124,116640,133044,168480,181440}, {0, 3444,36229,55284,107124,116640,123528,168480,181440}, {0, 3444,36229,55284,107124,116640,133044,168480,181440} }; static short table2[2][9] = { {1,3,2,2,3,1,3,1,0}, {1,3,2,1,3,1,3,1,0} }; static short table3[] = { 1,1,2,4,4,6,6,1,0 }; static char *jkind1[] = { "", "defective", "normal", "complete" }; static char *jkind2[] = { "", " leap" }; main(argc,argv) int argc; char **argv; { long secs, time(); struct tm *tbuf, *localtime(); void exit(); int year, yr, mo, da, unit(), jyr, jcycle; long jdate, jpart, jday, jarg, jstart; short yrm1, n, jyear; char style, leap, jtype, jleap; if (argc > 1 && argc != 4) { (void) printf("Usage: No arguments for today's date,"); (void) printf(" or '%s <mo> <da> <yr>'.\n", *argv); (void) exit(1); } else if (argc == 1) { secs = time((long *)0); tbuf = localtime(&secs); mo = tbuf->tm_mon + 1; da = tbuf->tm_mday; year = tbuf->tm_year + 1900; } else { mo = atoi(argv[1]); da = atoi(argv[2]); year = atoi(argv[3]); } if (year != 0 && year >= -3761 && year < 10000) { yr = year > 0 ? year : year + 1; style = year > 1582; leap = style ? (((yr % 4) == 0) && ((yr % 100) != 0)) || ((yr % 400) == 0) : ((yr % 4) == 0); mlen[2] = leap ? 29 : 28; if (mo >=1 && mo <= 12 && da >= 1 && da <= mlen[mo] && !(year == 1582 && (mo == 1 || mo == 2 || (mo == 10 && da >= 5 && da <= 14)))) { if (year == 1582 && mo == 10) { mlen[10] = 21; if (da >= 15) da -= 10; } else { mlen[10] = 31; } yrm1 = yr - 1; jdate = 1721423l+yrm1*365+unit(yrm1,4)+da; for (n=1;n<mo;++n) { jdate += mlen[n]; } if (style) { jdate -= 10 + (yrm1-1500)/100 - (yrm1-1200)/400; } if (jdate < 347998) { (void) printf("%s: Date of range!\n",*argv); (void) exit(2); } jyr = yr + 3761; do { jyr -= 1; jcycle = unit(jyr,19); jyear = rmdr(jyr,19); jtype = mtype[jyear]; jleap = jtype == 0; jpart = 17875l*jcycle+mparts[jyear]+25044l; jday = lunit(jpart,25920l); jpart -= jday * 25920l; jday += 6939l*jcycle+mdays[jyear]+347998l; jarg = lrmdr(jday,7l)*25920l+jpart; for(n=0;n<=7;++n) { if (table1[jtype][n]<=jarg && jarg<table1[jtype][n+1]) break; } jtype = table2[jleap][n]; jstart = jday+lrmdr(2l+table3[n]-jday,7l)-3l; } while (jdate < jstart); jyr += 1; jday = (jdate - jstart) + 1; switch (jtype) { case 1: jmlen[3] = 29; break; case 2: break; case 3: jmlen[2] = 30; break; default: printf("%s: Internal error 1\n",*argv); exit(3); break; } if (!jleap) { mname[7] = mname[6]; mname[6] = mname[0]; jmlen[6] = 0; } for(n=1;n<=13;++n) { if(jday<=jmlen[n]) break; jday -= jmlen[n]; } (void) printf("%s %d, %d %s%s\n", mname[n],jday,jyr, jkind1[jtype],jkind2[jleap]); (void) exit(0); } else { (void) printf("%s: Invalid date!\n",*argv); (void) exit(2); } } (void) printf("%s: Date out of range!\n",*argv); (void) exit(2); } int unit(f1,f2) int f1, f2; { int rmdr; rmdr = f1 % f2; if (rmdr < 0) rmdr += f2; return (f1 - rmdr) / f2; } long lunit(f1,f2) long f1, f2; { long rmdr; rmdr = f1 % f2; if (rmdr < 0) rmdr += f2; return (f1 - rmdr) / f2; } int rmdr(f1,f2) int f1, f2; { int rmdrx; rmdrx = f1 % f2; if (rmdrx < 0) rmdrx += f2; return rmdrx; } long lrmdr(f1,f2) long f1, f2; { long rmdrx; rmdrx = f1 % f2; if (rmdrx < 0) rmdrx += f2; return rmdrx; }