在Ruby中从DateTime减去n个小时
我有一个从窗体填充的Ruby DateTime。 另外我也有从表格n小时。 我想从前一个DateTime中减去那n个小时。 (要获得时间范围)。
date时间有两个方法“ – ”和“<<”减去日和月,但不是小时。 ( API )。 任何build议我怎么能做到这一点?
你可以做到这一点。
adjusted_datetime = (datetime_from_form.to_time - n.hours).to_datetime
你可以减去不到一整天:
two_hours_ago = DateTime.now - (2/24.0)
这适用于分钟和其他任何事情:
hours = 10 minutes = 5 seconds = 64 hours = DateTime.now - (hours/24.0) #<DateTime: 2015-03-11T07:27:17+02:00 ((2457093j,19637s,608393383n),+7200s,2299161j)> minutes = DateTime.now - (minutes/1440.0) #<DateTime: 2015-03-11T17:22:17+02:00 ((2457093j,55337s,614303598n),+7200s,2299161j)> seconds = DateTime.now - (seconds/86400.0) #<DateTime: 2015-03-11T17:26:14+02:00 ((2457093j,55574s,785701811n),+7200s,2299161j)>
如果浮点算术不准确是一个问题,那么可以使用Rational
或其他一些安全算术工具。
先进的方法是很好的,如果你想更像这样的行为更加明确。
adjusted = time_from_form.advance(:hours => -n)
n/24.0
技巧将无法正常工作,因为花车最终是四舍五入的:
>> DateTime.parse('2009-06-04 02:00:00').step(DateTime.parse('2009-06-04 05:00:00'),1.0/24){|d| puts d} 2009-06-04T02:00:00+00:00 2009-06-04T03:00:00+00:00 2009-06-04T03:59:59+00:00 2009-06-04T04:59:59+00:00
但是,您可以使用Rational类来代替:
>> DateTime.parse('2009-06-04 02:00:00').step(DateTime.parse('2009-06-04 05:00:00'),Rational(1,24)){|d| puts d} 2009-06-04T02:00:00+00:00 2009-06-04T03:00:00+00:00 2009-06-04T04:00:00+00:00 2009-06-04T05:00:00+00:00
你只需要脱掉一天中的一小部分。
two_hours_ago = DateTime.now - (2.0/24)
- 1.0 =一天
- 1.0 / 24 = 1小时
- 1.0 /(24 * 60)= 1分钟
- 1.0 /(24 * 60 * 60)= 1秒
如果我可以使用Time
而不是DateTime
Time
(有几种方法可以将一个翻译成另一个 ):
# Just remove the number of seconds from the Time object Time.now - (6 * 60 * 60) # 6 hours ago
你没有说出你需要怎样的价值来得到你的价值,但是把你的小时数除以24就可以减去一小部分的时间呢?
mydatetime = DateTime.parse(formvalue) nhoursbefore = mydatetime - n / 24.0
编辑 :看看这个问题,然后再决定使用我在这里概述的方法。 看来这可能不是最好的做法来修改Ruby中的基类的行为(我可以理解)。 所以,用一粒盐来回答这个问题
MattW的回答是我想到的第一件事,但我也不太喜欢它。
我想你可以通过修补DateTime
和Fixnum
来完成你想做的事情,
require 'date' # A placeholder class for holding a set number of hours. # Used so we can know when to change the behavior # of DateTime#-() by recognizing when hours are explicitly passed in. class Hours attr_reader :value def initialize(value) @value = value end end # Patch the #-() method to handle subtracting hours # in addition to what it normally does class DateTime alias old_subtract - def -(x) case x when Hours; return DateTime.new(year, month, day, hour-x.value, min, sec) else; return self.old_subtract(x) end end end # Add an #hours attribute to Fixnum that returns an Hours object. # This is for syntactic sugar, allowing you to write "someDate - 4.hours" for example class Fixnum def hours Hours.new(self) end end
然后你可以这样写你的代码:
some_date = some_date - n.hours
其中n
是您想要从some_date
减去的小时数
DateTime
Time
不能做到这一点,但Time
可以:
t = Time.now t = t-hours*60
请注意, Time
也存储date信息,这有点奇怪。
如果你必须使用DateTime
DateTime.commercial(date.year,date.month,date.day,date.hour-x,date.minute,date.second)
可能工作,但是很难看。 文档说DateTime
是不可变的,所以我甚-
不知道-
和<<
我喜欢在active_support中使用助手。 它使它非常干净,易于阅读。
看下面的例子:
require 'active_support' last_accessed = 2.hours.ago last_accessed = 2.weeks.ago last_accessed = 1.days.ago
如果使用当前date,可能有一种方法可以使用这种语法来做你正在寻找的东西。
你可以使用这个:
Time.now.ago(n*60*60)
例如Time.now.ago(7200)
将给出从现在开始2小时之前的date和时间。