TimeSpan ToString格式化

117

只是好奇,是否有一种格式字符串可以用来输出类似于 "5小时3分钟30秒" 的东西?

例如(显然不正确)

myTimeSpan.ToString("hh mm ss")
7个回答

156

尝试:

myTimeSpan.ToString("h'h 'm'm 's's'")

(请注意,即使空格也需要用引号括起来——这就是我第一次尝试时出错的原因。)

当然,我假设你正在使用.NET 4-在此之前,TimeSpan不支持自定义格式字符串。

编辑:请注意,这不能超过24小时。另外请注意,还可以通过Noda Time等替代方式进行操作 :)


6
请查看 Dimension 的回答,因为这个回答无法正确格式化24小时或更长时间。 - Scott
"dd'd 'hh'h 'mm'm'" - 这对我有效。请注意,您需要使用撇号将格式化文本包含在内:“dd'已经过的天数'”。这里的dd是数据片段,“已经过的天数”是您自己的文本。 - Pavel Shkleinik

46

使用Jon Skeet的答案时要注意,特别是像这样的代码:

// 12 days, 23 hours, 24 minutes, 2 seconds.
TimeSpan span = new TimeSpan(12, 23, 24, 2);
// 27 hours, 24 minutes, 2 seconds
TimeSpan span2 = new TimeSpan(27,24,2);

string format = span.ToString("h'h 'm'm 's's'");
string format2 = span2.ToString("h'h 'm'm 's's'");
Console.WriteLine(format);
Console.WriteLine(format2);
Console.ReadLine();

你会得到这样的结果:

23h 24m 2s
3h 24m 2s

小时格式最多可以显示23小时。它不会显示27小时或将12天转换为小时,它只会将它们截断,就像它们从未存在过一样。

解决此问题的一种方法是创建一个扩展程序,检查TimeSpan的长度,并基于TimeSpan是否超过一年、一天等来创建格式。或者您可以始终显示天数,因为它们永远不会被截断:

string newFormat = span.ToString("d'd 'h'h 'm'm 's's'");

请注意,我是编程初学者。这只是基于观察得出的结论,之前我幸运地注意到它会显示所有小时,但实际上并不是。我说这个是因为我不知道是否有更好的解决方案,比如可以显示无限小时的另一种小时格式。

然而,我认为这种格式正在执行其预期的功能。您只需要意识到这一点。因此,发布了这篇文章。Jon Skeet的答案从未指示过这种格式只能显示日期类型格式的小时属性,其中小时最多可以是23。


15
这就是为什么TimeSpan中有“TotalHours”等属性。你可能想要使用这个表达式:Math.Floor(span.TotalHours) + span.ToString("'h 'm'm 's's'") - Aximili

22

如果你不幸没有使用.NET4:

string.Format("{0}h{1}m{2}s",
    myTimeSpan.Hours,
    myTimeSpan.Minutes,
    myTimeSpan.Seconds);

11
即使在较新版本的.NET中,对于需要支持大于24小时的代码,使用TotalHours仍然是最佳选择。 - CodesInChaos
1
我个人认为这样更好,因为你可以信任它。 - Chris Marisic
请注意,如果使用TotalHours,它是一个double类型,而不是像Hours一样的int类型,即它将显示小时的分数以及整个小时。 - Jinlye

18

在尝试了所有其他答案之后,使用 Xamarin.NET Portable 4.5 ,这是唯一能够正常工作的格式:

timespan.ToString("hh':'mm':'ss");

本质上,我将 : 放在单引号中进行转义。


1
这对我来说在2022年是有效的,使用.NET Standard 4.7.2。 - carloswm85

7

以下代码示例将帮助您解析和反向解析TimeSpan:

var t = TimeSpan.FromMilliseconds(450780);
double d1 = t.TotalSeconds;
string t3 = t.ToString(@"hh\:mm\:ss\.f",null);
var tt = TimeSpan.ParseExact(t3, @"hh\:mm\:ss\.f",null);
double d2 = tt.TotalSeconds;

参考资料:自定义TimeSpan格式字符串

OP想要特定的格式“5h 3m 30s”。 - redtetrahedron

6
如何拼接呢?
String oTime = myTimeSpan.ToString("h") + "h " +
               myTimeSpan.ToString("m") + "m " +
               myTimeSpan.ToString("s") + "s "

更新1:

您可以使用单引号进行转义:h'h 'm'm 's's'


12
如果你要使用串联,我个人认为最好使用HoursMinutesSeconds属性。在弄清引用方式后,我更倾向于使用自定义格式字符串。 - Jon Skeet

6

我有时觉得格式化字符串有点像正则表达式,因为当我以后回来看代码时,我会忘记细节。因此,我选择了以下方式,这样不太可能让我再次查看文档:

string FormatTimeSpan(TimeSpan timeSpan) =>
    $"{Math.Floor(timeSpan.TotalHours)}h {timeSpan.Minutes}m {timeSpan.Seconds}s";

在 C# 6 中引入的字符串插值,使得这一点变得非常清晰明了。

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