Support bracket enclosed names in TZ POSIX rules
authorEric Erhardt <eric.erhardt@microsoft.com>
Tue, 14 Mar 2017 17:49:43 +0000 (12:49 -0500)
committerEric Erhardt <eric.erhardt@microsoft.com>
Wed, 15 Mar 2017 14:32:06 +0000 (09:32 -0500)
The POSIX time zone rules at the end of a tzfile have been updated to allow digits, plus signs and minus signs in the time zone names by enclosing the name in `<` and `>` characters. TimeZoneInfo's parsing logic was written using an older version of the spec, so it didn't have support for this format.

Fix https://github.com/dotnet/corefx/issues/16962

Commit migrated from https://github.com/dotnet/coreclr/commit/4bcc0d5d9e8870bfb579c069c2d5b4dd3b4b3b1e

src/coreclr/src/mscorlib/src/System/TimeZoneInfo.Unix.cs

index bb12c6b..5ebd063 100644 (file)
@@ -927,7 +927,7 @@ namespace System
         /// Creates an AdjustmentRule given the POSIX TZ environment variable string.
         /// </summary>
         /// <remarks>
-        /// See http://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html for the format and semantics of this POSX string.
+        /// See http://man7.org/linux/man-pages/man3/tzset.3.html for the format and semantics of this POSX string.
         /// </remarks>
         private static AdjustmentRule TZif_CreateAdjustmentRuleForPosixFormat(string posixFormat, DateTime startTransitionDate, TimeSpan timeZoneBaseUtcOffset)
         {
@@ -1189,8 +1189,32 @@ namespace System
             return !string.IsNullOrEmpty(standardName) && !string.IsNullOrEmpty(standardOffset);
         }
 
-        private static string TZif_ParsePosixName(string posixFormat, ref int index) =>
-            TZif_ParsePosixString(posixFormat, ref index, c => char.IsDigit(c) || c == '+' || c == '-' || c == ',');
+        private static string TZif_ParsePosixName(string posixFormat, ref int index)
+        {
+            bool isBracketEnclosed = index < posixFormat.Length && posixFormat[index] == '<';
+            if (isBracketEnclosed)
+            {
+                // move past the opening bracket
+                index++;
+
+                string result = TZif_ParsePosixString(posixFormat, ref index, c => c == '>');
+
+                // move past the closing bracket
+                if (index < posixFormat.Length && posixFormat[index] == '>')
+                {
+                    index++;
+                }
+
+                return result;
+            }
+            else
+            {
+                return TZif_ParsePosixString(
+                    posixFormat,
+                    ref index,
+                    c => char.IsDigit(c) || c == '+' || c == '-' || c == ',');
+            }
+        }
 
         private static string TZif_ParsePosixOffset(string posixFormat, ref int index) =>
             TZif_ParsePosixString(posixFormat, ref index, c => !char.IsDigit(c) && c != '+' && c != '-' && c != ':');