Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Map Unix TimeZoneId to Windows TimeZoneId #18644

Closed
jchannon opened this issue Sep 20, 2016 · 29 comments
Closed

Map Unix TimeZoneId to Windows TimeZoneId #18644

jchannon opened this issue Sep 20, 2016 · 29 comments
Labels
api-needs-work API needs work before it is approved, it is NOT ready for implementation area-System.DateTime
Milestone

Comments

@jchannon
Copy link

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?

@karelz
Copy link
Member

karelz commented Nov 8, 2016

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.

@mattjohnsonpint
Copy link
Contributor

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.

@jchannon
Copy link
Author

Any update on this, maybe a netstandard 2.0 thing?

@karelz
Copy link
Member

karelz commented Jan 12, 2017

.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.

@mattjohnsonpint
Copy link
Contributor

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.

@linflux
Copy link

linflux commented Jan 24, 2017

@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

@philjones88
Copy link

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.

@karelz
Copy link
Member

karelz commented Jan 24, 2017

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.

@mattjohnsonpint
Copy link
Contributor

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.

@mattjohnsonpint
Copy link
Contributor

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.

@jchannon
Copy link
Author

jchannon commented Jan 28, 2017 via email

@mattjohnsonpint
Copy link
Contributor

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

@jchannon
Copy link
Author

jchannon commented Jun 1, 2017 via email

@alexsandro-xpt
Copy link

alexsandro-xpt commented Dec 20, 2017

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.

@mattjohnsonpint
Copy link
Contributor

mattjohnsonpint commented Dec 28, 2017

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.

@alexsandro-xpt
Copy link

@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.

@CShepartd
Copy link

CShepartd commented Mar 14, 2018

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

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

@mattjohnsonpint
Copy link
Contributor

@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.

@mattjohnsonpint
Copy link
Contributor

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

@alexsandro-xpt
Copy link

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

@mattjohnsonpint
Copy link
Contributor

mattjohnsonpint commented Mar 16, 2018

@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.

@MatthewLymer
Copy link

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

@schmitch
Copy link

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)

ascott18 referenced this issue in IntelliTect/Coalesce Jan 4, 2019
* Update everything to netcoreapp2.2
Tests pass and generation works for both KO and Vue

* Remove deps on obsolete logging setup.  Fix some netcoreapp2.1 refs.  Upgraded vue-cli to fix build issues.

* Updated some Vue npm bits

* Update Sourcelink to latest to remove dep on GitSharpLib

* Changed to use 'webpack-env' instead of node in tsconfig per microsoft/nodejstools#2085

* Don't serve the /public/index.html, serve the one out of wwwroot

* Make UseTimeZone cross-platform until https://github.com/dotnet/corefx/issues/11897 is fixed.

* Fix VS trying to be "helpful"

* Not hardcode the wwwroot convention
@ahmedalejo
Copy link

ahmedalejo commented Jan 10, 2019

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.

@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the 5.0 milestone Jan 31, 2020
@maryamariyan maryamariyan added the untriaged New issue has not been triaged by the area owner label Feb 23, 2020
@qJake
Copy link

qJake commented Apr 6, 2020

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. ☹️)

@Clockwork-Muse
Copy link
Contributor

@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).

@tarekgh
Copy link
Member

tarekgh commented Mar 12, 2021

The PR #49412 now allowing to create a TZI objects using IANA or Windows Ids no matter you are running on Windows or Linux.

@tarekgh
Copy link
Member

tarekgh commented Apr 12, 2021

#51093

@tarekgh
Copy link
Member

tarekgh commented Apr 14, 2021

We have merged the time zone names conversion #51093. I am closing this issue but feel free to send any quesstion as needed.

@tarekgh tarekgh closed this as completed Apr 14, 2021
@ghost ghost locked as resolved and limited conversation to collaborators May 14, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-needs-work API needs work before it is approved, it is NOT ready for implementation area-System.DateTime
Projects
None yet
Development

No branches or pull requests