Was ist der beste Weg, um Sekunden in (Stunde: Minuten: Sekunden: Millisekunden) Zeit umzuwandeln?

290

Was ist der beste Weg, um Sekunden in (Stunde: Minuten: Sekunden: Millisekunden) Zeit umzuwandeln?

Angenommen, ich habe 80 Sekunden. Gibt es spezielle Klassen / Techniken in .NET, mit denen ich diese 80 Sekunden in das Format (00h: 00m: 00s: 00ms) wie DateTime oder so konvertieren kann?

John Saunders
quelle

Antworten:

565

Für .Net <= 4.0 Verwenden Sie die TimeSpan-Klasse.

TimeSpan t = TimeSpan.FromSeconds( secs );

string answer = string.Format("{0:D2}h:{1:D2}m:{2:D2}s:{3:D3}ms", 
                t.Hours, 
                t.Minutes, 
                t.Seconds, 
                t.Milliseconds);

(Wie von Inder Kumar Rathore angegeben) Für .NET> 4.0 können Sie verwenden

TimeSpan time = TimeSpan.FromSeconds(seconds);

//here backslash is must to tell that colon is
//not the part of format, it just a character that we want in output
string str = time .ToString(@"hh\:mm\:ss\:fff");

(Von Nick Molyneux) Stellen Sie sicher, dass die Sekunden kürzer sind TimeSpan.MaxValue.TotalSeconds, um eine Ausnahme zu vermeiden.

Curtis Shipley
quelle
using System;Die Klasse befindet sich in System.TimeSpan.
fbmd
61

Für .NET> 4.0 können Sie verwenden

TimeSpan time = TimeSpan.FromSeconds(seconds);

//here backslash is must to tell that colon is
//not the part of format, it just a character that we want in output
string str = time .ToString(@"hh\:mm\:ss\:fff");

Wenn Sie ein Datums- / Uhrzeitformat wünschen, können Sie dies auch tun

TimeSpan time = TimeSpan.FromSeconds(seconds);
DateTime dateTime = DateTime.Today.Add(time);
string displayTime = dateTime.ToString("hh:mm:tt");

Weitere Informationen finden Sie unter Benutzerdefinierte TimeSpan-Formatzeichenfolgen

Inder Kumar Rathore
quelle
2
Sie benötigen TimeSpan nicht, um DateTime Sekunden hinzuzufügen. Verwenden Sie einfach DateTime.AddSeconds ().
Evgeni Nabokov
@MehdiDehghani für 24-Stunden-Format müssen Sie "HH" anstelle von "hh" verwenden
Inder Kumar Rathore
@InderKumarRathore Ich habe über Ihre erste Lösung gesprochen, HHist dort ungültig.
Mehdi Dehghani
@ MehdiDehghani könnten Sie bitte, was daran falsch ist, weil es 3 Jahre waren, in denen ich nicht codiert habe.NET/C#
Inder Kumar Rathore
1
@InderKumarRathore .ToString(@"hh\:mm\:ss\:fff");ist bereits im 24hrFormat. HHist dort mit einer solchen Eingabe nicht gültig ( der Fehler istInput string was not in a correct format. )
Mehdi Dehghani
23

Wenn Sie wissen, dass Sie einige Sekunden Zeit haben, können Sie einen TimeSpan-Wert erstellen, indem Sie TimeSpan.FromSeconds aufrufen:

 TimeSpan ts = TimeSpan.FromSeconds(80);

Sie können dann die Anzahl der Tage, Stunden, Minuten oder Sekunden ermitteln. Oder verwenden Sie eine der ToString-Überladungen, um sie auf eine beliebige Weise auszugeben.

Jim Mischel
quelle
16

Ich habe einige Benchmarks durchgeführt, um herauszufinden, was der schnellste Weg ist. Dies sind meine Ergebnisse und Schlussfolgerungen. Ich habe jede Methode 10 Millionen Mal ausgeführt und einen Kommentar mit der durchschnittlichen Zeit pro Lauf hinzugefügt.

Wenn Ihre Eingabe-Millisekunden nicht auf einen Tag beschränkt sind (Ihr Ergebnis kann 143: 59: 59.999 sein), sind dies die Optionen, von schneller bis langsamer:

// 0.86 ms
static string Method1(int millisecs)
{
    int hours = millisecs / 3600000;
    int mins = (millisecs % 3600000) / 60000;
    // Make sure you use the appropriate decimal separator
    return string.Format("{0:D2}:{1:D2}:{2:D2}.{3:D3}", hours, mins, millisecs % 60000 / 1000, millisecs % 1000);
}

// 0.89 ms
static string Method2(int millisecs)
{
    double s = millisecs % 60000 / 1000.0;
    millisecs /= 60000;
    int mins = millisecs % 60;
    int hours = millisecs / 60;
    return string.Format("{0:D2}:{1:D2}:{2:00.000}", hours, mins, s);
}

// 0.95 ms
static string Method3(int millisecs)
{
    TimeSpan t = TimeSpan.FromMilliseconds(millisecs);
    // Make sure you use the appropriate decimal separator
    return string.Format("{0:D2}:{1:D2}:{2:D2}.{3:D3}",
        (int)t.TotalHours,
        t.Minutes,
        t.Seconds,
        t.Milliseconds);
}

Wenn Ihre eingegebenen Millisekunden auf einen Tag begrenzt sind (Ihr Ergebnis wird niemals größer als 23: 59: 59.999 sein), sind dies die Optionen, von schneller bis langsamer:

// 0.58 ms
static string Method5(int millisecs)
{
    // Fastest way to create a DateTime at midnight
    // Make sure you use the appropriate decimal separator
    return DateTime.FromBinary(599266080000000000).AddMilliseconds(millisecs).ToString("HH:mm:ss.fff");
}

// 0.59 ms
static string Method4(int millisecs)
{
    // Make sure you use the appropriate decimal separator
    return TimeSpan.FromMilliseconds(millisecs).ToString(@"hh\:mm\:ss\.fff");
}

// 0.93 ms
static string Method6(int millisecs)
{
    TimeSpan t = TimeSpan.FromMilliseconds(millisecs);
    // Make sure you use the appropriate decimal separator
    return string.Format("{0:D2}:{1:D2}:{2:D2}.{3:D3}",
        t.Hours,
        t.Minutes,
        t.Seconds,
        t.Milliseconds);
}

Wenn Ihre Eingabe nur Sekunden dauert , sind die Methoden etwas schneller. Auch hier gilt: Wenn Ihre Eingabesekunden nicht auf einen Tag beschränkt sind (Ihr Ergebnis kann 143: 59: 59 sein):

// 0.63 ms
static string Method1(int secs)
{
    int hours = secs / 3600;
    int mins = (secs % 3600) / 60;
    secs = secs % 60;
    return string.Format("{0:D2}:{1:D2}:{2:D2}", hours, mins, secs);
}

// 0.64 ms
static string Method2(int secs)
{
    int s = secs % 60;
    secs /= 60;
    int mins = secs % 60;
    int hours = secs / 60;
    return string.Format("{0:D2}:{1:D2}:{2:D2}", hours, mins, s);
}

// 0.70 ms
static string Method3(int secs)
{
    TimeSpan t = TimeSpan.FromSeconds(secs);
    return string.Format("{0:D2}:{1:D2}:{2:D2}",
        (int)t.TotalHours,
        t.Minutes,
        t.Seconds);
}

Und wenn Ihre Eingabesekunden auf einen Tag begrenzt sind (Ihr Ergebnis wird niemals größer als 23:59:59 sein):

// 0.33 ms
static string Method5(int secs)
{
    // Fastest way to create a DateTime at midnight
    return DateTime.FromBinary(599266080000000000).AddSeconds(secs).ToString("HH:mm:ss");
}

// 0.34 ms
static string Method4(int secs)
{
    return TimeSpan.FromSeconds(secs).ToString(@"hh\:mm\:ss");
}

// 0.70 ms
static string Method6(int secs)
{
    TimeSpan t = TimeSpan.FromSeconds(secs);
    return string.Format("{0:D2}:{1:D2}:{2:D2}",
        t.Hours,
        t.Minutes,
        t.Seconds);
}

Lassen Sie mich abschließend hinzufügen, dass mir aufgefallen ist, dass dies string.Formatetwas schneller ist, wenn Sie D2stattdessen verwenden 00.

Andrew
quelle
8

Mit dem TimeSpan-Konstruktor können Sie in Sekunden übergeben. Deklarieren Sie einfach eine Variable vom Typ TimeSpan in Sekunden. Ex:

TimeSpan span = new TimeSpan(0, 0, 500);
span.ToString();
Jim Petkus
quelle
4

Ich würde vorschlagen, dass Sie die TimeSpanKlasse dafür verwenden.

public static void Main(string[] args)
{
    TimeSpan t = TimeSpan.FromSeconds(80);
    Console.WriteLine(t.ToString());

    t = TimeSpan.FromSeconds(868693412);
    Console.WriteLine(t.ToString());
}

Ausgänge:

00:01:20
10054.07:43:32
Oliver Friedrich
quelle
4

In VB.NET, aber in C # ist es dasselbe:

Dim x As New TimeSpan(0, 0, 80)
debug.print(x.ToString())
' Will print 00:01:20
Stefan
quelle
2

Für .NET <4.0 (z. B. Unity ) können Sie eine Erweiterungsmethode schreiben, die das TimeSpan.ToString(string format)Verhalten von .NET> 4.0 aufweist

public static class TimeSpanExtensions
{
    public static string ToString(this TimeSpan time, string format)
    {
        DateTime dateTime = DateTime.Today.Add(time);
        return dateTime.ToString(format);
    }
}

Und von überall in Ihrem Code können Sie es wie folgt verwenden:

var time = TimeSpan.FromSeconds(timeElapsed);

string formattedDate = time.ToString("hh:mm:ss:fff");

Auf diese Weise können Sie jedes TimeSpanObjekt formatieren, indem Sie einfach ToString von einer beliebigen Stelle Ihres Codes aus aufrufen.

Ege Aydın
quelle
1

Warum brauchen Leute TimeSpan UND DateTime, wenn wir DateTime.AddSeconds () haben?

var dt = new DateTime(2015, 1, 1).AddSeconds(totalSeconds);

Das Datum ist beliebig. totalSeconds kann größer als 59 sein und ist ein Double. Anschließend können Sie Ihre Zeit mit DateTime.ToString () beliebig formatieren:

dt.ToString("H:mm:ss");

Dies funktioniert nicht, wenn totalSeconds <0 oder> 59:

new DateTime(2015, 1, 1, 0, 0, totalSeconds)
Evgeni Nabokov
quelle
0
private string ConvertTime(double miliSeconds)
{
    var timeSpan = TimeSpan.FromMilliseconds(totalMiliSeconds);
    // Converts the total miliseconds to the human readable time format
    return timeSpan.ToString(@"hh\:mm\:ss\:fff");
}

//Prüfung

    [TestCase(1002, "00:00:01:002")]
    [TestCase(700011, "00:11:40:011")]
    [TestCase(113879834, "07:37:59:834")]
    public void ConvertTime_ResturnsCorrectString(double totalMiliSeconds, string expectedMessage)
    {
        // Arrange
        var obj = new Class();;

        // Act
        var resultMessage = obj.ConvertTime(totalMiliSeconds);

        // Assert
        Assert.AreEqual(expectedMessage, resultMessage);
    }
Moh Rezaee
quelle
3
1. OP hat die Konvertierung von Sekunden und nicht von Millisekunden angefordert. 2. Wie ist Ihre Antwort besser als die aktuell akzeptierte Antwort?
Vesan
0

um Gesamtsekunden zu erhalten

var i = TimeSpan.FromTicks(startDate.Ticks).TotalSeconds;

und um datetime von Sekunden zu erhalten

var thatDateTime = new DateTime().AddSeconds(i)
unos baghaii
quelle
0

Dies wird im Format hh: mm: ss zurückgegeben

 public static string ConvertTime(long secs)
    {
        TimeSpan ts = TimeSpan.FromSeconds(secs);
        string displayTime = $"{ts.Hours}:{ts.Minutes}:{ts.Seconds}";
        return displayTime;
    }
ATUL SHARMA
quelle
Sie dürfen dies nicht getestet haben. ConvertTime(80)Rückgaben 0:1:20und ConvertTime(61)Rückgaben 0:1:1, die beide sind h:m:s. Die Verwendung der Zeichenfolgeninterpolation führt auch zu einem längeren Code als ToString()in anderen Antworten und erschwert die Visualisierung der formatierten Zeichenfolgenlänge.
Speck