in reply to How to get last month date using Date::Calc

Hi, date math is tricky, not so much because there are no tools, but because one must be very precise in thinking about the calculation actually needed.

If you are asking on, say, March 30, what month is a month ago?

Perl tools differ in their answer:

$ perl -MDate::Calc=Add_Delta_YM -E 'say "$_ : " . join "-", Add_Delta +_YM( split("-", $_), 0,-1) for qw/2018-03-28 2018-03-29 2018-03-30 20 +18-03-31/' 2018-03-28 : 2018-2-28 2018-03-29 : 2018-2-28 2018-03-30 : 2018-2-28 2018-03-31 : 2018-2-28 $ perl -MTime::Piece -E 'do { $t = Time::Piece->strptime($_, "%Y-%m-%d +"); say "$_ : " . $t->add_months(-1)->strftime("%Y-%m-%d") } for qw/2 +018-03-28 2018-03-29 2018-03-30 2018-03-31/' 2018-03-28 : 2018-02-28 2018-03-29 : 2018-03-01 2018-03-30 : 2018-03-02 2018-03-31 : 2018-03-03
... and that's not even taking into account Daylight Savings Time and other things. So be careful!

(For those wondering, DateTime returns the same as Date::Calc.)

Hope this helps!


The way forward always starts with a minimal test.

Replies are listed 'Best First'.
Re^2: How to get last month date using Date::Calc (caution advised)
by hippo (Archbishop) on Oct 12, 2018 at 12:39 UTC

    The docs for Time::Piece explain it thus (emphasis mine):

    The months and years can be negative for subtractions. Note that there is some "strange" behaviour when adding and subtracting months at the ends of months. Generally when the resulting month is shorter than the starting month then the number of overlap days is added. For example subtracting a month from 2008-03-31 will not result in 2008-02-31 as this is an impossible date. Instead you will get 2008-03-02. This appears to be consistent with other date manipulation tools.
      An odd thing to say, since it isn't consistent with DateTime, Time::Moment, or (apparently) Date::Calc.