14

我使用自由格式日期作为搜索语法的一部分。我需要从字符串中解析日期,但只保留实际指定的日期部分。例如,“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

4 回答 4

2

Parse parses a whole lot of stuff that no sane person would enter as a date, like "January / 2010 - 21 12: 00 :2". I think you'll have to write your own date parser if you want to know what exactly the user entered.

Personally I would do it like KeithS suggested: Parse the string with Parse and only call your own parse function if there's a 0 in one of the fields of the DateTime object. There are not that that possibilities you need to check for, because if the day is 0, the time will be 0, too. So start checking year, month, day, etc..

Or simply instruct the user to use specific formats you recognize.

于 2011-03-02T15:02:18.160 回答
2

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

您也可以使用正则表达式自己消化日期字符串。同样,您将需要不同的正则表达式(或非常复杂的单个正则表达式),但当然也可以通过这种方式将字符串分开;然后你知道你实际拥有什么。

于 2011-03-01T17:11:27.800 回答
0

本质上,我需要 DateTime.Parse("November, 2010") == {11/-1/2010 -1:-1:-1}; 然后我可以看到缺少日期部分并计算覆盖整个月的日期范围。

你想要的是一个非法的 DateTime 因为你不能有一个负的小时/秒/分钟/天值。如果您想返回除合法日期时间之外的其他内容,则必须编写自己的方法,该方法不返回日期时间。

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

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

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

于 2011-03-01T17:11:51.320 回答
0

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

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

我知道这是非常具有启发性的,但它是一种快速简单的解决方案,适用于大多数情况。我在Sharp-datefinder库中的DateFinder.DayExists()andDateFinder.YearExists()方法中用C# 编写了这个算法。

于 2016-09-14T21:01:51.490 回答