2011-03-25 12 views
14

Escribir el título de esta pregunta me llevó al this question. Estoy buscando lo mismo, pero algo tal vez con un formato menos estático si entiendes lo que quiero decir.TimeSpan formato de "tiempo bonito" en C#

Estoy escribiendo un programa rápido que tomará una duración temporal de dos objetos DateTime y los imprimirá para imprimir en papel.

El formato que se preferiría es: XX days, YY hours, ZZ minutes (los segundos son irrelevantes, como lo son los días porque no espero que el intervalo de tiempo incorpore más de unas pocas horas).

Diga el siguiente código (como ejemplo):

DateTime start = DateTime.Now; 
DateTime end = DateTime.Now.AddMinutes(135); 
TimeSpan duration = (end - start); 

// output duration as XX hours, YY minutes 

Gracias,
Zack

P.S. También me encontré con "PrettyTime.NET", pero salió cosas como "hace 3 días", etc. Todos los demás temas que encontré en google para formatear cadenas de duración de tiempo como los ejemplos anteriores me llevan a una solución basada en Java. : \


ACTUALIZACIÓN 09/08/2014:

Para el Seguimiento después de 3 años, he encontrado una biblioteca impresionante en NuGet y Github llamado "Humanizer" que resolvería este problema Estaba teniendo. No lo he usado tanto, pero lo probé y funciona muy bien. Aunque es bastante grande de una biblioteca (emite un montón de carpetas para diferentes culturas en la ruta de compilación de tu proyecto (estoy seguro de que hay una forma de personalizarlo)).

+0

enviar el enlace a las versiones de Java ... debe ser factible en C# :) – MattC

+0

@MattC: Eso me llevará unos minutos. Ya los cerré. :/ – Zack

+0

@MattC: eh. Aquí hay uno que es similar, pero con un formato diferente. Lo mismo generalmente de todos modos. http://stackoverflow.com/questions/3471397/pretty-print-duration-in-java – Zack

Respuesta

29

Y si se preocupan por la pluralización:

public static string ToPrettyFormat(this TimeSpan span) { 

    if (span == TimeSpan.Zero) return "0 minutes"; 

    var sb = new StringBuilder(); 
    if (span.Days > 0) 
     sb.AppendFormat("{0} day{1} ", span.Days, span.Days > 1 ? "s" : String.Empty); 
    if (span.Hours > 0) 
     sb.AppendFormat("{0} hour{1} ", span.Hours, span.Hours > 1 ? "s" : String.Empty); 
    if (span.Minutes > 0) 
     sb.AppendFormat("{0} minute{1} ", span.Minutes, span.Minutes > 1 ? "s" : String.Empty); 
    return sb.ToString(); 

} 
+0

Ahhh. Eso se ve bonito. +1 Gracias a todos los que publicaron una respuesta aquí. ;) – Zack

+0

Esto cortará el espacio final: sb.Remove (sb.Length - 1, 1); – solublefish

+0

Para cualquiera que esté considerando esto, hay un error en el código anterior. Si la duración es superior a cero segundos pero inferior a 1 minuto, pasa la verificación 'TimeSpan.Zero' pero luego devuelve una cadena vacía. Necesita evaluar 'span.Seconds' antes de devolver' sb'. –

9

Usted puede simplemente la salida de manera directa:

string result = string.Format("{0} days, {1} hours, {2} minutes", duration.Days, duration.Hours, duration.Minutes); 

Si va a ser el manejo de los tiempos "cortas", y desea que esto sea más limpia, se podía hacer algo como:

public string PrettyFormatTimeSpan(TimeSpan span) 
{ 
    if (span.Days > 0) 
     return string.Format("{0} days, {1} hours, {2} minutes", span.Days, span.Hours, span.Minutes); 
    if (span.Hours > 0) 
     return string.Format("{0} hours, {1} minutes", span.Hours, span.Minutes); 

    return string.Format("{0} minutes", span.Minutes); 
} 
+3

+1 si pudiera ... SO está diciendo que ya he votado esta respuesta ...:/ – Zack

+0

Bien , ni siquiera compila. Reemplace la duración con span. – Henrik