Calculate last day of month

H

Hunter Walker

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
 
A

ara.t.howard

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

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
 
J

James Moore

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 Moore
 
P

Patrick Hurley

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 Moore

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
 
H

Hoppy

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.
:)
 
A

ara.t.howard

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
 
A

ara.t.howard

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
 
R

Robert Klemme

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
 
P

Platoon Tb

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

Gregory Seidman

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
 
L

Lloyd Linklater

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?
 
B

Bill Walton

Gregory said:
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'?
 
G

Gregory Seidman

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,132
Latest member
TeresaWcq1
Top