Implement DateTime::ToString format specifier for genitive month names. Fixes #4708
authorMarek Safar <marek.safar@gmail.com>
Tue, 15 May 2012 17:34:21 +0000 (18:34 +0100)
committerMarek Safar <marek.safar@gmail.com>
Tue, 15 May 2012 17:34:21 +0000 (18:34 +0100)
mcs/class/corlib/System.Globalization/DateTimeFormatInfo.cs
mcs/class/corlib/System/DateTimeUtils.cs
mcs/class/corlib/Test/System/DateTimeTest.cs

index fac0b8511b98d0fc8905acb0672c43e9b0a30f52..09c21f1fc4e690a846740839dfd1c0e3fe41a82f 100644 (file)
@@ -237,6 +237,11 @@ namespace System.Globalization
                        if (month < 1 || month > 13) throw new ArgumentOutOfRangeException();
                        return monthNames[month-1];
                }
+               
+               internal string GetMonthGenitiveName (int month)
+               {
+                       return genitiveMonthNames [month - 1];
+               }
 
                public string[] AbbreviatedDayNames
                {
@@ -274,17 +279,9 @@ namespace System.Globalization
                        }
                }
 
-               public string[] DayNames
-               {
-                       get { return (string[]) RawDayNames.Clone (); }
-                       set { RawDayNames = value; }
-               }
-
-               internal string[] RawDayNames
-               {
-                       get
-                       {
-                               return dayNames;
+               public string[] DayNames {
+                       get {
+                               return (string[]) dayNames.Clone ();
                        }
                        set {
                                CheckDaysValue (value);
@@ -292,23 +289,27 @@ namespace System.Globalization
                        }
                }
 
-               public string[] MonthNames
-               {
-                       get { return (string[]) RawMonthNames.Clone (); }
-                       set { RawMonthNames = value; }
+               internal string[] RawDayNames  {
+                       get {
+                               return dayNames;
+                       }
                }
 
-               internal string[] RawMonthNames
-               {
-                       get
-                       {
-                               return monthNames;
+               public string[] MonthNames {
+                       get {
+                               return (string[]) monthNames.Clone ();
                        }
                        set {
                                CheckMonthsValue (value);
                                monthNames = (string[]) value.Clone();
                        }
                }
+
+               internal string[] RawMonthNames {
+                       get {
+                               return monthNames;
+                       }
+               }
                
                [ComVisible (false)]
                public string[] AbbreviatedMonthGenitiveNames {
@@ -331,8 +332,8 @@ namespace System.Globalization
                                genitiveMonthNames = value;
                        }
                }
-
-               [MonoLimitation ("Oly default calendar is supported")]
+               
+               [MonoLimitation ("Only default calendar is supported")]
                [ComVisible (false)]
                public string NativeCalendarName {
                        get {
index d46f0a1f8beb0d6f2824939999401309c8d7d981..febaf23e4afaafa3d1bd89dcbd5f31e26f054208 100644 (file)
@@ -190,6 +190,7 @@ namespace System {
                                dfi = inv;
 
                        int i = 0;
+                       bool saw_day_specifier = false;
 
                        while (i < format.Length) {
                                int tokLen;
@@ -320,6 +321,7 @@ namespace System {
                                        else
                                                result.Append (dfi.GetDayName (dfi.Calendar.GetDayOfWeek (dt)));
 
+                                       saw_day_specifier = true;
                                        break;
                                case 'M':
                                        // Month.m(m?) = month # (with leading 0 if two mm)
@@ -331,8 +333,11 @@ namespace System {
                                                DateTimeUtils.ZeroPad (result, month, tokLen);
                                        else if (tokLen == 3)
                                                result.Append (dfi.GetAbbreviatedMonthName (month));
-                                       else
-                                               result.Append (dfi.GetMonthName (month));
+                                       else {
+                                               // NOTE: .NET ignores quoted 'd' and reads it as day specifier but I think 
+                                               // that's wrong
+                                               result.Append (saw_day_specifier ? dfi.GetMonthGenitiveName (month) : dfi.GetMonthName (month));
+                                       }
 
                                        break;
                                case 'y':
index 1b94c126507c3f88c69029d78c1138b091dcec6b..99577c0b7954b03b01c8cea6450889c28db17bb3 100644 (file)
@@ -355,6 +355,18 @@ namespace MonoTests.System
                        Assert.AreEqual ("0999", t3.ToString ("yyyy"), "#B33");
                }
 
+               [Test]
+               public void TestToStringGenitive ()
+               {
+                       DateTime dt = new DateTime (2010, 1, 2, 3, 4, 5);
+                       var dtf = new CultureInfo ("cs-cz").DateTimeFormat;
+
+                       Assert.AreEqual ("2 ledna", dt.ToString ("d MMMM", dtf), "#A1");
+                       Assert.AreEqual ("2. ledna", dt.ToString ("d. MMMM", dtf), "#A2");
+                       Assert.AreEqual ("leden", dt.ToString ("MMMM", dtf), "#A4");
+                       Assert.AreEqual ("leden", dt.ToString ("MMMMMMM", dtf), "#A5");
+               }
+
                [Test]
                public void ParseExact_Format_Empty ()
                {