首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何为DateTime创建和使用自定义IFormatProvider?

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

Stack Overflow用户
提问于 2010-03-05 03:34:41
回答 3查看 53.2K关注 0票数 24

我正在尝试创建一个能够识别DateTime对象的自定义格式字符串的IFormatProvider实现。下面是我的实现:

代码语言:javascript
复制
 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();
   }
  } 

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

代码语言:javascript
复制
DateTime d = new DateTime(2000, 1, 2);
string s = d.ToString("mycustomformat", new MyDateFormatProvider());

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

但是,当我以以下方式使用相同的类时:

代码语言:javascript
复制
DateTime d = new DateTime(2000, 1, 2);
string s = String.Format(new MyDateFormatProvider(), "{0:mycustomformat}", d);

我得到了我想要的,即"Sun Jan 02"

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

谢谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-03-05 04:07:03

使用Reflector检查DateTime.ToString方法显示,DateTime结构使用DateTimeFormatInfo.GetInstance方法来获取要用于格式化的提供程序。DateTimeFormatInfo.GetInstance从传入的提供程序请求DateTimeFormatInfo类型的格式化程序,而不是ICustomFormmater,因此如果没有找到提供程序,它只返回DateTimeFormatInfoCultureInfo的实例。DateTime.ToString方法似乎不像StringBuilder.Format方法那样支持ICustomFormatter接口,如您的String.Format示例所示。

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

票数 11
EN

Stack Overflow用户

发布于 2010-03-05 04:26:40

简单的解释是,虽然

代码语言:javascript
复制
DateTime.ToString(string format, IFormatProvider provider)

允许您将任何实现IFormatProvider的内容作为其参数之一进行传递,它实际上只支持在其代码中实现IFormatProvider的两种可能类型:

DateTimeFormatInfoCultureInfo

如果您的参数不能(使用as)强制转换为二者之一,则该方法将缺省为CurrentCulture

String.Format不受这些界限的限制。

票数 22
EN

Stack Overflow用户

发布于 2010-03-05 04:14:50

使用扩展方法:)

代码语言:javascript
复制
public static class FormatProviderExtension
    {
        public static string FormatIt(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();
            }
        }

        public static string ToString(this DateTime d, IFormatProvider formatProvider, string format)
        {
            return FormatIt(format, d, formatProvider);
        }
    }
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2382154

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档