.NET:为什么TryParseExact在Hmm和Hmmss上失败?

时间:2010-01-06 21:01:54

标签: c# .net datetime parsing datetime-format

我正在尝试使用DateTime.TryParseExact方法,而且我遇到了一个我无法得到的案例。我有一些格式和一些主题要解析,每个格式应完全匹配其中一种格式:

var formats = new[]
     {
         "%H",
         "HH",
         "Hmm",
         "HHmm",
         "Hmmss",
         "HHmmss",
     };

var subjects = new[]
     {
         "1",
         "12",
         "123",
         "1234",
         "12345",
         "123456",
     };

然后我尝试解析它们并打印出结果:

foreach(var subject in subjects)
{
    DateTime result;
    DateTime.TryParseExact(subject, formats, 
        CultureInfo.InvariantCulture, 
        DateTimeStyles.NoCurrentDateDefault,
        out result);

    Console.WriteLine("{0,-6} : {1}", 
        subject,
        result.ToString("T", CultureInfo.InvariantCulture));
}

我得到以下内容:

1      : 01:00:00
12     : 12:00:00
123    : 00:00:00
1234   : 12:34:00
12345  : 00:00:00
123456 : 12:34:56

而我的问题是......为什么它在123和12345失败了?不应该成为01:23:00和01:23:45吗?我在这里错过了什么?我怎样才能让它像我期望的那样工作?


更新: 所以,好像我们可能已经弄明白为什么这种失败了。好像H实际上抓住了两个数字,然后只为mm留下一个数字,然后失败。但是,有没有人知道如何更改此代码以便我得到我想要的结果?

另一个更新: 认为我现在找到了合理的解决方案。添加它作为答案。将在2天内接受它,除非其他人想出更好的一个。谢谢你的帮助!

6 个答案:

答案 0 :(得分:13)

好的,所以我想我现在已经想到这一切了,感谢更多的阅读,实验和其他有用的答案。发生的事情是 H m s 实际抓住两位数,即使其余数字不足的格式。例如,格式为 Hmm ,数字 123 H 将抓取 12 ,只有一个 3 离开了。并且 mm 需要两位数,因此失败。 Tadaa

所以,我的解决方案目前只使用以下三种格式:

var formats = new[]
    {
        "%H",
        "Hm",
        "Hms",
    };

由于我的问题中的其余代码保持不变,我会得到这样的结果:

1      : 01:00:00
12     : 12:00:00
123    : 12:03:00
1234   : 12:34:00
12345  : 12:34:05
123456 : 12:34:56

我认为应该合理且可以接受:)

答案 1 :(得分:3)

0123 012345

我猜它在找到一串这样的数字时会查找2/4/6的长度。 123应该是AM还是PM? 0123并不像那样含糊不清。

答案 2 :(得分:2)

  

如果您不使用日期或时间   自定义格式模式中的分隔符,   使用不变的文化   provider参数和最宽的形式   每个自定义格式说明符。对于   例如,如果要指定小时数   在模式中,指定更宽   形式,“HH”,而不是更窄   形式,“H”

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

正如其他人所指出的那样,H是模棱两可的,因为它意味着每天10小时,其中HH为12

答案 3 :(得分:1)

我可能错了,但我怀疑它可能与格式字符串“H”部分固有的模糊性有关 - 也就是说,给定字符串“123”,你可能会处理小时“1” (01:00)或小时“12”(12:00);由于TryParseExact不知道哪个是正确的,因此返回false。

至于为什么这个方法没有提供“最佳猜测”:我担心文档不在你这边。来自MSDN documentation on DateTime.TryParse(强调我的):

  

当此方法返回时,包含   DateTime值等于日期   和 s 中包含的时间,如果是   转换成功,或   DateTime.MinValue如果   转换失败。转换   如果 s 格式,则会失败   参数是null,是空字符串,或者不是   包含日期和时间   对应于中指定的模式   格式。传递此参数   初始化。

答案 4 :(得分:1)

引用MSDN的使用单一自定义格式说明符

自定义日期和时间格式字符串由两个或多个字符组成。例如,如果格式字符串仅包含说明符h,则格式字符串将被解释为标准日期和时间格式说明符。但是,在这种特殊情况下,抛出异常是因为没有标准的日期和时间格式说明符。

要使用单个自定义日期和时间格式说明符,请在日期和时间说明符之前或之后包含空格,或者在单个自定义日期和时间说明符之前包含百分比(%)格式说明符。例如,格式字符串“h”和“%h”被解释为自定义日期和时间格式字符串,显示由当前日期和时间值表示的小时。请注意,如果使用空格,它将在结果字符串中显示为文字字符。

那么,% H数组的第一个元素中是formats吗?

希望这有帮助, 最好的祝福, 汤姆。

答案 5 :(得分:0)

“123”和“12345”似乎与TryParseExact方法不明确。例如,“12345”可以是12:34:50或01:23:45。只是一个猜测。