Nodatime 格式化来自特定文化的长日期模式,但使用来自另一种文化的月份名称

Nodatime Formatting Long Date Pattern From A Specific Culture But Using Month Names From Another Culture

在 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 是一个很棒的图书馆,也是我仍然留着头发的原因。

是的,这是 IFormatProvider 架构的一个问题,基本上 - 我们没有尽可能好地处理这个问题。 DateTimeFormatInfoCultureInfo 都实现了 IFormatProvider,但为了在某些情况下执行格式化,我们需要的不仅仅是 DateTimeFormatInfo - 我们需要 NumberFormatInfo(对于正负号)和 CompareInfo(用于文本比较)。

因此,当我们得到一个 IFormatInfo 而不是 CultureInfo 时,我们基本上做错了事 - 我们最终使用了当前的文化。

我们有一个 issue in github 用于 similar,但是很明显,如果你只传入一个 NumberFormatInfo,那将无法到达date/time 设置,传递 DateTimeFormatInfo.

时出错的情况不太明显

我可能会让这样的调用抛出一个有用的消息异常,而不仅仅是做错事......或者我可以只使用不变区域性来获得 CompareInfoNumberFormatInfo如果你传入 DateTimeFormatInfo.

请注意,这可能最终会变得很慢,因为我们必须在每次调用时重建内部 NodaTimeFormatInfo,因为您要传递可变的 DateTimeFormatInfoCultureInfo 在每种情况下。最好从 CultureInfo 创建一个 LocalDatePattern - 在这种情况下,以后不要再更改 CultureInfo 取决于你。 (基本上,CultureInfo 可变是一种巨大的痛苦。)