Kunal Vashist
Kunal Vashist

Reputation: 2471

Subtracting month from date is not giving correct value in ruby?

i am trying to subtract the month from Date its not giving accurate result

end_date = Date.parse("30-09-2019")
end_date - 1.months

returns 30 - aug - 2019

example 30-09-2019 - 1.month to give 31 - 08 - 2019
example 15-09-2019 - 1.month to give 14 - 08 - 2019

Upvotes: 0

Views: 505

Answers (3)

max
max

Reputation: 102443

You can use DateTime#advance from ActiveSupport.

Uses Date to provide precise Time calculations for years, months, and days. The options parameter takes a hash with any of these keys: :years, :months, :weeks, :days, :hours, :minutes, :seconds.

irb(main):001:0> end_date = Date.parse("30-09-2019")
=> Mon, 30 Sep 2019
irb(main):002:0> end_date.advance(months: 1)
=> Wed, 30 Oct 2019
irb(main):003:0> end_date.advance(months: -1)
=> Fri, 30 Aug 2019
irb(main):004:0> end_date.advance(months: -1, days: 2)
=> Sun, 01 Sep 2019

And yeah using .advance to go backwards is semantically strange but it works fine with negative values. Unfortunately there is no inverse method.

Upvotes: 0

3limin4t0r
3limin4t0r

Reputation: 21160

The reason Date.new(2019, 9, 30) - 1.month results in Fri, 30 Aug 2019 is simply because 1.month isn't 30 days, but a static value of 2629746 seconds (30.436875 days).

date = Date.new(2019, 9, 30)

1.month == 30.436875.days #=> true

date - 30.days        #=> Sat, 31 Aug 2019
date - 30.436875.days #=> Fri, 30 Aug 2019

You can find these static values documented here.

Upvotes: 2

dswdsyd
dswdsyd

Reputation: 616

There are a few approaches you can use to subtract months from a date in Ruby, the following guide is pretty comprehensive on all the date manipulation methods you can perform in Ruby:

Ruby Cookbook, 2nd Edition by Leonard Richardson, Lucas Carlson

1. Using << (method)

require 'date'

end_date = Date.parse("30-09-2019")
end_date = end_date << 1
print(end_date.strftime("%d-%m-%Y"))

2. Using prev_month()

require 'date'

end_date = Date.parse("30-09-2019")
end_date = end_date.prev_month //this would give the desired result
print(end_date.strftime("%d-%m-%Y"))

Upvotes: 0

Related Questions