Getting timezone in pure Ruby (no rails)

751 views Asked by At

I am wondering if I can change the timezone in Ruby. I am currently in Asia/Kolkata (+0530).

In my system if I run:

>> puts (1935..1945).map { |x| "#{x} => #{Time.new(x).strftime('%z')}" }
1935 => +0530
1936 => +0530
1937 => +0530
1938 => +0530
1939 => +0530
1940 => +0530
1941 => +0530
1942 => +0630
1943 => +0630
1944 => +0630
1945 => +0630

As you can see timezone changes based on historical events.

I want Ruby (running on any server in any place) to show the timzeone +0630 when Asia/Kolkata or IST is set.


But if I run this code on a different system located at different part of the globe:

I get back:

1935 => +0100
1936 => +0100
1937 => +0100
1938 => +0100
1939 => +0100
1940 => +0100
1941 => +0200
1942 => +0200
1943 => +0100
1944 => +0100
1945 => +0100

Which is probably correct according to their timezone.

Now if I try to follow this question Change Time zone in pure ruby (not rails), and the answer:

p Time.new(1942).utc.localtime("+05:30").strftime('%z')
=> "+0530"

My requirement breaks. Because Asia/Kolkata isn't +05:30 during 1942.


If I mention IST:

p Time.new(1942).utc.+(Time.zone_offset('IST')).strftime('%z')
=> "+0000"

This returns "+0000". But my desired output is "+0630".


Now there are websites which let you do that. So it's technically not impossible to get the +0630 on any server if I enter "IST".


So is there a way to getting back the timezone in Ruby by mentioning the timezone (IST)?

1

There are 1 answers

0
Stefan On BEST ANSWER

For the time being, this works TZ=Asia/Kolkata ruby -e "p Time.new(1942).strftime('%z')"

Setting the TZ environment variable also works from within Ruby: (seen in test_time_tz.rb)

def with_tz(tz)
  old = ENV['TZ']
  ENV['TZ'] = tz
  yield
ensure
  ENV['TZ'] = old
end

with_tz('Asia/Kolkata') do
  (1935..1945).each do |x|
    puts "#{x} => #{Time.local(x).strftime('%z')}"
  end
end