在没有指定所有值的情况下解析日期

时间:2011-03-01 17:00:10

标签: c# datetime date-parsing

我使用自由格式日期作为搜索语法的一部分。我需要从字符串中解析日期,但只保留实际指定的日期部分。例如,“2010年11月1日”是特定日期,但“2010年11月”是“2010年11月1日”至“2010年11月30日”的日期范围。

不幸的是,DateTime.Parse和朋友将这些日期解析为同一个DateTime

DateTime.Parse("November 1, 2010") // == {11/1/2010 12:00:00 AM}
DateTime.Parse("November, 2010") // == {11/1/2010 12:00:00 AM}

我需要知道DateTime的哪些部分实际被解析,哪些是解析器猜到的。基本上,我需要DateTime.Parse("November, 2010") == {11/-1/2010 -1:-1:-1};然后我可以看到缺少日期部分并计算整个月的日期范围。

(在内部,C#有DateTimeParseDateTimeResult类来解析日期并准确保存我需要的信息,但是当日期返回到公共接口时,它被剥离了。我宁愿避免反思这些课程,除非那是真正唯一的途径。)

有没有办法让DateTime.Parse告诉我用它来解析日期的格式?或者返回的DateTime是否有未指定部分的占位符?我也愿意使用另一个日期解析器,但我希望它与内部解析器一样可靠且区域灵活。提前谢谢。

编辑:我也尝试了ParseExact,但枚举Parse可以处理的所有格式似乎几乎不可能。 Parse实际上接受的格式多于DateTimeFormatInfo.GetAllDateTimePatterns返回的格式,这与我可以找到的规范源代码相同。

4 个答案:

答案 0 :(得分:2)

您可以尝试使用TryParseExact(),如果数据字符串不是指定的确切格式,则会失败。尝试一堆不同的组合,当一个成功时你知道日期所在的格式,因此你知道日期中那些不存在的部分以及解析器填充的默认部分。缺点是您必须预测用户将如何输入日期,因此您可以完全期待。

您也可以使用Regex自己消化日期字符串。同样,你需要不同的正则表达式(或者一个非常复杂的正则表达式),但是当然也可以将这个字符串拉开;那你知道你到底有什么。

答案 1 :(得分:2)

Parse解析了许多没有理智的人作为约会输入的内容,例如"January / 2010 - 21 12: 00 :2"。我想如果你想知道用户输入了什么,你必须编写自己的日期解析器。

我个人会像KeithS建议的那样:用Parse解析字符串,如果DateTime对象的某个字段中有0,则只调用自己的解析函数。没有你需要检查的可能性,因为如果日期是0,那么时间也将是0。所以开始检查年,月,日等。

或者只是指示用户使用您认可的特定格式。

答案 2 :(得分:0)

  

基本上,我需要   DateTime.Parse(“2010年11月”)==   {11 / -1 / 2010 -1:-1:-1};我可以看到   那天的部分缺失了   计算覆盖日期的范围   整个月。

你想要的是非法的DateTime,因为你不能有负的小时/秒/分钟/天值。如果你想返回一些合法的DateTime,你必须编写自己的方法,而不是返回DateTime。

  

有没有办法获得   DateTime.Parse告诉我哪种格式   它用于解析日期?或者可以   返回DateTime有占位符   对于未指定的零件?我也是开放的   使用另一个日期解析器,但我会   喜欢这样可靠   locale-flexible作为内部的。

看看http://msdn.microsoft.com/en-us/library/w2sa9yss.aspx

您将不得不手动跟踪输入的内容以执行此任务。唯一的解决方案是确保输入的格式正确。

答案 3 :(得分:0)

我使用这种方法返回到原始字符串,以检查是否存在日期和年份:

  • 对于,如果指定了日期,则原始字符串必须包含1作为整数。因此,拆分字符串并查找1.当月份为1月(#1个月)时,唯一的例外发生,因此您应检查原始字符串中的两个1或1以及“1月”或“1月”。 / LI>
  • 对于,原始字符串必须包含可以是一年的数字(例如,从1900年到2100年)。其他可能性可能是使用撇号,或类似02-10-16之类的东西,你可以通过正好有三个数字来识别它们。

我知道这是非常启发式的,但它是一种快速而简单的解决方案,适用于大多数情况。我使用DateFinder.DayExists()库中的DateFinder.YearExists()sharp-datefinder方法在C#中编码了此算法。