Changing default date format in Rails

I’ve spent all day digging through the rails api and postgres-pr on
this, I think it’s time to ask the list.

Postgres stores a Date in YYYY-MM-DD format. My users want the dates
in MM/DD/YYYY format.

Sure, I could explicitly convert it on the app level every place where
a date is displayed, but that seemed like a DRY violation.

I thought I’d be clever and simply redefine Date.to_s with

class Date
def to_s
strftime(’%m/%d/%Y’)
end
end

On Mon, 2006-03-13 at 20:01 -0800, Dav Y. wrote:

class Date
def to_s
strftime(’%m/%d/%Y’)
end
end


I don’t know the answer but I appreciate the question…that one is on
my todo list so when you do get a resolve on it, please post back to the
list.

Craig

Dav Y. wrote:

I’ve spent all day digging through the rails api and postgres-pr on
this, I think it’s time to ask the list.

Postgres stores a Date in YYYY-MM-DD format. My users want the dates
in MM/DD/YYYY format.

Sure, I could explicitly convert it on the app level every place where
a date is displayed, but that seemed like a DRY violation.

There’s already a nice way to do this. ActiveSupport enhances Date#to_s
to take a format parameter. Fire up script/console and look at the value
of this hash:
ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS

If you add an entry for :default, that will be used for all to_s
conversions where you don’t specify a format. And you can use
some_date.to_s(:db) to output in the format for your database. If you
want to change or add formats, put something like this in your
environment.rb after the end of the Initializer block:

ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS.merge!(
:default => ‘%m/%d/%Y’,
:date_time12 => “%m/%d/%Y %I:%M%p”,
:date_time24 => “%m/%d/%Y %H:%M”,
)

–josh
http://blog.hasmanythrough.com

Josh S. wrote:

Dav Y. wrote:

I’ve spent all day digging through the rails api and postgres-pr on
this, I think it’s time to ask the list.

Postgres stores a Date in YYYY-MM-DD format. My users want the dates
in MM/DD/YYYY format.

Sure, I could explicitly convert it on the app level every place where
a date is displayed, but that seemed like a DRY violation.

There’s already a nice way to do this. ActiveSupport enhances Date#to_s
to take a format parameter. Fire up script/console and look at the value
of this hash:
ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS

If you add an entry for :default, that will be used for all to_s
conversions where you don’t specify a format. And you can use
some_date.to_s(:db) to output in the format for your database. If you
want to change or add formats, put something like this in your
environment.rb after the end of the Initializer block:

ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS.merge!(
:default => ‘%m/%d/%Y’,
:date_time12 => “%m/%d/%Y %I:%M%p”,
:date_time24 => “%m/%d/%Y %H:%M”,
)

Oops, two small corrections. (No more late night postings!) For a Date,
you want to use this hash:
ActiveSupport::CoreExtensions::date::Conversions::DATE_FORMATS

And you can use some_date.to_s(:db) to output in the format for your database.

By the above I meant that Rails uses the :db formatter when converting a
date to a string to use in a database query. So if you need to you can
change the :db format and the way dates are formatted for the database
will change automatically.

–josh
http://blog.hasmanythrough.com

Dan,

Just to solve this particular problem with date formats with
in_place_editor_field, I just augmented my model. Originally, I had a
date of birth field called dob. I did this in the model:

def dob_formatted
dob.strftime ‘%m/%d/%Y’
end’

def dob_formatted=(value)
self.dob = Time.parse(value)
end

Then in the view:

<%= in_place_editor_field :client, ‘dob_formatted’ %>

HTH,
Ed

Argh, Gmail ate over half of my original post so I didn’t actually
explain myself.

Josh, thanks for the tip on the CoreExtension stuff. Unfortunately it
doesn’t really help.

The problem is that both the DATE_FORMATS thing, and my Date.to_s
overwrite, don’t extend deep enough into the rails system. It works
great once you have a model object and are just calling the attribute
reader methods on it, but when you use the ActionView helpers like
text_field or in_place_editor the customized default does come into
play. By digging into the rails code, I found that this is because
these tag helpers end up calling object.attribute_before_type_cast
which simply returns the raw string from the sql results. Let me
illustrate:

script/console
Loading development environment.

ActiveSupport::CoreExtensions::date::Conversions::DATE_FORMATS
=> {:short=>“%e %b”, :long=>“%B %e, %Y”}

Date.today.to_s
=> “2006-03-14”

ActiveSupport::CoreExtensions::date::Conversions::DATE_FORMATS[:default]=‘%m/%d/%Y’
=> “%m/%d/%Y”

Date.today.to_s
=> “03/14/2006”

(w00t)

r = Rebate.find 30
=> #<Rebate:0x2276778 @attributes={“reminder_list”=>“0”,
“status”=>“2”, “prorated”=>“0”, “updated_at”=>nil,
“service_period”=>“14”, “employee_id”=>“1”, “id”=>“30”,
“customer_id”=>“30”, “reminder_cancel_date”=>nil, “amount”=>“300.00”,
“credit_on”=>“2005-12-17”, “service_fee”=>“75.00”,
“created_at”=>“2005-12-17 14:35:19”}>

r.credit_on.to_s
=> “12/17/2005”

(w00t!)

av = ActionView::Base.new
=> #<ActionView::Base:0x25779b8 @assigns_added=nil, @controller=nil,
@base_path=nil, @assigns={}, @logger=nil>

av.instance_variable_set(“@rebate”,r)
=> #<Rebate:0x2276778 @attributes={“reminder_list”=>“0”,
“status”=>“2”, “prorated”=>“0”, “updated_at”=>nil,
“service_period”=>“14”, “employee_id”=>“1”, “id”=>“30”,
“customer_id”=>“30”, “reminder_cancel_date”=>nil, “amount”=>“300.00”,
“credit_on”=>“2005-12-17”, “service_fee”=>“75.00”,
“created_at”=>“2005-12-17 14:35:19”}>

av.text_field :rebate, ‘credit_on’
=> “<input id="rebate_credit_on" name="rebate[credit_on]"
size="30" type="text" value="2005-12-17" />”

(!w00t)

I don’t want to use a solution that requires me to give up on some of
the nicer parts of RoR. So this is where I became stuck. I took some
time to dig around in the ConnectionAdapter stuff, but I don’t see an
easy way to do what I want through that level either, although to be
honest I found some of the Postgres specific stuff confusing.

On 3/14/06, Josh S. [email protected] wrote:

And you can use some_date.to_s(:db) to output in the format for your database.
Posted via http://www.ruby-forum.com/.


Rails mailing list
[email protected]
http://lists.rubyonrails.org/mailman/listinfo/rails


Dav Y.
http://AkuAku.org/

Kevin O. wrote:

On Monday, July 31, 2006, at 11:25 AM, Ed Howland wrote:

def dob_formatted=(value)
On 3/14/06, Dav Y. [email protected] wrote:

text_field or in_place_editor the customized default does come into

Date.today.to_s

“customer_id”=>“30”, “reminder_cancel_date”=>nil, “amount”=>“300.00”,
the nicer parts of RoR. So this is where I became stuck. I took some

this, I think it’s time to ask the list.
to take a format parameter. Fire up script/console and look at

ActiveSupport::CoreExtensions::date::Conversions::DATE_FORMATS
–josh


Ed Howland
http://greenprogrammer.blogspot.com


Rails mailing list
[email protected]
http://lists.rubyonrails.org/mailman/listinfo/rails

Be careful changing the default format. I had an issue lately where
doing this completely hosed MySQL. Bottom line is that ActiveRecord was
trying to insert dates into the database in the new default format,
instead of the way MySQL was expecting to get it. It resulted in empty
dates, but no real error.

Twas quite a pain to track down.

_Kevin
www.sciwerks.com

Did you ever figure out how to fix this? I have the same problem,
changing the default date format effects the way it is passed to mysql.
I would think that the rails team could fix this somehow no?

On Monday, July 31, 2006, at 11:25 AM, Ed Howland wrote:

def dob_formatted=(value)
On 3/14/06, Dav Y. [email protected] wrote:

text_field or in_place_editor the customized default does come into

Date.today.to_s

“customer_id”=>“30”, “reminder_cancel_date”=>nil, “amount”=>“300.00”,
the nicer parts of RoR. So this is where I became stuck. I took some

this, I think it’s time to ask the list.
to take a format parameter. Fire up script/console and look at

ActiveSupport::CoreExtensions::date::Conversions::DATE_FORMATS
–josh


Ed Howland
http://greenprogrammer.blogspot.com


Rails mailing list
[email protected]
http://lists.rubyonrails.org/mailman/listinfo/rails

Be careful changing the default format. I had an issue lately where
doing this completely hosed MySQL. Bottom line is that ActiveRecord was
trying to insert dates into the database in the new default format,
instead of the way MySQL was expecting to get it. It resulted in empty
dates, but no real error.

Twas quite a pain to track down.

_Kevin
www.sciwerks.com

I hope this is relevant, I’m just starting out on Ruby, and with Rails,
and I ran into trouble with MySQL dates. Here’s how I got what I wanted:

This method takes in a MySQL formatted date (YYYY-MM-DD)

and returns a date formatted as (M/DD)

def format_date(date)
year, month, day = date.split(/-/) # splits date into 3
variables
month = month.sub(/^0/,’’) # Strips leading '0’s from the month
month + “/” + day # concatenates and returns date
end

I wasn’t sure how to get/use Date objects so I restricted myself to the
String class.

I put this method in my helper file.

Kris wrote:

this, I think it’s time to ask the list.
[email protected]

Posted via http://www.ruby-forum.com/.
Not yet. That’s on the back burner for the moment. I’ve just been
using the default output for now and specifically changing it when
necessary.

I think the fix for this is to define a default :db date format and
modify the appropriate AR code to use that format when writing to the
DB. That way you could change the default print format without
affecting the DB writes. I think I first encountered this while the
Trac was down, so I’ll go submit a ticket on this (if there isn’t one
already).

_Kevin

Stuart R. wrote:

Did you ever figure out how to fix this? I have the same problem,
changing the default date format effects the way it is passed to mysql.
I would think that the rails team could fix this somehow no?

The problem seems to be solved in the post 1.2.1 Edge Rails revison
6270, March 2007. See TRAC ticket http://dev.rubyonrails.org/ticket/7411
(alternatively 1.2.1 users could patch the quote method in
lib/active_record/connection_adapters/abstract/quoting.rb).

I’ve written a howto along with a date validator, date_field helper and
calendar control to address the whole date display/input/validation
question at methods.co.nz

Cheers, Staurt

Following this issue and guided by the Stuart’s howto I have written a
post solving this issue in a different way. Besides, time formatting is
also covered.

The post can be found here:

Cheers
Miquel

Hi Staurt,

I like your calendar but got into a weird problem where the calendar
overlaps with a drop down select underneath it. I tried to fix it using
the z-index in the css but not lock. It only overlaps with the drop down
control and not with others like text box, text area, buttons, labels
etc.

Any thoughts?

i_programmer

On 8/1/07, Dave M. [email protected] wrote:

Hi Staurt,

I like your calendar but got into a weird problem where the calendar
overlaps with a drop down select underneath it. I tried to fix it using
the z-index in the css but not lock. It only overlaps with the drop down
control and not with others like text box, text area, buttons, labels
etc.

Any thoughts?

Windows?
http://www.devguru.com/features/tutorials/ComboControl/combocontrol.html


Rick O.
http://lighthouseapp.com
http://weblog.techno-weenie.net
http://mephistoblog.com

Kris wrote:

Rails mailing list
[email protected]
http://lists.rubyonrails.org/mailman/listinfo/rails

Be careful changing the default format. I had an issue lately where
doing this completely hosed MySQL. Bottom line is that ActiveRecord was
trying to insert dates into the database in the new default format,
instead of the way MySQL was expecting to get it. It resulted in empty
dates, but no real error.

Twas quite a pain to track down.

_Kevin
www.sciwerks.com

Did you ever figure out how to fix this? I have the same problem,
changing the default date format effects the way it is passed to mysql.
I would think that the rails team could fix this somehow no?

The problem seems to be solved in the post 1.2.1 Edge Rails revison
6270, March 2007. See TRAC ticket http://dev.rubyonrails.org/ticket/7411
(alternatively 1.2.1 users could patch the quote method in
lib/active_record/connection_adapters/abstract/quoting.rb).

I’ve written a howto along with a date validator, date_field helper and
calendar control to address the whole date display/input/validation
question at methods.co.nz

Cheers, Staurt

Josh S. wrote:

There’s already a nice way to do this. ActiveSupport enhances Date#to_s
to take a format parameter. Fire up script/console and look at the value
of this hash:
ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS

If you add an entry for :default, that will be used for all to_s
conversions where you don’t specify a format. And you can use
some_date.to_s(:db) to output in the format for your database. If you
want to change or add formats, put something like this in your
environment.rb after the end of the Initializer block:

ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS.merge!(
:default => ‘%m/%d/%Y’,
:date_time12 => “%m/%d/%Y %I:%M%p”,
:date_time24 => “%m/%d/%Y %H:%M”,
)

–josh
http://blog.hasmanythrough.com

How can I tell to_xml to format a date according to one of these
predefined formats? Thanks,

Chris.

Dave M. wrote:

Hi Staurt,

I like your calendar but got into a weird problem where the calendar
overlaps with a drop down select underneath it. I tried to fix it using
the z-index in the css but not lock. It only overlaps with the drop down
control and not with others like text box, text area, buttons, labels
etc.

Any thoughts?

i_programmer

This is an issue with Internet Explorer. The easiest way to fix this
problem is by wrapping the div you want to be above the select box in an
iframe. Here is a simple jquery plugin that demonstrates the technique.
You should be able to easily port this to other JavaScript libraries to
solve the issue.

http://brandonaaron.net/jquery/plugins/bgiframe/jquery.bgiframe.js

Hope this helps!

Chris Gers32 wrote:

How can I tell to_xml to format a date according to one of these
predefined formats? Thanks,

Chris.

I got a reply from Railsfrance; I just redefine XML_FORMATTING locally,
like this:

old_proc = Hash::XML_FORMATTING['datetime']
Hash::XML_FORMATTING['datetime'] = Proc.new { |datetime| 

datetime.to_s(:rfc822) }

MY CODE THAT CALLS to_xml GOES HERE

Hash::XML_FORMATTING['datetime'] = old_proc

Chris.

Hello,
I found that the easiest way for me is using the built-in
localization/i18n support.

If the application is localized, you could include the appropriate
format in the localization file, and then you could use the “localize”
helper:
<%=localize object.time_attribute, :format => :custom_or_edited_format
%>.

If the application is not localized, it is after all even easier/faster
using the same technique.

Hope this helps.

Dav Y. wrote:

I’ve spent all day digging through the rails api and postgres-pr on
this, I think it’s time to ask the list.

Postgres stores a Date in YYYY-MM-DD format. My users want the dates
in MM/DD/YYYY format.

Sure, I could explicitly convert it on the app level every place where
a date is displayed, but that seemed like a DRY violation.

I thought I’d be clever and simply redefine Date.to_s with

class Date
def to_s
strftime(’%m/%d/%Y’)
end
end

In Rails3 you can run:

Date::DATE_FORMATS[:default] = “%m/%d/%Y”

skipping the ActiveSupport::CoreExtensions::…

see your installation of active support, eg:

activesupport-3.0.0.beta3/lib/active_support/core_ext/conversions.rb for
more info.

Josh S. wrote:

Dav Y. wrote:

I’ve spent all day digging through the rails api and postgres-pr on
this, I think it’s time to ask the list.

Postgres stores a Date in YYYY-MM-DD format. My users want the dates
in MM/DD/YYYY format.

Sure, I could explicitly convert it on the app level every place where
a date is displayed, but that seemed like a DRY violation.

There’s already a nice way to do this. ActiveSupport enhances Date#to_s
to take a format parameter. Fire up script/console and look at the value
of this hash:
ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS

If you add an entry for :default, that will be used for all to_s
conversions where you don’t specify a format. And you can use
some_date.to_s(:db) to output in the format for your database. If you
want to change or add formats, put something like this in your
environment.rb after the end of the Initializer block:

ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS.merge!(
:default => ‘%m/%d/%Y’,
:date_time12 => “%m/%d/%Y %I:%M%p”,
:date_time24 => “%m/%d/%Y %H:%M”,
)

–josh
http://blog.hasmanythrough.com

Use Rails I18n for this.

In config/locales/en.yml:

en:
date:
formats:
default: “%m/%d/%Y”

In views:

<%= l some_model.date_field %>