2010-08-01 3 views
7

J'ai ce code pour prendre un temps dans le passé et générer une chaîne lisible pour représenter depuis combien de temps il était.Y a-t-il un moyen plus intelligent de générer du "temps depuis" avec un objet DateTime?

  1. j'aurais Timespan.Hours de pensée ne vous donnera des heures même si ses multiples Daye dans le passé, mais on dirait qu'il se décompose en ses composants séparés (jours, mois, etc.). Comment puis-je obtenir il y a nombre total d'heures (même si son plus de 1 jour?

  2. Y at-il plus propre façon d'écrire ce type de code ci-dessous car il semble assez spagetti-ish.

Voici le code

 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

Une langue peut aider – TheLQ

+0

Semble être C#. –

+0

@ Lord.Quackstar - balises mises à jour et question – leora

Répondre

13

Utilisez le

propriété TotalHours ou d'autres Total[TimeUnit] propriétés dans l'objet timespan. Pour un timespan de 01h10 (hh: mm), il correspond à 1 Hours et 10 Minutes ou 1,167 TotalHours et 70 TotalMinutes. Pour ce qui est du nettoyage, respectez les branches if/else comme vous l'avez fait plus tôt. switch/case ne vous aidera pas avec ces conditions, seulement pour des valeurs spécifiques. Quelque chose comme ceci:

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 - merci.Toutes les idées sur la deuxième question ou est-ce ci-dessus est fondamentalement la solution – leora

1

Comme alternative, j'ai une solution qui fait qu'au-delà de jours avec des semaines, des mois et des années. L'approche est un peu différente Elle avance du passé vers le futur, en essayant d'abord les grandes étapes et en dépassant le passage au plus petit.

PeriodOfTimeOutput.cs

0

Je sais que c'est un ancien poste, mais je suis venu avec cette solution à l'aide récursion après la recherche de ce sujet et de lire la réponse 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; 
} 

utilisés en tant que tels

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

Une réponse très tardive, mais j'ai ressenti le besoin de cela, et la recherche de termes communs JS tels que "C# momentjs datetime" ou "C# timeago" a montré des résultats qui n'étaient pas du tout utiles - je ne veux pas garder de code supplémentaire avec des nombres magiques codés en dur et qui ne seront pas adaptés à la localisation. Alors, enfin, dans l'un des commentaires dans une autre réponse, je trouve la bibliothèque:

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

Utilisation:

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

Et c'est localisable aussi!

+0

Absolument la bonne réponse. –