如何为DateTime创建和使用自定义IFormatProvider?

Mar*_*edy 20 c# iformatprovider

我试图创建一个IFormatProvider可以识别DateTime对象的自定义格式字符串的实现.这是我的实现:

 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();
   }
  } 
Run Code Online (Sandbox Code Playgroud)

我希望能够在这样的DateTime.ToString(string format, IFormatProvider provider)方法中使用它,但是:

DateTime d = new DateTime(2000, 1, 2);
string s = d.ToString("mycustomformat", new MyDateFormatProvider());
Run Code Online (Sandbox Code Playgroud)

在该示例中,运行在美国文化中,结果"00cu0Ao00or0aA"显然是因为正在解释标准的DateTime格式字符串.

但是,当我以下列方式使用同一个类时:

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

我得到了我的期望,即 "Sun Jan 02"

我不明白不同的结果.有人能解释一下吗

谢谢!

Dyn*_*ard 18

简短的解释是,虽然

DateTime.ToString(string format, IFormatProvider provider)
Run Code Online (Sandbox Code Playgroud)

让你传递任何实现IFormatProvider作为其中一个参数的东西,它实际上只支持IFormatProvider在其代码中实现的两种可能的类型:

DateTimeFormatInfo 要么 CultureInfo

如果您的参数无法as作为其中之一(使用)进行转换,则该方法将默认为CurrentCulture.

String.Format 不受此限制的限制.


Kel*_*dge 10

DateTime.ToString使用Reflector 检查方法表明该DateTime结构使用该DateTimeFormatInfo.GetInstance方法来获取用于格式化的提供程序.传入提供DateTimeFormatInfo.GetInstance程序的类型格式化程序的请求DateTimeFormatInfo,永远不会ICustomFormmater,因此它只返回一个实例DateTimeFormatInfoCultureInfo如果找不到提供程序.正如您的示例所示,似乎该DateTime.ToString方法不像方法那样遵守ICustomFormatter接口.StringBuilder.FormatString.Format

我同意该DateTime.ToString方法应该支持该ICustomFormatter接口,但目前似乎并不支持.这可能已经改变或将在.NET 4.0中发生变化.