5

DateTime.new takes a timezone parameter as the 7th argument as an integer offset.

DateTime.new(2001,2,3,4,5,6,'-7')

However, since I don't easily know whether a given time falls in Daylight or Standard, I would rather do something like:

DateTime.new(2001,2,3,4,5,6,'Eastern Time (US & Canada)')

Please advise

jrhicks
  • 14,759
  • 9
  • 42
  • 57

2 Answers2

4

If you're using Rails your best bet is:

cur_zone = Time.zone
begin
  Time.zone = 'Eastern Time (US & Canada)'
  datetime = Time.zone.local(2001, 2, 3, 4, 5, 6)
ensure
  Time.zone = cur_zone
end

Or if you've already set Time.zone when you authenticate your uses, or in your application.rb config file then you can just use the Time.zone.local line by itself.

nzifnab
  • 15,876
  • 3
  • 50
  • 65
  • I went with the Rails best bet. I'm not certain how the second suggestion solves the Standard -vs- Daylight issue. Thanks!! – jrhicks Jun 26 '14 at 20:21
  • The second approach would just return the *standard* offset, which might not be the correct offset for the date in question. The first approach looks better. – Matt Johnson-Pint Jun 26 '14 at 20:31
  • I removed the second part from the answer. I hope @nzifnab doesn't mind. – jrhicks Jun 26 '14 at 21:20
  • Ahh good point about DST and such. I was just pointing out a way to get the offset value -- but realistically you shouldn't need to. I'm fine with the edit, thanks! – nzifnab Jun 26 '14 at 22:07
3

Idea found in: https://stackoverflow.com/a/41584881/3837660

In e.g. Rails 5.2.3

DateTime.included_modules.third
# => DateAndTime::Zones

which has #in_time_zone. (https://api.rubyonrails.org/classes/DateAndTime/Zones.html)

Allowing you to do the following:

#########################################
# Summer example
#
DateTime.new.in_time_zone(
  'Eastern Time (US & Canada)'
).change(
  year: 2017,
  month: 7,
  day: 31,
  hour: 7,
  min: 59,
  sec: 23
)
#
# => Mon, 31 Jul 2017 07:59:23 EDT -04:00
#
#########################################

#########################################
# Winter example
DateTime.new.in_time_zone(
  'Eastern Time (US & Canada)'
).change(
  year: 2017,
  month: 12,
  day: 31,
  hour: 7,
  min: 59,
  sec: 23
)
#
# => Sun, 31 Dec 2017 07:59:23 EST -05:00
#
#########################################

Note that DateTime#change is also an addition from Rails. See, e.g., https://api.rubyonrails.org/v5.2.3/classes/DateTime.html#method-i-change for details.

sunless
  • 597
  • 5
  • 19
  • excellent up to date answer that finally provides a sane way to handle ruby's goofy timezones – jpw Sep 17 '21 at 21:39