我有一个包含时间的变量foo,比如今天下午4点,但是区域偏移是错误的,即它处于错误的时区。如何更改时区?
当我打印它时,我得到了
Fri Jun 26 07:00:00 UTC 2009
所以没有偏移,我想将偏移设置为-4或东部标准时间。
我希望能够将偏移量设置为Time对象的属性,但这似乎不可用?
答案 0 :(得分:17)
你没有明确说明你是如何获得实际变量的,但是因为你提到了Time类所以我假设你有时间使用它,我将在我的回答中提及
时区实际上是Time类的一部分(在您的情况下,时区显示为UTC)。 Time.now将返回UTC的偏移量作为Time.now响应的一部分。
>> local = Time.now
=> 2012-08-13 08:36:50 +0000
>> local.hour
=> 8
>> local.min
=> 36
>>
......在这种情况下,我碰巧与GMT在同一时区
我发现最简单的方法是使用'+/- HH:MM'格式将偏移量更改为getlocal方法。让我假装我要在都柏林的时间和纽约的时间之间进行转换
?> dublin = Time.now
=> 2012-08-13 08:36:50 +0000
>> new_york = dublin + Time.zone_offset('EST')
=> 2012-08-13 08:36:50 +0000
>> dublin.hour
=> 8
>> new_york.hour
=> 3
假设'EST'是纽约时区的名称,Dan指出有时'EDT'是正确的TZ。
答案 1 :(得分:15)
如果给出:
2011-10-25 07:21:35 -700
你想要:
2011-10-25 07:21:35 UTC
然后做:
Time.parse(Time.now.strftime('%Y-%m-%d %H:%M:%S UTC')).to_s
答案 2 :(得分:14)
这利用了Time#asctime
不包括区域这一事实。
考虑一下时间:
>> time = Time.now
=> 2013-03-13 13:01:48 -0500
强制它到另一个区域(这会返回ActiveSupport::TimeWithZone
):
>> ActiveSupport::TimeZone['US/Pacific'].parse(time.asctime)
=> Wed, 13 Mar 2013 13:01:48 PDT -07:00
请注意,原始区域将被完全忽略。如果我将原始时间转换为utc,结果将会有所不同:
>> ActiveSupport::TimeZone['US/Pacific'].parse(time.getutc.asctime)
=> Wed, 13 Mar 2013 18:01:48 PDT -07:00
您可以对结果使用to_time
或to_datetime
来获取相应的Time
或DateTime
。
This question使用DateTime#change
的有趣方法设置tz偏移量。 (请记住,ActiveSupport可以轻松地在Time
和DateTime
之间进行转换。)缺点是没有DST检测;你必须使用TZInfo的current_period
。
答案 3 :(得分:11)
...
>> Time.at(Time.now.utc + Time.zone_offset('PST'))
=> Mon Jun 07 22:46:22 UTC 2010
>> Time.at(Time.now.utc + Time.zone_offset('PDT'))
=> Mon Jun 07 23:46:26 UTC 2010
>> Time.at(Time.now.utc + Time.zone_offset('CST'))
=> Tue Jun 08 00:46:32 UTC 2010
注意:确保当前时间对象首先设置为UTC时间,否则Ruby将尝试将Time对象转换为您的本地时区,从而抛出计算。在这种情况下,您可以通过在上述陈述的末尾应用“.utc”来获得调整时间。
答案 4 :(得分:10)
对于那些在寻找非铁路解决方案时遇到这种情况的人(正如我所做的那样),TZInfo为我解决了这个问题......
require 'tzinfo'
def adjust_time time, time_zone="America/Los_Angeles"
return TZInfo::Timezone.get(time_zone).utc_to_local(time.utc)
end
puts adjust_time(Time.now)
#=> PST or PDT
puts adjust_time(Time.now, "America/New_York")
#=> EST or EDT
这也处理DST,这是我需要的,上面没有处理过。
答案 5 :(得分:5)
搜索以下行。
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names.
config.time_zone = 'UTC'
请记住,ActiveRecord和Rails总是在内部处理UTC时间。
答案 6 :(得分:2)
我在使用Rails 2.0之前添加了使weppos解决方案有效的代码。这就是我做的事情
# Silly hack, because sometimes the input_date is in the wrong timezone
temp = input_date.to_time.to_a
temp[8] = true
temp[9] = "Eastern Daylight Time"
input_date = Time.local(*temp)
我将时间分解为10个元素数组,更改时区,然后将数组转换回时间。
答案 7 :(得分:1)
这对我有用......
def convert_zones(to_zone)
to_zone_time = to_zone.localtime
end
# have your time set as time
time = convert_zones(time)
time.strftime("%b #{day}, %Y (%a) #{hour}:%M %p %Z")
答案 8 :(得分:0)
选项1
my_date_time = DateTimeAttribute::Container.new(Time.zone.now)
my_date_time.date_time # => 2001-02-03 22:00:00 KRAT +0700
my_date_time.time_zone = 'Moscow'
my_date_time.date_time # => 2001-02-03 22:00:00 MSK +0400
选项2
如果将时间用作属性,则可以使用相同的date_time_attribute gem:
class Task
include DateTimeAttribute
date_time_attribute :due_at
end
task = Task.new
task.due_at_time_zone = 'Moscow'
task.due_at # => Mon, 03 Feb 2013 22:00:00 MSK +04:00
task.due_at_time_zone = 'London'
task.due_at # => Mon, 03 Feb 2013 22:00:00 GMT +00:00
答案 9 :(得分:0)
这就是我所做的,因为我没有使用Rails并且不想使用任何非核心宝石。
t = Time.now # my local time - which is GMT
zone_offset = 3600 # offset for CET - which is my target time zone
zone_offset += 3600 if t.dst? # an extra hour offset in summer
time_cet = Time.mktime(t.sec, t.min, t.hour, t.mday, t.mon, t.year, nil, nil, t.dst?, zone_offset)
答案 10 :(得分:0)
将时间存储为UTC然后在显示时在特定时区显示它可能是个好主意。这是一种简单的方法(适用于Rails 4,不确定早期版本)。
t = Time.now.utc
=> 2016-04-19 20:18:33 UTC
t.in_time_zone("EST")
=> Tue, 19 Apr 2016 15:18:33 EST -05:00
但是如果你真的想将它存储在特定的时区,你可以将初始的Time对象设置为self.in_time_zone,如下所示:
t = t.in_time_zone("EST")
答案 11 :(得分:0)
我很想听听您如何设置变量foo
。
如果您要解析的时间字符串没有时区(我在数据导入期间所做的事情),则可以使用String#in_time_zone
在解析过程中强制使用时区:
"Fri Jun 26 2019 07:00:00".in_time_zone( "Eastern Time (US & Canada)" )
# => Wed, 26 Jun 2019 07:00:00 EDT -04:00
作品像魅力,超级干净。
答案 12 :(得分:0)
您可以这样做:
DateTime.parse('Fri Jun 26 07:00:00 UTC 2009').change(offset: '-0400')
哪个返回:
Fri, 26 Jun 2009 07:00:00 -0400