从字符串中获取时间并添加到当前时间?

时间:2018-05-27 08:29:29

标签: ruby time

timestr = '15h 37m 5s'

我想从上面的字符串中获取小时分和秒,并将其添加到当前时间。

  def next_run
    timestr = '15h 37m 5s'
    timearr = timestr.split(' ').map { |t| t.to_i }
    case timearr.count
    when 3
      next_ = (timearr[0] * 3600) + (timearr[1] * 60) + timearr[2]
    when 2
      next_ = (timearr[1] * 60) + timearr[2]
    when 1
      next_ = timearr[2]
    else
      raise 'Unknown length for timestr'
    end
    time_to_run_in_secs =  next_
  end

现在我得到总秒数。我希望将其设置为小时分钟和秒,然后将其添加到当前时间以获得下一个运行时间。有没有简单的方法呢?

5 个答案:

答案 0 :(得分:1)

可以使用以下方法计算字符串中的秒数。

def seconds(str)
  3600 * str[/\d+h/].to_i + 60 * str[/\d+m/].to_i + str[/\d+s/].to_i
end

注意nil.to_i #=>0。一个轻微的变体是写3600 * (str[/\d+h/] || 0) +...

然后

Time.now + seconds(str)

str的可能值示例如下:”3h 26m 41s””3h 26m””3h 41s””41s 3h””3h”,{{1 }和”41s”

可以改为编写方法的操作线如下。

””

虽然DRYer,但我发现它的可读性较差。

答案 1 :(得分:1)

DateTime#+接受Rational个实例作为天添加。只需几秒就可以将所有内容转换为天数,然后将其添加到当前时间戳中:

DateTime.now.tap do |dt|
  break [dt, dt + Rational(100, 3600 * 24) ]
end
#⇒ [
#    [0] #<DateTime: 2018-05-27T11:13:00+02:00 ((2458266j,33180s,662475814n),+7200s,2299161j)>,
#    [1] #<DateTime: 2018-05-27T11:14:40+02:00 ((2458266j,33280s,662475814n),+7200s,2299161j)>
# ]

答案 2 :(得分:1)

首先,您可以使用split method代替Time#parse字符串。确保您也需要图书馆。

require 'time'
=> true
Time.parse('15h 37m 5s')
=> 2018-05-27 15:37:05 +0300

这将返回类Time的新对象,它有一些非常有用的方法 - #sec, #min, #hour

time = Time.parse('15h 37m 5s')
time.sec       #=> 5
time.min       #=> 37
time.hour      #=> 15

添加一个Time对象是非常简单的,因为你只能通过seconds来完成。解决当前问题的一个简单方法是:

def next_run
  time = Time.parse('15h 37m 5s')
  seconds_to_add = time.hour * 3600 + time.min * 60 + time.sec
  Time.now + seconds_to_add
end

希望这会回答你的问题! :)

答案 3 :(得分:1)

您可以使用此方法将字符串转换为秒数

def seconds(str)
  (3600 * str[/\d+(h|H)/].to_i) + (60 * str[/\d+(m|M)/].to_i) + (str[/\d+(s|S)/].to_i)
end

然后使用方法

将当前时间转换为秒
next_run_time = Time.now.to_i + seconds(<Your Time String>)

现在使用

获取下一次运行时间
Time.at(next_run_time)

在你的情况下使用strftime方法获得所需的时间格式

Time.at(next_run_time).strftime("%Hh %Mm %Ss")

答案 4 :(得分:1)

如果您不需要解析持续时间,并且只想在代码中定义它,请使用ActiveSupport::Duration以提高可读性。 (将the gem添加到您的Gemfile中,并阅读the guide了解如何使用它)

然后你可以像这样使用它:

require 'active_support'
require 'active_support/core_ext/integer'    

DURATION = 15.hours + 37.minutes + 5.seconds
# use DURATION.seconds or DURATION.to_i to get the seconds

def next_run
  Time.now + DURATION
end

请参阅API documentation of ActiveSupport::Duration

如果您需要通过用户输入定义下一次运行,最好使用ISO 8601来定义持续时间:https://en.wikipedia.org/wiki/ISO_8601#Durations

ISO 8601持续时间是可解析的:

ActiveSupport::Duration.parse('PT15H37M5S') # => 15 hours, 37 minutes, and 5 seconds (duration)