Jan 6, 2012

More Parsing User Supplied Dates and Times in Rails


Rails does a pretty good job of making work with time zones feel transparent.  If you do everything it's way, including use ActionView::Helpers::DateHelper.  If you use a Javascript control that returns a text input field or if you allow the users to enter values directly or need to process uploaded content things get a bit more complicated.

If the string returned by the text input can be parsed by Date._parse your in luck.  Everything will still work as expected with no extra effort.  If on the other hand you want to do something as simple as display U.S. style dates, in the format "MM/DD/YYYY", you will have to manually parse the input.  Ruby's Date._parse understands 'YYYY/MM/DD' and 'DD/MM/YYYY' but not 'MM/DD/YYYY'.  In the case where you're processing the input from a Javascript control the most direct solution is to do something like this...



The example above does return a time value in the current timezone and will work as expected.  One big problem with strptime is that it isn't very flexible, the input string must match the provided format string exactly right down the the separator characters and spaces.  So this approach can work if your processing the output of a control but tends to fail if you need to process human input.

Another problem I have with the approach above is that it quickly becomes incredibly redundant if you're working with a large number of date/time fields in many different models.  To Dry that up a bit I decided to move my specialized processing into a modified version of Date._parse.  This means I don't have to litter my controllers with date time parsing code and I have a single entry point to test that all desired formats are supported.



Basically all this is doing is taking the input string and re-arranging the values into an order the original method will understand.  The biggest disadvantage to this problem is that it doesn't support per-locale input formats.  It guess I'll cross that bridge if I ever get to it.

No comments: