Skip to content

System.Globalization: Abbreviated genitive month names won't work on custom DateTimeFormat strings #15035

@javiercampos

Description

@javiercampos

As found out by @jskeet , abbreviated genitive month names don't seem to work when using the "MMM" token on custom datetime format strings

The test, written by @jskeet (I'm just copying here from nodatime/nodatime#377):

using System;
using System.Globalization;
using System.Linq;

class Test
{
    static void Main()
    {
        var culture = (CultureInfo) CultureInfo.InvariantCulture.Clone();

        culture.DateTimeFormat.AbbreviatedMonthGenitiveNames
            = culture.DateTimeFormat.AbbreviatedMonthNames
                     .Select(x => "Gen" + x)
                     .ToArray();
        culture.DateTimeFormat.MonthGenitiveNames
            = culture.DateTimeFormat.MonthNames
                     .Select(x => "Gen" + x)
                     .ToArray();

        Console.WriteLine(new DateTime(1976, 6, 19).ToString("d MMMM yy", culture));
        Console.WriteLine(new DateTime(1976, 6, 19).ToString("MMMM yy", culture));
        Console.WriteLine(new DateTime(1976, 6, 19).ToString("d MMM yy", culture));
        Console.WriteLine(new DateTime(1976, 6, 19).ToString("MMM yy", culture));
    }
}

Should output:

19 GenJune 76
June 76
19 GenJun 76
Jun 76

But outputs:

19 GenJune 76
June 76
19 Jun 76
Jun 76

Disregarding the abbreviated genitives (and resorting to regular ones when abbreviated).

I haven't found the DateTimeFormat files on GitHub yet (just the tests, which don't cover this), so I can't issue a request or test it, but on the reference source: http://referencesource.microsoft.com/#mscorlib/system/globalization/datetimeformat.cs,578

We got this:

if ((dtfi.FormatFlags & DateTimeFormatFlags.UseGenitiveMonth) != 0 
              && tokenLen >= 4) {
        result.Append(
             dtfi.internalGetMonthName(
                    month, 
                    IsUseGenitiveForm(format, i, tokenLen, 'd')? MonthNameStyles.Genitive : MonthNameStyles.Regular, 
                    false));

Which doesn't take MMM into account (because of the tokenLen >= 4 conditional). If I'm not mistaken, it should look like this:

if ((dtfi.FormatFlags & DateTimeFormatFlags.UseGenitiveMonth) != 0 
              && tokenLen >= 3 /* Work for MMM and MMMM */ ) {
        result.Append(
             dtfi.internalGetMonthName(
                    month, 
                    IsUseGenitiveForm(format, i, tokenLen, 'd')? MonthNameStyles.Genitive : MonthNameStyles.Regular, 
                    tokenLen == 3 /* Abbreviated if MMM */));

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions