C# extension method that returns a relative humanized date string indicating how long ago something happened, eg "3 days ago". For future dates, returns when this DateTime will occur from DateTime.UtcNow.
public static class ExtensionMethods
{
/// <summary>
/// Returns a humanized string indicating how long ago something
/// happened, eg "3 days ago". For future dates, returns when this
/// DateTime will occur from DateTime.UtcNow.
/// </summary>
public static string ToRelativeTime(this DateTime dt)
{
DateTime utcNow = DateTime.UtcNow;
return dt <= utcNow ? ToRelativeTimePast(dt, utcNow) : ToRelativeTimeFuture(dt, utcNow);
}
private static string ToRelativeTimePast(DateTime dt, DateTime utcNow)
{
TimeSpan ts = utcNow - dt;
double delta = ts.TotalSeconds;
if (delta < 60)
{
return ts.Seconds == 1 ? "1 sec ago" : ts.Seconds + " secs ago";
}
if (delta < 3600) // 60 mins * 60 sec
{
return ts.Minutes == 1 ? "1 min ago" : ts.Minutes + " mins ago";
}
if (delta < 86400) // 24 hrs * 60 mins * 60 sec
{
return ts.Hours == 1 ? "1 hour ago" : ts.Hours + " hours ago";
}
int days = ts.Days;
if (days == 1)
{
return "yesterday";
}
if (days <= 2)
{
return days + " days ago";
}
if (days <= 330)
{
return dt.ToString("MMM %d 'at' %H:mmm");
}
return dt.ToString(@"MMM %d \'yy 'at' %H:mmm");
}
private static string ToRelativeTimeFuture(DateTime dt, DateTime utcNow)
{
TimeSpan ts = dt - utcNow;
double delta = ts.TotalSeconds;
if (delta < 60)
{
return ts.Seconds == 1 ? "in 1 second" : "in " + ts.Seconds + " seconds";
}
if (delta < 3600) // 60 mins * 60 sec
{
return ts.Minutes == 1 ? "in 1 minute" : "in " + ts.Minutes + " minutes";
}
if (delta < 86400) // 24 hrs * 60 mins * 60 sec
{
return ts.Hours == 1 ? "in 1 hour" : "in " + ts.Hours + " hours";
}
// use our own rounding so we can round the correct direction for future
var days = (int)Math.Round(ts.TotalDays, 0);
if (days == 1)
{
return "tomorrow";
}
if (days <= 10)
{
return "in " + days + " day" + (days > 1 ? "s" : "");
}
if (days <= 330)
{
return "on " + dt.ToString("MMM %d 'at' %H:mmm");
}
return "on " + dt.ToString(@"MMM %d \'yy 'at' %H:mmm");
}
}