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.

Subscribe
Follow
21 Comments
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.
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.
Cool. This came in useful. Thanks for hacking this out.
I appreciate the comment. I hope someone else gets some good use out of it.
Zach,
Very nice! This is exactly what I was looking for.
Thanks for sharing!
it is really nice script.
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.
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.
@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
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?
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..
replacing line 34 with this fixes it for me:
seconds = ((dt - new Date(time)) / 1000),
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.
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.
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.
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
@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.
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…
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?
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.
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
[...] Human Readable Alarm Dates: Think “29 Minutes”, “1 Hour”, “2 Days Ago”. [...]
[...] Finally, Zach Letterman commented that he updated Dean’s script, and posted a newer version. [...]
[...] Address Geocoder hosted by MaxMind that’s worth a look. It also uses a previously mentioned JavaScript Pretty Date Difference [...]
[...] 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 [...]