[wasm] Use timezone abbreviations as fallback if full names don't exist (#45385)
authorTammy Qiu <tammy.qiu@yahoo.com>
Fri, 5 Mar 2021 01:54:15 +0000 (20:54 -0500)
committerGitHub <noreply@github.com>
Fri, 5 Mar 2021 01:54:15 +0000 (19:54 -0600)
* use unix ver of GetDisplayName instead of invariant display name

* Add tests for Daylight Names

* Use tz abbreviations as fallback for browser cases, added test cases, fixed regex

* Move abbrev fields to TimeZoneInfo.Unix.cs

* [wasm] If standard, or daylight names are not available, then fallback

.. to abbreviations.

[This code](https://github.com/dotnet/runtime/blob/master/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.GetDisplayName.cs#L29-L40) seems to return `true` result, even though `timeZoneDisplayName` is null/empty. So, in such a case don't set the out var
and let the abbrev get used as the fallback (like it already says in the
comment).

* add additional platform tests

* edit displayname test

Co-authored-by: Ankit Jain <radical@gmail.com>
src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.GetDisplayName.Invariant.cs [deleted file]
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.GetDisplayName.cs
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Unix.cs
src/libraries/System.Runtime/tests/System/TimeZoneInfoTests.cs

index 54b2856..a6b2c16 100644 (file)
     <Compile Include="$(CommonPath)Interop\Interop.TimeZoneDisplayNameType.cs">
       <Link>Common\Interop\Interop.TimeZoneDisplayNameType.cs</Link>
     </Compile>
-    <Compile Include="$(CommonPath)Interop\Interop.TimeZoneInfo.cs" Condition="'$(TargetsBrowser)' != 'true'">
+    <Compile Include="$(CommonPath)Interop\Interop.TimeZoneInfo.cs">
       <Link>Common\Interop\Interop.TimeZoneInfo.cs</Link>
     </Compile>
     <Compile Include="$(CommonPath)Interop\Interop.Utils.cs">
     <Compile Include="$(MSBuildThisFileDirectory)System\Environment.Browser.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\IO\DriveInfoInternal.Browser.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)System\IO\PersistedFiles.Browser.cs" />
-    <Compile Include="$(MSBuildThisFileDirectory)System\TimeZoneInfo.GetDisplayName.Invariant.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)System\TimeZoneInfo.GetDisplayName.cs" />
   </ItemGroup>
   <ItemGroup Condition="'$(IsOSXLike)' == 'true'">
     <Compile Include="$(CommonPath)Interop\OSX\Interop.libobjc.cs">
diff --git a/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.GetDisplayName.Invariant.cs b/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.GetDisplayName.Invariant.cs
deleted file mode 100644 (file)
index 14b302d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace System
-{
-    public sealed partial class TimeZoneInfo
-    {
-        private unsafe void GetDisplayName(Interop.Globalization.TimeZoneDisplayNameType nameType, string uiCulture, ref string? displayName)
-        {
-            displayName = _standardDisplayName;
-        }
-    }
-}
index b557c15..834b719 100644 (file)
@@ -58,7 +58,7 @@ namespace System
 
             // If there is an unknown error, don't set the displayName field.
             // It will be set to the abbreviation that was read out of the tzfile.
-            if (result)
+            if (result && !string.IsNullOrEmpty(timeZoneDisplayName))
             {
                 displayName = timeZoneDisplayName;
             }
index 614541a..30d4ca7 100644 (file)
@@ -34,6 +34,8 @@ namespace System
             bool[] StandardTime;
             bool[] GmtTime;
             string? futureTransitionsPosixFormat;
+            string? standardAbbrevName = null;
+            string? daylightAbbrevName = null;
 
             // parse the raw TZif bytes; this method can throw ArgumentException when the data is malformed.
             TZif_ParseRaw(data, out t, out dts, out typeOfLocalTime, out transitionType, out zoneAbbreviations, out StandardTime, out GmtTime, out futureTransitionsPosixFormat);
@@ -52,11 +54,11 @@ namespace System
                 if (!transitionType[type].IsDst)
                 {
                     _baseUtcOffset = transitionType[type].UtcOffset;
-                    _standardDisplayName = TZif_GetZoneAbbreviation(zoneAbbreviations, transitionType[type].AbbreviationIndex);
+                    standardAbbrevName = TZif_GetZoneAbbreviation(zoneAbbreviations, transitionType[type].AbbreviationIndex);
                 }
                 else
                 {
-                    _daylightDisplayName = TZif_GetZoneAbbreviation(zoneAbbreviations, transitionType[type].AbbreviationIndex);
+                    daylightAbbrevName = TZif_GetZoneAbbreviation(zoneAbbreviations, transitionType[type].AbbreviationIndex);
                 }
             }
 
@@ -69,14 +71,18 @@ namespace System
                     if (!transitionType[i].IsDst)
                     {
                         _baseUtcOffset = transitionType[i].UtcOffset;
-                        _standardDisplayName = TZif_GetZoneAbbreviation(zoneAbbreviations, transitionType[i].AbbreviationIndex);
+                        standardAbbrevName = TZif_GetZoneAbbreviation(zoneAbbreviations, transitionType[i].AbbreviationIndex);
                     }
                     else
                     {
-                        _daylightDisplayName = TZif_GetZoneAbbreviation(zoneAbbreviations, transitionType[i].AbbreviationIndex);
+                        daylightAbbrevName = TZif_GetZoneAbbreviation(zoneAbbreviations, transitionType[i].AbbreviationIndex);
                     }
                 }
             }
+
+            // Use abbrev as the fallback
+            _standardDisplayName = standardAbbrevName;
+            _daylightDisplayName = daylightAbbrevName;
             _displayName = _standardDisplayName;
 
             string uiCulture = CultureInfo.CurrentUICulture.Name.Length == 0 ? FallbackCultureName : CultureInfo.CurrentUICulture.Name; // ICU doesn't work nicely with Invariant
index ee4a0a1..82ed2ed 100644 (file)
@@ -81,6 +81,47 @@ namespace System.Tests
             Assert.NotNull(utc.ToString());
         }
 
+        //  Due to ICU size limitations, full daylight/standard names are not included.
+        //  name abbreviations, if available, are used instead
+        public static IEnumerable<object []> Platform_TimeZoneNamesTestData()
+        {
+            if (PlatformDetection.IsBrowser)
+                return new TheoryData<TimeZoneInfo, string, string, string>
+                {
+                    { TimeZoneInfo.FindSystemTimeZoneById(s_strPacific), "(UTC-08:00) PST", "PST", "PDT" },
+                    { TimeZoneInfo.FindSystemTimeZoneById(s_strSydney), "(UTC+10:00) AEST", "AEST", "AEDT" },
+                    { TimeZoneInfo.FindSystemTimeZoneById(s_strPerth), "(UTC+08:00) AWST", "AWST", "AWDT" },
+                    { TimeZoneInfo.FindSystemTimeZoneById(s_strIran), "(UTC+03:30) +0330", "+0330", "+0430" },
+
+                    { s_NewfoundlandTz, "(UTC-03:30) NST", "NST", "NDT" },
+                    { s_catamarcaTz, "(UTC-03:00) -03", "-03", "-02" }
+                };
+            else
+                return new TheoryData<TimeZoneInfo, string, string, string>
+                {
+                    { TimeZoneInfo.FindSystemTimeZoneById(s_strPacific), "(UTC-08:00) Pacific Standard Time", "Pacific Standard Time", "Pacific Daylight Time" },
+                    { TimeZoneInfo.FindSystemTimeZoneById(s_strSydney), "(UTC+10:00) Australian Eastern Standard Time", "Australian Eastern Standard Time", "Australian Eastern Daylight Time" },
+                    { TimeZoneInfo.FindSystemTimeZoneById(s_strPerth), "(UTC+08:00) Australian Western Standard Time", "Australian Western Standard Time", "Australian Western Daylight Time" },
+                    { TimeZoneInfo.FindSystemTimeZoneById(s_strIran), "(UTC+03:30) +0330", "+0330", "+0430" },
+
+                    { s_NewfoundlandTz, "(UTC-03:30) NST", "NST", "NDT" },
+                    { s_catamarcaTz, "(UTC-03:00) -03", "-03", "-02" }
+                };        
+        }
+
+        [Theory]
+        [MemberData(nameof(Platform_TimeZoneNamesTestData))]
+        [PlatformSpecific(TestPlatforms.AnyUnix)]
+        public static void Platform_TimeZoneNames(TimeZoneInfo tzi, string displayName, string standardName, string daylightName)
+        {
+            if (PlatformDetection.IsBrowser)
+            {
+                // Console.WriteLine($"DisplayName: {tzi.DisplayName}, StandardName: {tzi.StandardName}, DaylightName: {tzi.DaylightName}");
+                Assert.Equal($"DisplayName: {tzi.DisplayName}, StandardName: {tzi.StandardName}, DaylightName: {tzi.DaylightName}",
+                            $"DisplayName: {displayName}, StandardName: {standardName}, DaylightName: {daylightName}");
+            }
+        }
+
         [Fact]
         public static void ConvertTime()
         {