00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "absl/time/internal/cctz/include/cctz/time_zone.h"
00016
00017 #include <chrono>
00018 #include <cstddef>
00019 #include <cstdlib>
00020 #include <future>
00021 #include <limits>
00022 #include <string>
00023 #include <thread>
00024 #include <vector>
00025
00026 #include "absl/time/internal/cctz/include/cctz/civil_time.h"
00027 #include "gtest/gtest.h"
00028
00029 namespace chrono = std::chrono;
00030
00031 namespace absl {
00032 namespace time_internal {
00033 namespace cctz {
00034
00035 namespace {
00036
00037
00038 const char* const kTimeZoneNames[] = {
00039 "Africa/Abidjan",
00040 "Africa/Accra",
00041 "Africa/Addis_Ababa",
00042 "Africa/Algiers",
00043 "Africa/Asmara",
00044 "Africa/Asmera",
00045 "Africa/Bamako",
00046 "Africa/Bangui",
00047 "Africa/Banjul",
00048 "Africa/Bissau",
00049 "Africa/Blantyre",
00050 "Africa/Brazzaville",
00051 "Africa/Bujumbura",
00052 "Africa/Cairo",
00053 "Africa/Casablanca",
00054 "Africa/Ceuta",
00055 "Africa/Conakry",
00056 "Africa/Dakar",
00057 "Africa/Dar_es_Salaam",
00058 "Africa/Djibouti",
00059 "Africa/Douala",
00060 "Africa/El_Aaiun",
00061 "Africa/Freetown",
00062 "Africa/Gaborone",
00063 "Africa/Harare",
00064 "Africa/Johannesburg",
00065 "Africa/Juba",
00066 "Africa/Kampala",
00067 "Africa/Khartoum",
00068 "Africa/Kigali",
00069 "Africa/Kinshasa",
00070 "Africa/Lagos",
00071 "Africa/Libreville",
00072 "Africa/Lome",
00073 "Africa/Luanda",
00074 "Africa/Lubumbashi",
00075 "Africa/Lusaka",
00076 "Africa/Malabo",
00077 "Africa/Maputo",
00078 "Africa/Maseru",
00079 "Africa/Mbabane",
00080 "Africa/Mogadishu",
00081 "Africa/Monrovia",
00082 "Africa/Nairobi",
00083 "Africa/Ndjamena",
00084 "Africa/Niamey",
00085 "Africa/Nouakchott",
00086 "Africa/Ouagadougou",
00087 "Africa/Porto-Novo",
00088 "Africa/Sao_Tome",
00089 "Africa/Timbuktu",
00090 "Africa/Tripoli",
00091 "Africa/Tunis",
00092 "Africa/Windhoek",
00093 "America/Adak",
00094 "America/Anchorage",
00095 "America/Anguilla",
00096 "America/Antigua",
00097 "America/Araguaina",
00098 "America/Argentina/Buenos_Aires",
00099 "America/Argentina/Catamarca",
00100 "America/Argentina/ComodRivadavia",
00101 "America/Argentina/Cordoba",
00102 "America/Argentina/Jujuy",
00103 "America/Argentina/La_Rioja",
00104 "America/Argentina/Mendoza",
00105 "America/Argentina/Rio_Gallegos",
00106 "America/Argentina/Salta",
00107 "America/Argentina/San_Juan",
00108 "America/Argentina/San_Luis",
00109 "America/Argentina/Tucuman",
00110 "America/Argentina/Ushuaia",
00111 "America/Aruba",
00112 "America/Asuncion",
00113 "America/Atikokan",
00114 "America/Atka",
00115 "America/Bahia",
00116 "America/Bahia_Banderas",
00117 "America/Barbados",
00118 "America/Belem",
00119 "America/Belize",
00120 "America/Blanc-Sablon",
00121 "America/Boa_Vista",
00122 "America/Bogota",
00123 "America/Boise",
00124 "America/Buenos_Aires",
00125 "America/Cambridge_Bay",
00126 "America/Campo_Grande",
00127 "America/Cancun",
00128 "America/Caracas",
00129 "America/Catamarca",
00130 "America/Cayenne",
00131 "America/Cayman",
00132 "America/Chicago",
00133 "America/Chihuahua",
00134 "America/Coral_Harbour",
00135 "America/Cordoba",
00136 "America/Costa_Rica",
00137 "America/Creston",
00138 "America/Cuiaba",
00139 "America/Curacao",
00140 "America/Danmarkshavn",
00141 "America/Dawson",
00142 "America/Dawson_Creek",
00143 "America/Denver",
00144 "America/Detroit",
00145 "America/Dominica",
00146 "America/Edmonton",
00147 "America/Eirunepe",
00148 "America/El_Salvador",
00149 "America/Ensenada",
00150 "America/Fort_Nelson",
00151 "America/Fort_Wayne",
00152 "America/Fortaleza",
00153 "America/Glace_Bay",
00154 "America/Godthab",
00155 "America/Goose_Bay",
00156 "America/Grand_Turk",
00157 "America/Grenada",
00158 "America/Guadeloupe",
00159 "America/Guatemala",
00160 "America/Guayaquil",
00161 "America/Guyana",
00162 "America/Halifax",
00163 "America/Havana",
00164 "America/Hermosillo",
00165 "America/Indiana/Indianapolis",
00166 "America/Indiana/Knox",
00167 "America/Indiana/Marengo",
00168 "America/Indiana/Petersburg",
00169 "America/Indiana/Tell_City",
00170 "America/Indiana/Vevay",
00171 "America/Indiana/Vincennes",
00172 "America/Indiana/Winamac",
00173 "America/Indianapolis",
00174 "America/Inuvik",
00175 "America/Iqaluit",
00176 "America/Jamaica",
00177 "America/Jujuy",
00178 "America/Juneau",
00179 "America/Kentucky/Louisville",
00180 "America/Kentucky/Monticello",
00181 "America/Knox_IN",
00182 "America/Kralendijk",
00183 "America/La_Paz",
00184 "America/Lima",
00185 "America/Los_Angeles",
00186 "America/Louisville",
00187 "America/Lower_Princes",
00188 "America/Maceio",
00189 "America/Managua",
00190 "America/Manaus",
00191 "America/Marigot",
00192 "America/Martinique",
00193 "America/Matamoros",
00194 "America/Mazatlan",
00195 "America/Mendoza",
00196 "America/Menominee",
00197 "America/Merida",
00198 "America/Metlakatla",
00199 "America/Mexico_City",
00200 "America/Miquelon",
00201 "America/Moncton",
00202 "America/Monterrey",
00203 "America/Montevideo",
00204 "America/Montreal",
00205 "America/Montserrat",
00206 "America/Nassau",
00207 "America/New_York",
00208 "America/Nipigon",
00209 "America/Nome",
00210 "America/Noronha",
00211 "America/North_Dakota/Beulah",
00212 "America/North_Dakota/Center",
00213 "America/North_Dakota/New_Salem",
00214 "America/Ojinaga",
00215 "America/Panama",
00216 "America/Pangnirtung",
00217 "America/Paramaribo",
00218 "America/Phoenix",
00219 "America/Port-au-Prince",
00220 "America/Port_of_Spain",
00221 "America/Porto_Acre",
00222 "America/Porto_Velho",
00223 "America/Puerto_Rico",
00224 "America/Punta_Arenas",
00225 "America/Rainy_River",
00226 "America/Rankin_Inlet",
00227 "America/Recife",
00228 "America/Regina",
00229 "America/Resolute",
00230 "America/Rio_Branco",
00231 "America/Rosario",
00232 "America/Santa_Isabel",
00233 "America/Santarem",
00234 "America/Santiago",
00235 "America/Santo_Domingo",
00236 "America/Sao_Paulo",
00237 "America/Scoresbysund",
00238 "America/Shiprock",
00239 "America/Sitka",
00240 "America/St_Barthelemy",
00241 "America/St_Johns",
00242 "America/St_Kitts",
00243 "America/St_Lucia",
00244 "America/St_Thomas",
00245 "America/St_Vincent",
00246 "America/Swift_Current",
00247 "America/Tegucigalpa",
00248 "America/Thule",
00249 "America/Thunder_Bay",
00250 "America/Tijuana",
00251 "America/Toronto",
00252 "America/Tortola",
00253 "America/Vancouver",
00254 "America/Virgin",
00255 "America/Whitehorse",
00256 "America/Winnipeg",
00257 "America/Yakutat",
00258 "America/Yellowknife",
00259 "Antarctica/Casey",
00260 "Antarctica/Davis",
00261 "Antarctica/DumontDUrville",
00262 "Antarctica/Macquarie",
00263 "Antarctica/Mawson",
00264 "Antarctica/McMurdo",
00265 "Antarctica/Palmer",
00266 "Antarctica/Rothera",
00267 "Antarctica/South_Pole",
00268 "Antarctica/Syowa",
00269 "Antarctica/Troll",
00270 "Antarctica/Vostok",
00271 "Arctic/Longyearbyen",
00272 "Asia/Aden",
00273 "Asia/Almaty",
00274 "Asia/Amman",
00275 "Asia/Anadyr",
00276 "Asia/Aqtau",
00277 "Asia/Aqtobe",
00278 "Asia/Ashgabat",
00279 "Asia/Ashkhabad",
00280 "Asia/Atyrau",
00281 "Asia/Baghdad",
00282 "Asia/Bahrain",
00283 "Asia/Baku",
00284 "Asia/Bangkok",
00285 "Asia/Barnaul",
00286 "Asia/Beirut",
00287 "Asia/Bishkek",
00288 "Asia/Brunei",
00289 "Asia/Calcutta",
00290 "Asia/Chita",
00291 "Asia/Choibalsan",
00292 "Asia/Chongqing",
00293 "Asia/Chungking",
00294 "Asia/Colombo",
00295 "Asia/Dacca",
00296 "Asia/Damascus",
00297 "Asia/Dhaka",
00298 "Asia/Dili",
00299 "Asia/Dubai",
00300 "Asia/Dushanbe",
00301 "Asia/Famagusta",
00302 "Asia/Gaza",
00303 "Asia/Harbin",
00304 "Asia/Hebron",
00305 "Asia/Ho_Chi_Minh",
00306 "Asia/Hong_Kong",
00307 "Asia/Hovd",
00308 "Asia/Irkutsk",
00309 "Asia/Istanbul",
00310 "Asia/Jakarta",
00311 "Asia/Jayapura",
00312 "Asia/Jerusalem",
00313 "Asia/Kabul",
00314 "Asia/Kamchatka",
00315 "Asia/Karachi",
00316 "Asia/Kashgar",
00317 "Asia/Kathmandu",
00318 "Asia/Katmandu",
00319 "Asia/Khandyga",
00320 "Asia/Kolkata",
00321 "Asia/Krasnoyarsk",
00322 "Asia/Kuala_Lumpur",
00323 "Asia/Kuching",
00324 "Asia/Kuwait",
00325 "Asia/Macao",
00326 "Asia/Macau",
00327 "Asia/Magadan",
00328 "Asia/Makassar",
00329 "Asia/Manila",
00330 "Asia/Muscat",
00331 "Asia/Nicosia",
00332 "Asia/Novokuznetsk",
00333 "Asia/Novosibirsk",
00334 "Asia/Omsk",
00335 "Asia/Oral",
00336 "Asia/Phnom_Penh",
00337 "Asia/Pontianak",
00338 "Asia/Pyongyang",
00339 "Asia/Qatar",
00340 "Asia/Qostanay",
00341 "Asia/Qyzylorda",
00342 "Asia/Rangoon",
00343 "Asia/Riyadh",
00344 "Asia/Saigon",
00345 "Asia/Sakhalin",
00346 "Asia/Samarkand",
00347 "Asia/Seoul",
00348 "Asia/Shanghai",
00349 "Asia/Singapore",
00350 "Asia/Srednekolymsk",
00351 "Asia/Taipei",
00352 "Asia/Tashkent",
00353 "Asia/Tbilisi",
00354 "Asia/Tehran",
00355 "Asia/Tel_Aviv",
00356 "Asia/Thimbu",
00357 "Asia/Thimphu",
00358 "Asia/Tokyo",
00359 "Asia/Tomsk",
00360 "Asia/Ujung_Pandang",
00361 "Asia/Ulaanbaatar",
00362 "Asia/Ulan_Bator",
00363 "Asia/Urumqi",
00364 "Asia/Ust-Nera",
00365 "Asia/Vientiane",
00366 "Asia/Vladivostok",
00367 "Asia/Yakutsk",
00368 "Asia/Yangon",
00369 "Asia/Yekaterinburg",
00370 "Asia/Yerevan",
00371 "Atlantic/Azores",
00372 "Atlantic/Bermuda",
00373 "Atlantic/Canary",
00374 "Atlantic/Cape_Verde",
00375 "Atlantic/Faeroe",
00376 "Atlantic/Faroe",
00377 "Atlantic/Jan_Mayen",
00378 "Atlantic/Madeira",
00379 "Atlantic/Reykjavik",
00380 "Atlantic/South_Georgia",
00381 "Atlantic/St_Helena",
00382 "Atlantic/Stanley",
00383 "Australia/ACT",
00384 "Australia/Adelaide",
00385 "Australia/Brisbane",
00386 "Australia/Broken_Hill",
00387 "Australia/Canberra",
00388 "Australia/Currie",
00389 "Australia/Darwin",
00390 "Australia/Eucla",
00391 "Australia/Hobart",
00392 "Australia/LHI",
00393 "Australia/Lindeman",
00394 "Australia/Lord_Howe",
00395 "Australia/Melbourne",
00396 "Australia/NSW",
00397 "Australia/North",
00398 "Australia/Perth",
00399 "Australia/Queensland",
00400 "Australia/South",
00401 "Australia/Sydney",
00402 "Australia/Tasmania",
00403 "Australia/Victoria",
00404 "Australia/West",
00405 "Australia/Yancowinna",
00406 "Brazil/Acre",
00407 "Brazil/DeNoronha",
00408 "Brazil/East",
00409 "Brazil/West",
00410 "CET",
00411 "CST6CDT",
00412 "Canada/Atlantic",
00413 "Canada/Central",
00414 "Canada/Eastern",
00415 "Canada/Mountain",
00416 "Canada/Newfoundland",
00417 "Canada/Pacific",
00418 "Canada/Saskatchewan",
00419 "Canada/Yukon",
00420 "Chile/Continental",
00421 "Chile/EasterIsland",
00422 "Cuba",
00423 "EET",
00424 "EST",
00425 "EST5EDT",
00426 "Egypt",
00427 "Eire",
00428 "Etc/GMT",
00429 "Etc/GMT+0",
00430 "Etc/GMT+1",
00431 "Etc/GMT+10",
00432 "Etc/GMT+11",
00433 "Etc/GMT+12",
00434 "Etc/GMT+2",
00435 "Etc/GMT+3",
00436 "Etc/GMT+4",
00437 "Etc/GMT+5",
00438 "Etc/GMT+6",
00439 "Etc/GMT+7",
00440 "Etc/GMT+8",
00441 "Etc/GMT+9",
00442 "Etc/GMT-0",
00443 "Etc/GMT-1",
00444 "Etc/GMT-10",
00445 "Etc/GMT-11",
00446 "Etc/GMT-12",
00447 "Etc/GMT-13",
00448 "Etc/GMT-14",
00449 "Etc/GMT-2",
00450 "Etc/GMT-3",
00451 "Etc/GMT-4",
00452 "Etc/GMT-5",
00453 "Etc/GMT-6",
00454 "Etc/GMT-7",
00455 "Etc/GMT-8",
00456 "Etc/GMT-9",
00457 "Etc/GMT0",
00458 "Etc/Greenwich",
00459 "Etc/UCT",
00460 "Etc/UTC",
00461 "Etc/Universal",
00462 "Etc/Zulu",
00463 "Europe/Amsterdam",
00464 "Europe/Andorra",
00465 "Europe/Astrakhan",
00466 "Europe/Athens",
00467 "Europe/Belfast",
00468 "Europe/Belgrade",
00469 "Europe/Berlin",
00470 "Europe/Bratislava",
00471 "Europe/Brussels",
00472 "Europe/Bucharest",
00473 "Europe/Budapest",
00474 "Europe/Busingen",
00475 "Europe/Chisinau",
00476 "Europe/Copenhagen",
00477 "Europe/Dublin",
00478 "Europe/Gibraltar",
00479 "Europe/Guernsey",
00480 "Europe/Helsinki",
00481 "Europe/Isle_of_Man",
00482 "Europe/Istanbul",
00483 "Europe/Jersey",
00484 "Europe/Kaliningrad",
00485 "Europe/Kiev",
00486 "Europe/Kirov",
00487 "Europe/Lisbon",
00488 "Europe/Ljubljana",
00489 "Europe/London",
00490 "Europe/Luxembourg",
00491 "Europe/Madrid",
00492 "Europe/Malta",
00493 "Europe/Mariehamn",
00494 "Europe/Minsk",
00495 "Europe/Monaco",
00496 "Europe/Moscow",
00497 "Europe/Nicosia",
00498 "Europe/Oslo",
00499 "Europe/Paris",
00500 "Europe/Podgorica",
00501 "Europe/Prague",
00502 "Europe/Riga",
00503 "Europe/Rome",
00504 "Europe/Samara",
00505 "Europe/San_Marino",
00506 "Europe/Sarajevo",
00507 "Europe/Saratov",
00508 "Europe/Simferopol",
00509 "Europe/Skopje",
00510 "Europe/Sofia",
00511 "Europe/Stockholm",
00512 "Europe/Tallinn",
00513 "Europe/Tirane",
00514 "Europe/Tiraspol",
00515 "Europe/Ulyanovsk",
00516 "Europe/Uzhgorod",
00517 "Europe/Vaduz",
00518 "Europe/Vatican",
00519 "Europe/Vienna",
00520 "Europe/Vilnius",
00521 "Europe/Volgograd",
00522 "Europe/Warsaw",
00523 "Europe/Zagreb",
00524 "Europe/Zaporozhye",
00525 "Europe/Zurich",
00526 "GB",
00527 "GB-Eire",
00528 "GMT",
00529 "GMT+0",
00530 "GMT-0",
00531 "GMT0",
00532 "Greenwich",
00533 "HST",
00534 "Hongkong",
00535 "Iceland",
00536 "Indian/Antananarivo",
00537 "Indian/Chagos",
00538 "Indian/Christmas",
00539 "Indian/Cocos",
00540 "Indian/Comoro",
00541 "Indian/Kerguelen",
00542 "Indian/Mahe",
00543 "Indian/Maldives",
00544 "Indian/Mauritius",
00545 "Indian/Mayotte",
00546 "Indian/Reunion",
00547 "Iran",
00548 "Israel",
00549 "Jamaica",
00550 "Japan",
00551 "Kwajalein",
00552 "Libya",
00553 "MET",
00554 "MST",
00555 "MST7MDT",
00556 "Mexico/BajaNorte",
00557 "Mexico/BajaSur",
00558 "Mexico/General",
00559 "NZ",
00560 "NZ-CHAT",
00561 "Navajo",
00562 "PRC",
00563 "PST8PDT",
00564 "Pacific/Apia",
00565 "Pacific/Auckland",
00566 "Pacific/Bougainville",
00567 "Pacific/Chatham",
00568 "Pacific/Chuuk",
00569 "Pacific/Easter",
00570 "Pacific/Efate",
00571 "Pacific/Enderbury",
00572 "Pacific/Fakaofo",
00573 "Pacific/Fiji",
00574 "Pacific/Funafuti",
00575 "Pacific/Galapagos",
00576 "Pacific/Gambier",
00577 "Pacific/Guadalcanal",
00578 "Pacific/Guam",
00579 "Pacific/Honolulu",
00580 "Pacific/Johnston",
00581 "Pacific/Kiritimati",
00582 "Pacific/Kosrae",
00583 "Pacific/Kwajalein",
00584 "Pacific/Majuro",
00585 "Pacific/Marquesas",
00586 "Pacific/Midway",
00587 "Pacific/Nauru",
00588 "Pacific/Niue",
00589 "Pacific/Norfolk",
00590 "Pacific/Noumea",
00591 "Pacific/Pago_Pago",
00592 "Pacific/Palau",
00593 "Pacific/Pitcairn",
00594 "Pacific/Pohnpei",
00595 "Pacific/Ponape",
00596 "Pacific/Port_Moresby",
00597 "Pacific/Rarotonga",
00598 "Pacific/Saipan",
00599 "Pacific/Samoa",
00600 "Pacific/Tahiti",
00601 "Pacific/Tarawa",
00602 "Pacific/Tongatapu",
00603 "Pacific/Truk",
00604 "Pacific/Wake",
00605 "Pacific/Wallis",
00606 "Pacific/Yap",
00607 "Poland",
00608 "Portugal",
00609 "ROC",
00610 "ROK",
00611 "Singapore",
00612 "Turkey",
00613 "UCT",
00614 "US/Alaska",
00615 "US/Aleutian",
00616 "US/Arizona",
00617 "US/Central",
00618 "US/East-Indiana",
00619 "US/Eastern",
00620 "US/Hawaii",
00621 "US/Indiana-Starke",
00622 "US/Michigan",
00623 "US/Mountain",
00624 "US/Pacific",
00625 "US/Samoa",
00626 "UTC",
00627 "Universal",
00628 "W-SU",
00629 "WET",
00630 "Zulu",
00631 nullptr
00632 };
00633
00634
00635 time_zone LoadZone(const std::string& name) {
00636 time_zone tz;
00637 load_time_zone(name, &tz);
00638 return tz;
00639 }
00640
00641
00642
00643 #define ExpectTime(tp, tz, y, m, d, hh, mm, ss, off, isdst, zone) \
00644 do { \
00645 time_zone::absolute_lookup al = tz.lookup(tp); \
00646 EXPECT_EQ(y, al.cs.year()); \
00647 EXPECT_EQ(m, al.cs.month()); \
00648 EXPECT_EQ(d, al.cs.day()); \
00649 EXPECT_EQ(hh, al.cs.hour()); \
00650 EXPECT_EQ(mm, al.cs.minute()); \
00651 EXPECT_EQ(ss, al.cs.second()); \
00652 EXPECT_EQ(off, al.offset); \
00653 EXPECT_TRUE(isdst == al.is_dst); \
00654 \
00655 } while (0)
00656
00657
00658
00659
00660
00661
00662 int VersionCmp(time_zone tz, const std::string& target) {
00663 std::string version = tz.version();
00664 if (version.empty() && !target.empty()) return 1;
00665 return version.compare(target);
00666 }
00667
00668 }
00669
00670 #if !defined(__EMSCRIPTEN__)
00671 TEST(TimeZones, LoadZonesConcurrently) {
00672 std::promise<void> ready_promise;
00673 std::shared_future<void> ready_future(ready_promise.get_future());
00674 auto load_zones = [ready_future](std::promise<void>* started,
00675 std::set<std::string>* failures) {
00676 started->set_value();
00677 ready_future.wait();
00678 for (const char* const* np = kTimeZoneNames; *np != nullptr; ++np) {
00679 std::string zone = *np;
00680 time_zone tz;
00681 if (load_time_zone(zone, &tz)) {
00682 EXPECT_EQ(zone, tz.name());
00683 } else {
00684 failures->insert(zone);
00685 }
00686 }
00687 };
00688
00689 const std::size_t n_threads = 128;
00690 std::vector<std::thread> threads;
00691 std::vector<std::set<std::string>> thread_failures(n_threads);
00692 for (std::size_t i = 0; i != n_threads; ++i) {
00693 std::promise<void> started;
00694 threads.emplace_back(load_zones, &started, &thread_failures[i]);
00695 started.get_future().wait();
00696 }
00697 ready_promise.set_value();
00698 for (auto& thread : threads) {
00699 thread.join();
00700 }
00701
00702
00703
00704 #if defined(__ANDROID__)
00705
00706
00707
00708 const std::size_t max_failures = 20;
00709 #else
00710 const std::size_t max_failures = 3;
00711 #endif
00712 std::set<std::string> failures;
00713 for (const auto& thread_failure : thread_failures) {
00714 failures.insert(thread_failure.begin(), thread_failure.end());
00715 }
00716 EXPECT_LE(failures.size(), max_failures) << testing::PrintToString(failures);
00717 }
00718 #endif
00719
00720 TEST(TimeZone, NamedTimeZones) {
00721 const time_zone utc = utc_time_zone();
00722 EXPECT_EQ("UTC", utc.name());
00723 const time_zone nyc = LoadZone("America/New_York");
00724 EXPECT_EQ("America/New_York", nyc.name());
00725 const time_zone syd = LoadZone("Australia/Sydney");
00726 EXPECT_EQ("Australia/Sydney", syd.name());
00727 const time_zone fixed0 = fixed_time_zone(absl::time_internal::cctz::seconds::zero());
00728 EXPECT_EQ("UTC", fixed0.name());
00729 const time_zone fixed_pos = fixed_time_zone(
00730 chrono::hours(3) + chrono::minutes(25) + chrono::seconds(45));
00731 EXPECT_EQ("Fixed/UTC+03:25:45", fixed_pos.name());
00732 const time_zone fixed_neg = fixed_time_zone(
00733 -(chrono::hours(12) + chrono::minutes(34) + chrono::seconds(56)));
00734 EXPECT_EQ("Fixed/UTC-12:34:56", fixed_neg.name());
00735 }
00736
00737 TEST(TimeZone, Failures) {
00738 time_zone tz;
00739 EXPECT_FALSE(load_time_zone(":America/Los_Angeles", &tz));
00740
00741 tz = LoadZone("America/Los_Angeles");
00742 EXPECT_FALSE(load_time_zone("Invalid/TimeZone", &tz));
00743 EXPECT_EQ(chrono::system_clock::from_time_t(0),
00744 convert(civil_second(1970, 1, 1, 0, 0, 0), tz));
00745
00746
00747 tz = LoadZone("America/Los_Angeles");
00748 EXPECT_FALSE(load_time_zone("Invalid/TimeZone", &tz));
00749 EXPECT_EQ(chrono::system_clock::from_time_t(0),
00750 convert(civil_second(1970, 1, 1, 0, 0, 0), tz));
00751
00752
00753 tz = LoadZone("America/Los_Angeles");
00754 EXPECT_FALSE(load_time_zone("", &tz));
00755 EXPECT_EQ(chrono::system_clock::from_time_t(0),
00756 convert(civil_second(1970, 1, 1, 0, 0, 0), tz));
00757 }
00758
00759 TEST(TimeZone, Equality) {
00760 const time_zone a;
00761 const time_zone b;
00762 EXPECT_EQ(a, b);
00763 EXPECT_EQ(a.name(), b.name());
00764
00765 const time_zone implicit_utc;
00766 const time_zone explicit_utc = utc_time_zone();
00767 EXPECT_EQ(implicit_utc, explicit_utc);
00768 EXPECT_EQ(implicit_utc.name(), explicit_utc.name());
00769
00770 const time_zone fixed_zero = fixed_time_zone(absl::time_internal::cctz::seconds::zero());
00771 EXPECT_EQ(fixed_zero, LoadZone(fixed_zero.name()));
00772 EXPECT_EQ(fixed_zero, explicit_utc);
00773
00774 const time_zone fixed_utc = LoadZone("Fixed/UTC+00:00:00");
00775 EXPECT_EQ(fixed_utc, LoadZone(fixed_utc.name()));
00776 EXPECT_EQ(fixed_utc, explicit_utc);
00777
00778 const time_zone fixed_pos = fixed_time_zone(
00779 chrono::hours(3) + chrono::minutes(25) + chrono::seconds(45));
00780 EXPECT_EQ(fixed_pos, LoadZone(fixed_pos.name()));
00781 EXPECT_NE(fixed_pos, explicit_utc);
00782 const time_zone fixed_neg = fixed_time_zone(
00783 -(chrono::hours(12) + chrono::minutes(34) + chrono::seconds(56)));
00784 EXPECT_EQ(fixed_neg, LoadZone(fixed_neg.name()));
00785 EXPECT_NE(fixed_neg, explicit_utc);
00786
00787 const time_zone fixed_lim = fixed_time_zone(chrono::hours(24));
00788 EXPECT_EQ(fixed_lim, LoadZone(fixed_lim.name()));
00789 EXPECT_NE(fixed_lim, explicit_utc);
00790 const time_zone fixed_ovfl =
00791 fixed_time_zone(chrono::hours(24) + chrono::seconds(1));
00792 EXPECT_EQ(fixed_ovfl, LoadZone(fixed_ovfl.name()));
00793 EXPECT_EQ(fixed_ovfl, explicit_utc);
00794
00795 EXPECT_EQ(fixed_time_zone(chrono::seconds(1)),
00796 fixed_time_zone(chrono::seconds(1)));
00797
00798 const time_zone local = local_time_zone();
00799 EXPECT_EQ(local, LoadZone(local.name()));
00800
00801 time_zone la = LoadZone("America/Los_Angeles");
00802 time_zone nyc = LoadZone("America/New_York");
00803 EXPECT_NE(la, nyc);
00804 }
00805
00806 TEST(StdChronoTimePoint, TimeTAlignment) {
00807
00808
00809 auto diff = chrono::system_clock::time_point() -
00810 chrono::system_clock::from_time_t(0);
00811 EXPECT_EQ(chrono::system_clock::time_point::duration::zero(),
00812 diff % chrono::seconds(1));
00813 }
00814
00815 TEST(BreakTime, TimePointResolution) {
00816 const time_zone utc = utc_time_zone();
00817 const auto t0 = chrono::system_clock::from_time_t(0);
00818
00819 ExpectTime(chrono::time_point_cast<chrono::nanoseconds>(t0), utc,
00820 1970, 1, 1, 0, 0, 0, 0, false, "UTC");
00821 ExpectTime(chrono::time_point_cast<chrono::microseconds>(t0), utc,
00822 1970, 1, 1, 0, 0, 0, 0, false, "UTC");
00823 ExpectTime(chrono::time_point_cast<chrono::milliseconds>(t0), utc,
00824 1970, 1, 1, 0, 0, 0, 0, false, "UTC");
00825 ExpectTime(chrono::time_point_cast<chrono::seconds>(t0), utc,
00826 1970, 1, 1, 0, 0, 0, 0, false, "UTC");
00827 ExpectTime(chrono::time_point_cast<absl::time_internal::cctz::seconds>(t0), utc,
00828 1970, 1, 1, 0, 0, 0, 0, false, "UTC");
00829 ExpectTime(chrono::time_point_cast<chrono::minutes>(t0), utc,
00830 1970, 1, 1, 0, 0, 0, 0, false, "UTC");
00831 ExpectTime(chrono::time_point_cast<chrono::hours>(t0), utc,
00832 1970, 1, 1, 0, 0, 0, 0, false, "UTC");
00833 }
00834
00835 TEST(BreakTime, LocalTimeInUTC) {
00836 const time_zone tz = utc_time_zone();
00837 const auto tp = chrono::system_clock::from_time_t(0);
00838 ExpectTime(tp, tz, 1970, 1, 1, 0, 0, 0, 0, false, "UTC");
00839 EXPECT_EQ(weekday::thursday, get_weekday(civil_day(convert(tp, tz))));
00840 }
00841
00842 TEST(BreakTime, LocalTimeInUTCUnaligned) {
00843 const time_zone tz = utc_time_zone();
00844 const auto tp =
00845 chrono::system_clock::from_time_t(0) - chrono::milliseconds(500);
00846 ExpectTime(tp, tz, 1969, 12, 31, 23, 59, 59, 0, false, "UTC");
00847 EXPECT_EQ(weekday::wednesday, get_weekday(civil_day(convert(tp, tz))));
00848 }
00849
00850 TEST(BreakTime, LocalTimePosix) {
00851
00852 const time_zone tz = utc_time_zone();
00853 const auto tp = chrono::system_clock::from_time_t(536457599);
00854 ExpectTime(tp, tz, 1986, 12, 31, 23, 59, 59, 0, false, "UTC");
00855 EXPECT_EQ(weekday::wednesday, get_weekday(civil_day(convert(tp, tz))));
00856 }
00857
00858 TEST(TimeZoneImpl, LocalTimeInFixed) {
00859 const absl::time_internal::cctz::seconds offset =
00860 -(chrono::hours(8) + chrono::minutes(33) + chrono::seconds(47));
00861 const time_zone tz = fixed_time_zone(offset);
00862 const auto tp = chrono::system_clock::from_time_t(0);
00863 ExpectTime(tp, tz, 1969, 12, 31, 15, 26, 13, offset.count(), false,
00864 "-083347");
00865 EXPECT_EQ(weekday::wednesday, get_weekday(civil_day(convert(tp, tz))));
00866 }
00867
00868 TEST(BreakTime, LocalTimeInNewYork) {
00869 const time_zone tz = LoadZone("America/New_York");
00870 const auto tp = chrono::system_clock::from_time_t(45);
00871 ExpectTime(tp, tz, 1969, 12, 31, 19, 0, 45, -5 * 60 * 60, false, "EST");
00872 EXPECT_EQ(weekday::wednesday, get_weekday(civil_day(convert(tp, tz))));
00873 }
00874
00875 TEST(BreakTime, LocalTimeInMTV) {
00876 const time_zone tz = LoadZone("America/Los_Angeles");
00877 const auto tp = chrono::system_clock::from_time_t(1380855729);
00878 ExpectTime(tp, tz, 2013, 10, 3, 20, 2, 9, -7 * 60 * 60, true, "PDT");
00879 EXPECT_EQ(weekday::thursday, get_weekday(civil_day(convert(tp, tz))));
00880 }
00881
00882 TEST(BreakTime, LocalTimeInSydney) {
00883 const time_zone tz = LoadZone("Australia/Sydney");
00884 const auto tp = chrono::system_clock::from_time_t(90);
00885 ExpectTime(tp, tz, 1970, 1, 1, 10, 1, 30, 10 * 60 * 60, false, "AEST");
00886 EXPECT_EQ(weekday::thursday, get_weekday(civil_day(convert(tp, tz))));
00887 }
00888
00889 TEST(MakeTime, TimePointResolution) {
00890 const time_zone utc = utc_time_zone();
00891 const time_point<chrono::nanoseconds> tp_ns =
00892 convert(civil_second(2015, 1, 2, 3, 4, 5), utc);
00893 EXPECT_EQ("04:05", format("%M:%E*S", tp_ns, utc));
00894 const time_point<chrono::microseconds> tp_us =
00895 convert(civil_second(2015, 1, 2, 3, 4, 5), utc);
00896 EXPECT_EQ("04:05", format("%M:%E*S", tp_us, utc));
00897 const time_point<chrono::milliseconds> tp_ms =
00898 convert(civil_second(2015, 1, 2, 3, 4, 5), utc);
00899 EXPECT_EQ("04:05", format("%M:%E*S", tp_ms, utc));
00900 const time_point<chrono::seconds> tp_s =
00901 convert(civil_second(2015, 1, 2, 3, 4, 5), utc);
00902 EXPECT_EQ("04:05", format("%M:%E*S", tp_s, utc));
00903 const time_point<absl::time_internal::cctz::seconds> tp_s64 =
00904 convert(civil_second(2015, 1, 2, 3, 4, 5), utc);
00905 EXPECT_EQ("04:05", format("%M:%E*S", tp_s64, utc));
00906
00907
00908
00909
00910 const time_point<chrono::minutes> tp_m =
00911 chrono::time_point_cast<chrono::minutes>(
00912 convert(civil_second(2015, 1, 2, 3, 4, 5), utc));
00913 EXPECT_EQ("04:00", format("%M:%E*S", tp_m, utc));
00914 const time_point<chrono::hours> tp_h =
00915 chrono::time_point_cast<chrono::hours>(
00916 convert(civil_second(2015, 1, 2, 3, 4, 5), utc));
00917 EXPECT_EQ("00:00", format("%M:%E*S", tp_h, utc));
00918 }
00919
00920 TEST(MakeTime, Normalization) {
00921 const time_zone tz = LoadZone("America/New_York");
00922 const auto tp = convert(civil_second(2009, 2, 13, 18, 31, 30), tz);
00923 EXPECT_EQ(chrono::system_clock::from_time_t(1234567890), tp);
00924
00925
00926 EXPECT_EQ(tp, convert(civil_second(2008, 14, 13, 18, 31, 30), tz));
00927 EXPECT_EQ(tp, convert(civil_second(2009, 1, 44, 18, 31, 30), tz));
00928 EXPECT_EQ(tp, convert(civil_second(2009, 2, 12, 42, 31, 30), tz));
00929 EXPECT_EQ(tp, convert(civil_second(2009, 2, 13, 17, 91, 30), tz));
00930 EXPECT_EQ(tp, convert(civil_second(2009, 2, 13, 18, 30, 90), tz));
00931 }
00932
00933
00934 TEST(MakeTime, SysSecondsLimits) {
00935 const char RFC3339[] = "%Y-%m-%dT%H:%M:%S%Ez";
00936 const time_zone utc = utc_time_zone();
00937 const time_zone east = fixed_time_zone(chrono::hours(14));
00938 const time_zone west = fixed_time_zone(-chrono::hours(14));
00939 time_point<absl::time_internal::cctz::seconds> tp;
00940
00941
00942 tp = convert(civil_second(292277026596, 12, 4, 15, 30, 6), utc);
00943 EXPECT_EQ("292277026596-12-04T15:30:06+00:00", format(RFC3339, tp, utc));
00944 tp = convert(civil_second(292277026596, 12, 4, 15, 30, 7), utc);
00945 EXPECT_EQ("292277026596-12-04T15:30:07+00:00", format(RFC3339, tp, utc));
00946 EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp);
00947 tp = convert(civil_second(292277026596, 12, 4, 15, 30, 8), utc);
00948 EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp);
00949 tp = convert(civil_second::max(), utc);
00950 EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp);
00951
00952
00953 tp = convert(civil_second(292277026596, 12, 5, 5, 30, 7), east);
00954 EXPECT_EQ("292277026596-12-05T05:30:07+14:00", format(RFC3339, tp, east));
00955 EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp);
00956 tp = convert(civil_second(292277026596, 12, 5, 5, 30, 8), east);
00957 EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp);
00958 tp = convert(civil_second::max(), east);
00959 EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp);
00960
00961
00962 tp = convert(civil_second(292277026596, 12, 4, 1, 30, 7), west);
00963 EXPECT_EQ("292277026596-12-04T01:30:07-14:00", format(RFC3339, tp, west));
00964 EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp);
00965 tp = convert(civil_second(292277026596, 12, 4, 7, 30, 8), west);
00966 EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp);
00967 tp = convert(civil_second::max(), west);
00968 EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp);
00969
00970
00971 tp = convert(civil_second(-292277022657, 1, 27, 8, 29, 53), utc);
00972 EXPECT_EQ("-292277022657-01-27T08:29:53+00:00", format(RFC3339, tp, utc));
00973 tp = convert(civil_second(-292277022657, 1, 27, 8, 29, 52), utc);
00974 EXPECT_EQ("-292277022657-01-27T08:29:52+00:00", format(RFC3339, tp, utc));
00975 EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp);
00976 tp = convert(civil_second(-292277022657, 1, 27, 8, 29, 51), utc);
00977 EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp);
00978 tp = convert(civil_second::min(), utc);
00979 EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp);
00980
00981
00982 tp = convert(civil_second(-292277022657, 1, 27, 22, 29, 52), east);
00983 EXPECT_EQ("-292277022657-01-27T22:29:52+14:00", format(RFC3339, tp, east));
00984 EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp);
00985 tp = convert(civil_second(-292277022657, 1, 27, 22, 29, 51), east);
00986 EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp);
00987 tp = convert(civil_second::min(), east);
00988 EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp);
00989
00990
00991 tp = convert(civil_second(-292277022657, 1, 26, 18, 29, 52), west);
00992 EXPECT_EQ("-292277022657-01-26T18:29:52-14:00", format(RFC3339, tp, west));
00993 EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp);
00994 tp = convert(civil_second(-292277022657, 1, 26, 18, 29, 51), west);
00995 EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp);
00996 tp = convert(civil_second::min(), west);
00997 EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp);
00998
00999
01000 if (sizeof(std::time_t) >= 8) {
01001
01002
01003 #if defined(_WIN32) || defined(_WIN64)
01004
01005 #else
01006 const time_zone utc = LoadZone("libc:UTC");
01007 const year_t max_tm_year = year_t{std::numeric_limits<int>::max()} + 1900;
01008 tp = convert(civil_second(max_tm_year, 12, 31, 23, 59, 59), utc);
01009 EXPECT_EQ("2147485547-12-31T23:59:59+00:00", format(RFC3339, tp, utc));
01010 const year_t min_tm_year = year_t{std::numeric_limits<int>::min()} + 1900;
01011 tp = convert(civil_second(min_tm_year, 1, 1, 0, 0, 0), utc);
01012 EXPECT_EQ("-2147481748-01-01T00:00:00+00:00", format(RFC3339, tp, utc));
01013 #endif
01014 }
01015 }
01016
01017 TEST(MakeTime, LocalTimeLibC) {
01018
01019
01020
01021
01022
01023
01024 #if defined(__linux__) && !defined(__ANDROID__)
01025 const char* const ep = getenv("TZ");
01026 std::string tz_name = (ep != nullptr) ? ep : "";
01027 for (const char* const* np = kTimeZoneNames; *np != nullptr; ++np) {
01028 ASSERT_EQ(0, setenv("TZ", *np, 1));
01029 const auto zi = local_time_zone();
01030 const auto lc = LoadZone("libc:localtime");
01031 time_zone::civil_transition trans;
01032 for (auto tp = zi.lookup(civil_second()).trans;
01033 zi.next_transition(tp, &trans);
01034 tp = zi.lookup(trans.to).trans) {
01035 const auto fcl = zi.lookup(trans.from);
01036 const auto tcl = zi.lookup(trans.to);
01037 civil_second cs;
01038 if (fcl.kind == time_zone::civil_lookup::UNIQUE) {
01039 if (tcl.kind == time_zone::civil_lookup::UNIQUE) {
01040
01041 ASSERT_EQ(trans.from, trans.to);
01042 const auto trans = fcl.trans;
01043 const auto tal = zi.lookup(trans);
01044 const auto tprev = trans - absl::time_internal::cctz::seconds(1);
01045 const auto pal = zi.lookup(tprev);
01046 if (pal.is_dst == tal.is_dst) {
01047 ASSERT_STRNE(pal.abbr, tal.abbr);
01048 }
01049 continue;
01050 }
01051 ASSERT_EQ(time_zone::civil_lookup::REPEATED, tcl.kind);
01052 cs = trans.to;
01053 } else {
01054 ASSERT_EQ(time_zone::civil_lookup::UNIQUE, tcl.kind);
01055 ASSERT_EQ(time_zone::civil_lookup::SKIPPED, fcl.kind);
01056 cs = trans.from;
01057 }
01058 if (cs.year() > 2037) break;
01059 const auto cl_zi = zi.lookup(cs);
01060 if (zi.lookup(cl_zi.pre).is_dst == zi.lookup(cl_zi.post).is_dst) {
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073 continue;
01074 }
01075 if (cs == civil_second(2037, 10, 4, 2, 0, 0)) {
01076 const std::string tzname = *np;
01077 if (tzname == "Africa/Casablanca" || tzname == "Africa/El_Aaiun") {
01078
01079
01080
01081 continue;
01082 }
01083 }
01084 const auto cl_lc = lc.lookup(cs);
01085 SCOPED_TRACE(testing::Message() << "For " << cs << " in " << *np);
01086 EXPECT_EQ(cl_zi.kind, cl_lc.kind);
01087 EXPECT_EQ(cl_zi.pre, cl_lc.pre);
01088 EXPECT_EQ(cl_zi.trans, cl_lc.trans);
01089 EXPECT_EQ(cl_zi.post, cl_lc.post);
01090 }
01091 }
01092 if (ep == nullptr) {
01093 ASSERT_EQ(0, unsetenv("TZ"));
01094 } else {
01095 ASSERT_EQ(0, setenv("TZ", tz_name.c_str(), 1));
01096 }
01097 #endif
01098 }
01099
01100 TEST(NextTransition, UTC) {
01101 const auto tz = utc_time_zone();
01102 time_zone::civil_transition trans;
01103
01104 auto tp = time_point<absl::time_internal::cctz::seconds>::min();
01105 EXPECT_FALSE(tz.next_transition(tp, &trans));
01106
01107 tp = time_point<absl::time_internal::cctz::seconds>::max();
01108 EXPECT_FALSE(tz.next_transition(tp, &trans));
01109 }
01110
01111 TEST(PrevTransition, UTC) {
01112 const auto tz = utc_time_zone();
01113 time_zone::civil_transition trans;
01114
01115 auto tp = time_point<absl::time_internal::cctz::seconds>::max();
01116 EXPECT_FALSE(tz.prev_transition(tp, &trans));
01117
01118 tp = time_point<absl::time_internal::cctz::seconds>::min();
01119 EXPECT_FALSE(tz.prev_transition(tp, &trans));
01120 }
01121
01122 TEST(NextTransition, AmericaNewYork) {
01123 const auto tz = LoadZone("America/New_York");
01124 time_zone::civil_transition trans;
01125
01126 auto tp = convert(civil_second(2018, 6, 30, 0, 0, 0), tz);
01127 EXPECT_TRUE(tz.next_transition(tp, &trans));
01128 EXPECT_EQ(civil_second(2018, 11, 4, 2, 0, 0), trans.from);
01129 EXPECT_EQ(civil_second(2018, 11, 4, 1, 0, 0), trans.to);
01130
01131 tp = time_point<absl::time_internal::cctz::seconds>::max();
01132 EXPECT_FALSE(tz.next_transition(tp, &trans));
01133
01134 tp = time_point<absl::time_internal::cctz::seconds>::min();
01135 EXPECT_TRUE(tz.next_transition(tp, &trans));
01136 if (trans.from == civil_second(1918, 3, 31, 2, 0, 0)) {
01137
01138
01139 EXPECT_EQ(civil_second(1918, 3, 31, 3, 0, 0), trans.to);
01140 } else {
01141 EXPECT_EQ(civil_second(1883, 11, 18, 12, 3, 58), trans.from);
01142 EXPECT_EQ(civil_second(1883, 11, 18, 12, 0, 0), trans.to);
01143 }
01144 }
01145
01146 TEST(PrevTransition, AmericaNewYork) {
01147 const auto tz = LoadZone("America/New_York");
01148 time_zone::civil_transition trans;
01149
01150 auto tp = convert(civil_second(2018, 6, 30, 0, 0, 0), tz);
01151 EXPECT_TRUE(tz.prev_transition(tp, &trans));
01152 EXPECT_EQ(civil_second(2018, 3, 11, 2, 0, 0), trans.from);
01153 EXPECT_EQ(civil_second(2018, 3, 11, 3, 0, 0), trans.to);
01154
01155 tp = time_point<absl::time_internal::cctz::seconds>::min();
01156 EXPECT_FALSE(tz.prev_transition(tp, &trans));
01157
01158 tp = time_point<absl::time_internal::cctz::seconds>::max();
01159 EXPECT_TRUE(tz.prev_transition(tp, &trans));
01160
01161 }
01162
01163 TEST(TimeZoneEdgeCase, AmericaNewYork) {
01164 const time_zone tz = LoadZone("America/New_York");
01165
01166
01167 auto tp = convert(civil_second(2013, 3, 10, 1, 59, 59), tz);
01168 ExpectTime(tp, tz, 2013, 3, 10, 1, 59, 59, -5 * 3600, false, "EST");
01169 tp += absl::time_internal::cctz::seconds(1);
01170 ExpectTime(tp, tz, 2013, 3, 10, 3, 0, 0, -4 * 3600, true, "EDT");
01171
01172
01173 tp = convert(civil_second(2013, 11, 3, 1, 59, 59), tz);
01174 ExpectTime(tp, tz, 2013, 11, 3, 1, 59, 59, -4 * 3600, true, "EDT");
01175 tp += absl::time_internal::cctz::seconds(1);
01176 ExpectTime(tp, tz, 2013, 11, 3, 1, 0, 0, -5 * 3600, false, "EST");
01177 }
01178
01179 TEST(TimeZoneEdgeCase, AmericaLosAngeles) {
01180 const time_zone tz = LoadZone("America/Los_Angeles");
01181
01182
01183 auto tp = convert(civil_second(2013, 3, 10, 1, 59, 59), tz);
01184 ExpectTime(tp, tz, 2013, 3, 10, 1, 59, 59, -8 * 3600, false, "PST");
01185 tp += absl::time_internal::cctz::seconds(1);
01186 ExpectTime(tp, tz, 2013, 3, 10, 3, 0, 0, -7 * 3600, true, "PDT");
01187
01188
01189 tp = convert(civil_second(2013, 11, 3, 1, 59, 59), tz);
01190 ExpectTime(tp, tz, 2013, 11, 3, 1, 59, 59, -7 * 3600, true, "PDT");
01191 tp += absl::time_internal::cctz::seconds(1);
01192 ExpectTime(tp, tz, 2013, 11, 3, 1, 0, 0, -8 * 3600, false, "PST");
01193 }
01194
01195 TEST(TimeZoneEdgeCase, ArizonaNoTransition) {
01196 const time_zone tz = LoadZone("America/Phoenix");
01197
01198
01199 auto tp = convert(civil_second(2013, 3, 10, 1, 59, 59), tz);
01200 ExpectTime(tp, tz, 2013, 3, 10, 1, 59, 59, -7 * 3600, false, "MST");
01201 tp += absl::time_internal::cctz::seconds(1);
01202 ExpectTime(tp, tz, 2013, 3, 10, 2, 0, 0, -7 * 3600, false, "MST");
01203
01204
01205 tp = convert(civil_second(2013, 11, 3, 1, 59, 59), tz);
01206 ExpectTime(tp, tz, 2013, 11, 3, 1, 59, 59, -7 * 3600, false, "MST");
01207 tp += absl::time_internal::cctz::seconds(1);
01208 ExpectTime(tp, tz, 2013, 11, 3, 2, 0, 0, -7 * 3600, false, "MST");
01209 }
01210
01211 TEST(TimeZoneEdgeCase, AsiaKathmandu) {
01212 const time_zone tz = LoadZone("Asia/Kathmandu");
01213
01214
01215
01216
01217
01218 auto tp = convert(civil_second(1985, 12, 31, 23, 59, 59), tz);
01219 ExpectTime(tp, tz, 1985, 12, 31, 23, 59, 59, 5.5 * 3600, false, "+0530");
01220 tp += absl::time_internal::cctz::seconds(1);
01221 ExpectTime(tp, tz, 1986, 1, 1, 0, 15, 0, 5.75 * 3600, false, "+0545");
01222 }
01223
01224 TEST(TimeZoneEdgeCase, PacificChatham) {
01225 const time_zone tz = LoadZone("Pacific/Chatham");
01226
01227
01228
01229
01230
01231 auto tp = convert(civil_second(2013, 4, 7, 3, 44, 59), tz);
01232 ExpectTime(tp, tz, 2013, 4, 7, 3, 44, 59, 13.75 * 3600, true, "+1345");
01233 tp += absl::time_internal::cctz::seconds(1);
01234 ExpectTime(tp, tz, 2013, 4, 7, 2, 45, 0, 12.75 * 3600, false, "+1245");
01235
01236
01237
01238 tp = convert(civil_second(2013, 9, 29, 2, 44, 59), tz);
01239 ExpectTime(tp, tz, 2013, 9, 29, 2, 44, 59, 12.75 * 3600, false, "+1245");
01240 tp += absl::time_internal::cctz::seconds(1);
01241 ExpectTime(tp, tz, 2013, 9, 29, 3, 45, 0, 13.75 * 3600, true, "+1345");
01242 }
01243
01244 TEST(TimeZoneEdgeCase, AustraliaLordHowe) {
01245 const time_zone tz = LoadZone("Australia/Lord_Howe");
01246
01247
01248
01249
01250
01251 auto tp = convert(civil_second(2013, 4, 7, 1, 59, 59), tz);
01252 ExpectTime(tp, tz, 2013, 4, 7, 1, 59, 59, 11 * 3600, true, "+11");
01253 tp += absl::time_internal::cctz::seconds(1);
01254 ExpectTime(tp, tz, 2013, 4, 7, 1, 30, 0, 10.5 * 3600, false, "+1030");
01255
01256
01257
01258 tp = convert(civil_second(2013, 10, 6, 1, 59, 59), tz);
01259 ExpectTime(tp, tz, 2013, 10, 6, 1, 59, 59, 10.5 * 3600, false, "+1030");
01260 tp += absl::time_internal::cctz::seconds(1);
01261 ExpectTime(tp, tz, 2013, 10, 6, 2, 30, 0, 11 * 3600, true, "+11");
01262 }
01263
01264 TEST(TimeZoneEdgeCase, PacificApia) {
01265 const time_zone tz = LoadZone("Pacific/Apia");
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275 auto tp = convert(civil_second(2011, 12, 29, 23, 59, 59), tz);
01276 ExpectTime(tp, tz, 2011, 12, 29, 23, 59, 59, -10 * 3600, true, "-10");
01277 EXPECT_EQ(363, get_yearday(civil_day(convert(tp, tz))));
01278 tp += absl::time_internal::cctz::seconds(1);
01279 ExpectTime(tp, tz, 2011, 12, 31, 0, 0, 0, 14 * 3600, true, "+14");
01280 EXPECT_EQ(365, get_yearday(civil_day(convert(tp, tz))));
01281 }
01282
01283 TEST(TimeZoneEdgeCase, AfricaCairo) {
01284 const time_zone tz = LoadZone("Africa/Cairo");
01285
01286 if (VersionCmp(tz, "2014c") >= 0) {
01287
01288
01289
01290
01291 auto tp = convert(civil_second(2014, 5, 15, 23, 59, 59), tz);
01292 ExpectTime(tp, tz, 2014, 5, 15, 23, 59, 59, 2 * 3600, false, "EET");
01293 tp += absl::time_internal::cctz::seconds(1);
01294 ExpectTime(tp, tz, 2014, 5, 16, 1, 0, 0, 3 * 3600, true, "EEST");
01295 }
01296 }
01297
01298 TEST(TimeZoneEdgeCase, AfricaMonrovia) {
01299 const time_zone tz = LoadZone("Africa/Monrovia");
01300
01301 if (VersionCmp(tz, "2017b") >= 0) {
01302
01303
01304
01305
01306 auto tp = convert(civil_second(1972, 1, 6, 23, 59, 59), tz);
01307 ExpectTime(tp, tz, 1972, 1, 6, 23, 59, 59, -44.5 * 60, false, "MMT");
01308 tp += absl::time_internal::cctz::seconds(1);
01309 ExpectTime(tp, tz, 1972, 1, 7, 0, 44, 30, 0 * 60, false, "GMT");
01310 }
01311 }
01312
01313 TEST(TimeZoneEdgeCase, AmericaJamaica) {
01314
01315
01316
01317
01318
01319 const time_zone tz = LoadZone("America/Jamaica");
01320
01321
01322 if (!tz.version().empty() && VersionCmp(tz, "2018d") >= 0) {
01323
01324
01325
01326
01327 auto tp = convert(civil_second(1889, 12, 31, 0, 0, 0), tz);
01328 ExpectTime(tp, tz, 1889, 12, 31, 0, 0, 0, -18430, false,
01329 tz.lookup(tp).abbr);
01330
01331
01332
01333
01334 tp = convert(civil_second(1889, 12, 31, 23, 59, 59), tz);
01335 ExpectTime(tp, tz, 1889, 12, 31, 23, 59, 59, -18430, false,
01336 tz.lookup(tp).abbr);
01337 tp += absl::time_internal::cctz::seconds(1);
01338 ExpectTime(tp, tz, 1890, 1, 1, 0, 0, 0, -18430, false, "KMT");
01339 }
01340
01341
01342
01343
01344 auto tp = convert(civil_second(1983, 10, 30, 1, 59, 59), tz);
01345 ExpectTime(tp, tz, 1983, 10, 30, 1, 59, 59, -4 * 3600, true, "EDT");
01346 tp += absl::time_internal::cctz::seconds(1);
01347 ExpectTime(tp, tz, 1983, 10, 30, 1, 0, 0, -5 * 3600, false, "EST");
01348
01349
01350 tp = convert(civil_second(1983, 12, 31, 23, 59, 59), tz);
01351 ExpectTime(tp, tz, 1983, 12, 31, 23, 59, 59, -5 * 3600, false, "EST");
01352 }
01353
01354 TEST(TimeZoneEdgeCase, WET) {
01355
01356 const time_zone tz = LoadZone("WET");
01357
01358
01359 auto tp = convert(civil_second(1977, 1, 1, 0, 0, 0), tz);
01360 ExpectTime(tp, tz, 1977, 1, 1, 0, 0, 0, 0, false, "WET");
01361
01362
01363
01364
01365 tp = convert(civil_second(1977, 4, 3, 0, 59, 59), tz);
01366 ExpectTime(tp, tz, 1977, 4, 3, 0, 59, 59, 0, false, "WET");
01367 tp += absl::time_internal::cctz::seconds(1);
01368 ExpectTime(tp, tz, 1977, 4, 3, 2, 0, 0, 1 * 3600, true, "WEST");
01369
01370
01371 time_zone::civil_lookup cl1 = tz.lookup(civil_second(1977, 4, 3, 1, 15, 0));
01372 EXPECT_EQ(time_zone::civil_lookup::SKIPPED, cl1.kind);
01373 ExpectTime(cl1.pre, tz, 1977, 4, 3, 2, 15, 0, 1 * 3600, true, "WEST");
01374 ExpectTime(cl1.trans, tz, 1977, 4, 3, 2, 0, 0, 1 * 3600, true, "WEST");
01375 ExpectTime(cl1.post, tz, 1977, 4, 3, 0, 15, 0, 0 * 3600, false, "WET");
01376
01377
01378 time_zone::civil_lookup cl2 = tz.lookup(civil_second(1978, 4, 2, 1, 15, 0));
01379 EXPECT_EQ(time_zone::civil_lookup::SKIPPED, cl2.kind);
01380 ExpectTime(cl2.pre, tz, 1978, 4, 2, 2, 15, 0, 1 * 3600, true, "WEST");
01381 ExpectTime(cl2.trans, tz, 1978, 4, 2, 2, 0, 0, 1 * 3600, true, "WEST");
01382 ExpectTime(cl2.post, tz, 1978, 4, 2, 0, 15, 0, 0 * 3600, false, "WET");
01383 }
01384
01385 TEST(TimeZoneEdgeCase, FixedOffsets) {
01386 const time_zone gmtm5 = LoadZone("Etc/GMT+5");
01387 auto tp = convert(civil_second(1970, 1, 1, 0, 0, 0), gmtm5);
01388 ExpectTime(tp, gmtm5, 1970, 1, 1, 0, 0, 0, -5 * 3600, false, "-05");
01389 EXPECT_EQ(chrono::system_clock::from_time_t(5 * 3600), tp);
01390
01391 const time_zone gmtp5 = LoadZone("Etc/GMT-5");
01392 tp = convert(civil_second(1970, 1, 1, 0, 0, 0), gmtp5);
01393 ExpectTime(tp, gmtp5, 1970, 1, 1, 0, 0, 0, 5 * 3600, false, "+05");
01394 EXPECT_EQ(chrono::system_clock::from_time_t(-5 * 3600), tp);
01395 }
01396
01397 TEST(TimeZoneEdgeCase, NegativeYear) {
01398
01399 const time_zone tz = utc_time_zone();
01400 auto tp = convert(civil_second(0, 1, 1, 0, 0, 0), tz);
01401 ExpectTime(tp, tz, 0, 1, 1, 0, 0, 0, 0 * 3600, false, "UTC");
01402 EXPECT_EQ(weekday::saturday, get_weekday(civil_day(convert(tp, tz))));
01403 tp -= absl::time_internal::cctz::seconds(1);
01404 ExpectTime(tp, tz, -1, 12, 31, 23, 59, 59, 0 * 3600, false, "UTC");
01405 EXPECT_EQ(weekday::friday, get_weekday(civil_day(convert(tp, tz))));
01406 }
01407
01408 TEST(TimeZoneEdgeCase, UTC32bitLimit) {
01409 const time_zone tz = utc_time_zone();
01410
01411
01412
01413
01414
01415 auto tp = convert(civil_second(2038, 1, 19, 3, 14, 7), tz);
01416 ExpectTime(tp, tz, 2038, 1, 19, 3, 14, 7, 0 * 3600, false, "UTC");
01417 tp += absl::time_internal::cctz::seconds(1);
01418 ExpectTime(tp, tz, 2038, 1, 19, 3, 14, 8, 0 * 3600, false, "UTC");
01419 }
01420
01421 TEST(TimeZoneEdgeCase, UTC5DigitYear) {
01422 const time_zone tz = utc_time_zone();
01423
01424
01425
01426
01427
01428 auto tp = convert(civil_second(9999, 12, 31, 23, 59, 59), tz);
01429 ExpectTime(tp, tz, 9999, 12, 31, 23, 59, 59, 0 * 3600, false, "UTC");
01430 tp += absl::time_internal::cctz::seconds(1);
01431 ExpectTime(tp, tz, 10000, 1, 1, 0, 0, 0, 0 * 3600, false, "UTC");
01432 }
01433
01434 }
01435 }
01436 }