如何为DateTime创建和使用自定义IFormatProvider?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何为DateTime创建和使用自定义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();
}
}
我希望能够像这样在DateTime.ToString(string format, IFormatProvider provider)
方法中使用它,但:
DateTime d = new DateTime(2000, 1, 2);
string s = d.ToString("mycustomformat", new MyDateFormatProvider());
在该示例中,以美国文化运行,结果为"00cu0Ao00or0aA"
,显然是因为标准的DateTime格式字符串正在被解释。
但是,当我通过以下方式使用相同的类时:
DateTime d = new DateTime(2000, 1, 2);
string s = String.Format(new MyDateFormatProvider(), "{0:mycustomformat}", d);
我得到了我所期望的,即"Sun Jan 02"
我不明白不同的结果。有人可以解释吗?
谢谢!
使用Reflector检查DateTime.ToString
方法显示DateTime
结构使用DateTimeFormatInfo.GetInstance
方法来获取要用于格式化的提供程序。 DateTimeFormatInfo.GetInstance
向传入的提供者请求类型为DateTimeFormatInfo
的格式化程序,从不为ICustomFormmater
请求,因此,如果未找到提供者,则仅返回DateTimeFormatInfo
或CultureInfo
的实例。就像您的DateTime.ToString
示例所示,ICustomFormatter
方法似乎不像StringBuilder.Format
方法那样接受String.Format
接口。
[我同意DateTime.ToString
方法应支持ICustomFormatter
接口,但目前似乎不支持。这可能已全部更改,或者将在.NET 4.0中更改。
简短的解释是,虽然
DateTime.ToString(string format, IFormatProvider provider)
让您传递实现IFormatProvider
作为其参数之一的任何内容,实际上它仅支持在其代码内部实现IFormatProvider
的2种可能的类型:
[DateTimeFormatInfo
或CultureInfo
如果无法将参数强制转换为(或使用as
),则该方法将默认为CurrentCulture
。
[String.Format
不受此类限制。
使用扩展方法:)
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);
}
}
以上是关于如何为DateTime创建和使用自定义IFormatProvider?的主要内容,如果未能解决你的问题,请参考以下文章
如何为 Firebase (Kotlin) 创建自定义身份验证