Home » Questions » Computers [ Ask a new question ]

datetime - Calculate relative time in C# -

"Given a specific DateTime value, how do I display relative time, like:

2 hours ago
3 days ago
a month ago






c# datetime time datediff relative-time-span












ShareShare a link to this question Copy linkCC BY-SA 3.0



Improve this question




Follow
Follow this question to receive notifications











edited Jun 4 '17 at 15:51
















community wiki




23 revs, 20 users 24%Jeff Atwood"

Asked by: Guest | Views: 317
Total answers/comments: 3
bert [Entry]

"Jeff, your code is nice but could be clearer with constants (as suggested in Code Complete).

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"";
}"
bert [Entry]

"jquery.timeago plugin

Jeff, because uses jQuery extensively, I recommend the jquery.timeago plugin.

Benefits:

Avoid timestamps dated ""1 minute ago"" even though the page was opened 10 minutes ago; timeago refreshes automatically.
You can take full advantage of page and/or fragment caching in your web applications, because the timestamps aren't calculated on the server.
You get to use microformats like the cool kids.

Just attach it to your timestamps on DOM ready:

jQuery(document).ready(function() {
jQuery('abbr.timeago').timeago();
});

This will turn all abbr elements with a class of timeago and an ISO 8601 timestamp in the title:

<abbr class=""timeago"" title=""2008-07-17T09:24:17Z"">July 17, 2008</abbr>

into something like this:

<abbr class=""timeago"" title=""July 17, 2008"">4 months ago</abbr>

which yields: 4 months ago. As time passes, the timestamps will automatically update.

Disclaimer: I wrote this plugin, so I'm biased."
bert [Entry]

"public static string RelativeDate(DateTime theDate)
{
Dictionary<long, string> thresholds = new Dictionary<long, string>();
int minute = 60;
int hour = 60 * minute;
int day = 24 * hour;
thresholds.Add(60, ""{0} seconds ago"");
thresholds.Add(minute * 2, ""a minute ago"");
thresholds.Add(45 * minute, ""{0} minutes ago"");
thresholds.Add(120 * minute, ""an hour ago"");
thresholds.Add(day, ""{0} hours ago"");
thresholds.Add(day * 2, ""yesterday"");
thresholds.Add(day * 30, ""{0} days ago"");
thresholds.Add(day * 365, ""{0} months ago"");
thresholds.Add(long.MaxValue, ""{0} years ago"");
long since = (DateTime.Now.Ticks - theDate.Ticks) / 10000000;
foreach (long threshold in thresholds.Keys)
{
if (since < threshold)
{
TimeSpan t = new TimeSpan((DateTime.Now.Ticks - theDate.Ticks));
return string.Format(thresholds[threshold], (t.Days > 365 ? t.Days / 365 : (t.Days > 0 ? t.Days : (t.Hours > 0 ? t.Hours : (t.Minutes > 0 ? t.Minutes : (t.Seconds > 0 ? t.Seconds : 0))))).ToString());
}
}
return """";
}

I prefer this version for its conciseness, and ability to add in new tick points.
This could be encapsulated with a Latest() extension to Timespan instead of that long 1 liner, but for the sake of brevity in posting, this will do.
This fixes the an hour ago, 1 hours ago, by providing an hour until 2 hours have elapsed"