Calculate last day of month

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

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. :slight_smile:

Very cool! That worked! Thank you!

-Hunter

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. :slight_smile:

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

 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.

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

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

On 21/09/06, Hunter W. [email protected] 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

On 9/21/06, James M. [email protected] 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

[email protected] 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 :wink:

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

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

robert

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

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

-a

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

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

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

[email protected] wrote:

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

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

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

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/

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

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

class Date
def self.last_day_of_the_month(yyyy, mm)
new(yyyy, mm).next_month - 1
end
end

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::date::Calculations and can just use
‘end_of_month’?

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?

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

Why override Date at all when we’ve got
ActiveSupport::CoreExtensions::date::Calculations and can just use
‘end_of_month’?

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

–Greg

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::date::Calculations and can just use
‘end_of_month’?

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

–Greg

Oops :wink: Should have checked the header. My bad.

Best regards,
Bill