Subtract n hours from a DateTime in Ruby

后端 未结 11 1293
别那么骄傲
别那么骄傲 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 07:00

    I like using the helpers in active_support. It makes it really clean and easy to read.

    See the example below:

    require 'active_support'
    
    last_accessed = 2.hours.ago
    last_accessed = 2.weeks.ago
    last_accessed = 1.days.ago
    

    There might be a way to use that kind of syntax to do what you are looking for, if the current date is used.

    0 讨论(0)
  • 2020-12-14 07:01

    EDIT: Take a look at this question before you decide to use the approach I've outlined here. It seems it may not be best practice to modify the behavior of a base class in Ruby (which I can understand). So, take this answer with a grain of salt...


    MattW's answer was the first thing I thought of, but I also didn't like it very much.

    I suppose you could make it less ugly by patching DateTime and Fixnum to do what you want:

    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
    

    Then you can write your code like this:

    some_date = some_date - n.hours
    

    where n is the number of hours you want to substract from some_date

    0 讨论(0)
  • 2020-12-14 07:03

    You can use this :

    Time.now.ago(n*60*60)
    

    For example Time.now.ago(7200) will give the date and time that was before 2 hours from now.

    0 讨论(0)
  • 2020-12-14 07:05

    You didn't say what use you need to make of the value you get, but what about just dividing your hours by 24 so you're subtracting a fraction of a day?

    mydatetime = DateTime.parse(formvalue)
    nhoursbefore = mydatetime - n / 24.0
    
    0 讨论(0)
  • 2020-12-14 07:05

    If you are working in Rails, the following super-intutive possibility exists:

    > Time.now - 12.hours
    => 2019-08-19 05:50:43 +0200
    

    (This also works with seconds, minutes, days, and years)

    if you're using just Ruby, DateTime can't do this, but Time can:

    t = Time.now
    t = t - (hours*60**2)
    

    Note that Time also stores date information, it's all a little strange.

    If you have to work with DateTime

    DateTime.commercial(date.year,date.month,date.day,date.hour-x,date.minute,date.second)
    

    might work, but is ugly. The doc says DateTime is immutable, so I'm not even sure about - and <<

    0 讨论(0)
提交回复
热议问题