Adding a Day suffix in a DateTime variable is not a complex task, but it should be done properly.
In programming while most of the times we deal with logic that is not exposed to the UI there are times when we have to define and format an output for the client UI.
In this article I will talk about formatting a date so that the output will be composed by the day and the month and the day will have a suffix depending on it’s number value.
Most of the times we neglect the built in mechanisms in .NET Framework and especially this formatter interface because implementing it is a bit tricky, we have the tendency to use some built-in helpers that would solve our problem by manipulating strings. Even if the outcome is the same, I consider that for some situations we shouldn’t that far as to create a separate logic for the same functionality.
The interface IFormatProvider as stated in the microsoft’s official documentation it “Provides a mechanism for retrieving an object to control formatting.”. Well, what this really means is it’s a provider, it provides (based on our custom logic) the type/class that it should be used (which is a CustomFormatter) in order to create a formatting.
The formatter that will be returned from the provider must implement the ICustomFormatter interface and here is where we define our logic.
What we want to achieve in this example is to take a DateTime and apply a formatter :
static void Main(string[] args) { Console.WriteLine(string.Format(new DaySuffixFormatter(), "{0:ddnn MMMM}", DateTime.Now)); }
The output must be similar to:
28th May
Our formatter will be created from 3 parts
- public object GetFormat(Type formatType) – this method is required by the IFormatProvider interface. In this method we should check if the formatter was required, if the type belongs to the ICustomFormatter
- public string Format(string format, object arg, IFormatProvider formatProvider) – this method is required by the ICustomFormatter and in this method we will manipulate our datetime.
- private string AddDaySuffix(int integer) – this method determines the suffix to be added based on the day integer value
public class DaySuffixFormatter : IFormatProvider, ICustomFormatter { private string AddDaySuffix(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 string Format(string format, object arg, IFormatProvider formatProvider) { if (arg is DateTime dateTime) { string formatted = dateTime.ToString(format); formatted = formatted.Replace("nn", AddDaySuffix(dateTime.Day).ToLower()); formatted = formatted.Replace("NN", AddDaySuffix(dateTime.Day).ToUpper()); if (formatted.StartsWith("0")) formatted.Remove(0, 1); return formatted; } return string.Format(format, arg); } public object GetFormat(Type formatType) { return (formatType == typeof(ICustomFormatter)) ? this : null; } }
As you can see the approach is pretty straight forward. The format string contains additional characters “nn” which will be replaced with the appropiate suffix