Ruby 如何等待特定的时间,如午夜,然后再继续

Ruby 如何等待特定的时间,如午夜,然后再继续,ruby,Ruby,我们正试图让测试等到午夜才进行 目前,它每秒钟检查一次午夜,控制台中充满了一堆“等待午夜”消息 有没有办法让它检查一下时间然后等到午夜 def wait_if_almost_midnight max_minutes_needed, utc: false seconds_waited = 0 now = utc ? Time.now.utc : DateTime.now now_hour = now.strftime('%k').to_i now_minute =

我们正试图让测试等到午夜才进行

目前,它每秒钟检查一次午夜,控制台中充满了一堆“等待午夜”消息

有没有办法让它检查一下时间然后等到午夜

def wait_if_almost_midnight max_minutes_needed, utc: false
    seconds_waited = 0
    now = utc ? Time.now.utc : DateTime.now
    now_hour = now.strftime('%k').to_i
    now_minute = now.strftime('%M').to_i
    while now_hour == 23 && max_minutes_needed > (59 - now_minute)
      sleep 1
      seconds_waited += 1
       p "Waiting for midnight, seconds: #{seconds_waited}"
       now_hour = now.strftime('%k').to_i
      now_minute = now.strftime('%M').to_i
    end
  end
删除对内核#p的调用 要回答实际问题,只需删除内核#p调用以停止填充控制台:

# This is what's printing to your console.
p "Waiting for midnight, seconds: #{seconds_waited}"
然而,像这样的睡眠循环并不是很有效。您最好在午夜使用cron启动一个进程,或者在您想要的任何时间使用Sidekiq或类似的排队和处理作业

警告 因为我不知道为什么这是一个对你有用的测试,我不会告诉你不要用这种方式测试。然而,我怀疑你有一些时间敏感的边缘案件,你想处理。通常最好是存根/模拟任何对时间敏感的方法,而不是等待很长时间,或者调整web服务器的实际系统时钟,这样测试只能在接近午夜时执行

与外部条件的紧密耦合通常是一种代码气味。考虑是否真的需要在提交X/Y解决方案之前测试此方法,因为这种类型的方法常常导致测试缓慢或“HeieNebug”。您的里程可能会有所不同。

将调用删除到内核μP。 要回答实际问题,只需删除内核#p调用以停止填充控制台:

# This is what's printing to your console.
p "Waiting for midnight, seconds: #{seconds_waited}"
然而,像这样的睡眠循环并不是很有效。您最好在午夜使用cron启动一个进程,或者在您想要的任何时间使用Sidekiq或类似的排队和处理作业

警告 因为我不知道为什么这是一个对你有用的测试,我不会告诉你不要用这种方式测试。然而,我怀疑你有一些时间敏感的边缘案件,你想处理。通常最好是存根/模拟任何对时间敏感的方法,而不是等待很长时间,或者调整web服务器的实际系统时钟,这样测试只能在接近午夜时执行


与外部条件的紧密耦合通常是一种代码气味。考虑在提交X/Y解决方案之前是否真的需要测试这种方法,因为这种类型的方法通常会导致测试缓慢或“HeieNebug”。您的里程可能会有所不同。

< P>您太难了。只需计算到午夜还有多少秒,然后
sleep

我过去也用过类似的方法:

require 'date'

def seconds_until_midnight
  Date.today.next_day.to_time.to_i - Time.now.to_i
end
测试它:

5.times do
  puts '%i seconds until midnight' % seconds_until_midnight()
  sleep 1
end

# >> 35142 seconds until midnight
# >> 35141 seconds until midnight
# >> 35140 seconds until midnight
# >> 35139 seconds until midnight
# >> 35138 seconds until midnight
只需使用:

sleep seconds_until_midnight()
或将代码更改为:

require 'date'

def sleep_until_midnight
  midnight = Date.today.next_day.to_time.to_i - Time.now.to_i
  sleep midnight
end
然后调用
sleep\u直到午夜()

这就是神奇的部分:

Date.today                  # => #<Date: 2020-04-09 ((2458949j,0s,0n),+0s,2299161j)>
Date.today.next_day         # => #<Date: 2020-04-10 ((2458950j,0s,0n),+0s,2299161j)>
Date.today.next_day.to_time # => 2020-04-10 00:00:00 -0700
把它叫做:

sleep_until_midnight(-5)
sleep_until_midnight(+1)

然而,与托德·雅各布斯在回答中所说的相似,为什么?测试应该立即运行,而不是在特定的时间运行,这样您就可以在开发过程中获得结果并对其作出反应。如果要测试某个页面是否存在或在特定时间解析它,请使用
cron
或类似的工具。

你太难了。只需计算到午夜还有多少秒,然后
sleep

我过去也用过类似的方法:

require 'date'

def seconds_until_midnight
  Date.today.next_day.to_time.to_i - Time.now.to_i
end
测试它:

5.times do
  puts '%i seconds until midnight' % seconds_until_midnight()
  sleep 1
end

# >> 35142 seconds until midnight
# >> 35141 seconds until midnight
# >> 35140 seconds until midnight
# >> 35139 seconds until midnight
# >> 35138 seconds until midnight
只需使用:

sleep seconds_until_midnight()
或将代码更改为:

require 'date'

def sleep_until_midnight
  midnight = Date.today.next_day.to_time.to_i - Time.now.to_i
  sleep midnight
end
然后调用
sleep\u直到午夜()

这就是神奇的部分:

Date.today                  # => #<Date: 2020-04-09 ((2458949j,0s,0n),+0s,2299161j)>
Date.today.next_day         # => #<Date: 2020-04-10 ((2458950j,0s,0n),+0s,2299161j)>
Date.today.next_day.to_time # => 2020-04-10 00:00:00 -0700
把它叫做:

sleep_until_midnight(-5)
sleep_until_midnight(+1)

然而,与托德·雅各布斯在回答中所说的相似,为什么?测试应该立即运行,而不是在特定的时间运行,这样您就可以在开发过程中获得结果并对其作出反应。如果要测试页面是否存在或在特定时间对其进行解析,请使用
cron
或类似的工具。

我将回答此问题,而不受
utc
参数的干扰

require 'date'

def wait_if_almost_midnight(secs_left_to_begin_reporting = 3600)
  time_now = DateTime.now.to_time
  time_at_midnight = time_now.to_date.next.to_time
  secs_to_midnight = time_at_midnight.to_i - time_now.to_i
  puts "#{secs_to_midnight} seconds until midnight"
  secs_left = secs_to_midnight
  if secs_left > secs_left_to_begin_reporting
    sleep_time = secs_left - secs_left_to_begin_reporting
    secs_left -= sleep_time
    puts "I'm off to sleep for #{sleep_time} seconds, then I'll report "
    puts "every second for the last #{secs_left_to_begin_reporting-1} seconds"
    puts "zzzzzzzzzzzz"
    sleep(sleep_time)
  end
  (secs_left-1).downto(1) do |i|
    p "Waiting for midnight, seconds waited so far: #{secs_to_midnight-i}"
    sleep(1)
  end
end
让我们试试看:

wait_if_almost_midnight(10)
# 37965 seconds until midnight
# I'm off to sleep for 37779 seconds, then I'll report 
# every second for the last 9 seconds
# zzzzzzzzzzzz
(稍后…)


我将回答这个问题,而不受
utc
参数的干扰

require 'date'

def wait_if_almost_midnight(secs_left_to_begin_reporting = 3600)
  time_now = DateTime.now.to_time
  time_at_midnight = time_now.to_date.next.to_time
  secs_to_midnight = time_at_midnight.to_i - time_now.to_i
  puts "#{secs_to_midnight} seconds until midnight"
  secs_left = secs_to_midnight
  if secs_left > secs_left_to_begin_reporting
    sleep_time = secs_left - secs_left_to_begin_reporting
    secs_left -= sleep_time
    puts "I'm off to sleep for #{sleep_time} seconds, then I'll report "
    puts "every second for the last #{secs_left_to_begin_reporting-1} seconds"
    puts "zzzzzzzzzzzz"
    sleep(sleep_time)
  end
  (secs_left-1).downto(1) do |i|
    p "Waiting for midnight, seconds waited so far: #{secs_to_midnight-i}"
    sleep(1)
  end
end
让我们试试看:

wait_if_almost_midnight(10)
# 37965 seconds until midnight
# I'm off to sleep for 37779 seconds, then I'll report 
# every second for the last 9 seconds
# zzzzzzzzzzzz
(稍后…)


如果现在是一个月的最后一天,那么您现在用于计算<代码>午夜的内容不是一个问题吗?我建议
midnight=date.next.to\u time\u to\u I
。否则,答案很好。你可能是对的。我原以为它会翻滚,但那可能是一个错误。你的建议更简洁,总是很好的。如果现在是一个月的最后一天,那么你现在用来计算
午夜的
难道不是一个问题吗?我建议
midnight=date.next.to\u time\u to\u I
。否则,答案很好。你可能是对的。我原以为它会翻滚,但那可能是一个错误。你的建议更简洁,总是好的。