Click here to Skip to main content
15,878,959 members
Articles / Programming Languages / C#
Article

How To Append 'st', 'nd', 'rd' or 'th' To Day Numbers in Dates

Rate me:
Please Sign up or sign in to vote.
3.92/5 (9 votes)
16 Nov 2007CPOL4 min read 161.2K   1.2K   40   11
A custom type formatter to append the appropriate 'st/nd/rd/th' text to day numbers when outputting date strings

Introduction

I recently had a requirement to output date strings in a format that included the two letter suffix added to the day number. E.g. "January 1st 2008" as opposed to "January 1 2008"

After some investigation, it seems this is not supported out of the box (not surprising really). I concluded that there are a number of ways to implement this behaviour in .NET and decided on a method that is ".NET Framework friendly" and therefore offers good reuse value and is intuitive for .NET developers to use.

Approach

The solution makes use of the custom formatting capabilities in the framework whereby it is possible to implement the IFormatProvider and ICustomFormatter interfaces to provide custom string formatting for use with methods that support formatting such as String.Format() or Console.WriteLine()

I decided to extend the existing DateTime format provision in the framework by adding new format options for the DateTime type. The existing framework support for date formatting is comprehensive; here are a few of the commonly used format specifiers:

FormatOutput
dShort date pattern
DLong date pattern
FFull date/time pattern

For more, see the MSDN article - Standard DateTime Format Strings.

My idea was to duplicate some of these standard formats (where appropriate) and include the day number suffix. The following date formats have been "extended":

StandardExampleWith suffixExample
dd31ddx31st
D31 January 2008Dx31st January 2008
F31 January 2008 21:30:15Fx31st January 2008 21:30:15
f31 January 2008 21:30fx31st January 2008 21:30
m31 Januarymx31st January
RThu, 31 Jan 2008 21:30:15 GMTRxThu, 31st Jan 2008 21:30:15 GMT
U31 January 2008 21:30:15Ux31st January 2008 21:30:15
--xst

Note, the above examples show dates in English (British) format.

I also wanted to allow a developer to create her or his own date formats by taking advantage of the day number suffix. This makes it possible to use just the suffixed day number to compose your own formats. For example:

C#
string.Format(new DayNumberFormatInfo(), 
	"It's the {0:ddx} day of the month", DateTime.Now);

Code Structure

There are two projects in the attached solution:

  • MarkGwilliam.com.Framework.Formatting - Format class
  • MarkGwilliam.com.Framework.Formatting.Tests - Unit tests (requires NUnit)

The DayNumberFormatInfo class contains the actual formatting logic. This class implements the required framework interface methods which, in turn, call the GetDayNumberSuffix() helper method to perform the string formatting.

Demo Project / Unit Tests

This is such a small topic that there isn't really a demo project as such. Instead, there are a number of unit tests which show how to use the supported formats and allow you to tinker with code without inadvertently introducing defects.

Example Usage

In the following example, a format string "Dx" has been used which is identical to the output you would receive from using a format string of "D" but with the added two letter suffix to the day number:

C#
string.Format(new GetDayNumberSuffix(), "{0:Dx}", DateTime.Now);

Globalization (And Some Limitations)

The code has been developed to format dates for a British culture. The "extended" date formats all follow British date formatting:

With some extra work, it could be modified to be more culture aware and mimic other cultures but this was outside what I needed so I haven't gone through the trouble. If you're interested in doing so, then you will need to alter the DayNumberFormatInfo.Format() method and maybe use another technique to replace the day number in the standard formatted string.

However, this code can still be used effectively in all cultures in its current state and serves as a starting point if you wish to extend it further.

.NET Framework Limitations

I had originally hoped to provide this formatting functionality in calls to DateTime.ToString(), but the .NET Framework code does NOT support the use of ICustomFormatter in that way. That is unfortunate as the String.ToString() function does. This can be proven by looking at the IL code using Reflector or a similar tool. Parsing is also not supported for this reason.

Points of Interest

None really apart from the fact that if you're considering adding some functionality, it's worth checking to see if you can extend the framework in some way. This allows developers to consume your code more easily and hopefully expands your knowledge of .NET along the way.

Further Reading

The topic of customer formatters is well described in the MSDN documentation as well as in the article, Custom String Formatting in .NET, on The Code Project.

History

  • Version 1.0 - 16th Nov 2007 - Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect oo.magic
United Kingdom United Kingdom
Mark Gwilliam is a freelance .Net consultant based in the UK specialising in .Net architecture, design and coding.

He has been working in IT for around 15 years and has worked primarily in the financial sector and is always keen to lead, learn, follow or teach

Comments and Discussions

 
QuestionIts not supported because 1st it is bad grammar and 2nd you should not do this (progression not DATES) Pin
Madeleine Mc Jones21-Oct-14 8:27
Madeleine Mc Jones21-Oct-14 8:27 
QuestionHow about this: Pin
Fawad Raza14-Dec-09 22:40
Fawad Raza14-Dec-09 22:40 
QuestionHow about this? Pin
daokfella14-Sep-09 21:24
daokfella14-Sep-09 21:24 
GeneralWorks good - One Suggestion Pin
developerz22-Jan-08 1:58
developerz22-Jan-08 1:58 
GeneralRe: Works good - One Suggestion Pin
MarkGwilliam23-Jan-08 6:44
MarkGwilliam23-Jan-08 6:44 
GeneralRe: Works good - One Suggestion Pin
developerz23-Jan-08 7:08
developerz23-Jan-08 7:08 
Thanks Mark! That seems to do the trick... I just wrapped TrimZeros around FormatDayNumberSuffix within the ICustomFormatter.Format:
-------------------------

else if (formatString.Equals("ddx", StringComparison.Ordinal))
return TrimZeros(FormatDayNumberSuffix(dateTime));

-------------------------
GeneralRe: Works good - One Suggestion Pin
MarkGwilliam23-Jan-08 7:11
MarkGwilliam23-Jan-08 7:11 
GeneralRe: Works good - One Suggestion Pin
mbooth951720-Apr-08 18:35
mbooth951720-Apr-08 18:35 
GeneralNice Pin
si61820-Nov-07 12:54
si61820-Nov-07 12:54 
GeneralRe: Nice Pin
MarkGwilliam23-Nov-07 2:38
MarkGwilliam23-Nov-07 2:38 
GeneralRe: Nice Pin
si61825-Nov-07 12:45
si61825-Nov-07 12:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.