运行 .Net 8 控制台应用程序时,为什么
MMM
当它是日期格式的一部分时(例如 .ToString("dd-MMM-yy")
)显示“June”而不是“Jun”,而当它是日期格式时显示“Jun”(例如 .ToString("MMM")
)本身?
// Set culture to English (Australia)
var culture = new CultureInfo("en-AU");
// Get the current date
var currentDate = new DateTime(2024, 6, 8);
// Display the current date using the short date pattern
var formattedDate = currentDate.ToString("d", culture);
Console.WriteLine("Short date in en-AU culture: " + formattedDate); // Outputs: 8/06/2024
// Display the abbreviated month name separately
var abbreviatedMonth = currentDate.ToString("MMM", culture);
Console.WriteLine("Abbreviated month: " + abbreviatedMonth); // Outputs: Jun
var incorrect = currentDate.ToString("dd-MMM-yy", culture);
Console.WriteLine("Incorrect format: " + incorrect); // Outputs: 08-June-24
Windows 可以,但 C# 不行。请注意屏幕截图右下角的月份(我将 Windows 时间更改为六月)。
DateTimeFormatInfo
中月份有两种缩写,一种叫AbbreviatedMonthNames
,另一种叫AbbreviatedMonthGenitiveNames
。六月在 AbbreviatedMonthNames
中的缩写是 Jun
,在 AbbreviatedMonthGenitiveNames
中是 June
。
文档中属格月份名称的解释如下:
在某些语言中,作为日期一部分的月份名称出现在所有格中。例如,ru-RU 或俄语(俄罗斯)文化中的日期由日数和属格月份名称组成,例如 1 Января(1 月 1 日)。
选择缩写的关键代码在这里:IsUseGenitiveForm,其注释为:
操作:检查格式,看看我们是否应该在格式中使用属格月份。从(format)字符串中的位置(index)开始,向后看并向前看是否有“d”或“dd”。在像“d MMMM”或“MMMM dd”这样的情况下,我们可以使用属格形式。如果有两个以上的“d”,则不使用属格形式。
因此,如果格式中有
d
或dd
,则会选择June
。
正如 shingo 已经指出的那样,该行为似乎起源于使用属性
DateTimeFormatInfo.AbbreviatedMonthNames
和 DateTimeFormatInfo.AbbreviatedMonthGenitiveNames
的逻辑。
但是,目前还没有提供解决问题的方案。
这两个属性具有公共设置器。操作这些数组以使它们具有预期的内容可能非常容易。
// Set culture to English (Australia)
var culture = new CultureInfo("en-AU");
// Workaround for unexpected month abbreviations:
culture.DateTimeFormat.AbbreviatedMonthGenitiveNames =
new string[] { "Jan", "Feb", "Mar",
"Apr", "May", "Jun",
"Jul", "Aug", "Sep",
"Oct", "Nov", "Dec",
"" };
// Get the current date
var currentDate = new DateTime(2024, 6, 8);
// Display the current date using the short date pattern
var formattedDate = currentDate.ToString("d", culture);
Console.WriteLine("Short date in en-AU culture: " + formattedDate); // Outputs: 8/06/2024
// Display the abbreviated month name separately
var abbreviatedMonth = currentDate.ToString("MMM", culture);
Console.WriteLine("Abbreviated month: " + abbreviatedMonth); // Outputs: Jun
var fixedIncorrect = currentDate.ToString("dd-MMM-yy", culture);
Console.WriteLine("Fixed incorrect format: " + fixedIncorrect); // Outputs: 08-Jun-24 :-)
我不清楚为什么 .NET 的某些版本会为这些月份缩写公开不同的值。