Runtime: Map Unix TimeZoneId to Windows TimeZoneId

Created on 20 Sep 2016  ·  26Comments  ·  Source: dotnet/runtime

If I execute TimeZoneInfo.GetSystemTimeZones() on Linux & Windows I get different lists, this is because each OS uses a different timezone db.

However, is there a way in .netcore to get a consistent list no matter the OS and/or is there a way that TimeZoneInfo.FindSystemTimeZoneById on Windows will work with a Unix timezone id and vice versa a Windows id parsed on a Unix OS?

api-needs-work area-System.Globalization

Most helpful comment

I've completed this work. The package is on Nuget as TimeZoneConverter, and it targets .NET Standard 1.1.

https://github.com/mj1856/TimeZoneConverter

Example usages in the readme, including one to get a TimeZoneInfo regardless of which platform you're on or which flavor of time zone you have.

All 26 comments

Next steps: We need formal API proposal.
It will be entangled with all the other TimeZoneInfo issue - will likely be non-trivial API design and implementation.

Any such implementation will require the mapping data from CLDR. This may or may not already be available on the OS, or may have to be included manually.

Then you have to consider _overrides_. That is - since CLDR only updates twice annually, what do you do to keep in sync when new time zones come out (on either side)?

FYI, Noda Time also had this concern, and this same problem. See nodatime/nodatime#473

IMHO, if there were to be a library for this, it should be done in its own nuget package. It might contain a fair amount of data, and would rev frequently to keep up with overrides.

Any update on this, maybe a netstandard 2.0 thing?

.NET Standard 2.0 is about APIs which are common across runtimes/implementations - .NET Core, Desktop and Xamarin. This is new API, so it does not fit that bucket.
We intentionally set the Milestone to Future to communicate that we do not plan to address it ourselves in next release - .NET Core 2.0.

The next steps are highlighted in my earlier comment. If anyone from the community is passionate about it, feel free to help and contribute.

So far there is only 1 person interested. There is also suggestion to make it external to CoreFX (I don't have personal opinion on that yet), it should be seriously considered as well.
Realistically: Given the limited interest and given that we have many issues which have much more impact and interest from community, it is unlikely .NET Core team will invest in this issue anytime soon if ever.
Of course, if you believe the impact is not well understood/assessed on our side, we are always open to more evidence, discussion, etc. - we are willing to change our view point under the right circumstances.

I plan to create a separate OSS library that will properly do CLDR-based IANA to Windows time zone conversions, in a maintainable way, and isolated from other libraries. This will complement the framework, as well as other libraries in this space, such as NodaTime and my GeoTimeZone and TimeZoneNames libraries.

I'll ship it as a netstandard library. That will give people a viable solution to this problem.

@karelz I'm here to say that i'm interested in this too.
I'm using dotnet core 1.1 on Web API Applications running on Linux Docker and need to convert DateTime.Now to an EST (-5h) TimeZone. It works on Windows using:

TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");

But fails on Linux, I should use this instead:

TimeZoneInfo.FindSystemTimeZoneById("America/New_York");

And to help the TimeZoneNotFoundException isn't exposed in .NET Core.
TimeZoneNotFoundException not exist in .NET Core

I was hoping that Unix + Windows would share timezone ID's and finally enable a cross platform API that uses date time data to work properly without having to do hacky stuff server side.

I really wanted the Windows version to use the same as Unix so in our company's Angular (2) app we could use something like momentjs to do datetime calculations browser side without having to talk to the server incase the API is running on Windows.

Momentjs uses the standard timezones so won't work with Window's database versions.

Really disappointing this isn't a higher priority.

Thanks for feedback @linflux @philjones88 , for easier tracking can you please upvote top most post? It is something easy to sort and look at in future.

Overall, after reading https://github.com/dotnet/corefx/issues/11897#issuecomment-259851156 by @mj1856 it seems to me that a standalone library is probably the best solution in this case. I don't think it is a great idea to include in the framework something that changes twice annually. ... just my 2 cents for now.

It revs much more than that because we can't only rely on CLDR release versions. We also have to take into consideration the changes that ship in IANA TZDB releases, and in Windows updates. These tend to make it into the dev-trunk of CLDR in a relatively timely manner, but then they sit there until the next semiannual CLDR release. So really - having a separate microlibrary for this bit makes a lot of sense because a maintainer (like myself) can rev the library as necessary, regardless of which input signal changes.

I've completed this work. The package is on Nuget as TimeZoneConverter, and it targets .NET Standard 1.1.

https://github.com/mj1856/TimeZoneConverter

Example usages in the readme, including one to get a TimeZoneInfo regardless of which platform you're on or which flavor of time zone you have.

Awesome work. Thank you!!

On 28 January 2017 at 01:28, Matt Johnson notifications@github.com wrote:

I've completed this work. The package is on Nuget as TimeZoneConverter,
and it targets .NET Standard 1.1.

https://github.com/mj1856/TimeZoneConverter

Example usages in the readme, including one to get a TimeZoneInfo
regardless of which platform you're on or which flavor of time zone you
have.


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/dotnet/corefx/issues/11897#issuecomment-275816438,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAGappAyIT5qOfDCOAFnJoSqs0HNUQ9Rks5rWpnMgaJpZM4KBbk1
.

FYI - I merged the GetTimeZoneInfo code into the library in version 2.0.0.

Great, thanks!

On 1 June 2017 at 01:47, Matt Johnson notifications@github.com wrote:

FYI - I merged the GetTimeZoneInfo code into the library in version 2.0.0.


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/dotnet/corefx/issues/11897#issuecomment-305357781,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAGapibBD0NdF8e88JVr5TBJSUoljePkks5r_goqgaJpZM4KBbk1
.

Is this issue still paused?!

I'm using dotnet core 2.0 trying use alternative solution like NodaTime and TimeZoneConverter but some IANA ids not exist in Windows and convertions like ZConvert.IanaToWindows("Antarctica/Troll") throw exception "Antarctica/Troll" was not recognized as a valid IANA time zone name, or has no equivalant Windows time zone.

The exception message is correct. Antarctica/Troll does not currently have an equivalent Windows time zone. Nothing could be done in .NET to change that.

For years 2015 and prior, Troll Station rotated through three distinct time zone offsets (+0, +1, +2), causing the transitions between offsets also to deviate (+1, +1 -2). See reference here. This data cannot be represented in the underlying Windows registry TZI format.

It would be possible for a Windows zone to be established, but conversions would only be accurate for 2016 forward (when they switched to alternating between just +0 and +2) . If you have sufficient need for such a time zone to exist, please explain in detail here (or contact me directly) and I will take it up with the Windows time zone servicing team here at Microsoft.

Note that according to Wikipedia's entry on Troll Station, it has a capacity of 8 people in winter and 40 in the summer. To my knowledge, we haven't had a request from any of them, or from the Norwegian government, or other parties that may have an interest in timekeeping of Troll Station. It is mildly annoying that there exists an unmappable time zone between the two data sets, but other than that - it is difficult to justify creation of one in this particular case.

@mj1856 thank you for reply, I tell Antarctica/Troll as an example of that I can't trust in TimeZone Convertion between Linux and Windows and I knowing why. I was looking for some kind of conversion but like you said, It's more about Windows limitation and how it is implemented today.

So, to solve my question temporarily I'm using fixed IANA TimeZone.
Thank you for attention.

Be carefull about using TimeZoneConverter (https://github.com/mj1856/TimeZoneConverter) cuz is vver 13000% slower than BCL and over 54000% slower than NodaTime (https://github.com/mj1856/TimeZoneConverter/issues/14)

I hope .Net Core get independent from system timezone and evolve into IANA time (or windows get new timezone API)

@CShepartd - there is a constructive way to go about requesting perf improvements and this is not it. Note that in your tests you posted to the issue in my repo, you are primarily testing conversion - which is outside the scope of what the library provides. We can discuss improving perf on the lookup/mapping, perhaps by adding some internal caching, but as I pointed out before - being inflammatory and flippant does not get you very far.

FYI - I have addressed the perf concern @CShepartd described. It is resolved in version 2.3.1.

Take a look how I'm using @CShepartd

public static DateTimeOffset FromUtcToTimeZone(DateTime date, string timeZoneId)
{
    if (date.Kind != DateTimeKind.Utc) throw new Exception($"Can not convert to {timeZoneId} because {date} is not set as UTC kind.");

    DateTimeOffset dateWithOffSet  = date;

    if (string.IsNullOrWhiteSpace(timeZoneId))
    {
        return dateWithOffSet;
    }

    TimeZoneInfo tz;
    if (System.Environment.OSVersion.Platform == PlatformID.Win32NT)
    {
        tz = TimeZoneInfo.FindSystemTimeZoneById(TZConvert.IanaToWindows(timeZoneId));
    }
    else
    {
        tz = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
    }

    return TimeZoneInfo.ConvertTime(dateWithOffSet, tz);
}

I'm using TZConvert.IanaToWindows from https://github.com/mj1856/TimeZoneConverter I will change it to NodaTime ASAP

@alexsandro-xpt The perf issue was not with the IanaToWindows call, but in the GetTimeZoneInfo method - which you could use to replace the middle part of your code (L12-20 shown here).

The issue was specifically related to a control-flow-by-exception in the implementation, which has since been refactored out. The latest version, 2.3.1, does not have this perf issue.

I'd like this functionality built into .NET Core. Thanks for your effort on the library @mj1856, it's very useful for us.

well it would be enough if the Library would be named Microsoft.TimeZone or something along the lines and be officially supported (or at least listed in the official docs)

FYI - I have addressed the perf concern @CShepartd described. It is resolved in version 2.3.1.

So it did get far enough for it get to resolved. He´s word were really noisy and correct to ignore.

Would be great to have this. I am running into a scenario where I'm building a Docker container containing an ASP.NET Core 3.1 website, and I offer up a dropdown of timezones. In certain container environments, TimeZoneInfo.GetSystemTimeZones() does not return any results.

And, as mentioned before, if the TZ environment variable is set, it contains a Unix-style timezone (e.g. America/Chicago), not the .NET parseable equivalent (Central Standard Time).

image

It would be great if we could address this and/or find a better cross-platform solution for .NET 5!

(P.S. Timezones are really hard. ☹️)

@qJake -

Unix-style timezone strings are indeed parseable - on Unix derivatives.

In certain container environments, TimeZoneInfo.GetSystemTimeZones() does not return any results.

This is the actual problem - your string should be parseable, but because it can't find _any_ timezones, it looks like your _specific_ ones don't work. For that matter, if GetSystemTimeZones() returns no results, I'd expect Windows timezones to fail as well.

Note that varying the list of timezones offered to your users based on the OS would likely be a mis-feature - and given the prevalence elsewhere, in a web context I'd default to the Unix/Olson tzdb identifiers (even if my OS was Windows).

Was this page helpful?
0 / 5 - 0 ratings