Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
216 views
in Technique[技术] by (71.8m points)

c# - How to create and use a custom IFormatProvider for DateTime?

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!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...