解析未指定所有值的日期

发布于 2024-10-19 22:18:01 字数 1028 浏览 6 评论 0 原文

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

I'm using free-form dates as part of a search syntax. I need to parse dates from strings, but only preserve the parts of the date that are actually specified. For instance, "november 1, 2010" is a specific date, but "november 2010" is the range of dates "november 1, 2010" to "november 30, 2010".

Unfortunately, DateTime.Parse and friends parse these dates to the same DateTime:

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

I need to know which parts of the DateTime were actually parsed and which were guessed by the parser. Essentially, I need DateTime.Parse("November, 2010") == {11/-1/2010 -1:-1:-1}; I can then see that the day portion is missing and calculate the range of dates covering the whole month.

(Internally, C# has the DateTimeParse and DateTimeResult classes that parse the date and preserve exactly the information I need, but by the time the date gets back to the public interfaces it's been stripped off. I'd rather avoid reflecting into these classes, unless that's really the only route.)

Is there some way to get DateTime.Parse to tell me which format it used to parse the date? Or can the returned DateTime have placeholders for unspecified parts? I'm also open to using another date parser, but I'd like it to be as reliable and locale-flexible as the internal one. Thanks in advance.

EDIT: I've also tried ParseExact, but enumerating all of the formats that Parse can handle seems nearly impossible. Parse actually accepts more formats than are returned by DateTimeFormatInfo.GetAllDateTimePatterns, which is about as canonical a source as I can find.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦归所梦 2024-10-26 22:18:01

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

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

You could try using TryParseExact(), which will fail if the data string isn't in the exact format specified. Try a bunch of different combinations, and when one succeeds you know the format the date was in, and thus you know the parts of the date that weren't there and for which the parser filled in defaults. The downside is you have to anticipate how the user will want to enter dates, so you can expect exactly that.

You could also use a Regex to digest the date string yourself. Again, you'll need different regexes (or a REALLY complex single one), but it is certainly possible to pull the string apart this way as well; then you know what you actually have.

停顿的约定 2024-10-26 22:18:01

Parse 会解析大量任何理智的人都不会输入的日期内容,例如 “January / 2010 - 21 12: 00 :2”。我认为如果您想知道用户到底输入了什么,您必须编写自己的日期解析器。

就我个人而言,我会像 KeithS 建议的那样:使用 Parse 解析字符串,并且仅在 DateTime 对象的字段之一中有 0 时调用您自己的解析函数。您无需检查这种可能性,因为如果日期为 0,则时间也将为 0。因此,开始检查年、月、日等。

或者简单地指示用户使用您识别的特定格式。

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.

誰ツ都不明白 2024-10-26 22:18:01

基本上,我需要
DateTime.Parse("2010 年 11 月") ==
{11/-1/2010 -1:-1:-1};然后我就可以看到
白天部分缺失并且
计算涵盖的日期范围
整个月。

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

有什么办法可以得到
DateTime.Parse 告诉我哪种格式
它用来解析日期?或者可以
返回的日期时间有占位符
对于未指定的部分?我也开着
使用另一个日期解析器,但我会
喜欢它一样可靠和
locale-flexible 作为内部的。

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

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

Essentially, I need
DateTime.Parse("November, 2010") ==
{11/-1/2010 -1:-1:-1}; I can then see
that the day portion is missing and
calculate the range of dates covering
the whole month.

What you want is an illegal DateTime because you cannot have a negative hours/seconds/minute/day values. If you want to return something else other then a legal DateTime you have to write your own method which does NOT return a DateTime.

Is there some way to get
DateTime.Parse to tell me which format
it used to parse the date? Or can the
returned DateTime have placeholders
for unspecified parts? I'm also open
to using another date parser, but I'd
like it to be as reliable and
locale-flexible as the internal one.

Take a look here http://msdn.microsoft.com/en-us/library/w2sa9yss.aspx

You are going to have to manually keep track of what is entered to do this task. The only solution is to make sure the input is in the correct format.

淡忘如思 2024-10-26 22:18:01

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

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

我知道这是相当启发式的,但它是一个快速而简单的解决方案,适用于大多数情况。我在 < 中用 C# 编写了该算法代码>DateFinder.DayExists()DateFinder.YearExists() 方法>sharp-datefinder 库。

I used this method that goes back to the original string in order to check for existence of the day and the year:

  • For days, the original string must contain a 1 as integer if the day was specified. So, split the string and look for a 1. The only exception occurs when the month is January (#1 month), so you should check for two 1s or a 1 and "January" or "Jan" in the original string.
  • For years, the original string must contain a number that can be a year (say, from 1900 to 2100). Other possibilities may be the use of an apostrophe, or things like 02-10-16, which you can recognize by the fact that there are exactly three numbers.

I know that this is pretty heuristic, but it's a fast and simple solution that works in most cases. I coded this algorithm in C# in the DateFinder.DayExists() and DateFinder.YearExists() methods in the sharp-datefinder library.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文