Adam Tegen
Adam Tegen

Reputation: 25887

How to get a Long Date format from DateTime without a weekday

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:

ToLongDateString() returns the following:

Upvotes: 32

Views: 28558

Answers (17)

Jono
Jono

Reputation: 4076

This is an improved answer from @VDWWD, which does not work correctly with some locales;

  • Hungarian hu-HU has a trailing comma instead of starting.

  • Arabic langauges ar-* use a different character for commas ،

  • Danish da-DK uses the 'den' suffix when including a named weekday (eg Tirsdag den for Tuesday), which isn't included in the day name.

  • Mongolian mn-MN similarily uses 'гараг' (eg Мягмар гараг for Tuesday) which from what I read isnt actually a suffix, it's more like day in Tuesday, but c# dates dont add it as part of the day name anyway.

      var date = DateTime.Now;
      string formattedDate = date.ToLongDateString()
          .Replace(DateTimeFormatInfo.CurrentInfo.GetDayName(date.DayOfWeek) + " den", "")
          .Replace(DateTimeFormatInfo.CurrentInfo.GetDayName(date.DayOfWeek) + " гараг", "")
          .Replace(DateTimeFormatInfo.CurrentInfo.GetDayName(date.DayOfWeek), "")
          .TrimStart('،', ',', ' ')
          .TrimEnd('،', ',', ' ');
    

Here's a c# fiddle that shows it working on a full list of culture codes

Upvotes: 0

Emperor Eto
Emperor Eto

Reputation: 3520

Kinda hilarious how many answers this question has (and that it's still an issue). Might as well join the party with my solution:

    CultureInfo culture = CultureInfo.CurrentCulture; // or replace with the culture of your choosing

    string pattern = culture.DateTimeFormat.LongDatePattern
        .Replace("dddd, ", "")
        .Replace(",dddd", "");

    return dt.ToString(pattern, culture);

Then you've got both cases covered whether the day of the week precedes or follows the rest.

Upvotes: 2

Marcio J
Marcio J

Reputation: 780

You can concatenate the standard month/day pattern (m) with custom year (yyyy):

string formattedDate = date.ToString("M") + ", " + date.ToString("yyyy");

Examples:

June 15, 2020 (en-US)
15. juni, 2020 (da-DK)
15 Juni, 2020 (id-ID)

Upvotes: -1

VDWWD
VDWWD

Reputation: 35514

This is an improved answer from Reza, which does not work correctly with some localizations.

string formattedDate = DateTime.Now.ToLongDateString()
   .Replace(DateTimeFormatInfo.CurrentInfo.GetDayName(DateTime.Now.DayOfWeek), "")
   .TrimStart(", ".ToCharArray());

Upvotes: 5

franzo
franzo

Reputation: 1469

Improving on the accepted answer, GetAllDateTimePatterns can take a parameter to restrict the result to patterns relating to a standard format string, such as 'D' for the long date pattern.

For example, GetAllDateTimePatterns('D') is currently returning this for en-US:

"dddd, MMMM d, yyyy", "MMMM d, yyyy", "dddd, d MMMM, yyyy", "d MMMM, yyyy" 

and this for zh-HK:

"yyyy'年'M'月'd'日'", "yyyy'年'MM'月'dd'日'", "yyyy年MMMd日", "yyyy年MMMd日, dddd"

Assuming they're listed in some order of preference or prevalence, we can select the first option that does not contain the day of the week.

Here are extension methods so you can simply use myDateTime.ToLongDateStringWithoutDayOfWeek() and myDateTime.ToLongDateTimeStringWithoutDayOfWeek().

public static string ToLongDateStringWithoutDayOfWeek(this DateTime d)
{
    return d.ToString(
               CultureInfo.CurrentCulture.DateTimeFormat.GetAllDateTimePatterns('D')
                   .FirstOrDefault(a => !a.Contains("ddd") && !a.Contains("dddd")) 
               ?? "D");
}

public static string ToLongDateTimeStringWithoutDayOfWeek(this DateTime d, bool includeSeconds = false)
{
    char format = includeSeconds ? 'F' : 'f';
    return d.ToString(
               CultureInfo.CurrentCulture.DateTimeFormat.GetAllDateTimePatterns(format)
                   .FirstOrDefault(a => !a.Contains("ddd") && !a.Contains("dddd")) 
               ?? format.ToString()); 
}

Upvotes: 6

user9435394
user9435394

Reputation:

My solution:

DateTime date = DateTime.Now;
CultureInfo culture = CultureInfo.CurrentCulture;
string dayName = date.ToString("dddd", culture);
string fullDate = date.ToString("f", culture);
string trim = string.Join(" ", fullDate.Replace(dayName, "").TrimStart(',').TrimStart(' ').Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)); 

The last line:

  1. Removes leftover comma at start
  2. Removes leftover space at start
  3. Removes leftover double-space from anywhere in the string

Tested for each culture from

CultureInfo[] cultures = CultureInfo.GetCultures(CultureTypes.AllCultures);

Upvotes: 0

Frank Smith
Frank Smith

Reputation: 21

I have expanded on the suggestion by Bart Calixto to fix the dd MMM yyyy format issue (here in Australia we also use UK date format dd/mm/yy)

I also frequently need to convert between Aust and US date formats.

This code fixes the problem (my version is in VB)

Public Shared Function ToLongDateWithoutWeekDayString(source As DateTime, cult As System.Globalization.CultureInfo) As String

Return source.ToString("D", cult).Replace(source.DayOfWeek.ToString(), "").Trim(","c, " "c)

End Function

Before calling the function you need to set culture, I do it this way after getting the visitor's country from http://ipinfo.io

Select Case Country.country
            Case "AU"
                cult = New CultureInfo("en-AU")
            Case "US"
                cult = New CultureInfo("en-US")
            Case "GB"
                cult = New CultureInfo("en-GB")
        End Select

Dim date1 As New Date(2010, 8, 18)
lblDate.Text = ToLongDateWithoutWeekDayString(date1, cult)

After setting AU or GB culture result is 18 August 2010

After setting US culture result is August 18, 2010

Adam do you agree this solves the formatting issue you refer to?

Thanks Bart that was very nice code.

Dont forget to add Dim cult As System.Globalization.CultureInfo after Inherits System.Web.UI.Page

Upvotes: 1

Bart Calixto
Bart Calixto

Reputation: 19705

Old post, but I'm using this:

public static string ToLongDateWithoutWeekDayString(this DateTime source)
{
    return source.ToLongDateString()
                 .Replace(source.DayOfWeek.ToString(), "")
                 .Trim(',', ' ');
}

Upvotes: 0

itsclarke
itsclarke

Reputation: 8982

Why not get the LongDate and trim off the first portion where the weekday appears?

DateTime date = Convert.ToDateTime(content["DisplayDate"]); 
  //-->3/15/2016 2:09:13 PM

string newDate = date.ToString("D", new CultureInfo("es-ES")); 
  //--> martes, 15 de marzo de 2016

var index = newDate.IndexOf(",") + 1;
  //--> 7

string finalDate = newDate.Substring(index);
  //--> 15 de marzo de 2016

Upvotes: 0

Curt
Curt

Reputation: 5722

This is an old, old thead, but I came across it because it perfectly matched the use case I needed to solve. I ended up writing a piece of code that works, so I thought I'd include it for those that need it. (It has a few extra tricks, like defaulting to the current date, and allowing either the full date string for a culture, or one with the day-of-the-week removed):

 public string DateString(DateTime? pDt = null, string lang, bool includeDayOfWeek = true)
 {
    if (pDt == null) pDt = DateTime.Now;
    DateTime dt = (DateTime)pDt;

    System.Globalization.CultureInfo culture = null; 
    try {   culture = new System.Globalization.CultureInfo(lang); } 
       catch{ culture = System.Globalization.CultureInfo.InvariantCulture; }

    string ss = dt.ToString("D", culture);
    if (!includeDayOfWeek)
    {
       //  Find day-of-week string, and remove it from the date string
       //  (including any trailing spaces or punctuation)
       string dow = dt.ToString("dddd", culture);
       int len = dow.Length;
       int pos = ss.IndexOf(dow);
       if (pos >= 0)
       {
          while ( ((len + pos) < ss.Length)  &&  ( !Char.IsLetterOrDigit(ss[len+pos])))
             len++;
          ss = ss.Substring(0, pos) + ss.Substring(len+pos, ss.Length - (len+pos));
       }
    }
   return ss;
 }

Upvotes: 3

Mindless
Mindless

Reputation: 2357

Just specify the format:

DateTime.ToString("MMMM dd, yyyy");

Upvotes: -1

Rafael Herscovici
Rafael Herscovici

Reputation: 17094

What wrong with:

var ci = CultureInfo.CreateSpecificCulture("nl-NL");
var date1 = DateTime.ParseExact(date, "dd MMM yyyy", ci);

Upvotes: -1

Moslem Hadi
Moslem Hadi

Reputation: 1020

String formattedDate = DateTime.Now.Date.ToLongDateString().Replace(DateTime.Now.DayOfWeek.ToString()+ ", ", "")

Upvotes: 13

Adam Tegen
Adam Tegen

Reputation: 25887

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.

Upvotes: 11

user7116
user7116

Reputation: 64068

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();
}

Upvotes: 4

David Rutten
David Rutten

Reputation: 4806

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.

Upvotes: 2

waqasahmed
waqasahmed

Reputation: 3825

Try:

DateTime time = ....
string formmattedDate = time.Day.ToString() + " " + time.ToString("MMMM");

Upvotes: 0

Related Questions