如何将TimeSpan转换为格式化的string?

我有两个date时间variables,beginTime和endTime。 我通过下面的方法得到了他们的区别:

TimeSpan dateDifference = endTime.Subtract(beginTime); 

我现在怎样才能以hh,hms,ss secs格式使用C#返回一串string。

如果差异是00:06:32.4458750

它应该返回这个00小时,06分钟,32秒

TimeSpan.ToString()会为你做诡计吗? 如果不是,则该页面上的代码示例看起来像描述了如何执行TimeSpan对象的自定义格式。

我只是build立了几个TimeSpan扩展方法。 以为我可以分享:

 public static string ToReadableAgeString(this TimeSpan span) { return string.Format("{0:0}", span.Days / 365.25); } public static string ToReadableString(this TimeSpan span) { string formatted = string.Format("{0}{1}{2}{3}", span.Duration().Days > 0 ? string.Format("{0:0} day{1}, ", span.Days, span.Days == 1 ? String.Empty : "s") : string.Empty, span.Duration().Hours > 0 ? string.Format("{0:0} hour{1}, ", span.Hours, span.Hours == 1 ? String.Empty : "s") : string.Empty, span.Duration().Minutes > 0 ? string.Format("{0:0} minute{1}, ", span.Minutes, span.Minutes == 1 ? String.Empty : "s") : string.Empty, span.Duration().Seconds > 0 ? string.Format("{0:0} second{1}", span.Seconds, span.Seconds == 1 ? String.Empty : "s") : string.Empty); if (formatted.EndsWith(", ")) formatted = formatted.Substring(0, formatted.Length - 2); if (string.IsNullOrEmpty(formatted)) formatted = "0 seconds"; return formatted; } 

通过将其转换为date时间,您可以获得本地化的格式:

 new DateTime(timeSpan.Ticks).ToString("HH:mm"); 

这是最短的解决scheme。

 timeSpan.ToString(@"hh\:mm"); 

使用String.Format()与多个参数。

 using System; namespace TimeSpanFormat { class Program { static void Main(string[] args) { TimeSpan dateDifference = new TimeSpan(0, 0, 6, 32, 445); string formattedTimeSpan = string.Format("{0:D2} hrs, {1:D2} mins, {2:D2} secs", dateDifference.Hours, dateDifference.Minutes, dateDifference.Seconds); Console.WriteLine(formattedTimeSpan); } } } 

格式化TimeSpan最简单的方法是将其添加到DateTime并格式为:

 string formatted = (DateTime.Today + dateDifference).ToString("HH 'hrs' mm 'mins' ss 'secs'"); 

只要时差不超过24小时,这就可以工作。

Today属性返回时间分量为零的DateTime值,因此结果的时间分量是TimeSpan值。

  public static class TimeSpanFormattingExtensions { public static string ToReadableString(this TimeSpan span) { return string.Join(", ", span.GetReadableStringElements() .Where(str => !string.IsNullOrWhiteSpace(str))); } private static IEnumerable<string> GetReadableStringElements(this TimeSpan span) { yield return GetDaysString((int)Math.Floor(span.TotalDays)); yield return GetHoursString(span.Hours); yield return GetMinutesString(span.Minutes); yield return GetSecondsString(span.Seconds); } private static string GetDaysString(int days) { if (days == 0) return string.Empty; if (days == 1) return "1 day"; return string.Format("{0:0} days", days); } private static string GetHoursString(int hours) { if (hours == 0) return string.Empty; if (hours == 1) return "1 hour"; return string.Format("{0:0} hours", hours); } private static string GetMinutesString(int minutes) { if (minutes == 0) return string.Empty; if (minutes == 1) return "1 minute"; return string.Format("{0:0} minutes", minutes); } private static string GetSecondsString(int seconds) { if (seconds == 0) return string.Empty; if (seconds == 1) return "1 second"; return string.Format("{0:0} seconds", seconds); } } 

根据Microsoft文档 ,TimeSpan结构将小时,分钟,秒和毫秒公开为整数成员。 也许你想要像这样的东西:

 dateDifference.Hours.ToString() + " hrs, " + dateDifference.Minutes.ToString() + " mins, " + dateDifference.Seconds.ToString() + " secs" 

感谢彼得的扩展方法。 我修改了它可以更好地处理更长的时间跨度:

 namespace ExtensionMethods { public static class TimeSpanExtensionMethods { public static string ToReadableString(this TimeSpan span) { string formatted = string.Format("{0}{1}{2}", (span.Days / 7) > 0 ? string.Format("{0:0} weeks, ", span.Days / 7) : string.Empty, span.Days % 7 > 0 ? string.Format("{0:0} days, ", span.Days % 7) : string.Empty, span.Hours > 0 ? string.Format("{0:0} hours, ", span.Hours) : string.Empty); if (formatted.EndsWith(", ")) formatted = formatted.Substring(0, formatted.Length - 2); return formatted; } } } 

我知道这个问题比较老,但是.Net 4现在支持Custom TimeSpan格式 。

另外我知道它已被提及,但它把我抓出来,将Ticks转换为DateTime作品,但不能正确处理超过24小时的时间。

 new DateTime((DateTime.Now - DateTime.Now.AddHours(-25)).Ticks).ToString("HH:mm") 

这可以让你01:00而不是你所期望的25:00。

您可以使用下面的代码。

 public static class TimeSpanExtensions { public static String Verbose(this TimeSpan timeSpan) { var hours = timeSpan.Hours; var minutes = timeSpan.Minutes; if (hours > 0) return String.Format("{0} hours {1} minutes", hours, minutes); return String.Format("{0} minutes", minutes); } } 

我也有类似的问题,并提出了自己的扩展,但似乎有点不同于其他一切。

  public static string TimeSpanToString(this TimeSpan timeSpan) { //if it's negative if (timeSpan.Ticks < 0) { timeSpan = timeSpan - timeSpan - timeSpan; if (timeSpan.Days != 0) return string.Format("-{0}:{1}", timeSpan.Days.ToString("d"), new DateTime(timeSpan.Ticks).ToString("HH:mm:ss")); else return new DateTime(timeSpan.Ticks).ToString("-HH:mm:ss"); } //if it has days else if (timeSpan.Days != 0) return string.Format("{0}:{1}", timeSpan.Days.ToString("d"), new DateTime(timeSpan.Ticks).ToString("HH:mm:ss")); //otherwise return the time else return new DateTime(timeSpan.Ticks).ToString("HH:mm:ss"); } 

我知道这是一个迟到的答案,但这对我有用:

 TimeSpan dateDifference = new TimeSpan(0,0,0, (int)endTime.Subtract(beginTime).TotalSeconds); 

dateDifference现在应该排除小于一秒的部分。 也在.net 2.0中工作。

 ''' <summary> ''' Return specified Double # (NumDbl) as String using specified Number Format String (FormatStr, ''' Default = "N0") and Format Provider (FmtProvider, Default = Nothing) followed by space and, ''' if NumDbl = 1, the specified Singular Unit Name (SglUnitStr), else the Plural Unit Name ''' (PluralUnitStr). ''' </summary> ''' <param name="NumDbl"></param> ''' <param name="SglUnitStr"></param> ''' <param name="PluralUnitStr"></param> ''' <param name="FormatStr"></param> ''' <param name="FmtProvider"></param> ''' <returns></returns> ''' <remarks></remarks> Public Function PluralizeUnitsStr( _ ByVal NumDbl As Double, _ ByVal SglUnitStr As String, _ ByVal PluralUnitStr As String, _ Optional ByVal FormatStr As String = "N0", _ Optional ByVal FmtProvider As System.IFormatProvider = Nothing _ ) As String PluralizeUnitsStr = NumDbl.ToString(FormatStr, FmtProvider) & " " Dim RsltUnitStr As String If NumDbl = 1 Then RsltUnitStr = SglUnitStr Else RsltUnitStr = PluralUnitStr End If PluralizeUnitsStr &= RsltUnitStr End Function ''' <summary> ''' Info about a # Unit. ''' </summary> ''' <remarks></remarks> Public Class clsNumUnitInfoItem ''' <summary> ''' Name of a Singular Unit (ie "day", "trillion", "foot") ''' </summary> ''' <remarks></remarks> Public UnitSglStr As String ''' <summary> ''' Name of a Plural Unit (ie "days", "trillion", "feet") ''' </summary> ''' <remarks></remarks> Public UnitPluralStr As String ''' <summary> ''' # of Units to = 1 of Next Higher (aka Parent) Unit (ie 24 "hours", 1000 "million", ''' 5280 "feet") ''' </summary> ''' <remarks></remarks> Public UnitsInParentInt As Integer End Class ' -- clsNumUnitInfoItem Dim TimeLongEnUnitInfoItms As clsNumUnitInfoItem() = { _ New clsNumUnitInfoItem With {.UnitSglStr = "day", .UnitPluralStr = "days", .UnitsInParentInt = 1}, _ New clsNumUnitInfoItem With {.UnitSglStr = "hour", .UnitPluralStr = "hours", .UnitsInParentInt = 24}, _ New clsNumUnitInfoItem With {.UnitSglStr = "minute", .UnitPluralStr = "minutes", .UnitsInParentInt = 60}, _ New clsNumUnitInfoItem With {.UnitSglStr = "second", .UnitPluralStr = "seconds", .UnitsInParentInt = 60}, _ New clsNumUnitInfoItem With {.UnitSglStr = "millisecond", .UnitPluralStr = "milliseconds", .UnitsInParentInt = 1000} _ } ' -- Dim TimeLongEnUnitInfoItms Dim TimeShortEnUnitInfoItms As clsNumUnitInfoItem() = { _ New clsNumUnitInfoItem With {.UnitSglStr = "day", .UnitPluralStr = "days", .UnitsInParentInt = 1}, _ New clsNumUnitInfoItem With {.UnitSglStr = "hr", .UnitPluralStr = "hrs", .UnitsInParentInt = 24}, _ New clsNumUnitInfoItem With {.UnitSglStr = "min", .UnitPluralStr = "mins", .UnitsInParentInt = 60}, _ New clsNumUnitInfoItem With {.UnitSglStr = "sec", .UnitPluralStr = "secs", .UnitsInParentInt = 60}, _ New clsNumUnitInfoItem With {.UnitSglStr = "msec", .UnitPluralStr = "msecs", .UnitsInParentInt = 1000} _ } ' -- Dim TimeShortEnUnitInfoItms ''' <summary> ''' Convert a specified Double Number (NumDbl) to a long (aka verbose) format (ie "1 day, ''' 2 hours, 3 minutes, 4 seconds and 567 milliseconds") with a specified Array of Time Unit ''' Info Items (TimeUnitInfoItms), Conjunction (ConjStr, Default = "and"), Minimum Unit Level ''' Shown (MinUnitLevInt) (0 to TimeUnitInfoItms.Length - 1, -1=All), Maximum Unit Level Shown ''' (MaxUnitLevInt) (-1=All), Maximum # of Unit Levels Shown (MaxNumUnitLevsInt) (1 to 0 to ''' TimeUnitInfoItms.Length - 1, 0=All) and Round Last Shown Units Up Flag (RoundUpBool). ''' Suppress leading 0 Unit Levels. ''' </summary> ''' <param name="NumDbl"></param> ''' <param name="NumUnitInfoItms"></param> ''' <param name="ConjStr"></param> ''' <param name="MinUnitLevInt"></param> ''' <param name="MaxUnitLevInt"></param> ''' <param name="MaxNumUnitLevsInt"></param> ''' <param name="RoundUpBool"></param> ''' <param name="FormatStr"></param> ''' <param name="FmtProvider"></param> ''' <returns></returns> ''' <remarks></remarks> Public Function NumToLongStr( _ ByVal NumDbl As Double, _ ByVal NumUnitInfoItms As clsNumUnitInfoItem(), _ Optional ByVal ConjStr As String = "and", _ Optional ByVal MinUnitLevInt As Integer = -1, _ Optional ByVal MaxUnitLevInt As Integer = -1, _ Optional ByVal MaxNumUnitLevsInt As Integer = 0, _ Optional ByVal RoundUpBool As Boolean = False, _ Optional ByVal FormatStr As String = "N0", _ Optional ByVal FmtProvider As System.IFormatProvider = Nothing _ ) As String NumToLongStr = "" Const TUnitDelimStr As String = ", " If (MinUnitLevInt < -1) OrElse (MinUnitLevInt >= NumUnitInfoItms.Length) Then Throw New Exception("Invalid MinUnitLevInt: " & MaxUnitLevInt) End If If (MaxUnitLevInt < -1) OrElse (MaxUnitLevInt >= NumUnitInfoItms.Length) Then Throw New Exception("Invalid MaxDetailLevelInt: " & MaxUnitLevInt) End If If (MaxNumUnitLevsInt < 0) OrElse (MaxNumUnitLevsInt > NumUnitInfoItms.Length) Then Throw New Exception("Invalid MaxNumUnitLevsInt: " & MaxNumUnitLevsInt) End If Dim PrevNumUnitsDbl As Double = NumDbl Dim CurrUnitLevInt As Integer = -1 Dim NumUnitLevsShownInt As Integer = 0 For Each UnitInfoItem In NumUnitInfoItms CurrUnitLevInt += 1 With UnitInfoItem Dim CurrNumUnitsDbl As Double = PrevNumUnitsDbl * .UnitsInParentInt Dim CurrTruncNumUnitsInt As Integer = Math.Truncate(CurrNumUnitsDbl) PrevNumUnitsDbl = CurrNumUnitsDbl If CurrUnitLevInt < MinUnitLevInt Then Continue For PrevNumUnitsDbl -= CurrTruncNumUnitsInt 'If (CurrUnitLevInt > TimeUnitInfoItms.Length) _ ' OrElse _ ' ( _ ' (CurrUnitLevInt > MaxUnitLevInt) AndAlso _ ' (MaxUnitLevInt <> -1) _ ' ) _ ' OrElse _ ' ( _ ' (NumUnitLevsShownInt + 1 > MaxNumUnitLevsInt) AndAlso _ ' (MaxNumUnitLevsInt <> 0) _ ' ) Then Exit For If (CurrUnitLevInt = (NumUnitInfoItms.Length - 1)) OrElse _ (CurrUnitLevInt = MaxUnitLevInt) OrElse _ ((NumUnitLevsShownInt + 1) = MaxNumUnitLevsInt) Then If NumUnitLevsShownInt > 0 Then Dim TUnitDelimStrLenInt As Integer = TUnitDelimStr.Length NumToLongStr = NumToLongStr.Remove( _ NumToLongStr.Length - TUnitDelimStrLenInt, _ TUnitDelimStrLenInt) NumToLongStr &= " " & ConjStr & " " End If Dim CurrNunUnitsRoundedInt As Integer If RoundUpBool Then If CurrNumUnitsDbl <> CurrTruncNumUnitsInt Then CurrNunUnitsRoundedInt = CurrTruncNumUnitsInt + 1 Else CurrNunUnitsRoundedInt = CurrTruncNumUnitsInt End If Else CurrNunUnitsRoundedInt = Math.Round( _ value:=CurrNumUnitsDbl, mode:=MidpointRounding.AwayFromZero) End If NumToLongStr &= _ PluralizeUnitsStr(CurrNunUnitsRoundedInt, _ .UnitSglStr, .UnitPluralStr, FormatStr, FmtProvider) Exit For Else ' -- Not (MaxUnitLevInt or MaxNumUnitLevsInt) If NumUnitLevsShownInt > 0 OrElse CurrTruncNumUnitsInt <> 0 Then NumToLongStr &= _ PluralizeUnitsStr(CurrTruncNumUnitsInt, _ .UnitSglStr, .UnitPluralStr, FormatStr, FmtProvider) & _ TUnitDelimStr NumUnitLevsShownInt += 1 End If End If ' -- Else Not (MaxUnitLevInt or MaxNumUnitLevsInt) End With ' -- UnitInfoItem Next UnitInfoItem End Function ''' <summary> ''' Call NumToLongStr with a specified TimeSpan's (TS) TotalDays. ''' </summary> ''' <param name="TS"></param> ''' <param name="TimeUnitInfoItms"></param> ''' <param name="ConjStr"></param> ''' <param name="MinUnitLevInt"></param> ''' <param name="MaxUnitLevInt"></param> ''' <param name="MaxNumUnitLevsInt"></param> ''' <param name="RoundUpBool"></param> ''' <param name="FormatStr"></param> ''' <param name="FmtProvider"></param> ''' <returns></returns> ''' <remarks></remarks> Public Function TimeSpanToStr( _ ByVal TS As TimeSpan, _ ByVal TimeUnitInfoItms As clsNumUnitInfoItem(), _ Optional ByVal ConjStr As String = "and", _ Optional ByVal MinUnitLevInt As Integer = -1, _ Optional ByVal MaxUnitLevInt As Integer = -1, _ Optional ByVal MaxNumUnitLevsInt As Integer = 0, _ Optional ByVal RoundUpBool As Boolean = False, _ Optional ByVal FormatStr As String = "N0", _ Optional ByVal FmtProvider As System.IFormatProvider = Nothing _ ) As String Return NumToLongStr( _ NumDbl:=TS.TotalDays, _ NumUnitInfoItms:=TimeUnitInfoItms, _ ConjStr:=ConjStr, _ MinUnitLevInt:=MinUnitLevInt, _ MaxUnitLevInt:=MaxUnitLevInt, _ MaxNumUnitLevsInt:=MaxNumUnitLevsInt, _ RoundUpBool:=RoundUpBool, _ FormatStr:=FormatStr, _ FmtProvider:=FmtProvider _ ) End Function ''' <summary> ''' Call TimeSpanToStr with TimeLongEnUnitInfoItms. ''' </summary> ''' <param name="TS"></param> ''' <param name="MinUnitLevInt"></param> ''' <param name="MaxUnitLevInt"></param> ''' <param name="MaxNumUnitLevsInt"></param> ''' <param name="RoundUpBool"></param> ''' <param name="FormatStr"></param> ''' <param name="FmtProvider"></param> ''' <returns></returns> ''' <remarks></remarks> Public Function TimeSpanToLongEnStr( _ ByVal TS As TimeSpan, _ Optional ByVal MinUnitLevInt As Integer = -1, _ Optional ByVal MaxUnitLevInt As Integer = -1, _ Optional ByVal MaxNumUnitLevsInt As Integer = 0, _ Optional ByVal RoundUpBool As Boolean = False, _ Optional ByVal FormatStr As String = "N0", _ Optional ByVal FmtProvider As System.IFormatProvider = Nothing _ ) As String Return TimeSpanToStr( _ TS:=TS, _ TimeUnitInfoItms:=TimeLongEnUnitInfoItms, _ MinUnitLevInt:=MinUnitLevInt, _ MaxUnitLevInt:=MaxUnitLevInt, _ MaxNumUnitLevsInt:=MaxNumUnitLevsInt, _ RoundUpBool:=RoundUpBool, _ FormatStr:=FormatStr, _ FmtProvider:=FmtProvider _ ) End Function