Как получить вчерашнюю дату по местному времени? - PullRequest
13 голосов
/ 18 августа 2010

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

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 ]

22 голосов
/ 18 августа 2010
use DateTime qw();
DateTime->now->subtract(days => 1); 

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

18 голосов
/ 18 августа 2010

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

#!/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";
12 голосов
/ 18 августа 2010

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

#!/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, этот подход может быть лучше, если вы не можете проверить ожидаемые, но не гарантированные результаты на нескольких платформах.

6 голосов
/ 18 августа 2010

use Time :: Piece .

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, как описано в другом ответе.Это не основной модуль.

4 голосов
/ 18 декабря 2013

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

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

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

Пример: часовой пояс - Америка / Нью-Йорк, дата - понедельник, 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, Class::Date, etc) делают то же самое.

Вот и все.

1 голос
/ 18 августа 2010
localtime(time() - 24*60*60)
0 голосов
/ 02 июля 2014
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";
...