in reply to Re^3: Finding End of Month's date
in thread Finding End of Month's date

I want to see you get the lookup right for all edge cases.

Date::Manip is a fine choice if, as the author himself says, you want to allow users to specify dates in fairly freeform, descriptive fashion.

But other than that, I'd avoid it. It doesn't even make for particularly readable code. The only thing that's intuitive about your snippet is DateCalc()'s offset format. The output format string isn't self-documenting and the implicit truncation is not obvious. I had to read your explanation to know what it does.

Try this on for size:

use DateTime; my $date = DateTime ->now ->truncate( to => 'month' ) ->add( months => 1, days => -1 ); print $date->day;

DateTime rocks.

Makeshifts last the longest.

Replies are listed 'Best First'.
Re^5: Finding End of Month's date
by Anonymous Monk on Jan 03, 2005 at 17:09 UTC
    Trying it for size? Your fragment, without the use statement, uses 87 non-whitespace characters characters. Mine can be reduced to:
    print UnixDate DateCalc("@ARGV", "+1m -1d"), "%e";
    for 46 non-whitespace characters, while it even takes an argument (yours only does the current month). So. size-wise, you lose (unless you want to the longest solution....).

    Whether something is intuitive or not is a subjective thing. The output format may not be very intuitive, it's far more flexible (it could easily be changed to, say "The answer to the question is %e". The "%e" directive of UnixDate is exactly the same as the one of strftime.

    As for the implicite truncation not being obvious, I fully agree with that as well. It isn't obvious to me either. In fact, I've no idea what truncation you are referring to.

    BTW, I'm pretty convinced I'd get all the edge cases correctly when doing a look-up table. How the lookup-table would look like strongly depends on the edges. (Which years, which calendar, which country, etc). Or did you think the well known formula that checks the remainers of division of the year by 4, 100 and 400 got the edge cases right? ;-)

      Trying on for size is a figure or speech for “now see how that looks”. I never golf.

      Also, please look at a module before decrying it for inflexibility.

      print $date->strftime( '%e' ); # it's there if you think you need it

      By truncation I was referring the fact that the calculation starts at the beginning of the month rather than from “now”. Without your explanation, I'd've expected your snippet to produce June 15 when given May 16 as a start date. It's not obvious why it produces May 31 instead.

      Or did you think the well known formula that checks the remainers of division of the year by 4, 100 and 400 got the edge cases right? ;-)

      I know it doesn't, no need for the smiley. That's why I asked the question in the first place. I'd never attempt to do any date math on my own unless I'm setting out to write a date math library. Otherwise, there's just way too many gotchas to hang yourself with in that area. And when I pick a date math library, I usually stick to DateTime because I know there was (and is) a large and painstaking effort to get every last possible edge case right, and because the API is terrifically slick.

      Makeshifts last the longest.

        I'd've expected your snippet to produce June 15 when given May 16 as a start date. It's not obvious why it produces May 31 instead.

        Actually, if you give it "May 16" as arguments, it will produce 31 as the answer. Why? Because the original question stated the problem as given a month and a year. So, my snippet takes a month and a year, and hence "May 16" will be the month of May in the year 16.

        And if you give ParseDate incomplete dates, it assumes defaults. Like oh, the first second (00), the first minute (00), the first hour (00) and the first day (1). Exactly what I expect. BTW, Date::Time uses the same defaults.

        and because the API is terrifically slick

        Oh, the irony. The irony. The API specially allows chaining mutators - and your example makes use of them.