想象一下你在某个时区(例如America / New_York)采取当地日期,比如2016-12-28,并将该日期的开头转换为UTC(在这种情况下2016-12-28T05:00:00Z )。
是否可以从UTC时间返回到原始本地日期而不知道时区?你所知道的是UTC时间代表某些当地午夜/一天的开始。
我想在某些情况下这是可能的,例如当偏移量相当小时,但我不确定时区接近日期线时是否会有两个可能的答案,即当两个时区具有相同的时间但是日期/偏移不同时(-10)和+14)。
(此问题最初是在数据库中遇到的,其中本地日期错误地存储在UTC中,并且原始时区数据难以再次检索。)
答案 0 :(得分:3)
使用此free, open-source C++ library,我可以计算此问题的可能时区列表。
更新我已经重写了此代码的驱动程序,以便真正探索一整天的结果,并将其与Matt优秀答案中的具体示例进行比较。
以下是代码:
#include <iostream>
#include <vector>
template <class Duration>
std::vector<date::zoned_time<std::common_type_t<Duration, std::chrono::seconds>>>
find_by_offset(date::sys_time<Duration> tp, const std::chrono::seconds& offset)
{
using namespace std::chrono;
using namespace date;
std::vector<zoned_time<std::common_type_t<Duration, std::chrono::seconds>>> results;
auto& db = get_tzdb();
for (auto& z : db.zones)
{
if (z.get_info(tp).offset == offset)
results.push_back(make_zoned(&z, tp));
}
return results;
}
int
main()
{
using namespace date;
using namespace std::chrono;
for (auto offset = -15h; offset <= 13h; offset += 1h)
{
auto tp = sys_days{2016_y/12/28} + offset;
std::cout << "These are all the timezones it is midnight at " << format("%F %T %Z\n", tp);
auto d0 = round<days>(tp);
auto dm1 = d0 - days{1};
auto dp1 = d0 + days{1};
auto v = find_by_offset(tp, dm1 - tp);
for (auto const& zt : v)
std::cout << format("%F %T %Z %z ", zt) << zt.get_time_zone()->name() << '\n';
v = find_by_offset(tp, d0 - tp);
for (auto const& zt : v)
std::cout << format("%F %T %Z %z ", zt) << zt.get_time_zone()->name() << '\n';
v = find_by_offset(tp, dp1 - tp);
for (auto const& zt : v)
std::cout << format("%F %T %Z %z ", zt) << zt.get_time_zone()->name() << '\n';
std::cout << '\n';
}
}
代码创建一个UTC时间戳和偏移对,并将其提供给find_by_offset
,它遍历所有时区,并在每个时区查询该时间戳的偏移量。如果时区的偏移量与所需的偏移量匹配,则会在结果中添加zoned_time
(zoned_time
是时区与时间戳的配对。)
以下是2016-12-28日期可能有午夜的所有结果:
These are all the timezones it is midnight at 2016-12-27 09:00:00 UTC
2016-12-27 00:00:00 AKST -0900 America/Anchorage
2016-12-27 00:00:00 AKST -0900 America/Juneau
2016-12-27 00:00:00 AKST -0900 America/Metlakatla
2016-12-27 00:00:00 AKST -0900 America/Nome
2016-12-27 00:00:00 AKST -0900 America/Sitka
2016-12-27 00:00:00 AKST -0900 America/Yakutat
2016-12-27 00:00:00 -09 -0900 Etc/GMT+9
2016-12-27 00:00:00 GAMT -0900 Pacific/Gambier
These are all the timezones it is midnight at 2016-12-27 10:00:00 UTC
2016-12-27 00:00:00 HST -1000 America/Adak
2016-12-27 00:00:00 -10 -1000 Etc/GMT+10
2016-12-27 00:00:00 HST -1000 HST
2016-12-27 00:00:00 HST -1000 Pacific/Honolulu
2016-12-27 00:00:00 CKT -1000 Pacific/Rarotonga
2016-12-27 00:00:00 TAHT -1000 Pacific/Tahiti
2016-12-28 00:00:00 +14 +1400 Etc/GMT-14
2016-12-28 00:00:00 WSDT +1400 Pacific/Apia
2016-12-28 00:00:00 LINT +1400 Pacific/Kiritimati
2016-12-28 00:00:00 +14 +1400 Pacific/Tongatapu
These are all the timezones it is midnight at 2016-12-27 11:00:00 UTC
2016-12-27 00:00:00 -11 -1100 Etc/GMT+11
2016-12-27 00:00:00 NUT -1100 Pacific/Niue
2016-12-27 00:00:00 SST -1100 Pacific/Pago_Pago
2016-12-28 00:00:00 +13 +1300 Etc/GMT-13
2016-12-28 00:00:00 NZDT +1300 Pacific/Auckland
2016-12-28 00:00:00 PHOT +1300 Pacific/Enderbury
2016-12-28 00:00:00 TKT +1300 Pacific/Fakaofo
2016-12-28 00:00:00 FJST +1300 Pacific/Fiji
These are all the timezones it is midnight at 2016-12-27 12:00:00 UTC
2016-12-27 00:00:00 -12 -1200 Etc/GMT+12
2016-12-28 00:00:00 +12 +1200 Asia/Anadyr
2016-12-28 00:00:00 +12 +1200 Asia/Kamchatka
2016-12-28 00:00:00 +12 +1200 Etc/GMT-12
2016-12-28 00:00:00 TVT +1200 Pacific/Funafuti
2016-12-28 00:00:00 MHT +1200 Pacific/Kwajalein
2016-12-28 00:00:00 MHT +1200 Pacific/Majuro
2016-12-28 00:00:00 NRT +1200 Pacific/Nauru
2016-12-28 00:00:00 GILT +1200 Pacific/Tarawa
2016-12-28 00:00:00 WAKT +1200 Pacific/Wake
2016-12-28 00:00:00 WFT +1200 Pacific/Wallis
These are all the timezones it is midnight at 2016-12-27 13:00:00 UTC
2016-12-28 00:00:00 +11 +1100 Antarctica/Casey
2016-12-28 00:00:00 MIST +1100 Antarctica/Macquarie
2016-12-28 00:00:00 +11 +1100 Asia/Magadan
2016-12-28 00:00:00 +11 +1100 Asia/Sakhalin
2016-12-28 00:00:00 +11 +1100 Asia/Srednekolymsk
2016-12-28 00:00:00 AEDT +1100 Australia/Currie
2016-12-28 00:00:00 AEDT +1100 Australia/Hobart
2016-12-28 00:00:00 LHDT +1100 Australia/Lord_Howe
2016-12-28 00:00:00 AEDT +1100 Australia/Melbourne
2016-12-28 00:00:00 AEDT +1100 Australia/Sydney
2016-12-28 00:00:00 +11 +1100 Etc/GMT-11
2016-12-28 00:00:00 BST +1100 Pacific/Bougainville
2016-12-28 00:00:00 VUT +1100 Pacific/Efate
2016-12-28 00:00:00 SBT +1100 Pacific/Guadalcanal
2016-12-28 00:00:00 KOST +1100 Pacific/Kosrae
2016-12-28 00:00:00 NFT +1100 Pacific/Norfolk
2016-12-28 00:00:00 NCT +1100 Pacific/Noumea
2016-12-28 00:00:00 PONT +1100 Pacific/Pohnpei
These are all the timezones it is midnight at 2016-12-27 14:00:00 UTC
2016-12-28 00:00:00 +10 +1000 Antarctica/DumontDUrville
2016-12-28 00:00:00 +10 +1000 Asia/Ust-Nera
2016-12-28 00:00:00 +10 +1000 Asia/Vladivostok
2016-12-28 00:00:00 AEST +1000 Australia/Brisbane
2016-12-28 00:00:00 AEST +1000 Australia/Lindeman
2016-12-28 00:00:00 +10 +1000 Etc/GMT-10
2016-12-28 00:00:00 CHUT +1000 Pacific/Chuuk
2016-12-28 00:00:00 ChST +1000 Pacific/Guam
2016-12-28 00:00:00 PGT +1000 Pacific/Port_Moresby
These are all the timezones it is midnight at 2016-12-27 15:00:00 UTC
2016-12-28 00:00:00 +09 +0900 Asia/Chita
2016-12-28 00:00:00 TLT +0900 Asia/Dili
2016-12-28 00:00:00 WIT +0900 Asia/Jayapura
2016-12-28 00:00:00 +09 +0900 Asia/Khandyga
2016-12-28 00:00:00 KST +0900 Asia/Seoul
2016-12-28 00:00:00 JST +0900 Asia/Tokyo
2016-12-28 00:00:00 +09 +0900 Asia/Yakutsk
2016-12-28 00:00:00 +09 +0900 Etc/GMT-9
2016-12-28 00:00:00 PWT +0900 Pacific/Palau
These are all the timezones it is midnight at 2016-12-27 16:00:00 UTC
2016-12-28 00:00:00 BNT +0800 Asia/Brunei
2016-12-28 00:00:00 CHOT +0800 Asia/Choibalsan
2016-12-28 00:00:00 HKT +0800 Asia/Hong_Kong
2016-12-28 00:00:00 +08 +0800 Asia/Irkutsk
2016-12-28 00:00:00 MYT +0800 Asia/Kuala_Lumpur
2016-12-28 00:00:00 MYT +0800 Asia/Kuching
2016-12-28 00:00:00 CST +0800 Asia/Macau
2016-12-28 00:00:00 WITA +0800 Asia/Makassar
2016-12-28 00:00:00 PHT +0800 Asia/Manila
2016-12-28 00:00:00 CST +0800 Asia/Shanghai
2016-12-28 00:00:00 SGT +0800 Asia/Singapore
2016-12-28 00:00:00 CST +0800 Asia/Taipei
2016-12-28 00:00:00 ULAT +0800 Asia/Ulaanbaatar
2016-12-28 00:00:00 AWST +0800 Australia/Perth
2016-12-28 00:00:00 +08 +0800 Etc/GMT-8
These are all the timezones it is midnight at 2016-12-27 17:00:00 UTC
2016-12-28 00:00:00 +07 +0700 Antarctica/Davis
2016-12-28 00:00:00 ICT +0700 Asia/Bangkok
2016-12-28 00:00:00 +07 +0700 Asia/Barnaul
2016-12-28 00:00:00 ICT +0700 Asia/Ho_Chi_Minh
2016-12-28 00:00:00 HOVT +0700 Asia/Hovd
2016-12-28 00:00:00 WIB +0700 Asia/Jakarta
2016-12-28 00:00:00 +07 +0700 Asia/Krasnoyarsk
2016-12-28 00:00:00 +07 +0700 Asia/Novokuznetsk
2016-12-28 00:00:00 +07 +0700 Asia/Novosibirsk
2016-12-28 00:00:00 WIB +0700 Asia/Pontianak
2016-12-28 00:00:00 +07 +0700 Asia/Tomsk
2016-12-28 00:00:00 +07 +0700 Etc/GMT-7
2016-12-28 00:00:00 CXT +0700 Indian/Christmas
These are all the timezones it is midnight at 2016-12-27 18:00:00 UTC
2016-12-28 00:00:00 +06 +0600 Antarctica/Vostok
2016-12-28 00:00:00 +06 +0600 Asia/Almaty
2016-12-28 00:00:00 +06 +0600 Asia/Bishkek
2016-12-28 00:00:00 BDT +0600 Asia/Dhaka
2016-12-28 00:00:00 +06 +0600 Asia/Omsk
2016-12-28 00:00:00 +06 +0600 Asia/Qyzylorda
2016-12-28 00:00:00 BTT +0600 Asia/Thimphu
2016-12-28 00:00:00 XJT +0600 Asia/Urumqi
2016-12-28 00:00:00 +06 +0600 Etc/GMT-6
2016-12-28 00:00:00 IOT +0600 Indian/Chagos
These are all the timezones it is midnight at 2016-12-27 19:00:00 UTC
2016-12-28 00:00:00 +05 +0500 Antarctica/Mawson
2016-12-28 00:00:00 +05 +0500 Asia/Aqtau
2016-12-28 00:00:00 +05 +0500 Asia/Aqtobe
2016-12-28 00:00:00 +05 +0500 Asia/Ashgabat
2016-12-28 00:00:00 +05 +0500 Asia/Atyrau
2016-12-28 00:00:00 +05 +0500 Asia/Dushanbe
2016-12-28 00:00:00 PKT +0500 Asia/Karachi
2016-12-28 00:00:00 +05 +0500 Asia/Oral
2016-12-28 00:00:00 +05 +0500 Asia/Samarkand
2016-12-28 00:00:00 +05 +0500 Asia/Tashkent
2016-12-28 00:00:00 +05 +0500 Asia/Yekaterinburg
2016-12-28 00:00:00 +05 +0500 Etc/GMT-5
2016-12-28 00:00:00 +05 +0500 Indian/Kerguelen
2016-12-28 00:00:00 MVT +0500 Indian/Maldives
These are all the timezones it is midnight at 2016-12-27 20:00:00 UTC
2016-12-28 00:00:00 +04 +0400 Asia/Baku
2016-12-28 00:00:00 GST +0400 Asia/Dubai
2016-12-28 00:00:00 +04 +0400 Asia/Tbilisi
2016-12-28 00:00:00 +04 +0400 Asia/Yerevan
2016-12-28 00:00:00 +04 +0400 Etc/GMT-4
2016-12-28 00:00:00 +04 +0400 Europe/Astrakhan
2016-12-28 00:00:00 +04 +0400 Europe/Samara
2016-12-28 00:00:00 +04 +0400 Europe/Saratov
2016-12-28 00:00:00 +04 +0400 Europe/Ulyanovsk
2016-12-28 00:00:00 SCT +0400 Indian/Mahe
2016-12-28 00:00:00 MUT +0400 Indian/Mauritius
2016-12-28 00:00:00 RET +0400 Indian/Reunion
These are all the timezones it is midnight at 2016-12-27 21:00:00 UTC
2016-12-28 00:00:00 EAT +0300 Africa/Khartoum
2016-12-28 00:00:00 EAT +0300 Africa/Nairobi
2016-12-28 00:00:00 +03 +0300 Antarctica/Syowa
2016-12-28 00:00:00 AST +0300 Asia/Baghdad
2016-12-28 00:00:00 +03 +0300 Asia/Famagusta
2016-12-28 00:00:00 AST +0300 Asia/Qatar
2016-12-28 00:00:00 AST +0300 Asia/Riyadh
2016-12-28 00:00:00 +03 +0300 Etc/GMT-3
2016-12-28 00:00:00 +03 +0300 Europe/Istanbul
2016-12-28 00:00:00 +03 +0300 Europe/Kirov
2016-12-28 00:00:00 +03 +0300 Europe/Minsk
2016-12-28 00:00:00 MSK +0300 Europe/Moscow
2016-12-28 00:00:00 MSK +0300 Europe/Simferopol
2016-12-28 00:00:00 +03 +0300 Europe/Volgograd
These are all the timezones it is midnight at 2016-12-27 22:00:00 UTC
2016-12-28 00:00:00 EET +0200 Africa/Cairo
2016-12-28 00:00:00 SAST +0200 Africa/Johannesburg
2016-12-28 00:00:00 CAT +0200 Africa/Maputo
2016-12-28 00:00:00 EET +0200 Africa/Tripoli
2016-12-28 00:00:00 WAST +0200 Africa/Windhoek
2016-12-28 00:00:00 EET +0200 Asia/Amman
2016-12-28 00:00:00 EET +0200 Asia/Beirut
2016-12-28 00:00:00 EET +0200 Asia/Damascus
2016-12-28 00:00:00 EET +0200 Asia/Gaza
2016-12-28 00:00:00 EET +0200 Asia/Hebron
2016-12-28 00:00:00 IST +0200 Asia/Jerusalem
2016-12-28 00:00:00 EET +0200 Asia/Nicosia
2016-12-28 00:00:00 EET +0200 EET
2016-12-28 00:00:00 +02 +0200 Etc/GMT-2
2016-12-28 00:00:00 EET +0200 Europe/Athens
2016-12-28 00:00:00 EET +0200 Europe/Bucharest
2016-12-28 00:00:00 EET +0200 Europe/Chisinau
2016-12-28 00:00:00 EET +0200 Europe/Helsinki
2016-12-28 00:00:00 EET +0200 Europe/Kaliningrad
2016-12-28 00:00:00 EET +0200 Europe/Kiev
2016-12-28 00:00:00 EET +0200 Europe/Riga
2016-12-28 00:00:00 EET +0200 Europe/Sofia
2016-12-28 00:00:00 EET +0200 Europe/Tallinn
2016-12-28 00:00:00 EET +0200 Europe/Uzhgorod
2016-12-28 00:00:00 EET +0200 Europe/Vilnius
2016-12-28 00:00:00 EET +0200 Europe/Zaporozhye
These are all the timezones it is midnight at 2016-12-27 23:00:00 UTC
2016-12-28 00:00:00 CET +0100 Africa/Algiers
2016-12-28 00:00:00 CET +0100 Africa/Ceuta
2016-12-28 00:00:00 WAT +0100 Africa/Lagos
2016-12-28 00:00:00 WAT +0100 Africa/Ndjamena
2016-12-28 00:00:00 CET +0100 Africa/Tunis
2016-12-28 00:00:00 CET +0100 CET
2016-12-28 00:00:00 +01 +0100 Etc/GMT-1
2016-12-28 00:00:00 CET +0100 Europe/Amsterdam
2016-12-28 00:00:00 CET +0100 Europe/Andorra
2016-12-28 00:00:00 CET +0100 Europe/Belgrade
2016-12-28 00:00:00 CET +0100 Europe/Berlin
2016-12-28 00:00:00 CET +0100 Europe/Brussels
2016-12-28 00:00:00 CET +0100 Europe/Budapest
2016-12-28 00:00:00 CET +0100 Europe/Copenhagen
2016-12-28 00:00:00 CET +0100 Europe/Gibraltar
2016-12-28 00:00:00 CET +0100 Europe/Luxembourg
2016-12-28 00:00:00 CET +0100 Europe/Madrid
2016-12-28 00:00:00 CET +0100 Europe/Malta
2016-12-28 00:00:00 CET +0100 Europe/Monaco
2016-12-28 00:00:00 CET +0100 Europe/Oslo
2016-12-28 00:00:00 CET +0100 Europe/Paris
2016-12-28 00:00:00 CET +0100 Europe/Prague
2016-12-28 00:00:00 CET +0100 Europe/Rome
2016-12-28 00:00:00 CET +0100 Europe/Stockholm
2016-12-28 00:00:00 CET +0100 Europe/Tirane
2016-12-28 00:00:00 CET +0100 Europe/Vienna
2016-12-28 00:00:00 CET +0100 Europe/Warsaw
2016-12-28 00:00:00 CET +0100 Europe/Zurich
2016-12-28 00:00:00 MET +0100 MET
These are all the timezones it is midnight at 2016-12-28 00:00:00 UTC
2016-12-28 00:00:00 GMT +0000 Africa/Abidjan
2016-12-28 00:00:00 GMT +0000 Africa/Accra
2016-12-28 00:00:00 GMT +0000 Africa/Bissau
2016-12-28 00:00:00 WET +0000 Africa/Casablanca
2016-12-28 00:00:00 WET +0000 Africa/El_Aaiun
2016-12-28 00:00:00 GMT +0000 Africa/Monrovia
2016-12-28 00:00:00 GMT +0000 America/Danmarkshavn
2016-12-28 00:00:00 +00 +0000 Antarctica/Troll
2016-12-28 00:00:00 WET +0000 Atlantic/Canary
2016-12-28 00:00:00 WET +0000 Atlantic/Faroe
2016-12-28 00:00:00 WET +0000 Atlantic/Madeira
2016-12-28 00:00:00 GMT +0000 Atlantic/Reykjavik
2016-12-28 00:00:00 GMT +0000 Etc/GMT
2016-12-28 00:00:00 UCT +0000 Etc/UCT
2016-12-28 00:00:00 UTC +0000 Etc/UTC
2016-12-28 00:00:00 GMT +0000 Europe/Dublin
2016-12-28 00:00:00 WET +0000 Europe/Lisbon
2016-12-28 00:00:00 GMT +0000 Europe/London
2016-12-28 00:00:00 WET +0000 WET
These are all the timezones it is midnight at 2016-12-28 01:00:00 UTC
2016-12-28 00:00:00 EGT -0100 America/Scoresbysund
2016-12-28 00:00:00 AZOT -0100 Atlantic/Azores
2016-12-28 00:00:00 CVT -0100 Atlantic/Cape_Verde
2016-12-28 00:00:00 -01 -0100 Etc/GMT+1
These are all the timezones it is midnight at 2016-12-28 02:00:00 UTC
2016-12-28 00:00:00 FNT -0200 America/Noronha
2016-12-28 00:00:00 BRST -0200 America/Sao_Paulo
2016-12-28 00:00:00 GST -0200 Atlantic/South_Georgia
2016-12-28 00:00:00 -02 -0200 Etc/GMT+2
These are all the timezones it is midnight at 2016-12-28 03:00:00 UTC
2016-12-28 00:00:00 BRT -0300 America/Araguaina
2016-12-28 00:00:00 ART -0300 America/Argentina/Buenos_Aires
2016-12-28 00:00:00 ART -0300 America/Argentina/Catamarca
2016-12-28 00:00:00 ART -0300 America/Argentina/Cordoba
2016-12-28 00:00:00 ART -0300 America/Argentina/Jujuy
2016-12-28 00:00:00 ART -0300 America/Argentina/La_Rioja
2016-12-28 00:00:00 ART -0300 America/Argentina/Mendoza
2016-12-28 00:00:00 ART -0300 America/Argentina/Rio_Gallegos
2016-12-28 00:00:00 ART -0300 America/Argentina/Salta
2016-12-28 00:00:00 ART -0300 America/Argentina/San_Juan
2016-12-28 00:00:00 ART -0300 America/Argentina/San_Luis
2016-12-28 00:00:00 ART -0300 America/Argentina/Tucuman
2016-12-28 00:00:00 ART -0300 America/Argentina/Ushuaia
2016-12-28 00:00:00 PYST -0300 America/Asuncion
2016-12-28 00:00:00 BRT -0300 America/Bahia
2016-12-28 00:00:00 BRT -0300 America/Belem
2016-12-28 00:00:00 AMST -0300 America/Campo_Grande
2016-12-28 00:00:00 GFT -0300 America/Cayenne
2016-12-28 00:00:00 AMST -0300 America/Cuiaba
2016-12-28 00:00:00 BRT -0300 America/Fortaleza
2016-12-28 00:00:00 WGT -0300 America/Godthab
2016-12-28 00:00:00 BRT -0300 America/Maceio
2016-12-28 00:00:00 PMST -0300 America/Miquelon
2016-12-28 00:00:00 UYT -0300 America/Montevideo
2016-12-28 00:00:00 SRT -0300 America/Paramaribo
2016-12-28 00:00:00 BRT -0300 America/Recife
2016-12-28 00:00:00 BRT -0300 America/Santarem
2016-12-28 00:00:00 CLST -0300 America/Santiago
2016-12-28 00:00:00 CLST -0300 Antarctica/Palmer
2016-12-28 00:00:00 -03 -0300 Antarctica/Rothera
2016-12-28 00:00:00 FKST -0300 Atlantic/Stanley
2016-12-28 00:00:00 -03 -0300 Etc/GMT+3
These are all the timezones it is midnight at 2016-12-28 04:00:00 UTC
2016-12-28 00:00:00 AST -0400 America/Barbados
2016-12-28 00:00:00 AST -0400 America/Blanc-Sablon
2016-12-28 00:00:00 AMT -0400 America/Boa_Vista
2016-12-28 00:00:00 VET -0400 America/Caracas
2016-12-28 00:00:00 AST -0400 America/Curacao
2016-12-28 00:00:00 AST -0400 America/Glace_Bay
2016-12-28 00:00:00 AST -0400 America/Goose_Bay
2016-12-28 00:00:00 AST -0400 America/Grand_Turk
2016-12-28 00:00:00 GYT -0400 America/Guyana
2016-12-28 00:00:00 AST -0400 America/Halifax
2016-12-28 00:00:00 BOT -0400 America/La_Paz
2016-12-28 00:00:00 AMT -0400 America/Manaus
2016-12-28 00:00:00 AST -0400 America/Martinique
2016-12-28 00:00:00 AST -0400 America/Moncton
2016-12-28 00:00:00 AST -0400 America/Port_of_Spain
2016-12-28 00:00:00 AMT -0400 America/Porto_Velho
2016-12-28 00:00:00 AST -0400 America/Puerto_Rico
2016-12-28 00:00:00 AST -0400 America/Santo_Domingo
2016-12-28 00:00:00 AST -0400 America/Thule
2016-12-28 00:00:00 AST -0400 Atlantic/Bermuda
2016-12-28 00:00:00 -04 -0400 Etc/GMT+4
These are all the timezones it is midnight at 2016-12-28 05:00:00 UTC
2016-12-28 00:00:00 EST -0500 America/Atikokan
2016-12-28 00:00:00 COT -0500 America/Bogota
2016-12-28 00:00:00 EST -0500 America/Cancun
2016-12-28 00:00:00 EST -0500 America/Detroit
2016-12-28 00:00:00 ACT -0500 America/Eirunepe
2016-12-28 00:00:00 ECT -0500 America/Guayaquil
2016-12-28 00:00:00 CST -0500 America/Havana
2016-12-28 00:00:00 EST -0500 America/Indiana/Indianapolis
2016-12-28 00:00:00 EST -0500 America/Indiana/Marengo
2016-12-28 00:00:00 EST -0500 America/Indiana/Petersburg
2016-12-28 00:00:00 EST -0500 America/Indiana/Vevay
2016-12-28 00:00:00 EST -0500 America/Indiana/Vincennes
2016-12-28 00:00:00 EST -0500 America/Indiana/Winamac
2016-12-28 00:00:00 EST -0500 America/Iqaluit
2016-12-28 00:00:00 EST -0500 America/Jamaica
2016-12-28 00:00:00 EST -0500 America/Kentucky/Louisville
2016-12-28 00:00:00 EST -0500 America/Kentucky/Monticello
2016-12-28 00:00:00 PET -0500 America/Lima
2016-12-28 00:00:00 EST -0500 America/Nassau
2016-12-28 00:00:00 EST -0500 America/New_York
2016-12-28 00:00:00 EST -0500 America/Nipigon
2016-12-28 00:00:00 EST -0500 America/Panama
2016-12-28 00:00:00 EST -0500 America/Pangnirtung
2016-12-28 00:00:00 EST -0500 America/Port-au-Prince
2016-12-28 00:00:00 ACT -0500 America/Rio_Branco
2016-12-28 00:00:00 EST -0500 America/Thunder_Bay
2016-12-28 00:00:00 EST -0500 America/Toronto
2016-12-28 00:00:00 EST -0500 EST
2016-12-28 00:00:00 EST -0500 EST5EDT
2016-12-28 00:00:00 -05 -0500 Etc/GMT+5
2016-12-28 00:00:00 EASST -0500 Pacific/Easter
These are all the timezones it is midnight at 2016-12-28 06:00:00 UTC
2016-12-28 00:00:00 CST -0600 America/Bahia_Banderas
2016-12-28 00:00:00 CST -0600 America/Belize
2016-12-28 00:00:00 CST -0600 America/Chicago
2016-12-28 00:00:00 CST -0600 America/Costa_Rica
2016-12-28 00:00:00 CST -0600 America/El_Salvador
2016-12-28 00:00:00 CST -0600 America/Guatemala
2016-12-28 00:00:00 CST -0600 America/Indiana/Knox
2016-12-28 00:00:00 CST -0600 America/Indiana/Tell_City
2016-12-28 00:00:00 CST -0600 America/Managua
2016-12-28 00:00:00 CST -0600 America/Matamoros
2016-12-28 00:00:00 CST -0600 America/Menominee
2016-12-28 00:00:00 CST -0600 America/Merida
2016-12-28 00:00:00 CST -0600 America/Mexico_City
2016-12-28 00:00:00 CST -0600 America/Monterrey
2016-12-28 00:00:00 CST -0600 America/North_Dakota/Beulah
2016-12-28 00:00:00 CST -0600 America/North_Dakota/Center
2016-12-28 00:00:00 CST -0600 America/North_Dakota/New_Salem
2016-12-28 00:00:00 CST -0600 America/Rainy_River
2016-12-28 00:00:00 CST -0600 America/Rankin_Inlet
2016-12-28 00:00:00 CST -0600 America/Regina
2016-12-28 00:00:00 CST -0600 America/Resolute
2016-12-28 00:00:00 CST -0600 America/Swift_Current
2016-12-28 00:00:00 CST -0600 America/Tegucigalpa
2016-12-28 00:00:00 CST -0600 America/Winnipeg
2016-12-28 00:00:00 CST -0600 CST6CDT
2016-12-28 00:00:00 -06 -0600 Etc/GMT+6
2016-12-28 00:00:00 GALT -0600 Pacific/Galapagos
These are all the timezones it is midnight at 2016-12-28 07:00:00 UTC
2016-12-28 00:00:00 MST -0700 America/Boise
2016-12-28 00:00:00 MST -0700 America/Cambridge_Bay
2016-12-28 00:00:00 MST -0700 America/Chihuahua
2016-12-28 00:00:00 MST -0700 America/Creston
2016-12-28 00:00:00 MST -0700 America/Dawson_Creek
2016-12-28 00:00:00 MST -0700 America/Denver
2016-12-28 00:00:00 MST -0700 America/Edmonton
2016-12-28 00:00:00 MST -0700 America/Fort_Nelson
2016-12-28 00:00:00 MST -0700 America/Hermosillo
2016-12-28 00:00:00 MST -0700 America/Inuvik
2016-12-28 00:00:00 MST -0700 America/Mazatlan
2016-12-28 00:00:00 MST -0700 America/Ojinaga
2016-12-28 00:00:00 MST -0700 America/Phoenix
2016-12-28 00:00:00 MST -0700 America/Yellowknife
2016-12-28 00:00:00 -07 -0700 Etc/GMT+7
2016-12-28 00:00:00 MST -0700 MST
2016-12-28 00:00:00 MST -0700 MST7MDT
These are all the timezones it is midnight at 2016-12-28 08:00:00 UTC
2016-12-28 00:00:00 PST -0800 America/Dawson
2016-12-28 00:00:00 PST -0800 America/Los_Angeles
2016-12-28 00:00:00 PST -0800 America/Tijuana
2016-12-28 00:00:00 PST -0800 America/Vancouver
2016-12-28 00:00:00 PST -0800 America/Whitehorse
2016-12-28 00:00:00 -08 -0800 Etc/GMT+8
2016-12-28 00:00:00 PST -0800 PST8PDT
2016-12-28 00:00:00 PST -0800 Pacific/Pitcairn
These are all the timezones it is midnight at 2016-12-28 09:00:00 UTC
2016-12-28 00:00:00 AKST -0900 America/Anchorage
2016-12-28 00:00:00 AKST -0900 America/Juneau
2016-12-28 00:00:00 AKST -0900 America/Metlakatla
2016-12-28 00:00:00 AKST -0900 America/Nome
2016-12-28 00:00:00 AKST -0900 America/Sitka
2016-12-28 00:00:00 AKST -0900 America/Yakutat
2016-12-28 00:00:00 -09 -0900 Etc/GMT+9
2016-12-28 00:00:00 GAMT -0900 Pacific/Gambier
These are all the timezones it is midnight at 2016-12-28 10:00:00 UTC
2016-12-28 00:00:00 HST -1000 America/Adak
2016-12-28 00:00:00 -10 -1000 Etc/GMT+10
2016-12-28 00:00:00 HST -1000 HST
2016-12-28 00:00:00 HST -1000 Pacific/Honolulu
2016-12-28 00:00:00 CKT -1000 Pacific/Rarotonga
2016-12-28 00:00:00 TAHT -1000 Pacific/Tahiti
2016-12-29 00:00:00 +14 +1400 Etc/GMT-14
2016-12-29 00:00:00 WSDT +1400 Pacific/Apia
2016-12-29 00:00:00 LINT +1400 Pacific/Kiritimati
2016-12-29 00:00:00 +14 +1400 Pacific/Tongatapu
These are all the timezones it is midnight at 2016-12-28 11:00:00 UTC
2016-12-28 00:00:00 -11 -1100 Etc/GMT+11
2016-12-28 00:00:00 NUT -1100 Pacific/Niue
2016-12-28 00:00:00 SST -1100 Pacific/Pago_Pago
2016-12-29 00:00:00 +13 +1300 Etc/GMT-13
2016-12-29 00:00:00 NZDT +1300 Pacific/Auckland
2016-12-29 00:00:00 PHOT +1300 Pacific/Enderbury
2016-12-29 00:00:00 TKT +1300 Pacific/Fakaofo
2016-12-29 00:00:00 FJST +1300 Pacific/Fiji
These are all the timezones it is midnight at 2016-12-28 12:00:00 UTC
2016-12-28 00:00:00 -12 -1200 Etc/GMT+12
2016-12-29 00:00:00 +12 +1200 Asia/Anadyr
2016-12-29 00:00:00 +12 +1200 Asia/Kamchatka
2016-12-29 00:00:00 +12 +1200 Etc/GMT-12
2016-12-29 00:00:00 TVT +1200 Pacific/Funafuti
2016-12-29 00:00:00 MHT +1200 Pacific/Kwajalein
2016-12-29 00:00:00 MHT +1200 Pacific/Majuro
2016-12-29 00:00:00 NRT +1200 Pacific/Nauru
2016-12-29 00:00:00 GILT +1200 Pacific/Tarawa
2016-12-29 00:00:00 WAKT +1200 Pacific/Wake
2016-12-29 00:00:00 WFT +1200 Pacific/Wallis
These are all the timezones it is midnight at 2016-12-28 13:00:00 UTC
2016-12-29 00:00:00 +11 +1100 Antarctica/Casey
2016-12-29 00:00:00 MIST +1100 Antarctica/Macquarie
2016-12-29 00:00:00 +11 +1100 Asia/Magadan
2016-12-29 00:00:00 +11 +1100 Asia/Sakhalin
2016-12-29 00:00:00 +11 +1100 Asia/Srednekolymsk
2016-12-29 00:00:00 AEDT +1100 Australia/Currie
2016-12-29 00:00:00 AEDT +1100 Australia/Hobart
2016-12-29 00:00:00 LHDT +1100 Australia/Lord_Howe
2016-12-29 00:00:00 AEDT +1100 Australia/Melbourne
2016-12-29 00:00:00 AEDT +1100 Australia/Sydney
2016-12-29 00:00:00 +11 +1100 Etc/GMT-11
2016-12-29 00:00:00 BST +1100 Pacific/Bougainville
2016-12-29 00:00:00 VUT +1100 Pacific/Efate
2016-12-29 00:00:00 SBT +1100 Pacific/Guadalcanal
2016-12-29 00:00:00 KOST +1100 Pacific/Kosrae
2016-12-29 00:00:00 NFT +1100 Pacific/Norfolk
2016-12-29 00:00:00 NCT +1100 Pacific/Noumea
2016-12-29 00:00:00 PONT +1100 Pacific/Pohnpei
注意:
2016-12-28 10:00:00 UTC在其结果中列出太平洋/檀香山和太平洋/汤加塔普(以及其他几个)。
这些结果列出了-10/+14
和-11/+13
配对的所有以及其他几个,但其他几个只涉及“海上”时区如“Etc / GMT + 12”。
如果您改变要探索的节目2016-10-16 America/Sao_Paulo
从未列出,虽然它列于2016-12-28,因为America/Sao_Paulo
在2016-10没有午夜-16。但您确实在2016-10-16 03:00:00 UTC(偏移-0300)下列出了America/Bahia
。
更改程序以探索2016-11-06显示America/Havana
列于2016-11-06 04:00:00 UTC和2016-11-06 05:00:00 UTC
在此处突出显示的示例的 none 中,有一个唯一时区,在此时间点为给定UTC时间点的午夜。可能存在这样一个时区的时区,其UTC时间偏差不是整数小时。
啊,是的,这里有几个:
These are all the timezones it is midnight at 2016-12-27 09:30:00 UTC
2016-12-27 00:00:00 MART -0930 Pacific/Marquesas
These are all the timezones it is midnight at 2016-12-27 10:15:00 UTC
2016-12-28 00:00:00 CHADT +1345 Pacific/Chatham
These are all the timezones it is midnight at 2016-12-27 14:30:00 UTC
2016-12-28 00:00:00 ACST +0930 Australia/Darwin
These are all the timezones it is midnight at 2016-12-27 15:15:00 UTC
2016-12-28 00:00:00 ACWST +0845 Australia/Eucla
These are all the timezones it is midnight at 2016-12-27 15:30:00 UTC
2016-12-28 00:00:00 KST +0830 Asia/Pyongyang
These are all the timezones it is midnight at 2016-12-27 18:15:00 UTC
2016-12-28 00:00:00 NPT +0545 Asia/Kathmandu
These are all the timezones it is midnight at 2016-12-27 19:30:00 UTC
2016-12-28 00:00:00 AFT +0430 Asia/Kabul
These are all the timezones it is midnight at 2016-12-27 20:30:00 UTC
2016-12-28 00:00:00 IRST +0330 Asia/Tehran
These are all the timezones it is midnight at 2016-12-28 03:30:00 UTC
2016-12-28 00:00:00 NST -0330 America/St_Johns
答案 1 :(得分:3)
在某些限制条件下,可以识别时区偏移量(UTC-05:00
),但不能识别原始时区(America/New_York
)。霍华德在答案中表示,你只能列出当时偏移可能属于的可能时区。还有其他边缘情况使这个问题变得困难:
您明确说明了如何无法确定国际日期变更线附近的抵消日期。
例如,考虑2016-12-31T10:00:00Z
。这可能是2016-12-31T00:00:00-10:00
(可能是Pacific/Honolulu
),也可能是2017-01-01T00:00:00+14:00
(可能是Pacific/Tongatapu
)。
-10/+14
和-11/+13
配对都是可能的,但地球上没有人居住的地方实际使用-12
。因此,如果你的价值正好在中午,那么它们可能是+12
,除非你在海上与船只打交道。
您所期望的时区中的本地午夜值可能不存在。
2016-10-16T03:00:00Z
是America/Sao_Paulo
和America/Bahia
(都在巴西)的当天开始。但是,America/Sao_Paulo
的当地时间为01:00
,而不是00:00
。由于他们的DST春季前进过渡,当天没有午夜。您所期望的时区中的本地午夜值可能会存在两次。
America/Havana
中,2016-11-06T04:00:00Z
和2016-11-06T05:00:00Z
的本地时间为00:00
,原因是他们的DST回退过渡。因此,在一般情况下,您可以将大多数解析回原始偏移量,但对于-10
,{{1}的时区,您会有歧义}},-11
或+13
偏移,以及在午夜(春季)或凌晨1:00(秋季)进行DST过渡的时区。 (请记住,北半球/南半球的春/秋季不同。)
答案 2 :(得分:0)
这是一些使用现代 java.time 类的Java代码。
假设您在给定的时区(例如America / New_York)中输入本地日期(例如2016-12-28),然后将该日期的开始时间转换为UTC(在这种情况下为2016-12-28T05:00:00Z )。
请注意,我们通过LocalDate::atStartOfDay
方法让 java.time 确定一天中的第一时刻。不要以为一天从00:00:00开始。诸如夏令时之类的异常表示一天可能在另一个时间(如01:00:00)开始。
LocalDate localDate = LocalDate.parse( "2016-12-28" ) ;
ZoneId zNewYork = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdtNewYork = localDate.atStartOfDay( zNewYork ) ; // First moment of the day in that zone on that date.
通过提取Instant
调整为UTC值。根据定义,Instant
始终采用UTC。
Instant instant = zdtNewYork.toInstant() ;
在数据库中存储的列类型类似于SQL标准TIMESTAMP WITH TIME ZONE
。
myPreparedStatement.setObject( … , instant ) ;
在不知道时区的情况下返回原始的本地日期?
检索。
Instant instant = myResultSet.getObject( … , Instant.class ) ;
现在尝试每个时区。仅供参考,请参阅list of zone names at Wikipedia,尽管该页面可能已过时。
对于每个区域,将我们的Instant
(我们的UTC时刻)调整到该区域,以获取ZonedDateTime
对象。某个时刻,时间轴上的同一点,但挂钟时间不同。
对于每个ZonedDateTime
,仅提取日期,不提取日期和时区。渲染LocalDate
对象。要求LocalDate
确定正在考虑的我们时区中的一天的第一时刻(可能在00:00:00发生或可能不发生)。这将产生另一个ZonedDateTime
对象。
从第二个ZonedDateTime
中提取一个Instant
,以调整回UTC。将这个新的Instant
对象与原始Instant
进行比较。如果它们相同,那么我们很受欢迎。我们已经确定了存储在数据库中的一天开始的时区。因此,我们上面产生的LocalDate
与原始存储在我们数据库中的日期相同。
List< ZoneId > hits = new ArrayList<>() ;
LocalDate originalLocalDate = null ;
Set< String > zoneIds = ZoneId.getAvailableZoneIds() ; // Gets the set of available zone IDs.
for( String zoneId : zoneIds ) {
ZoneId z = ZoneId.of( zoneId ) ; // Get zone with that name.
ZonedDateTime zdt = instant.atZone( z ) ;
LocalDate ld = zdt.toLocalDate() ; // Extract the date-only value, dropping the time-of-day and dropping the time zone.
ZonedDateTime startOfDay = ld.atStartOfDay( z ) ; // Determine first moment of the day on that date in that zone.
Instant instantOfStartOfDay = startOfDay.toInstant() ; // Adjust back to UTC.
boolean hit = instant.equals( instantOfStartOfDay ) ;
if( hit ) {
originalLocalDate = ld ;
hits.add( z ) ; // Collect this time zone as the zone possibly used originally.
}
}
请参阅此code run live at IdeOne.com。
运行时,我们看到该日期的America/New_York
时区比UTC偏移了五个小时。您可以从此列表中看到许多其他时区共享相同的-05:00
偏移量。
originalLocalDate.toString():2016-12-28
hits.toString():[美国/巴拿马,美国/印第安纳州/彼得斯堡,美国/埃鲁尼佩,古巴,Etc / GMT + 5,太平洋/复活节,美国/ Fort_Wayne,美国/哈瓦那,美国/ Porto_Acre,美国/密歇根州,美国/路易斯维尔,美国/瓜亚基尔,美国/印第安纳州/韦韦,美国/印第安纳州/文森斯,美国/印第安纳波利斯,美国/伊卡卢伊特,美国/肯塔基州/路易斯维尔,EST5EDT,美国/拿骚,美国/牙买加,美国/ Atikokan,美洲/肯塔基州/蒙蒂塞洛,美洲/珊瑚港,美洲/开曼,智利/东岛,美洲/印第安纳州/印第安纳波利斯,美洲/雷霆湾,美洲/印第安纳州/马伦戈,美洲/波哥大,SystemV / EST5,美洲/东部,加拿大/东部,美国/太子港,美国/尼皮贡,巴西/英亩,美国/东印第安纳州,美国/坎昆,美国/利马,美国/里奥布兰科,美国/底特律,牙买加,美国/庞尼通,美国/蒙特利尔,美国/印第安纳州/威纳马克,美国/纽约,美国/多伦多,SystemV / EST5EDT]
请注意,区域的结果列表可能不会不同。一些区域名称是别名,其中一个区域具有多个名称。例如,旧的Asia/Calcutta
现在是Asia/Kolkata
。
java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和SimpleDateFormat
。
目前位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*
类。
在哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如Interval
,YearWeek
,YearQuarter
和more。