【问题标题】:Getting timezone in pure Ruby (no rails)在纯 Ruby 中获取时区(无轨道)
【发布时间】:2020-09-10 20:04:27
【问题描述】:

我想知道是否可以更改 Ruby 中的时区。我目前在亚洲/加尔各答 (+0530)。

如果我运行,在我的系统中:

>> 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

如您所见,时区会根据历史事件发生变化。

我希望 Ruby(在任何地方的任何服务器上运行)在设置 Asia/Kolkata 或 IST 时显示 timzeone +0630。


但如果我在位于全球不同地区的different system 上运行此代码:

我回来了:

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

根据他们的时区,这可能是正确的。

现在,如果我尝试关注这个问题Change Time zone in pure ruby (not rails),得到答案:

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

我的要求中断了。因为亚洲/加尔各答在 1942 年不是 +05:30。


如果我提到 IST:

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

这将返回“+0000”。但我想要的输出是“+0630”。


现在有websites 可以让你这样做。因此,如果我输入“IST”,从技术上讲,在任何服务器上都无法获得 +0630。


那么有没有办法通过提及时区 (IST) 在 Ruby 中恢复时区?

【问题讨论】:

  • 暂时,这行得通TZ=Asia/Kolkata ruby -e "p Time.new(1942).strftime('%z')"
  • 对于“亚洲/加尔各答”时区的历史变化,您无能为力。如果您看到给定日期的偏移量是错误的,您将需要更新您的 tzdata 或在您的 Ruby 或数据库代码中自己处理它。但是,您当然可以创建使用区域或给定日期的特定偏移量的 Time 和 DateTime 对象。您还可以在 Ruby 中临时设置 ENV["TZ"] 或在 shell 命令中设置 TZ
  • DateTime gem 通常更擅长处理历史日期。默认的 Time 仅适用于现代标准适用的相对较新的时代。

标签: ruby tzinfo


【解决方案1】:

目前,这行得通TZ=Asia/Kolkata ruby -e "p Time.new(1942).strftime('%z')"

设置 TZ 环境变量也可以在 Ruby 中使用:(见 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-10
    • 2015-02-14
    • 2014-10-08
    • 1970-01-01
    • 2017-01-21
    • 1970-01-01
    • 2020-01-17
    • 1970-01-01
    相关资源
    最近更新 更多