Thursday, August 01, 2013

Perl - How to get yesterday's date

The quick but dirty way to get yesterday's time is:

my ($psec, $pmin, $phour, $pmday, $pmon, $pyear, $pwday, $pyday, $pisdst) = localtime(time() - 24*60*60);
$pyear += 1900;
$pmon  += 1;
$pmon = '0' . $pmon if $pmon < 10;
my $pdate = $pyear . '-' . $pmon . '-' . $pmday;
print $pdate;


But sometimes this might yield the wrong answer (leap seconds, DST, and possibly others), see the following example:
#!/usr/bin/perl

use strict;
use warnings;
use Time::Local;
use POSIX qw/strftime/;

#2010-03-15 02:00:00
my ($s, $min, $h, $d, $m, $y) = (0, 0, 0, 15, 2, 110);
my $time      = timelocal $s, $min, $h, $d, $m, $y;   
my $today     = strftime "%Y-%m-%d %T", localtime $time;
my $yesterday = strftime "%Y-%m-%d %T", $s, $min, $h, $d - 1, $m, $y;
my $oops      = strftime "%Y-%m-%d %T", localtime $time - 24*60*60;
print "$today -> $yesterday -> $oops\n";

The above code will print out, the "-24*60*60" doesn't work in the above example:
2010-03-15 00:00:00 -> 2010-03-14 00:00:00 -> 2010-03-13 23:00:00

You can use strftime (available in the Perl 5 core module POSIX) which does a pretty good job.

#!/usr/bin/perl
use strict;
use warnings;
use Time::Local;
use POSIX qw/strftime/;

# Today's date
my ($s, $min, $h, $d, $m, $y) = localtime();

my $time      = timelocal $s, $min, $h, $d, $m, $y;
my $today     = strftime "%Y-%m-%d %T", localtime;
my $yesterday = strftime "%Y-%m-%d %T", $s, $min, $h, $d - 1, $m, $y;
my $oops      = strftime "%Y-%m-%d %T", localtime $time - 24*60*60;
print "$today -> $yesterday -> $oops\n";




No comments: