IFormatProvider做什么?


Answers:


61

除了伊恩·博伊德(Ian Boyd)的答案:

CultureInfo实现此接口,可以在您的情况下使用。例如,您可以解析一个法语日期字符串;你可以用

var ci = new CultureInfo("fr-FR");
DateTime dt = DateTime.ParseExact(yourDateInputString, yourFormatString, ci);

2
在.NET Framework 4.6中似乎不再有与您的示例匹配的重载。DateTime.ParseExact(string, string, IFormatProvider)我相信您必须改为使用-这样: DateTime.ParseExact("20160409 111559","yyyyMMdd HHmmss",CultureInfo.CurrentCulture)
James King

1
在.NET Framework 4.6.2中,您没有输入参数。我只使用了两个,效果很好。DateTime dt = DateTime.Parse(yourDateInputString, ci);请修改您的答案。
开发人员

1
抱歉,我的答案已经过期很长时间了。
安德烈·里内(AndreiRînea)'18年

49

IFormatProvider接口通常由一个CultureInfo类为您实现,例如:

  • CultureInfo.CurrentCulture
  • CultureInfo.CurrentUICulture
  • CultureInfo.InvariantCulture
  • CultureInfo.CreateSpecificCulture("de-CA") //German (Canada)

该接口是一个功能的网关,该功能可从区域性获取一组区域性特定数据。IFormatProvider可以查询的两个常用的文化对象是:

通常它的工作方式是您要求IFormatProvider给您一个DateTimeFormatInfo对象:

DateTimeFormatInfo format;
format = (DateTimeFormatInfo)provider.GetFormat(typeof(DateTimeFormatInfo));
if (format != null)
   DoStuffWithDatesOrTimes(format);

也有内在知识,任何IFormatProvider接口都可能由继承于CultureInfo或继承于的类实现DateTimeFormatInfo,因此您可以直接转换接口:

CultureInfo info = provider as CultureInfo;
if (info != null)
   format = info.DateTimeInfo;
else
{
   DateTimeFormatInfo dtfi = provider as DateTimeFormatInfo;
   if (dtfi != null)
       format = dtfi;
   else
       format = (DateTimeFormatInfo)provider.GetFormat(typeof(DateTimeFormatInfo));
}

if (format != null)
   DoStuffWithDatesOrTimes(format);

但是不要那样

所有的辛苦工作已经为您编写:

为了得到一个DateTimeFormatInfoIFormatProvider

DateTimeFormatInfo format = DateTimeFormatInfo.GetInstance(provider);

为了得到一个NumberFormatInfoIFormatProvider

NumberFormatInfo format = NumberFormatInfo.GetInstance(provider);

价值IFormatProvider在于您创建自己的文化对象。只要他们执行IFormatProvider,并返回要求的对象,您就可以绕过内置的区域性。

您还可以使用IFormatProvider一种通过传递任意文化对象的方法IFormatProvider。例如不同文化中的上帝之名

  • 耶和华
  • 雅威
  • יהוה
  • אהיהאשראהיה

这样一来,您的自定义LordsNameFormatInfo课程就可以在IFormatProvider就可以,并且可以保留该惯用法。

实际上,您永远不需要调用以下GetFormat方法IFormatProvider自己的。

每当需要时,IFormatProvider您都可以传递一个CultureInfo对象:

DateTime.Now.ToString(CultureInfo.CurrentCulture);

endTime.ToString(CultureInfo.InvariantCulture);

transactionID.toString(CultureInfo.CreateSpecificCulture("qps-ploc"));

注意:任何代码都会发布到公共领域。无需注明出处。


18

将null传递为 IFormatProvider为并不是正确的方法。如果用户在其PC上具有自定义的日期/时间格式,则在解析和转换为字符串时会遇到问题。我刚刚修复了一个错误,该错误在转换为字符串时有人将null作为IFormatProvider传递了。

相反,您应该使用 CultureInfo.InvariantCulture

错误:

string output = theDate.ToString("dd/MM/yy HH:mm:ss.fff", null);

正确:

string output = theDate.ToString("dd/MM/yy HH:mm:ss.fff", CultureInfo.InvariantCulture);

2
我们有什么理由要CultureInfo.InvariantCulture代替使用CultureInfo.CurrentCulture吗?
Stephen Booher 2013年

5
InvariantCulture是一种特殊的区域性,它保证始终存在于任何计算机上,并且始终会转换并解析回相同的值。CurrentCulture是当前线程的区域性。这可能会有所不同,如果您不使用相同的区域性将其转换为字符串并进行解析,则会出现格式错误……
蒂姆

5
传入的@StephenBooher null默认为CultureInfo.CurrentCulture。请参阅参考源中的调用,如果您遵循调用链,那么最终将替换为null,DateTimeFormatInfo.CurrentInfo它等于CultureInfo.CurrentCulture输出的内容。
Scott Chamberlain 2014年

我一直在寻找InvariantCulture。谢谢
Chicowitz '19




2

通过 MSDN

.NET Framework包括以下三个预定义的IFormatProvider实现,以提供特定于区域性的信息,这些信息用于格式化或解析数字以及日期和时间值:

  1. NumberFormatInfo类,它提供一个用于格式化数字,如货币,千位分隔符和小数分隔符号用于特定文化的信息。有关NumberFormatInfo对象识别并用于数字格式操作的预定义格式字符串的信息,请参阅“标准数字格式字符串”和“自定义数字格式字符串”。
  2. DateTimeFormatInfo类,它提供了用于日期和时间格式,如特定的文化或日期的年,月,日组成部分的顺序和格式的日期和时间分隔符符号的信息。有关由a识别的预定义格式字符串的信息DateTimeFormatInfo对象并用于数字格式操作,请参阅标准日期和时间格式字符串和自定义日期和时间格式字符串。
  3. CultureInfo类,它代表一个特定的文化。它的GetFormat方法返回特定于区域性的NumberFormatInfoDateTimeFormatInfo对象,具体取决于CultureInfo对象是在涉及数字还是日期和时间的格式化或解析操作中使用的。

.NET Framework也支持自定义格式。这通常涉及创建同时实现IFormatProvider和ICustomFormatter的格式化类。然后,将该类的实例作为参数传递给执行自定义格式操作的方法,例如String.Format(IFormatProvider, String, Object[])


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.