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';
|