在Noda Time,我想使用特定文化格式化长日期模式,但使用其他文化中的月份名称和日期名称。
我的初始代码是:
var dtfi = (DateTimeFormatInfo) CultureInfo.CurrentCulture.DateTimeFormat.Clone(); // fr-FR
dtfi.DayNames = CultureInfo.CurrentUICulture.DateTimeFormat.DayNames; // en-US
dtfi.MonthNames = CultureInfo.CurrentUICulture.DateTimeFormat.MonthNames;
dtfi.MonthGenitiveNames = CultureInfo.CurrentUICulture.DateTimeFormat.MonthGenitiveNames;
return localDate.ToString("D", dtfi);
克隆DateTimeFormat不起作用。仍然使用法语打印日期名称和月份名称的日期。但是,如果我克隆了CurrentCulture,它就会起作用:
var ci = (CultureInfo) CultureInfo.CurrentCulture.Clone(); // fr-FR
ci.DateTimeFormat.DayNames = CultureInfo.CurrentUICulture.DateTimeFormat.DayNames; // en-US
ci.DateTimeFormat.MonthNames = CultureInfo.CurrentUICulture.DateTimeFormat.MonthNames;
ci.DateTimeFormat.MonthGenitiveNames = CultureInfo.CurrentUICulture.DateTimeFormat.MonthGenitiveNames;
return localDate.ToString("D", ci);
在两个代码片段中,我跟踪代码,可以看到在调用localDate.ToString之前分配了日期名称,月份名称和月份名称。
任何人都可以解释为什么第一个代码段不起作用吗?
P.S。 Noda Time是一个了不起的图书馆,也是我还有头发的原因。
答案 0 :(得分:0)
是的,这是IFormatProvider
架构的一个问题,基本上 - 我们没有尽可能地处理。 DateTimeFormatInfo
和CultureInfo
都实现了IFormatProvider
,但为了在某些情况下执行格式化,我们需要的不只是DateTimeFormatInfo
- 我们需要NumberFormatInfo
(对于CompareInfo
正面和负面的迹象)和IFormatInfo
(用于文本比较)。
因此,当我们获得CultureInfo
而不是NumberFormatInfo
时,我们基本上做错了 - 我们最终使用了当前的文化。
对于类似的,我们有一个issue in github,但很明显,如果只传入DateTimeFormatInfo
,则无法获取日期/时间设置,传递CompareInfo
时,事情会出现问题的情况不太明显。
我可能会使这样的调用使用有用的消息抛出异常,而不仅仅是做错了...或者我可以使用不变文化来获取NumberFormatInfo
和DateTimeFormatInfo
如果你传递NodaTimeFormatInfo
。
请注意,由于我们必须在每个调用中重建内部DateTimeFormatInfo
,因此您可能最终会变得非常缓慢,因为您传入了一个可变的CultureInfo
或LocalDatePattern
in每个案例。最好从CultureInfo
创建一个CultureInfo
- 在这种情况下,由您决定以后不再更改CultureInfo
。 (基本上,{{1}}可变是一种巨大的痛苦。)