DateTime 和 DateTimeOffset 的 ParseExact() 中的格式提供程序的目的是什么?

问题描述

让我们考虑一下DateTimeOffset.ParseExact

public static DateTime ParseExact (
    string s,string format,IFormatProvider? provider,System.Globalization.DateTimeStyles style
);

预期的格式已经通过 format 参数进行了描述,那么 provider 参数的目的是什么?谁能举例说明不同的 provider 值如何导致不同的结果?

解决方法

自定义日期时间格式字符串的各种元素的含义取决于格式提供程序。

示例:

var aString = "12 avr. 2021";
var gbCulture = new CultureInfo("en-GB");
var frCulture = new CultureInfo("fr-FR");

var canParseGb = 
    DateTime.TryParseExact(aString,"dd MMM yyyy",gbCulture,DateTimeStyles.None,out var gbDateTime);
var canParseFr = 
    DateTime.TryParseExact(aString,frCulture,out var frDateTime);

相同的输入字符串s,相同的格式字符串format,不同的provider=>不同的结果。

,

例如 CultureInfo 实现 IFormatProvider。因此,除了提供的格式字符串之外,您还可以传递一种具有自己格式规则的文化。

另请注意,格式字符串可以包含在不同文化/格式提供者(如 "/" custom format specifier)下表现不同的说明符:

CultureInfo deCulture = new CultureInfo("de-DE"); // german
CultureInfo frCulture = new CultureInfo("fr-FR"); // french
// works because / is replaced with the passed culture's date-separator which is . in germany
DateTime dateDe = DateTime.ParseExact("25.02.2021","dd/MM/yyyy",deCulture,DateTimeStyles.None); 
// works not since french use / as date-separator
DateTime dateFr = DateTime.ParseExact("25.02.2021",DateTimeStyles.None); 

正如 Magnetron 所评论的,这同样适用于 ":" custom time format specifier

,

不同的文化会对月份名称和星期几等内容使用不同的值。 Jul 对您来说可能是七月,但在法国却不是。例如:

var frenchDate = DateTimeOffset.ParseExact("1 févr. 2020","d MMM yyyy",CultureInfo.GetCultureInfo("fr-FR"));

var englishDate = DateTimeOffset.ParseExact("1 Feb 2020",CultureInfo.GetCultureInfo("en-GB"));

所有这些细节都可以在 CultureInfo 对象中看到,例如 fr-FR 看起来像这样:

enter image description here

,

文档对此非常清楚:

input 中使用的特定日期和时间符号和字符串由 formatProvider 参数定义...