5

考虑这段代码(预装了一个例子):

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 ));

这代表了我至少从 .NET 1.1 开始工作的一段代码。

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

30.00:00:28.3580246

但现在我看到它在 .NET 4 中死掉并显示错误消息:

Input string was not in a correct format.

所以就好像 .NET 4 突然决定它不喜欢这种格式的时差。换行,说

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

有同样的效果。

现在我注意到的是,如果我只做默认设置.ToString(),我会得到相同的输出。我相信思考过程是,这是针对未来版本中更改默认格式的保险单。但现在看起来这甚至不是一个选择。

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

4

5 回答 5

6

有一个配置开关可以恢复TimeSpan的旧行为。

于 2010-07-30T15:53:42.793 回答
3

An alternative to the configuration switch is a format change that is compatible with previous versions.

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

This solution is detail here.

于 2010-08-30T12:40:46.663 回答
1

事实上,您在代码中使用的复合格式字符串根本没有任何效果,因为TimeSpan 支持自定义格式字符串(.NET < 4.0)。

30.00:00:28.3580246,无论格式字符串如何,您的 TimeSpan 都会一直被格式化。

来自 MSDN:

在 .NET Framework 的早期版本中,TimeSpan 结构没有实现 IFormattable 并且不支持格式字符串。

但是,许多开发人员错误地认为 TimeSpan 确实支持一组格式字符串,并通过 String.Format 等方法将它们用于复合格式化操作。通常,如果一个类型实现了 IFormattable 并支持格式字符串,则使用不受支持的格式字符串调用格式化方法通常会引发 FormatException。但是,因为 TimeSpan 没有实现 IFormattable,所以运行时忽略了格式字符串,而是调用了 TimeSpan.ToString() 方法。这意味着,尽管格式字符串对格式化操作没有影响,但它们的存在不会导致 FormatException。

于 2014-08-25T17:31:54.150 回答
1

正如 Mitch Wheat 和 Saeb Amini 在他们的 回答中指出的那样,在 .NET 4.0 之前TimeSpan没有实现。IFormattable因此,格式字符串对输出没有影响TimeSpan.ToString(),因为它们被忽略了。

但是,因为 TimeSpan 没有实现 IFormattable,所以运行时忽略了格式字符串,而是调用了 TimeSpan.ToString 方法。这意味着,尽管格式字符串对格式化操作没有影响,但它们的存在不会导致 FormatException。

资源

也就是说,如果您希望TimeSpan在 .NET 框架的所有版本中格式化一个值,最好将TimeSpan值转换为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
于 2015-01-02T05:03:24.217 回答
0

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

使用 .NET 2 也会引发 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);
于 2010-07-30T15:47:10.930 回答