'System.TimeZoneNotFoundException error while getting datetime for particular time zone in c#

I've a JSON file which has time_zone parameter. It has values like London, Casablanca, Arizona, Pacific Time (US & Canada) etc. Based on the time_zone, I want to get the DateTime result of that time zone.

For example,

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.

I want to display the current time as well as time as per given time zone.

I tried following approach to get time for respected time zone but it is throwing an error.

Code: Works

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

Error : 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);

Also tried but same error,

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

My issue is, time_zone values are in Central Time (US & Canada), Pacific Time (US & Canada), etc. format and I've to work with that as well as different time zones like London, Casablanca . How to handle this kind of scenarios.



Solution 1:[1]

if using docker use this

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

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

else go with this it takes 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;
}

Solution 2:[2]

I didn't solved this issue but I have a work around for this scenario using https://stackoverflow.com/a/6144229/7670060. Hope this will help.

Step1:

Find the list of time zone in your computer.

var timeZones = TimeZoneInfo.GetSystemTimeZones();

Step2:

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;
    }

Step3:

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;
    }

Solution 3:[3]

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);
    }

I solve the issue by making a quick validator first.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 IvanO