【问题标题】:Why is string.Format("{0:d}", DateTime.Now) returning "yyyy-MM-dd" instead of US-local "M/d/yyyy" after changing local display settings?为什么在更改本地显示设置后 string.Format("{0:d}", DateTime.Now) 返回 "yyyy-MM-dd" 而不是美国本地 "M/d/yyyy"?
【发布时间】:2017-03-07 07:58:22
【问题描述】:

在查看一些失败的测试时,我发现了这个意想不到的结果:

// Expected "3/6/2017"
string.Format("{0:d}", System.DateTime.Now)
"2017-03-06"

// Expected "3/6/2017 09:31:13 AM" (or similar)
string.Format("{0}", System.DateTime.Now)
"2017-03-06 09:31:13"

string.Format("{0:G}", System.DateTime.Now)
"2017-03-06 09:31:13"

[nunit 控制台运行程序、Visual Studio 的交互式控制台和 LINQPad 的结果是一致的。由于 LINQPad 中的结果是相同的,没有运行它的其余代码,这似乎是一个机器/全局配置问题 - 合适,因为我更改了本地机器的日期/时间显示格式。]

等等……什么?这与我对美国本地化的“3/6/2017 09:31:13”的预期明显不同。

  • 为什么会发生这种情况,这种行为在哪里清楚地记录在案?

    美国的文化不再是“真正的”吗?

  • 如何确保输出符合 en-US 规则?

    无论机器特定的设置修改如何,如何保证输出遵循机器的本地化设置?

由于这是一个格式本地化问题,我还捕捉到了当前的文化。似乎“en-US”文化不足以保证格式一致。


System.Threading.Thread.CurrentThread.CurrentCulture
{en-US}
    Calendar: {System.Globalization.GregorianCalendar}
    CompareInfo: {CompareInfo - en-US}
    CultureTypes: SpecificCultures | InstalledWin32Cultures | FrameworkCultures
    DateTimeFormat: {System.Globalization.DateTimeFormatInfo}
    DisplayName: "English (United States)"
    EnglishName: "English (United States)"
    IetfLanguageTag: "en-US"
    IsNeutralCulture: false
    IsReadOnly: true
    KeyboardLayoutId: 1033
    LCID: 1033
    Name: "en-US"
    NativeName: "English (United States)"
    NumberFormat: {System.Globalization.NumberFormatInfo}
    OptionalCalendars: {System.Globalization.Calendar[2]}
    Parent: {en}
    TextInfo: {TextInfo - en-US}
    ThreeLetterISOLanguageName: "eng"
    ThreeLetterWindowsLanguageName: "ENU"
    TwoLetterISOLanguageName: "en"
    UseUserOverride: true

【问题讨论】:

  • 你需要给它一个特定的格式提供者msdn.microsoft.com/en-us/library/1ksz8yb7(v=vs.110).aspx 或者你只是在问为什么你的文化设置会出现这种行为?
  • @juharr 这意味着我之前对在假定的“en-US”默认值下运行的代码的预期输出的所有假设都是错误的。
  • @juharr 我猜:为什么“en-US”看起来是“我的本地机器”?
  • 为什么你会得到这些结果,我不确定。我正在使用“en-US”运行并获得您期望的输出。一定有什么设置可以改变它。
  • 这里也一样,希望了解更多日期格式细节的人可以帮助您。

标签: c# datetime localization


【解决方案1】:

根据documentation for the CultureInfo class:

控制面板覆盖

用户可以选择通过控制面板的区域和语言选项部分覆盖与当前 Windows 文化相关的一些值。例如,用户可能会选择以不同的格式显示日期,或者使用不同于文化默认值的货币。一般来说,您的应用程序应该尊重这些用户覆盖。

如果 UseUserOverride 为 true 并且指定的区域性与 Windows 的当前区域性匹配,CultureInfo 将使用这些覆盖,包括 DateTimeFormat 属性返回的 DateTimeFormatInfo 实例的属性的用户设置,以及NumberFormat 属性返回的 NumberFormatInfo 实例的属性。

默认情况下,UseUserOverride 为 true,正如您在捕获当前文化中所看到的那样。

要忽略控制面板覆盖并使用 en-US 区域性的默认设置,请调用 CultureInfo.GetCultureInfo(String) 并将结果分配给 Thread.CurrentThread.CurrentCulture。根据此方法的文档:

如果 name 是当前区域性的名称,则返回的 CultureInfo 对象不反映任何用户覆盖。这使得该方法适用于在系统上没有真实用户帐户并且需要有效加载多种文化的服务器应用程序或工具。

【讨论】:

  • 如果这是默认的 sigh。很多很好的信息。
【解决方案2】:

文化是指年-月-日的安排。至于格式“yyyy-MM-dd”是默认格式。(我可能错了,但这是根据我的理解)。因此,您可能希望为其提供自定义格式。 Applying date format

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2015-11-10
  • 1970-01-01
  • 1970-01-01
  • 2014-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多