简体   繁体   English

有没有更简洁的方法来结合Ruby中的许多比较?

[英]Is there a more concise way to combine many comparisons in Ruby?

I currently have this if statement: 我目前有这个if语句:

if Time.now.day == 1 and Time.now.hour == 0 and Time.now.minute == 0 and Time.now.second == 0

Is there a more concise way to do this? 有没有更简洁的方法来做到这一点?

You can use Time#to_a to convert your time to an array (sec, min, hour, day, month, year, wday, yday, isdst, zone): 您可以使用Time#to_a将您的时间转换为数组(秒,分钟,小时,日,月,年,星期日,日,星期日,区域):

Time.now.to_a  # => [20, 57, 16, 30, 11, 2010, 2, 334, false, "CET"]

then slice off just the part you want to match against: 然后切掉你想要匹配的部分:

Time.now.to_a[0,4]  # => [20, 57, 16, 30]

Your particular check can then be made as concise as this: 您的特定支票可以简洁如下:

if Time.now.to_a[0,4] == [0,0,0,1]
[:day,:hour,:minute,:second].map{|s|Time.now.send s}==[1,0,0,0]

The standard Ruby Time library is pretty spare, so I would simply add my own method to make this easier: 标准的Ruby Time库非常有用,所以我只想添加自己的方法来简化:

class Time
  def beginning_of_month
    Time.local(self.year, self.month, 1)
  end

  def beginning_of_month?
    self == beginning_of_month
  end
end

so you could then write: 所以你可以写:

if Time.now.beginning_of_month?

How about? 怎么样?

Time.now.strftime('%d %H:%M:%S') == '01 00:00:00'

I like this because it's very self-documenting; 我喜欢这个,因为它非常自我记录; It's obvious you're comparing to a certain day at midnight. 很明显,你比较午夜的某一天。

Explanation: The strftime() method makes it easy to output a custom date and/or time string. Explanation: strftime()方法可以轻松输出自定义日期和/或时间字符串。 This format is outputting the day of the month, hour, minute and second. 此格式输出月,日,分和秒的日期。

Time.now.strftime('%d %H:%M:%S') #=> "01 16:54:24"

You can compare it to a time you created: 您可以将它与您创建的时间进行比较:

if Time.now == Time.at(0)

or 要么

if Time.now == Time.utc(2000,"jan",1,20,15,1)

I guess that you are trying to make something similar to cron , ie you are in an endless loop and checking whether time has come to perform certain action. 我想你正在尝试制作类似于cron东西,即你处于无限循环中并检查是否有时间执行某些动作。

If that is the case, I don't think you should rely that your timestamp check will fall exactly on the first second of the day. 如果是这种情况,我认为你不应该依赖你的时间戳检查将完全落在当天的第一天。 What would happen if is delayed (for any reason), and first it fires on 23:59:59 , and the next cycle happens on 00:00:01 instead of :00 ? 如果延迟(由于任何原因)会发生什么,并且首先它在23:59:59触发,下一个周期发生在00:00:01而不是:00 You will fail to perform desired action whatsoever. 您将无法执行任何所需的操作。

Also, you would want to include some sleep , so that your empty loop wouldn't consume all you resources while waiting. 此外,您可能希望包含一些sleep ,以便空循环在等待时不会消耗所有资源。

What you could do instead, is keep the last action timestamp, and compare now with the next action timestamp, performing the action if now >= next_timestamp . 您可以做的是保留最后一个操作时间戳,并now与下一个操作时间戳进行比较,如果now >= next_timestamp则执行操作。 Something like: 就像是:

last_action_on = Time.at(0)
loop do
  now = Time.now
  next_action_on = Time.local(now.year, now.month, 1) # beginning of the current day
  if last_action_on < next_action_on && now >= next_action_on
    last_action_on = now
    do_action
  end
  sleep 1
end
 %w(day==1 hour==0 minute==0 second==0).all? { |e| eval "Time.now.#{e}" }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM