¿Cuál es la mejor manera de convertir segundos en (hora: minutos: segundos: milisegundos) de tiempo?

290

¿Cuál es la mejor manera de convertir segundos en (hora: minutos: segundos: milisegundos) de tiempo?

Digamos que tengo 80 segundos, ¿hay clases / técnicas especializadas en .NET que me permitan convertir esos 80 segundos en formato (00h: 00m: 00s: 00ms) como DateTime o algo así?

John Saunders
fuente

Respuestas:

565

Para .Net <= 4.0 Use la clase TimeSpan.

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

(Como señaló Inder Kumar Rathore) Para .NET> 4.0 puede usar

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

(De Nick Molyneux) Asegúrese de que los segundos sean menores que TimeSpan.MaxValue.TotalSecondspara evitar una excepción.

Curtis Shipley
fuente
using System;La clase reside en System.TimeSpan.
fbmd
61

Para .NET> 4.0 puede usar

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

o si desea el formato de fecha y hora, también puede hacerlo

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

Para obtener más información, puede consultar cadenas de formato TimeSpan personalizadas

Inder Kumar Rathore
fuente
2
No necesita TimeSpan para agregar segundos a DateTime. Simplemente use DateTime.AddSeconds ().
Evgeni Nabokov
@MehdiDehghani para el formato de 24 horas, debe usar 'HH' en lugar de 'hh'
Inder Kumar Rathore
@InderKumarRathore Estaba hablando de su primera solución, HHno es válida allí.
Mehdi Dehghani
@MehdiDehghani, por favor, ¿qué hay de malo en eso porque han pasado 3 años que no he codificado?.NET/C#
Inder Kumar Rathore
1
@InderKumarRathore .ToString(@"hh\:mm\:ss\:fff");ya está en 24hrformato. HHno es válido allí con dicha entrada ( el error esInput string was not in a correct format. )
Mehdi Dehghani
23

Si sabe que tiene varios segundos, puede crear un valor de TimeSpan llamando a TimeSpan.FromSeconds:

 TimeSpan ts = TimeSpan.FromSeconds(80);

Luego puede obtener el número de días, horas, minutos o segundos. O utilice una de las sobrecargas de ToString para generarla de la manera que desee.

Jim Mischel
fuente
16

Hice algunos puntos de referencia para ver cuál es la forma más rápida y estos son mis resultados y conclusiones. Ejecuté cada método 10M veces y agregué un comentario con el tiempo promedio por ejecución.

Si sus milisegundos de entrada no se limitan a un día (su resultado puede ser 143: 59: 59.999), estas son las opciones, de más rápido a más lento:

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

Si sus milisegundos de entrada están limitados a un día (su resultado nunca será mayor que 23: 59: 59.999), estas son las opciones, de más rápido a más lento:

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

En caso de que su entrada sea de solo segundos , los métodos son un poco más rápidos. Nuevamente, si sus segundos de entrada no se limitan a un día (su resultado puede ser 143: 59: 59):

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

Y si sus segundos de entrada están limitados a un día (su resultado nunca será mayor que 23:59:59):

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

Como comentario final, permítanme agregar que noté que string.Formates un poco más rápido si lo usa en D2lugar de 00.

Andrés
fuente
8

El constructor TimeSpan le permite pasar en segundos. Simplemente declare una variable de tipo TimeSpan cantidad de segundos. Ex:

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

Te sugiero que uses la TimeSpanclase para esto.

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

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

Salidas:

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

En VB.NET, pero es lo mismo en C #:

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

Para .NET <4.0 (ej .: Unity ) puede escribir un método de extensión para tener el TimeSpan.ToString(string format)comportamiento como .NET> 4.0

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

Y desde cualquier parte de su código puede usarlo como:

var time = TimeSpan.FromSeconds(timeElapsed);

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

De esta manera, puede formatear cualquier TimeSpanobjeto simplemente llamando a ToString desde cualquier parte de su código.

Ege Aydın
fuente
1

¿Por qué las personas necesitan TimeSpan AND DateTime si tenemos DateTime.AddSeconds ()?

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

La fecha es arbitraria. totalSeconds puede ser mayor que 59 y es un doble. Luego puede formatear su tiempo como lo desee usando DateTime.ToString ():

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

Esto no funciona si totalSeconds <0 o> 59:

new DateTime(2015, 1, 1, 0, 0, totalSeconds)
Evgeni Nabokov
fuente
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");
}

//Prueba

    [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
fuente
3
1. OP solicitó la conversión de segundos, no milisegundos. 2. ¿Cómo es su respuesta más alta que la respuesta actualmente aceptada?
vesan
0

para obtener el total de segundos

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

y para obtener la fecha y hora de segundos

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

Esto volverá en formato hh: mm: ss

 public static string ConvertTime(long secs)
    {
        TimeSpan ts = TimeSpan.FromSeconds(secs);
        string displayTime = $"{ts.Hours}:{ts.Minutes}:{ts.Seconds}";
        return displayTime;
    }
ATUL SHARMA
fuente
No debes haber probado esto. ConvertTime(80)vuelve 0:1:20y ConvertTime(61)vuelve 0:1:1, los cuales son h:m:s. El uso de la interpolación de cadenas también genera un código más largo que ToString(), como se usa en otras respuestas, y también dificulta la visualización de la longitud de la cadena formateada.
BACON