如何使用localtime获取昨天的日期?

jda*_*mae 13 perl 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;
}
Run Code Online (Sandbox Code Playgroud)

dax*_*xim 22

use DateTime qw();
DateTime->now->subtract(days => 1); 
Run Code Online (Sandbox Code Playgroud)

第二行上的表达式返回一个DateTime对象.


Cha*_*ens 18

由于它只是从当前时间减去一天的秒数而很诱人,有时会产生错误的答案(闰秒,DST,以及可能的其他).我发现更容易让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";
Run Code Online (Sandbox Code Playgroud)


big*_*ain 12

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;
}
Run Code Online (Sandbox Code Playgroud)

根据Chas建议的strftime解决方案的"未指定"记录行为,如果您无法跨多个平台测试预期但不保证的结果,则此方法可能会更好.


msc*_*cha 6

使用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');
Run Code Online (Sandbox Code Playgroud)

请注意,在某些临界情况下,例如夏令时的开始,这可能会出错.在这种情况下,以下版本的行为正确:

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');
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用DateTime模块,如另一个答案中所述.不过,这不是核心模块.

  • 在Timel 5.10(5.9.5,但是谁使用dev版本?)之前,`Time :: Piece`和`Time :: Seconds`没有被添加到核心. (2认同)

小智 5

大多数用户建议的解决方案是错误的!

localtime(time() - 24*60*60)
Run Code Online (Sandbox Code Playgroud)

您能做的最坏的事情是假设1天= 86400秒。

例如:时区是America / New_York,日期是Mon Apr 3 00:30:00 2006

timelocal给我们1144038600

当地时间(1144038600-86400)= 2006年4月1日星期六23:30:00

哎呀!

正确且唯一的解决方案是让系统功能标准化值

$prev_day = timelocal(0, 0, 0, $mday-1, $mon, $year);
Run Code Online (Sandbox Code Playgroud)

或者让datetime框架(DateTime, Class::Date, etc)做同样的事情。

而已。