Jep*_*sen 4 .net windows datetime locale regional-settings
当我使用InvariantCulture来解析字符串时,同时使用:
var christ1 = DateTime.Parse("12/25/35", CultureInfo.InvariantCulture);
Run Code Online (Sandbox Code Playgroud)
和:
var christ2 = DateTime.ParseExact("12/25/35", "MM/dd/yy", CultureInfo.InvariantCulture);
Run Code Online (Sandbox Code Playgroud)
结果取决于应用程序在哪台计算机上运行。在一台机器上,我得到相当于:
20 年12 月 25日35
而在另一台机器上,我得到了一个世纪前的日期,即:
19 年12 月 25日35
到底是怎么回事?
在这种情况下,所谓的不变文化并不是那么一成不变。这取决于您的操作系统版本和当前用户在操作系统中的区域设置。
在 .NET 术语中,感兴趣的属性TwoDigitYearMax在日历上,因此检查CultureInfo.InvariantCulture.DateTimeFormat.Calendar.TwoDigitYearMax或(new GregorianCalendar()).TwoDigitYearMax. 覆盖的文档GregorianCalendar.TwoDigitYearMax。
在用户未更改区域设置的 Windows 10 版本 1809(“2018 年 10 月更新”、“Redstone 5”)机器上(更多内容见下文),属性TwoDigitYearMax为2029,因此您将获得19 年12 月 25日35 .
但是在 Windows 10 版本 1903(“2019 年 5 月更新”、“19H1”)上,相同的属性返回2049,因此您的结果是2019 年12 月 25日35。
但是,该值不仅取决于 Windows 版本。用户在区域设置中输入的内容也很重要。所以这并不是真正的“不变”。
您可以通过以下方式在控制面板中更改截止年份:
在较旧的 Windows 版本中,它可能是(粘贴自microsoft.com):
或者您可以直接使用 Windows 注册表,转到 key HKEY_CURRENT_USER\Control Panel\International\Calendars\TwoDigitYearMax,对于该键中的每个相关“值”,保持名称组件不变并将值的数据组件编辑为(通常的十进制字符串表示)您想要的截止年份. 如果用户从未从控制面板更改此设置,则最里面的两个键 ( Calendars\TwoDigitYearMax) 尚不存在。有关与注册表混合的常见警告适用。
一旦您在控制面板中更改了年份,在您进行这些更改后启动的每个 .NET 进程都会在TwoDigitYearMax通过InvarantCulture!
因此,如果您希望跨操作系统版本和用户首选项保持一致的行为,我认为您不能使用InvariantCulture. 相反,这样的事情可以工作:
var tmp = (CultureInfo)(CultureInfo.InvariantCulture.Clone());
tmp.DateTimeFormat.Calendar.TwoDigitYearMax = 2039; // any cutoff you need
// incorrect: tmp.Calendar.TwoDigitYearMax = 2039
var newInvariantCulture = CultureInfo.ReadOnly(tmp);
Run Code Online (Sandbox Code Playgroud)
然后newInvariantCulture在解析带有 2 位数年份的日期时使用该实例(您可以将它放在某个static readonly字段中)。
警告:每个都CultureInfo x带有两个不同的Calendars,它们可能具有不同的 2 位数年份最大值,即:
x.DateTimeFormat.Calendar.TwoDigitYearMax
!=
x.Calendar.TwoDigitYearMax
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
782 次 |
| 最近记录: |