为什么我的本地计算机可能会错误地格式化国际日期? [英] Why might my local machine be incorrectly formatting international dates?

查看:81
本文介绍了为什么我的本地计算机可能会错误地格式化国际日期?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个奇怪的人...

我刚刚看到(先前通过的)测试失败,原因是日期的字符串表示中有多余的空格.有问题的测试以前已经在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小提琴),此代码可以正确返回:

31.1.2018

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

31. 1. 2018

注意多余的空格!

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

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

解决方案

在Windows(与许多其他系统一样)中,语言环境日期/时间格式的来源是 Locale Explorer . /p>

短日期格式(已在sk-SK文化中以d. M. yyyy本地化)是此存档中列出的格式.对于所有操作系统(Windows 7到Window 10)都是相同的.

与MS开发人员相关的博客:语言环境生成器和芬兰语或其他语言环境.

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日期现代

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

MSDN全球化和本地化的最新指南(与UWP相关):
全球化和本地化
全球化日期/时间/数字格式
使用多语言应用工具包4.0

Here's a weird one...

I've just seen a (previously passing) test fail because of extra spaces in a string representation of a date. The test in question has previously passed in CI and on my local machine, but is now failing (on my local machine) because of extra spaces between segments of the date.

The same behaviour is exhibited by the following 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));
    }
}

In most places (including .NET Fiddle) this correctly returns:

31.1.2018

But on my machine, I now get:

31. 1. 2018

Note the extra spaces!

I'm confident that this was working as expected on my local PC just earlier this week, as I was using the project with this test in as a starting point for some experimentation with coverage tools. When I've resumed that experimentation this afternoon, the coverage file is no longer being produced due to the newly failing test.

What could have changed on my PC to cause this broken behaviour?

解决方案

In Windows (like many others System), the source for the Locale date/time formats is the Unicode Common Locale Data Repository (CLDR), which provides internationalization and localization support specific for software developers and linguists.
A Short list of meaningful users:

  • Microsoft (Windows, Office, Visual Studio etc.)
  • Apple (macOS, iOS, watchOS, tvOS, Apple Mobile Device Support and iTunes for Windows;
  • Google (Web Search, Chrome, Android, Adwords, Google+, Google Maps, Blogger, Google Analytics)
  • IBM (DB2, Lotus, Websphere, Tivoli, Rational, AIX, i/OS, z/OS)
  • Amazon

See the Online data explorer of the Localizations: Locale Explorer.

The Short Date format, localized to the sk-SK culture as d. M. yyyy, is the one listed in this archive. It's the same for all OS (Windows 7 to Window 10).

A MS Developer related blog: Locale Builder and Finnish or other locales.

Fiddler or other Online code-runners services are not a source of comparison on this matter.
Locales are different from system to system. Also, these international formats change over time and depend on the updates that a system receives (if it receives these updates at all).

In Windows 7 and Windows 10, the default Short Date format for the sk-SK Culture is d. M. yyyy.
But the DateTime patterns do not match, if the formats list is parsed further.

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

In Windows 7, the second element in the DateTimePatterns list is d.M.yyyy
In Windows 10, the element at the same index is: dddd d. MMMM yyyy

A Windows update may change the default pattern for any of the Locales (without explicit notification).
It's understood that applications must provide parsing means for special cases. Or refer to the user Locale settings when formatting, without trying to force a specific pattern for internal uses.
Date/Time formats should be used for presentation only. The Locale and the user settings determine that format. An user of a System may decide to use a different format than the default Locale.

This GitHub repository holds an updated JSON of the CLDR database:
CLDR Date Modern

Also interesting, the ECMAScript reference for API internationalization:
ECMAScript® 2017 Internationalization API Specification

MSDN latest guidelines for Globalization and localization (UWP related):
Globalization and localization
Globalize your date/time/number formats
Use the Multilingual App Toolkit 4.0

这篇关于为什么我的本地计算机可能会错误地格式化国际日期?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆