代码之家  ›  专栏  ›  技术社区  ›  Tom Kidd

为什么这个特定的TimeSpan格式字符串在.NET4中停止工作?

  •  5
  • Tom Kidd  · 技术社区  · 14 年前

    考虑下面的代码(用一个例子来说明):

    DateTime dt1 = DateTime.Parse("7/30/2010 9:33:29.1234567 AM");
    DateTime dt2 = DateTime.Parse("6/30/2010 9:33:00.7654321 AM");
    
    TimeSpan ts = dt1 - dt2;
    
    Console.WriteLine(string.Format( "{0:d.hh:mm:ss.ff}", ts ));
    

    它在1.1到3.5中运行良好,输出如下(对于这些虚拟输入):

    30.00:00:28.3580246
    

    Input string was not in a correct format.

    所以就好像.NET4突然决定不喜欢这种时差格式。把线路改成

    Console.WriteLine(string.Format( "{0}", ts.ToString("d.hh:mm:ss.ff") ));
    

    有同样的效果。

    现在我注意到如果我只做默认值 .ToString()

    有人知道为什么会发生这种变化吗?如果我做错了什么,或者是否有一个最佳实践方法来完成我想要完成的任务?

    5 回复  |  直到 14 年前
        1
  •  6
  •   Mitch Wheat    14 年前
        2
  •  3
  •   wilk    14 年前

    Console.WriteLine(string.Format( "{0:hh\\:mm\\:ss.ff}", ts )); 
    

    这个解决方案非常详细 here .

        3
  •  1
  •   Community CDub    4 年前

    一点效果都没有 ,因为 TimeSpan 支持自定义格式字符串(.NET<4.0).

    30.00:00:28.3580246 不考虑格式字符串。

    来自MSDN:

    不实现IFormattable,不支持格式字符串。

    然而, 许多开发人员错误地认为TimeSpan确实支持 使用String.Format等方法的操作。通常,如果 实现IFormattable并支持格式化字符串、调用 IFormattable,运行时忽略格式字符串,而是调用 这意味着,虽然

        4
  •  1
  •   Community CDub    4 年前

    正如米奇·麦特和萨伯·阿米尼在 their answers TimeSpan IFormattable 在.NET 4.0之前。因此,格式字符串 无影响 TimeSpan.ToString() 输出,因为它们被忽略了。

    但是,由于TimeSpan没有实现IFormattable, 运行时 忽略了格式字符串 而是调用TimeSpan.ToString方法

    Source

    也就是说,你想要格式化一个 在.NET framework的所有版本中,转换 时间跨度 DateTime

    DateTime dt1 = DateTime.Parse("7/30/2010 9:33:29.1234567 AM");
    DateTime dt2 = DateTime.Parse("6/30/2010 9:33:00.7654321 AM");
    
    TimeSpan ts = dt1 - dt2;
    
    Console.WriteLine(String.Format("{0:d.hh:mm:ss.ff}", new DateTime(ts.Ticks))) 
    // prints 30.00:00:28.36
    
        5
  •  0
  •   Florian    14 年前

    我粘贴了你的代码,这似乎是一个文化问题:

    对于.NET2,也会引发FormatException

    如果我指定了美国区域性(默认情况下,区域性为fr fr),则代码可以工作:

    DateTime dt1 = DateTime.Parse("7/30/2010 9:33:29.1234567 AM", CultureInfo.GetCultureInfo("en-US"));
    

    还可以指定一个不变区域性以忽略该区域性

    DateTime dt1 = DateTime.Parse("7/30/2010 9:33:29.1234567 AM", CultureInfo.InvariantCulture);