How to create a Ruby DateTime from existing Time.zone for Rails?
Asked Answered
C

6

35

I have users entering in dates in a Ruby on Rails website. I parse the dates into a DateTime object with something like:

date = DateTime.new(params[:year].to_i, params[:month].to_i, params[:day].to_i, params[:hour].to_i, params[:minute].to_i)

or

date = DateTime.parse(params[:date])

Both DateTimes will not be in the time zone of the user which I previously set with something like:

Time.zone = "Pacific Time (US & Canada)"

How do I parse the above DateTimes to be in the right time zone? I know the DateTime.new method has a 7th argument for the time offset. Is there an easy way to look up the offset for a time zone in a given time? Or should I be using something other than DateTime?

Catton answered 6/4, 2013 at 9:13 Comment(0)
S
23

You can use Time.zone.local if you set Time.zone previously:

user_time = Time.zone.local(params[:year].to_i, params[:month].to_i, params[:day].to_i, params[:hour].to_i, params[:minute].to_i, 0)

Have a look at the ActiveSupport::TimeWithZone documentation.

Subsidize answered 6/4, 2013 at 9:29 Comment(3)
For anyone with a Railscasts.com pro account: railscasts.com/episodes/106-time-zones-revisedEpithalamium
@Epithalamium I just subscribed to railscasts because of you, thanks.Catton
please see https://mcmap.net/q/423611/-how-to-create-a-ruby-datetime-from-existing-time-zone-for-rails if you want to accept parameters like 0 or -1 for month and days.Sanjiv
B
43

Try:

Time.zone = "Pacific Time (US & Canada)"
Time.zone.parse('8-11-2013 23:59:59') #=> Fri, 08 Nov 2013 23:59:59 PST -08:00 

OR

Time.now.in_time_zone("Pacific Time (US & Canada)")

OR

DateTime.now.in_time_zone("Pacific Time (US & Canada)")
Bracketing answered 8/11, 2013 at 9:57 Comment(1)
Just to complement the answer here you i'll find in constants all the list of available zones apidock.com/rails/TimeZoneCarvelbuilt
S
25

You can use the following code to create a DateTime object with your desired TimeZone.

DateTime.new(2013, 6, 29, 10, 15, 30).change(:offset => "+0530")

With Ruby v1.9.1, the below line does the same job like a magic.

DateTime.new(2013, 6, 29, 10, 15, 30, "+0530")

Documentation here

Schatz answered 29/6, 2013 at 4:39 Comment(4)
And of you have an already existing time with a set timezone you can do DateTime.new(2013, 6,29,10,15,30).change(:offset => known_time.zone)Ferne
This does not result in the desired value. The point is that the time "10:15:30" should be in the desired time zone, and one wants to get a value out out that: (byebug) p DateTime.new(2015,12,27,0,0,0).change(:offset => 'America/New_York') Sun, 27 Dec 2015 00:00:00 +0000Sherikasherill
DateTime.new accepts offset as the seventh optional argument. See https://mcmap.net/q/423611/-how-to-create-a-ruby-datetime-from-existing-time-zone-for-rails for usage.Sanjiv
Thanks @twnaing. Updated the comment :-)Schatz
S
23

You can use Time.zone.local if you set Time.zone previously:

user_time = Time.zone.local(params[:year].to_i, params[:month].to_i, params[:day].to_i, params[:hour].to_i, params[:minute].to_i, 0)

Have a look at the ActiveSupport::TimeWithZone documentation.

Subsidize answered 6/4, 2013 at 9:29 Comment(3)
For anyone with a Railscasts.com pro account: railscasts.com/episodes/106-time-zones-revisedEpithalamium
@Epithalamium I just subscribed to railscasts because of you, thanks.Catton
please see https://mcmap.net/q/423611/-how-to-create-a-ruby-datetime-from-existing-time-zone-for-rails if you want to accept parameters like 0 or -1 for month and days.Sanjiv
S
7

DateTime.new accepts optional offset argument (as the seventh) starting from ruby 1.9.1

We can write

DateTime.new(2018, 1, 1, 0, 0, 0, Time.zone.formatted_offset)
Sanjiv answered 29/3, 2018 at 15:4 Comment(0)
F
1

If you have already a correct DateTime object with the name 'datetime', and you want to copy it, you can simply call the 'getutc' on it and after that use the 'in_time_zone'

DateTime.new(datetime.getutc.year, datetime.getutc.month, datetime.getutc.day, time.getutc.hour, time.getutc.min).in_time_zone
Ferne answered 18/8, 2013 at 10:54 Comment(0)
H
0

Surprisingly none of these answers are very good.

DateTime now takes a 7th argument for time zone:

DateTime.new(2024, 7, 2, 6, 30, 0, 'PST')
Huttan answered 5/7 at 0:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.