解析两位数日期

8
我正在尝试读取一种非常老旧格式的文件。其中日期格式被指定为yymmdd格式,其中[00,59]范围内的2位数年份被认为是21世纪的年份,[60,99]范围内的年份被认为是20世纪的年份,因此59代表2059年,60代表1960年。
我该如何在C#中将其解析为DateTime?我已经尝试过以下方法:
string str = ReadDateFromFile();
DateTime dt;    
DateTime.TryParseExact(str, "yyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt);

但默认的2位数年份规则将范围在[00, 29]内的值视为21世纪,而将范围在[30, 99]内的值视为20世纪。

有没有办法修改这种行为以满足我的需求,或者有没有其他技术可以使用?


1
在“TryParseExact”后添加一行代码,如果日期在2030年至2059年之间,则减去100年? - Adam V
在将字符串传递给TryParseExact之前,您可以根据自己决定的规则将字符串从2位数年份更改为4位数年份。 - John Hascall
考虑使用默认模板构建自己的'Calendar'类,并修改 'Calendar.TwoDigitYearMax'属性。 - Lasse V. Karlsen
3
这个帖子看起来很相似,使用了一个"Culture"对象。https://dev59.com/Z1rUa4cB1Zd3GeqPmK2D - Nikki9696
@Nikki9696 啊,我试着搜索了一下,但没有找到。我可能用错了词。 - Pharap
3个回答

7

只需在字符串后添加世纪前缀,然后更改格式字符串以解析四位数年份。

string str = ReadDateFromFile();
if (int.Parse(str.Substring(0, 2) >= 60)
   str = "19" + str;
else
   str = "20" + str;

DateTime dt;    
DateTime.TryParseExact(str, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt);

你可以修改Calendar.TwoDigitYearMax并使用修改后的区域设置进行解析。
var myCulture = (CultureInfo)CultureInfo.InvariantCulture.Clone();
myCulture.Calendar.TwoDigitYearMax = 2059;
DateTime dt;
DateTime.TryParseExact(str, "yyMMdd", myCulture, DateTimeStyles.None, out dt);

1
或者更简洁的写法 str = str.Substring(0, 2) >= 60 ? "19" + str : "20" + str; - bto.rdz
2
@bto.rdz 这真的更简洁吗?一眼看不出它在做什么。 - Cyral
2
@bto.rdz,您正在将字符串与整数进行比较。 - Hamid Pourjam

3

我认为在这种情况下,最好使用正则表达式,例如(\d{2})(\d{2})(\d{2})分别提取年、月和日,然后进行业务逻辑并从中构建新的日期时间对象。

如果这是您应用程序中的常见行为,则可以考虑将其作为扩展方法。


2
您可以使用正则表达式来解析日期的值,然后使用您自己的逻辑构造它:
var regex = new Regex(@"(?<year>\d{2})(?<month>\d{2})(?<day>\d{2})");
var match = regex.Match(str);
var year = int.Parse(match.Groups["year"].Value);
// Same for day and month
var date = new DateTime(
    year >= 60 ? 1900 + year : 2000 + year,
    month, day);
return date;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接