views:

385

answers:

3

I need to convert a Date object into a TimeWithZone object representing the beginning of that day in a given time zone.

The following approach works, but seems too convoluted as it requires me to convert the date to a string:

?> date = Date.parse("2010-02-17")
=> Wed, 17 Feb 2010
>> ActiveSupport::TimeZone['Eastern Time (US & Canada)'].parse(date.to_s)
=> Wed, 17 Feb 2010 00:00:00 EST -05:00
>> ActiveSupport::TimeZone['UTC'].parse(date.to_s)
=> Wed, 17 Feb 2010 00:00:00 UTC 00:00

Is there a better way I'm missing?

Edit: People are suggesting variations of:

?> date.to_datetime.in_time_zone('Eastern Time (US & Canada)').beginning_of_day
=> Tue, 16 Feb 2010 00:00:00 EST -05:00

As you can see, this isn't an equivalent conversion since it leaves me at the start of Feb. 16th EST, instead of the start of Feb. 17th EST.

A: 

You must first convert the date object to a DateTime object, and then apply the timezone you want.

date = Date.today
date.to_datetime.in_time_zone('UTC').beginning_of_day #Bad ideea, since the utc offset can also be negative, so you may end up with 'yesterday'.

In conclusion, a good ideea (and without involving parsing strings) would be:

date.to_datetime.in_time_zone('Eastern Time (US & Canada)') - ActiveSupport::TimeZone['Eastern Time (US & Canada)'].utc_offset
=> Wed, 17 Feb 2010 00:00:00 EST -05:00
Vlad Zloteanu
to_datetime will give me the beginning of the day in UTC: "Converts a Date instance to a DateTime, where the time is set to the beginning of the day and UTC offset is set to 0." If I then apply an in_time_zone the time will shift to that timezone; for the example above I get "date.to_datetime.in_time_zone('America/New_York') => Tue, 16 Feb 2010 19:00:00 EST -05:00". Note that the date is now Feb 16. What I really want to do is keep the year, month, day, hour, minutes, seconds the same and only change the timezone. Make sense?
avaynshtok
but.. the Date object does not store the hour, min, sec.>> Date.parse("2010-02-17 12:02") == Date.parse("2010-02-17 12:03") => trueThe difference between a Date object and a Time object is that the Time object stores those attributes.In your question, you asked how to convert a *Date*.
Vlad Zloteanu
Right, I'm starting w/ a Date, but need to end up w/ a TimeWithZone. The code in the question does the conversion I need, I simply want equivalent code that looks cleaner, if such exists. What you suggested is not equivalent.If a TimeWithZone object had a way to modify the timezone, not convert the timezone, I think that would fulfill my requirements.
avaynshtok
OK. Edited my response :)
Vlad Zloteanu
see my edit to the question for why this doesn't work
avaynshtok
OK :) I finally got it to work. I edited my response. Now it's certainly working.
Vlad Zloteanu
A: 

Would something like this work for you?

'2010-04-01'.to_time.in_time_zone('Eastern Time (US & Canada)').beginning_of_day
Corey
see my edit to the question for why this doesn't work
avaynshtok
A: 

-1 to everyone for confusing everything

simianarmy