Getting day suffix when using DateTime.ToString()

C#.NetDate

C# Problem Overview


Is it possible to include the day suffix when formatting a date using DateTime.ToString()?

For example I would like to print the date in the following format - Monday 27th July 2009. However the closest example I can find using DateTime.ToString() is Monday 27 July 2009.

Can I do this with DateTime.ToString() or am I going to have to fall back to my own code?

C# Solutions


Solution 1 - C#

Another option using switch:

string GetDaySuffix(int day)
{
	switch (day)
	{
		case 1:
		case 21:
		case 31:
			return "st";
		case 2:
		case 22:
			return "nd";
		case 3:
		case 23:
			return "rd";
		default:
			return "th";
	}
}

Solution 2 - C#

As a reference I always use/refer to [SteveX String Formatting] 1 and there doesn't appear to be any "th" in any of the available variables but you could easily build a string with

string.Format("{0:dddd dd}{1} {0:MMMM yyyy}", DateTime.Now, (?));

You would then have to supply a "st" for 1, "nd" for 2, "rd" for 3, and "th" for all others and could be in-lined with a "? :" statement.

var now = DateTime.Now;
(now.Day % 10 == 1 && now.Day % 100 != 11) ? "st"
: (now.Day % 10 == 2 && now.Day % 100 != 12) ? "nd"
: (now.Day % 10 == 3 && now.Day % 100 != 13) ? "rd"
: "th"

Solution 3 - C#

Using a couple of extension methods:

namespace System
{
    public static class IntegerExtensions
    {
        public static string ToOccurrenceSuffix(this int integer)
        {
            switch (integer % 100)
            {
                case 11:
                case 12:
                case 13:
                    return "th";
            }
            switch (integer % 10)
            {
                case 1:
                    return "st";
                case 2:
                    return "nd";
                case 3:
                    return "rd";
                default:
                    return "th";
            }
        }
    }   
 
    public static class DateTimeExtensions
    {
        public static string ToString(this DateTime dateTime, string format, bool useExtendedSpecifiers)
        {
            return useExtendedSpecifiers 
                ? dateTime.ToString(format)
                    .Replace("nn", dateTime.Day.ToOccurrenceSuffix().ToLower())
                    .Replace("NN", dateTime.Day.ToOccurrenceSuffix().ToUpper())
                : dateTime.ToString(format);
        } 
    }
}

Usage:

return DateTime.Now.ToString("dddd, dnn MMMM yyyy", useExtendedSpecifiers: true);
// Friday, 7th March 2014

Note: The integer extension method can be used for any number, not just 1 to 31. e.g.

return 332211.ToOccurrenceSuffix();
// th

Solution 4 - C#

Another option is using the Modulo Operator:

public string CreateDateSuffix(DateTime date)
{
    // Get day...
    var day = date.Day;

    // Get day modulo...
    var dayModulo = day%10;

    // Convert day to string...
    var suffix = day.ToString(CultureInfo.InvariantCulture);

    // Combine day with correct suffix...
    suffix += (day == 11 || day == 12 || day == 13) ? "th" :
        (dayModulo == 1) ? "st" :
        (dayModulo == 2) ? "nd" :
        (dayModulo == 3) ? "rd" :
        "th";

    // Return result...
    return suffix;
}

You would then call the above method by passing-in a DateTime object as a parameter, for example:

// Get date suffix for 'October 8th, 2019':
var suffix = CreateDateSuffix(new DateTime(2019, 10, 8));

For more info about the DateTime constructor, please see Microsoft Docs Page.

Solution 5 - C#

Here is extended version including 11th, 12th and 13th:

DateTime dt = DateTime.Now;
string d2d = dt.ToString("dd").Substring(1);
string daySuffix =
    (dt.Day == 11 || dt.Day == 12 || dt.Day == 13) ? "th"
    : (d2d == "1") ? "st"
    : (d2d == "2") ? "nd"
    : (d2d == "3") ? "rd"
    : "th";

Solution 6 - C#

Taking @Lazlow's answer to a complete solution, the following is a fully reusable extension method, with example usage;

internal static string HumanisedDate(this DateTime date)
{
	string ordinal;

	switch (date.Day)
	{
		case 1:
		case 21:
		case 31:
			ordinal = "st";
			break;
		case 2:
		case 22:
			ordinal = "nd";
			break;
		case 3:
		case 23:
			ordinal = "rd";
			break;
		default:
			ordinal = "th";
			break;
	}

	return string.Format("{0:dddd dd}{1} {0:MMMM yyyy}", date, ordinal);
} 

To use this you would simply call it on a DateTime object;

var myDate = DateTime.Now();
var myDateString = myDate.HumanisedFormat()

Which will give you: > Friday 17th June 2016

Solution 7 - C#

UPDATE

NuGet package:
https://www.nuget.org/packages/DateTimeToStringWithSuffix

Example:
https://dotnetfiddle.net/zXQX7y

Supports:
.NET Core 1.0 and higher
.NET Framework 4.5 and high


Here's an extension method (because everyone loves extension methods), with Lazlow's answer as the basis (picked Lazlow's as it's easy to read).

Works just like the regular ToString() method on DateTime with the exception that if the format contains a d or dd, then the suffix will be added automatically.

/// <summary>
/// Return a DateTime string with suffix e.g. "st", "nd", "rd", "th"
/// So a format "dd-MMM-yyyy" could return "16th-Jan-2014"
/// </summary>
public static string ToStringWithSuffix(this DateTime dateTime, string format, string suffixPlaceHolder = "$") {
    if(format.LastIndexOf("d", StringComparison.Ordinal) == -1 || format.Count(x => x == 'd') > 2) {
        return dateTime.ToString(format);
    }

    string suffix;
    switch(dateTime.Day) {
        case 1:
        case 21:
        case 31:
            suffix = "st";
            break;
        case 2:
        case 22:
            suffix = "nd";
            break;
        case 3:
        case 23:
            suffix = "rd";
            break;
        default:
            suffix = "th";
            break;
    }

    var formatWithSuffix = format.Insert(format.LastIndexOf("d", StringComparison.InvariantCultureIgnoreCase) + 1, suffixPlaceHolder);
    var date = dateTime.ToString(formatWithSuffix);

    return date.Replace(suffixPlaceHolder, suffix);
}

Solution 8 - C#

I believe this to be a good solution, covering numbers such as 111th etc:

private string daySuffix(int day)
{
    if (day > 0)
    {
        if (day % 10 == 1 && day % 100 != 11)
            return "st";
        else if (day % 10 == 2 && day % 100 != 12)
            return "nd";
        else if (day % 10 == 3 && day % 100 != 13)
            return "rd";
        else
            return "th";
    }
    else
        return string.Empty;
}

Solution 9 - C#

For those who are happy to use external dependencies (in this case the fantastic Humanizr .net), it's as simple as

dateVar.Day.Ordinalize(); \\ 1st, 4th etc depending on the value of dateVar

Solution 10 - C#

public static String SuffixDate(DateTime date) { string ordinal;

     switch (date.Day)
     {
        case 1:
        case 21:
        case 31:
           ordinal = "st";
           break;
        case 2:
        case 22:
           ordinal = "nd";
           break;
        case 3:
        case 23:
           ordinal = "rd";
           break;
        default:
           ordinal = "th";
           break;
     }
     if (date.Day < 10)
        return string.Format("{0:d}{2} {1:MMMM yyyy}", date.Day, date, ordinal);
     else
        return string.Format("{0:dd}{1} {0:MMMM yyyy}", date, ordinal);
  }

Solution 11 - C#

For what its worth here is my final solution using the below answers

     DateTime dt = DateTime.Now;
        string d2d = dt.ToString("dd").Substring(1); 
        
        string suffix =
       (dt.Day == 11 || dt.Day == 12 || dt.Day == 13) ? "th"
       : (d2d == "1") ? "st"
       : (d2d == "2") ? "nd"
       : (d2d == "3") ? "rd"
       : "th";


        Date.Text = DateTime.Today.ToString("dddd d") + suffix + " " + DateTime.Today.ToString("MMMM") + DateTime.Today.ToString(" yyyy"); 

Solution 12 - C#

Get Date Suffix. (Static Function)

public static string GetSuffix(this string day)
{
    string suffix = "th";

    if (int.Parse(day) < 11 || int.Parse(day) > 20)
    {
        day = day.ToCharArray()[day.ToCharArray().Length - 1].ToString();
        switch (day)
        {
            case "1":
                suffix = "st";
                break;
            case "2":
                suffix = "nd";
                break;
            case "3":
                suffix = "rd";
                break;
        }
    }

    return suffix;
}

Reference: https://www.aspsnippets.com/Articles/Display-st-nd-rd-and-th-suffix-after-day-numbers-in-Formatted-Dates-using-C-and-VBNet.aspx

Solution 13 - C#

Check out humanizr: https://github.com/Humanizr/Humanizer#date-time-to-ordinal-words

new DateTime(2015, 1, 1).ToOrdinalWords() => "1st January 2015"
new DateTime(2015, 2, 12).ToOrdinalWords() => "12th February 2015"
new DateTime(2015, 3, 22).ToOrdinalWords() => "22nd March 2015"
// for English US locale
new DateTime(2015, 1, 1).ToOrdinalWords() => "January 1st, 2015"
new DateTime(2015, 2, 12).ToOrdinalWords() => "February 12th, 2015"
new DateTime(2015, 3, 22).ToOrdinalWords() => "March 22nd, 2015"

I realized right after posting this that @Gumzle suggested the same thing, but I missed his post because it was buried in code snippets. So this is his answer with enough code that someone (like me) quickly scrolling through might see it.

Solution 14 - C#

Simpler answer using a switch expression (since C# 8):

var daySuffix = dateTime.Day switch {
                    1 or 21 or 31 => "st",
                    2 or 22 => "nd",
                    3 or 23 => "rd",
                    _ => "th",
                };

Solution 15 - C#

A cheap and cheerful VB solution:

litDate.Text = DatePart("dd", Now) & GetDateSuffix(DatePart("dd", Now))

Function GetDateSuffix(ByVal dateIn As Integer) As String

    '// returns formatted date suffix

    Dim dateSuffix As String = ""
    Select Case dateIn
        Case 1, 21, 31
            dateSuffix = "st"
        Case 2, 22
            dateSuffix = "nd"
        Case 3, 23
            dateSuffix = "rd"
        Case Else
            dateSuffix = "th"
    End Select

    Return dateSuffix

End Function

Solution 16 - C#

I did it like this, it gets around some of the problems given in the other examples.

    public static string TwoLetterSuffix(this DateTime @this)
    {
        var dayMod10 = @this.Day % 10;

        if (dayMod10 > 3 || dayMod10 == 0 || (@this.Day >= 10 && @this.Day <= 19))
        {
            return "th";
        }
        else if(dayMod10 == 1)
        {
            return "st";
        }
        else if (dayMod10 == 2)
        {
            return "nd";
        }
        else
        {
            return "rd";
        }
    }

Solution 17 - C#

string datestring;    
// datestring = DateTime.Now.ToString("dd MMMM yyyy"); // 16 January 2021

	// code to add 'st' ,'nd', 'rd' and 'th' with day of month 
	// DateTime todaysDate = DateTime.Now.Date; // enable this line for current date 
	DateTime todaysDate = DateTime.Parse("01-13-2021"); // custom date to verify code // 13th January 2021
	int day = todaysDate.Day;
	string dateSuffix;

	if(day==1 || day==21 || day==31){
		dateSuffix= "st";
	}else if(day==2 || day==22 ){
		dateSuffix= "nd";
	}else if(day==3 || day==23 ){
		dateSuffix= "rd";
	}else{
		dateSuffix= "th";
	}
	datestring= day+dateSuffix+" "+todaysDate.ToString("MMMM")+" "+todaysDate.ToString("yyyy");
	Console.WriteLine(datestring);

Solution 18 - C#

Another option using the last string character:

public static string getDayWithSuffix(int day) {
 string d = day.ToString();
 if (day < 11 || day > 13) {
  if (d.EndsWith("1")) {
   d += "st";
  } else if (d.EndsWith("2")) {
   d += "nd";
  } else if (d.EndsWith("3")) {
   d += "rd";
  } else {
   d += "th";
 } else {
  d += "th";
 }
 return d;
}

Solution 19 - C#

in the MSDN documentation there is no reference to a culture that could convert that 17 into 17th. so You should do it manually via code-behind.Or build one...you could build a function that does that.

public string CustomToString(this DateTime date)
    {
        string dateAsString = string.empty;
        <here wright your code to convert 17 to 17th>
        return dateAsString;
    }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCraig BovisView Question on Stackoverflow
Solution 1 - C#LazlowView Answer on Stackoverflow
Solution 2 - C#Bryan BailliacheView Answer on Stackoverflow
Solution 3 - C#OundlessView Answer on Stackoverflow
Solution 4 - C#Anthony WalshView Answer on Stackoverflow
Solution 5 - C#Piotr LewandowskiView Answer on Stackoverflow
Solution 6 - C#Mark CooperView Answer on Stackoverflow
Solution 7 - C#GFoley83View Answer on Stackoverflow
Solution 8 - C#DuncanView Answer on Stackoverflow
Solution 9 - C#GumzleView Answer on Stackoverflow
Solution 10 - C#Robert Peter BronsteinView Answer on Stackoverflow
Solution 11 - C#Corbin SpicerView Answer on Stackoverflow
Solution 12 - C#Manjunath BilwarView Answer on Stackoverflow
Solution 13 - C#Drew DelanoView Answer on Stackoverflow
Solution 14 - C#mylView Answer on Stackoverflow
Solution 15 - C#TonyView Answer on Stackoverflow
Solution 16 - C#rashleighpView Answer on Stackoverflow
Solution 17 - C#mhkView Answer on Stackoverflow
Solution 18 - C#JoddaView Answer on Stackoverflow
Solution 19 - C#GxGView Answer on Stackoverflow