dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.36k stars 4.75k forks source link

ToString() MMM_Specifier Broken #75950

Closed vsfeedback closed 2 years ago

vsfeedback commented 2 years ago

_This issue has been moved from a ticket on Developer Community._


[severity:It's more difficult to complete my work] .ToString() Date formatting is broken when using the "MMM" to return the 3 digit month.

Month return is appended with a Period

To reproduce create a new .NET 6 Console Application with this line:

Console.WriteLine(new DateTime(2009, 1, 1).ToString("dd-MMM-yyyy"));

Expected Output: 01-Jan-2009

Actual Output: 01-Jan.-2009

Reference: https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings#MMM_Specifier

Broken in Visual Studio Version 17.3.3 Framework: .NET Core 6


Original Comments

Feedback Bot on 9/12/2022, 10:04 PM:

(private comment, text removed)


Original Solutions

(no solutions)

dotnet-issue-labeler[bot] commented 2 years ago

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

ghost commented 2 years ago

Tagging subscribers to this area: @dotnet/area-system-runtime See info in area-owners.md if you want to be subscribed.

Issue Details
_This issue has been moved from [a ticket on Developer Community](https://developercommunity.visualstudio.com/t/ToString-MMM_Specifier-Broken/10144458)._ --- [severity:It's more difficult to complete my work] .ToString() Date formatting is broken when using the "MMM" to return the 3 digit month. Month return is appended with a Period To reproduce create a new .NET 6 Console Application with this line: Console.WriteLine(new DateTime(2009, 1, 1).ToString("dd-MMM-yyyy")); Expected Output: 01-Jan-2009 Actual Output: 01-Jan.-2009 Reference: https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings#MMM_Specifier Broken in Visual Studio Version 17.3.3 Framework: .NET Core 6 --- ### Original Comments #### Feedback Bot on 9/12/2022, 10:04 PM: (private comment, text removed) --- ### Original Solutions (no solutions)
Author: vsfeedback
Assignees: -
Labels: `area-System.Runtime`, `untriaged`
Milestone: -
jozkee commented 2 years ago

hmm, I don't see the reported behavior but it might be related to the culture? https://sharplab.io/#v2:C4LgTgrgdgNAJiA1AHwAICYAMBYAUBgRjz1QIE4AKAIkB4NwEH2qBKAbhPIqgFMB3AAgBEAhsE4AVAJYBbThSyYyMXgUUFGAOlEB7AMrAw4qAHNqcOAFoAslbMBPOzaYsgA=

stephentoub commented 2 years ago

Note that the cited docs say:

"The "MMM" custom format specifier represents the abbreviated name of the month. The localized abbreviated name of the month is retrieved from the DateTimeFormatInfo.AbbreviatedMonthNames property of the current or specified culture."

So the string is just being pulled from your current culture. And lots of cultures have a period as part of the abbreviated month name, e.g. on my machine this:

using System.Globalization;

foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures))
    if (ci.DateTimeFormat.AbbreviatedMonthNames[0].Contains('.'))
        Console.WriteLine($"{ci}: {ci.DateTimeFormat.AbbreviatedMonthNames[0]}");

outputs this:

af: Jan.
af-NA: Jan.
af-ZA: Jan.
br: Gen.
br-FR: Gen.
ca: gen.
ca-AD: gen.
ca-ES: gen.
ca-FR: gen.
ca-IT: gen.
da: jan.
da-DK: jan.
da-GL: jan.
doi: जन.
doi-IN: जन.
en-CA: Jan.
es-419: ene.
es-AR: ene.
es-BO: ene.
es-BR: ene.
es-BZ: ene.
es-CL: ene.
es-CO: ene.
es-CR: ene.
es-CU: ene.
es-DO: ene.
es-EC: ene.
es-GT: ene.
es-HN: ene.
es-MX: ene.
es-NI: ene.
es-PA: ene.
es-PE: Ene.
es-PR: ene.
es-PY: ene.
es-SV: ene.
es-US: ene.
es-UY: Ene.
es-VE: ene.
eu: urt.
eu-ES: urt.
fr: janv.
fr-029: janv.
fr-BE: janv.
fr-BF: janv.
fr-BI: janv.
fr-BJ: janv.
fr-BL: janv.
fr-CA: janv.
fr-CD: janv.
fr-CF: janv.
fr-CG: janv.
fr-CH: janv.
fr-CI: janv.
fr-CM: janv.
fr-DJ: janv.
fr-DZ: janv.
fr-FR: janv.
fr-GA: janv.
fr-GF: janv.
fr-GN: janv.
fr-GP: janv.
fr-GQ: janv.
fr-HT: janv.
fr-KM: janv.
fr-LU: janv.
fr-MA: jan.
fr-MC: janv.
fr-MF: janv.
fr-MG: janv.
fr-ML: janv.
fr-MQ: janv.
fr-MR: janv.
fr-MU: janv.
fr-NC: janv.
fr-NE: janv.
fr-PF: janv.
fr-PM: janv.
fr-RE: janv.
fr-RW: janv.
fr-SC: janv.
fr-SN: janv.
fr-SY: janv.
fr-TD: janv.
fr-TG: janv.
fr-TN: janv.
fr-VU: janv.
fr-WF: janv.
fr-YT: janv.
gl: Xan.
gl-ES: Xan.
haw: Ian.
haw-US: Ian.
hu: jan.
hu-HU: jan.
is: jan.
is-IS: jan.
kk: қаң.
kk-KZ: қаң.
ksh: Jan.
ksh-DE: Jan.
lo: ມ.ກ.
lo-LA: ມ.ກ.
lt: saus.
lt-LT: saus.
lv: janv.
lv-LV: janv.
mk: јан.
mk-MK: јан.
nl: jan.
nl-AW: jan.
nl-BE: jan.
nl-BQ: jan.
nl-CW: jan.
nl-NL: jan.
nl-SR: jan.
nl-SX: jan.
os: Янв.
os-GE: Янв.
os-RU: Янв.
pt: jan.
pt-AO: jan.
pt-BR: jan.
pt-CH: jan.
pt-CV: jan.
pt-GQ: jan.
pt-GW: jan.
pt-LU: jan.
pt-MO: jan.
pt-MZ: jan.
pt-PT: jan.
pt-ST: jan.
pt-TL: jan.
rm: schan.
rm-CH: schan.
rn: Mut.
rn-BI: Mut.
ro: ian.
ro-MD: ian.
ro-RO: ian.
ru: янв.
ru-BY: янв.
ru-KG: янв.
ru-KZ: янв.
ru-MD: янв.
ru-RU: янв.
ru-UA: янв.
rw: mut.
rw-RW: mut.
sl: jan.
sl-SI: jan.
sv: jan.
sv-AX: jan.
sv-FI: jan.
sv-SE: jan.
ta: ஜன.
ta-IN: ஜன.
ta-LK: ஜன.
ta-MY: ஜன.
ta-SG: ஜன.
th: ม.ค.
th-TH: ม.ค.
tt: гыйн.
tt-RU: гыйн.
yav: o.1
yav-CM: o.1
tannergooding commented 2 years ago

This sounds "by-design" given the above.

tarekgh commented 2 years ago

Thanks @stephentoub.

For competence, we get this data from Unicode standard through ICU library. Here is example of such data from CLDR https://github.com/unicode-org/cldr/blob/3c8b810a0a16f843ee590727a0022fd80d0db2a7/common/main/da.xml#L1705.