如何在.NET 中使用自定义格式设置 String.Format TimeSpan 对象的格式?

TimeSpan对象格式化为具有自定义格式的字符串的推荐方法是什么?

139363 次浏览

一种方法是创建一个 DateTime对象并使用它进行格式化:

new DateTime(myTimeSpan.Ticks).ToString(myCustomFormat)


// or using String.Format:
String.Format("{0:HHmmss}", new DateTime(myTimeSpan.Ticks))

这是我知道的方法。我希望有人能提出一个更好的方法。

对于.NET 3.5或更低版本,您可以使用:

string.Format ("{0:00}:{1:00}:{2:00}",
(int)myTimeSpan.TotalHours,
myTimeSpan.Minutes,
myTimeSpan.Seconds);

取自 Jon Skeet 的代码 rel = “ noReferrer”> response on bytes

有关.NET 4.0及以上版本,请参阅 DoctaJonez 回答

这个很棒:

string.Format("{0:00}:{1:00}:{2:00}",
(int)myTimeSpan.TotalHours,
myTimeSpan.Minutes,
myTimeSpan.Seconds);

简单。使用与 c,g 或 G 的 TimeSpan.ToString。更多信息在 MSDN

请注意: 这个答案是。净值4.0及以上。中设置时间跨度的格式。净值3.5或以下请参阅约翰内斯的回答。

中引入了自定义 TimeSpan 格式字符串。净值4.0。您可以在 MSDN自定义时间跨度格式字符串页面上找到可用格式说明符的完整引用。

下面是一个时间跨度格式字符串的例子:

string.Format("{0:hh\\:mm\\:ss}", myTimeSpan); //example output 15:36:15

(更新) ,下面是一个使用 C # 6字符串插值的例子:

$"{myTimeSpan:hh\\:mm\\:ss}"; //example output 15:36:15

您需要用一个“”来转义“ :”字符(除非使用逐字字符串,否则必须转义该字符本身)。

本文节选自 MSDN自定义时间跨度格式字符串页面,解释了如何在格式字符串中转义“ :”和“ .”字符:

自定义 TimeSpan 格式说明符不包括占位符分隔符号,例如将天与小时、小时与分钟或秒与小数秒分隔开的符号。相反,这些符号必须作为字符串文字包含在自定义格式字符串中。例如,“ dd.hh: mm”定义句点(.)作为天和小时之间的分隔符,冒号(:)作为小时和分钟之间的分隔符。

Dim duration As New TimeSpan(1, 12, 23, 62)


DEBUG.WriteLine("Time of Travel: " + duration.ToString("dd\.hh\:mm\:ss"))

它适用于框架4

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

你也可以选择:

Dim ts As New TimeSpan(35, 21, 59, 59)  '(11, 22, 30, 30)    '
Dim TimeStr1 As String = String.Format("{0:c}", ts)
Dim TimeStr2 As String = New Date(ts.Ticks).ToString("dd.HH:mm:ss")

编辑:

您还可以查看 字符串,格式

    Dim ts As New TimeSpan(23, 30, 59)
Dim str As String = Strings.Format(New DateTime(ts.Ticks), "H:mm:ss")

就个人而言,我喜欢这种方法:

TimeSpan ts = ...;
string.Format("{0:%d}d {0:%h}h {0:%m}m {0:%s}s", ts);

你可以按照自己的喜好定制,没有任何问题:

string.Format("{0:%d}days {0:%h}hours {0:%m}min {0:%s}sec", ts);
string.Format("{0:%d}d {0:%h}h {0:%m}' {0:%s}''", ts);

我用了下面的代码。它很长,但仍然是一个表达式,并且产生非常友好的输出,因为如果天、小时、分钟或秒的值为零,则它不输出它们。

在示例中,它产生输出: “4天1小时3秒”。

TimeSpan sp = new TimeSpan(4,1,0,3);
string.Format("{0}{1}{2}{3}",
sp.Days > 0 ? ( sp.Days > 1 ? sp.ToString(@"d\ \d\a\y\s\ "): sp.ToString(@"d\ \d\a\y\ ")):string.Empty,
sp.Hours > 0 ? (sp.Hours > 1 ? sp.ToString(@"h\ \h\o\u\r\s\ ") : sp.ToString(@"h\ \h\o\u\r\ ")):string.Empty,
sp.Minutes > 0 ? (sp.Minutes > 1 ? sp.ToString(@"m\ \m\i\n\u\t\e\s\ ") :sp.ToString(@"m\ \m\i\n\u\t\e\ ")):string.Empty,
sp.Seconds > 0 ? (sp.Seconds > 1 ? sp.ToString(@"s\ \s\e\c\o\n\d\s"): sp.ToString(@"s\ \s\e\c\o\n\d\s")):string.Empty);

我用这种方法。我是比利时人,说荷兰语,所以“小时”和“分钟”的复数形式不仅仅是在结尾加上“ s”,而且几乎和单数形式完全不同。

它可能看起来很长,但我认为它非常易读:

 public static string SpanToReadableTime(TimeSpan span)
{
string[] values = new string[4];  //4 slots: days, hours, minutes, seconds
StringBuilder readableTime = new StringBuilder();


if (span.Days > 0)
{
if (span.Days == 1)
values[0] = span.Days.ToString() + " dag"; //day
else
values[0] = span.Days.ToString() + " dagen";  //days


readableTime.Append(values[0]);
readableTime.Append(", ");
}
else
values[0] = String.Empty;




if (span.Hours > 0)
{
if (span.Hours == 1)
values[1] = span.Hours.ToString() + " uur";  //hour
else
values[1] = span.Hours.ToString() + " uren";  //hours


readableTime.Append(values[1]);
readableTime.Append(", ");


}
else
values[1] = string.Empty;


if (span.Minutes > 0)
{
if (span.Minutes == 1)
values[2] = span.Minutes.ToString() + " minuut";  //minute
else
values[2] = span.Minutes.ToString() + " minuten";  //minutes


readableTime.Append(values[2]);
readableTime.Append(", ");
}
else
values[2] = string.Empty;


if (span.Seconds > 0)
{
if (span.Seconds == 1)
values[3] = span.Seconds.ToString() + " seconde";  //second
else
values[3] = span.Seconds.ToString() + " seconden";  //seconds


readableTime.Append(values[3]);
}
else
values[3] = string.Empty;




return readableTime.ToString();
}//end SpanToReadableTime

我会和你一起去

myTimeSpan.ToString("hh\\:mm\\:ss");
if (timeSpan.TotalDays < 1)
return timeSpan.ToString(@"hh\:mm\:ss");


return timeSpan.TotalDays < 2
? timeSpan.ToString(@"d\ \d\a\y\ hh\:mm\:ss")
: timeSpan.ToString(@"d\ \d\a\y\s\ hh\:mm\:ss");

必须转义所有文字字符。

这是我自己使用条件格式的方法。我把它贴在这里,因为我认为这是干净的方式。

$"{time.Days:#0:;;\\}{time.Hours:#0:;;\\}{time.Minutes:00:}{time.Seconds:00}"

产出实例:

00:00(最低)

(当我们有时间的时候)

15:03:01(小时数超过1位数)

(当我们有时间的时候)

格式很简单。time.Days:#0:;;\\的格式在 ;;之前是当值是正的。负值被忽略。对于零值,我们使用 ;;\\将其隐藏在格式化的字符串中。请注意,转义反斜杠是必要的,否则它将无法正确格式化。

这是我的版本。它只显示必要的内容,处理复数和底片,我试图让它更轻量级。

输出示例

0 seconds
1.404 seconds
1 hour, 14.4 seconds
14 hours, 57 minutes, 22.473 seconds
1 day, 14 hours, 57 minutes, 22.475 seconds

密码

public static class TimeSpanExtensions
{
public static string ToReadableString(this TimeSpan timeSpan)
{
int days = (int)(timeSpan.Ticks / TimeSpan.TicksPerDay);
long subDayTicks = timeSpan.Ticks % TimeSpan.TicksPerDay;


bool isNegative = false;
if (timeSpan.Ticks < 0L)
{
isNegative = true;
days = -days;
subDayTicks = -subDayTicks;
}


int hours = (int)((subDayTicks / TimeSpan.TicksPerHour) % 24L);
int minutes = (int)((subDayTicks / TimeSpan.TicksPerMinute) % 60L);
int seconds = (int)((subDayTicks / TimeSpan.TicksPerSecond) % 60L);
int subSecondTicks = (int)(subDayTicks % TimeSpan.TicksPerSecond);
double fractionalSeconds = (double)subSecondTicks / TimeSpan.TicksPerSecond;


var parts = new List<string>(4);


if (days > 0)
parts.Add(string.Format("{0} day{1}", days, days == 1 ? null : "s"));
if (hours > 0)
parts.Add(string.Format("{0} hour{1}", hours, hours == 1 ? null : "s"));
if (minutes > 0)
parts.Add(string.Format("{0} minute{1}", minutes, minutes == 1 ? null : "s"));
if (fractionalSeconds.Equals(0D))
{
switch (seconds)
{
case 0:
// Only write "0 seconds" if we haven't written anything at all.
if (parts.Count == 0)
parts.Add("0 seconds");
break;


case 1:
parts.Add("1 second");
break;


default:
parts.Add(seconds + " seconds");
break;
}
}
else
{
parts.Add(string.Format("{0}{1:.###} seconds", seconds, fractionalSeconds));
}


string resultString = string.Join(", ", parts);
return isNegative ? "(negative) " + resultString : resultString;
}
}

如果您想要的持续时间格式类似于 youtube,给定的秒数

int[] duration = { 0, 4, 40, 59, 60, 61, 400, 4000, 40000, 400000 };
foreach (int d in duration)
{
Console.WriteLine("{0, 6} -> {1, 10}", d, d > 59 ? TimeSpan.FromSeconds(d).ToString().TrimStart("00:".ToCharArray()) : string.Format("0:{0:00}", d));
}

产出:

     0 ->       0:00
4 ->       0:04
40 ->       0:40
59 ->       0:59
60 ->       1:00
61 ->       1:01
400 ->       6:40
4000 ->    1:06:40
40000 ->   11:06:40
400000 -> 4.15:06:40

我想返回一个字符串,比如“1天2小时3分钟”,并且考虑到例如天或分钟是0,然后不显示它们。感谢 约翰 · 拉什的回答,我的回答仅仅是

TimeSpan timeLeft = New Timespan(0, 70, 0);
String.Format("{0}{1}{2}{3}{4}{5}",
Math.Floor(timeLeft.TotalDays) == 0 ? "" :
Math.Floor(timeLeft.TotalDays).ToString() + " ",
Math.Floor(timeLeft.TotalDays) == 0 ? "" : Math.Floor(timeLeft.TotalDays) == 1 ? "day " : "days ",
timeLeft.Hours == 0 ? "" : timeLeft.Hours.ToString() + " ",
timeLeft.Hours == 0 ? "" : timeLeft.Hours == 1 ? "hour " : "hours ",
timeLeft.Minutes == 0 ? "" : timeLeft.Minutes.ToString() + " ",
timeLeft.Minutes == 0 ? "" : timeLeft.Minutes == 1 ? "minute " : "minutes ");

这是我的 推广方法推广方法:

public static string ToFormattedString(this TimeSpan ts)
{
const string separator = ", ";


if (ts.TotalMilliseconds < 1) { return "No time"; }


return string.Join(separator, new string[]
{
ts.Days > 0 ? ts.Days + (ts.Days > 1 ? " days" : " day") : null,
ts.Hours > 0 ? ts.Hours + (ts.Hours > 1 ? " hours" : " hour") : null,
ts.Minutes > 0 ? ts.Minutes + (ts.Minutes > 1 ? " minutes" : " minute") : null,
ts.Seconds > 0 ? ts.Seconds + (ts.Seconds > 1 ? " seconds" : " second") : null,
ts.Milliseconds > 0 ? ts.Milliseconds + (ts.Milliseconds > 1 ? " milliseconds" : " millisecond") : null,
}.Where(t => t != null));
}

示例呼叫:

string time = new TimeSpan(3, 14, 15, 0, 65).ToFormattedString();

产出:

3 days, 14 hours, 15 minutes, 65 milliseconds

这是 VS2010中的一个痛处,这是我的变通解决方案。

 public string DurationString
{
get
{
if (this.Duration.TotalHours < 24)
return new DateTime(this.Duration.Ticks).ToString("HH:mm");
else //If duration is more than 24 hours
{
double totalminutes = this.Duration.TotalMinutes;
double hours = totalminutes / 60;
double minutes = this.Duration.TotalMinutes - (Math.Floor(hours) * 60);
string result = string.Format("{0}:{1}", Math.Floor(hours).ToString("00"), Math.Floor(minutes).ToString("00"));
return result;
}
}
}

当你只想要小时: 分钟: 秒的时候,Substring方法可以很好地工作。它简单,代码干净,易于理解。

    var yourTimeSpan = DateTime.Now - DateTime.Now.AddMinutes(-2);


var formatted = yourTimeSpan.ToString().Substring(0,8);// 00:00:00


Console.WriteLine(formatted);

没有人显示的方法与十进制格式说明书,这是我最喜欢的一个,特别是当使用字符串插值 -https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings?redirectedfrom=MSDN#decimal-format-specifier-d

例如:

$"{time.Hours:D2}:{time.Minutes:D2}:{time.Seconds:D2}.{time.Milliseconds:D3}"
// Sample output: 00:00:09.200

当然,您可以将其包装在某个 helper 方法中。