-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Improve time zone display names on Unix #48931
Improve time zone display names on Unix #48931
Conversation
Tagging subscribers to this area: @tarekgh, @safern Issue DetailsThis PR tackles the problem described in #16232, addressing a long-unresolved TODO comment in the Unix implementation of setting the value for While its still true that ICU doesn't expose the generic name via the
In my implementation, each is retrieved separately in native code, then they are combined with the base UTC offset in managed code. They are combined in various ways to produce a final Even with access to these strings, there are several edge cases that have to be handled. Most are in the managed code in Below are the time zones before and after this change (Ubuntu 20.10, ICU 67.1-4, en-US). Observe from the "before" list, the problem of not being able to distinguish one time zone from another by looking only at the I also addressed a related issue, which was that the UTC time zone not using localized display names, but was fixed to the English "Coordinated Universal Time" on both Unix and Windows. It is now localized using the same locale as the other names (using the OS language on Windows, and using Before(click to expand)
After(click to expand)
The above lists were generated with this simple program: using System;
using System.Linq;
namespace ListTimeZones
{
class Program
{
static void Main(string[] args)
{
var timeZones = TimeZoneInfo.GetSystemTimeZones();
int col1Size = timeZones.Max(x => x.Id.Length);
int col2Size = timeZones.Max(x => x.DisplayName.Length);
Console.WriteLine("| " + "Id".PadRight(col1Size) + " | " + "Display Name".PadRight(col2Size) + " |");
Console.WriteLine("| " + new string('-', col1Size) + " | " + new string('-', col2Size) + " |");
foreach (TimeZoneInfo tzi in timeZones)
{
Console.WriteLine($"| {tzi.Id.PadRight(col1Size)} | {tzi.DisplayName.PadRight(col2Size)} |");
}
Console.WriteLine();
}
}
}
|
src/libraries/Native/Unix/System.Globalization.Native/pal_timeZoneInfo.c
Outdated
Show resolved
Hide resolved
src/libraries/Native/Unix/System.Globalization.Native/pal_timeZoneInfo.c
Outdated
Show resolved
Hide resolved
src/libraries/Native/Unix/System.Globalization.Native/pal_timeZoneInfo.c
Outdated
Show resolved
Hide resolved
src/libraries/Native/Unix/System.Globalization.Native/pal_timeZoneInfo.c
Outdated
Show resolved
Hide resolved
cc @tqiu8 |
src/libraries/Native/Unix/System.Globalization.Native/pal_timeZoneInfo.c
Outdated
Show resolved
Hide resolved
src/libraries/Native/Unix/System.Globalization.Native/pal_timeZoneInfo.c
Outdated
Show resolved
Hide resolved
src/libraries/Native/Unix/System.Globalization.Native/pal_timeZoneInfo.c
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Unix.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Unix.cs
Outdated
Show resolved
Hide resolved
Just curious as I am not knowledgeable about timezones -- what would be the impact of the user picking the wrong one of the several Alaska time zones? They are all -9:00. I'm not sure which -8:00 I should pick for Seattle, even when they are marked Los Angeles and Vancouver. |
Looks like I have some platform-specific build failures to resolve also. |
@danmoseley - Indeed, that's a general issue with time zones - there are quite a lot of them. The reason has to do with historical accuracy. IANA time zones aim to be accurate from 1970 forward, thus any variation in local time between nearby locations since 1970 get a distinct time zone. For Alaska, the only two that matter today are For Pacific time, there are three. Vancouver for Canada, Los Angeles for the USA, and Tijuana for Mexico. They too have had some historical differences. Thus, the impact if a user choses the wrong time zone is that they get the changes in UTC offsets and daylight start/stop transition dates for the entire range of that time zone. If they are only working with "now" or nearby dates, that might not be noticed at all. If they are working with older dates, they could be off by an hour or more depending on the date in question. The same thing plays out with regard to any anticipated upcoming changes for future dates, if those changes are accounted for in their respective time zones. Since the only API we have presently is Incidentally, legacy Windows registry-based time zones are fewer in number only because originally Windows hadn't set any particular consistency date (like IANA's 1970). That changed in 2016 when we formalized some of Microsoft's time zone policies and set a consistency date of 2010. If they had aimed for 1970 and covering the world, there would be just as many as IANA. |
@lewing could you please advise if referencing the extra ICU methods is fine with wasm and other mobile platforms? |
Are there any tests we can write for this new functionality? |
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.GetDisplayName.Invariant.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Unix.cs
Outdated
Show resolved
Hide resolved
src/libraries/Native/Unix/System.Globalization.Native/pal_timeZoneInfo.c
Outdated
Show resolved
Hide resolved
Yes. I will add some. Thanks for calling that out. 👍 |
719c8d1
to
4200b75
Compare
It looks like this overlaps with #45385 for browser which is trying to get something to display when the display name doesn't exist in icu. From a quick scan my main concern is that we'd end up pulling in more unmanaged symbols (and size) to query for data that is unlikely to be in the icu data. @tqiu8 can you take a look? |
I thought that was already handled, but I guess not. The changes in #45385 look good to me. IMHO, it should go first and then I can rebase this on top of that and adjust. |
a1701e4
to
2fdfaea
Compare
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Unix.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Unix.cs
Outdated
Show resolved
Hide resolved
src/libraries/Native/Unix/System.Globalization.Native/pal_timeZoneInfo.c
Show resolved
Hide resolved
I am not getting why we have this condition? we are executing the method with remote executer any way and we force Invariant to the UI culture. This doesn't look right to condition it. I know this not your change but I think we can remove this condition and keep only the remote execution condition. Refers to: src/libraries/System.Runtime/tests/System/TimeZoneInfoTests.cs:2542 in 50d0fd2. [](commit_id = 50d0fd2, deletion_comment = False) |
I think this is specifically about proper handling of The English condition is again about being locked to the OS language on Windows. |
Thanks @mattjohnsonpint for all work provided here. |
+1 thank you @mattjohnsonpint for this significant effort. |
Seems like this possibly caused a size regression in dotnet.wasm |
* Update dependencies from https://github.com/dotnet/installer build 20210408.1 Microsoft.Dotnet.Sdk.Internal From Version 6.0.100-preview.3.21202.5 -> To Version 6.0.100-preview.4.21208.1 * Update dependencies from https://github.com/dotnet/installer build 20210409.4 Microsoft.Dotnet.Sdk.Internal From Version 6.0.100-preview.3.21202.5 -> To Version 6.0.100-preview.4.21209.4 * Update dependencies from https://github.com/dotnet/installer build 20210410.1 Microsoft.Dotnet.Sdk.Internal From Version 6.0.100-preview.3.21202.5 -> To Version 6.0.100-preview.4.21210.1 * same P4 specific fix as ccb43cb but the ICU support was added based on P3 but merged after ^ * Update dependencies from https://github.com/dotnet/installer build 20210412.5 Microsoft.Dotnet.Sdk.Internal From Version 6.0.100-preview.3.21202.5 -> To Version 6.0.100-preview.4.21212.5 * Update dependencies from https://github.com/dotnet/installer build 20210413.70 Microsoft.Dotnet.Sdk.Internal From Version 6.0.100-preview.3.21202.5 -> To Version 6.0.100-preview.4.21213.70 * Update dependencies from https://github.com/dotnet/installer build 20210414.14 Microsoft.Dotnet.Sdk.Internal From Version 6.0.100-preview.3.21202.5 -> To Version 6.0.100-preview.4.21214.14 * Update to new package names Thanks @pjcollins for the heads up #11175 (comment) * Update dependencies from https://github.com/dotnet/installer build 20210415.1 Microsoft.Dotnet.Sdk.Internal From Version 6.0.100-preview.3.21202.5 -> To Version 6.0.100-preview.4.21215.1 * Fix build (path changed to include '.mono') * remove more '.mono' special case that are not needed anymore * Update dependencies from https://github.com/dotnet/installer build 20210415.12 Microsoft.Dotnet.Sdk.Internal From Version 6.0.100-preview.3.21202.5 -> To Version 6.0.100-preview.4.21215.12 * Fix building apps (it now finds the native libs) Credits to @filipnavara filipnavara@8325f8d * Add back IsTrimmable (or nothing gets linked) * Update dependencies from https://github.com/dotnet/installer build 20210418.6 Microsoft.Dotnet.Sdk.Internal From Version 6.0.100-preview.3.21202.5 -> To Version 6.0.100-preview.4.21218.6 * Keep downloading the CoreCLR runtime packs. * [runtime] Adjust the build to link with the correct runtime library for CoreCLR. * [tests][monotouch-test] Ignore NSTimeZoneTest / All_28300 on dotnet as it hangs Introduced with dotnet/runtime#48931 Issue https://unicode-org.atlassian.net/browse/ICU-21591 PR unicode-org/icu#1699 * [dotnet][msbuild] Add more (missing) '\' Fix satellite/location assemblies and some unit tests Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com> Co-authored-by: Alex Soto <alex@alexsoto.me> Co-authored-by: Manuel de la Pena <mandel@microsoft.com> Co-authored-by: Sebastien Pouliot <sebastien.pouliot@microsoft.com> Co-authored-by: Sebastien Pouliot <sebastien.pouliot@gmail.com> Co-authored-by: Rolf Bjarne Kvinge <rolf@xamarin.com>
This PR tackles the problem described in #16232, addressing a long-unresolved TODO comment in the Unix implementation of setting the value for
TimeZoneInfo.DisplayName
.While its still true that ICU doesn't expose the generic name via the
ucal_getTimeZoneDisplayName
function, we can get at various forms of the generic name via theudat_format
function instead, by formatting the a datetime with patterns. The ICU date field symbol table gives several different patterns that are useful to us:vvvv
- The generic non-location time zone name (ex: "Pacific Time")VVVV
- The generic time zone location name (ex: "Los Angeles Time")VVV
- The exemplar city associated with the time zone (ex: "Los Angeles")In my implementation, each is retrieved separately in native code, then they are combined with the base UTC offset in managed code. They are combined in various ways to produce a final
DisplayName
for the time zone that is unique, discoverable, and intuitive when presenting a list.Even with access to these strings, there are several edge cases that have to be handled. Most are in the managed code in
TimeZoneInfo.Unix.cs
, and one is handled in native code inpal_timeZoneInfo.c
. They are documented in the code comments.Below are the time zones before and after this change (Ubuntu 20.10, ICU 67.1-4, en-US). Observe from the "before" list, the problem of not being able to distinguish one time zone from another by looking only at the
DisplayName
. For example, there were 13 different time zones that had the same string(UTC-07:00) Mountain Standard Time
. That was very problematic for an end-user to choose a time zone.I also addressed a related issue, which was that the UTC time zone not using localized display names, but was fixed to the English "Coordinated Universal Time" on both Unix and Windows. It is now localized using the same locale as the other names (using the OS language on Windows, and using
CurrentUICulture
on Unix).Before
(click to expand)
After
(click to expand)
The above lists were generated with this simple program: