我有一个从窗体填充的Ruby DateTime。此外,我还有n小时的表格。我想从前一个DateTime中减去这n个小时。 (要获得时间范围)。从Ruby中的日期时间减去n小时
DateTime有两种方法“ - ”和“< <”来减去日和月,但不是小时。 (API)。任何建议如何我可以做到这一点?
我有一个从窗体填充的Ruby DateTime。此外,我还有n小时的表格。我想从前一个DateTime中减去这n个小时。 (要获得时间范围)。从Ruby中的日期时间减去n小时
DateTime有两种方法“ - ”和“< <”来减去日和月,但不是小时。 (API)。任何建议如何我可以做到这一点?
你可以这样做。
adjusted_datetime = (datetime_from_form.to_time - n.hours).to_datetime
DateTime
不能做到这一点,但Time
可以:
t = Time.now
t = t-hours*60
注意Time
还存储最新信息,这一切都有点怪。
如果你有DateTime
DateTime.commercial(date.year,date.month,date.day,date.hour-x,date.minute,date.second)
工作可能会奏效,但丑陋。该医生说DateTime
是不变的,所以我甚至不能肯定-
和<<
是的,“DateTime对象一旦创建就是不可变的。” - 它就像Java中的String类。尽管如此:**方法“ - ”:**“如果x是一个数值,则创建一个比当前时间早x天的新Date对象。”,所以我们可以使用它。我也想过你的想法,但我不确定ruby如何将“小时x”的负值转换成负值。这是什么让你丑陋?那么,我试试看。让我们来看看DateTime类的功能;) – 2008-10-26 21:56:16
编辑:在this question看看你决定使用我在这里介绍的方法之前。看起来在Ruby中修改基类的行为可能不是最好的做法(我可以理解)。因此,采取这样的回答与一粒盐...
MattW's answer是我想到的第一件事,但我还没有非常喜欢它。
我想你可以使它不那么难看的补丁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
这是一个完整的解决方案。我不知道这个问题是真的被问到,还是他没有发现新操作员是 “h,min和sec的负值被认为是从下一个更大单位的末尾向后倒数” – Jonke 2008-10-27 00:10:45
你没有说你需要做什么用的VA假如你得到了,那么把你的小时数除以24就可以减去一小部分时间呢?
mydatetime = DateTime.parse(formvalue)
nhoursbefore = mydatetime - n/24.0
我喜欢在active_support中使用助手。它使它非常干净,易于阅读。
见下面的例子:
require 'active_support'
last_accessed = 2.hours.ago
last_accessed = 2.weeks.ago
last_accessed = 1.days.ago
有可能是使用那种语法,做你所寻找的,如果使用当前日期的方式。
你可以只减去小于一整天:
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
或其他一些安全算术实用程序。
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
你可以,但是,使用,而不是理性类:
>> 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
也不是核心Ruby。 – dfrankow 2012-02-17 15:47:54
先遣方法是好的,如果你想对此类行为更明确。
adjusted = time_from_form.advance(:hours => -n)
您可以使用此:
Time.now.ago(n*60*60)
例如Time.now.ago(7200)
会给那是前2小时内从现在的日期和时间。
如果我允许使用Time
代替DateTime
(有several ways to translate one to another):
# Just remove the number of seconds from the Time object
Time.now - (6 * 60 * 60) # 6 hours ago
你只需要脱下一天的部分。
two_hours_ago = DateTime.now - (2.0/24)
请记住,这只适用于Rails环境。 hours()方法来自Rails中的日期帮助程序之一,而不是来自Ruby标准库。 – 2011-11-18 16:41:35
令人沮丧的是,有那么多人认为Ruby = Rails – 2014-01-11 03:04:38