为什么我的本地计算机可能会错误地格式化国际日期?

时间:2018-11-03 02:57:57

标签: c# .net datetime localization

这是一个奇怪的人...

我刚刚看到(先前通过)测试失败,因为日期的字符串表示中有多余的空格。有问题的测试以前已经在CI和我的本地计算机上通过,但是现在(在我的本地计算机上)失败了,因为日期段之间有多余的空格。

以下MCVE表现出相同的行为:

using System;
using System.Globalization;

public class Program
{
    public static void Main()
    {
        var date = new DateTime(2018, 01, 31);
        var format = "d/M/yyyy";
        var skSK = new CultureInfo("sk-SK");
        Console.WriteLine(date.ToString(format, skSK));
    }
}

在大多数地方(包括.NET Fiddle),它可以正确返回:

31.1.2018

但是在我的机器上,我现在得到:

31. 1. 2018

注意多余的空格!

我有信心本周早些时候可以在我的本地PC上按预期方式工作,因为我将带有该测试的项目用作一些覆盖工具试验的起点。当我今天下午恢复该实验后,由于新的测试失败,不再生成coverage文件。

我的PC可能发生什么变化,导致这种行为中断?

2 个答案:

答案 0 :(得分:4)

在Windows(与许多其他系统一样)中,语言环境日期/时间格式的来源是Unicode Common Locale Data Repository (CLDR),它为软件开发人员和语言学家提供了国际化和本地化支持。
有意义的 users

  
      
  • Microsoft(Windows,Office,Visual Studio等)
  •   
  • Apple(适用于Windows的macOS,iOS,watchOS,tvOS,Apple移动设备支持和iTunes;
  •   
  • Google(网络搜索,Chrome,Android,Adwords,Google +,Google Maps,Blogger,Google Analytics)
  •   
  • IBM(DB2,Lotus,Websphere,Tivoli,Rational,AIX,i / OS,z / OS)
  •   
  • 亚马逊
  •   

请参阅本地化的在线数据浏览器:Locale Explorer

此档案中列出了一种短日期格式,本地化为sk-SK文化为d. M. yyyy。对于所有操作系统(Windows 7到Window 10)都是相同的。

与MS开发人员相关的博客:Locale Builder and Finnish or other locales.

Fiddler或其他在线代码运行器服务不是此事项的比较来源。
区域设置因系统而异。此外,这些国际格式会随着时间的推移而变化,并且取决于系统收到的更新(如果它完全收到了这些更新)。

在Windows 7和Windows 10中,sk-SK文化的默认“短日期”格式为d. M. yyyy
但是,如果进一步解析格式列表,则DateTime模式不匹配。

string format = CultureInfo.CreateSpecificCulture("sk-SK")
                           .DateTimeFormat.GetAllDateTimePatterns()[1]; 

在Windows 7中,DateTimePatterns列表中的第二个元素是d.M.yyyy
在Windows 10中,具有相同索引的元素是:dddd d. MMMM yyyy

Windows更新可能会更改任何语言环境的默认模式(无明确通知)。
可以理解,应用程序必须为特殊情况提供解析方法。或在格式化时参考用户的语言环境设置,而无需尝试为内部使用强制使用特定的模式。
日期/时间格式应仅用于演示。语言环境和用户设置确定该格式。系统用户可以决定使用与默认语言环境不同的格式。

此GitHub存储库包含CLDR数据库的更新的JSON:
CLDR Date Modern

有趣的是,用于API国际化的ECMAScript参考:
ECMAScript® 2017 Internationalization API Specification

MSDN全球化和本地化的最新指南(与UWP相关):
Globalization and localization
Globalize your date/time/number formats
Use the Multilingual App Toolkit 4.0

答案 1 :(得分:0)

我在Windows 10计算机上遇到了同样的问题,得到的是“ 31.1.208”。但是使用:

var format = "d.M.yyyy";

产生:31.1.2018

它似乎与 CultureInfo(“ sk-SK”)相似:

Console.WriteLine(date.ToString("d", new CultureInfo("de-DE")));

产生:31.01.2018

Console.WriteLine(date.ToString("d/M/yyyy", new CultureInfo("de-DE")));

产生:31.1.2018

(在Windows“控制面板-区域”中,我的设置为“英语-加拿大”,短日期设置为“ dd / MM / yyyy”。

它似乎是在.Net Framework中定义的-请参见其中的空格:

It seems to be defined in the .Net Framework - see the spaces there

我希望有帮助。