Why GetAllDateTimePatterns method doesn't return unique formats?

.net, c#, datetime, datetime-format

Solution

The main reason is; because some of standard date and time format strings have multiple format specifiers. Such as;

- `"M", "m"`

- `"O", "o"`

- `"R", "r"`

- `"Y", "y"`

Let's look at how `GetAllDateTimePatterns` method implemented;

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();
}

This method calls `GetAllDateTimePatterns(char)` method with the all return values of `DateTimeFormat.allStandardFormats` array. And this array implemented as;

internal static char[] allStandardFormats = 
{
    'd', 'D', 'f', 'F', 'g', 'G', 
    'm', 'M', 'o', 'O', 'r', 'R', 
    's', 't', 'T', 'u', 'U', 'y', 'Y',
};

That's why this method and overloads will generate same formats for `m` and `M` and they added to `results` array which is the source of this method.

Besides on that reason, `("F") Format Specifier` and `("U") format specifier` are equivalent. These are also generates same formats which is handled in `GetAllDateTimePatterns(char)` method's impelementation;

public  String[] GetAllDateTimePatterns(char format)
{
    String [] result = null;

    switch (format)
    {
        case 'd':
            result = this.AllShortDatePatterns;
            break;
        case 'D':
            result = this.AllLongDatePatterns;
            break;
        case 'f':
            result = GetCombinedPatterns(AllLongDatePatterns, AllShortTimePatterns, " ");
            break;
        case 'F':
        case 'U':
            result = GetCombinedPatterns(AllLongDatePatterns, AllLongTimePatterns, " ");
            break;
        case 'g':
            result = GetCombinedPatterns(AllShortDatePatterns, AllShortTimePatterns, " ");
            break;
        case 'G':
            result = GetCombinedPatterns(AllShortDatePatterns, AllLongTimePatterns, " ");
            break;
        case 'm':
        case 'M':
            result = new String[] {MonthDayPattern};
            break;
        case 'o':
        case 'O':
            result = new String[] {DateTimeFormat.RoundtripFormat};
            break;
        case 'r':
        case 'R':
            result = new String[] {rfc1123Pattern};
            break;
        case 's':
            result = new String[] {sortableDateTimePattern};
            break;
        case 't':
            result = this.AllShortTimePatterns;
            break;
        case 'T':
            result = this.AllLongTimePatterns;
            break;
        case 'u':
            result = new String[] {UniversalSortableDateTimePattern};
            break;
        case 'y':
        case 'Y':
            result = this.AllYearMonthPatterns;
            break;
        default:
            throw new ArgumentException(Environment.GetResourceString("Format_BadFormatSpecifier"), "format");
    }
    return (result);
}

Problem

I'm really surprised with `DateTimeFormatInfo.GetAllDateTimePatterns` method does not return unique standard formats. Let me give you an example with `InvariantCulture`; ``` var pattern = CultureInfo.InvariantCulture.DateTimeFormat GetAllDateTimePatterns(); foreach (var format in pattern) { Console.WriteLine(format); } ``` In .NET Framework 4.5, this code will print `34` standard pattern. When I used `Enumerable.Distinct` method with this method; ``` var pattern = CultureInfo.InvariantCulture.DateTimeFormat. GetAllDateTimePatterns(). Distinct(); foreach (var format in pattern) { Console.WriteLine(format); } ``` This code will print `29` standard patterns under the same conditions. You can even see these duplicate patterns when you debug it; Why this method returns same patterns multiple times?

Original source