ActiveRecord with different Date/Time format

I have an application where user sets his/her preferred date/time format. User is expected to enter datetime in his preferred format across the application. Now the problem is for few formats the datetime is parsed wrongly while create/update ActiveRecord.

For example user has set date/time format in hh:mm dd/MM/yyyy. Now if user enters 17:00 04/05/2012 it parses it as 5 PM 5 Apr, 2012 where it should be 5 PM 4 May, 2012

1.8.7 :004 > a = Article.create!(:name => 'a1', :published_at => '17:00 04/05/2012') => #<Article id: 2, name: "a1", published_at: "2012-04-05 17:00:00", created_at: "2012-04-16 13:54:36", updated_at: "2012-04-16 13:54:36">

I understand that ruby/rails has predefined set of formats against which the date/time string is evaluated and if matches any format in sequence it parses given string with that format/

1.8.7 :006 > a = Article.create!(:name => 'a1', :published_at => '17:00 15/12/2012') => #<Article id: 4, name: "a1", published_at: nil, created_at: "2012-04-16 13:55:43", updated_at: "2012-04-16 13:55:43">

Here user entered 15 December, 2012 which was parsed to nil. I understand that ruby/rails was not able to match any predefined format and hence returns nil.

Someone has already asked similar questions (ruby on rails - ActiveRecord date format - Stack Overflow and Changing default date format in Rails - Rails - Ruby-Forum) but the solution seems not applicable in my case as I don't want single datetime format across the application as each user will have his own preferred datetime format.

Now to work with multiple datetime format, we are planning to manipulate it before the params is passed to the ActiveRecord. So the steps would like

1. Read datetime from params map 2. Parse it with user's preferred datetime format 3. Format datetime to the default format used by ActiveRecord 4. Replace current datetime in params with re-formatted datetime Here is a snippet of the controller

class ArticlesController < ApplicationController   before_filter :format_date_time, :only => [:create, :update]   ...   ...   private     def format_date_time       datetime = params[:datetime]       params[:datetime] = DateTime.strptime(datetime, pref_date_time_format).strftime('%c')     end end

Would anyone please verify if it is right approach or not? Also I would appreciate someone outlines better ways to accomplish this.

Thanks, Amit Patel

Since each user inputs a data with different formats, you have to treat them as they come in to the controller.

Using strptime with the specified format is the correct way to create the correct datetime give the user's format. When showing this same date you'll present them in the format they use, but the date on the database is always going to be in the same format.

You could also override the setter of the datetime param on the model, but I've never had good experiences overriding attributes in AR.

When showing the date you can use a decorator to format it on the view using the I18n.localize with :format parameter.

Thanks Draiken, for your valuable inputs.

Actually the application is not internationalized fully. We just have given liberty to user to choose different date/time formats. So we would not be using I18n for now.

I also feel not to override attribute setter in AR to manipulate date/time before saving.

It looks ok to me apart from the fact that you need to allow for the user entering invalid data so that strptime fails. I suggest you have a look at datetime_select however, you might find that useful and then you don't have to worry so much about operator error.

Colin

Thanks Colin. We have used datetime_select in our application.

Do you mean you have changed to using datetime_select, or you are already using datetime_select and have the problem you previously described?

Colin

Hi Colin,

We are using datetime_select but planning to use javascript datetime picker. We chosen http://jongsma.org/software/protoplasm/control/datepicker which also support configurable datetime format. So we are facing this issue while preparing POC.

Thanks, Amit