Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create and use a custom IFormatProvider for DateTime?

Tags:

I was trying to create an IFormatProvider implementation that would recognize custom format strings for DateTime objects. Here is my implementation:

 public class MyDateFormatProvider : IFormatProvider, ICustomFormatter  {   public object GetFormat(Type formatType)   {    if (formatType == typeof(ICustomFormatter))    {     return this;    }    return null;   }    public string Format(string format, object arg, IFormatProvider formatProvider)   {    if(arg == null) throw new ArgumentNullException("arg");    if (arg.GetType() != typeof(DateTime)) return arg.ToString();    DateTime date = (DateTime)arg;    switch(format)    {     case "mycustomformat":      switch(CultureInfo.CurrentCulture.Name)      {       case "en-GB":        return date.ToString("ddd dd MMM");       default:        return date.ToString("ddd MMM dd");      }     default:      throw new FormatException();    }   }  

I was expecting to be able to use it in the DateTime.ToString(string format, IFormatProvider provider) method like so, but :

DateTime d = new DateTime(2000, 1, 2); string s = d.ToString("mycustomformat", new MyDateFormatProvider()); 

In that example, running in the US Culture, the result is "00cu0Ao00or0aA", apparently because the standard DateTime format strings are being interpreted.

However, when I use the same class in the following way:

DateTime d = new DateTime(2000, 1, 2); string s = String.Format(new MyDateFormatProvider(), "{0:mycustomformat}", d); 

I get what I expect, namely "Sun Jan 02"

I don't understand the different results. Could someone explain?

Thanks!

like image 759
Mark Kennedy Avatar asked Mar 04 '10 19:03

Mark Kennedy


People also ask

How do I use IFormatProvider?

The class that implements IFormatProvider can then be used in a call to a formatting and parsing operation. For example, the following code calls the String. Format(IFormatProvider, String, Object[]) method to generate a string that contains a formatted 12-digit account number.

What is FFF in time format?

The "fff" custom format specifier represents the three most significant digits of the seconds fraction; that is, it represents the milliseconds in a date and time value.

What is TT time format?

Terrestrial Time (TT) is a modern astronomical time standard defined by the International Astronomical Union, primarily for time-measurements of astronomical observations made from the surface of Earth.


1 Answers

The short explanation is that while

DateTime.ToString(string format, IFormatProvider provider) 

lets you pass anything implementing IFormatProvider as one of its parameters, it actually only supports 2 possible types implementing IFormatProvider inside its code:

DateTimeFormatInfo or CultureInfo

If your parameter cannot be casted (using as) as either or those, the method will default to CurrentCulture.

String.Format is not limited by such bounds.

like image 105
Dynami Le Savard Avatar answered Jan 15 '23 20:01

Dynami Le Savard