in reply to Re^3: Yesterday's date
in thread Yesterday's date

This is because Time::Piece doesn't care as much about timezones and DST. When using DateTime (because I know it is exact with timezones, bordering on the unusable), in the following program, I can make things skip from 03/27/2023 to 03/25/2023:

use 5.020; use Test2::V0; use DateTime; use DateTime::Format::Strptime; my $dstr = '2023-03-27 00:30'; my $strp = DateTime::Format::Strptime->new( pattern => '%Y-%m-%d %H:%M', locale => 'de_DE', time_zone => 'Europe/Paris', ); my $t = $strp->parse_datetime($dstr); diag $t->strftime('%Y-%m-%d %H:%M %z'); my $nt = $t->clone->subtract( seconds => 24*60*60 ); isnt $t->ymd('-'), $nt->ymd('-'); diag $nt->strftime('%Y-%m-%d %H:%M %z'); my $ddiff = $t->mday - $nt->mday; ok( ($ddiff < 0 || $ddiff == 1), '1 day different or month wrap'); $dstr = $nt->ymd ('-'); is $dstr, '2023-03-26';

Update: I just realized that your code doesn't care about the time, and it (implicitly) always is at 00:00. Adjusting my example from 00:30 to 00:00 shows the problem there:

use 5.020; use Test2::V0; use DateTime; use DateTime::Format::Strptime; my $dstr = '2023-03-27'; my $strp = DateTime::Format::Strptime->new( pattern => '%Y-%m-%d', locale => 'de_DE', time_zone => 'Europe/Paris', ); my $t = $strp->parse_datetime($dstr); diag $t->strftime('%Y-%m-%d %H:%M %z'); my $nt = $t->clone->subtract( seconds => 24*60*60 ); isnt $t->ymd('-'), $nt->ymd('-'); diag $nt->strftime('%Y-%m-%d %H:%M %z'); my $ddiff = $t->mday - $nt->mday; ok( ($ddiff < 0 || $ddiff == 1), '1 day different or month wrap'); $dstr = $nt->ymd ('-'); is $dstr, '2023-03-26';

Replies are listed 'Best First'.
Re^5: Yesterday's date
by hippo (Archbishop) on May 28, 2023 at 15:02 UTC
    This is because Time::Piece doesn't care as much about timezones and DST.

    Precisely so. That's another good reason to use it in this sort of scenario where DST is a hindrance at best. I don't see why, given a problem where DST and timezones would only complicate things, the user would choose a non-core module where these are important over a core module which for the most part ignores them.

    For the general audience reading this, if you are used to DateTime or Date::Calc or any of the myriad other modules, I do recommend that you become at least passingly familiar with Time::Piece. It is pretty simple, fairly lightweight and core. It won't solve all problems but it handles a good subset of them, including the one in this thread, very well indeed.


    🦛

      Hold on now. It's just as easy to use UTC with non-core modules as it is with Time::Piece. It's the default time zone for the DateTime module too, for example.

      While it is lightweight, it's not any better at handling dates. (And one could say it's worse, because of the piss-poor interface.)