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?