Question

    

Cette question a déjà une réponse ici:

         

J'ai deux vars DateTime, beginTime et endTime. J'ai compris la différence en procédant comme suit:

TimeSpan dateDifference = endTime.Subtract(beginTime);

Comment puis-je maintenant renvoyer une chaîne de ce type au format hh heures, mm minutes, ss secondes à l'aide de C #.

Si la différence était de 00: 06: 32.4458750

Il devrait retourner ce 00 heures, 06 minutes, 32 secondes

Était-ce utile?

La solution

TimeSpan.ToString () ferait l'affaire pour vous? Sinon, il semble que l'exemple de code de cette page explique comment formater un objet TimeSpan sur mesure.

Autres conseils

Je viens de construire quelques méthodes d'extension TimeSpan. Je pensais pouvoir partager:

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

En le convertissant en date / heure, vous pouvez obtenir les formats localisés:

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

C’est la solution la plus courte.

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

Utilisez String.Format () avec plusieurs paramètres.

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

Le moyen le plus simple de formater un TimeSpan consiste à l'ajouter à un DateTime et à formater celui-ci:

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

Ceci fonctionne tant que le décalage horaire ne dépasse pas 24 heures.

La propriété Today renvoie une <=> valeur où le composant heure est égal à zéro, le composant heure du résultat est donc la <=> valeur.

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

Selon la documentation Microsoft , la structure TimeSpan expose les heures, les minutes, les secondes et les millisecondes en tant que membres entiers. Peut-être que vous voulez quelque chose comme:

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

Vous pouvez utiliser le code suivant.

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

Merci à Peter pour la méthode d'extension. Je l'ai modifié pour fonctionner avec des durées plus longues:

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

Je sais que cette question est ancienne, mais .Net 4 prend désormais en charge TimeSpan personnalisé. formats .

Je sais aussi que cela a été mentionné, mais cela m’a pris au dépourvu. Convertir Ticks en DateTime fonctionne, mais ne gère pas correctement plus de 24 heures.

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

Cela vous mènera à 01h00 et non à 25h00 comme vous pouvez vous attendre.

J'ai également eu un problème similaire et j'ai créé ma propre extension, mais il semble être un peu différent de tout le reste.

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

Je sais que c'est une réponse tardive, mais cela fonctionne pour moi:

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

dateDifference devrait maintenant exclure les parties inférieures à une seconde. Fonctionne également en .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 (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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top