Wie kann ich bei einem bestimmten "DateTime"-Wert die relative Zeit anzeigen?
Jeff, dein Code ist schön, könnte aber mit Konstanten (wie in Code Complete vorgeschlagen) klarer sein.
const int SECOND = 1;
const int MINUTE = 60 * SECOND;
const int HOUR = 60 * MINUTE;
const int DAY = 24 * HOUR;
const int MONTH = 30 * DAY;
var ts = new TimeSpan(DateTime.UtcNow.Ticks - yourDate.Ticks);
double delta = Math.Abs(ts.TotalSeconds);
if (delta < 1 * MINUTE)
return ts.Seconds == 1 ? "one second ago" : ts.Seconds + " seconds ago";
if (delta < 2 * MINUTE)
return "a minute ago";
if (delta < 45 * MINUTE)
return ts.Minutes + " minutes ago";
if (delta < 90 * MINUTE)
return "an hour ago";
if (delta < 24 * HOUR)
return ts.Hours + " hours ago";
if (delta < 48 * HOUR)
return "yesterday";
if (delta < 30 * DAY)
return ts.Days + " days ago";
if (delta < 12 * MONTH)
{
int months = Convert.ToInt32(Math.Floor((double)ts.Days / 30));
return months <= 1 ? "one month ago" : months + " months ago";
}
else
{
int years = Convert.ToInt32(Math.Floor((double)ts.Days / 365));
return years <= 1 ? "one year ago" : years + " years ago";
}
So mache ich es
var ts = new TimeSpan(DateTime.UtcNow.Ticks - dt.Ticks);
double delta = Math.Abs(ts.TotalSeconds);
if (delta < 60)
{
return ts.Seconds == 1 ? "one second ago" : ts.Seconds + " seconds ago";
}
if (delta < 120)
{
return "a minute ago";
}
if (delta < 2700) // 45 * 60
{
return ts.Minutes + " minutes ago";
}
if (delta < 5400) // 90 * 60
{
return "an hour ago";
}
if (delta < 86400) // 24 * 60 * 60
{
return ts.Hours + " hours ago";
}
if (delta < 172800) // 48 * 60 * 60
{
return "yesterday";
}
if (delta < 2592000) // 30 * 24 * 60 * 60
{
return ts.Days + " days ago";
}
if (delta < 31104000) // 12 * 30 * 24 * 60 * 60
{
int months = Convert.ToInt32(Math.Floor((double)ts.Days / 30));
return months <= 1 ? "one month ago" : months + " months ago";
}
int years = Convert.ToInt32(Math.Floor((double)ts.Days / 365));
return years <= 1 ? "one year ago" : years + " years ago";
Verbesserungsvorschläge? Kommentare? Wie kann man diesen Algorithmus verbessern?
@jeff
IMHO scheint Ihre Lösung ein wenig zu lang. Allerdings scheint es mit der Unterstützung für "gestern" und "Jahre" ein wenig robuster zu sein. Meiner Erfahrung nach werden die Inhalte jedoch am ehesten in den ersten 30 Tagen angezeigt. Danach kommen nur noch die wirklich hartgesottenen Leute. Deshalb entscheide ich mich in der Regel dafür, die Seite kurz und einfach zu halten.
Dies ist die Methode, die ich derzeit auf einer meiner Websites verwende. Sie liefert nur einen relativen Tag, eine Stunde und eine Uhrzeit. Und dann muss der Benutzer bei der Ausgabe auf "ago" klicken.
public static string ToLongString(this TimeSpan time)
{
string output = String.Empty;
if (time.Days > 0)
output += time.Days + " days ";
if ((time.Days == 0 || time.Days == 1) && time.Hours > 0)
output += time.Hours + " hr ";
if (time.Days == 0 && time.Minutes > 0)
output += time.Minutes + " min ";
if (output.Length == 0)
output += time.Seconds + " sec";
return output.Trim();
}