# Calculate last day of month

**URL:** <https://www.ruby-forum.com/t/calculate-last-day-of-month/69561>\
**Category:** Ruby\
**Created:** [September 21, 2006, 9:00pm UTC](https://www.ruby-forum.com/t/calculate-last-day-of-month/69561 "2006-09-21T21:00:04Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![siguva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c5a1d2/32.png) [@siguva](https://www.ruby-forum.com/u/siguva)\
**Post date:** [September 21, 2006, 9:00pm UTC](https://www.ruby-forum.com/t/calculate-last-day-of-month/69561/1 "2006-09-21T21:00:04Z")

</div>

This is probably an easy one for somebody, but I couldn’t figure it out  
using the Date class in the documentation.

require ‘date’

d = Date.new(2006, 9,16)

How do I return the date for the last day of this month (September in  
this example)?

Thank you for your help!

-Hunter

---

<div class="post-metadata">

**Author:** ![siguva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c5a1d2/32.png) [@siguva](https://www.ruby-forum.com/u/siguva)\
**Post date:** [September 21, 2006, 9:11pm UTC](https://www.ruby-forum.com/t/calculate-last-day-of-month/69561/2 "2006-09-21T21:11:11Z")

</div>

Hunter W. wrote:

> This is probably an easy one for somebody, but I couldn’t figure it out  
> using the Date class in the documentation.
> 
> How do I return the date for the last day of this month (September in  
> this example)?

Easy: Construct a date for the first day of the following month, then  
subtract one day and read the resulting components.

Hard: construct a date for the first day of the target month, then add  
days  
unitil the month number changes. Then go back one.

I think I know which option you’ll choose. 🙂

---

<div class="post-metadata">

**Author:** ![siguva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c5a1d2/32.png) [@siguva](https://www.ruby-forum.com/u/siguva)\
**Post date:** [September 21, 2006, 9:49pm UTC](https://www.ruby-forum.com/t/calculate-last-day-of-month/69561/3 "2006-09-21T21:49:57Z")

</div>

Very cool! That worked! Thank you!

-Hunter

---

<div class="post-metadata">

**Author:** ![siguva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c5a1d2/32.png) [@siguva](https://www.ruby-forum.com/u/siguva)\
**Post date:** [September 21, 2006, 9:37pm UTC](https://www.ruby-forum.com/t/calculate-last-day-of-month/69561/4 "2006-09-21T21:37:13Z")

</div>

On Fri, 22 Sep 2006, Paul L. wrote:

> Hard: construct a date for the first day of the target month, then add days  
> unitil the month number changes. Then go back one.
> 
> I think I know which option you’ll choose. 🙂

except you have to handle december specially - else you’ll end up with  
the  
with the wrong year.

easiest is probably:

harp:~ \> cat a.rb  
require ‘date’

class Date  
def self.last\_day\_of\_the\_month yyyy, mm  
d = new yyyy, mm  
d += 42 # warp into the next month  
new(d.year, d.month) - 1 # back off one day from first of that  
month  
end  
end

puts Date.last\_day\_of\_the\_month(2006, 9)  
puts Date.last\_day\_of\_the\_month(2006, 12)  
puts Date.last\_day\_of\_the\_month(2007, 2)

harp:~ \> ruby a.rb  
2006-09-30  
2006-12-31  
2007-02-28

-a

---

<div class="post-metadata">

**Author:** ![siguva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c5a1d2/32.png) [@siguva](https://www.ruby-forum.com/u/siguva)\
**Post date:** [September 21, 2006, 10:15pm UTC](https://www.ruby-forum.com/t/calculate-last-day-of-month/69561/5 "2006-09-21T22:15:18Z")

</div>

> ```
> d += 42 # warp into the next month
> 
> ```

You need to add a month, not a fixed number of days, since you can’t  
predict  
how many days are in the next month:

irb(main):033:0\> d = Date.new 2006, 1, 31  
=\> #\<Date: 4907533/2,0,2299161\>  
irb(main):034:0\> (d \>\> 1).to\_s  
=\> “2006-02-28”

irb(main):039:0\> d = Date.new 1996, 1, 31  
=\> #\<Date: 4900227/2,0,2299161\>  
irb(main):040:0\> (d \>\> 1).to\_s  
=\> “1996-02-29”

- James M.

---

<div class="post-metadata">

**Author:** ![siguva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c5a1d2/32.png) [@siguva](https://www.ruby-forum.com/u/siguva)\
**Post date:** [September 21, 2006, 10:41pm UTC](https://www.ruby-forum.com/t/calculate-last-day-of-month/69561/6 "2006-09-21T22:41:25Z")

</div>

> How do I return the date for the last day of this month (September in  
> this example)?

Looking for an alternate way: could this be a step in the right  
direction?  
(See [http://chronic.rubyforge.org/](http://chronic.rubyforge.org/))

irb(main):001:0\> require ‘chronic’  
irb(main):011:0\> Chronic.parse(‘last day of this month’)  
=\> nil  
Well… this was close.  
🙂

---

<div class="post-metadata">

**Author:** ![siguva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c5a1d2/32.png) [@siguva](https://www.ruby-forum.com/u/siguva)\
**Post date:** [September 21, 2006, 10:57pm UTC](https://www.ruby-forum.com/t/calculate-last-day-of-month/69561/7 "2006-09-21T22:57:27Z")

</div>

On 21/09/06, Hunter W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> How do I return the date for the last day of this month (September in  
> this example)?

Date.new((Date.today\>\>1).year,(Date.today\>\>1).month,1)-1)

-Thomas

---

<div class="post-metadata">

**Author:** ![siguva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c5a1d2/32.png) [@siguva](https://www.ruby-forum.com/u/siguva)\
**Post date:** [September 21, 2006, 10:21pm UTC](https://www.ruby-forum.com/t/calculate-last-day-of-month/69561/8 "2006-09-21T22:21:20Z")

</div>

On 9/21/06, James M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> irb(main):039:0\> d = Date.new 1996, 1, 31  
> =\> #\<Date: 4900227/2,0,2299161\>  
> irb(main):040:0\> (d \>\> 1).to\_s  
> =\> “1996-02-29”
> 
> - James M.

Yeah that was my first thought too, but notice he is constructing a  
new date at the beginning of the month. I am guessing he picked 42,  
over 32 as it is just much better number.

pth

---

<div class="post-metadata">

**Author:** ![siguva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c5a1d2/32.png) [@siguva](https://www.ruby-forum.com/u/siguva)\
**Post date:** [September 22, 2006, 12:01am UTC](https://www.ruby-forum.com/t/calculate-last-day-of-month/69561/9 "2006-09-22T00:01:34Z")

</div>

removed\_email\_address@domain.invalid wrote:

> On Fri, 22 Sep 2006, Patrick H. wrote:
> 
> > Yeah that was my first thought too, but notice he is constructing a  
> > new date at the beginning of the month. I am guessing he picked 42,  
> > over 32 as it is just much better number.
> 
> exactly 😉
> 
> the point is that it always lands into the next month.

Or the month after that - depending on where you start. 🙂

```
robert
```

---

<div class="post-metadata">

**Author:** ![siguva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c5a1d2/32.png) [@siguva](https://www.ruby-forum.com/u/siguva)\
**Post date:** [September 21, 2006, 11:05pm UTC](https://www.ruby-forum.com/t/calculate-last-day-of-month/69561/10 "2006-09-21T23:05:29Z")

</div>

On Fri, 22 Sep 2006, Patrick H. wrote:

> Yeah that was my first thought too, but notice he is constructing a  
> new date at the beginning of the month. I am guessing he picked 42,  
> over 32 as it is just much better number.

exactly 😉

the point is that it always lands into the next month.

-a

---

<div class="post-metadata">

**Author:** ![siguva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c5a1d2/32.png) [@siguva](https://www.ruby-forum.com/u/siguva)\
**Post date:** [September 22, 2006, 12:11am UTC](https://www.ruby-forum.com/t/calculate-last-day-of-month/69561/11 "2006-09-22T00:11:34Z")

</div>

On Fri, 22 Sep 2006, Robert K. wrote:

> Or the month after that - depending on where you start. 🙂

sure - but it always starts on the first day of the month:

require ‘date’

class Date  
def self.last\_day\_of\_the\_month yyyy, mm  
d = new yyyy, mm # no day means the first  
one  
d += 42 # always the next month  
new(d.year, d.month) - 1  
end  
end

puts Date.last\_day\_of\_the\_month(2006, 9)  
puts Date.last\_day\_of\_the\_month(2006, 12)  
puts Date.last\_day\_of\_the\_month(2007, 2)

cheers.

-a

---

<div class="post-metadata">

**Author:** ![siguva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c5a1d2/32.png) [@siguva](https://www.ruby-forum.com/u/siguva)\
**Post date:** [September 22, 2006, 9:16am UTC](https://www.ruby-forum.com/t/calculate-last-day-of-month/69561/12 "2006-09-22T09:16:35Z")

</div>

removed\_email\_address@domain.invalid wrote:

> > > the point is that it always lands into the next month.
> > 
> > Or the month after that - depending on where you start. 🙂
> 
> sure - but it always starts on the first day of the month:

Yes, of course. I didn’t want to insunuate you code would not do what  
you  
claimed it to do. It was merely a silly remark, probably stirred up by  
this  
strange number that I haven’t seen in a while. I am sorry.

Kind regards

```
robert
```

---

<div class="post-metadata">

**Author:** ![siguva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c5a1d2/32.png) [@siguva](https://www.ruby-forum.com/u/siguva)\
**Post date:** [September 22, 2006, 5:11pm UTC](https://www.ruby-forum.com/t/calculate-last-day-of-month/69561/13 "2006-09-22T17:11:39Z")

</div>

I’ve had this problem often enough to make a gem of my solution:

require ‘expanded\_date’

d = Date.new =\> 2006-09-22  
d.end\_of\_month =\> 2006-09-30  
d.end\_of\_next\_month =\> 2006-10-31

The gems is in production use and will continue to be maintained.

Any feedback would be welcome.

Rdoc: [http://backofficegems.rubyforge.org/expanded\_date/doc/](http://backofficegems.rubyforge.org/expanded_date/doc/)

---

<div class="post-metadata">

**Author:** ![siguva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c5a1d2/32.png) [@siguva](https://www.ruby-forum.com/u/siguva)\
**Post date:** [September 22, 2006, 9:06pm UTC](https://www.ruby-forum.com/t/calculate-last-day-of-month/69561/14 "2006-09-22T21:06:02Z")

</div>

Hunter W. wrote:

> This is probably an easy one for somebody, but I couldn’t figure it out  
> using the Date class in the documentation.
> 
> require ‘date’
> 
> d = Date.new(2006, 9,16)
> 
> How do I return the date for the last day of this month (September in  
> this example)?
> 
> Thank you for your help!
> 
> -Hunter

Date.new(2006, 9,-1)

-1 means count backwards in this context. more info at  
[http://www.ruby-doc.org/core/classes/Date.html#M001193](http://www.ruby-doc.org/core/classes/Date.html#M001193)

---

<div class="post-metadata">

**Author:** ![siguva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c5a1d2/32.png) [@siguva](https://www.ruby-forum.com/u/siguva)\
**Post date:** [July 16, 2008, 2:38pm UTC](https://www.ruby-forum.com/t/calculate-last-day-of-month/69561/15 "2008-07-16T14:38:24Z")

</div>

On Wed, Jul 16, 2008 at 11:41:32AM +0900, Platoon Tb wrote:

> class Date  
> def self.last\_day\_of\_the\_month(yyyy, mm)  
> new(yyyy, mm).next\_month - 1  
> end  
> end

It’s easier than that.

class Date  
def self.last\_day\_of\_the\_month(yyyy, mm)  
new(yyyy, mm, -1)  
end  
end

–Greg

---

<div class="post-metadata">

**Author:** ![siguva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c5a1d2/32.png) [@siguva](https://www.ruby-forum.com/u/siguva)\
**Post date:** [July 16, 2008, 4:45am UTC](https://www.ruby-forum.com/t/calculate-last-day-of-month/69561/16 "2008-07-16T04:45:48Z")

</div>

class Date  
def self.last\_day\_of\_the\_month(yyyy, mm)  
new(yyyy, mm).next\_month - 1  
end  
end

---

<div class="post-metadata">

**Author:** ![siguva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c5a1d2/32.png) [@siguva](https://www.ruby-forum.com/u/siguva)\
**Post date:** [July 16, 2008, 3:50pm UTC](https://www.ruby-forum.com/t/calculate-last-day-of-month/69561/17 "2008-07-16T15:50:04Z")

</div>

Gregory S. wrote:

> It’s easier than that.
> 
> class Date  
> def self.last\_day\_of\_the\_month(yyyy, mm)  
> new(yyyy, mm, -1)  
> end  
> end

Why override Date at all when we’ve got  
ActiveSupport::CoreExtensions:📅:Calculations and can just use  
‘end\_of\_month’?

---

<div class="post-metadata">

**Author:** ![siguva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c5a1d2/32.png) [@siguva](https://www.ruby-forum.com/u/siguva)\
**Post date:** [July 16, 2008, 3:11pm UTC](https://www.ruby-forum.com/t/calculate-last-day-of-month/69561/18 "2008-07-16T15:11:21Z")

</div>

Ok, I know that I am going to be smacked for this, but we DO know how  
many days are in each month. Why not just have one for february with  
considerations for leap year, and lists for those with 30 and 31 days,  
or possibly 30 days and everything else has 31. It is nothing more than  
a lookup.

Is that too easy or too non Ruby-ish?

---

<div class="post-metadata">

**Author:** ![siguva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c5a1d2/32.png) [@siguva](https://www.ruby-forum.com/u/siguva)\
**Post date:** [July 16, 2008, 4:22pm UTC](https://www.ruby-forum.com/t/calculate-last-day-of-month/69561/19 "2008-07-16T16:22:30Z")

</div>

On Wed, Jul 16, 2008 at 10:44:35PM +0900, Bill W. wrote:

> Why override Date at all when we’ve got  
> ActiveSupport::CoreExtensions:📅:Calculations and can just use  
> ‘end\_of\_month’?

Because this is the ruby list, not the rubyonrails list.

–Greg

---

<div class="post-metadata">

**Author:** ![siguva](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c5a1d2/32.png) [@siguva](https://www.ruby-forum.com/u/siguva)\
**Post date:** [July 16, 2008, 7:00pm UTC](https://www.ruby-forum.com/t/calculate-last-day-of-month/69561/20 "2008-07-16T19:00:39Z")

</div>

Gregory S. wrote:

> On Wed, Jul 16, 2008 at 10:44:35PM +0900, Bill W. wrote:
> 
> > Why override Date at all when we’ve got  
> > ActiveSupport::CoreExtensions:📅:Calculations and can just use  
> > ‘end\_of\_month’?
> 
> Because this is the ruby list, not the rubyonrails list.
> 
> –Greg

Oops 😉 Should have checked the header. My bad.

Best regards,  
Bill
