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

.NET 6 TimeZoneInfo.FindSystemTimeZoneById does not support IANA timezone ids on Windows Server 2016 & 2019 #62329

Closed
Tracked by #64603
dmytro-gokun opened this issue Dec 3, 2021 · 18 comments · Fixed by #72656

Comments

@dmytro-gokun
Copy link

dmytro-gokun commented Dec 3, 2021

Description

As announced here: https://devblogs.microsoft.com/dotnet/date-time-and-time-zone-enhancements-in-net-6/
starting with .NET 6 TimeZoneInfo.FindSystemTimeZoneById should now support IANA timezone ids. That works just fine on Windows 10/10 & Windows Server 2022. It does not work on Windows Server 2016 & 2019 thought. Those are versions user by Azure App Services today. So, this functionality simple does not work on Azure.

Reproduction Steps

System.Console.WriteLine("{0}", System.TimeZoneInfo.FindSystemTimeZoneById("Europe/Copenhagen").Id);

Expected behavior

IANA timezone is resolved no matter what OS the code is run on.

Actual behavior

It is not resolved.

Regression?

Technically, it's not a regression. But, TimeZoneConverter library which was recommended to use before seems to be struggling to find a new maintainer: https://github.com/mattjohnsonpint/TimeZoneConverter/issues/105 which means it may not have regular updates in the future.

Known Workarounds

Add this to a project file helps:

<ItemGroup>
    <PackageReference Include="Microsoft.ICU.ICU4C.Runtime" Version="68.2.0.9" />
    <RuntimeHostConfigurationOption Include="System.Globalization.AppLocalIcu" Value="68.2" />
</ItemGroup>

This, however, has to be done to every single project which is tedious, time-consuming and error-prone.
Moreover, if we have a test DLL which uses TimeZoneInfo.FindSystemTimeZoneById, this workaround does not work (it only applies to EXEs).

Configuration

No response

Other information

No response

@dotnet-issue-labeler dotnet-issue-labeler bot added area-System.Globalization untriaged New issue has not been triaged by the area owner labels Dec 3, 2021
@ghost
Copy link

ghost commented Dec 3, 2021

Tagging subscribers to this area: @dotnet/area-system-globalization
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

As announced here: https://devblogs.microsoft.com/dotnet/date-time-and-time-zone-enhancements-in-net-6/
starting with .NET 6 TimeZoneInfo.FindSystemTimeZoneById should now support IANA timezone ids. That works just fine on Windows 10/10 & Windows Server 2022. It does not work on Windows Server 2016 & 2019 thought. Those are versions user by Azure App Services today. So, this functionality simple does not work on Azure.

Reproduction Steps

System.Console.WriteLine("{0}", System.TimeZoneInfo.FindSystemTimeZoneById("Europe/Copenhagen").Id);

Expected behavior

IANA timezone is resolved no matter what OS the code is run on.

Actual behavior

It is not resolved.

Regression?

Technically, it's not a regression. But, TimeZoneConverter library which was recommended to use before seems to be struggling to find a new maintainer: https://github.com/mattjohnsonpint/TimeZoneConverter/issues/105 which means it may not have regular updates in the future.

Known Workarounds

Add this to a project file helps:

This, however, has to be done to every single project which is tedious, time-consuming and error-prone.
Moreover, if we have a test DLL which uses TimeZoneInfo.FindSystemTimeZoneById, this workaround does not work (it only applies to EXEs).

Configuration

No response

Other information

No response

Author: dmytro-gokun
Assignees: -
Labels:

area-System.Globalization, untriaged

Milestone: -

@tarekgh
Copy link
Member

tarekgh commented Dec 3, 2021

This is by design as .NET doesn't carry ICU library. We still provide a solution for this situation which is deploying the ICU package as part of your app. it is easy to do so by adding the following to your csproj

  <ItemGroup>
    <RuntimeHostConfigurationOption Include="System.Globalization.AppLocalIcu" Value="68.2.0.6" />
    <PackageReference Include="Microsoft.ICU.ICU4C.Runtime" Version="68.2.0.6" />
  </ItemGroup>

If you want to learn more about that, please consult the doc https://docs.microsoft.com/en-us/dotnet/core/extensions/globalization-icu#app-local-icu.

@dmytro-gokun
Copy link
Author

@tarekgh Please read what i have written above:

This, however, has to be done to every single project which is tedious, time-consuming and error-prone.
Moreover, if we have a test DLL which uses TimeZoneInfo.FindSystemTimeZoneById, this workaround does not work (it only applies to EXEs).

All in all, it a really bad solution for a framework with is advertised as a cross-platform solution. IMO.

@tarekgh
Copy link
Member

tarekgh commented Dec 3, 2021

@dmytro-gokun

We are trying to not carry time zone data inside the framework. The reason is the data is changing rapidly and servicing is not trivial. If using ICU app-local feature is not satisfying you, you still have the option to use a library like https://www.nuget.org/packages/TimeZoneConverter/.

Thanks for your report.

@dmytro-gokun
Copy link
Author

@tarekgh

We are trying to not carry time zone data inside the framework

That's an absolutely correct decision. Still, I do not see why a completely separate native DLL is required here. A regular managed nuget package would do it perfectly. A 3rd party native DLL which is distributed with OS and depends on OS version - that's a definition of an overkill and overcomplication :)

If using ICU app-local feature is not satisfying you, you still have the option to use a library like nuget.org/packages/TimeZoneConverter.

That's what i've always been doing. Then i saw .NET 6 had a native "solution" and wanted to give it try. And as I can see now this solution creates more problems then it solves. Really disappointing.

Besides, TimeZoneConverter is not currently supported by anyone. Check out this: https://github.com/mattjohnsonpint/TimeZoneConverter/issues/105 IMO, if MS officially recommends a 3rd party lib in its documentation, it at least need to make sure the lib is alive (and maybe dedicate a maintainer to that lib).

Do not get me wrong: I really like what has been happening to .NET during the latest years. But this new "feature" is nothing more than a disappointment.

@wjrogers
Copy link

wjrogers commented Dec 3, 2021

I just hit this problem, too. I read the blog post announcing the new features in .NET 6, then happily removed references to TimeZoneConverter from my project because .NET supports it natively now! But when I pushed my changes, my units tests failed on GitHub Actions because IANA names do not work on Windows Server 2019. How do we apply the necessary "app-local ICU" configuration for unit tests?

@dmytro-gokun
Copy link
Author

@wjrogers Exactly my scenario. And they suggested solution simply does not work for unit tests

@tarekgh
Copy link
Member

tarekgh commented Dec 3, 2021

Reopen to try find a solution for the unit tests.

@tarekgh tarekgh reopened this Dec 3, 2021
@tarekgh tarekgh removed the untriaged New issue has not been triaged by the area owner label Dec 3, 2021
@tarekgh tarekgh added this to the Future milestone Dec 3, 2021
@wjrogers
Copy link

wjrogers commented Dec 3, 2021

I looked into the suggested work-around of referencing Microsoft.ICU.ICU4C.Runtime. The native ICU library is ~30 MB per runtime, for each of five supported arches. I honestly don't feel that referencing it is practical given its size. Is there any alternative for compatibility with Windows Server 2019? For example, is there a way to install Microsoft's system-wide ICU library?

@martincostello
Copy link
Member

The proposed solution does also work for unit tests. You just have to add the same properties/package to the test projects too.

@tarekgh
Copy link
Member

tarekgh commented Dec 3, 2021

@wjrogers

I looked into the suggested work-around of referencing Microsoft.ICU.ICU4C.Runtime. The native ICU library is ~30 MB per runtime, for each of five supported arches. I honestly don't feel that referencing it is practical given its size.

if you are publishing your app for specific architecture, only ICU bits match this runtime architecture will be copied to the bin folder. I am not sure why this is not acceptable.

@martincostello thanks for your response. @dmytro-gokun did you try what @martincostello mentioned and didn't work for you?

@wjrogers
Copy link

wjrogers commented Dec 3, 2021

if you are publishing your app for specific architecture, only ICU bits match this runtime architecture will be copied to the bin folder

The ~30 MB for one target runtime is still about a 30% increase in the size of my published application. I know storage is abundant and cheap, but I still think this matters when CI builds generate artifacts on every push. It's hard to justify compared to the 25 KB third-party alternative.

Thanks for your guidance. I'm just a bit disappointed that a new .NET feature announced with the phrase "there is now an easier way" doesn't work out of the box on Microsoft's own server operating system. Maybe you could edit the blog to mention the requirements for Windows support, too? (It currently only mentions pre-requisites for Linux, Mac, and Docker images.)

@tarekgh
Copy link
Member

tarekgh commented Dec 3, 2021

@wjrogers thanks for the feedback. I appreciate it.

Note that you'll need to add ICU only for Server 2019 deployment, but I understand this is not the best experience. Therefore, I am keeping this issue open to find out if we can make this experience better. Note, everything will work fine in Server 2022 :-) so, the issue would be localized only to Server 2019. (Server 2016 will be out of service for the mainstream next month). Anyway, I'll try to look more later early next year to see if we can do something for Server 2019.

@dmytro-gokun
Copy link
Author

@wjrogers JFYI: Server 2016 i still an OS on which Azure App Services run. So, this days this simply means the feature is unusable on Azure w/o additional hoop jumping. I have no idea when MS plans to switch Azure App Services to Windows Server 2022 and if that happens automatically for existing deployments or not.

@tarekgh
Copy link
Member

tarekgh commented Dec 6, 2021

Server 2016 i still an OS on which Azure App Services run.

I expect this will change soon after it is out of service.

So, this days this simply means the feature is unusable on Azure w/o additional hoop jumping

The feature is working using the app-locale. We are keeping this issue open to figure out if there is something we can do to improve the experience of Server versions which we don't use ICU there.

@dmytro-gokun
Copy link
Author

@tarekgh I have no idea what will happen in the future and when exactly. What i'm saying is that feature is unusable today on Azure without additional hoop jumping (which is not documented properly btw). That's it. .NET 6 has been released and one of its new features does not work out of the box on Microsoft's flagship platform. You may say whatever you want, but that is the fact. Sometimes it makes sense to admit that a mistake was made and think how to help people deal with that.

TWIMC: the good news is that TimeZoneConverter's author promises to maintain the library in foreseeable future: mattjohnsonpint/TimeZoneConverter#107 (comment)

@tarekgh tarekgh modified the milestones: Future, 7.0.0 Jan 13, 2022
@ghost
Copy link

ghost commented Jan 13, 2022

Tagging subscribers to this area: @dotnet/area-system-globalization
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

As announced here: https://devblogs.microsoft.com/dotnet/date-time-and-time-zone-enhancements-in-net-6/
starting with .NET 6 TimeZoneInfo.FindSystemTimeZoneById should now support IANA timezone ids. That works just fine on Windows 10/10 & Windows Server 2022. It does not work on Windows Server 2016 & 2019 thought. Those are versions user by Azure App Services today. So, this functionality simple does not work on Azure.

Reproduction Steps

System.Console.WriteLine("{0}", System.TimeZoneInfo.FindSystemTimeZoneById("Europe/Copenhagen").Id);

Expected behavior

IANA timezone is resolved no matter what OS the code is run on.

Actual behavior

It is not resolved.

Regression?

Technically, it's not a regression. But, TimeZoneConverter library which was recommended to use before seems to be struggling to find a new maintainer: https://github.com/mattjohnsonpint/TimeZoneConverter/issues/105 which means it may not have regular updates in the future.

Known Workarounds

Add this to a project file helps:

<ItemGroup>
    <PackageReference Include="Microsoft.ICU.ICU4C.Runtime" Version="68.2.0.9" />
    <RuntimeHostConfigurationOption Include="System.Globalization.AppLocalIcu" Value="68.2" />
</ItemGroup>

This, however, has to be done to every single project which is tedious, time-consuming and error-prone.
Moreover, if we have a test DLL which uses TimeZoneInfo.FindSystemTimeZoneById, this workaround does not work (it only applies to EXEs).

Configuration

No response

Other information

No response

Author: dmytro-gokun
Assignees: -
Labels:

area-System.Globalization

Milestone: 7.0.0

@tarekgh
Copy link
Member

tarekgh commented Feb 15, 2022

#60175

@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Jul 22, 2022
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Jul 22, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Aug 22, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants