Rails 2.3.8 - What happens to a datetime field between a form being submitted and the controller receiving the params

I currently have a model that simply contains one datetime field:

class CreateElectricityReadings < ActiveRecord::Migration   def self.up     create_table :clocks do |t|       t.datetime :time_keeper       t.timestamps     end   end

  def self.down     drop_table :clocks   end end

If I enter the date string "13/10/2010" into this field its showing up in the controller as params[:clock][:time_keeper] "2010-10-13 23:00:00 UTC". I've tried overloading ActiveRecord::ConnectionAdapters::Column string_to_date(string) and ActiveRecord::ConnectionAdapters::Column string_to_time(string) but these seems to get hit when an object is saved not between the form submitting and the controller receiving the params object. Where is the mysterious 23:00:00 hours coming from? Can anyone point me to a good piece of reference reading for how dates and times work in rails land?

Thanks

voidstar wrote in post #949920:

I currently have a model that simply contains one datetime field:

class CreateElectricityReadings < ActiveRecord::Migration   def self.up     create_table :clocks do |t|       t.datetime :time_keeper       t.timestamps     end   end

  def self.down     drop_table :clocks   end end

If I enter the date string "13/10/2010" into this field its showing up in the controller as params[:clock][:time_keeper] "2010-10-13 23:00:00 UTC".

Then you just need to call to_s on the date with the format you want. Do this in the controller or the view: it's just like any other presentation issue. Dates are not stored as strings in the DB.

I've tried overloading ActiveRecord::ConnectionAdapters::Column string_to_date(string) and ActiveRecord::ConnectionAdapters::Column string_to_time(string) but these seems to get hit when an object is saved not between the form submitting and the controller receiving the params object. Where is the mysterious 23:00:00 hours coming from?

If I had to guess, I'd guess that you're in UTC+1 (Central European Time). So perhaps it's storing the time as 0:00 local time, then converting to UTC. But I could be wrong.

Can anyone point me to a good piece of reference reading for how dates and times work in rails land?

You're overthinking it. Rails does some conversion when the form is submitted to convert three form fields (day, month, year) into a Date object for the DB, and then saves it to a date or datetime field in the DB. In this case, you specified a datetime field in your migration, so when Rails retrieves the record, it puts the value into a DateTime object. If you don't want the time, don't use a datetime field in the DB -- or just ignore the time.

Thanks

Best,

Hey, Thanks for the reply, I could easily write some code to discard the time field, which is what I'll probably do now but I'd just like to know how rails is doing this, I guess is should go about downloading the rails source and grok it myself.

I'm in GMT but using daylight savings.

I guess if I just reset the time members of the DateTime object its returning to me I'm relatively insulated from errors if this translation changes in a future release.

Thanks Barry

voidstar wrote in post #950126:

Hey, Thanks for the reply, I could easily write some code to discard the time field, which is what I'll probably do now

You don't have to discard anything. Just ignore it.

Check Rails' field types; I think if you define the field in the migration as date instead of datetime, you will get a Date object from the DB, not the DateTime you currently have.

but I'd just like to know how rails is doing this, I guess is should go about downloading the rails source and grok it myself.

You've already got the Rails source.

I'm in GMT but using daylight savings.

I guess if I just reset the time members of the DateTime object its returning to me I'm relatively insulated from errors if this translation changes in a future release.

There's no need to reset. There's no translation, really; Rails is creating a DateTime object, so it needs a time value. Again, you're overthinking it and persuading yourself into more complex code than is actually necessary.

Thanks Barry

Best,

I need a date/time object due to domain requirements although at this point I don't care about the time object, I just want it to be midnight. There are other ways for the user to enter data into this table where the time element becomes relevant.

Where do I have the rails source? Also do you know what file/class handles receiving a post request from a form?

If anyone else is interested here's the code I'm using to reset the time to midnight.

    @gas_reading = @user.gas_readings.build(params[:gas_reading])

    @gas_reading.start_date = @gas_reading.start_date.change(:hour => 0, :min => 0, :second => 0) unless @gas_reading.start_date.nil?     @gas_reading.end_date = @gas_reading.end_date.change(:hour => 0, :min => 0, :second => 0) unless @gas_reading.end_date.nil?

I'd suggest you use the Rails' ".beginning_of_day" method...

http://apidock.com/rails/ActiveSupport/CoreExtensions/Date/Calculations/beginning_of_day

... possibly easier and certainly more idiomatic.

Open a new Terminal window and type gem server [and press return]. Open a new browser and visit http://0.0.0.0:8808

Each Gem you have installed will (probably) have two links next to its name, rdoc and www. The rdoc is whatever was generated when you installed the Gem, and the www will be whatever passes for the developer's Web site.

Walter

I need a date/time object due to domain requirements although at this point I don't care about the time object, I just want it to be midnight. There are other ways for the user to enter data into this table where the time element becomes relevant.

My understanding of this issue (which may be flawed) is that if you have a datetime field on a form the rails assumes the value entered is in local time, and converts it to gmt ready to be put in the database. I _think_ that if, in environment.rb you put config.time_zone = 'UTC' then it will assume that the value entered is already in UTC and will not apply the timezone offset.

Colin

voidstar wrote in post #950166:

I need a date/time object due to domain requirements although at this point I don't care about the time object,

Huh? Design for what you have now, not what you might need in future.

[...]

Where do I have the rails source?

Do you really need to ask? Remember, Ruby is an interpreted language. That means that you've got the source wherever the Rails gem is installed (in vendor/rails if you've done that, or wherever "gem which rails" tells you).

Best,

Thanks for the replies,

beginning_of_day makes a lot more sense.

Yes Colin that's what's happening, I'd just like to know where exactly the string goes from "dd/mm/yyyy" to being "yyyy-mm-dd hh:mm:ss timezone offset" and if there's anyway for me to control/over ride that behaviour.

Marnen, You're right what we're doing right now isn't good and we're creating technical debt. As a team we've discussed this and given the current requirements and priorities/time we have left, we've decided to do it this way.

Also I wouldn't have asked how to see the rails/ruby code if I knew how. I'm coming from java land and before that c++ where I'm used to having to grab the sources for libraries before being able to debug them or read them.

The source seems to be scattered about in different gems on my machine, I found doing a "git clone git://github.com/rails/rails.git v2.3.8" was handier to have everything in one place. Any suggestions on where to start looking for how rails accepts a post request and builds the params object and sends it to the correct controller?

Thanks again for all the help Barry

Where and how _exactly_ are you seeing it as this string? What do you see in the log when the form is posted? Apologies if you have already provided that info, I have not got time to look back in detail at the thread at this moment.

Colin