2010-08-23 44 views
13

Quiero mostrar el tiempo transcurrido entre dos fechas en una cadena.Usar String.Format en un TimeSpan para generar segundos completos sin milisegundos

Digamos que tengo el siguiente código:

DateTime date1 = DateTime.Now(); 
System.Threading.Thread.Sleep(2500); 
DateTime date2 = DateTime.Now(); 

TimeSpan elapsed = date2.substract(date1); 
Console.WriteLine("> {0:hh:mm:ss}", elapsed); 

Lo que espero:

> 00:00:03 

Lo que me sale:

> 00:00:02.5002500 

¿Hay una manera de utilizar la cadena. ¿La función de formato solo devuelve segundos completos?
También probé para eliminar los decimales con:

elapsed = elapsed.Substract(TimeSpan.FromMiliseconds((double)Timespan.Miliseconds); 

Pero eso no funciona, ya sea desde elapsed.Miliseconds devuelve 500 como un entero.

Respuesta

18

Cambiar el

Console.WriteLine("> {0:hh:mm:ss}", elapsed); 

a

Console.WriteLine("> {0:hh\\:mm\\:ss}", elapsed); 

.Net 4 permite el uso de cadenas de formato personalizado con Timespan. Puede encontrar una referencia completa de los especificadores de formato disponibles en la página MSDN Custom TimeSpan Format Strings.

Necesita escapar del carácter ":" con una "\" (que a su vez debe escaparse a menos que esté usando una cadena literal).

Este extracto de la página de MSDN Custom TimeSpan Format Strings explica cómo salir de ":" y "." caracteres en una cadena de formato:

la costumbre especificadores de formato TimeSpan no incluyen símbolos de separación de marcador de posición, como los símbolos que días separados de horas, horas de minutos o segundos desde fracciones de segundo. En cambio, estos símbolos se deben incluir en la cadena de formato personalizado como literales de cadena. Por ejemplo, "dd.hh: mm" define un período (.) Como el separador entre días y horas, y dos puntos (:) como el separador entre horas y minutos.

2

Después de ver algunas formas de hacerlo, desafortunadamente me queda una fea respuesta. Realmente no se puede utilizar garrapatas, ya que no devuelve el formato correctamente, pero el siguiente trabajo:

DateTime date1 = DateTime.Now; 
System.Threading.Thread.Sleep(2500); 
DateTime date2 = DateTime.Now; 

TimeSpan elapsed = date2.Subtract(date1); 

string[] Split = elapsed.ToString().Split('.'); 

string m = Split[0]; // Returns 00:00:02 
+0

Una solución agradable, también (y probablemente el más eficiente respecto al rendimiento). –

+0

podría haber hecho un nuevo TimeSpan con 0 segundos de fragmentos y luego imprimir ese. El formato "g" junto con CultureInfo.InvariantCulture debería funcionar bien –

-6

Existen las siguientes especificadores de formato personalizado y (año), M (mes), d (día), h (hora 12), H (hora 24), m (minuto), s (segundo), f (segunda fracción), F (segunda fracción, ceros finales), t (PM o AM) yz (zona horaria).

Los siguientes ejemplos demuestran cómo se vuelven a escribir los especificadores de formato en la salida. [C#]

// create date time 2008-03-09 16:05:07.123  
DateTime dt = new DateTime(2008, 3, 9, 16, 5, 7, 123);  
String.Format("{0:y yy yyy yyyy}", dt); // "8 08 008 2008" year  
String.Format("{0:M MM MMM MMMM}", dt); // "3 03 Mar March" month  
String.Format("{0:d dd ddd dddd}", dt); // "9 09 Sun Sunday" day  
String.Format("{0:h hh H HH}",  dt); // "4 04 16 16"  hour 12/24 
String.Format("{0:m mm}",   dt); // "5 05"   minute 
String.Format("{0:s ss}",   dt); // "7 07"   second  
String.Format("{0:f ff fff ffff}", dt); // "1 12 123 1230" sec.fraction  
String.Format("{0:F FF FFF FFFF}", dt); // "1 12 123 123" without zeroes  
String.Format("{0:t tt}",   dt); // "P PM"   A.M. or P.M.  
String.Format("{0:z zz zzz}",  dt); // "-6 -06 -06:00" time zone 
+2

El OP está buscando formatear un * TimeSpan *, no un * DateTime *. –

13

Por desgracia, no es posible dar formato a un TimeSpan de la misma manera como un valor DateTime. Sin embargo, puede hacer una conversión rápida porque tanto TimeSpan como DateTime almacenan su valor como ticks (en la propiedad Ticks).

en el código que se vería así:

Console.WriteLine("> {0:hh:mm:ss}", new DateTime(elapsed.Ticks));

ACTUALIZACIÓN: Esto se aplica a .NET 3.5 y anteriores, .NET 4 ¿son compatibles con el formato de lapsos.

+0

Creo que quiere 'HH: mm: ss' para que esto sea correcto. Buen truco sin embargo, +1 de mí – fearofawhackplanet

+0

Gran solución (ya que mi Timespan nunca será superior a 24 h) y fearofawhackplanet está en lo cierto: 'HH: mm: ss' tiene más sentido. –

+2

En .Net 4, puede formatear un Timespan de la misma manera que DateTime. Puede usar lo siguiente: {0: hh \\: mm \\: ss}. Ver mi respuesta a continuación para más detalles. –

1

Hmm, esto es desagradable (como resulta) - al menos antes de .NET 4.0

Si vas aquí: http://msdn.microsoft.com/en-us/library/1ecy8h51(v=VS.90).aspx que le dirá que no hay sobrecarga de formato para un espacio de tiempo y que tiene a hacerlo a mano por ejemplo:

 span.Hours.ToString("00") + ":" + 
    span.Minutes.ToString("00") + ":" + 
    span.Seconds.ToString("00") + "." 

Esto parece - al menos desde la documentación - que se fija en .NET 4.0

4

la clase TimeSpan tiene Hours, Minutes y Seconds propiedades que devuelven cada parte de forma individual. Para que pueda probar:

String.Format(CultureInfo.CurrentCulture, "{0}:{1}:{2}", 
    elapsed.Hours, 
    elapsed.Minutes, 
    elapsed.Seconds) 

Para obtener el formato que desea.

Puede haber una forma más óptima, pero todavía no la he encontrado.

-2

usted puede hacer esto:

dt.Subtract(TimeSpan.FromMilliseconds(dt.Millisecond)).ToString(); 
+2

¡Añada también algunas explicaciones! –

+0

Esto también funcionaría, pero dado que Framework 4 .NET soporta nativamente el formato de intervalo de tiempo, es la mejor solución. –

Cuestiones relacionadas