为什么DateTime.ParseExact无法解析DateTime输出?

13

在 DateTime.ParseExact 格式化方面遇到问题时,我决定将 DateTime.ToString() 的输出作为 ParseExact 的输入,像这样:

DateTime date2 = new DateTime(1962, 1, 27);
string[] expectedFormats = { "G", "g", "f", "F", "D", "d", "M/d/yyy", "MM/dd/yyy", "MM-dd-yyy", "MMM dd, yyy", "MMM dd yyy", "MMMM dd, yyy", "MMMM dd yyy" };
bool parsed = false;

foreach (string fmt in expectedFormats)
{
    try
    {
        DateTime dtDateTime = DateTime.ParseExact(date2.ToString(fmt), fmt, new CultureInfo("en-US"));
        parsed = true;
    }
    catch (Exception)
    {
        parsed = false;
    }

    Console.WriteLine("[{0}] {1}", parsed,date2.ToString(fmt));
}

这是输出结果:

[True] 1/27/1962 12:00:00 AM
[True] 1/27/1962 12:00 AM
[True] Saturday, January 27, 1962 12:00 AM
[True] Saturday, January 27, 1962 12:00:00 AM
[True] Saturday, January 27, 1962
[True] 1/27/1962
[False] 1/27/1962
[False] 01/27/1962
[False] 01-27-1962
[False] Jan 27, 1962
[False] Jan 27 1962
[False] January 27, 1962
[False] January 27 1962

我需要做什么才能使ParseExact解析自定义格式的字符串?我是否期望DateTime能够基于相同的格式字符串摄入它自己的输出?


1
这不是 bug 的原因,但是提供信息:您正在将特定区域设置传递给 Parse,但是在 ToString 中使用默认区域设置。这本身会由于区域设置而导致问题。但是我已经测试过了,这不是唯一的问题。 - Marc Gravell
@Marc:我也测试了一下,将相同的文化传递给两种方法。我还尝试了CultureInfo.InvariantCulture,但没有成功。 - Brian Gideon
4个回答

11
这明显表明DateTime.ParseExactDatetime.ToString不是往返安全的。我不确定这算不算一个答案,但问题明显与3位数字年份格式yyy有关。由于1962年无法用3位数字表示,ToString被强制使用4位数字。显然,ParseExact没有足够聪明的逆转这个逻辑,而是寻找恰好3个数字。解决方法是使用yyyy替代yyy。建议将此提交为错误到Microsoft Connect网站,并观察结果。

0

0

我很惊讶看到这个,但是在 msdn 的文档中说:

您可以指定标准日期和时间格式说明符之一或有限的自定义日期和时间格式说明符组合

http://msdn.microsoft.com/en-us/library/2h3syy57.aspx

更新

您可以使用先前答案中提到的解决方法。


0

我拿了你的代码,只需将“yyy”更改为“yyyy”,就足以使它们全部返回“TRUE”(在进行任何更改之前,首先要复制“FALSE”)。

MSDN上的文档不清楚,但强调了需要指定每个组件的完整宽度(例如yyyy而不是yyy),而不使用不变的文化:

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

如果格式是不包含日期或时间分隔符的自定义格式模式(例如“yyyyMMdd HHmm”),则应该对提供程序参数使用固定区域性,并使用每个自定义格式说明符的最宽泛形式。例如,如果您想在格式模式中指定小时,则应指定更宽松的形式“HH”,而不是较窄的形式“H”。

空格、破折号和斜杠是日期/时间分隔符。 - Powerlord
1
我也看到了。但是Greg的示例代码确实使用了分隔符,所以这个条款似乎不适用。不过指出这一点仍然是很好的信息。 - Brian Gideon
我同意你们的观点,MSDN上的措辞表明日期/时间分隔符是关键因素,但是使用“yyyy”运行代码可以解决问题。 - Tom Carver

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接