我想计算2次之间的差异。 start_time:22:00(Rails将此解释为2015-12-31 22:00:00 +0100) second_time:02:00(Rails将其解释为2015-12-31 02:00:00 +0100)。第二次是4小时后,所以在第二天。有没有办法计算这种差异?
我不能简单地这样做:second_time - first_time,因为这给了我22小时而不是4小时的差异。
编辑: 一些背景信息: 工作从22:00开始,到第二天02:00结束。因为我只填写这份工作的形式,所以上述2个值的时间是2015-12-31 22:00:00 +0100和2015-12-31 02:00:00 +0100。我不希望用户填写包括日期在内的时间。时间之间的真正差异应该是4个小时。
所以我真正想要的是计算22:00和02:00之间的差异(第二天)。
答案 0 :(得分:8)
我不明白为什么你认为它应该返回4小时或为什么它会返回22小时。你的例子20小时是正确的:
require 'time'
a = Time.parse('2015-12-31 22:00:00 +0100')
b = Time.parse('2015-12-31 02:00:00 +0100')
a - b
#=> 72000.0 # difference in seconds
(a - b) / 3600
#=> 20.0 # difference in hours
更新:您似乎只处理时间部分,而不是实际日期。我认为你必须处理的最大差异是24小时:
def time_difference(time_a, time_b)
difference = time_b - time_a
if difference > 0
difference
else
24 * 3600 + difference
end
end
a = Time.parse('2015-12-31 22:00:00 +0100')
b = Time.parse('2015-12-31 02:00:00 +0100')
time_difference(a, b) / 3600
# => 4 # hours
a = Time.parse('2015-12-31 02:00:00 +0100')
b = Time.parse('2015-12-31 22:00:00 +0100')
time_difference(a, b) / 3600
# => 20 # hours
答案 1 :(得分:2)
我会这样写(在添加数据检查之前),试图让它自我记录:
require 'time'
DT_FMT = '%Y-%m-%d %H:%M:%S %z'
SECONDS_PER_DAY = 24*60*60
def hours_elapsed(start_str, finish_str)
start = DateTime.strptime(start_str, DT_FMT).to_time
finish = DateTime.strptime(finish_str, DT_FMT).to_time
finish = same_time_tomorrow(finish) if finish < start
(finish-start)/3600
end
def same_time_tomorrow(time)
time + SECONDS_PER_DAY
end
hours_elapsed '2015-12-31 22:00:00 +0100',
'2015-12-31 02:00:00 +0100'
#=> 4.0
hours_elapsed '2015-12-31 02:00:00 +0100',
'2015-12-31 22:00:00 +0100'
#=> 20.0
hours_elapsed
的参数可能更好,只是包含小时和分钟的字符串,在这种情况下我们也可以重命名该方法。 time_elapsed("18:00", "2:30")
是如何调用此方法的示例。
MINUTES_PER_DAY = 24*60
def time_elapsed(start_str, finish_str)
start_mins = time_str_to_minutes(start_str)
finish_mins = time_str_to_minutes(finish_str)
finish_mins += MINUTES_PER_DAY if
finish_mins < start_mins
(finish_mins-start_mins).divmod(60)
end
def time_str_to_minutes(str)
hrs, mins = str.split(':').map(&:to_i)
60 * hrs + mins
end
time_elapsed("8:00", "17:30")
#=> [9, 30]
time_elapsed("18:00", "2:30")
#=> [8, 30]
答案 2 :(得分:0)
老问题,但我做了一个很好的方法来处理它:
def time(start,ending)
if start != ending
medidas=["year","month","day","hour","minute","second"]
array=[1970,1,1,0,0,0]
text = ""
Time.at(ending-start).utc.to_a.take(6).reverse.each_with_index do |k,i|
text = "#{text} #{I18n.translate medidas[i].to_sym, count: k-array[i]}"
end
text = text.strip.squish
pos = text.rindex(" ",(text.rindex(" ")-1))
unless pos.nil?
text = text.insert(pos," and")
end
text = text.strip.squish #This shouldn't be needed but just in case
else
"0 seconds"
end
end
然后在config / locales / en.yml中我添加了:
en:
año:
zero: ''
one: '1 year'
other: '%{count} years'
mes:
zero: ''
one: '1 month'
other: '%{count} months'
dia:
zero: ''
one: '1 day'
other: '%{count} days'
hora:
zero: ''
one: '1 hour'
other: '%{count} hours'
minuto:
zero: ''
one: '1 minute'
other: '%{count} minutes'
segundo:
zero: ''
one: '1 second'
other: '%{count} seconds'
例如,当您致电:
时start = Time.now
ending = start + (60*60)
time(start,ending)
=> "1 hour"
ending = start + (60*60*28)
time(start,ending)
=> "1 day and 4 hours"
ending = start + (53*60*5874)
time(start,ending)
=> "7 months 4 days 4 hours and 42 minutes"
希望它有用