Yet Another Pretty Date JavaScript

I can’t let this Pretty Date thing go. I decided to use a modification of John Resig’s Pretty Date JavaScript implementation written by Dean Landolt and shared in the comments on John’s page. The script was an obvious choice for the next iteration of Alarmd, which is nearing completion as I type.

The more I used Dean Landolt’s script, the more problems I began to see with his implementation. It was a good start, but definitely had bugs. His assumptions translating from integer second differences to human readable labels stretched too far at times (there is an error in logic to say anything between 24 hours and 48 hours from now can be labeled “Tomorrow”), and he was a bit loose with his difference categories (assumed average month length was 28 days, and always used Math.floor instead of rounding — 47 hours from now would be labeled “1 Day”). It was great code otherwise, and I definitely liked the way he used the while loop to run through the comparisons.

So, I’ve cleaned up his great start, and am releasing it to the world in the spirit of cooperation and open sauce. You just read that typo out loud didn’t you?

Download: Yet Another Pretty Date Implementation (2 KB)

Update: Dates for this script must have a specific ISO8601 format: YYYY-MM-DDTHH:MM:SSZ (in UTC) where T and Z are literals.

VN:F [1.8.1_1037]
Rating: 3.6/5 (5 votes cast)
Yet Another Pretty Date JavaScript3.655
This entry was posted in JavaScript, Projects and tagged , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.
  • Thanks for reading. If you found this article useful, and you've read through some of my previous articles, you might as well Subscribe to my content subscribe to my blog. You'll save me some bandwidth that way.

21 Comments

  1. Posted March 25, 2008 at 8:39 am | Permalink

    Thanks for the fixes. I actually can’t take credit for introducing those bugs (just completely missing them) — I got that piece of code from a comment on Resig’s original post which was actually the imputus for me to do the rewrite in the first place…

    I like your code a lot better than mine — cleaner and easier to understand.

  2. Zach Leatherman
    Posted March 25, 2008 at 4:17 pm | Permalink

    Thanks Dean. I wouldn’t have even noticed the problems had I not been trying to use the script for a project.

    Open source moves solely due to impetus sometimes.

  3. Posted March 27, 2008 at 1:33 am | Permalink

    Cool. This came in useful. Thanks for hacking this out.

  4. Zach Leatherman
    Posted March 27, 2008 at 11:15 pm | Permalink

    I appreciate the comment. I hope someone else gets some good use out of it.

  5. Posted May 5, 2008 at 3:39 pm | Permalink

    Zach,

    Very nice! This is exactly what I was looking for.
    Thanks for sharing!

  6. Posted May 20, 2008 at 7:30 am | Permalink

    it is really nice script.

  7. unwiredbrain
    Posted June 28, 2008 at 9:28 am | Permalink

    Very nice work.

    But there’s something I really don’t get: if I’m using a future date (think about a dtstart / dtend duet, like hCalendar does), the script treats them as past events!

    If current year is 2008 and I’m planning some event for year 2009, the script says “1 Year Ago”! This is undoubtedly wrong! And should be avoided, of course.

    For me, the problem resides in the first if clause: seconds should not be modified; if seconds are less than zero, then the script should do nothing, returning null.

    A null returning would be very comfortable, allowing control statements as John Resig did in his original scripts; in particular, would be comfortable because you would not soil the innerHTML.

    Also, if you avoid the token, all the script will instantly get more suitable for l10n, making the code more clean and readable.

  8. unwiredbrain
    Posted June 28, 2008 at 9:21 pm | Permalink

    OK. Wait a sec. My previous comment clearly shows that I did not understand anything about your script. I apologize for that.

    But…

    I (think I) found a glitch — from now on consider all the dates & everything treated as UTC: if you set a date to exactly now (where “now” is the instant where the page loads) the script returns a “2 Hours” — I mean: future!

    Is to be said that I live in a country where right now the time zone is CEST that is GMT plus two hours (see Wikipedia for more), but, as you can easily imagine, in other countries this could vary: zero, one or two, like me, or even more.

    Now: all your script runs using UTC (which is good), but at line 34 you add the current local time zone offset, which is wrong in my opinion.

    I think that this should be fixed, but I look forward to your opinion.

    Anyway, I still think that you should never touch a future date, and I still think that by removing the token you’ll get a more compact, readable and elegant code.

    PS: just FYI, here’s my test case: http://phpfi.com/327787

    Leaving the script vanilla, I get the glitch; removing the time zone offset I get the correct behavior.

    Also, you can test this by adding some minutes: just modify the ‘difference’ variable in the HTML document.

    I hope the whole thing is clearer now.

    Have a nice day.

  9. Zach Leatherman
    Posted January 7, 2009 at 7:57 pm | Permalink

    @unwiredbrain I tried to check out your test script and it would seem that the link is down.

    Can you repost somewhere else, or include the code?

    I developed this for alarmd, so you can see it in action there. If you add an alarm, it will create a pretty date in the bottom right corner.

    For instance, I just added an alarm for +1h, resulting in 2009-01-08T02:56:38Z. I’m in CST (-6), which is is right (it’s now 7:56PM).

    Thanks,
    Zach

  10. unwiredbrain
    Posted January 8, 2009 at 2:10 am | Permalink

    Zach,

    not receiving a reply for months I deleted all the relative documents; my documents deleted, phpfi.com down… Guess what? I had to recreate the glitch from scratch.

    Let’s assume my current system date is 2008-01-08;
    Let’s assume my current system time is 08:45:00;
    Let’s assume my current time zone offset is +0100;
    Let’s assume my current span looks like this:
    <span class="dtstart" title="2009-01-08T08:45:00Z+0100">Some event that just happened</span>

    On my test page, launching $(".dtstart").humane_dates() I will see “60 Minutes”. Which is future.
    That’s exactly my current local time added with my current local time zone offset.

    Apart from the glitch; being a future event, isn’t it supposed to be left as it was — i.e. not humanized at all?

  11. webmack
    Posted January 20, 2009 at 8:37 pm | Permalink

    I confirm what unwiredbrain says. The script adds the timezoneoffset to the current local time returning a humanized date that is in the future..

    eg. ‘11 hours’ no ago..

  12. webmack
    Posted January 20, 2009 at 8:45 pm | Permalink

    replacing line 34 with this fixes it for me:


    seconds = ((dt - new Date(time)) / 1000),

  13. Zach Leatherman
    Posted January 20, 2009 at 11:34 pm | Permalink

    I believe the script should work as intended (as is).

    It should be noted that including a timezone offset into your markup date is not a supported use case for this script. Outputting UTC time only (no hardcoded offsets in the dates) allows for the JavaScript code to interpret the date to the offset of the client.

    I believe that adding support for hardcoded timezone offsets would add unnecessary complexity to the code. Output Z +/- 0 and it will work fine.

    That being said, if you disagree, feel free to modify the script and re-release it! It’s all open source.

  14. Frank
    Posted March 16, 2009 at 2:01 pm | Permalink

    Whats are you trying to do with the .replace(/[TZ]/g, ” “) call?

    It ends up removing all the letter Ts. so some dates fail.

    e.g. “Thu Feb 5 08:02:38 PST 2009″ is parsed as
    “hu Feb 5 08:02:38 PST 2009″ and subsequently fails.

  15. Zach Leatherman
    Posted March 16, 2009 at 7:10 pm | Permalink

    Hey Frank,
    Take a look at the Original Script, it’s intended to take ISO8601 dates, such as “2008-01-28T20:24:17Z”

    The T and Z removal make more sense in that context.

  16. Posted April 18, 2009 at 7:15 am | Permalink

    Hi, I just find out this post from john post about pretty date.

    @unwiredbrain
    You must change the date to shown in title attribute into GMT. So it must written as:
    Some event that just happened

    See that it is 7:45 in GMT, because your timezone is +01:00.

    The javascript will use the browser timezone setting, so the result will be correct.

    If you are using PHP in the server-side, this is the code to change timestamp into GMT (using server’s timezone setting), then format it to become ISO.

    http://pastie.org/450720

  17. Posted April 18, 2009 at 7:20 am | Permalink

    @webmack

    The line 34 is to overcome the timezone setting in user’s browser. Since the calculation is done in each user browser, the js script must know how much the time different is.

    If you remove the (dt.getTimezoneOffset() * 60000) addition, all user browser is assumed at GMT.

    The addition is proposed by Dean in the comment at john blog. So the date that must changed is the one in the html. It must in GMT.

    Check my previous comment to find the way to convert local server date into GMT, then show it as ISO format using PHP.

  18. tristan
    Posted June 11, 2009 at 6:54 pm | Permalink

    Has anyone else noticed that this script, when implemented with JQuery, will not work on firefox 3? I’m trying to find a solution, but currently it just outputs the original date string, and does not format it…

  19. Zach Leatherman
    Posted June 11, 2009 at 8:03 pm | Permalink

    I use the script in ALARMd, so I know that it works in Firefox 3. What date are you trying to transform that doesn’t work?

  20. tristan
    Posted June 11, 2009 at 8:06 pm | Permalink

    Hi there, If you can help you will end hours of head scratching. The dates i’m working with look like: 2009-06-03 20:06:44+0000
    Firefox finds this as an invalid date.

  21. Zach Leatherman
    Posted June 13, 2009 at 8:38 am | Permalink

    Hey Tristan, as mentioned in some of the previous comments, your dates should be ISO8601 using GMT:
    2009-06-03T20:06:44Z

    Thanks!

4 Trackbacks

  1. [...] Human Readable Alarm Dates: Think “29 Minutes”, “1 Hour”, “2 Days Ago”. [...]

  2. By Gary Sherman : Pretty Dates in JavaScript on May 5, 2008 at 3:58 pm

    [...] Finally, Zach Letterman commented that he updated Dean’s script, and posted a newer version. [...]

  3. [...] Address Geocoder hosted by MaxMind that’s worth a look. It also uses a previously mentioned JavaScript Pretty Date Difference [...]

  4. By girtby.net – Monkeying With JavaScript on January 7, 2009 at 5:31 am

    [...] chance I came across yet another pretty date JavaScript from Zach Leatherman (but with ancestry tracing back to jQuery author John Resig). This allowed me [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

Additional comments powered by BackType