从字符串中获取时间(以秒为单位)并添加到当前时间



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

现在我得到了总秒数。我想把它变成小时、分钟和秒,然后把它加到当前时间,得到下一次运行时间。有什么简单的方法可以做到这一点吗?

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

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””41s”””

相反,可以将该方法的操作行写如下。

%w| s m h |.each_with_index.sum { |s,i| 60**i * str[/d+#{s}/].to_i }

虽然是博士,但我觉得可读性较差。

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)>
# ]

您可以通过此方法将字符串转换为秒

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")

如果您不需要解析持续时间,只想在代码中定义它,请使用ActiveSupport::Duration以提高可读性。(将宝石添加到您的宝石文件中,并阅读如何使用它的指南)

然后你可以这样使用它:

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

请参阅ActiveSupport的API文档::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)

首先,您可以使用Time#parse方法,而不是split来处理字符串。请确保您也需要该库。

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

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

最新更新