Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby's strftime not displaying timezone offset with '%Z'

I have the following Time object:

[8] pry(#<#<Class:0x007f928f12f560>>)> display_num
=> 2015-02-19 09:00:00 -0600
[9] pry(#<#<Class:0x007f928f12f560>>)> display_num.is_a?(Time)
=> true
[10] pry(#<#<Class:0x007f928f12f560>>)> display_num.is_a?(DateTime)
=> false
[11] pry(#<#<Class:0x007f928f12f560>>)> display_num.strftime("%l:%M%P %Z")
=> " 9:00am "
[12] pry(#<#<Class:0x007f928f12f560>>)> display_num.strftime("%l:%M%P %z")
=> " 9:00am -0600"

I'm completely stumped as this:

[16] pry(#<#<Class:0x007f928f12f560>>)> Time.new
=> 2015-02-02 14:09:13 -0800
[17] pry(#<#<Class:0x007f928f12f560>>)> t = Time.new
=> 2015-02-02 14:09:25 -0800
[18] pry(#<#<Class:0x007f928f12f560>>)> t.strftime("%l:%M%P %Z")
=> " 2:09pm PST"

works just fine.

What is going on in the above block to prevent a timezone from displaying in human readable format?

like image 907
Gregg Horton Avatar asked Feb 02 '15 22:02

Gregg Horton


2 Answers

The format directive %Z requests the symbolic time zone (name or abbreviation); %z is the offset. While you always know the offset, you may not know the symbolic time zone name.

I suspect that's what's going on with display_time. It was initialized with an offset, so it doesn't have any symbolic time zone name to display.

You can't reliably derive a name from an offset, either; for example, -0400 could be Atlantic Standard Time or Eastern Daylight Time. Most offsets will have more than one option for what time zone they are, and most time zones have more than one name anyway.

like image 69
Mark Reed Avatar answered Nov 09 '22 00:11

Mark Reed


Worth adding, if you're using Rails, ActiveSupport monkey-patches in the method in_time_zone that you can use to fix this issue with strftime:

Time.current.localtime("-06:00").strftime("TZ is: %Z") # => "TZ is: "
Time.current.in_time_zone("America/Chicago").strftime("TZ is: %Z") # => "TZ is: CDT"
Time.current.in_time_zone("America/New_York").strftime("TZ is: %Z") # => "TZ is: EDT"

References:

DateAndTime::Zones#in_time_zone

Full list of time zone strings is defined in ActiveSupport::TimeZone::MAPPING

like image 42
Nathan Wallace Avatar answered Nov 09 '22 00:11

Nathan Wallace