On Mon, 14 Jul 2025 at 11:08, Björn Schäpers <g...@hazardy.de> wrote: > > Am 14.07.2025 um 10:20 schrieb Tomasz Kaminski: > > > > > > On Tue, Jul 8, 2025 at 10:48 PM Björn Schäpers <g...@hazardy.de > > <mailto:g...@hazardy.de>> wrote: > > > > From: Björn Schäpers <bjo...@hazardy.de <mailto:bjo...@hazardy.de>> > > > > I have based this on my previous (not yet landed) patch, but it only > > reuses the #ifdef to include <array>. Since std::array isn't used > > anywhere else I thought that was the right place to put it. > > > > I hope the formatting is okay. > > > > I've used wide strings for the Windows zone name and territory, since > > the Windows API returns wide strings and thus they can be compared > > directly. For the territory there exists a narrow string API, but > > internally it calls the wide string version and narrows it down. If > > desired I can switch to narrow strings, the conversion can be done by > > static_cast per character since only ASCII chars are used. > > > > -- >8 -- > > On Windows there is no API to get the current time zone as IANA name, > > instead Windows has its own zones. But there exists a mapping provided > > by the Unicode Consortium. This patch adds a script to convert the XML > > file with the mapping to a lookup table and adds a Windows code path to > > use that mapping. > > > > libstdc++-v3/Changelog: > > > > Implement std::chrono::current_zone() for Windows > > > > * include/bits/windows_zones-map.h: New file, contains the look > > up table. > > * scripts/gen_windows_zones_map.py: New file, generates > > windows_zones-map.h. > > * src/c++20/tzdb.cc (tzdb::current_zone): Add Windows code > > path. > > > > Signed-off-by: Björn Schäpers <bjo...@hazardy.de > > <mailto:bjo...@hazardy.de>> > > --- > > libstdc++-v3/include/bits/windows_zones-map.h | 407 ++++++++++++++++++ > > libstdc++-v3/scripts/gen_windows_zones_map.py | 128 ++++++ > > libstdc++-v3/src/c++20/tzdb.cc | 102 ++++- > > 3 files changed, 635 insertions(+), 2 deletions(-) > > create mode 100644 libstdc++-v3/include/bits/windows_zones-map.h > > create mode 100644 libstdc++-v3/scripts/gen_windows_zones_map.py > > > > diff --git a/libstdc++-v3/include/bits/windows_zones-map.h > > b/libstdc++-v3/ > > include/bits/windows_zones-map.h > > new file mode 100644 > > index 00000000000..7be736b063d > > --- /dev/null > > +++ b/libstdc++-v3/include/bits/windows_zones-map.h > > @@ -0,0 +1,407 @@ > > +// Generated by scripts/gen_windows_zones_map.py, do not edit. > > + > > +// Copyright The GNU Toolchain Authors. > > +// > > +// This file is part of the GNU ISO C++ Library. This library is free > > +// software; you can redistribute it and/or modify it under the > > +// terms of the GNU General Public License as published by the > > +// Free Software Foundation; either version 3, or (at your option) > > +// any later version. > > + > > +// This library is distributed in the hope that it will be useful, > > +// but WITHOUT ANY WARRANTY; without even the implied warranty of > > +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > > +// GNU General Public License for more details. > > + > > +// Under Section 7 of GPL version 3, you are granted additional > > +// permissions described in the GCC Runtime Library Exception, version > > +// 3.1, as published by the Free Software Foundation. > > + > > +// You should have received a copy of the GNU General Public License > > and > > +// a copy of the GCC Runtime Library Exception along with this program; > > +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, > > see > > +// <http://www.gnu.org/licenses/ <http://www.gnu.org/licenses/>>. > > + > > +/** @file bits/windows_zones-map.h > > + * This is an internal header file, included by other library headers. > > + * Do not attempt to use it directly. @headername{chrono} > > + */ > > + > > +#ifndef _GLIBCXX_GET_WINDOWS_ZONES_MAP > > +# error "This is not a public header, do not include it directly" > > +#endif > > + > > +struct windows_zone_map_entry > > +{ > > + wstring_view windows_name; > > + wstring_view territory; > > + string_view iana_name; > > +}; > > + > > +static constexpr array<windows_zone_map_entry, 361> windows_zone_map{ > > + { > > + {L"AUS Central Standard Time", L"001", "Australia/Darwin"}, > > + {L"AUS Eastern Standard Time", L"001", "Australia/Sydney"}, > > + {L"Afghanistan Standard Time", L"001", "Asia/Kabul"}, > > + {L"Alaskan Standard Time", L"001", "America/Anchorage"}, > > + {L"Aleutian Standard Time", L"001", "America/Adak"}, > > + {L"Altai Standard Time", L"001", "Asia/Barnaul"}, > > + {L"Arab Standard Time", L"001", "Asia/Riyadh"}, > > + {L"Arab Standard Time", L"BH", "Asia/Bahrain"}, > > + {L"Arab Standard Time", L"KW", "Asia/Kuwait"}, > > + {L"Arab Standard Time", L"QA", "Asia/Qatar"}, > > + {L"Arab Standard Time", L"YE", "Asia/Aden"}, > > + {L"Arabian Standard Time", L"001", "Asia/Dubai"}, > > + {L"Arabian Standard Time", L"OM", "Asia/Muscat"}, > > + {L"Arabian Standard Time", L"ZZ", "Etc/GMT-4"}, > > + {L"Arabic Standard Time", L"001", "Asia/Baghdad"}, > > + {L"Argentina Standard Time", L"001", "America/Buenos_Aires"}, > > + {L"Astrakhan Standard Time", L"001", "Europe/Astrakhan"}, > > + {L"Atlantic Standard Time", L"001", "America/Halifax"}, > > + {L"Atlantic Standard Time", L"BM", "Atlantic/Bermuda"}, > > + {L"Atlantic Standard Time", L"GL", "America/Thule"}, > > + {L"Aus Central W. Standard Time", L"001", "Australia/Eucla"}, > > + {L"Azerbaijan Standard Time", L"001", "Asia/Baku"}, > > + {L"Azores Standard Time", L"001", "Atlantic/Azores"}, > > + {L"Azores Standard Time", L"GL", "America/Scoresbysund"}, > > + {L"Bahia Standard Time", L"001", "America/Bahia"}, > > + {L"Bangladesh Standard Time", L"001", "Asia/Dhaka"}, > > + {L"Bangladesh Standard Time", L"BT", "Asia/Thimphu"}, > > + {L"Belarus Standard Time", L"001", "Europe/Minsk"}, > > + {L"Bougainville Standard Time", L"001", "Pacific/Bougainville"}, > > + {L"Canada Central Standard Time", L"001", "America/Regina"}, > > + {L"Cape Verde Standard Time", L"001", "Atlantic/Cape_Verde"}, > > + {L"Cape Verde Standard Time", L"ZZ", "Etc/GMT+1"}, > > + {L"Caucasus Standard Time", L"001", "Asia/Yerevan"}, > > + {L"Cen. Australia Standard Time", L"001", "Australia/Adelaide"}, > > + {L"Central America Standard Time", L"001", "America/Guatemala"}, > > + {L"Central America Standard Time", L"BZ", "America/Belize"}, > > + {L"Central America Standard Time", L"CR", "America/Costa_Rica"}, > > + {L"Central America Standard Time", L"EC", "Pacific/Galapagos"}, > > + {L"Central America Standard Time", L"HN", "America/Tegucigalpa"}, > > + {L"Central America Standard Time", L"NI", "America/Managua"}, > > + {L"Central America Standard Time", L"SV", "America/El_Salvador"}, > > + {L"Central America Standard Time", L"ZZ", "Etc/GMT+6"}, > > + {L"Central Asia Standard Time", L"001", "Asia/Bishkek"}, > > + {L"Central Asia Standard Time", L"AQ", "Antarctica/Vostok"}, > > + {L"Central Asia Standard Time", L"CN", "Asia/Urumqi"}, > > + {L"Central Asia Standard Time", L"IO", "Indian/Chagos"}, > > + {L"Central Asia Standard Time", L"ZZ", "Etc/GMT-6"}, > > + {L"Central Brazilian Standard Time", L"001", "America/Cuiaba"}, > > + {L"Central Europe Standard Time", L"001", "Europe/Budapest"}, > > + {L"Central Europe Standard Time", L"AL", "Europe/Tirane"}, > > + {L"Central Europe Standard Time", L"CZ", "Europe/Prague"}, > > + {L"Central Europe Standard Time", L"ME", "Europe/Podgorica"}, > > + {L"Central Europe Standard Time", L"RS", "Europe/Belgrade"}, > > + {L"Central Europe Standard Time", L"SI", "Europe/Ljubljana"}, > > + {L"Central Europe Standard Time", L"SK", "Europe/Bratislava"}, > > + {L"Central European Standard Time", L"001", "Europe/Warsaw"}, > > + {L"Central European Standard Time", L"BA", "Europe/Sarajevo"}, > > + {L"Central European Standard Time", L"HR", "Europe/Zagreb"}, > > + {L"Central European Standard Time", L"MK", "Europe/Skopje"}, > > + {L"Central Pacific Standard Time", L"001", "Pacific/Guadalcanal"}, > > + {L"Central Pacific Standard Time", L"AQ", "Antarctica/Casey"}, > > + {L"Central Pacific Standard Time", L"FM", "Pacific/Ponape"}, > > + {L"Central Pacific Standard Time", L"NC", "Pacific/Noumea"}, > > + {L"Central Pacific Standard Time", L"VU", "Pacific/Efate"}, > > + {L"Central Pacific Standard Time", L"ZZ", "Etc/GMT-11"}, > > + {L"Central Standard Time", L"001", "America/Chicago"}, > > + {L"Central Standard Time", L"CA", "America/Winnipeg"}, > > + {L"Central Standard Time", L"MX", "America/Matamoros"}, > > + {L"Central Standard Time (Mexico)", L"001", "America/Mexico_City"}, > > + {L"Chatham Islands Standard Time", L"001", "Pacific/Chatham"}, > > + {L"China Standard Time", L"001", "Asia/Shanghai"}, > > + {L"China Standard Time", L"HK", "Asia/Hong_Kong"}, > > + {L"China Standard Time", L"MO", "Asia/Macau"}, > > + {L"Cuba Standard Time", L"001", "America/Havana"}, > > + {L"Dateline Standard Time", L"001", "Etc/GMT+12"}, > > + {L"E. Africa Standard Time", L"001", "Africa/Nairobi"}, > > + {L"E. Africa Standard Time", L"AQ", "Antarctica/Syowa"}, > > + {L"E. Africa Standard Time", L"DJ", "Africa/Djibouti"}, > > + {L"E. Africa Standard Time", L"ER", "Africa/Asmera"}, > > + {L"E. Africa Standard Time", L"ET", "Africa/Addis_Ababa"}, > > + {L"E. Africa Standard Time", L"KM", "Indian/Comoro"}, > > + {L"E. Africa Standard Time", L"MG", "Indian/Antananarivo"}, > > + {L"E. Africa Standard Time", L"SO", "Africa/Mogadishu"}, > > + {L"E. Africa Standard Time", L"TZ", "Africa/Dar_es_Salaam"}, > > + {L"E. Africa Standard Time", L"UG", "Africa/Kampala"}, > > + {L"E. Africa Standard Time", L"YT", "Indian/Mayotte"}, > > + {L"E. Africa Standard Time", L"ZZ", "Etc/GMT-3"}, > > + {L"E. Australia Standard Time", L"001", "Australia/Brisbane"}, > > + {L"E. Europe Standard Time", L"001", "Europe/Chisinau"}, > > + {L"E. South America Standard Time", L"001", "America/Sao_Paulo"}, > > + {L"Easter Island Standard Time", L"001", "Pacific/Easter"}, > > + {L"Eastern Standard Time", L"001", "America/New_York"}, > > + {L"Eastern Standard Time", L"BS", "America/Nassau"}, > > + {L"Eastern Standard Time", L"CA", "America/Toronto"}, > > + {L"Eastern Standard Time (Mexico)", L"001", "America/Cancun"}, > > + {L"Egypt Standard Time", L"001", "Africa/Cairo"}, > > + {L"Ekaterinburg Standard Time", L"001", "Asia/Yekaterinburg"}, > > + {L"FLE Standard Time", L"001", "Europe/Kiev"}, > > + {L"FLE Standard Time", L"AX", "Europe/Mariehamn"}, > > + {L"FLE Standard Time", L"BG", "Europe/Sofia"}, > > + {L"FLE Standard Time", L"EE", "Europe/Tallinn"}, > > + {L"FLE Standard Time", L"FI", "Europe/Helsinki"}, > > + {L"FLE Standard Time", L"LT", "Europe/Vilnius"}, > > + {L"FLE Standard Time", L"LV", "Europe/Riga"}, > > + {L"Fiji Standard Time", L"001", "Pacific/Fiji"}, > > + {L"GMT Standard Time", L"001", "Europe/London"}, > > + {L"GMT Standard Time", L"ES", "Atlantic/Canary"}, > > + {L"GMT Standard Time", L"FO", "Atlantic/Faeroe"}, > > + {L"GMT Standard Time", L"GG", "Europe/Guernsey"}, > > + {L"GMT Standard Time", L"IE", "Europe/Dublin"}, > > + {L"GMT Standard Time", L"IM", "Europe/Isle_of_Man"}, > > + {L"GMT Standard Time", L"JE", "Europe/Jersey"}, > > + {L"GMT Standard Time", L"PT", "Europe/Lisbon"}, > > + {L"GTB Standard Time", L"001", "Europe/Bucharest"}, > > + {L"GTB Standard Time", L"CY", "Asia/Nicosia"}, > > + {L"GTB Standard Time", L"GR", "Europe/Athens"}, > > + {L"Georgian Standard Time", L"001", "Asia/Tbilisi"}, > > + {L"Greenland Standard Time", L"001", "America/Godthab"}, > > + {L"Greenwich Standard Time", L"001", "Atlantic/Reykjavik"}, > > + {L"Greenwich Standard Time", L"BF", "Africa/Ouagadougou"}, > > + {L"Greenwich Standard Time", L"CI", "Africa/Abidjan"}, > > + {L"Greenwich Standard Time", L"GH", "Africa/Accra"}, > > + {L"Greenwich Standard Time", L"GL", "America/Danmarkshavn"}, > > + {L"Greenwich Standard Time", L"GM", "Africa/Banjul"}, > > + {L"Greenwich Standard Time", L"GN", "Africa/Conakry"}, > > + {L"Greenwich Standard Time", L"GW", "Africa/Bissau"}, > > + {L"Greenwich Standard Time", L"LR", "Africa/Monrovia"}, > > + {L"Greenwich Standard Time", L"ML", "Africa/Bamako"}, > > + {L"Greenwich Standard Time", L"MR", "Africa/Nouakchott"}, > > + {L"Greenwich Standard Time", L"SH", "Atlantic/St_Helena"}, > > + {L"Greenwich Standard Time", L"SL", "Africa/Freetown"}, > > + {L"Greenwich Standard Time", L"SN", "Africa/Dakar"}, > > + {L"Greenwich Standard Time", L"TG", "Africa/Lome"}, > > + {L"Haiti Standard Time", L"001", "America/Port-au-Prince"}, > > + {L"Hawaiian Standard Time", L"001", "Pacific/Honolulu"}, > > + {L"Hawaiian Standard Time", L"CK", "Pacific/Rarotonga"}, > > + {L"Hawaiian Standard Time", L"PF", "Pacific/Tahiti"}, > > + {L"Hawaiian Standard Time", L"ZZ", "Etc/GMT+10"}, > > + {L"India Standard Time", L"001", "Asia/Calcutta"}, > > + {L"Iran Standard Time", L"001", "Asia/Tehran"}, > > + {L"Israel Standard Time", L"001", "Asia/Jerusalem"}, > > + {L"Jordan Standard Time", L"001", "Asia/Amman"}, > > + {L"Kaliningrad Standard Time", L"001", "Europe/Kaliningrad"}, > > + {L"Korea Standard Time", L"001", "Asia/Seoul"}, > > + {L"Libya Standard Time", L"001", "Africa/Tripoli"}, > > + {L"Line Islands Standard Time", L"001", "Pacific/Kiritimati"}, > > + {L"Line Islands Standard Time", L"ZZ", "Etc/GMT-14"}, > > + {L"Lord Howe Standard Time", L"001", "Australia/Lord_Howe"}, > > + {L"Magadan Standard Time", L"001", "Asia/Magadan"}, > > + {L"Magallanes Standard Time", L"001", "America/Punta_Arenas"}, > > + {L"Marquesas Standard Time", L"001", "Pacific/Marquesas"}, > > + {L"Mauritius Standard Time", L"001", "Indian/Mauritius"}, > > + {L"Mauritius Standard Time", L"RE", "Indian/Reunion"}, > > + {L"Mauritius Standard Time", L"SC", "Indian/Mahe"}, > > + {L"Middle East Standard Time", L"001", "Asia/Beirut"}, > > + {L"Montevideo Standard Time", L"001", "America/Montevideo"}, > > + {L"Morocco Standard Time", L"001", "Africa/Casablanca"}, > > + {L"Morocco Standard Time", L"EH", "Africa/El_Aaiun"}, > > + {L"Mountain Standard Time", L"001", "America/Denver"}, > > + {L"Mountain Standard Time", L"CA", "America/Edmonton"}, > > + {L"Mountain Standard Time", L"MX", "America/Ciudad_Juarez"}, > > + {L"Mountain Standard Time (Mexico)", L"001", "America/Mazatlan"}, > > + {L"Myanmar Standard Time", L"001", "Asia/Rangoon"}, > > + {L"Myanmar Standard Time", L"CC", "Indian/Cocos"}, > > + {L"N. Central Asia Standard Time", L"001", "Asia/Novosibirsk"}, > > + {L"Namibia Standard Time", L"001", "Africa/Windhoek"}, > > + {L"Nepal Standard Time", L"001", "Asia/Katmandu"}, > > + {L"New Zealand Standard Time", L"001", "Pacific/Auckland"}, > > + {L"New Zealand Standard Time", L"AQ", "Antarctica/McMurdo"}, > > + {L"Newfoundland Standard Time", L"001", "America/St_Johns"}, > > + {L"Norfolk Standard Time", L"001", "Pacific/Norfolk"}, > > + {L"North Asia East Standard Time", L"001", "Asia/Irkutsk"}, > > + {L"North Asia Standard Time", L"001", "Asia/Krasnoyarsk"}, > > + {L"North Korea Standard Time", L"001", "Asia/Pyongyang"}, > > + {L"Omsk Standard Time", L"001", "Asia/Omsk"}, > > + {L"Pacific SA Standard Time", L"001", "America/Santiago"}, > > + {L"Pacific Standard Time", L"001", "America/Los_Angeles"}, > > + {L"Pacific Standard Time", L"CA", "America/Vancouver"}, > > + {L"Pacific Standard Time (Mexico)", L"001", "America/Tijuana"}, > > + {L"Pakistan Standard Time", L"001", "Asia/Karachi"}, > > + {L"Paraguay Standard Time", L"001", "America/Asuncion"}, > > + {L"Qyzylorda Standard Time", L"001", "Asia/Qyzylorda"}, > > + {L"Romance Standard Time", L"001", "Europe/Paris"}, > > + {L"Romance Standard Time", L"BE", "Europe/Brussels"}, > > + {L"Romance Standard Time", L"DK", "Europe/Copenhagen"}, > > + {L"Romance Standard Time", L"ES", "Europe/Madrid"}, > > + {L"Russia Time Zone 10", L"001", "Asia/Srednekolymsk"}, > > + {L"Russia Time Zone 11", L"001", "Asia/Kamchatka"}, > > + {L"Russia Time Zone 3", L"001", "Europe/Samara"}, > > + {L"Russian Standard Time", L"001", "Europe/Moscow"}, > > + {L"Russian Standard Time", L"UA", "Europe/Simferopol"}, > > + {L"SA Eastern Standard Time", L"001", "America/Cayenne"}, > > + {L"SA Eastern Standard Time", L"AQ", "Antarctica/Rothera"}, > > + {L"SA Eastern Standard Time", L"BR", "America/Fortaleza"}, > > + {L"SA Eastern Standard Time", L"FK", "Atlantic/Stanley"}, > > + {L"SA Eastern Standard Time", L"SR", "America/Paramaribo"}, > > + {L"SA Eastern Standard Time", L"ZZ", "Etc/GMT+3"}, > > + {L"SA Pacific Standard Time", L"001", "America/Bogota"}, > > + {L"SA Pacific Standard Time", L"BR", "America/Rio_Branco"}, > > + {L"SA Pacific Standard Time", L"CA", "America/Coral_Harbour"}, > > + {L"SA Pacific Standard Time", L"EC", "America/Guayaquil"}, > > + {L"SA Pacific Standard Time", L"JM", "America/Jamaica"}, > > + {L"SA Pacific Standard Time", L"KY", "America/Cayman"}, > > + {L"SA Pacific Standard Time", L"PA", "America/Panama"}, > > + {L"SA Pacific Standard Time", L"PE", "America/Lima"}, > > + {L"SA Pacific Standard Time", L"ZZ", "Etc/GMT+5"}, > > + {L"SA Western Standard Time", L"001", "America/La_Paz"}, > > + {L"SA Western Standard Time", L"AG", "America/Antigua"}, > > + {L"SA Western Standard Time", L"AI", "America/Anguilla"}, > > + {L"SA Western Standard Time", L"AW", "America/Aruba"}, > > + {L"SA Western Standard Time", L"BB", "America/Barbados"}, > > + {L"SA Western Standard Time", L"BL", "America/St_Barthelemy"}, > > + {L"SA Western Standard Time", L"BQ", "America/Kralendijk"}, > > + {L"SA Western Standard Time", L"BR", "America/Manaus"}, > > + {L"SA Western Standard Time", L"CA", "America/Blanc-Sablon"}, > > + {L"SA Western Standard Time", L"CW", "America/Curacao"}, > > + {L"SA Western Standard Time", L"DM", "America/Dominica"}, > > + {L"SA Western Standard Time", L"DO", "America/Santo_Domingo"}, > > + {L"SA Western Standard Time", L"GD", "America/Grenada"}, > > + {L"SA Western Standard Time", L"GP", "America/Guadeloupe"}, > > + {L"SA Western Standard Time", L"GY", "America/Guyana"}, > > + {L"SA Western Standard Time", L"KN", "America/St_Kitts"}, > > + {L"SA Western Standard Time", L"LC", "America/St_Lucia"}, > > + {L"SA Western Standard Time", L"MF", "America/Marigot"}, > > + {L"SA Western Standard Time", L"MQ", "America/Martinique"}, > > + {L"SA Western Standard Time", L"MS", "America/Montserrat"}, > > + {L"SA Western Standard Time", L"PR", "America/Puerto_Rico"}, > > + {L"SA Western Standard Time", L"SX", "America/Lower_Princes"}, > > + {L"SA Western Standard Time", L"TT", "America/Port_of_Spain"}, > > + {L"SA Western Standard Time", L"VC", "America/St_Vincent"}, > > + {L"SA Western Standard Time", L"VG", "America/Tortola"}, > > + {L"SA Western Standard Time", L"VI", "America/St_Thomas"}, > > + {L"SA Western Standard Time", L"ZZ", "Etc/GMT+4"}, > > + {L"SE Asia Standard Time", L"001", "Asia/Bangkok"}, > > + {L"SE Asia Standard Time", L"AQ", "Antarctica/Davis"}, > > + {L"SE Asia Standard Time", L"CX", "Indian/Christmas"}, > > + {L"SE Asia Standard Time", L"ID", "Asia/Jakarta"}, > > + {L"SE Asia Standard Time", L"KH", "Asia/Phnom_Penh"}, > > + {L"SE Asia Standard Time", L"LA", "Asia/Vientiane"}, > > + {L"SE Asia Standard Time", L"VN", "Asia/Saigon"}, > > + {L"SE Asia Standard Time", L"ZZ", "Etc/GMT-7"}, > > + {L"Saint Pierre Standard Time", L"001", "America/Miquelon"}, > > + {L"Sakhalin Standard Time", L"001", "Asia/Sakhalin"}, > > + {L"Samoa Standard Time", L"001", "Pacific/Apia"}, > > + {L"Sao Tome Standard Time", L"001", "Africa/Sao_Tome"}, > > + {L"Saratov Standard Time", L"001", "Europe/Saratov"}, > > + {L"Singapore Standard Time", L"001", "Asia/Singapore"}, > > + {L"Singapore Standard Time", L"BN", "Asia/Brunei"}, > > + {L"Singapore Standard Time", L"ID", "Asia/Makassar"}, > > + {L"Singapore Standard Time", L"MY", "Asia/Kuala_Lumpur"}, > > + {L"Singapore Standard Time", L"PH", "Asia/Manila"}, > > + {L"Singapore Standard Time", L"ZZ", "Etc/GMT-8"}, > > + {L"South Africa Standard Time", L"001", "Africa/Johannesburg"}, > > + {L"South Africa Standard Time", L"BI", "Africa/Bujumbura"}, > > + {L"South Africa Standard Time", L"BW", "Africa/Gaborone"}, > > + {L"South Africa Standard Time", L"CD", "Africa/Lubumbashi"}, > > + {L"South Africa Standard Time", L"LS", "Africa/Maseru"}, > > + {L"South Africa Standard Time", L"MW", "Africa/Blantyre"}, > > + {L"South Africa Standard Time", L"MZ", "Africa/Maputo"}, > > + {L"South Africa Standard Time", L"RW", "Africa/Kigali"}, > > + {L"South Africa Standard Time", L"SZ", "Africa/Mbabane"}, > > + {L"South Africa Standard Time", L"ZM", "Africa/Lusaka"}, > > + {L"South Africa Standard Time", L"ZW", "Africa/Harare"}, > > + {L"South Africa Standard Time", L"ZZ", "Etc/GMT-2"}, > > + {L"South Sudan Standard Time", L"001", "Africa/Juba"}, > > + {L"Sri Lanka Standard Time", L"001", "Asia/Colombo"}, > > + {L"Sudan Standard Time", L"001", "Africa/Khartoum"}, > > + {L"Syria Standard Time", L"001", "Asia/Damascus"}, > > + {L"Taipei Standard Time", L"001", "Asia/Taipei"}, > > + {L"Tasmania Standard Time", L"001", "Australia/Hobart"}, > > + {L"Tocantins Standard Time", L"001", "America/Araguaina"}, > > + {L"Tokyo Standard Time", L"001", "Asia/Tokyo"}, > > + {L"Tokyo Standard Time", L"ID", "Asia/Jayapura"}, > > + {L"Tokyo Standard Time", L"PW", "Pacific/Palau"}, > > + {L"Tokyo Standard Time", L"TL", "Asia/Dili"}, > > + {L"Tokyo Standard Time", L"ZZ", "Etc/GMT-9"}, > > + {L"Tomsk Standard Time", L"001", "Asia/Tomsk"}, > > + {L"Tonga Standard Time", L"001", "Pacific/Tongatapu"}, > > + {L"Transbaikal Standard Time", L"001", "Asia/Chita"}, > > + {L"Turkey Standard Time", L"001", "Europe/Istanbul"}, > > + {L"Turks And Caicos Standard Time", L"001", "America/Grand_Turk"}, > > + {L"US Eastern Standard Time", L"001", "America/Indianapolis"}, > > + {L"US Mountain Standard Time", L"001", "America/Phoenix"}, > > + {L"US Mountain Standard Time", L"CA", "America/Creston"}, > > + {L"US Mountain Standard Time", L"MX", "America/Hermosillo"}, > > + {L"US Mountain Standard Time", L"ZZ", "Etc/GMT+7"}, > > + {L"UTC", L"001", "Etc/UTC"}, > > + {L"UTC+12", L"001", "Etc/GMT-12"}, > > + {L"UTC+12", L"KI", "Pacific/Tarawa"}, > > + {L"UTC+12", L"MH", "Pacific/Majuro"}, > > + {L"UTC+12", L"NR", "Pacific/Nauru"}, > > + {L"UTC+12", L"TV", "Pacific/Funafuti"}, > > + {L"UTC+12", L"UM", "Pacific/Wake"}, > > + {L"UTC+12", L"WF", "Pacific/Wallis"}, > > + {L"UTC+13", L"001", "Etc/GMT-13"}, > > + {L"UTC+13", L"KI", "Pacific/Enderbury"}, > > + {L"UTC+13", L"TK", "Pacific/Fakaofo"}, > > + {L"UTC-02", L"001", "Etc/GMT+2"}, > > + {L"UTC-02", L"BR", "America/Noronha"}, > > + {L"UTC-02", L"GS", "Atlantic/South_Georgia"}, > > + {L"UTC-08", L"001", "Etc/GMT+8"}, > > + {L"UTC-08", L"PN", "Pacific/Pitcairn"}, > > + {L"UTC-09", L"001", "Etc/GMT+9"}, > > + {L"UTC-09", L"PF", "Pacific/Gambier"}, > > + {L"UTC-11", L"001", "Etc/GMT+11"}, > > + {L"UTC-11", L"AS", "Pacific/Pago_Pago"}, > > + {L"UTC-11", L"NU", "Pacific/Niue"}, > > + {L"UTC-11", L"UM", "Pacific/Midway"}, > > + {L"Ulaanbaatar Standard Time", L"001", "Asia/Ulaanbaatar"}, > > + {L"Venezuela Standard Time", L"001", "America/Caracas"}, > > + {L"Vladivostok Standard Time", L"001", "Asia/Vladivostok"}, > > + {L"Volgograd Standard Time", L"001", "Europe/Volgograd"}, > > + {L"W. Australia Standard Time", L"001", "Australia/Perth"}, > > + {L"W. Central Africa Standard Time", L"001", "Africa/Lagos"}, > > + {L"W. Central Africa Standard Time", L"AO", "Africa/Luanda"}, > > + {L"W. Central Africa Standard Time", L"BJ", "Africa/Porto-Novo"}, > > + {L"W. Central Africa Standard Time", L"CD", "Africa/Kinshasa"}, > > + {L"W. Central Africa Standard Time", L"CF", "Africa/Bangui"}, > > + {L"W. Central Africa Standard Time", L"CG", "Africa/Brazzaville"}, > > + {L"W. Central Africa Standard Time", L"CM", "Africa/Douala"}, > > + {L"W. Central Africa Standard Time", L"DZ", "Africa/Algiers"}, > > + {L"W. Central Africa Standard Time", L"GA", "Africa/Libreville"}, > > + {L"W. Central Africa Standard Time", L"GQ", "Africa/Malabo"}, > > + {L"W. Central Africa Standard Time", L"NE", "Africa/Niamey"}, > > + {L"W. Central Africa Standard Time", L"TD", "Africa/Ndjamena"}, > > + {L"W. Central Africa Standard Time", L"TN", "Africa/Tunis"}, > > + {L"W. Central Africa Standard Time", L"ZZ", "Etc/GMT-1"}, > > + {L"W. Europe Standard Time", L"001", "Europe/Berlin"}, > > + {L"W. Europe Standard Time", L"AD", "Europe/Andorra"}, > > + {L"W. Europe Standard Time", L"AT", "Europe/Vienna"}, > > + {L"W. Europe Standard Time", L"CH", "Europe/Zurich"}, > > + {L"W. Europe Standard Time", L"GI", "Europe/Gibraltar"}, > > + {L"W. Europe Standard Time", L"IT", "Europe/Rome"}, > > + {L"W. Europe Standard Time", L"LI", "Europe/Vaduz"}, > > + {L"W. Europe Standard Time", L"LU", "Europe/Luxembourg"}, > > + {L"W. Europe Standard Time", L"MC", "Europe/Monaco"}, > > + {L"W. Europe Standard Time", L"MT", "Europe/Malta"}, > > + {L"W. Europe Standard Time", L"NL", "Europe/Amsterdam"}, > > + {L"W. Europe Standard Time", L"NO", "Europe/Oslo"}, > > + {L"W. Europe Standard Time", L"SE", "Europe/Stockholm"}, > > + {L"W. Europe Standard Time", L"SJ", "Arctic/Longyearbyen"}, > > + {L"W. Europe Standard Time", L"SM", "Europe/San_Marino"}, > > + {L"W. Europe Standard Time", L"VA", "Europe/Vatican"}, > > + {L"W. Mongolia Standard Time", L"001", "Asia/Hovd"}, > > + {L"West Asia Standard Time", L"001", "Asia/Tashkent"}, > > + {L"West Asia Standard Time", L"AQ", "Antarctica/Mawson"}, > > + {L"West Asia Standard Time", L"KZ", "Asia/Oral"}, > > + {L"West Asia Standard Time", L"MV", "Indian/Maldives"}, > > + {L"West Asia Standard Time", L"TF", "Indian/Kerguelen"}, > > + {L"West Asia Standard Time", L"TJ", "Asia/Dushanbe"}, > > + {L"West Asia Standard Time", L"TM", "Asia/Ashgabat"}, > > + {L"West Asia Standard Time", L"ZZ", "Etc/GMT-5"}, > > + {L"West Bank Standard Time", L"001", "Asia/Hebron"}, > > + {L"West Pacific Standard Time", L"001", "Pacific/Port_Moresby"}, > > + {L"West Pacific Standard Time", L"AQ", > > "Antarctica/DumontDUrville"}, > > + {L"West Pacific Standard Time", L"FM", "Pacific/Truk"}, > > + {L"West Pacific Standard Time", L"GU", "Pacific/Guam"}, > > + {L"West Pacific Standard Time", L"MP", "Pacific/Saipan"}, > > + {L"West Pacific Standard Time", L"ZZ", "Etc/GMT-10"}, > > + {L"Yakutsk Standard Time", L"001", "Asia/Yakutsk"}, > > + {L"Yukon Standard Time", L"001", "America/Whitehorse"}, > > + } > > +}; > > + > > +#undef _GLIBCXX_GET_WINDOWS_ZONES_MAP > > diff --git a/libstdc++-v3/scripts/gen_windows_zones_map.py > > b/libstdc++-v3/ > > scripts/gen_windows_zones_map.py > > new file mode 100644 > > index 00000000000..9edfe457a5f > > --- /dev/null > > +++ b/libstdc++-v3/scripts/gen_windows_zones_map.py > > @@ -0,0 +1,128 @@ > > +#!/usr/bin/env python3 > > +# > > +# Script to generate the map for libstdc++ std::chrono::current_zone > > under > > Windows. > > +# > > +# This file is part of GCC. > > +# > > +# GCC is free software; you can redistribute it and/or modify it under > > +# the terms of the GNU General Public License as published by the Free > > +# Software Foundation; either version 3, or (at your option) any later > > +# version. > > +# > > +# GCC is distributed in the hope that it will be useful, but WITHOUT > > ANY > > +# WARRANTY; without even the implied warranty of MERCHANTABILITY or > > +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > > +# for more details. > > +# > > +# You should have received a copy of the GNU General Public License > > +# along with GCC; see the file COPYING3. If not see > > +# <http://www.gnu.org/licenses/ <http://www.gnu.org/licenses/>>. > > + > > +# To update the Libstdc++ static data in <bits/windows_zones-map.h> > > download > > +# the latest: > > +# https://raw.githubusercontent.com/unicode-org/cldr/master/common/ > > supplemental/windowsZones.xml > > <https://raw.githubusercontent.com/unicode- > > org/cldr/master/common/supplemental/windowsZones.xml> > > +# Then run this script and save the output to > > +# include/bits/windows_zones-map.h > > + > > +import os > > +import sys > > +import xml.etree.ElementTree as et > > + > > +if len(sys.argv) != 2: > > + print("Usage: %s <windows zones xml>" % sys.argv[0], > > file=sys.stderr) > > + sys.exit(1) > > + > > +self = os.path.basename(__file__) > > +print("// Generated by scripts/{}, do not edit.".format(self)) > > +print(""" > > +// Copyright The GNU Toolchain Authors. > > +// > > +// This file is part of the GNU ISO C++ Library. This library is free > > +// software; you can redistribute it and/or modify it under the > > +// terms of the GNU General Public License as published by the > > +// Free Software Foundation; either version 3, or (at your option) > > +// any later version. > > + > > +// This library is distributed in the hope that it will be useful, > > +// but WITHOUT ANY WARRANTY; without even the implied warranty of > > +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > > +// GNU General Public License for more details. > > + > > +// Under Section 7 of GPL version 3, you are granted additional > > +// permissions described in the GCC Runtime Library Exception, version > > +// 3.1, as published by the Free Software Foundation. > > + > > +// You should have received a copy of the GNU General Public License > > and > > +// a copy of the GCC Runtime Library Exception along with this program; > > +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, > > see > > +// <http://www.gnu.org/licenses/ <http://www.gnu.org/licenses/>>. > > + > > +/** @file bits/windows_zones-map.h > > + * This is an internal header file, included by other library headers. > > + * Do not attempt to use it directly. @headername{chrono} > > + */ > > +""") > > + > > +print("#ifndef _GLIBCXX_GET_WINDOWS_ZONES_MAP") > > +print('# error "This is not a public header, do not include it > > directly"') > > +print("#endif\n") > > + > > +class WindowsZoneMapEntry: > > + def __init__(self, windows, territory, iana): > > + self.windows = windows > > + self.territory = territory > > + self.iana = iana > > + > > + def __lt__(self, other): > > + if self.windows < other.windows: > > + return True > > + if self.windows > other.windows: > > + return False > > + return self.territory < other.territory > > + > > +windows_zone_map = [] > > + > > +tree = et.parse(sys.argv[1]) > > +xml_zone_map = tree.getroot().find("windowsZones").find("mapTimezones") > > + > > +for entry in xml_zone_map.iter("mapZone"): > > + iana = entry.attrib["type"] > > + space = iana.find(" ") > > + if space != -1: > > + iana = iana[0:space] > > + windows_zone_map.append(WindowsZoneMapEntry(entry.attrib["other"], > > entry.attrib["territory"], iana)) > > + > > +# Sort so we can use binary search on the array. > > +windows_zone_map.sort(); > > + > > +# Skip territories which have the same IANA zone as 001, so we can > > reduce > > the data. > > +last_windows_zone = "" > > +for entry in windows_zone_map[:]: > > + if entry.windows != last_windows_zone: > > + if entry.territory != "001": > > + raise ValueError("Territory \"001\" not the first one, this > > breaks assumptions in tzdb.cc!") > > + last_windows_zone = entry.windows > > + fallback_iana = entry.iana > > + else: > > + if entry.iana == fallback_iana: > > + windows_zone_map.remove(entry) > > + > > +print("""struct windows_zone_map_entry > > +{{ > > + wstring_view windows_name; > > + wstring_view territory; > > + string_view iana_name; > > +}}; > > + > > +static constexpr array<windows_zone_map_entry, {}> windows_zone_map{{ > > + {{""".format(len(windows_zone_map))) > > + > > +for entry in windows_zone_map: > > + print(' {{L"{}", L"{}", "{}"}},'.format(entry.windows, > > entry.territory, entry.iana)) > > + > > +print(""" } > > +};""") > > + > > +# <chrono> gives an error if this macro is left defined. > > +# Do this last, so that the generated output is not usable unless we > > reach > > here. > > +print("\n#undef _GLIBCXX_GET_WINDOWS_ZONES_MAP") > > diff --git a/libstdc++-v3/src/c++20/tzdb.cc > > b/libstdc++-v3/src/c++20/tzdb.cc > > index 9923d14b7a7..bfbba077b92 100644 > > --- a/libstdc++-v3/src/c++20/tzdb.cc > > +++ b/libstdc++-v3/src/c++20/tzdb.cc > > @@ -48,6 +48,8 @@ > > # define WIN32_LEAN_AND_MEAN > > # include <windows.h> > > # include <psapi.h> > > + > > +# include <array> > > #endif > > > > #if defined __GTHREADS && ATOMIC_POINTER_LOCK_FREE == 2 > > @@ -1768,6 +1770,98 @@ namespace std::chrono > > > > return nullptr; // not found > > } > > + > > +#ifdef _GLIBCXX_HAVE_WINDOWS_H > > + string_view > > + detect_windows_zone() noexcept > > + { > > + DYNAMIC_TIME_ZONE_INFORMATION information{}; > > + if (GetDynamicTimeZoneInformation(&information) == > > TIME_ZONE_ID_INVALID) > > + return {}; > > + > > + constexpr SYSTEMTIME all_zero_time{}; > > + const wstring_view zone_name{ information.TimeZoneKeyName }; > > + auto equal = [](const SYSTEMTIME &lhs, const SYSTEMTIME &rhs) > > noexcept > > + { return memcmp(&lhs, &rhs, sizeof(SYSTEMTIME)) == 0; }; > > + // The logic is copied from icu, couldn't find the source. > > + // Detect if DST is disabled. > > + if (information.DynamicDaylightTimeDisabled > > + && equal(information.StandardDate, information.DaylightDate) > > + && ((!zone_name.empty() > > + && equal(information.StandardDate, all_zero_time)) > > + || (zone_name.empty() > > + && !equal(information.StandardDate, all_zero_time)))) > > + { > > + if (information.Bias == 0) > > + return "Etc/UTC"; > > + > > + if (information.Bias % 60 != 0) > > + // If the offset is not in full hours, we can't do anything > > really. > > + return {}; > > + > > + const auto raw_index = information.Bias / 60; > > + > > + // The bias added to the local time equals UTC. And GMT+X > > corrosponds > > + // to UTC-X, the sign is negated. Thus we can use the hourly > > bias as > > + // an index into an array. > > + if (raw_index < 0 && raw_index >= -14) > > + { > > + static array<string_view, 14> table{ > > + "Etc/GMT-1", "Etc/GMT-2", "Etc/GMT-3", "Etc/GMT-4", > > + "Etc/GMT-5", "Etc/GMT-6", "Etc/GMT-7", "Etc/GMT-8", > > + "Etc/GMT-9", "Etc/GMT-10", "Etc/GMT-11", "Etc/GMT-12", > > + "Etc/GMT-13", "Etc/GMT-14" > > + }; > > + return table[-raw_index - 1]; > > + } > > + else if (raw_index > 0 && raw_index <= 12) > > + { > > + static array<string_view, 14> table{ > > > > This table has size 14, but only 12 entries. I do not think there are zones > > past +12, > > but I believe size and entries should match. > > That is totally correct and this a classic copy and paste error. > @Jonathan: Should I correct that (and the other things you mentioned), or are > you doing that?
I can do it before I push it (probably later today). > > > > > + "Etc/GMT+1", "Etc/GMT+2", "Etc/GMT+3", "Etc/GMT+4", > > + "Etc/GMT+5", "Etc/GMT+6", "Etc/GMT+7", "Etc/GMT+8", > > + "Etc/GMT+9", "Etc/GMT+10", "Etc/GMT+11", "Etc/GMT+12" > > + }; > > + return table[raw_index - 1]; > > + } > > + return {}; > > + } > > + > > +#define _GLIBCXX_GET_WINDOWS_ZONES_MAP > > +#include <bits/windows_zones-map.h> > > +#ifdef _GLIBCXX_GET_WINDOWS_ZONES_MAP > > +# error "Invalid windows_zones map" > > +#endif > > + > > + const auto zone_range > > + = ranges::equal_range(windows_zone_map, zone_name, {}, > > + &windows_zone_map_entry::windows_name); > > + > > + const auto size = ranges::size(zone_range); > > + if (size == 0) > > + // Unknown zone, we can't detect anything. > > + return {}; > > + > > + if (size == 1) > > + // Some zones have only one territory, use the quick path. > > + return zone_range.front().iana_name; > > + > > + const auto geo_id = GetUserGeoID(GEOCLASS_NATION); > > + wstring territory; > > + territory.resize(2); // The terminating zero is always added on > > top. > > + if (GetGeoInfoW(geo_id, GEO_ISO2, territory.data(), 3, 0) == 0) > > + // Couldn't detect the territory, fallback to "001", which is > > the first > > + // entry. > > + return zone_range.front().iana_name; > > + > > + const auto iter = ranges::lower_bound( > > + zone_range, territory, {}, > > &windows_zone_map_entry::territory); > > + if (iter == zone_range.end() || iter->territory != territory) > > + // Territory not within the the map, use "001". > > + return zone_range.front().iana_name; > > + > > + return iter->iana_name; > > + } > > +#endif > > } // namespace > > > > // Implementation of std::chrono::tzdb::locate_zone(string_view). > > @@ -1790,7 +1884,7 @@ namespace std::chrono > > { > > // TODO cache this function's result? > > > > -#ifndef _AIX > > +#if !defined(_AIX) && !defined(_GLIBCXX_HAVE_WINDOWS_H) > > // Repeat the preprocessor condition used by > > filesystem::read_symlink, > > // to avoid a dependency on src/c++17/fs_ops.o if it won't work > > anyway. > > #if defined(_GLIBCXX_HAVE_READLINK) && > > defined(_GLIBCXX_HAVE_SYS_STAT_H) > > @@ -1847,7 +1941,11 @@ namespace std::chrono > > return tz; > > } > > } > > -#else > > +#elif defined(_GLIBCXX_HAVE_WINDOWS_H) > > + if (auto tz > > + = do_locate_zone(this->zones, this->links, > > detect_windows_zone())) > > + return tz; > > +#else // defined(_AIX) > > // AIX stores current zone in $TZ in /etc/environment but the > > value > > // is typically a POSIX time zone name, not IANA zone. > > // https://developer.ibm.com/articles/au-aix-posix/ <https:// > > developer.ibm.com/articles/au-aix-posix/> > > -- > > 2.50.0 > > >