Как получить вчерашнюю дату с помощью localtime?

Как настроить это, чтобы получить вчерашнюю дату с помощью localtime?

use strict;

sub spGetCurrentDateTime;
print spGetCurrentDateTime;

sub spGetCurrentDateTime {
my ($sec, $min, $hour, $mday, $mon, $year) = localtime();
my @abbr = qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec );
my $currentDateTime = sprintf "%s %02d %4d", $abbr[$mon], $mday, $year+1900; #Returns => 'Aug 17 2010' 
return $currentDateTime;
}

~

7 ответов


проблему DST можно обойти, взяв 3600s с полудня сегодня вместо текущего времени:

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

sub spGetYesterdaysDate;
print spGetYesterdaysDate;

sub spGetYesterdaysDate {
my ($sec, $min, $hour, $mday, $mon, $year) = localtime();
my $yesterday_midday=timelocal(0,0,12,$mday,$mon,$year) - 24*60*60;
($sec, $min, $hour, $mday, $mon, $year) = localtime($yesterday_midday);
my @abbr = qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec );
my $YesterdaysDate = sprintf "%s %02d %4d", $abbr[$mon], $mday, $year+1900;
return $YesterdaysDate;
}

в свете" неопределенного " документированного поведения решения strftime, предложенного Chas, этот подход может быть лучше, если вы не можете проверить ожидаемые, но не гарантированные результаты на нескольких платформах.


use DateTime qw();
DateTime->now->subtract(days => 1); 

выражение во второй строке возвращает DateTime


как заманчиво, как это просто вычесть стоимость дня секунд от текущего времени, есть моменты, когда это даст неправильный ответ (високосные секунды, DST и, возможно, другие). Мне легче просто позволить strftime (доступно в модуле Perl 5 corePOSIX) позаботьтесь обо всем этом для меня.

#!/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";

использовать Время::Кусок.

use strict;
use warnings;
use 5.010;

# These are core modules in Perl 5.10 and newer
use Time::Piece;
use Time::Seconds;

my $yesterday = localtime() - ONE_DAY;
say $yesterday->strftime('%b %d %Y');

обратите внимание, что это может пойти не так, в некоторых пограничных случаях, таких как начало перехода на летнее время. Следующая версия ведет себя правильно в таких случаях:

use strict;
use warnings;
use 5.010;

# These are core modules in Perl 5.10 and newer
use Time::Piece;
use Time::Seconds;

my $now = localtime();
my $yesterday = $now - ONE_HOUR*($now->hour + 12);
say $yesterday->strftime('%b %d %Y');

кроме того, вы можете использовать модуль DateTime, как описано в другом ответе. Однако это не основной модуль.


решение, предложенное большинством пользователей, неверно!

localtime(time() - 24*60*60)

на хуже что вы можете сделать, это предположить, что 1 день = 86400 секунд.

пример: часовой пояс-Америка / New_York, дата-Пн АПР 3 00: 30: 00 2006

timelocal дает 1144038600

местное время (1144038600 - 86400) = СБ 1 апреля 23:30:00 EST 2006

упс!

право и единственное решение - позволить системной функции нормализовать значения

$prev_day = timelocal(0, 0, 0, $mday-1, $mon, $year);

или пусть datetime Framework (DateTime, Class::Date, etc) сделать то же самое.

вот именно.


localtime(time() - 24*60*60)

This is how I do it.

#!/usr/bin/perl

use POSIX qw(strftime);

$epoc = time();
$epoc = $epoc - 24 * 60 * 60;

$datestring = strftime "%F", localtime($epoc);

print "Yesterday's date is $datestring \n";