Omar
Omar

Reputation: 40182

What's the correct way to construct a custom date/time string format that can be localized in .NET?

I need a date string with one digit for the month, one digit for the day and two digits for the year (which is M/d/yy in the US, d/M/yy in most other places). I also need it to work across locales so it should automatically deal with the order of month/day and the separator. The closest to this is the d format which returns MM/dd/yyyy when called via date.ToString("d").

This needs to work across locales, so I tried this is what I came up with:

string format = culture.DateTimeFormat.ShortDatePattern
                                   .Replace("yyyy", "yy")
                                   .Replace("dd", "d")
                                   .Replace("MM", "M");

return date.ToString(format);

Using culture.DateTimeFormat.ShortDatePattern gives me the date format used for the d date format. Using this property will take care of the ordering of day/month/year and the date separator.

Is there a better way to do this?

Upvotes: 0

Views: 195

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1500835

If you definitely want exactly the format M/d/yy then just use that:

return date.ToString("M/d/yy", culture);

However, that isn't necessarily an appropriate string for the culture. For example, it would be rather alien to anyone in the UK, which would expect more of a d/M/yy format - day before month.

Note that the MM/dd/yyyy format may be what you get when you use date.ToString("d") but that's definitely not what you'd get in the UK.

Basically, you need to decide whether you want to nail down the format, in which case you're blowing localization - or whether you want to use the "normal" culture-specific short date string format, in which case date.ToString("d", culture) would make sense.

It sounds like you may be trying to go half way - "the short date format, but definitely don't use 4-digit years" etc. While that could work (make sure you pass culture into the ToString method as well) there's no guarantee that the culture's short date pattern will be using dd etc to start with. It could go horribly wrong, for example if the normal short date format is ddd dd MMM yyyy you'd end up with dd d MM yy, so something like "09 9 06 12" for June 9th 2012.

Basically, unless you've actually got a mapping from culture to "even shorter date format" I wouldn't suggest fudging it like this.

EDIT: Here's a short program whose output you should check. Basically it prints the original format and the modified one.

using System;
using System.Globalization;

class Program
{
    public static void Main()
    {
        foreach (var culture in 
                        CultureInfo.GetCultures(CultureTypes.SpecificCultures))
        {
            string original = culture.DateTimeFormat.ShortDatePattern;
            string modified = original.Replace("yyyy", "yy")
                                      .Replace("dd", "d")
                                      .Replace("MM", "M");
            Console.WriteLine("{0,11}: {1,12} => {2,-9}",
                              culture, original, modified);
        }
    }
}

On my machine, scanning down the list quickly, I think you'd actually be okay. Nothing seems to use ddd or MMM in the original format. But there's no guarantee that that will continue to be the case...

Upvotes: 1

Related Questions