2010-08-01 8 views
7

tengo este código para tomar un tiempo en el pasado y generar una cadena legible para representar cuánto tiempo atrás fue.existe una forma más inteligente de generar "tiempo desde" con un objeto DateTime

  1. que tendría Timespan.Hours pensó que le dará horas aunque su daye múltiple en el pasado, pero parece que lo descompone en sus componentes separados (días, meses, etc.). ¿Cómo puedo obtener Hace total de horas (aunque su más de 1 día?

  2. ¿Hay alguna manera más clara para escribir este tipo de código de abajo, ya que parece bastante espagueti-ish.

Aquí es el código

 DateTime when = GetDateTimeinPast(); 
     TimeSpan ts = DateTime.Now.Subtract(when); 

     switch (ts.Days) 
     { 
      case 0: 
       if (ts.Hours < 1) 
        b.Append(ts.Minutes + " minutes ago"); 
       else 
        b.Append(ts.Hours + " hours ago"); 
       break; 
      case 1: 
       b.Append(" yesterday"); 
       break; 
      case 2: 
      case 3:     
      case 4: 

       b.Append("on " + when.DayOfWeek.ToString()); 
       break; 
      default: 
       b.Append(ts.Days + " days ago"); 
       break; 
     } 
+0

Un idioma podría ayudar – TheLQ

+0

Parece ser C#. –

+0

@ Lord.Quackstar - etiquetas actualizadas y pregunta – leora

Respuesta

13

Utilice la propiedad TotalHours u otros Total[TimeUnit] propiedades en el objeto de intervalo de tiempo.

Para un intervalo de tiempo de 1:10 (hh: mm), equivale a 1 Hours y 10 Minutes o 1.167 TotalHours y 70 TotalMinutes.

En cuanto a la limpieza, adhiérase a usar ramas if/else como lo hizo anteriormente. switch/case no lo ayudará con estas condiciones, solo para valores específicos. Algo como esto:

DateTime when = GetDateTimeinPast(); 
TimeSpan ts = DateTime.Now.Subtract(when); 
if (ts.TotalHours < 1) 
    b.AppendFormat("{0} minutes ago", (int)ts.TotalMinutes); 
else if (ts.TotalDays < 1) 
    b.AppendFormat("{0} hours ago", (int)ts.TotalHours); 
//etc... 
+0

M - gracias.Cualquier idea sobre la segunda pregunta o es esto de arriba es básicamente la solución – leora

1

Como alternativa, tengo una solución que lo hace más allá de días con semanas, meses y años. El enfoque es un poco diferente. Avanza del pasado al futuro, primero probando los grandes pasos y si pasa demasiado tiempo cambiando al próximo más pequeño.

PeriodOfTimeOutput.cs

0

Sé que esto es una entrada antigua, pero se me ocurrió con esta solución utilizando la recursividad después de buscar este tema y leer la respuesta de Jeff Mercado

private string PeriodOfTimeOutput(TimeSpan tspan, int level = 0) 
{ 
    string how_long_ago = "ago"; 
    if (level >= 2) return how_long_ago; 
    if (tspan.Days > 1) 
     how_long_ago = string.Format("{0} Days ago", tspan.Days); 
    else if (tspan.Days == 1) 
     how_long_ago = string.Format("1 Day {0}", PeriodOfTimeOutput(new TimeSpan(tspan.Hours, tspan.Minutes, tspan.Seconds), level + 1)); 
    else if (tspan.Hours >= 1) 
     how_long_ago = string.Format("{0} {1} {2}", tspan.Hours, (tspan.Hours > 1) ? "Hours" : "Hour", PeriodOfTimeOutput(new TimeSpan(0, tspan.Minutes, tspan.Seconds), level + 1)); 
    else if (tspan.Minutes >= 1) 
     how_long_ago = string.Format("{0} {1} {2}", tspan.Minutes, (tspan.Minutes > 1) ? "Minutes" : "Minute", PeriodOfTimeOutput(new TimeSpan(0, 0, tspan.Seconds), level + 1)); 
    else if (tspan.Seconds >= 1) 
     how_long_ago = string.Format("{0} {1} ago", tspan.Seconds, (tspan.Seconds > 1) ? "Seconds" : "Second");   
    return how_long_ago; 
} 

utilizarse como tales

var tspan = DateTime.Now.Subtract(reqDate); 
string how_long_ago = PeriodOfTimeOutput(tspan); 
1

Una respuesta muy tardía, pero sentí la necesidad de esto, y la búsqueda de términos comunes de JS como "C# momentjs datetime" o "C# timeago" mostró resultados que no fueron del todo útiles. No quiero mantener un código adicional con números mágicos codificados y que no será amigable con la localización. Así que, finalmente, en uno de los comentarios en otro SO responder, me encontré con la biblioteca:

Humanizer para .NET - https://github.com/Humanizr/Humanizer#humanize-datetime

Uso:

DateTime.UtcNow.AddHours(-2).Humanize() => "2 hours ago" 

Y es localizable también!

+0

Absolutamente la respuesta correcta. –

Cuestiones relacionadas