htmanning has asked for the wisdom of the Perl Monks concerning the following question:

Monks, I'm doing a simple reservation system and using DateTime I can make sure the reservation is not before today.
use DateTime; my $now = DateTime->now( time_zone => 'Pacific/Honolulu' ); my $reservation_date = DateTime->new( year => $CONFIG{'date_year'}, month => $CONFIG{'date_month'}, day => $CONFIG{'date_day'}, hour => $myhour, minute => $mymin, time_zone => 'Pacific/Honolulu', ); if ($reservation_date < $now) { print "error"; }
But what I need now is to restrict future reservations to no more than 1 week ahead of time, but something like this doesn't work:
} elsif ($reservation_date - $now > 7) { do something. }
It seems I have to use the duration compare class, but I'm not sure how to do it when I'm only comparing the reservation date to now, and the base time to compare to is now.

Replies are listed 'Best First'.
Re: Counting days with DateTime (updated x2)
by haukex (Archbishop) on Apr 01, 2020 at 19:06 UTC

    Personally I try to avoid the overloaded DateTime math operators, and only use the comparisons. I'd suggest something like:

    my $now = DateTime->now( time_zone => 'Pacific/Honolulu' ); my $one_week_from_now = $now->clone->add( weeks=>1 ); if ( $reservation_date > $one_week_from_now ) ...

    Update: Corrected ->add( week=>1 ) to ->add( weeks=>1 )!

    Update 2: Added ->clone, as suggested by tobyink below. That's what I get for running a different test case (DateTime->now->add(weeks=>1)) than what I posted here :-/

      Consider using:

      my $one_week_from_now = $now->clone->add( weeks=>1 );

      This is because most of the DateTime add/subtract methods mutate the object the operated on, and you probably don't want $now to be a date in the future!

      Thanks so much! This worked after I changed "week" to "weeks."
      A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Counting days with DateTime
by Corion (Patriarch) on Apr 01, 2020 at 18:54 UTC

    DateTime is very finnicky with differences and timezones, but as you're using the same timezone in both elements, maybe you just need the ->delta_days method?

Re: Counting days with DateTime
by soonix (Chancellor) on Apr 02, 2020 at 08:36 UTC
    The duration class is DateTime's way to specify whether your '7' stands for '7 seconds' (as it would be in unix time stamps), or '7 days', '7 years', or other units in between. You'd have to write
    DateTime::Duration->new( days => 7 )
    or, since in the text you you wrote "1 week", not "7 days":
    DateTime::Duration->new( weeks => 1 )
    instead of that simple 7.