DateTime.TryParseExact 未按预期工作
谁能解释为什么以下代码片段返回 true?
根据“d”自定义格式说明符的文档,“一位数日期的格式没有前导零。”那么,当我给它一个带前导零的个位数日期时,为什么 TryParseExact 不会失败呢?
DateTime x;
return DateTime.TryParseExact
(
"01/01/2001",
@"d\/MM\/yyyy",
null,
System.Globalization.DateTimeStyles.None,
out x
);
更新
我想也许我最初不清楚。我真正想要了解的是:为什么 TryParseExact 接受一些不完全匹配的值?从我见过的所有文档中,'d' 匹配 '01' 和 '1'就像“MM”匹配“March”和“03”一样是一个错误。 这里的问题不是值相等,而是它们与格式不匹配。
相关的文档片段是:
来自 TryParseExact:字符串表示形式的格式必须与指定的格式完全匹配。
来自“d”说明符:A单位数字日期的格式不带前导零。
对我来说,“01”有一个前导 0 似乎非常清楚,因此与“不完全匹配” d'。
Can anyone explain why the following snippet returns true?
According to the docs for The "d" custom format specifier, "A single-digit day is formatted without a leading zero." So why doesn't TryParseExact fail when I give it a single-digit day with a leading zero?
DateTime x;
return DateTime.TryParseExact
(
"01/01/2001",
@"d\/MM\/yyyy",
null,
System.Globalization.DateTimeStyles.None,
out x
);
UPDATE
I think maybe I was unclear originally. What I am really trying to get at is: Why does TryParseExact accept some values that don't match exactly? from all of the documentation I have seen, 'd' matching '01' and '1' is just as much a bug as if 'MM' matched 'March' as well as '03'. The issue here isn't that the values are equivalent, its that they don't match the format.
The relevant snippets of documentation are:
From TryParseExact: The format of the string representation must match a specified format exactly.
From The 'd' Specifier: A single-digit day is formatted without a leading zero.
It seems abundantly clear to me that '01' has a leading 0, and therefore doesn't exactly match 'd'.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
来自 DateTimeParse.ParseByFormat() 中的 .NET 4 源代码:
解析器将“d”和“dd”集中在一起。
From the .NET 4 source in DateTimeParse.ParseByFormat():
The parser lumps "d" and "dd" together.
看来这种行为是设计使然的,我认为它的工作方式是为了与其他字符串格式选项保持一致。
采取以下示例:
在第一部分中,
ToString()
输出 10 月 12 日的两位数日期,因为仅写出一位数日期没有多大意义(以及哪个数字将它选择 1 还是 2?)。因此,由于“d”在转换为字符串时代表一个或两个数字天,因此在转换回DateTime.如果没有,在我的示例中
TryParseExact
中转换回DateTime
将会失败,这绝对不是预期的行为。我想说,如果您确实需要完全匹配 ad/MM/yyyy 格式,您可能可以使用正则表达式来验证字符串,然后通过
Parse
、TryParse
传递它或TryParseExact
(取决于您的正则表达式有多好,因为如果您想使用Parse
,它必须处理闰年、30/31 天等)。It appears that behavior is by design, and I think it works that way to be consistent with other string formatting options.
Take the following example:
In the first part,
ToString()
outputs a two digit day for October 12th, because it wouldn't make much sense to just write out a single digit day (and which digit would it pick, the 1 or the 2?). So since the "d" represents one OR two digit days when converting to a string, it would have to work the same way when converting back toDateTime
. If it didn't, the conversion back toDateTime
inTryParseExact
in my example would fail, and that would definitely not be an expected behavior.I would say that if you really need to match a d/MM/yyyy format exactly, you could probably use a regex to validate the string and then pass it through
Parse
,TryParse
orTryParseExact
(depending on how good your regex is, since it would have to handle leap years, 30/31 days, etc if you wanted to useParse
).我想说它不会失败,因为
TryParseExact
足够聪明,知道 '01' == '1'。I'd say it doesn't fail because
TryParseExact
is smart enough to know that '01' == '1'.我猜
TryParseExact
只是在这种情况下尝试变得灵活。但是,当您使用格式说明符将日期转换为字符串时,“d”与“dd”应该并且会像所宣传的那样工作。TryParseExact
is just trying to be flexible in this case I guess. But the "d" vs "dd" should and would work as advertised when you are converting date to string using a format specifier.因为单个“d”意味着您的 DateTime 值将被转换为尽可能短的值,即如果没有必要,则不带前导零。我想当您从字符串转换为 DateTime 时它不应该失败,因为 TryParseExact 格式字符串的主要目的是帮助转换为 DateTime,即它充当提示,它并不是为了验证字符串格式。
如果您仍然需要硬核,您可以使用 RegEx字符串格式验证。
Because a single 'd' means that your DateTime value will be converted to as short value as possible, i.e. without leading zero if there's no necessity for it. I suppose it shouldn't fail when you're converting from string to DateTime because the main purpose of TryParseExact's format string is to help to convert to DateTime, i.e. it serves like a hint, it's not intended to validate string format.
You can use RegEx if you still need hardcore string format validation.