Ruby Date Subtraction (e.g. 90 days Ago)

RubyDate

Ruby Problem Overview


I've been a bit spoiled by the joda-time API of:

DateTime now = new DateTime();
DateTime ninetyDaysAgo = now.minusDays(90);

I'm trying to do a similar thing in Ruby, but I'm

now = Time.now
ninetyDaysAgo = now - (90*24)

However, the math is off here (I'm really working with dates at midnight).

Is there friendly API for date subtraction?

Ruby Solutions


Solution 1 - Ruby

require 'date'
now = Date.today
ninety_days_ago = (now - 90)

Running this thru the IRB console I get:

>>require 'date'
now = Date.today
ninety_days_ago = (now - 90)

require 'date'
=> false
now = Date.today
=> #<Date: 2011-03-02 (4911245/2,0,2299161)>
ninety_days_ago = (now - 90)
=> #<Date: 2010-12-02 (4911065/2,0,2299161)>

If you need the time you could just say now = DateTime.now

Solution 2 - Ruby

For those using Rails, check out the following:

DateTime.now - 10.days
=> Sat, 04 May 2013 12:12:07 +0300

20.days.ago - 10.days
=> Sun, 14 Apr 2013 09:12:13 UTC +00:00

Solution 3 - Ruby

If you're using Rails or don't mind including ActiveSupport, you can use the Numeric#days DSL like this:

ruby-1.9.2-p136 :002 > Date.today
 => Wed, 02 Mar 2011 
ruby-1.9.2-p136 :003 > Date.today - 90.days
 => Thu, 02 Dec 2010 

Since you are working with dates instead of times, you should also either start with Date instances, or convert your DateTime intances with #to_date. When adding/subtracting numbers from date instances, the numbers are implicitly days.

ruby-1.9.2-p136 :016 > DateTime.now.to_date
 => #<Date: 2011-03-02 (4911245/2,0,2299161)> 
ruby-1.9.2-p136 :017 > DateTime.now.to_date - 90
 => #<Date: 2010-12-02 (4911065/2,0,2299161)> 

Solution 4 - Ruby

Ruby supports date arithmetic in the Date and DateTime classes, which are part of Ruby's standard library. Both those classes expose #+ and #- methods, which add and subtract days from a date or a time.

$ irb
 > require 'date'
 => true 
 > (DateTime.new(2015,4,1) - 90).to_s  # Apr 1, 2015 - 90 days
 => "2015-01-01T00:00:00+00:00"
 > (DateTime.new(2015,4,1) - 1).to_s   # Apr 1, 2015 - 1 day
 => "2015-03-31T00:00:00+00:00" 

Use the #<< and #>> methods to operate on months instead of days. Arithmetic on months is a little different than arithmetic on days. Using Date instead of DateTime makes the effect more obvious.

 > (Date.new(2015, 5, 31) << 3).to_s  # May 31 - 3 months; 92 days diff
 => "2015-02-28" 

Following your joda-time example, you might write something like this in Ruby.

now =  DateTime.now
ninety_days_ago = now - 90

or maybe just

ninety_days_ago = DateTime.now - 90

Solution 5 - Ruby

use the number of seconds:

Time.now - 90*24*60*60

Solution 6 - Ruby

This is a super old post, but if you wanted to keep with a Time object, like was originally asked, rather than switching to a Date object you might want to consider using Ruby Facets.

Ruby Facets is a standardized library of extensions for core Ruby classes.

http://rubyworks.github.io/facets/

By requiring Facets you can then do the following with Time objects.

Time.now.less(90, :days)

Solution 7 - Ruby

Simple solution using Rails Active Support:

days90_ago = 90.days.ago.to_date.to_s

OUTPUT:
puts 90_days_ago
=> "2019-10-09" # considering cur_date: 2020-01-07

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondarthtrevinoView Question on Stackoverflow
Solution 1 - RubyMattView Answer on Stackoverflow
Solution 2 - RubyAbdoView Answer on Stackoverflow
Solution 3 - RubyGabe Martin-DempesyView Answer on Stackoverflow
Solution 4 - RubyMike Sherrill 'Cat Recall'View Answer on Stackoverflow
Solution 5 - RubyRubyView Answer on Stackoverflow
Solution 6 - RubybigtunacanView Answer on Stackoverflow
Solution 7 - RubyRavistmView Answer on Stackoverflow