Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Format used when converting and saving a date string to database with rails

My user wants to use the date format %d/%m/%Y (eg: 26/02/2011).

In order to correctly display dates, I therefore changed to :default format in environment.rb:

environment.rb :

ActiveSupport::CoreExtensions::Date::Conversions::DATE_FORMATS.merge!(
     :default => "%d/%m/%Y"
)

It's working fine but I have one problem when trying to save date strings entered in this format in the database.

Rails seems to take the strings as formated with %m/%d/%Y instead of %d/%m/%Y
04/02/2011 is saved as 2011-04-02 and 26/02/2011 is simply invalid and not saved...

I searched for solutions for this but the ones I found rely on reformating the dates in my models such as the one below :

mymodel.rb :   

def datefield_formatted
   datefield.strftime '%m/%d/%Y'
end

def datefield_formatted=(value)
   self.datefield = Time.parse(value)
end


view.html.erb :

<%= form.input :datefield_formatted %>

I could use this solution but it will require a change in my models for every 'datefield' (there are many in my apps).

I was therefore wondering if there is a was to tell Rails to correctly 'read' string as %d/%m/%Y when converting and saving to the database.

like image 633
LapinLove404 Avatar asked Dec 28 '25 01:12

LapinLove404


2 Answers

I think the best would be to save the dates in the usual sql format (i.e. date fields not varchar) and only to show them in the %d/%m/%Y. For that I usually use the localization files and l(date) function. e.g. this in localization file

date:
  formats:
    default: "%d/%m/%Y"

and this wherever you use the date in views l(date)

Another idea is to overload the activerecord how it saves dates, but this is a bit of overkill :/

like image 124
Boris Churzin Avatar answered Dec 30 '25 15:12

Boris Churzin


I eventually found a solution searching more deeply into Stackoverlow :

This blog post explains the problem and gives a working solution : http://blog.nominet.org.uk/tech/2007/06/14/date-and-time-formating-issues-in-ruby-on-rails/

So we have : lib/column-patch.rb

class ActiveRecord::ConnectionAdapters::Column

def self.string_to_date(string)
    return string unless string.is_a?(String)

    begin
        return DateTime.strptime(string, ActiveSupport::CoreExtensions::Date::Conversions::DATE_FORMATS[:default])
    rescue
        date_array = ParseDate.parsedate(string)
        # treat 0000-00-00 as nil
        Date.new(date_array[0], date_array[1], date_array[2]) rescue nil
    end
end

def self.string_to_time(string)
    return string unless string.is_a?(String)

    begin
    if dt=Date._strptime(string,ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS[:default])
        return Time.mktime(*dt.values_at(:year, :mon, :mday, :hour, :min, :sec, :zone, :wday))
    else
        raise "Bad format"
    end
    rescue
        time_hash = Date._parse(string)
        time_hash[:sec_fraction] = microseconds(time_hash)
        time_array = time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction)
        # treat 0000-00-00 00:00:00 as nil
        Time.send(ActiveRecord::Base.default_timezone, *time_array) rescue DateTime.new(*time_array[0..5]) rescue nil
    end
end

end

And we add in config/environment.rb

require 'column-patch'
like image 27
LapinLove404 Avatar answered Dec 30 '25 15:12

LapinLove404



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!