I need to parse strings with timestamps and convert them to Time
objects.
I am struggling to understand how Time.parse
works and how to ignore DST and use always UTC
or simply convert to UTC
I keep having duplicate hours when time transition from GMT
to DST
. I have tried:
Time.parse(t)
Time.parse(t).utc
Time.strptime(t, "%Y-%m-%d %H:%M:%S")
and all give the same result.This is an extract of my code
require 'time'
ts = ["2010-03-28 00:00:00", "2010-03-28 01:00:00", "2010-03-28 02:00:00", "2010-03-28 03:00:00"]
ts.each do |t|
puts "t: #{t} -- pt: #{Time.parse(t)} -- dst: #{Time.parse(t).dst?} -- utc: #{Time.parse(t).utc} -- strptime: #{Time.strptime(t, "%Y-%m-%d %H:%M:%S")}"
end
The output is:
t: 2010-03-28 00:00:00 -- pt: 2010-03-28 00:00:00 +0000 -- dst: false -- utc: 2010-03-28 00:00:00 UTC -- strptime: 2010-03-28 00:00:00 +0000
t: 2010-03-28 01:00:00 -- pt: 2010-03-28 02:00:00 +0100 -- dst: true -- utc: 2010-03-28 01:00:00 UTC -- strptime: 2010-03-28 02:00:00 +0100
t: 2010-03-28 02:00:00 -- pt: 2010-03-28 02:00:00 +0100 -- dst: true -- utc: 2010-03-28 01:00:00 UTC -- strptime: 2010-03-28 02:00:00 +0100
t: 2010-03-28 03:00:00 -- pt: 2010-03-28 03:00:00 +0100 -- dst: true -- utc: 2010-03-28 02:00:00 UTC -- strptime: 2010-03-28 03:00:00 +0100
Location: UK (if locale
is important)
Time: DST
Ruby 2.0.0-p247
on macos
(I cannot change it)
EDIT
Not sure this is a hack, but adding " UTC"
to the time string solves the problem. See updated code:
require 'time'
ts.map{|t| t + " UTC"}.each do |t|
puts "t: #{t} -- pt: #{Time.parse(t)} -- dst: #{Time.parse(t).dst?} -- utc: #{Time.parse(t).utc} -- \
strptime: #{Time.strptime(t, "%Y-%m-%d %H:%M:%S")}"
end
The output is now:
t: 2010-03-28 00:00:00 UTC -- pt: 2010-03-28 00:00:00 UTC -- dst: false -- utc: 2010-03-28 00:00:00 UTC -- strptime: 2010-03-28 00:00:00 +0000
t: 2010-03-28 01:00:00 UTC -- pt: 2010-03-28 01:00:00 UTC -- dst: false -- utc: 2010-03-28 01:00:00 UTC -- strptime: 2010-03-28 02:00:00 +0100
t: 2010-03-28 02:00:00 UTC -- pt: 2010-03-28 02:00:00 UTC -- dst: false -- utc: 2010-03-28 02:00:00 UTC -- strptime: 2010-03-28 02:00:00 +0100
t: 2010-03-28 03:00:00 UTC -- pt: 2010-03-28 03:00:00 UTC -- dst: false -- utc: 2010-03-28 03:00:00 UTC -- strptime: 2010-03-28 03:00:00 +0100
Of course the last parsing with strptime
is wrong as it is ignoring UTC
.