First of all, note that by writing $delta->{'months'} you are reaching into the internals of the object, which bypasses any accessors and may break if the field names happen to change. So don't do that and use only the accessors instead. Second, note the section "Math Methods" in DateTime and the documentation of DateTime::Duration: Because the number of days per month is not fixed, IMHO it's better to tell the modules exactly what kind of math you want to do. For instance, in your case, you might want the ->delta_md method. Note that it returns an absolute difference, which is why an additional check of $date>$now is necessary, but personally I don't mind being explicit.

use warnings; use strict; use DateTime; use DateTime::Format::Human::Duration; my $now = DateTime->new( time_zone => "UTC", year => 2019, month => 6, day => 10 ); my $fmt = DateTime::Format::Human::Duration->new(); for my $mon ( 4, 6, 8 ) { for my $day ( 1, 9 , 10, 11, 19 ) { my $date = DateTime->new( time_zone => "UTC", year => 2019, month => $mon, day => $day ); my $delta = $now->delta_md($date); my ($months,$days) = $delta->in_units(qw/ months days /); print $now->ymd, " to ", $date->ymd, " is ", $fmt->format_duration($delta, units=>[qw/months days/]); if ( $date>$now && ( $months>2 || $months==2 && $days>0 ) ) { print " *** Alert ***"; } print "\n"; } } __END__ 2019-06-10 to 2019-04-01 is 2 months and 9 days 2019-06-10 to 2019-04-09 is 2 months and 1 day 2019-06-10 to 2019-04-10 is 2 months 2019-06-10 to 2019-04-11 is 1 month and 29 days 2019-06-10 to 2019-04-19 is 1 month and 21 days 2019-06-10 to 2019-06-01 is 9 days 2019-06-10 to 2019-06-09 is 1 day 2019-06-10 to 2019-06-10 is no time 2019-06-10 to 2019-06-11 is 1 day 2019-06-10 to 2019-06-19 is 9 days 2019-06-10 to 2019-08-01 is 1 month and 21 days 2019-06-10 to 2019-08-09 is 1 month and 29 days 2019-06-10 to 2019-08-10 is 2 months 2019-06-10 to 2019-08-11 is 2 months and 1 day *** Alert *** 2019-06-10 to 2019-08-19 is 2 months and 9 days *** Alert ***

(Of course it's also possible to do this in SQL.)


In reply to Re: Months between dates ? by haukex
in thread Months between dates ? by bgroper

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.