long julian(long date) { long offset; long result; long yr; long yend; offset = date - STARTDATE; result = STARTDATE; #ifdef WIN32 /* Disable warning about conditional expression is constant */ #pragma warning(disable:4127) #endif while (1) { #ifdef WIN32 #pragma warning(default:4127) #endif yr = result / 1000; yend = yr * 1000 + 365 + LEAP(yr); if (result + offset > yend) /* overflow into next year */ { offset -= yend - result + 1; result += 1000; continue; } else break; } return (result + offset); }
/* * unjulian (long date) -- return(date - STARTDATE) */ long unjulian(long date) { int i; long res = 0; for (i = STARTDATE / 1000; i < date / 1000; i++) res += 365 + LEAP(i); res += date % 1000 - 1; return (res); }
int is_last_day_in_month(int year,int month,int day){ int * days; if(LEAP(year)) days = days_in_a_month_l; else days = days_in_a_month; if(day == days[month-1]) return 1; return 0; }
int dayOfYear( date_t d ) { int dOY = d.dd + 31 * (d.mm - 1); if (d.mm > FEB) { dOY -= (4 * d.mm + 23) / 10; if (LEAP (d.yy)) dOY++; } return dOY; }
/* i_year: year - 1900 i_month: 0-11 i_mday: 1-31 i_hour: 0-23 i_minute: 0-59 i_second: 0-59 */ static int64_t vlc_timegm( int i_year, int i_month, int i_mday, int i_hour, int i_minute, int i_second ) { static const int pn_day[12+1] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; int64_t i_day; if( i_year < 70 || i_month < 0 || i_month > 11 || i_mday < 1 || i_mday > 31 || i_hour < 0 || i_hour > 23 || i_minute < 0 || i_minute > 59 || i_second < 0 || i_second > 59 ) return -1; /* Count the number of days */ i_day = (int64_t)365 * (i_year-70) + pn_day[i_month] + i_mday - 1; #define LEAP(y) ( ((y)%4) == 0 && (((y)%100) != 0 || ((y)%400) == 0) ? 1 : 0) for( int i = 70; i < i_year; i++ ) i_day += LEAP(1900+i); if( i_month > 1 ) i_day += LEAP(1900+i_year); #undef LEAP /**/ return ((24*i_day + i_hour)*60 + i_minute)*60 + i_second; }
int main() { int sum=0, dow=0, y, m, d; for ( y=1900; y <= 2000; ++y ) for ( m=0; m < 12; ++m ) for ( d=0; d < mdays[LEAP(y)][m]; ++d, dow = (dow+1)%7 ) { if ( y>1900 && d==0 && dow==6 ) printf("%4d-%.2d-%.2d fell on a sunday (sum=%d)\n", y, m+1, d+1, ++sum); } }
long mk_time(long index, dss_time_t *t) { long m = 0; long y; long d; t->timekey = index + JDAY_BASE; y = julian(index + STARTDATE - 1) / 1000; d = julian(index + STARTDATE - 1) % 1000; while (d > months[m].dcnt + LEAP_ADJ(y, m)) m++; PR_DATE(t->alpha, y, m, d - months[m - 1].dcnt - ((LEAP(y) && m > 2) ? 1 : 0)); t->year = 1900 + y; t->month = m + 12 * y + JMNTH_BASE; t->week = (d + T_START_DAY - 1) / 7 + 1; t->day = d - months[m - 1].dcnt - LEAP_ADJ(y, m-1); return (0); }
/* * See the footnote on page 384 of ``Calendrical Calculations, Part II: * Three Historical Calendars'' by E. M. Reingold, N. Dershowitz, and S. M. * Clamen, Software--Practice and Experience, Volume 23, Number 4 * (April, 1993), pages 383-404 for an explanation. */ date_t abs2greg( long theDate ) { int day, year, month, mlen; date_t d; long int d0, n400, d1, n100, d2, n4, d3, n1; d0 = theDate - 1L; n400 = d0 / 146097L; d1 = d0 % 146097L; n100 = d1 / 36524L; d2 = d1 % 36524L; n4 = d2 / 1461L; d3 = d2 % 1461L; n1 = d3 / 365L; day = (int) ((d3 % 365L) + 1L); year = (int) (400L * n400 + 100L * n100 + 4L * n4 + n1); if (4L == n100 || 4L == n1) { d.mm = 12; d.dd = 31; d.yy = year; return d; } else { year++; month = 1; while ((mlen = MonthLengths[LEAP (year)][month]) < day) { day -= mlen; month++; } d.yy = year; d.mm = month; d.dd = day; return d; } }
Tm_t* tmfix(register Tm_t* tm) { register int n; register int w; Tm_t* p; time_t t; /* * check for special case that adjusts tm_wday at the end * this happens during * nl_langinfo() => strftime() => tmfmt() */ if (w = !tm->tm_sec && !tm->tm_min && !tm->tm_mday && !tm->tm_year && !tm->tm_yday && !tm->tm_isdst) { tm->tm_year = 99; tm->tm_mday = 2; } /* * adjust from shortest to longest units */ if ((n = tm->tm_nsec) < 0) { tm->tm_sec -= (TMX_RESOLUTION - n) / TMX_RESOLUTION; tm->tm_nsec = TMX_RESOLUTION - (-n) % TMX_RESOLUTION; } else if (n >= TMX_RESOLUTION) { tm->tm_sec += n / TMX_RESOLUTION; tm->tm_nsec %= TMX_RESOLUTION; } if ((n = tm->tm_sec) < 0) { tm->tm_min -= (60 - n) / 60; tm->tm_sec = 60 - (-n) % 60; } else if (n > (59 + TM_MAXLEAP)) { tm->tm_min += n / 60; tm->tm_sec %= 60; } if ((n = tm->tm_min) < 0) { tm->tm_hour -= (60 - n) / 60; n = tm->tm_min = 60 - (-n) % 60; } if (n > 59) { tm->tm_hour += n / 60; tm->tm_min %= 60; } if ((n = tm->tm_hour) < 0) { tm->tm_mday -= (23 - n) / 24; tm->tm_hour = 24 - (-n) % 24; } else if (n >= 24) { tm->tm_mday += n / 24; tm->tm_hour %= 24; } if (tm->tm_mon >= 12) { tm->tm_year += tm->tm_mon / 12; tm->tm_mon %= 12; } else if (tm->tm_mon < 0) { tm->tm_year--; if ((tm->tm_mon += 12) < 0) { tm->tm_year += tm->tm_mon / 12; tm->tm_mon = (-tm->tm_mon) % 12; } } while (tm->tm_mday < -365) { tm->tm_year--; tm->tm_mday += 365 + LEAP(tm); } while (tm->tm_mday > 365) { tm->tm_mday -= 365 + LEAP(tm); tm->tm_year++; } while (tm->tm_mday < 1) { if (--tm->tm_mon < 0) { tm->tm_mon = 11; tm->tm_year--; } tm->tm_mday += DAYS(tm); } while (tm->tm_mday > (n = DAYS(tm))) { tm->tm_mday -= n; if (++tm->tm_mon > 11) { tm->tm_mon = 0; tm->tm_year++; } } if (w) { w = tm->tm_wday; t = tmtime(tm, TM_LOCALZONE); p = tmmake(&t); if (w = (w - p->tm_wday)) { if (w < 0) w += 7; tm->tm_wday += w; if ((tm->tm_mday += w) > DAYS(tm)) tm->tm_mday -= 7; } } tm->tm_yday = tm_data.sum[tm->tm_mon] + (tm->tm_mon > 1 && LEAP(tm)) + tm->tm_mday - 1; n = tm->tm_year + 1900 - 1; tm->tm_wday = (n + n / 4 - n / 100 + n / 400 + tm->tm_yday + 1) % 7; /* * tm_isdst is adjusted by tmtime() */ return tm; }
int main(int argc, char* argv[]) { date_t tempDate; long startAbs, endAbs; char *envStr; int envArgc; char *envArgv[40]; /* this should be big enough */ progname = argv[0]; set_default_city(); if ((envStr = getenv(ENV_OPTS)) && strcmp(envStr, "")) { int i; tokenize(envStr, &envArgc, envArgv); for (i = 1; i < argc; i++) /* append argv onto envArgv */ envArgv[envArgc++] = argv[i]; handleArgs(envArgc, envArgv); } else handleArgs(argc, argv); tempDate.yy = theYear; if (theYear < (hebrewDates_sw ? 3761 : 1)) die("Sorry, hebcal can only handle dates in the common era.", ""); switch (rangeType) { case TODAY: printHebDates_sw = 1; tempDate.dd = theDay; tempDate.mm = theMonth; tempDate.yy = theYear; startAbs = endAbs = greg2abs(tempDate); break; case DAY: printHebDates_sw = 1; tempDate.dd = theDay; tempDate.mm = theMonth; tempDate.yy = theYear; if (hebrewDates_sw) startAbs = endAbs = hebrew2abs(tempDate); else startAbs = endAbs = greg2abs(tempDate); break; case MONTH: tempDate.dd = 1; tempDate.mm = theMonth; tempDate.yy = theYear; if (hebrewDates_sw) { startAbs = hebrew2abs(tempDate); tempDate.dd = max_days_in_heb_month(tempDate.mm, tempDate.yy); endAbs = hebrew2abs(tempDate); } else { startAbs = greg2abs(tempDate); tempDate.dd = MonthLengths[LEAP(theYear)][theMonth]; endAbs = greg2abs(tempDate); } break; case YEAR: if (hebrewDates_sw) { tempDate.dd = 1; tempDate.mm = TISHREI; tempDate.yy = theYear; startAbs = hebrew2abs(tempDate); /* start yearly calendar with the day before RH (i.e. Erev * Rosh Hashanah) */ startAbs--; tempDate.yy += numYears; endAbs = hebrew2abs(tempDate) - 1; } else { tempDate.dd = 1; tempDate.mm = JAN; tempDate.yy = theYear; startAbs = greg2abs(tempDate); tempDate.yy += numYears; endAbs = greg2abs(tempDate) - 1; } break; default: die("Oh, NO! internal error #17q!", ""); /* this is dead code, but it silences some uninitialized variable warnings in gcc */ startAbs = endAbs =0; } tempDate = abs2hebrew(startAbs); if (ok_to_run) { init_holidays(tempDate.yy); /* load the holiday array */ main_calendar(startAbs, endAbs); return 0; /* success! Kol hakavod to thorough programmers */ } else return 1; }
void handleArgs(int argc, char *argv[]) { date_t greg_today; char **remain; size_t remain_count; char *cityNameArg = NULL; char *inFileName = NULL; char *tzid = NULL; char *yahrtzeitFileName = NULL; int today_sw = 0; int zemanim_sw = 0; int help_sw = 0; int version_sw = 0; int utf8_hebrew_sw = 0; char *latitudeStr = NULL; char *longitudeStr = NULL; char *langStr = NULL; static struct option long_options[] = { {"24hour", no_argument, 0, 'E'}, {"abbreviated", no_argument, 0, 'W'}, {"add-hebrew-dates", no_argument, 0, 'd'}, {"add-hebrew-dates-for-events", no_argument, 0, 'D'}, {"ashkenazi", no_argument, 0, 'a'}, {"candle-mins", required_argument, 0, 'b'}, {"candlelighting", no_argument, 0, 'c'}, {"city", required_argument, 0, 'C'}, {"daf-yomi", no_argument, 0, 'F'}, {"daily-sedra", no_argument, 0, 'S'}, {"euro-dates", no_argument, 0, 'e'}, {"format", required_argument, 0, 'f'}, {"havdalah-mins", required_argument, 0, 'm'}, {"hebrew-date", no_argument, 0, 'H'}, {"help", no_argument, 0, 0}, {"infile", required_argument, 0, 'I'}, {"israeli", no_argument, 0, 'i'}, {"latitude", required_argument, 0, 'l'}, {"lang", required_argument, 0, 0}, {"longitude", required_argument, 0, 'L'}, {"molad", no_argument, 0, 'M'}, {"no-holidays", no_argument, 0, 'h'}, {"no-modern", no_argument, 0, 0}, {"no-rosh-chodesh", no_argument, 0, 'x'}, {"omer", no_argument, 0, 'o'}, {"sedrot", no_argument, 0, 's'}, {"sunrise-and-sunset", no_argument, 0, 'O'}, {"tabs", no_argument, 0, 'r'}, {"timezone", required_argument, 0, 'z'}, {"today", no_argument, 0, 't'}, {"today-brief", no_argument, 0, 'T'}, {"version", no_argument, 0, 0}, {"weekday", no_argument, 0, 'w'}, {"yahrtzeit", required_argument, 0, 'Y'}, {"years", required_argument, 0, 0}, {"year-abbrev", no_argument, 0, 'y'}, {"zmanim", no_argument, 0, 'Z'}, {NULL, 0, NULL, 0} }; int c; int option_index = 0; setDate(&greg_today); /* keep the current greg. date here */ while ((c = getopt_long(argc, argv, "ab:cC:dDeEFhHI:il:L:m:MoOrsStTwWxyY:z:Z8", long_options, &option_index)) != -1) { switch (c) { case 0: /* long option without short alias */ if (0 == strcmp("version", long_options[option_index].name)) { version_sw = 1; } else if (0 == strcmp("help", long_options[option_index].name)) { help_sw = 1; } else if (0 == strcmp("lang", long_options[option_index].name)) { langStr = strdup(optarg); } else if (0 == strcmp("years", long_options[option_index].name)) { if (!(sscanf(optarg, "%d", &numYears) == 1)) { die("unable to read --years argument: %s", optarg); } } else if (0 == strcmp("no-modern", long_options[option_index].name)) { suppressModern_sw = 1; } else { shortUsage(); exit(1); } break; case 'a': ashkenazis_sw = 1; break; case '8': utf8_hebrew_sw = 1; break; case 'b': /* candle_lighting_minutes_before_sundown */ if (!(sscanf(optarg, "%d", &light_offset) == 1)) die("unable to read candle_lighting_minutes_before_sundown argument: %s", optarg); break; case 'c': /* calculate candlelighting times on fridays */ candleLighting_sw = 1; break; case 'C': cityNameArg = strdup(optarg); break; case 'd': /* print hebrew date */ printHebDates_sw = 1; break; case 'D': /* print hebrew date when there's */ /* something else to print */ printSomeHebDates_sw = 1; break; case 'I': /* input file */ inFileName = strdup(optarg); break; case 'e': /* european date format */ euroDates_sw = 1; break; case 'E': /* 24-hour time format */ twentyFourHour_sw = 1; break; case 'F': /* Daf Yomi */ dafYomi_sw = 1; break; case 'h': /* suppress internal holidays */ noHolidays_sw = 1; break; case 'H': /* suppress use hebrew range dates */ hebrewDates_sw = 1; break; case 'i': /* use Israeli sedra scheme */ israel_sw = 1; break; case 'l': /* latitude */ latitudeStr = strdup(optarg); break; case 'L': /* longitude */ longitudeStr = strdup(optarg); break; case 'm': /* havdalah_minutes */ if (!(sscanf(optarg, "%d", &havdalah_minutes) == 1)) die("unable to read havdalah_minutes argument: %s", optarg); break; case 'M': /* print the molad */ printMolad_sw = 1; break; case 'o': /* print the omer */ printOmer_sw = 1; break; case 'O': /* print sunrise and sunset */ printSunriseSunset_sw = 1; break; case 'r': /* Tab-delineated Format */ tabs_sw = 1; break; case 's': /* print sedrot */ sedrot_sw = 1; break; case 'S': /* print sedra every day. */ sedraAllWeek_sw = 1; break; case 'T': /* do hebcal for today, omit gregorian date. */ noGreg_sw = 1; break; case 't': /* do hebcal for today. */ today_sw = 1; break; case 'w': /* print days of the week */ weekday_sw = 1; break; case 'W': /* abbreviated week view */ abbrev_sw = 1; break; case 'y': /* Print only last 2 digits of year */ yearDigits_sw = 1; break; case 'Y': /* input file */ yahrtzeitFileName = strdup(optarg); break; case 'x': /* input file */ suppress_rosh_chodesh_sw = 1; break; case 'z': /* time zone */ tzid = strdup(optarg); break; case 'Z': zemanim_sw = 1; break; default: shortUsage(); exit(1); break; } } if (langStr != NULL) { hebcal_lang lang = hebcal_get_language(langStr); if (lang == HEBCAL_LANG_UNDEFINED) { warn("Unknown lang '%s'; using default", langStr); } else { hebcal_set_language(lang); } free(langStr); } else if (ashkenazis_sw) { hebcal_set_language(HEBCAL_LANG_ASHKENAZI); } else if (utf8_hebrew_sw) { hebcal_set_language(HEBCAL_LANG_HE); } else { hebcal_set_language(HEBCAL_LANG_DEFAULT); } if (help_sw) { displayHelp(); exit(0); } if (version_sw) { printf("Hebcal version %s\n", VERSION); exit(0); } errno = 0; if (light_offset > 0) { light_offset *= -1; } if (cityNameArg != NULL) { candleLighting_sw = 1; localize_to_city(cityNameArg); free(cityNameArg); } if (inFileName != NULL) { inputFile_sw = 1; if (!(inFile = fopen(inFileName, "r"))) { die("could not open input file %s.", inFileName); } free(inFileName); } if (noGreg_sw) { today_sw = 1; } if (today_sw) { printHebDates_sw = 1; rangeType = TODAY; theMonth = greg_today.mm; /* year and month specified */ theDay = greg_today.dd; /* printc theDay of theMonth */ yearDirty = 1; printOmer_sw = 1; } if (yahrtzeitFileName != NULL) { yahrtzeitFile_sw = 1; if (!(yFile = fopen(yahrtzeitFileName, "r"))) { die("could not open yahrtzeit input file %s.", yahrtzeitFileName); } free(yahrtzeitFileName); } if (latitudeStr != NULL) { if (sscanf(latitudeStr, "%d,%d", &latdeg, &latmin) < 2) { die("unable to read latitude argument: %s", latitudeStr); } latp = 1; if ((abs(latdeg) > 90) || latmin > 60 || latmin < 0) { die("Error, latitude argument out of range: %s", latitudeStr); } latmin = abs(latmin); if (latdeg < 0) { latmin = -latmin; } free(latitudeStr); } if (longitudeStr != NULL) { if (sscanf(longitudeStr, "%d,%d", &longdeg, &longmin) < 2) { die("unable to read longitude argument: %s", longitudeStr); } longp = 1; if ((abs(longdeg) > 180) || longmin > 60 || longmin < 0) { die("Error, longitude argument out of range: %s", longitudeStr); } longmin = abs(longmin); if (longdeg < 0) { longmin = -longmin; } free(longitudeStr); } if (tzid != NULL) { TZ_INFO = timelib_parse_tzfile(tzid, timelib_builtin_db()); if (TZ_INFO == NULL) { die("unable to read time zone argument: %s", tzid); } free(tzid); } if (zemanim_sw) { default_zemanim = (ZMAN_SUNRISE | ZMAN_SZKS | ZMAN_TEFILAH | ZMAN_CHATZOT | ZMAN_MINCHA_GEDOLA | ZMAN_MINCHA_KETANA | ZMAN_PLAG_HAMINCHA | ZMAN_SUNSET | ZMAN_TZAIT_42); } if (latp) cityName = "User Defined City"; if (latp ^ longp) die("You must enter BOTH the latitude and the longitude", ""); if( !strcmp(cityName, "Jerusalem" )) light_offset = -40; /* does everyone hold by this? */ remain_count = argc - optind; remain = argv + optind; switch (remain_count) /* suck up the date */ { case 0: /* process this year */ if (hebrewDates_sw) theYear = abs2hebrew(greg2abs(greg_today)).yy; else theYear = greg_today.yy; break; case 1: if (isAllNums(remain[0])) { theYear = atoi(remain[0]); /* just year specified */ yearDirty = 1; /* print whole year */ } else if (0 == istrncasecmp(5, remain[0], "help")) { displayHelp(); exit(0); } else if (0 == istrncasecmp(3, remain[0], "info")) { print_version_data(); exit(0); } else if (0 == istrncasecmp(3, remain[0], "cities")) { print_city_data(); exit(0); } else if (0 == istrncasecmp(3, remain[0], "copying")) { print_copying(); exit(0); } else if (0 == istrncasecmp(3, remain[0], "warranty")) { print_warranty(); exit(0); } else { printf("%s: unrecognized command '%s'\n", progname, remain[0]); shortUsage(); exit(1); } break; case 2: if (!isAllNums(remain[1])) { shortUsage(); exit(1); } theYear = atoi(remain[1]); /* print theMonth of theYear */ theMonth = lookup_hebrew_month(remain[0]); if (theMonth) { hebrewDates_sw = 1; /* automagically turn it on */ if (theMonth == ADAR_II && !LEAP_YR_HEB(theYear)) { theMonth = ADAR_I; /* silently fix this mistake */ } } else if (isAllNums(remain[0])) { if (hebrewDates_sw) { die("Don't use numbers to specify Hebrew months.", ""); } else { theMonth = atoi(remain[0]); /* gregorian month */ } } else if (hebrewDates_sw) { die("Unknown Hebrew month: %s", remain[0]); } else { die("bad gregorian month: %s", remain[0]); } yearDirty = 1; rangeType = MONTH; break; case 3: if (!(isAllNums(remain[1]) && isAllNums(remain[2]))) { shortUsage(); exit(1); } theDay = atoi(remain[1]); /* print theDay of theMonth */ theYear = atoi(remain[2]); /* print theMonth of theYear */ theMonth = lookup_hebrew_month(remain[0]); if (theMonth) { hebrewDates_sw = 1; /* automagically turn it on */ if (theMonth == ADAR_II && !LEAP_YR_HEB(theYear)) { theMonth = ADAR_I; /* silently fix this mistake */ } } else if (isAllNums(remain[0])) { if (hebrewDates_sw) { die("Don't use numbers to specify Hebrew months.", ""); } else { theMonth = atoi(remain[0]); /* gregorian month */ } } else if (hebrewDates_sw) { die("Unknown Hebrew month: %s", remain[0]); } else { die("bad gregorian month: %s", remain[0]); } if (theDay < 1) die("The day of the month must be greater than 0", ""); if (theMonth < 1) die("The month must be greater than 0", ""); if (hebrewDates_sw) { if (theDay > max_days_in_heb_month(theMonth, theYear)) die("Sorry, there aren't that many days in %s (then)", LANGUAGE2(hMonths[LEAP_YR_HEB(theYear)][theMonth].name)); } else { if (theMonth > 12) die("The month must be less than 13", ""); if (theDay > MonthLengths[LEAP(theYear)][theMonth]) die("Sorry, there aren't that many days in %s (then)", eMonths[theMonth]); } rangeType = DAY; yearDirty = 1; break; default: displayHelp(); exit(1); } if (numYears != 1 && rangeType != YEAR) { die("Sorry, --years option works only with entire-year calendars", ""); } }
void init_yahrtzeits( int hyear ) { holstorep_t tmpholp; char *s, *monthStr, *eventStr, nextChar; int index, inMonth, inDay, inYear, lineNum = 1; date_t hDeath, gDeath; initStr (&s, MAX_LINE_LEN); initStr (&monthStr, MAX_LINE_LEN); rewind (yFile); nextChar = (char) getc (yFile); /* priming getc */ for (; !feof (yFile); lineNum++, nextChar = (char) getc (yFile)) { /* force an EOF */ ungetc (nextChar, yFile); if (!fgets (s, MAX_LINE_LEN, yFile)) { warn ("yahrtzeit file read error. Skipping line %s", hc_itoa (lineNum)); continue; } if (s[0] == '\n') /* blank line */ continue; if (sscanf (s, "%s %d %d%n", monthStr, &inDay, &inYear, &index) < 3) { warn ("Error in yahrtzeit file. Skipping line %s", hc_itoa (lineNum)); continue; } if (!isAllNums (monthStr)) { warn ("Non-numeric month in yahrtzeit file. Skipping line %s", hc_itoa (lineNum)); continue; } sscanf (monthStr, "%d", &inMonth); if (inMonth > 12 || inMonth < 1 || inDay < 1 || inDay > MonthLengths[LEAP (inYear)][inMonth]) { warn ("Date out of range in yahrtzeit file. Skipping line %s", hc_itoa (lineNum)); continue; } gDeath.dd = inDay; gDeath.mm = inMonth; gDeath.yy = inYear; hDeath = abs2hebrew (greg2abs (gDeath)); /* If it's Heshvan 30 it depends on the first anniversary; if that was not Heshvan 30, use the day before Kislev 1. */ if (hDeath.mm == CHESHVAN && hDeath.dd == 30 && !long_cheshvan (hDeath.yy + 1)) { hDeath.dd = 1; hDeath.mm = KISLEV; hDeath.yy = hyear; hDeath = abs2hebrew (hebrew2abs (hDeath) - 1L); } /* If it's Kislev 30 it depends on the first anniversary; if that was not Kislev 30, use the day before Teveth 1. */ else if (hDeath.mm == KISLEV && hDeath.dd == 30 && !short_kislev (hDeath.yy + 1)) { hDeath.dd = 1; hDeath.mm = TEVET; hDeath.yy = hyear; hDeath = abs2hebrew (hebrew2abs (hDeath) - 1L); } /* If it's Adar II, use the same day in last month of year (Adar or Adar II). */ else if (hDeath.mm == ADAR_II) { hDeath.mm = MONTHS_IN_HEB (hyear); } /* If it's the 30th in Adar I and year is not a leap year (so Adar has only 29 days), use the last day in Shevat. */ else if (hDeath.mm == ADAR_I && hDeath.dd == 30 && !LEAP_YR_HEB (hyear)) { hDeath.dd = 30; hDeath.mm = SHVAT; } /* In all other cases, use the normal anniversary of the date of death. */ /* advance day to rosh chodesh if needed */ if (hDeath.mm == CHESHVAN && hDeath.dd == 30 && !long_cheshvan(hyear)) { hDeath.mm = KISLEV; hDeath.dd = 1; } else if (hDeath.mm == KISLEV && hDeath.dd == 30 && short_kislev(hyear)) { hDeath.mm = TEVET; hDeath.dd = 1; } eventStr = s + index + 1; /* get the name of the event */ /* if (eventStr[strlen(eventStr)-1] == '\n') */ eventStr[strlen (eventStr) - 1] = '\0'; /* chop off the \n */ /* store the holiday in the LUT */ tmpholp = getHolstorep (); initStr (&tmpholp->name, MAX_LINE_LEN); strcpy (tmpholp->name, eventStr); /* load the user holiday into it. */ tmpholp->typeMask = USER_EVENT; PushHoliday (tmpholp, &var_holidays[hDeath.mm][hDeath.dd]); } }
SEXP make_dt(SEXP year, SEXP month, SEXP day, SEXP hour, SEXP minute, SEXP second) { if(!isInteger(year)) error("year must be integer"); if(!isInteger(month)) error("month must be integer"); if(!isInteger(day)) error("day must be integer"); if(!isInteger(hour)) error("hour must be integer"); if(!isInteger(minute)) error("minute must be integer"); if(!isNumeric(second)) error("second must be numeric"); R_len_t n = LENGTH(year); if(n != LENGTH(month)) error("length of 'month' vector is not the same as that of 'year'"); if(n != LENGTH(day)) error("length of 'day' vector is not the same as that of 'year'"); if(n != LENGTH(hour)) error("length of 'hour' vector is not the same as that of 'year'"); if(n != LENGTH(minute)) error("length of 'minute' vector is not the same as that of 'year'"); if(n != LENGTH(second)) error("length of 'second' vector is not the same as that of 'year'"); int* pyear = INTEGER(year); int* pmonth = INTEGER(month); int* pday = INTEGER(day); int* phour = INTEGER(hour); int* pminute = INTEGER(minute); int int_second = TYPEOF(second) == INTSXP; SEXP res = allocVector(REALSXP, n); double *data = REAL(res); for(int i = 0; i < n; i++) { // main accumulator double SECS = 0.0; int y = pyear[i]; int m = pmonth[i]; int d = pday[i]; int H = phour[i]; int M = pminute[i]; int naS; double S; if(int_second){ S = (double) INTEGER(second)[i]; naS = INTEGER(second)[i] == NA_INTEGER; } else { S = REAL(second)[i]; naS = ISNA(S); } if(naS || y == NA_INTEGER || m == NA_INTEGER || d == NA_INTEGER || H == NA_INTEGER || M == NA_INTEGER) { data[i] = NA_REAL; } else { if ( 0 < m && m < 13 ) SECS += sm[m]; else { data[i] = NA_REAL; continue; } if ( 0 < d && d < 32 ) SECS += (d - 1) * 86400; else { data[i] = NA_REAL; continue; } if( H < 25 ) SECS += H * 3600; else { data[i] = NA_REAL; continue; } if ( M < 61 ) SECS += M * 60; else{ data[i] = NA_REAL; continue; } // allow leap seconds if ( S < 62 ) { SECS += S; } else { data[i] = NA_REAL; continue; } int is_leap = LEAP(y); if(check_ymd(y, m, d, is_leap)){ SECS += d30; y -= 2000; SECS += y * yearlen; SECS += adjust_leap_years(y, m, is_leap); data[i] = SECS; } else { data[i] = NA_REAL; } } } return res; }
/* FIX: this wants to become gnu-ish */ void handleArgs(int argc, char *argv[]) { char dummy[10]; date_t greg_today; int option; char *usage = /* not quite sure how compatible this is */ "usage: \n\ hebcal [-acdDehHiMoOrsStTwxy]\n\ [-b candle_lighting_minutes_before_sundown]\n\ [-I input_file]\n\ [-Y yahrtzeit_file]\n\ [-C city]\n\ [-L longitude -l latitude]\n\ [-m havdalah_minutes]\n\ [-z timezone]\n\ [-Z daylight_savings_scheme]\n\ [[month [day]] year]\n\ hebcal help\n\ hebcal info\n\ hebcal DST\n\ hebcal cities\n\ hebcal warranty\n\ hebcal copying\n"; setDate(&greg_today); /* keep the current greg. date here */ Getopt(argc, argv, "", 1); while (EOF != (option = Getopt(argc, argv, "ab:cC:dDeFf:hHI:il:L:m:MoOrsStTwxyY:z:Z:8", 0))) { switch ((char) option) { case 'a': /* ashkenazis hebrew */ ashkenazis_sw = 1; break; case '8': /* ashkenazis hebrew */ iso8859_8_sw = 1; break; case 'b': /* candle_lighting_minutes_before_sundown */ if (!(sscanf(Optarg, "%d", &light_offset) == 1)) die("unable to read candle_lighting_minutes_before_sundown argument: %s", Optarg); light_offset *= -1; break; case 'c': /* calculate candlelighting times on fridays */ candleLighting_sw = 1; break; case 'C': localize_to_city(Optarg); candleLighting_sw = 1; break; case 'd': /* print hebrew date */ printHebDates_sw = 1; break; case 'D': /* print hebrew date when there's */ /* something else to print */ printSomeHebDates_sw = 1; break; case 'I': /* input file */ inputFile_sw = 1; if (!(inFile = fopen(Optarg, "r"))) die("could not open input file %s.", Optarg); break; case 'e': /* european date format */ euroDates_sw = 1; break; case 'f': /* output format */ formatString = strdup(Optarg); break; case 'F': /* Daf Yomi */ dafYomi_sw = 1; break; case 'h': /* suppress internal holidays */ noHolidays_sw = 1; break; case 'H': /* suppress use hebrew range dates */ hebrewDates_sw = 1; break; case 'i': /* use Israeli sedra scheme */ israel_sw = 1; break; case 'l': /* latitude */ latdeg = latmin = 0; latp = 1; if (sscanf(Optarg, "%d,%d", &latdeg, &latmin) < 2) die("unable to read latitude argument: %s", Optarg); if ((abs(latdeg) > 90) || latmin > 60 || latmin < 0) die("latitude argument out of range", ""); latmin = abs(latmin); if (latdeg < 0) latmin = -latmin; break; case 'L': /* longitude */ longdeg = longmin = 0; longp = 1; if (sscanf(Optarg, "%d,%d", &longdeg, &longmin) < 2) die("unable to read longitude argument: %s", Optarg); if ((abs(longdeg) > 180) || longmin > 60 || longmin < 0) die("longitude argument out of range", ""); longmin = abs(longmin); if (longdeg < 0) longmin = -longmin; break; case 'm': /* havdalah_minutes */ if (!(sscanf(Optarg, "%d", &havdalah_minutes) == 1)) die("unable to read havdalah_minutes argument: %s", Optarg); break; case 'M': /* print the molad */ printMolad_sw = 1; break; case 'o': /* print the omer */ printOmer_sw = 1; break; case 'O': /* print sunrise and sunset */ printSunriseSunset_sw = 1; break; case 'r': /* Tab-delineated Format */ tabs_sw = 1; break; case 's': /* print sedrot */ sedrot_sw = 1; break; case 'S': /* print sedra every day. */ sedraAllWeek_sw = 1; break; case 'T': /* do hebcal for today, omit gregorian date. */ noGreg_sw = 1; /*** note this falls through to 't' case ***/ case 't': /* do hebcal for today. */ printHebDates_sw = 1; rangeType = TODAY; theMonth = greg_today.mm; /* year and month specified */ theDay = greg_today.dd; /* printc theDay of theMonth */ yearDirty = 1; printOmer_sw = 1; break; case 'w': /* print days of the week */ weekday_sw = 1; break; case 'y': /* Print only last 2 digits of year */ yearDigits_sw = 1; break; case 'Y': /* input file */ yahrtzeitFile_sw = 1; if (!(yFile = fopen(Optarg, "r"))) die("could not open yahrtzeit input file %s.", Optarg); break; case 'x': /* input file */ suppress_rosh_chodesh_sw = 1; break; case 'Z': schemep = 1; sscanf(Optarg, "%s", dummy); set_DST_scheme(dummy); break; case 'z': /* time zone */ if (!(sscanf(Optarg, "%d", &TZ) == 1)) die("unable to read time zone argument: %s", Optarg); if (!schemep) DST_scheme = DST_NONE; zonep = 1; break; default: die(usage, ""); } } if (latp) cityName = "User Defined City"; if (latp ^ longp) die("You must enter BOTH the latitude and the longitude", ""); if( !strcmp(cityName, "Jerusalem" )) light_offset = -40; /* does everyone hold by this? */ switch (argc - Optind) /* suck up the date */ { case 0: /* process this year */ if (hebrewDates_sw) theYear = abs2hebrew(greg2abs(greg_today)).yy; else theYear = greg_today.yy; break; case 1: if (isAllNums(argv[Optind])) { theYear = atoi(argv[Optind]); /* just year specified */ yearDirty = 1; /* print whole year */ } else if (0 == istrncasecmp(5, argv[Optind], "help")) { size_t lineNumber; for (lineNumber = 0; (lineNumber < sizeof(helpArray) / sizeof(char *)); lineNumber++) { puts(helpArray[lineNumber]); } exit(0); } else if (0 == istrncasecmp(3, argv[Optind], "info")) { print_version_data(); exit(0); } else if (0 == istrncasecmp(3, argv[Optind], "cities")) { print_city_data(); exit(0); } else if (0 == istrncasecmp(3, argv[Optind], "DST")) { print_DST_data(); exit(0); } else if (0 == istrncasecmp(3, argv[Optind], "copying")) { print_copying(); exit(0); } else if (0 == istrncasecmp(3, argv[Optind], "warranty")) { print_warranty(); exit(0); } else die(usage, ""); break; case 2: if (!isAllNums(argv[Optind + 1])) die(usage, ""); theYear = atoi(argv[Optind + 1]); /* print theMonth of theYear */ theMonth = lookup_hebrew_month(argv[Optind]); if (theMonth) { hebrewDates_sw = 1; /* automagically turn it on */ if (theMonth == ADAR_II && !LEAP_YR_HEB(theYear)) theMonth = ADAR_I; /* silently fix this mistake */ } else if (isAllNums(argv[Optind])) if (hebrewDates_sw) die("Don't use numbers to specify hebrew months.", ""); else theMonth = atoi(argv[Optind]); /* gregorian month */ else if (hebrewDates_sw) die("Unknown hebrew month: %s", argv[Optind]); else die(usage, ""); /* bad gregorian month. */ Optind++; yearDirty = 1; rangeType = MONTH; break; case 3: if (!(isAllNums(argv[Optind + 1]) && isAllNums(argv[Optind + 2]))) die(usage, ""); theDay = atoi(argv[Optind + 1]); /* print theDay of theMonth */ theYear = atoi(argv[Optind + 2]); /* print theMonth of theYear */ theMonth = lookup_hebrew_month(argv[Optind]); if (theMonth) { hebrewDates_sw = 1; /* automagically turn it on */ if (theMonth == ADAR_II && !LEAP_YR_HEB(theYear)) theMonth = ADAR_I; /* silently fix this mistake */ } else if (isAllNums(argv[Optind])) if (hebrewDates_sw) die("Don't use numbers to specify hebrew months.", ""); else theMonth = atoi(argv[Optind]); /* gregorian month */ else if (hebrewDates_sw) die("Unknown hebrew month: %s", argv[Optind]); else die("bad month.%s", usage); /* bad gregorian month. */ if (theDay < 1) die("The day of the month must be greater than 0", ""); if (theMonth < 1) die("The month must be greater than 0", ""); if (hebrewDates_sw) { if (theDay > max_days_in_heb_month(theMonth, theYear)) die("Sorry, there aren't that many days in %s (then)", LANGUAGE2(hMonths[LEAP_YR_HEB(theYear)][theMonth].name)); } else { if (theMonth > 12) die("The month must be less than 13", ""); if (theDay > MonthLengths[LEAP(theYear)][theMonth]) die("Sorry, there aren't that many days in %s (then)", eMonths[theMonth]); } rangeType = DAY; yearDirty = 1; break; default: die(usage, ""); } }