在c#中获取特定时区的日期时间时发生System.TimeZoneNotFoundException错误

本文关键字:System 错误 TimeZoneNotFoundException 时间 日期 获取 定时区 | 更新日期: 2023-09-27 18:06:22

我有一个JSON文件,它有time_zone参数。它有London, Casablanca, Arizona, Pacific Time (US & Canada)等值。基于time_zone,我想得到该时区的DateTime结果。

例如,

Current time = 8/3/2015 4:00:00 PM
 
If time_zone = Central Time (US & Canada) then result should be 8/3/2015 3:00:00 PM,
If time_zone = Pacific Time (US & Canada) then result should be 8/3/2015 1:00:00 PM,
If time_zone = London then result should be 8/3/2015 9:00:00 PM and so on.

我想显示当前时间以及给定时区的时间。

我试着按照下面的方法为受尊重的时区争取时间,但这是一个错误。

代码:Works

 DateTime timeUtc = DateTime.Now;
 TimeZoneInfo cstZone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
 var b = TimeZoneInfo.ConvertTime(timeUtc, cstZone);

错误:The time zone ID 'Central Time (US & Canada)' was not found on the local computer.

 TimeZoneInfo cstZone = TimeZoneInfo.FindSystemTimeZoneById("Central Time (US & Canada)");
 var b = TimeZoneInfo.ConvertTime(timeUtc , cstZone);

也尝试过,但出现了相同的错误,

var c = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(timeUtc, "Central Time (US & Canada)");

我的问题是,time_zone的值是Central Time (US & Canada), Pacific Time (US & Canada), etc.格式的,我必须处理它以及像London, Casablanca这样的不同时区。如何处理这种情况。

在c#中获取特定时区的日期时间时发生System.TimeZoneNotFoundException错误

如果使用docker,请使用此

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-alpine  
RUN apk add --no-cache tzdata

参考:https://www.stevejgordon.co.uk/timezonenotfoundexception-in-alpine-based-docker-images

否则就需要iana_timezone

calling fn:
var timezone = "Asia/Kolkata";
var dtUtc = GetUtcByTimezone(timezone, utc);
public static DateTimeOffset GetUtcByTimezone(string timezone, DateTime? dateTime = null)
{
    dateTime ??= DateTime.UtcNow;
    var timeZoneInfo = TZConvert.GetTimeZoneInfo(timezone);
    var dtUtc = TimeZoneInfo.ConvertTimeToUtc(dateTime.Value, timeZoneInfo);
    return dtUtc;
}

假设文件中的时区标识符来自Rails,那么您基本上是在问这个问题的反面。

与该问题的答案类似,我们将使用Rails映射以及CLDR映射来获得C#中的Rails-to-Windows映射常量。

public static class TZConvert
{
    public static string RailsToWindows(string railsTimeZoneId)
    {
        return RailsWindowsMapping.ContainsKey(railsTimeZoneId)
            ? RailsWindowsMapping[railsTimeZoneId]
            : null;
    }
    private static readonly IReadOnlyDictionary<string, string> RailsWindowsMapping =
        new Dictionary<string, string>
        {
            {"Abu Dhabi", "Arabian Standard Time"},
            {"Adelaide", "Cen. Australia Standard Time"},
            {"Alaska", "Alaskan Standard Time"},
            {"Almaty", "Central Asia Standard Time"},
            {"American Samoa", "UTC-11"},
            {"Amsterdam", "W. Europe Standard Time"},
            {"Arizona", "US Mountain Standard Time"},
            {"Astana", "Bangladesh Standard Time"},
            {"Athens", "GTB Standard Time"},
            {"Atlantic Time (Canada)", "Atlantic Standard Time"},
            {"Auckland", "New Zealand Standard Time"},
            {"Azores", "Azores Standard Time"},
            {"Baghdad", "Arabic Standard Time"},
            {"Baku", "Azerbaijan Standard Time"},
            {"Bangkok", "SE Asia Standard Time"},
            {"Beijing", "China Standard Time"},
            {"Belgrade", "Central Europe Standard Time"},
            {"Berlin", "W. Europe Standard Time"},
            {"Bern", "W. Europe Standard Time"},
            {"Bogota", "SA Pacific Standard Time"},
            {"Brasilia", "E. South America Standard Time"},
            {"Bratislava", "Central Europe Standard Time"},
            {"Brisbane", "E. Australia Standard Time"},
            {"Brussels", "Romance Standard Time"},
            {"Bucharest", "GTB Standard Time"},
            {"Budapest", "Central Europe Standard Time"},
            {"Buenos Aires", "Argentina Standard Time"},
            {"Cairo", "Egypt Standard Time"},
            {"Canberra", "AUS Eastern Standard Time"},
            {"Cape Verde Is.", "Cape Verde Standard Time"},
            {"Caracas", "Venezuela Standard Time"},
            {"Casablanca", "Morocco Standard Time"},
            {"Central America", "Central America Standard Time"},
            {"Central Time (US & Canada)", "Central Standard Time"},
            {"Chennai", "India Standard Time"},
            {"Chihuahua", "Mountain Standard Time (Mexico)"},
            {"Chongqing", "China Standard Time"},
            {"Copenhagen", "Romance Standard Time"},
            {"Darwin", "AUS Central Standard Time"},
            {"Dhaka", "Bangladesh Standard Time"},
            {"Dublin", "GMT Standard Time"},
            {"Eastern Time (US & Canada)", "Eastern Standard Time"},
            {"Edinburgh", "GMT Standard Time"},
            {"Ekaterinburg", "Ekaterinburg Standard Time"},
            {"Fiji", "Fiji Standard Time"},
            {"Georgetown", "SA Western Standard Time"},
            {"Greenland", "Greenland Standard Time"},
            {"Guadalajara", "Central Standard Time (Mexico)"},
            {"Guam", "West Pacific Standard Time"},
            {"Hanoi", "SE Asia Standard Time"},
            {"Harare", "South Africa Standard Time"},
            {"Hawaii", "Hawaiian Standard Time"},
            {"Helsinki", "FLE Standard Time"},
            {"Hobart", "Tasmania Standard Time"},
            {"Hong Kong", "China Standard Time"},
            {"Indiana (East)", "US Eastern Standard Time"},
            {"International Date Line West", "UTC-11"},
            {"Irkutsk", "North Asia East Standard Time"},
            {"Islamabad", "Pakistan Standard Time"},
            {"Istanbul", "Turkey Standard Time"},
            {"Jakarta", "SE Asia Standard Time"},
            {"Jerusalem", "Israel Standard Time"},
            {"Kabul", "Afghanistan Standard Time"},
            {"Kaliningrad", "Kaliningrad Standard Time"},
            {"Kamchatka", "Russia Time Zone 11"},
            {"Karachi", "Pakistan Standard Time"},
            {"Kathmandu", "Nepal Standard Time"},
            {"Kolkata", "India Standard Time"},
            {"Krasnoyarsk", "North Asia Standard Time"},
            {"Kuala Lumpur", "Singapore Standard Time"},
            {"Kuwait", "Arab Standard Time"},
            {"Kyiv", "FLE Standard Time"},
            {"La Paz", "SA Western Standard Time"},
            {"Lima", "SA Pacific Standard Time"},
            {"Lisbon", "GMT Standard Time"},
            {"Ljubljana", "Central Europe Standard Time"},
            {"London", "GMT Standard Time"},
            {"Madrid", "Romance Standard Time"},
            {"Magadan", "Magadan Standard Time"},
            {"Marshall Is.", "UTC+12"},
            {"Mazatlan", "Mountain Standard Time (Mexico)"},
            {"Melbourne", "AUS Eastern Standard Time"},
            {"Mexico City", "Central Standard Time (Mexico)"},
            {"Mid-Atlantic", "UTC-02"},
            {"Midway Island", "UTC-11"},
            {"Minsk", "Belarus Standard Time"},
            {"Monrovia", "Greenwich Standard Time"},
            {"Monterrey", "Central Standard Time (Mexico)"},
            {"Montevideo", "Montevideo Standard Time"},
            {"Moscow", "Russian Standard Time"},
            {"Mountain Time (US & Canada)", "Mountain Standard Time"},
            {"Mumbai", "India Standard Time"},
            {"Muscat", "Arabian Standard Time"},
            {"Nairobi", "E. Africa Standard Time"},
            {"New Caledonia", "Central Pacific Standard Time"},
            {"New Delhi", "India Standard Time"},
            {"Newfoundland", "Newfoundland Standard Time"},
            {"Novosibirsk", "N. Central Asia Standard Time"},
            {"Nuku'alofa", "Tonga Standard Time"},
            {"Osaka", "Tokyo Standard Time"},
            {"Pacific Time (US & Canada)", "Pacific Standard Time"},
            {"Paris", "Romance Standard Time"},
            {"Perth", "W. Australia Standard Time"},
            {"Port Moresby", "West Pacific Standard Time"},
            {"Prague", "Central Europe Standard Time"},
            {"Pretoria", "South Africa Standard Time"},
            {"Quito", "SA Pacific Standard Time"},
            {"Rangoon", "Myanmar Standard Time"},
            {"Riga", "FLE Standard Time"},
            {"Riyadh", "Arab Standard Time"},
            {"Rome", "W. Europe Standard Time"},
            {"Samara", "Russia Time Zone 3"},
            {"Samoa", "Samoa Standard Time"},
            {"Santiago", "Pacific SA Standard Time"},
            {"Sapporo", "Tokyo Standard Time"},
            {"Sarajevo", "Central European Standard Time"},
            {"Saskatchewan", "Canada Central Standard Time"},
            {"Seoul", "Korea Standard Time"},
            {"Singapore", "Singapore Standard Time"},
            {"Skopje", "Central European Standard Time"},
            {"Sofia", "FLE Standard Time"},
            {"Solomon Is.", "Central Pacific Standard Time"},
            {"Srednekolymsk", "Russia Time Zone 10"},
            {"Sri Jayawardenepura", "Sri Lanka Standard Time"},
            {"St. Petersburg", "Russian Standard Time"},
            {"Stockholm", "W. Europe Standard Time"},
            {"Sydney", "AUS Eastern Standard Time"},
            {"Taipei", "Taipei Standard Time"},
            {"Tallinn", "FLE Standard Time"},
            {"Tashkent", "West Asia Standard Time"},
            {"Tbilisi", "Georgian Standard Time"},
            {"Tehran", "Iran Standard Time"},
            {"Tijuana", "Pacific Standard Time"},
            {"Tokelau Is.", "Tonga Standard Time"},
            {"Tokyo", "Tokyo Standard Time"},
            {"Ulaanbaatar", "Ulaanbaatar Standard Time"},
            {"Urumqi", "Central Asia Standard Time"},
            {"UTC", "UTC"},
            {"Vienna", "W. Europe Standard Time"},
            {"Vilnius", "FLE Standard Time"},
            {"Vladivostok", "Vladivostok Standard Time"},
            {"Volgograd", "Russian Standard Time"},
            {"Warsaw", "Central European Standard Time"},
            {"Wellington", "New Zealand Standard Time"},
            {"West Central Africa", "W. Central Africa Standard Time"},
            {"Yakutsk", "Yakutsk Standard Time"},
            {"Yerevan", "Caucasus Standard Time"},
            {"Zagreb", "Central European Standard Time"}
        };
}

您现在可以将其与TimeZoneInfo一起使用,如下所示:

string windowsZoneId = TZConvert.RailsToWindows("Central Time (US & Canada)");
TimeZoneInfo central = TimeZoneInfo.FindSystemTimeZoneById(windowsZoneId);

注意以下几点:

  • Rails映射似乎相对固定,但CLDR映射偶尔会更新。您可能需要不时地重新访问,以确保任何新的时区都得到了适当的映射。

  • Rails时区"Chatham Is."当前无法映射到任何Windows时区。(Windows中没有为查塔姆群岛定义时区。(

  • 如果你想更准确并支持所有区域,你可以从Rails转到IANA/TZDB时区,而不是Windows时区。然后,您可以将Noda Time与它的本地TZDB支持一起使用。这也将消除使用CLDR映射的需要。

我没有解决这个问题,但我使用https://stackoverflow.com/a/6144229/7670060.希望这会有所帮助。

步骤1:

在计算机中查找时区列表。

var timeZones = TimeZoneInfo.GetSystemTimeZones();

步骤2:

public string OlsonTimeZoneToTimeZoneInfo(string timeInfo)
    {
        var olsonWindowsTimes = new Dictionary<string, string>()
        {
            { "Africa/Bangui", "W. Central Africa Standard Time" },
            { "Africa/Cairo", "Egypt Standard Time" },
            { "Africa/Casablanca", "Morocco Standard Time" },
            { "Africa/Harare", "South Africa Standard Time" },
            { "Africa/Johannesburg", "South Africa Standard Time" },
            { "Africa/Lagos", "W. Central Africa Standard Time" },
            { "Africa/Monrovia", "Greenwich Standard Time" },
            { "Africa/Nairobi", "E. Africa Standard Time" },
            { "Africa/Windhoek", "Namibia Standard Time" },
            { "America/Anchorage", "Alaskan Standard Time" },
            { "America/Argentina/San_Juan", "Argentina Standard Time" },
            { "America/Asuncion", "Paraguay Standard Time" },
            { "America/Bahia", "Bahia Standard Time" },
            { "America/Bogota", "SA Pacific Standard Time" },
            { "America/Buenos_Aires", "Argentina Standard Time" },
            { "America/Caracas", "Venezuela Standard Time" },
            { "America/Cayenne", "SA Eastern Standard Time" },
            { "America/Chicago", "Central Standard Time" },
            { "America/Chihuahua", "Mountain Standard Time (Mexico)" },
            { "America/Cuiaba", "Central Brazilian Standard Time" },
            { "America/Denver", "Mountain Standard Time" },
            { "America/Fortaleza", "SA Eastern Standard Time" },
            { "America/Godthab", "Greenland Standard Time" },
            { "America/Guatemala", "Central America Standard Time" },
            { "America/Halifax", "Atlantic Standard Time" },
            { "America/Indianapolis", "US Eastern Standard Time" },
            { "America/Indiana/Indianapolis", "US Eastern Standard Time" },
            { "America/La_Paz", "SA Western Standard Time" },
            { "America/Los_Angeles", "Pacific Standard Time" },
            { "America/Mexico_City", "Mexico Standard Time" },
            { "America/Montevideo", "Montevideo Standard Time" },
            { "America/New_York", "Eastern Standard Time" },
            { "America/Noronha", "UTC-02" },
            { "America/Phoenix", "US Mountain Standard Time" },
            { "America/Regina", "Canada Central Standard Time" },
            { "America/Santa_Isabel", "Pacific Standard Time (Mexico)" },
            { "America/Santiago", "Pacific SA Standard Time" },
            { "America/Sao_Paulo", "E. South America Standard Time" },
            { "America/St_Johns", "Newfoundland Standard Time" },
            { "America/Tijuana", "Pacific Standard Time" },
            { "Antarctica/McMurdo", "New Zealand Standard Time" },
            { "Atlantic/South_Georgia", "UTC-02" },
            { "Asia/Almaty", "Central Asia Standard Time" },
            { "Asia/Amman", "Jordan Standard Time" },
            { "Asia/Baghdad", "Arabic Standard Time" },
            { "Asia/Baku", "Azerbaijan Standard Time" },
            { "Asia/Bangkok", "SE Asia Standard Time" },
            { "Asia/Beirut", "Middle East Standard Time" },
            { "Asia/Calcutta", "India Standard Time" },
            { "Asia/Colombo", "Sri Lanka Standard Time" },
            { "Asia/Damascus", "Syria Standard Time" },
            { "Asia/Dhaka", "Bangladesh Standard Time" },
            { "Asia/Dubai", "Arabian Standard Time" },
            { "Asia/Irkutsk", "North Asia East Standard Time" },
            { "Asia/Jerusalem", "Israel Standard Time" },
            { "Asia/Kabul", "Afghanistan Standard Time" },
            { "Asia/Kamchatka", "Kamchatka Standard Time" },
            { "Asia/Karachi", "Pakistan Standard Time" },
            { "Asia/Katmandu", "Nepal Standard Time" },
            { "Asia/Kolkata", "India Standard Time" },
            { "Asia/Krasnoyarsk", "North Asia Standard Time" },
            { "Asia/Kuala_Lumpur", "Singapore Standard Time" },
            { "Asia/Kuwait", "Arab Standard Time" },
            { "Asia/Magadan", "Magadan Standard Time" },
            { "Asia/Muscat", "Arabian Standard Time" },
            { "Asia/Novosibirsk", "N. Central Asia Standard Time" },
            { "Asia/Oral", "West Asia Standard Time" },
            { "Asia/Rangoon", "Myanmar Standard Time" },
            { "Asia/Riyadh", "Arab Standard Time" },
            { "Asia/Seoul", "Korea Standard Time" },
            { "Asia/Shanghai", "China Standard Time" },
            { "Asia/Singapore", "Singapore Standard Time" },
            { "Asia/Taipei", "Taipei Standard Time" },
            { "Asia/Tashkent", "West Asia Standard Time" },
            { "Asia/Tbilisi", "Georgian Standard Time" },
            { "Asia/Tehran", "Iran Standard Time" },
            { "Asia/Tokyo", "Tokyo Standard Time" },
            { "Asia/Ulaanbaatar", "Ulaanbaatar Standard Time" },
            { "Asia/Vladivostok", "Vladivostok Standard Time" },
            { "Asia/Yakutsk", "Yakutsk Standard Time" },
            { "Asia/Yekaterinburg", "Ekaterinburg Standard Time" },
            { "Asia/Yerevan", "Armenian Standard Time" },
            { "Atlantic/Azores", "Azores Standard Time" },
            { "Atlantic/Cape_Verde", "Cape Verde Standard Time" },
            { "Atlantic/Reykjavik", "Greenwich Standard Time" },
            { "Australia/Adelaide", "Cen. Australia Standard Time" },
            { "Australia/Brisbane", "E. Australia Standard Time" },
            { "Australia/Darwin", "AUS Central Standard Time" },
            { "Australia/Hobart", "Tasmania Standard Time" },
            { "Australia/Perth", "W. Australia Standard Time" },
            { "Australia/Sydney", "AUS Eastern Standard Time" },
            { "Etc/GMT", "UTC" },
            { "Etc/GMT+11", "UTC-11" },
            { "Etc/GMT+12", "Dateline Standard Time" },
            { "Etc/GMT+2", "UTC-02" },
            { "Etc/GMT-12", "UTC+12" },
            { "Europe/Amsterdam", "W. Europe Standard Time" },
            { "Europe/Athens", "GTB Standard Time" },
            { "Europe/Belgrade", "Central Europe Standard Time" },
            { "Europe/Berlin", "W. Europe Standard Time" },
            { "Europe/Brussels", "Romance Standard Time" },
            { "Europe/Budapest", "Central Europe Standard Time" },
            { "Europe/Dublin", "GMT Standard Time" },
            { "Europe/Helsinki", "FLE Standard Time" },
            { "Europe/Istanbul", "GTB Standard Time" },
            { "Europe/Kiev", "FLE Standard Time" },
            { "Europe/London", "GMT Standard Time" },
            { "Europe/Minsk", "E. Europe Standard Time" },
            { "Europe/Moscow", "Russian Standard Time" },
            { "Europe/Paris", "Romance Standard Time" },
            { "Europe/Sarajevo", "Central European Standard Time" },
            { "Europe/Warsaw", "Central European Standard Time" },
            { "Indian/Mauritius", "Mauritius Standard Time" },
            { "Pacific/Apia", "Samoa Standard Time" },
            { "Pacific/Auckland", "New Zealand Standard Time" },
            { "Pacific/Fiji", "Fiji Standard Time" },
            { "Pacific/Guadalcanal", "Central Pacific Standard Time" },
            { "Pacific/Guam", "West Pacific Standard Time" },
            { "Pacific/Honolulu", "Hawaiian Standard Time" },
            { "Pacific/Pago_Pago", "UTC-11" },
            { "Pacific/Port_Moresby", "West Pacific Standard Time" },
            { "Pacific/Tongatapu", "Tonga Standard Time" }
        };
        string timeInfoKey = string.Empty;
        if (olsonWindowsTimes.ContainsValue(timeInfo))
            timeInfoKey = olsonWindowsTimes.FirstOrDefault(x => x.Value == timeInfo).Key;
        return timeInfoKey;
    }

第3步:

var finalResult=ConvertTimeZone(Datetime.UtcNow,"Central Standard Time");

public DateTime ConvertTimeZone(DateTime dateTime, string timeInfo)
    {
        var result = OlsonTimeZoneToTimeZoneInfo(timeInfo);
        if (result != null)
        {
            var finalTimeZone = TimeZoneInfo.FindSystemTimeZoneById(result);
            dateTime = (dateTime != null ? TimeZoneInfo.ConvertTimeFromUtc(dateTime != null ? dateTime : DateTime.UtcNow, finalTimeZone) : DateTime.UtcNow);
        }
        return dateTime;
    }
public static bool isValidTimeZoneId(string timeZoneId)
    {
        if (string.IsNullOrEmpty(timeZoneId) || string.IsNullOrWhiteSpace(timeZoneId))
            return false;
        ReadOnlyCollection<TimeZoneInfo> tz;
        tz = TimeZoneInfo.GetSystemTimeZones();
        return tz.Any(x => x.Id == timeZoneId);
    }

我首先通过制作一个快速验证器来解决这个问题。

相关文章: