Subtract n hours from a DateTime in Ruby

后端 未结 11 1292
别那么骄傲
别那么骄傲 2020-12-14 06:02

I have a Ruby DateTime which gets filled from a form. Additionally I have n hours from the form as well. I\'d like to subtract those n hours from the previous DateTime. (To

相关标签:
11条回答
  • 2020-12-14 06:45

    If I'm allowed to use Time instead of DateTime (There are 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
    
    0 讨论(0)
  • 2020-12-14 06:49

    The advance method is nice if you want to be more explicit about behavior like this.

    adjusted = time_from_form.advance(:hours => -n)
    
    0 讨论(0)
  • 2020-12-14 06:52

    You just need to take off fractions of a day.

    two_hours_ago = DateTime.now - (2.0/24)
    
    • 1.0 = one day
    • 1.0/24 = 1 hour
    • 1.0/(24*60) = 1 minute
    • 1.0/(24*60*60) = 1 second
    0 讨论(0)
  • 2020-12-14 06:55

    You can just subtract less than one whole day:

    two_hours_ago = DateTime.now - (2/24.0)
    

    This works for minutes and anything else too:

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

    If floating point arithmetic inaccuracies are a problem, you can use Rational or some other safe arithmetic utility.

    0 讨论(0)
  • 2020-12-14 06:56

    You could do this.

    adjusted_datetime = (datetime_from_form.to_time - n.hours).to_datetime
    
    0 讨论(0)
  • 2020-12-14 06:57

    n/24.0 trick won't work properly as floats are eventually rounded:

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

    You can, however, use Rational class instead:

    >> 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
    
    0 讨论(0)
提交回复
热议问题