Enable DateTimeFormatInfo netstandard 1.7 APIs on Linux (#7713)
authorTarek Mahmoud Sayed <tarekms@microsoft.com>
Wed, 19 Oct 2016 01:28:36 +0000 (18:28 -0700)
committerGitHub <noreply@github.com>
Wed, 19 Oct 2016 01:28:36 +0000 (18:28 -0700)
* Enable DateTimeFormatInfo netstandard 1.7 APIs on Linux

* Remove un-necessary return

src/mscorlib/corefx/SR.cs
src/mscorlib/corefx/System/Globalization/CultureData.cs
src/mscorlib/corefx/System/Globalization/DateTimeFormatInfo.cs
src/mscorlib/corefx/System/Globalization/STUBS.cs

index 7ec0904..1b32d92 100644 (file)
@@ -4,6 +4,11 @@ namespace System.Globalization
 {
     internal static class SR
     {
+        public static string Arg_ArrayZeroError
+        {
+            get { return Environment.GetResourceString("Arg_ArrayZeroError"); }
+        }
+
         public static string Arg_HexStyleNotSupported
         {
             get { return Environment.GetResourceString("Arg_HexStyleNotSupported"); }
index 4a92c08..62c1ff4 100644 (file)
@@ -1665,6 +1665,13 @@ namespace System.Globalization
             }
         }
 
+        // Native calendar names.  index of optional calendar - 1, empty if no optional calendar at that number
+        internal string CalendarName(CalendarId calendarId)
+        {
+            // Get the calendar
+            return GetCalendar(calendarId).sNativeName;
+        }
+
         internal CalendarData GetCalendar(CalendarId calendarId)
         {
             Contract.Assert(calendarId > 0 && calendarId <= CalendarId.LAST_CALENDAR,
index da746ad..8f4f775 100644 (file)
@@ -55,7 +55,6 @@ namespace System.Globalization
 
 
     [Serializable]
-    [System.Runtime.InteropServices.ComVisible(true)]
     public sealed partial class DateTimeFormatInfo : IFormatProvider, ICloneable
     {
         // cache for the invariant culture.
@@ -807,27 +806,35 @@ namespace System.Globalization
             }
         }
 
-
         // Note that cultureData derives this from the short date format (unless someone's set this previously)
         // Note that this property is quite undesirable.
-        internal String DateSeparator
+        public string DateSeparator
         {
             get
             {
-                if (this.dateSeparator == null)
+                if (dateSeparator == null)
                 {
-                    this.dateSeparator = _cultureData.DateSeparator(Calendar.ID);
+                    dateSeparator = _cultureData.DateSeparator(Calendar.ID);
                 }
                 Contract.Assert(this.dateSeparator != null, "DateTimeFormatInfo.DateSeparator, dateSeparator != null");
-                return (this.dateSeparator);
+                return dateSeparator;
             }
+           
             set
             {
-                throw null;
+                if (IsReadOnly)
+                    throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+
+                if (value == null)
+                {
+                    throw new ArgumentNullException("value", SR.ArgumentNull_String);
+                }
+                Contract.EndContractBlock();
+                ClearTokenHashTable();
+                dateSeparator = value;
             }
         }
 
-
         public DayOfWeek FirstDayOfWeek
         {
             get
@@ -1270,7 +1277,7 @@ namespace System.Globalization
 
         // Note that cultureData derives this from the long time format (unless someone's set this previously)
         // Note that this property is quite undesirable.
-        internal String TimeSeparator
+        public string TimeSeparator
         {
             get
             {
@@ -1284,11 +1291,21 @@ namespace System.Globalization
 
             set
             {
-                throw null;
+                if (IsReadOnly)
+                    throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+
+                if (value == null)
+                {
+                    throw new ArgumentNullException("value", SR.ArgumentNull_String);
+                }
+
+                Contract.EndContractBlock();
+                ClearTokenHashTable();
+
+                timeSeparator = value;
             }
         }
 
-
         public String UniversalSortableDateTimePattern
         {
             get
@@ -1381,7 +1398,6 @@ namespace System.Globalization
         }
 
         // Returns the string array of the one-letter day of week names.
-        [System.Runtime.InteropServices.ComVisible(false)]
         public String[] ShortestDayNames
         {
             get
@@ -1622,6 +1638,23 @@ namespace System.Globalization
             return (internalGetAbbreviatedDayOfWeekNames()[(int)dayofweek]);
         }
 
+        // Returns the super short day of week names for the specified day of week.
+        public string GetShortestDayName(DayOfWeek dayOfWeek)
+        {
+            if ((int)dayOfWeek < 0 || (int)dayOfWeek > 6)
+            {
+                throw new ArgumentOutOfRangeException(
+                    "dayOfWeek", SR.Format(SR.ArgumentOutOfRange_Range,
+                    DayOfWeek.Sunday, DayOfWeek.Saturday));
+            }
+            Contract.EndContractBlock();
+            //
+            // Don't call the public property SuperShortDayNames here since a clone is needed in that
+            // property, so it will be slower.  Instead, use internalGetSuperShortDayNames() directly.
+            //
+            return (internalGetSuperShortDayNames()[(int)dayOfWeek]);
+        }
+
         // Get all possible combination of inputs
         private static String[] GetCombinedPatterns(String[] patterns1, String[] patterns2, String connectString)
         {
@@ -1646,9 +1679,22 @@ namespace System.Globalization
             return (result);
         }
 
+        public string[] GetAllDateTimePatterns()
+        {
+            List<String> results = new List<String>(DEFAULT_ALL_DATETIMES_SIZE);
+
+            for (int i = 0; i < DateTimeFormat.allStandardFormats.Length; i++)
+            {
+                String[] strings = GetAllDateTimePatterns(DateTimeFormat.allStandardFormats[i]);
+                for (int j = 0; j < strings.Length; j++)
+                {
+                    results.Add(strings[j]);
+                }
+            }
+            return results.ToArray();
+        }
 
-        // auto-generated
-        internal String[] GetAllDateTimePatterns(char format)
+        public string[] GetAllDateTimePatterns(char format)
         {
             Contract.Ensures(Contract.Result<String[]>() != null);
             String[] result = null;
@@ -1973,7 +2019,99 @@ namespace System.Globalization
             }
         }
 
-        [System.Runtime.InteropServices.ComVisible(false)]
+        // Return the native name for the calendar in DTFI.Calendar.  The native name is referred to
+        // the culture used to create the DTFI.  E.g. in the following example, the native language is Japanese.
+        // DateTimeFormatInfo dtfi = new CultureInfo("ja-JP", false).DateTimeFormat.Calendar = new JapaneseCalendar();
+        // String nativeName = dtfi.NativeCalendarName; // Get the Japanese name for the Japanese calendar.
+        // DateTimeFormatInfo dtfi = new CultureInfo("ja-JP", false).DateTimeFormat.Calendar = new GregorianCalendar(GregorianCalendarTypes.Localized);
+        // String nativeName = dtfi.NativeCalendarName; // Get the Japanese name for the Gregorian calendar.
+        public string NativeCalendarName
+        {
+            get
+            {
+                return _cultureData.CalendarName(Calendar.ID);
+            }
+        }
+
+        //
+        // Used by custom cultures and others to set the list of available formats. Note that none of them are
+        // explicitly used unless someone calls GetAllDateTimePatterns and subsequently uses one of the items
+        // from the list.
+        //
+        // Most of the format characters that can be used in GetAllDateTimePatterns are
+        // not really needed since they are one of the following:
+        //
+        //  r/R/s/u     locale-independent constants -- cannot be changed!
+        //  m/M/y/Y     fields with a single string in them -- that can be set through props directly
+        //  f/F/g/G/U   derived fields based on combinations of various of the below formats
+        //
+        // NOTE: No special validation is done here beyond what is done when the actual respective fields
+        // are used (what would be the point of disallowing here what we allow in the appropriate property?)
+        //
+        // WARNING: If more validation is ever done in one place, it should be done in the other.
+        //
+        public void SetAllDateTimePatterns(String[] patterns, char format)
+        {
+            if (IsReadOnly)
+                throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+
+            if (patterns == null)
+            {
+                throw new ArgumentNullException("patterns", SR.ArgumentNull_Array);
+            }
+
+            if (patterns.Length == 0)
+            {
+                throw new ArgumentException(SR.Arg_ArrayZeroError, "patterns");
+            }
+
+            Contract.EndContractBlock();
+
+            for (int i=0; i<patterns.Length; i++)
+            {
+                if (patterns[i] == null)
+                {
+                    throw new ArgumentNullException("patterns[" + i + "]", SR.ArgumentNull_ArrayValue);
+                }
+            }
+
+            // Remember the patterns, and use the 1st as default
+            switch (format)
+            {
+                case 'd':
+                    allShortDatePatterns = patterns;
+                    shortDatePattern = allShortDatePatterns[0];
+                    break;
+
+                case 'D':
+                    allLongDatePatterns = patterns;
+                    longDatePattern = allLongDatePatterns[0];
+                    break;
+
+                case 't':
+                    allShortTimePatterns = patterns;
+                    shortTimePattern = allShortTimePatterns[0];
+                    break;
+
+                case 'T':
+                    allLongTimePatterns = patterns;
+                    longTimePattern = allLongTimePatterns[0];
+                    break;
+
+                case 'y':
+                case 'Y':
+                    allYearMonthPatterns = patterns;
+                    yearMonthPattern = allYearMonthPatterns[0];
+                    break;
+
+                default:
+                    throw new ArgumentException(SR.Format_BadFormatSpecifier, "format");
+            }
+
+            // Clear the token hash table, note that even short dates could require this
+            ClearTokenHashTable();
+        }
+
         public String[] AbbreviatedMonthGenitiveNames
         {
             get
@@ -2001,7 +2139,6 @@ namespace System.Globalization
             }
         }
 
-        [System.Runtime.InteropServices.ComVisible(false)]
         public String[] MonthGenitiveNames
         {
             get
index fc2c5ca..82afc23 100644 (file)
@@ -26,18 +26,6 @@ namespace System.Globalization
         WindowsOnlyCultures = 32,
     }
 
-    public sealed partial class DateTimeFormatInfo : System.ICloneable, System.IFormatProvider
-    {
-        // Can't do partial properties so add the setter for DateSeparator and TimeSeparator
-        [System.Runtime.InteropServices.ComVisibleAttribute(false)]
-        public string NativeCalendarName { get { throw new NotImplementedException(); } }
-        public string[] GetAllDateTimePatterns() { throw new NotImplementedException(); }
-        [System.Runtime.InteropServices.ComVisibleAttribute(false)]
-        public string GetShortestDayName(System.DayOfWeek dayOfWeek) { throw new NotImplementedException(); }
-        [System.Runtime.InteropServices.ComVisibleAttribute(false)]
-        public void SetAllDateTimePatterns(string[] patterns, char format) { throw new NotImplementedException(); }
-    }
-
     public sealed partial class IdnMapping
     {
         public IdnMapping() { }