2

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.

Rojj
  • 1,170
  • 1
  • 12
  • 32

0 Answers0