views:

845

answers:

5

I'm looking for a locale-aware way of acquiring a long date time without the weekday. Just such a beast exist?

Below is the code I use to get the long date format including the weekday:

DateTime time = ...
String formattedDate = time.ToLongDateString();

Edit

Examples of what I would like to see:

  • en-us: December 5, 2009
  • fr-fr: 5 décembre 2009
  • es-es: 05 de diciembre de 2009

ToLongDateString() returns the following:

  • en-us: Saturday, December 5, 2009
  • fr-fr: samedi 5 décembre 2009
  • es-es: sábado, 05 de diciembre de 2009
A: 

Try:

DateTime time = ....
string formmattedDate = time.Day.ToString() + " " + time.ToString("MMMM");
waqasahmed
+1  A: 

If the LongDate sequence is also culture specific, then I'm afraid you're out of luck and you'll have to write actual code for this. Otherwise, a collection of formatting tags will do the trick.

I'm afraid what you'll have to do is create an array of 7 strings (one for each day) in the local culture, and remove those strings from your LongDate format output. Then make sure you remove all duplicated /'s -'s and spaces.

Hope there's a better way but I don't see it.

David Rutten
Asking for the wrong result (a string with the day of the week) and trying to munge it to an acceptable form (by deleting the day of the week) is a very poor substitute for simply asking for a date string formatted appropriately in the first place.
Stephen C. Steel
@ Stephen: I agree. But how do you know the proper formatting for the current culture? The order of Year, month and day, the separator chars etc. etc.
David Rutten
@David - exactly right, you can't. If it matters, you'd have to go research the appropriate formatting for each culture, as Microsoft has done with cultureInfo.DateTimeFormat.LongDatePattern.
Michael Petrotta
+5  A: 

It sounds like you're looking for a locale-specific way of producing what in the en-US locale would produce "September 08, 2009". That is, a long month string, zero-padded date, and four-digit year. This is what ToLongDateString() produces, minus the weekday.

You can use:

DateTime date = DateTime.Now;
string formattedDate = date.ToString("MMMM dd, yyyy");
Console.WriteLine(formattedDate);

As described in the MSDN article discussing custom date/time format strings (and see the Notes section at the bottom), the result produced will be localized according to the Regional and Language Options control panel settings.

The format strings discussed in that MSDN article give you a lot of power and control, though I do find myself having to refer back to it every time I need to create a custom format string.

EDIT: reading the OP's edit, I see my solution doesn't meet his needs. Some of the 'trim' methods in other answers come closer.

The main problem: Microsoft has researched the appropriate long date format string for each locale. You're asking for some way of producing a different date format customized for each locale, programmaticaly. Trimming the 'dddd' from the CultureInfo's LongDatePattern will get you close, maybe close enough, but for all you know, Norway has a completely different way of representing a date when it doesn't include a day-of-week. See Adam's comment to sixlettervariables' answer for a locale (Georgian) that will throw you off.

Michael Petrotta
A: 

A very awful, horrible way to accomplish this is to remove the format specifiers you don't want from the existing LongDatePattern:

public static string CorrectedLongDatePattern(CultureInfo cultureInfo)
{
    var info = cultureInfo.DateTimeFormat;

    // This is bad, mmmkay?
    return Regex.Replace(info.LongDatePattern, "dddd,?",String.Empty).Trim();
}
sixlettervariables
This is nice and simple, but doesn't handle *all* cases. For instance ka-GE is "yyyy 'წლის' dd MM, dddd". This answer would leave the trailing comma
Adam Tegen
Agreed, it is a "very awful, horrible" solution :D You could add that to the regex: /,?\s*dddd,?/
sixlettervariables
I think adding that to the regex would help, yes.
Adam Tegen
+2  A: 

This seemed to do the trick.

  1. Enumerate all valid datetime patterns: CultureInfo.DateTimeFormat.GetAllDateTimePatterns
  2. Select longest pattern (presumably this is the best match) that:
    • Is a substring of the CultureInfo.DateTimeFormat.LongDatePattern
    • Does not contain "ddd" (short day name)
    • Does not contain "dddd" (long day name)

This appears to come up with the strings I was looking for.

See code below:

class DateTest
{
    static private string GetDatePatternWithoutWeekday(CultureInfo cultureInfo)
    {
        string[] patterns = cultureInfo e.DateTimeFormat.GetAllDateTimePatterns();

        string longPattern = cultureInfo.DateTimeFormat.LongDatePattern;

        string acceptablePattern = String.Empty;

        foreach (string pattern in patterns)
        {
            if (longPattern.Contains(pattern) && !pattern.Contains("ddd") && !pattern.Contains("dddd"))
            {
                if (pattern.Length > acceptablePattern.Length)
                {
                    acceptablePattern = pattern;
                }
            }
        }

        if (String.IsNullOrEmpty(acceptablePattern))
        {
            return longPattern;
        }
        return acceptablePattern;
    }

    static private void Test(string locale)
    {
        DateTime dateTime = new DateTime(2009, 12, 5);

        Thread.CurrentThread.CurrentCulture  = new CultureInfo(locale);

        string format = GetDatePatternWithoutWeekday(Thread.CurrentThread.CurrentCulture);

        string result = dateTime.ToString(format);

        MessageBox.Show(result);            
    }
}

Technically, it probably wouldn't work if a long format had the name of the day sandwiched in the middle. For that, I should choose the pattern with longest common substring instead of longest exact match.

Adam Tegen