Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 在rails DateTime.parse中更正夏令时的时间_Ruby On Rails_Ruby On Rails 3_Timezone - Fatal编程技术网

Ruby on rails 在rails DateTime.parse中更正夏令时的时间

Ruby on rails 在rails DateTime.parse中更正夏令时的时间,ruby-on-rails,ruby-on-rails-3,timezone,Ruby On Rails,Ruby On Rails 3,Timezone,只是增加了关于时区和DST问题的百万个问题 我有一个带有单独日期和时间字段的表单,我将其组合起来创建一个类似这样的日期时间 start_time = DateTime.parse("#{parse_date(form_date)} #{form_start_time} #{Time.zone}") 如果我用2012年8月21日和15:00填写表格,则这些是我在重新加载表格时看到的值。然后,如果我查看模型中的“开始时间”属性,它将正确设置为2012年8月21日星期二15:00:00东部标准时间+

只是增加了关于时区和DST问题的百万个问题

我有一个带有单独日期和时间字段的表单,我将其组合起来创建一个类似这样的日期时间

start_time = DateTime.parse("#{parse_date(form_date)} #{form_start_time} #{Time.zone}")
如果我用2012年8月21日和15:00填写表格,则这些是我在重新加载表格时看到的值。然后,如果我查看模型中的“开始时间”属性,它将正确设置为2012年8月21日星期二15:00:00东部标准时间+10:00

如果我在今年晚些时候开始使用夏令时(我在澳大利亚),我就会遇到这个问题。如果我使用2012年12月21日和15:00,那么请检查我看到的开始时间
Fri,2012年12月21日东部时间16:00:00+11:00

我对问题的解释是,日期保存在我当前的时区(+10:00),因为这是我告诉DateTime.parse要做的。然而,当返回值时,Rails会查看日期并说“嘿,这是12月的夏令时”,然后返回+11:00时区的时间


我要做的是告诉DateTime.parse,如果DST有效,则将时间保存在+11:00时区。显然,将Time.zone传递到字符串中并不能实现这一点。有没有一个简单的方法可以做到这一点?我能找到用时间做这件事的方法?但我怀疑这会产生一些非常难看的卷积代码。我想可能有一种内置的方式是我所缺少的。

这是我目前为止的解决方案。我希望有人有更好的

start_time = DateTime.parse "#{date} #{(form_start_time || start_time)} #{Time.zone}"
start_time = start_time - 1.hour if start_time.dst? && !Time.now.dst?
start_time = start_time + 1.hour if Time.now.dst? && start_time.dst?
它似乎有效,但我还没有严格测试它。我怀疑它可以被修饰和缩短,但我认为这是可读和可以理解的。有什么改进吗?

我会尝试使用

Australian Eastern Standard Time (AEST) (UTC +10).  
Australian Central Standard Time (ACST) (UTC +9 ½).  
Australian Western Standard Time (AWST) (UTC +8).  

可根据夏时制进行调整。

对于Rails,我们可以使用ActiveSupport::TimeZone来实现以下功能:

tz = ActiveSupport::TimeZone.new 'Pacific Time (US & Canada)'
tz.parse(date_str_without_zone).to_datetime

我过去常常从邮政编码中获取时区字符串(例如“太平洋时间(美国和加拿大)”。

我遇到了这个问题。我的应用程序允许用户查看即将到来的事件。在美国,11月2日是DST的秋季,当天和之后的所有事件都提前了一小时

我们需要有机会选择时区并将其存储到自己的字段中。在我使用以下内容存储日期时间之前:

timezone_offset = Time.now.in_time_zone(params[:opportunity][:time_zone]).strftime("%z") #-0700
DateTime.parse("#{params[:opportunity][:start_datetime]} #{timezone_offset}")
要解决此问题,我已更改为:

start_datetime = Time.zone.parse(params[:opportunity][:start_datetime])
要显示我们使用的正确时间,请执行以下操作:

@opportunity.start_datetime.in_time_zone(@opportunity.time_zone)
(Rails 4.2.4的答案,没有检查旧版本或新版本)

我建议使用时区名称作为参数的
in_time_zone
字符串方法,而不是使用固定移位+01:00、+02:00等:

夏季时间:

ruby :001 > "2016-07-02 00:00:00".in_time_zone('Paris')
 => Sat, 02 Jul 2016 00:00:00 CEST +02:00 
冬季时间:

ruby :002 > "2016-11-02 00:00:00".in_time_zone('Paris')
 => Wed, 02 Nov 2016 00:00:00 CET +01:00 
String#in_time_分区
相当于:

ruby :003 > Time.find_zone!("Paris").parse("2016-07-02 00:00:00")
 => Sat, 02 Jul 2016 00:00:00 CEST +02:00 

ruby :004 > Time.find_zone!("Paris").parse("2016-11-02 00:00:00")
 => Wed, 02 Nov 2016 00:00:00 CET +01:00 
您可以通过以下方式获取时区名称:

$ rake time:zones:all
或在rails控制台中:

ruby :001 > ActiveSupport::TimeZone.all.map(&:name)
或为选择标记生成集合:

ActiveSupport::TimeZone.all.map do |timezone|
  formatted_offset = Time.now.in_time_zone(timezone.name).formatted_offset
  [ "(GMT#{formatted_offset}) #{timezone.name}", timezone.name ]
end
并存储时区名称而不是班次

注意:不要混淆
字符串#在时区
方法和
时间#在时区
方法

考虑一下我的系统的时区是“巴黎”

ruby :001 > Time.parse("2016-07-02 00:00:00")
 => 2016-07-02 00:00:00 +0200 
ruby :002 > Time.parse("2016-07-02 00:00:00").in_time_zone("Nuku'alofa")
 => Sat, 02 Jul 2016 11:00:00 TOT +13:00 

如果您有一个自定义的日期/时间格式,不同于时区中的
字符串所支持的格式,您还可以使用(因为rails 5)如下:


我将如何以及在哪里设置这些。当我做rake time:zones:all时,我没有看到列出这些时区。这不应该是if time.now.dst吗?&&!开始时间。dst?@brad,我意识到这是一个非常古老的问题,但你有没有找到更好的处理方法?如果没有,您是否发现这很有效?谢谢
Time.find_zone!('Auckland').strptime('2021-02-02 08.00.00', '%Y-%m-%d %H.%M.%S')