解决 .NET Core 在 Linux 下的时区问题
环境
# dotnet --info .NET Core SDK (reflecting any global.json): Version: 2.2.202 Commit: 8a7ff6789d Runtime Environment: OS Name: centos OS Version: 7 OS Platform: Linux RID: centos.7-x64 Base Path: /usr/share/dotnet/sdk/2.2.202/ Host (useful for support): Version: 2.2.3 Commit: 6b8ad509b6 .NET Core SDKs installed: 2.2.202 [/usr/share/dotnet/sdk] .NET Core runtimes installed: Microsoft.AspNetCore.All 2.2.3 [/usr/share/dotnet/shared/Microsoft.AspNetCore.All] Microsoft.AspNetCore.App 2.2.3 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App] Microsoft.NETCore.App 2.2.3 [/usr/share/dotnet/shared/Microsoft.NETCore.App] To install additional .NET Core runtimes or SDKs: https://aka.ms/dotnet-download
错误
Unhandled Exception: System.TimeZoneNotFoundException: The time zone ID 'China Standard Time' was not found on the local computer. ---> System.IO.FileNotFoundException: Could not find file '/usr/share/zoneinfo/China Standard Time'. at Interop.ThrowExceptionForIoErrno(ErrorInfo errorInfo, String path, Boolean isDirectory, Func`2 errorRewriter) at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String path, OpenFlags flags, Int32 mode) at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options) at Internal.IO.File.ReadAllBytes(String path) at System.TimeZoneInfo.TryGetTimeZoneFromLocalMachine(String id, TimeZoneInfo& value, Exception& e) --- End of inner exception stack trace --- at System.TimeZoneInfo.FindSystemTimeZoneById(String id)
System.TimeZoneNotFoundException:“The time zone ID 'Asia/Shanghai' was not found on the local computer.”
Google 一番,找到这个帖子: https://dejanstojanovic.net/aspnet/2018/july/differences-in-time-zones-in-net-core-on-windows-and-linux-host-os/ ,是由于 Win 与 Unix 时区信息不一致导致的,也有点太弱了。
Win
Dateline Standard Time UTC-11 Aleutian Standard Time Hawaiian Standard Time Marquesas Standard Time Alaskan Standard Time UTC-09 Pacific Standard Time (Mexico) UTC-08 Pacific Standard Time US Mountain Standard Time Mountain Standard Time (Mexico) Mountain Standard Time Central America Standard Time Central Standard Time Easter Island Standard Time Central Standard Time (Mexico) Canada Central Standard Time SA Pacific Standard Time Eastern Standard Time (Mexico) Eastern Standard Time Haiti Standard Time Cuba Standard Time US Eastern Standard Time Turks And Caicos Standard Time Paraguay Standard Time Atlantic Standard Time Venezuela Standard Time Central Brazilian Standard Time SA Western Standard Time Pacific SA Standard Time Newfoundland Standard Time Tocantins Standard Time E. South America Standard Time SA Eastern Standard Time Argentina Standard Time Greenland Standard Time Montevideo Standard Time Magallanes Standard Time Saint Pierre Standard Time Bahia Standard Time UTC-02 Mid-Atlantic Standard Time Azores Standard Time Cape Verde Standard Time UTC Morocco Standard Time GMT Standard Time Greenwich Standard Time W. Europe Standard Time Central Europe Standard Time Romance Standard Time Sao Tome Standard Time Central European Standard Time W. Central Africa Standard Time Jordan Standard Time GTB Standard Time Middle East Standard Time Egypt Standard Time E. Europe Standard Time Syria Standard Time West Bank Standard Time South Africa Standard Time FLE Standard Time Israel Standard Time Kaliningrad Standard Time Sudan Standard Time Libya Standard Time Namibia Standard Time Arabic Standard Time Turkey Standard Time Arab Standard Time Belarus Standard Time Russian Standard Time E. Africa Standard Time Iran Standard Time Arabian Standard Time Astrakhan Standard Time Azerbaijan Standard Time Russia Time Zone 3 Mauritius Standard Time Saratov Standard Time Georgian Standard Time Caucasus Standard Time Afghanistan Standard Time West Asia Standard Time Ekaterinburg Standard Time Pakistan Standard Time India Standard Time Sri Lanka Standard Time Nepal Standard Time Central Asia Standard Time Bangladesh Standard Time Omsk Standard Time Myanmar Standard Time SE Asia Standard Time Altai Standard Time W. Mongolia Standard Time North Asia Standard Time N. Central Asia Standard Time Tomsk Standard Time China Standard Time North Asia East Standard Time Singapore Standard Time W. Australia Standard Time Taipei Standard Time Ulaanbaatar Standard Time North Korea Standard Time Aus Central W. Standard Time Transbaikal Standard Time Tokyo Standard Time Korea Standard Time Yakutsk Standard Time Cen. Australia Standard Time AUS Central Standard Time E. Australia Standard Time AUS Eastern Standard Time West Pacific Standard Time Tasmania Standard Time Vladivostok Standard Time Lord Howe Standard Time Bougainville Standard Time Russia Time Zone 10 Magadan Standard Time Norfolk Standard Time Sakhalin Standard Time Central Pacific Standard Time Russia Time Zone 11 New Zealand Standard Time UTC+12 Fiji Standard Time Kamchatka Standard Time Chatham Islands Standard Time UTC+13 Tonga Standard Time Samoa Standard Time Line Islands Standard Time
Unix
Pacific/Niue Pacific/Pago_Pago Pacific/Midway Pacific/Rarotonga America/Adak Pacific/Honolulu Pacific/Tahiti Pacific/Marquesas America/Metlakatla America/Sitka America/Nome America/Juneau America/Yakutat America/Anchorage Pacific/Gambier America/Los_Angeles America/Vancouver America/Whitehorse America/Dawson America/Tijuana Pacific/Pitcairn America/Hermosillo America/Chihuahua America/Mazatlan America/Yellowknife America/Phoenix America/Boise America/Denver America/Edmonton America/Cambridge_Bay America/Fort_Nelson America/Creston America/Dawson_Creek America/Ojinaga America/Inuvik America/Belize America/Winnipeg America/Rainy_River America/Resolute America/Regina America/Swift_Current America/Matamoros America/Monterrey America/Managua America/Merida America/Costa_Rica America/Mexico_City America/Guatemala America/Tegucigalpa America/El_Salvador America/Rankin_Inlet America/Bahia_Banderas America/North_Dakota/New_Salem America/Indiana/Knox America/North_Dakota/Beulah America/Indiana/Tell_City America/North_Dakota/Center America/Chicago America/Menominee Pacific/Easter Pacific/Galapagos America/Rio_Branco America/Eirunepe America/Bogota America/Havana America/Kentucky/Louisville America/Atikokan America/Indiana/Indianapolis America/Nassau America/Pangnirtung America/Iqaluit America/Thunder_Bay America/Kentucky/Monticello America/Indiana/Vevay America/Nipigon America/Port-au-Prince America/Detroit America/New_York America/Panama America/Cancun America/Jamaica America/Indiana/Vincennes America/Cayman America/Indiana/Winamac America/Indiana/Marengo America/Indiana/Petersburg America/Toronto America/Guayaquil America/Lima America/Manaus America/Boa_Vista America/Porto_Velho America/Cuiaba America/Campo_Grande America/Goose_Bay America/Kralendijk America/Curacao America/Grenada America/Puerto_Rico America/St_Lucia America/Marigot America/St_Vincent America/Grand_Turk America/Dominica America/Santo_Domingo Atlantic/Bermuda America/Port_of_Spain America/St_Barthelemy America/Lower_Princes America/Anguilla America/St_Kitts America/Antigua America/Tortola America/St_Thomas America/Montserrat America/Martinique America/Blanc-Sablon America/Thule America/Barbados America/Aruba America/Halifax America/Guadeloupe America/Moncton America/Glace_Bay America/La_Paz America/Santiago America/Guyana America/Asuncion America/Caracas America/St_Johns America/Argentina/La_Rioja America/Argentina/Ushuaia America/Argentina/Rio_Gallegos America/Argentina/Mendoza America/Argentina/San_Juan America/Argentina/Catamarca America/Argentina/Jujuy America/Argentina/Salta America/Argentina/Buenos_Aires America/Argentina/Tucuman America/Argentina/Cordoba America/Maceio America/Araguaina America/Bahia America/Sao_Paulo America/Santarem America/Recife America/Belem America/Fortaleza Antarctica/Palmer Atlantic/Stanley America/Cayenne America/Punta_Arenas Antarctica/Rothera America/Miquelon America/Paramaribo America/Montevideo America/Godthab America/Argentina/San_Luis America/Noronha Atlantic/South_Georgia Atlantic/Azores Atlantic/Cape_Verde America/Scoresbysund Europe/Isle_of_Man Antarctica/Troll Africa/Dakar Africa/Ouagadougou Africa/Bissau Africa/Nouakchott Europe/Jersey Africa/Abidjan Atlantic/St_Helena Africa/Banjul Africa/Freetown Europe/London Africa/Lome Africa/Conakry Europe/Guernsey Africa/Accra Atlantic/Reykjavik America/Danmarkshavn Africa/Bamako Africa/Monrovia Africa/Casablanca Atlantic/Canary Africa/El_Aaiun Atlantic/Faroe Europe/Lisbon Atlantic/Madeira Europe/Vaduz Europe/Malta Europe/Podgorica Europe/Monaco Europe/Rome Europe/Luxembourg Europe/Amsterdam Europe/Oslo Europe/Andorra Africa/Algiers Europe/Tirane Europe/Vatican Europe/Vienna Europe/Sarajevo Europe/Brussels Europe/Zurich Africa/Tunis Europe/Prague Europe/Berlin Europe/Busingen Europe/Copenhagen Europe/Warsaw Europe/Madrid Africa/Ceuta Europe/San_Marino Europe/Skopje Europe/Belgrade Arctic/Longyearbyen Europe/Paris Europe/Budapest Europe/Ljubljana Europe/Zagreb Europe/Gibraltar Europe/Stockholm Europe/Bratislava Europe/Dublin Africa/Sao_Tome Africa/Luanda Africa/Porto-Novo Africa/Kinshasa Africa/Brazzaville Africa/Bangui Africa/Malabo Africa/Douala Africa/Ndjamena Africa/Libreville Africa/Lagos Africa/Niamey Africa/Kigali Africa/Blantyre Africa/Maputo Africa/Harare Africa/Lusaka Africa/Lubumbashi Africa/Gaborone Africa/Bujumbura Africa/Khartoum Asia/Gaza Asia/Hebron Europe/Bucharest Europe/Kiev Europe/Mariehamn Europe/Sofia Europe/Athens Europe/Helsinki Africa/Cairo Europe/Tallinn Asia/Damascus Asia/Nicosia Europe/Zaporozhye Asia/Amman Europe/Kaliningrad Europe/Uzhgorod Asia/Beirut Africa/Tripoli Europe/Vilnius Europe/Chisinau Europe/Riga Asia/Famagusta Asia/Jerusalem Africa/Maseru Africa/Mbabane Africa/Johannesburg Africa/Windhoek Asia/Aden Asia/Qatar Asia/Bahrain Asia/Riyadh Asia/Kuwait Asia/Baghdad Africa/Addis_Ababa Africa/Djibouti Africa/Mogadishu Africa/Juba Africa/Asmara Indian/Mayotte Africa/Dar_es_Salaam Indian/Antananarivo Africa/Kampala Indian/Comoro Africa/Nairobi Europe/Istanbul Europe/Minsk Europe/Kirov Europe/Moscow Europe/Volgograd Europe/Simferopol Antarctica/Syowa Asia/Tehran Asia/Yerevan Asia/Baku Europe/Saratov Europe/Astrakhan Europe/Ulyanovsk Asia/Tbilisi Asia/Dubai Asia/Muscat Indian/Mauritius Indian/Reunion Europe/Samara Indian/Mahe Asia/Kabul Indian/Kerguelen Asia/Atyrau Indian/Maldives Antarctica/Mawson Asia/Karachi Asia/Dushanbe Asia/Ashgabat Asia/Tashkent Asia/Samarkand Asia/Aqtobe Asia/Aqtau Asia/Oral Asia/Yekaterinburg Asia/Colombo Asia/Kolkata Asia/Kathmandu Asia/Dhaka Asia/Thimphu Asia/Almaty Asia/Qyzylorda Asia/Urumqi Indian/Chagos Asia/Bishkek Asia/Omsk Antarctica/Vostok Indian/Cocos Asia/Yangon Indian/Christmas Antarctica/Davis Asia/Tomsk Asia/Barnaul Asia/Hovd Asia/Ho_Chi_Minh Asia/Vientiane Asia/Phnom_Penh Asia/Bangkok Asia/Krasnoyarsk Asia/Novokuznetsk Asia/Novosibirsk Asia/Jakarta Asia/Pontianak Antarctica/Casey Australia/Perth Asia/Brunei Asia/Makassar Asia/Macau Asia/Shanghai Asia/Choibalsan Asia/Hong_Kong Asia/Irkutsk Asia/Kuching Asia/Kuala_Lumpur Asia/Manila Asia/Singapore Asia/Taipei Asia/Ulaanbaatar Australia/Eucla Asia/Dili Asia/Jayapura Asia/Tokyo Asia/Seoul Pacific/Palau Asia/Pyongyang Asia/Chita Asia/Yakutsk Asia/Khandyga Australia/Broken_Hill Australia/Adelaide Australia/Darwin Australia/Currie Australia/Hobart Australia/Melbourne Australia/Sydney Australia/Brisbane Australia/Lindeman Pacific/Saipan Pacific/Guam Pacific/Chuuk Antarctica/DumontDUrville Pacific/Port_Moresby Asia/Ust-Nera Asia/Vladivostok Australia/Lord_Howe Pacific/Bougainville Asia/Srednekolymsk Pacific/Kosrae Antarctica/Macquarie Asia/Magadan Pacific/Noumea Pacific/Norfolk Pacific/Pohnpei Asia/Sakhalin Pacific/Guadalcanal Pacific/Efate Asia/Anadyr Pacific/Fiji Pacific/Tarawa Pacific/Kwajalein Pacific/Majuro Pacific/Nauru Pacific/Auckland Antarctica/McMurdo Asia/Kamchatka Pacific/Funafuti Pacific/Wake Pacific/Wallis Pacific/Chatham Pacific/Apia Pacific/Enderbury Pacific/Fakaofo Pacific/Tongatapu Pacific/Kiritimati
在官方的 github 中也有类似的 Issues ,需要转一个转换的工作,可以借助第三方的一个包 TimeZoneConverter :
TimeZoneInfo tzi = TZConvert.GetTimeZoneInfo("Central Standard Time"); TimeZoneInfo tzi = TZConvert.GetTimeZoneInfo("America/New_York"); #修改 RecurringJob.AddOrUpdate(() => SchedulePollingTaskBackgroundJobAsync(), @"30 16,20 * * *", TZConvert.GetTimeZoneInfo("Asia/Shanghai"));
解决问题
REFER:
https://github.com/dotnet/corefx/issues/11897
https://github.com/mj1856/TimeZoneConverter
https://stackoverflow.com/questions/47848111/how-should-i-fetch-timezoneinfo-in-a-platform-agnostic-way
https://devblogs.microsoft.com/dotnet/cross-platform-time-zones-with-net-core/