11

我正在尝试这种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 吗?我在这里想念什么?我怎样才能让它像我期望的那样工作?


更新:所以,似乎我们可能已经弄清楚为什么这会失败。似乎 theH实际上是抓取两位数,然后只为 留下一个数字,然后mm会失败。但是,有没有人知道如何更改此代码以便获得所需的结果?

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

4

6 回答 6

13

好的,所以我想我现在已经弄清楚了这一切,这要归功于更多的阅读、实验和其他有用的答案。发生的事情是Hms实际上会尽可能地抓取两位数字,即使其余格式没有足够的数字。因此,例如使用格式Hmm和数字123H将抓取12并且只剩下3。而mm需要两位数,所以它失败了。多达

因此,我目前的解决方案是仅使用以下三种格式:

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

我认为这应该既合理又可以接受:)

于 2010-01-06T21:37:31.947 回答
3

0123 012345

我猜当它找到一串这样的数字时,它会寻找 2/4/6 的长度。123应该是上午还是下午?0123 并不像那样模棱两可。

于 2010-01-06T21:04:58.920 回答
2

如果您不在自定义格式模式中使用日期或时间分隔符,请对提供程序参数使用不变的区域性以及每个自定义格式说明符的最宽形式。例如,如果要在模式中指定小时,请指定较宽的形式“HH”,而不是较窄的形式“H”

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

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

于 2010-01-06T21:13:04.153 回答
1

我可能是错的,但我怀疑这可能与格式字符串的“H”部分固有的歧义有关 - 即,给定字符串“123”,您可能正在处理小时“1”(01: 00) 或小时“12” (12:00);并且由于TryParseExact不知道哪个是正确的,所以它返回 false。

至于为什么该方法不提供“最佳猜测”:恐怕文档不在您这边。从DateTime.TryParse 上的 MSDN 文档(强调我的):

当此方法返回 时,如果转换成功转换失败,则包含与sDateTime中包含的日期和时间等效的值。如果sformat 参数为、为空字符串或不包含与 format中指定的模式相对应的日期和时间,则转换失败。此参数未初始化传递。DateTime.MinValuenull

于 2010-01-06T21:07:38.507 回答
1

引用 MSDN 的Using Single Custom Format Specifiers

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

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

那么,这应该% Hformats数组的第一个元素中吗?

希望这会有所帮助,最好的问候,汤姆。

于 2010-01-06T21:12:00.370 回答
0

对于 TryParseExact 方法,“123”和“12345”似乎是模棱两可的。例如,“12345”可以是 12:34:50 或 01:23:45。不过只是猜测。

于 2010-01-06T21:07:14.623 回答