我正在尝试从创建的方法中减去3个小时,但出现错误

时间:2018-10-04 14:45:51

标签: ruby date datetime time dst

我已经成功创建了一个名为dst_datechange的DST方法,该方法带有一个日期,可以使用Time.parse进行解析。看起来像这样:

require 'time'
def dst_datechange(date)
  date = Time.parse(date.to_s) # if date.class.eql?(String)
  case
  when (date > Time.parse('March 11, 2018 2:00am')) && (date < 
Time.parse('November 4, 2018 2:00am'))
    date = Time.parse('November 4, 2018 2:00am')
    puts "the date rounded to november 4, 2018"
  when (date > Time.parse('November 4 2018, 2:00am')) && (date < 
Time.parse('March 10, 2:00am'))
    date = Time.parse('March 10, 2019 2:00am')
    puts "the date rounded to march 10 2019"
  when (date > Time.parse('March 10, 2019 2:00am')) && (date < 
Time.parse('November 3, 2019 2:00am'))
    date = Time.parse('November 3, 2019 2:00am')
  when (date > Time.parse('November 3, 2019 2:00am')) && (date < 
Time.parse('March 8, 2020 2:00am'))
    date = Time.parse('March 8, 2020 2:00am')
  when (date > Time.parse('March 8, 2020 2:00am')) && (date < 
Time.parse('November 1, 2020 2:00am'))
    date = Time.parse ('November 1, 2020 2:00am')
  else
    raise "The date #{date} does not match any dst date parameter"
  end
  date
  puts "the new DST date is #{date}"
end

我的“ puts”显示此内容...

the date rounded to: november 4, 2018 
 the new DST date is now: 2018-11-04 02:00:00 -0600

现在我收到了正确的日期,我有一个将dst_datechange减去并执行减法的步骤,但是,我收到一条错误消息:

TypeError: no implicit conversion of Integer into Array

我不确定自己在做什么错,但我知道它很可能是格式问题,我试图用一个时间对象减去一个日期时间对象。这是我在下面的步骤中,堆栈跟踪将故障指向:

  date = (dst_datechange(Time.now) - (60*60*3))
  puts "the date is now adjusted 3 hours back from 2:00am:  #{date} "
end

我不确定如何格式化该格式(60 * 60 * 3)以从新的11月2018-11-04 02:00:00 -0600日期减去3小时并将其基本回滚到2018-11-03 23:00:00 -0600

3 个答案:

答案 0 :(得分:0)

您需要指定要减去小时数。试试:

# PowerShell *Core* only
[double](get-date -uformat %s ((get-date).AddMinutes(-5))) * 1000

或者,如果使用ActiveSupport,则可以指定三个小时前:

(Time.now - 3.hours).to_datetime

答案 1 :(得分:0)

您的方法def dst_datechange(date)不会返回您想要的日期,而是放置您的字符串。

当您在第二部分中调用dst_datechange(Time.now)时,它不会返回日期,而是最后一次看跌期权的返回值。

在将最终结果放入dst_datechange方法之后,尝试再次调用“日期”:

when (date > Time.parse('March 8, 2020 2:00am')) && (date < Time.parse('November 1, 2020 2:00am'))
date = Time.parse ('November 1, 2020 2:00am')
  else
    raise "The date #{date} does not match any dst date parameter"
  end
  puts "the new DST date is #{date}"
  date
end

答案 2 :(得分:0)

自2007年以来,在美国和加拿大的大多数辖区中,夏令时(“ DST”)从3月的第二个星期日的凌晨2:00开始,到11月的第一个星期日的凌晨2:00结束。在墨西哥,夏令时开始于4月的第一个星期日的2:00 am,结束于10月的最后一个星期日的2:00 am。在世界其他地方,体验各不相同。 1

给出一个Time对象(可能是根据时间的字符串表示来计算的),您的代码将返回第二个Time对象,该对象等于从DST到STD的下一次更改的时间,或者反之亦然(即在美国和加拿大采用DST的部分地区)。无需硬性规定这些日期。计算可以如下进行。

require 'time'

def dst_datechange(time)
  year = time.year
  if time.dst?
    start_std(year)
  else
    year += 1 if time >= Time.new(year, 11)
    start_dst(year)
  end
end

def start_std(year)
  date = Date.new(year, 11)
  date += (7-date.wday) % 7
  Time.new(date.year, date.month, date.day, 2)
end

def start_dst(year)
  date = Date.new(year, 3, 8)
  date += (7-date.wday) % 7
  Time.new(date.year, date.month, date.day, 2)
end

['June 17, 2018 1:00pm', 'November 4, 2018 12:59am', 'November 4, 2018 1:00am',      
 'March 10, 2019 1:59am', 'March 10, 2019 2:00am'].
  each do |s|
    t = DateTime.strptime(s, '%B %e, %Y %l:%M%P').to_time
    t = Time.new(t.year, t.month, t.day, t.hour, t.min, t.sec)
    puts "#{s}: #{ dst_datechange(t) }"
  end
  June     17, 2018  1:00pm: 2018-11-04 02:00:00 -0800
  November  4, 2018 12:59am: 2018-11-04 02:00:00 -0800
  November  4, 2018  1:00am: 2019-03-10 03:00:00 -0700
  March    10, 2019  1:59am: 2019-03-10 03:00:00 -0700
  March    10, 2019  2:00am: 2019-11-03 02:00:00 -0800

请注意,第一个,第二个和最后一个示例返回的时间为2。实际上,这是时间更改后的一个小时。其他两个示例返回3的小时,这是时间更改后的瞬间。注意:

Time.new(2019, 3, 10, 2)
  #=> 2019-03-10 03:00:00 -0700
Time.parse('March 10, 2019 2:00am')
  #=> 2019-03-10 03:00:00 -0700

将来,夏令时的日期范围可能会更改(就像2007年一样),或者夏令时的日期可能是eliminated altogether。因此,在生产代码中,谨慎处理这些可能性。假设方法Time#dst?将继续存在,Time.new(year,6).dst?应该告诉我们是否还有DST,如果存在,则可以每天进行搜索以查看时间何时发生变化。

1。 Source