Tuesday, November 27th, 2007
Mad Cool Date Library
Ok, I’ve seen some cool libraries in my time but I’ve just found one that is ssssooo cool that I didn’t want to wait to post about it until tomorrow (sorry Dion!).
So I get this email from a bud asking me to check out this date handling library and I’m figuring “great, Yet Another Date Library”. So I jump on over to Datejs.com to check it out and I’m presented with a nice looking site. I mean the little ninja dude at top is pretty slick! Anyways, I digress.
I start reading up on it and I see the usual pitch:
Datejs is an open-source JavaScript Date Library.
Comprehensive, yet simple, stealthy and fast. Datejs has passed all trials and is ready to strike. Datejs doesn’t just parse strings, it slices them cleanly in two.
Read that before, must be the same ole, blah, blah. So I look for like a date picker or something and all I see is a text box. Hmm. I see some suggestions listed below it:
So I give it a go and…woah!
Okay, lucky try. I know if I try that t+5years, it’s gonna choke.
Holy cow!!! All I have to say is wow. This is a VERY cool date library and definitely unique. I’ve not seen anything like this.
Datejs is the brainchild of Geoffrey McGill and the team at Coolite. It was developed to handle both parsing, formatting and processing of dates within the JS language. Apart from its incredible parsing capabilities, it also supports a TON of different language formats!
All 150+ CultureInfo files have been pre-compiled and are available within the same /build/ folder as date.js. Each culture file includes translations for many of the strings used in the Datejs library. Some strings have not been translated, although will be filled in over time as the community contributes.
The widget does a complete Date.parse(text) on each keystroke. Notice that no ‘date format’ is passed into the Parser. The Parser figures everything out on it’s own.
The API is also so simple to use. I mean just look below at the code examples. It doesn’t get much easier then that:
// What date is next thursday?
Date.today().next().thursday();
// Add 3 days to Today
Date.today().add(3).days();
// Is today Friday?
Date.today().is().friday();
// Number fun
(3).days().ago();
// 6 months from now
var n = 6;
n.months().fromNow();
// Set to 8:30 AM on the 15th day of the month
Date.today().set({ day: 15, hour: 8, mintue: 30 });
// Convert text into Date
Date.parse(‘today’);
Date.parse(‘t + 5 d’); // today + 5 days
Date.parse(‘next thursday’);
Date.parse(‘February 20th 1973′);
Date.parse(‘Thu, 1 July 2004 22:30:00′);
Overall, Datejs is REALLY impressive and I’m definitely going to see where I can use it in. Datejs is released under the MIT License and available for download at GoogleCode.
















Very cool! I need a server side version of this. Maybe it can be run using Rhino?
I was hoping, “Christmas,” would work since it is coming up!
rememberthemilk.com has always (as far as I know) had date parsing like this.
Thing is, some people don’t like the user interface on this because they shy away from the keyboard, thinking the mouse interaction with little calendars is better. Actually typing in a date can be much faster.
But what is definitely cool is the I18N support.
Hmmm. Looks like the same idea as Simon Willison’s date control that I’ve been using for forever (he announced in 2003 apparently: see http://simonwillison.net/2003/Oct/6/betterDateInput/).
Willison’s javascript library doesn’t have as many different formats (t +5) but it has the same basic idea of using free form date input plus a few special ones like “next friday”, etc… It’d be nice to see the idea spread - why force users to enter in a format like mm-dd-yy or click on a popup calendar?
how about “first monday next month”? it seems to fail…
Nice library, but a shame that it splooges methods and properties all over the Date and Number prototypes :(
Perl has had this (and it can be serverside.)
Its called Date::Manip.
http://www.cise.ufl.edu/~sbeck/Date-Manip.html#examples
If you’re using php, strtotime does this also.
Anyone know something similar for python?
Try put in “the day after tomorrow”.
10/10
Very cool, but the more complex you make your “date” the more confused it gets… while I wouldn’t expect “tomorrow last april +5years” to be a common entry, it doesn’t currently work, and there are some common phrases that don’t parse will (like the above “day after tomorrow” phrase).
All in all though, I gave it 5/5, its a nifty tool and approaches user interaction in a different way. I’d use it in my stuff.
The phrase “last april april 2008″ really throws it for a loop, heh.
This isn’t a particularly novel way of parsing strings. While the first implementation I’ve seen in JS, as always the GNU people got ahead of us: this is just copying the GNU Date Input Standard:
http://www.gnu.org/software/tar/manual/html_chapter/tar_7.html
PHP includes a function that does more or less the same, called strtotime:
http://us2.php.net/manual/en/function.strtotime.php
which parses the given string into a Unix timestamp.
Oh gosh! The suggested examples actually work! Who would have thought?!?
Rey, are you kidding me?
@Martin: Dude, just go with the flow. I was trying to build it up to the climax. ;)
Nice parsing!
Use clearDate() after Date.parse() if just want date and not date/time.
Would be cool if you could say: “Next christmas” or “Boxing day 2010″ (although not sure where can find good cross country db of holidays - and irregular dates like easter are hard!).
Meh, wake me up when “my birthday” works.
:P
Is it just me? None of these common ones work:
day after tomorrow
8 days from now
11/9/2001
tomorrow+1
yesterday-1
4 days after tomorrow
fortnight
thursday week
1/2/3
10 minutes from now
11:30 GMT
@VLC: I know the developer of the lib is watching it so offer up your suggestions or contact them directly via the site. I’m sure they’d be interested in hearing about it.
Hey Rey, so why would Dion get mad that you released the news today? Seems counterintuitive. You guys broadcast news… seems as though you’d want to broadcast more and more news, and as soon as possible.
@VLC (and others) Thanks for noting all the edge cases! There all fantastic suggestions and we’ll feed these into future test cases.
A couple thoughts…
Please note/remember this is an Alpha-1 release. This is our first kick at the can and it’s only going to better from here. The goal of the Alpha-1 Parser was to provide support for pretty much 100% of the commonly understood/accepted date formats, support 150+ cultures and make it wicked-ass *fast*. That I think we achieved. Check out the test suite to see what’s currently supported by the parser (http://www.datejs.com/test/).
Now it’s onto the next stage… more relative date support, like all the suggestions above. We’ve also come up with a plan to make the Parser even faster. Things get weird when you start to hit terminal velocity on the browsers JavaScript engine, but we have a plan, and it will be cool.
Keep the parsing failures coming! I want to hear about them all and each is being diligently recorded.
Looks very similar to the date picker of RTM …. hey, still cool, nice pick, Rey.
@Jon Hartmann
It looks like the parser is adding the “2008″ to “last april (2007)” and coming up with a year of 4015. Very strange. But, should be an easy fix. Thanks for pointing out the problem.
@Nikola - Thanks for pointing out the date picker in RTM. I just signed up for an account. Theirs is a pretty similar concept, although a little limited in the amount of acceptable formats. I’m sure they would benefit immensely by ripping out their existing parsing and plugging in Datejs.
Nice library. I miss a little more documentation about how to change the input language, and the tests are quite impressive too; what test library are you using?
@Ignacio Coloma - Check out the “Getting Started with Datejs” for more information on how to change the culture. Also the GoogleCode project home page contains a few CultureInfo details. We’re hoping to get some more tutorials up shortly.
.
Basically all you have to do is swap out the date.js file for a culture-specific version. All the pre-compiled culture files are stored within the /trunk/build/ folder. All none-minified original source culture files are in the /trunk/src/globalization folder.
.
All the month and day name string have been translated, but any help translating the other strings is appreciated. There are comments within each culture file detailing how/where to submit your translations.
.
The Datejs test suite is built on a slightly modified version of Specifications by Dan Yoder (Dan was the co-developer on Datejs).
Nice work! todoist.com has this as well when you set reminders. It still needs more “magic words” but that’s just a matter of time. A Multilingual version would be the killer app. ;)
This is all very nice but it’s kinda academic when you consider that the two most common date formats used by real people are mm/dd/yyyy (in the US) and dd/mm/yyyy (in the rest of the world). For dates such as 11/12/2007, this class is worse than useless.
@Tamlyn Oh my. *sigh* What does “real people” mean exactly? I appreciate your comments, but things are a little different in the “real world”.
Seems a bit flakey still
“tomorrow+1day” and “tomorrow” gives the same result.
Nice idea though… will be good if the issues are ironed out.
I like the random funny error messages. I just noticed one bug with “sat” or “saturday” it came up with Thursday November 1st.
11/12/2007 is 11th of December, not November 12 for most of the world. (The states that use yyyy-mm-dd are fine of anyway.)
Only Canada, Micronesia, Palau, Philippines and the United States use the month/day format fully or partly.
http://en.wikipedia.org/wiki/Calendar_date#mm.2Fdd.2Fyy_or_mm.2Fdd.2Fyyyy_.28month.2C_day.2C_year.29
This is a parsing problem without a good solution. But you could at least parse 11.12.2007 to 11th of December. In dot is never used as a separator in the mm/dd format.
@geoffrey Surely you agree that the *vast* majority of people, when faced with a free-form date input field, will enter a date as either dd/mm/yy(yy) or mm/dd/yy(yy) rather than any of the other forms that your library (very elegantly) supports? I just feel that the utility of such a library is very limited by the fact that these formats are ambiguous (not your fault, of course).
@Tamlyn - I agree that the d/M/y vs M/d/y format can be ambiguous, and that perfectly demonstrates one of the biggest benefits of using the Datejs library. The library includes logic for determining how the date should be parsed based on the culture. Some cultures/countries like the format one way, others another. The library currently comes in 150+ different versions and we’ve conveniently pre-compiled one CultureInfo file for each supported culture.
.
Within each CultureInfo file is a .dateElementOrder property. The .dateElementOrder may be different for each culture. We’re in Canada and the typical order is day-month-year (dmy). If a user supplies an ambiguous date, the parser relies on the Date.CultureInfo.dateElementOrder property to give it a hint as to the expected order.
.
This same/similar topic is being discussed in our forums
.
I also agree that the *vast* majority of users will enter a Date in some kind of slashed format, although not all. And that 20% is a big problem.
.
Check out date and time input formats acceptable to RememberTheMilk.com. Now you can include the same functionality (actually better functionality) in your app with one line of code. How cool is that? AND, it doesn’t cost you a single penny.
.
Your trollish comments got me to respond originally.
@Martin - The library supports 150 different cultures/countries. The parser will function differently depending on the expected date-element-order for you particular country. Please check out my comments above, the “Getting Started with Datejs” blog post, the Discussions about this same topic or the GoogleCode home page for more information.
Sweet, before I had to send the date through php’s strtotime function and back. I wonder how this compares to that and Remember the Milk ( which I use daily ).
- Troy
@Geoffrey–any particular reason the +format doesn’t work with anything over 99? +99days/months/years works, but +100 doesn’t.
This is cool. I like the parser and the locale stuff, I haven’t seen much like it before.
My favourite is the neat extensions to the Date prototype.
(3).days().ago(); is awesome!
Wonderful library.
Anyone of you clicked on the eyes of the ninja in the header?
@geoffrey apologies for my ill-informed comment, it was still a bit early in the morning for me and I hadn’t had my coffee! When I said “worse than useless” I was thinking of a scenario where a ‘classic’ date input field would be replaced with this free input field without specifying a format. In this situation it could easily be highly detrimental to usability. But in a web app context it makes a lot more sense once a user learns some of the input formats available (and where the app is aware of the user’s locale/’culture’).
As an open source developer myself I am aware of the frustration caused by people criticising your work without taking the time to understand it first so I really should have known better!
@Geoffrey McGill
Thanks for the response… like I said, the phrase doesn’t really make sense, but it does throw it for a loop. Looks like specifying a month and a year together give it problems… “tomorrow, april 2008″ yields a date in the 41st century as well.
Pretty innovative! Hope they keep it up.
for JSP see an appropriate taglib here http://www.servletsuite.com/servlets/dateaddtag.htm for example
Nice work, Geoffrey! I’m definitely going to keep an eye on this and I look forward to future releases.
Very slick. Any chance of getting start and end dates based on an implied range?
ie “July 2008″ becomes:
{start: new Date(2008, 7, 1, 0, 0, 0, 0),
end: new Darte(2008, 8, 1, 0, 0, 0, 0)}
Hi,
very nice lib, loved it. Question: Is there a way to convert one format to the other?
examples:
* a search in a webservice returns a date in mdy format, and we need to show in dmy format.
* the user types a date in dmy format, and we need to use this in the search on the webservice which uses mdy.
thx
There’s a Ruby library called Chronic (http://chronic.rubyforge.org/) that handles this same sort of thing (though not client-side, obviously). Based on the comments here, it sounds like it might have a little wider coverage in terms of what it’ll handle.
Very impressive in thinking outside the box especially. Practical wise though - it’s the box that I and I think many appreciate and want. I want to see the big picture - I want to see the calendar. I want to see what day is the last of the month or what are the dates of each Saturday. I want something to pick from. I want to see the whole month or week. Anyway, it’s still a very cool tool.
Look at the PHP functions for date… they are just connecting that with AJAX… sure it’s nice to have, but it doesn’t deserve this type of hype… you asshat
…wow trolls rule
What about fortnights! Even with the En-GB / En-AU l10n files there are no fortnights. I guess it shows how difficult i18n can be — there are heaps of other locale-specific concepts like “再来週”(JA) for “the week after next”. And do Americans say “Friday week” too, meaning “Friday next week”?
It’s fun to pick apart other people’s code huh. Glad it’s not my date library under scrutiny.
@Jack Viers
This is a known bug and we’re expecting to have a fix very shortly.
.
@puRe - “Ninjas can divide by zero”
.
@David
We’ve talked about a DateRange object, although nothing firm yet. I would encourage you to start the topic in the forums and we’ll see where it takes us.
.
@Fabio Lima - Here’s an example to demonstrate taking in one date format and .toString()ing into another format. Just pass a format parameter to the .toString() function(). Example
.
Date.parse(”5/15/2007″).toString(”d/M/yyyy”); // returns “15/5/2007″
.
@Eric
We have something coming that will make you happy. Stay tuned.
.
@you’re an idiot - You figured out our dirty little secret. I wish you wouldn’t have told anyone.
.
@skold - “fortnight” should be trivial to support. I’ll see what I can do to squeeze it in.
@Geoffrey McGill, idea about the dd/MM/YY and MM/dd/YY problem:
In many cases, it is hard to know what culture visitors are from. One way of solving this would be to have the library be able to automatically detect ambigous dates and create a popup where people could select what date they actually meant.
This could possibly be done directly, or at least there could be an API getting a suitable set of strings/suitable information for a popup. Choice could be remembered in a cookie or available so the library user could put it in persistent storage somewhere.
Anything like this for Java?
@Eivind Eklund - The Datejs library does not include user interface components. It’s just code API. Any kind of popup message would have to be created by the developer. The library deals with ambiguous dates very elegantly, but the key is that the developer should detect the user-agent culture and serve up the appropriate culture-specific Datejs file. The library is completely oblivious of the user-agent. Just serve up the appropriate culture-specific file and there should be very few problems.
.
Another option would be to restrict user entry to only two possible formats (”dd/MM/yy” and “MM/dd/yy”), use .parseExact() instead of .parse() and then prompt the user each time to confirm which format/date they thought they were entering when either the month or day is 12 or lower. But that all seems rather goofy.
@okohll - We’re very interested in porting the library (especially the Parser) to other Languages. Work should start on ports to Ruby and C# very shortly. Porting to Java should be trivial after the C# version is complete (or vice-versa). Feel free to bring up the topic in the Datejs Forum if you’re interested in working on a Port.
Baaah…. It can’t even tell “My birthday” ;-)
It looks very nice, I’ll have it in mind the next time the need arise.
Nice library, but a shame that it splooges methods and properties all over the Date