4

I'm having an issue with Ruby 1.8.7 strftime where the %z is returning the local time after i convert the time to UTC.

I'm doing the following:

>> t = Time.now
=> Mon Dec 19 15:20:16 -0800 2011
>> t.strftime("%z")
=> "-0800"

>> t = Time.now.utc
=> Mon Dec 19 23:20:28 UTC 2011
>> t.strftime("%z")
=> "-0800"

Even after I change the time to UTC, the timezone formatted gets defaulted to my local PST -0800.

Is this a known issue? Is there a way around it?

mu is too short
  • 426,620
  • 70
  • 833
  • 800
roloenusa
  • 761
  • 1
  • 10
  • 19

2 Answers2

5

Note that the fine 1.8.7 manual makes no mention of %z:

...
%w - Day of the week (Sunday is 0, 0..6)
%x - Preferred representation for the date alone, no time
%X - Preferred representation for the time alone, no date
%y - Year without a century (00..99)
%Y - Year with century
%Z - Time zone name
%% - Literal ``%'' character

but the 1.9.3 version does have documented support for %z:

Time zone:
  %z - Time zone as hour and minute offset from UTC (e.g. +0900)
          %:z - hour and minute offset from UTC with a colon (e.g. +09:00)
          %::z - hour, minute and second offset from UTC (e.g. +09:00:00)
  %Z - Time zone abbreviation name

The fact the %z produces anything at all appears to be an undocumented and possibly accidental implementation detail.

You can use %Z in 1.8.7 and 1.9.3; for example, you get these results in 1.8.7:

>> t = Time.now
=> Mon Dec 19 16:46:06 -0800 2011
>> t.zone
=> "PST"
>> t.strftime('%z %Z')
=> "-0800 PST"
>> t = Time.now.utc
=> Tue Dec 20 00:46:27 UTC 2011
>> t.zone
=> "UTC"
>> t.strftime('%z %Z')
=> "-0800 UTC"

That will give you the timezone as UTC, PST, EDT, and similar common abbreviations. If you want the offset, you should be using gmt_offset in both 1.9.3 and 1.8.7:

>> Time.now.gmt_offset
=> -28800
>> Time.now.utc.gmt_offset
=> 0

Note that gmt_offset gives you the offset in seconds.

mu is too short
  • 426,620
  • 70
  • 833
  • 800
  • Awesome. Thank you for the quick response! Right now the program works with the offset, so we won't upset it too much but it's good to know that the offset itself is not part of the library. – roloenusa Dec 20 '11 at 03:01
  • 2
    Quick-and-dirty implementation of "%z" in 1.8 using gmt_offset: `time = Time.now; "#{time.gmt_offset < 0 ? "-" : "+"}%02d%02d" % (time.gmt_offset/60).abs.divmod(60)` – Henrik N Feb 08 '12 at 16:50
-3

Your problem.

ruby-1.9.2-p290 :004 > Time.now.strftime("%z")
 => "-0500" 
ruby-1.9.2-p290 :005 > Time.now.utc.strftime("%z")
 => "+0000" 
daniel
  • 9,732
  • 7
  • 42
  • 57