日期时间字符串解析

Posted

技术标签:

【中文标题】日期时间字符串解析【英文标题】:DateTime string parsing 【发布时间】:2009-08-14 11:14:28 【问题描述】:

我制作了一个用于解析 ascii 文件的通用解析器。 当我想解析日期时,我使用 DateTime 对象中的 ParseExact 函数来解析,但是我遇到了年份问题。

要解析的文本是“090812”和 parseExact 字符串“yyMMdd”。

我希望得到一个显示“12/8-2009”的 DateTime 对象,但我得到的是“12/8-1909”。 我知道,我可以通过事后解析来做出一个丑陋的解决方案,从而修改年份..

有人知道解决这个问题的聪明方法吗??

提前谢谢..

索伦

【问题讨论】:

文档和其他帖子表明这应该适用于您提供的日期(例如 09 的 2009 年)。你能发布你正在做的确切 ParseExact 调用吗? 更多信息在这里:msdn.microsoft.com/en-us/library/… 【参考方案1】:

理论上优雅的做法:更改 Calendar 用于解析文本的 DateTimeFormatInfoTwoDigitYearMax 属性。例如:

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 只是一次设置。它还允许不同的截止日期,而不是仅仅假设一切都在本世纪。 看起来不错..不太确定,您要做什么..!?但无论如何,dtfi.Calendar.TwoDigitYearMax 只能设置为 99 以上的数字.. :-(.. 而且我对只在前面添加“20”的解决方案不满意,因为我不能保证这不是 beeing用于查看旧数据 @MullerDK:抱歉,如果您希望 100812 为 1910 等,它应该设置为 2000...或者可能是 1910。 (编辑了 1910 年的代码。)您最早会看到哪一年?在某些时候,你会得到一个模棱两可的格式......你不能只用两位小数来表示超过 100 年的范围。请注意,如果您将其设置为 1910,那么明年您需要将其设置为 1911 等。您可能需要使用 DateTime.Now.Year - 100 仅供参考 DateTimeFormatInfo.Clone() 确实调用 this.Calendar.Clone()【参考方案2】:

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

【讨论】:

【参考方案3】:

您需要确定适合您数据的某种阈值日期。如果解析的日期早于该日期,则添加 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 发布了一个很好的示例,我暂时忘记了 :)

【讨论】:

以上是关于日期时间字符串解析的主要内容,如果未能解决你的问题,请参考以下文章

日期时间字符串解析

单独的日期字符串和时间字符串组合成一个解析日期时间戳

将RSS日期/时间字符串解析为日期/时间对象

Tabulator 5.0 - 解析日期时间 luxon - 日期时间 ISO 8601

Globalize.js - 如何解析日期和时间而不仅仅是日期

java 8及以下版本的日期时间格式化与解析