timelib_tzinfo* TimeZone::GetTimeZoneInfoRaw(char* name, const timelib_tzdb* db) { auto const it = s_tzCache->find(name); if (it != s_tzCache->end()) { return it->second; } auto tzi = timelib_parse_tzfile(name, db); if (!tzi) { char* tzid = timelib_timezone_id_from_abbr(name, -1, 0); if (tzid) { tzi = timelib_parse_tzfile(tzid, db); } } if (tzi) { auto key = strdup(name); auto result = s_tzCache->insert(TimeZoneCacheEntry(key, tzi)); if (!result.second) { // The cache should never fill up since tzinfos are finite. always_assert(result.first != s_tzCache->end()); // A collision occurred, so we don't need our strdup'ed key. free(key); timelib_tzinfo_dtor(tzi); tzi = result.first->second; } } return tzi; }
TEST(issues, issue0051_test2) { char str1[] = "2018-11-22 13:27:52"; char str2[] = "2018-11-22 13:27:52.089635"; timelib_time *t1 = timelib_strtotime(str1, sizeof(str1), NULL, timelib_builtin_db(), timelib_parse_tzfile); timelib_time *t2 = timelib_strtotime(str2, sizeof(str2), NULL, timelib_builtin_db(), timelib_parse_tzfile); int dummy_error; timelib_tzinfo *tzi; timelib_rel_time *diff; tzi = timelib_parse_tzfile((char*) "UTC", timelib_builtin_db(), &dummy_error); timelib_update_ts(t1, tzi); timelib_update_ts(t2, tzi); diff = timelib_diff(t1, t2); LONGS_EQUAL(0, diff->s); LONGS_EQUAL(89635, diff->us); LONGS_EQUAL(0, diff->invert); timelib_time_dtor(t1); timelib_time_dtor(t2); timelib_rel_time_dtor(diff); timelib_tzinfo_dtor(tzi); }
TEST(issues, issue0050_test2) { char str1[] = "2018-10-11 20:59:06.237419"; char str2[] = "2018-10-11 20:59:06.914653"; timelib_time *t1 = timelib_strtotime(str1, sizeof(str1), NULL, timelib_builtin_db(), timelib_parse_tzfile); timelib_time *t2 = timelib_strtotime(str2, sizeof(str2), NULL, timelib_builtin_db(), timelib_parse_tzfile); int dummy_error; timelib_tzinfo *tzi; timelib_rel_time *diff; tzi = timelib_parse_tzfile((char*) "UTC", timelib_builtin_db(), &dummy_error); timelib_update_ts(t1, tzi); timelib_update_ts(t2, tzi); diff = timelib_diff(t1, t2); LONGS_EQUAL(0, diff->s); LONGS_EQUAL(677234, diff->us); timelib_time_dtor(t1); timelib_time_dtor(t2); timelib_rel_time_dtor(diff); timelib_tzinfo_dtor(tzi); }
TimeZoneInfo TimeZone::GetTimeZoneInfo(char* name, const timelib_tzdb* db) { MapStringToTimeZoneInfo &Cache = s_timezone_data->Cache; MapStringToTimeZoneInfo::const_iterator iter = Cache.find(name); if (iter != Cache.end()) { return iter->second; } TimeZoneInfo tzi(timelib_parse_tzfile(name, db), tzinfo_deleter()); if (tzi) { Cache[name] = tzi; } return tzi; }
/* Test for no transitions */ TEST(issues, issue0065_test1) { int dummy_error; timelib_tzinfo *tzi; timelib_time_offset *offset; tzi = timelib_parse_tzfile((char*) "Etc/Gmt+5", timelib_builtin_db(), &dummy_error); offset = timelib_get_time_zone_info(-1822500432, tzi); LONGS_EQUAL(INT64_MIN, offset->transition_time); timelib_time_offset_dtor(offset); timelib_tzinfo_dtor(tzi); }
TimeZoneInfo TimeZone::GetTimeZoneInfo(CStrRef name) { MapStringToTimeZoneInfo &Cache = s_timezone_data->Cache; MapStringToTimeZoneInfo::const_iterator iter = Cache.find(name.data()); if (iter != Cache.end()) { return iter->second; } TimeZoneInfo tzi(timelib_parse_tzfile((char *)name.data(), GetDatabase()), tzinfo_deleter()); if (tzi) { Cache[name.data()] = tzi; } return tzi; }
TEST(issues, issue0053_test3) { int dummy_error; timelib_tzinfo *tzi; timelib_sll ts = -1822500432; timelib_time *t = timelib_time_ctor(); tzi = timelib_parse_tzfile((char*) "America/Belize", timelib_builtin_db(), &dummy_error); t->tz_info = tzi; t->zone_type = TIMELIB_ZONETYPE_ID; timelib_unixtime2local(t, ts); LONGS_EQUAL(-21600, t->z); timelib_time_dtor(t); timelib_tzinfo_dtor(tzi); }
/* Test for offset from time before first transition */ TEST(issues, issue0065_test2) { int dummy_error; timelib_tzinfo *tzi; timelib_time_offset *offset; tzi = timelib_parse_tzfile((char*) "Europe/London", timelib_builtin_db(), &dummy_error); offset = timelib_get_time_zone_info(-3852662326, tzi); LONGS_EQUAL(INT64_MIN, offset->transition_time); timelib_time_offset_dtor(offset); offset = timelib_get_time_zone_info(-3852662325, tzi); LONGS_EQUAL(-3852662325, offset->transition_time); timelib_time_offset_dtor(offset); timelib_tzinfo_dtor(tzi); }
void localize_to_city(const char *cityNameArg) { size_t len = strlen(cityNameArg); char *pc, *cityStr; city_t *pcity; initStr(&cityStr, strlen(cityNameArg)); strcpy(cityStr, cityNameArg); if (cityName != NULL) free(cityName); /* convert non-alpha to spaces */ for ( pc = cityStr; *pc != '\0'; pc++ ) if ( ! isalpha( (int)*pc ) ) *pc = ' '; for (pcity = &cities[0]; pcity->name != NULL; pcity++) if (0 == istrncasecmp(len, cityStr, pcity->name)) { if (!(longp || latp)) /* -l and -L override -C */ { latdeg = pcity->latdeg; latmin = pcity->latmin; longdeg = pcity->longdeg; longmin = pcity->longmin; } TZ_INFO = timelib_parse_tzfile(pcity->tz, timelib_builtin_db()); if (TZ_INFO == NULL) { die("unable to read time zone argument: %s", pcity->tz); } free(cityStr); initStr(&cityName, strlen(pcity->name)); strcpy(cityName, pcity->name); return; } warn("unknown city: %s. Use a nearby city or geographic coordinates.", cityNameArg); warn("run 'hebcal cities' for a list of cities.", ""); ok_to_run = 0; }
TEST(issues, issue0035_test2) { int dummy_error; timelib_tzinfo *tzi; char str[] = "2017-12-31 23:59:59.999999 +2 microsecond"; timelib_time *t = timelib_strtotime(str, sizeof(str), NULL, timelib_builtin_db(), timelib_parse_tzfile); tzi = timelib_parse_tzfile((char*) "UTC", timelib_builtin_db(), &dummy_error); timelib_update_ts(t, tzi); LONGS_EQUAL(2018, t->y); LONGS_EQUAL(1, t->m); LONGS_EQUAL(1, t->d); LONGS_EQUAL(0, t->h); LONGS_EQUAL(0, t->i); LONGS_EQUAL(0, t->s); LONGS_EQUAL(1, t->us); timelib_time_dtor(t); timelib_tzinfo_dtor(tzi); }
TEST(issues, issue0053_test1) { int dummy_error; timelib_tzinfo *tzi; timelib_sll ts = -61626506832; timelib_time *t = timelib_time_ctor(); tzi = timelib_parse_tzfile((char*) "America/Belize", timelib_builtin_db(), &dummy_error); t->tz_info = tzi; t->zone_type = TIMELIB_ZONETYPE_ID; timelib_unixtime2local(t, ts); LONGS_EQUAL(17, t->y); LONGS_EQUAL(2, t->m); LONGS_EQUAL(18, t->d); LONGS_EQUAL(0, t->h); LONGS_EQUAL(0, t->i); LONGS_EQUAL(0, t->s); LONGS_EQUAL(-21168, t->z); timelib_time_dtor(t); timelib_tzinfo_dtor(tzi); }
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", ""); } }