Home > .net 3.5, c#, Visual Studio 2008 > Creating Twitter-esque Relative Dates in C#

Creating Twitter-esque Relative Dates in C#

August 21, 2008

Recently, I was asked if we could have “relative dates like on Twitter” for a project.  With a great deal surprise (they knew what Twitter was??), I thought about it for a second and said, “Sure, why not”

Twitter relative dates

It’s just a machine—how difficult can it be?  Well, actually, not very difficult in C#. 

Here’s what I came up with to handle everything from seconds to years.  It’s not really pretty and, honestly, may not be that efficient (I haven’t ran it with tens of thouasnds of dates at once and benchmarked it), but it works well and is convenient as an extension method.

/// <summary>

/// Converts the specified DateTime to its relative date.

/// </summary>

/// <param name=”dateTime”>The DateTime to convert.</param>

/// <returns>A string value based on the relative date

/// of the datetime as compared to the current date.</returns>

public static string ToRelativeDate(this DateTime dateTime)

{

var timeSpan = DateTime.Now – dateTime;

 

       // span is less than or equal to 60 seconds, measure in seconds.

       if (timeSpan <= TimeSpan.FromSeconds(60))

{

              return timeSpan.Seconds + ” seconds ago”;

}

// span is less than or equal to 60 minutes, measure in minutes.

if (timeSpan <= TimeSpan.FromMinutes(60))

{

    return timeSpan.Minutes > 1

        ? “about “ + timeSpan.Minutes + ” minutes ago”

        : “about a minute ago”;

}

// span is less than or equal to 24 hours, measure in hours.

if (timeSpan <= TimeSpan.FromHours(24))

{

    return timeSpan.Hours > 1

        ? “about “ + timeSpan.Hours + ” hours ago”

        : “about an hour ago”;

}

// span is less than or equal to 30 days (1 month), measure in days.

if (timeSpan <= TimeSpan.FromDays(30))

{

    return timeSpan.Days > 1

        ? “about “ + timeSpan.Days + ” days ago”

        : “about a day ago”;

}

// span is less than or equal to 365 days (1 year), measure in months.

if (timeSpan <= TimeSpan.FromDays(365))

{

    return timeSpan.Days > 30

        ? “about “ + timeSpan.Days / 30 + ” months ago”

        : “about a month ago”;

}

 

// span is greater than 365 days (1 year), measure in years.

return timeSpan.Days > 365

    ? “about “ + timeSpan.Days / 365 + ” years ago”

    : “about a year ago”;

}

Output:

Friday, September 18, 1981 :: about 26 years ago
Monday, August 06, 2001 :: about 7 years ago

Known Gotchas:

Notice that I’m not accounting for leap years—every year is 365 instead of 366 every fourth year [year calculations are fun!].  Given a certain number of years, you’d eventually be a few days, then weeks, then months ahead.  You could accomodate for this in the timeSpan, but for a ‘relative date’—does that add value (unless wanting the relative date of 10,000 years ago and it shows up as 10,001.

About these ads
  1. August 21, 2008 at 3:22 pm

    I’ve got an almost identical method that I use in a ton of projects. In most situations, people don’t care about the exact date, so I slip it in there by using the ACRONYM tag and have the tooltip show the exact date and time if they mouse over it.

    string.Format(“{1} minutes ago“, dt, timeSpan.Minutes)

    Then I’ll style the acronym with a dotted border and a help cursor so it’s a little more obvious that something’s there, but not so bold as to be distracting.

    acronym { border-bottom: 1px dotted #ccc; cursor: help; }

  2. August 21, 2008 at 3:25 pm

    @Bryan-

    Ahh, brilliant idea. It’s coming up in alt tags at the moment, but that’d be less intrusive (and misused) as it won’t flood the page with fake link tags.

  3. Ben
    January 8, 2009 at 7:53 am

    Thanks for this useful function

    I noticed that it sometimes generates “about 1 months ago”

    This can be fixed by changing the line
    return timeSpan.Days > 30
    to
    return (timeSpan.Days / 30) > 1

    Also how about “yesterday” instead of “about a day ago” ?

  4. January 8, 2009 at 8:19 am

    @Ben-

    Could you provide a test case (if you have one) where it doesn’t generate one month correctly–I haven’t ran into that yet and would love to add the edge case to my tests. :)

    The “yesterday” vs. “about a day ago” is a great idea, though IMHO, would break the consistency of the labels and the “about..”. Also, it’d require some testing to make sure that it communicated ‘yesterday’ appropriately.

    At 01:00, something posted at 23:00 the prior day would technically be “yesterday”, but with the current counts would read as “about 2 hours ago…” :)

  1. No trackbacks yet.
Comments are closed.
Follow

Get every new post delivered to your Inbox.

%d bloggers like this: