Re: Yesterday's date
by hippo (Bishop) on May 28, 2023 at 13:33 UTC
|
#!/usr/bin/env perl
use strict;
use warnings;
use Time::Piece;
my $t = Time::Piece->strptime ($ARGV[0], '%d/%m/%Y');
printf "Date as supplied: %s\n", $t->dmy ('/');
$t = $t - 86400;
printf "Date minus one day: %s\n", $t->dmy ('/');
$ ./yesterday.pl 01/12/2022
Date as supplied: 01/12/2022
Date minus one day: 30/11/2022
$
| [reply] [d/l] [select] |
|
Note that this approach will have a problem for those days with less than 24 hours (like when switching between normal and daylight savings time.
I prefer the approach to iteratively subtract 22 hours until the (stringified) date changes:
...
my $res = $t - 22*60*60;
while( $res->ymd('-') eq $t->ymd('-') ) {
$res -= 22*60*60;
}
return $res
| [reply] [d/l] |
|
Note that this approach will have a problem for those days with less than 24 hours
I would be interested to see a test case showing that, if you could provide one. The tests I tried all worked fine, even on 23-hour days. That's why I posted it as-is rather than trying to work around a problem which didn't appear to be there.
Here's my trivial test script for comparison:
use strict;
use warnings;
use Time::Piece;
use Test::More tests => 366 * 2 + 1;
my $dstr = '01/01/2023';
for (1 .. 366) {
my $t = Time::Piece->strptime ($dstr, '%d/%m/%Y');
my $nt = $t - 86400;
isnt $dstr, $nt->dmy ('/');
my $ddiff = $t->mday - $nt->mday;
ok ($ddiff < 0 || $ddiff == 1), '1 day different or month wrap';
$dstr = $nt->dmy ('/');
}
is $dstr, '31/12/2021';
| [reply] [d/l] |
|
|
|
|
$ TZ=Europe/London perl -MTime::Piece -wE '
for my $source ("Time::Piece", scalar localtime()) {
my $t = $source->strptime("2023/03/27", "%Y/%m/%d");
say $t - 86400;
}'
Sun Mar 26 00:00:00 2023
Sat Mar 25 23:00:00 2023
map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
| [reply] [d/l] [select] |
|
| [reply] |
|
G'day hippo,
++ I agree with your approach; particularly in light of the OP's
"I am not concerned about daylight savings time, time zone nor do I need HMS.".
Having said that, I believe use of the ONE_DAY constant from
Time::Seconds (also a core module)
would add clarity.
It's the same value:
$ perl -E 'use Time::Seconds; say ONE_DAY'
86400
It works as a direct replacement in your code:
$ perl -e '
use strict;
use warnings;
use Time::Piece;
use Time::Seconds;
my $t = Time::Piece->strptime($ARGV[0], "%d/%m/%Y");
printf "Date as supplied: %s\n", $t->dmy("/");
$t = $t - ONE_DAY;
printf "Date minus one day: %s\n", $t->dmy("/");
' 01/12/2022
Date as supplied: 01/12/2022
Date minus one day: 30/11/2022
| [reply] [d/l] [select] |
|
If $Time::Seconds::ONE_DAY remains constant regardless of current time, then do not see how that would add "clarity" or see its purpose. If 24 *60 *60 conjures up magic number, then just assign that to a local variable.
| [reply] [d/l] |
|
Re: Yesterday's date
by 1nickt (Canon) on May 28, 2023 at 14:06 UTC
|
use strict;
use warnings;
use DateTime::Format::Strptime;
my $parser = DateTime::Format::Strptime->new(pattern => '%d/%m/%Y', on
+_error => 'croak');
my $dt = $parser->parse_datetime('28/05/2023');
print $dt->subtract(days => 1)->strftime('%d/%m/%Y'), "\n";
Hope this helps!
The way forward always starts with a minimal test.
| [reply] [d/l] |
Re: Yesterday's date
by tybalt89 (Monsignor) on May 29, 2023 at 05:03 UTC
|
Avoid all those problems with short or long days and daylight savings time switches by using the middle of the day :)
#!/usr/bin/perl
use strict; # https://perlmonks.org/?node_id=11152433
use warnings;
use Time::Piece;
use Time::Seconds;
@ARGV = '28/05/2023';
my $t = -ONE_DAY + Time::Piece->strptime("$ARGV[0] 12", "%d/%m/%Y %H")
+;
print localtime($t) . " should be near middle of the day\n\n";
printf "Date as supplied: %s\nDate minus one day: %s\n", $ARGV[0], $t-
+>dmy("/");
Outputs:
Sat May 27 12:00:00 2023 should be near middle of the day
Date as supplied: 28/05/2023
Date minus one day: 27/05/2023
| [reply] [d/l] [select] |
Re: Yesterday's date
by jpys (Novice) on May 31, 2023 at 06:37 UTC
|
I think I'm getting more than I bargained for. To try to clarify: The script I am working will ONLY be used in the Philippines, laptop knows the date/time of course. There is no DST here. What I need is this: The script will provide the date, from here I need to know what the day before that date was. The initial date will be provided by the script and it WON'T always be today. It could be 04/24/2023 or 05/31/2023 for example. From there I need to know what date yesterday was. Only the date, not HMS no other info. Just the date one day before the date the script provides. Thanks! I appreciate everyone's attention and help. | [reply] |
|
| [reply] |
|
Hello, what I meant was it can be any date that the script will provide - I was just giving examples. The script format will display MMDDYYYY. From there I need to know how to figure out what the day before was. As to my examples the day before would be 04/23/2023 and 05/30/2023 respectively.
| [reply] |
|