C#使用InvariantCulture解析yyMM格式日期字符串为何出现不同结果
差异原因说明
本质是两位数年份的映射规则不固定
使用yy格式解析两位数年份时,.NET的解析逻辑依赖对应日历的TwoDigitYearMax属性:该属性定义了两位数年份能映射到的最大公元年,所有两位数年份会被自动匹配到[TwoDigitYearMax - 99, TwoDigitYearMax]这个100年区间内:
- 当设备上的
TwoDigitYearMax值为2029时,区间为1930~2029,两位数30落在区间起始位,解析结果为1930年 - 当设备上的
TwoDigitYearMax值为2039时,区间为1940~2039,两位数30落在区间内,解析结果为2030年
指定不变文化不能保证幂等的原因
不变文化的配置并非完全不可篡改,出现差异通常有两个原因:
- 不同.NET运行时的默认配置不同:早期.NET Framework版本中,不变文化的公历默认
TwoDigitYearMax为2029,.NET Core 3.0之后的版本将该默认值调整为2039,跨版本运行就会出现结果不一致 - 运行环境的全局配置被修改:如果设备上的其他代码全局修改过不变文化的日历属性,也会影响所有使用不变文化的日期解析逻辑
实现解析幂等的解决方案
要完全消除该歧义,推荐两种方案:
- 优先使用四位数年份格式
yyyy做解析,从数据源层面避免年份歧义 - 如果只能使用两位数年份,显式固定映射规则:
// 克隆不变文化并自定义年份映射规则 var customCulture = CultureInfo.InvariantCulture.Clone() as CultureInfo; // 固定最大映射年份为2099,所有两位数年份都会映射到2000~2099区间 customCulture.DateTimeFormat.Calendar.TwoDigitYearMax = 2099; var date = DateTime.ParseExact("3012", "yyMM", customCulture); Console.WriteLine(date);
内容的提问来源于stack exchange,提问作者Buda Gavril
相关产品推荐
相关产品推荐

