代码之家  ›  专栏  ›  技术社区  ›  Michael Wheeler

如何将TimeSpan转换为格式化字符串?[副本]

  •  141
  • Michael Wheeler  · 技术社区  · 17 年前

    我有两个DateTime变量,beginTime和endTime。我通过以下步骤了解了它们的不同之处:

    TimeSpan dateDifference = endTime.Subtract(beginTime);
    

    它应该返回00小时06分32秒

    14 回复  |  直到 9 年前
        1
  •  37
  •   Andy    17 年前

    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;
    }
    
        2
  •  167
  •   Jim G.    13 年前

    new DateTime(timeSpan.Ticks).ToString("HH:mm");
    
        3
  •  115
  •   vdboor    15 年前

    timeSpan.ToString(@"hh\:mm");
    
        4
  •  86
  •   Ruberoid    13 年前

    会 TimeSpan.ToString() 为你表演这个把戏?如果没有,那么该页面上的代码示例似乎描述了如何对 TimeSpan

        5
  •  31
  •   GBegen    17 年前

    使用带有多个参数的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);
            }
        }
    }
    
        6
  •  8
  •   Guffa    17 年前
       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);
          }
       }
    
        7
  •  8
  •   GregC Benjamin Baumann    15 年前

    格式化a的最简单方法 TimeSpan 将其添加到a DateTime

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

    Today 属性返回a 值,其中时间分量为零,因此结果的时间分量为 时间间隔 价值。

        8
  •  5
  •   Jason 'Bug' Fenter    17 年前

    the Microsoft documentation

    dateDifference.Hours.ToString() + " hrs, " + dateDifference.Minutes.ToString() + " mins, " + dateDifference.Seconds.ToString() + " secs"
    
        9
  •  4
  •   DShook    14 年前

    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);
      }
    }
    
        10
  •  4
  •   Edwin    9 年前

    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;
            }
        }
    }
    
        11
  •  3
  •   Jeff    14 年前

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

        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");
        }
    
        12
  •  1
  •   bizah    14 年前

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

    我也知道有人提到过,但它让我感到困惑,将Ticks转换为DateTime是可行的,但不能正确处理超过24小时的时间跨度。

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

    这将使你达到01:00,而不是你所期望的25:00。

        13
  •  0
  •   Kell    15 年前

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

        14
  •  -11
  •   Tom    15 年前
    ''' <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 (i.e. "day", "trillion", "foot")
        ''' </summary>
        ''' <remarks></remarks>
        Public UnitSglStr As String
    
        ''' <summary>
        ''' Name of a Plural Unit (i.e. "days", "trillion", "feet")
        ''' </summary>
        ''' <remarks></remarks>
        Public UnitPluralStr As String
    
        ''' <summary>
        ''' # of Units to = 1 of Next Higher (aka Parent) Unit (i.e. 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 (i.e. "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