日期时间字符串解析

11
我已经为解析ASCII文件创建了一个通用解析器。当我想解析日期时,我使用DateTime对象中的ParseExact函数进行解析,但是年份却出现了问题。
要解析的文本是“090812”,使用parseExact字符串“yyMMdd”。
我希望得到一个DateTime对象,显示为“12/8-2009”,但我得到的是“12/8-1909”。 我知道,我可以通过之后解析并修改年份来实现一个丑陋的解决方案。
有没有人知道一种聪明的方法来解决这个问题?
提前致谢。。
Søren

文档和其他帖子建议这应该适用于您提供的日期(例如,09年的2009年)。您能发布一下您正在进行的确切ParseExact调用吗? - Joe
1
更多信息请参见:http://msdn.microsoft.com/zh-cn/library/system.globalization.gregoriancalendar.tofourdigityear.aspx - Joe
3个回答

19

一种从理论上优雅的方法是:更改用于解析文本的DateTimeFormatInfo使用的CalendarTwoDigitYearMax属性。例如:

CultureInfo current = CultureInfo.CurrentCulture;
DateTimeFormatInfo dtfi = (DateTimeFormatInfo) current.DateTimeFormat.Clone();
// I'm not *sure* whether this is necessary
dtfi.Calendar = (Calendar) dtfi.Calendar.Clone();
dtfi.Calendar.TwoDigitYearMax = 1910;

然后在调用 DateTime.ParseExact 的时候使用 dtfi 参数。

实现这个的实际方法是:在输入的开头添加 "20",并使用 "yyyyMMdd" 进行解析。


我有点喜欢你的理论解决方案。DateTimeFormatInfo 只需要一次设置即可。它还允许使用不同的截止日期,而不仅仅是假设所有日期都在本世纪。 - Thorarin
看起来不错。 我不太确定你想做什么。 但是,无论如何,dtfi.Calendar.TwoDigitYearMax 只能设置为大于99的数字.. :-(.. 而且我对只在前面添加“20”的解决方案并不满意,因为我不能保证这不会用于查看2000年以前的旧数据。 - MüllerDK
@MullerDK:抱歉,它应该设置为2000...或者如果你想要100812成为1910等等,可以设置为1910。 - Jon Skeet
4
(对1910年的代码进行了编辑。)你能看到的最早年份是什么?在某个时候,你会遇到一个模糊的格式……你不能仅用两位小数表示超过100年的范围。请注意,如果你将它设置为1910年,那么下一年你就需要将它设置为1911年等等。你可能想使用 DateTime.Now.Year - 100 - Jon Skeet
1
FYI,DateTimeFormatInfo.Clone()确实会调用this.Calendar.Clone()。 - daveidmx

2

您需要确定适合您数据的某种阈值日期。如果解析的日期在此日期之前,则添加100年。一种安全的方法是在输入字符串前缀中添加适当的世纪。在本例中,我选择了1970年作为截止日期:

string input = ...;
DateTime myDate;

if (Convert.ToInt32(input.Substring(0, 2)) < 70)
    myDate = DateTime.ParseExact("20" + input, ...);
else
    myDate = DateTime.ParseExact("19" + input, ...); 

Jon Skeet也发布了一个不错的例子,使用DateTimeFormatInfo,我曾经短暂地忘记了它 :)


2

如果您确定所有的源日期都是本世纪,那么您可以使用parseExact来处理以“20”为前缀的源字符串。


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