Zach’s ugly mug (his face) Zach Leatherman

Yet Another Pretty Date JavaScript

March 23, 2008

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.

Update: This script has been moved to Github.


< Newer
Architecture Choices: Callbacks and Events in JavaScript
Older >
Minor Annoyances with Firefox Development

Zach Leatherman IndieWeb Avatar for https://zachleat.com/is a builder for the web at IndieWeb Avatar for https://cloudcannon.com/CloudCannon. He is the creator and maintainer of IndieWeb Avatar for https://www.11ty.devEleventy (11ty), an award-winning open source site generator. At one point he became entirely too fixated on web fonts. He has given 79 talks in nine different countries at events like Beyond Tellerrand, Smashing Conference, Jamstack Conf, CSSConf, and The White House. Formerly part of Netlify, Filament Group, NEJS CONF, and NebraskaJS. Learn more about Zach »

25 Comments
  1. Dean Landolt Disqus

    25 Mar 2008
    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 Disqus

    26 Mar 2008
    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. Jauder Ho Disqus

    27 Mar 2008
    Cool. This came in useful. Thanks for hacking this out.
  4. Zach Leatherman Disqus

    28 Mar 2008
    I appreciate the comment. I hope someone else gets some good use out of it.
  5. Gary Sherman Disqus

    06 May 2008
    Zach,Very nice! This is exactly what I was looking for.Thanks for sharing!
  6. Hunka Disqus

    20 May 2008
    it is really nice script.
  7. unwiredbrain Disqus

    28 Jun 2008
    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 Disqus

    29 Jun 2008
    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/327787Leaving 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 Disqus

    08 Jan 2009
    @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 Disqus

    08 Jan 2009
    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 Disqus

    21 Jan 2009
    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 Disqus

    21 Jan 2009
    replacing line 34 with this fixes it for me:seconds = ((dt - new Date(time)) / 1000),
  13. Zach Leatherman Disqus

    21 Jan 2009
    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 Disqus

    17 Mar 2009
    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.
    1. Zach Leatherman Disqus

      17 Mar 2009
      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.
  15. Donny Kurnia Disqus

    18 Apr 2009
    Hi, I just find out this post from john post about pretty date.@unwiredbrainYou must change the date to shown in title attribute into GMT. So it must written as:Some event that just happenedSee 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
  16. Donny Kurnia Disqus

    18 Apr 2009
    @webmackThe 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.
  17. tristan Disqus

    12 Jun 2009
    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...
  18. Zach Leatherman Disqus

    12 Jun 2009
    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?
  19. tristan Disqus

    12 Jun 2009
    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+0000Firefox finds this as an invalid date.
  20. Zach Leatherman Disqus

    13 Jun 2009
    Hey Tristan, as mentioned in some of the previous comments, your dates should be ISO8601 using GMT:2009-06-03T20:06:44ZThanks!
  21. Sherman Monroe Disqus

    05 Aug 2011
    Small tweak, it wasn't accounting for GMT time, thus, it parsed 10:00 am CST, which is 15:00 GMT time, and told me "5 hours ago" when viewing it at 10:05 am. So I made the following change at line 34, but don't know how this will affect all cases:seconds = ((dt - new Date(time) + ((-dt.getTimezoneOffset()/60) * 60000)) / 1000),
  22. Zach Leatherman Disqus

    05 Aug 2011
    Hey Sherman,You can make your modification to the GitHub repo and run the unit tests:https://github.com/zachleat...Feel free to put in a Pull Request and I'll merge it in.Zach
  23. Johnie R Disqus

    19 Oct 2011
    Hey guys, I am pretty new to JS, but i am curious, if i wanted a date older than 4 weeks to say the actual date, how hard is that?Example: instead of saying 1 month ago, how about just September 18 @ 10:06PM.any feedback is appreciated. thanks.
  24. Aravind NC Disqus

    07 Feb 2012
    You saved the day man !!! Thanks a lot
Shamelessly plug your related post

These are webmentions via the IndieWeb and webmention.io.

Sharing on social media?

This is what will show up when you share this post on Social Media:

How did you do this? I automated my Open Graph images. (Peer behind the curtain at the test page)