日期时间字符串解析
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
用于解析文本的 DateTimeFormatInfo
的 TwoDigitYearMax
属性。例如:
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
发布了一个很好的示例,我暂时忘记了 :)
【讨论】:
以上是关于日期时间字符串解析的主要内容,如果未能解决你的问题,请参考以下文章
Tabulator 5.0 - 解析日期时间 luxon - 日期时间 ISO 8601