jQuery Timeago and Django DateTimeFields
Here’s a (relatively) quick one, kids.
I love Django and its humble ORM. We’ve been casually dancing for the past five or so years, and it seems like things could be getting serious between us.
I also love timeago, a jQuery plugin that replaces ugly date/time strings with fuzzy approximations that humans (like myself) can understand.
I’ve always found date/time programming to be a real pain in the foot. There exists ISO 8901, which attempts to standardize the exchange of dates and times, but the myriad of variations that count as “standard” can result in systems adopting some subset of them to work with instead of fretting over each iteration.
Django’s built-in template filter for datetime formatting (appropriately called date) has a new parameter coming in Django 1.2 (example usage: somedatetime|date:"c") that gives you a full ISO 8601 representation without much work. Example output for that (directly lifted from Django’s documentation) is provided below:
2008-01-02 10:30:00.000123
So what’s the catch, man?
So all is well so far, but there’s a hitch. You see, using timeago on dates generated by somedatetime|date:"c" simply doesn’t work.
I spent some time digging through timeago’s source to find the issue and it seems that Django’s ISO 8601-compliant output is slightly too specific for timeago. It turns out that timeago hates microseconds, which date:"c" includes. When timeago encounters a string containing microsecond, it just quits.
Taming the Tiger
So how do we work around this? As soon as I get a few spare minutes, I’ll be submitting a patch to timeago that allows it to work with ISO 8601 strings containing microseconds. For now (and as a backup plan in case I never find those spare minutes), you can use the following format string to generate a timeago compatible representation in your Django templates.
{{ somedatetime|date:'Y-m-d\TH:i:s' }}
If you’re running Django 1.1.x or earlier, the above snippet will get the job done for you as well.
I’m likely violating best practices here by not specifying timezone information, but my current project is an internal tool, so I just needed something working quickly.
Hope that helps.
Special Note: Django provides a template filter for datetimes called timesince that outputs a relative string, but I much prefer the casual fuzziness of timeago.
Update 4/17/2010: I’ve forked timeago to add a patch that discards any microsecond data and allows it to work out of the box with Django. Timeago’s tests all seem to be passing, so I’ll be submitting this upstream after I get my head around its test suite and write one covering this use case.