目前我使用以下代码获取今天的日期。现在我需要获取昨天的日期,应该如何实现?
my $today = `date "+%Y-%m-%d"`;
如果您想获取昨天的日期:
use DateTime qw( );
my $yday_date =
DateTime
->now( time_zone => 'local' )
->set_time_zone('floating')
->truncate( to => 'day' )
->subtract( days => 1 )
->strftime('%Y-%m-%d');
->now( time_zone => 'local' )->set_time_zone('floating')->truncate( to => 'day' )
而不是->today( time_zone => 'local' )
来避免这个问题。
如果您想提前一天获得时间:
use DateTime qw( );
my $yday_datetime =
DateTime
->now( time_zone => 'local' )
->subtract( days => 1 )
->strftime('%Y-%m-%d %H:%M:%S');
如果你想把时间提前24小时:
use DateTime qw( );
my $yday_datetime =
DateTime
->now( time_zone => 'local' )
->subtract( hours => 24 )
->strftime('%Y-%m-%d %H:%M:%S');
day
而不是days
来截断,以防止以下异常:Validation failed for type named TruncationLevel declared in package DateTime::Types (C:/Strawberry/perl/vendor/lib/DateTime/Types.pm) at line 135 in sub named (eval) with value "days"
。 - nckuse strict;
use warnings;
use feature 'say';
use DateTime;
my $today = DateTime->today(time_zone => 'local');
my $yesterday = $today->clone->add(days => -1);
say $yesterday->ymd; #--> 2019-05-13
my $yesterday = DateTime->today(time_zone => 'local')->add(days => -1);
$yesterday->ymd
,因为ymd的默认格式是%Y-%m-%d
。可以使用strftime方法获得几乎任意格式。
date
甚至不是一种选择,因为您只会得到一个字符串,您必须手动解析以进行进一步使用。
my $today = DateTime->now(time_zone => 'local');
say $today->strftime("%Y%m%d_%H.%M.%S"); #--> 20190522_22.44.23
my $yesterday = $today->clone->add(days => -1);
say $yesterday->strftime("%Y%m%d_%H.%M.%S"); #--> 20190521_22.44.23
where方法now“保留”(本地)时间和日期,其中today
是对now
进行truncate
操作的结果。
->set_time_zone('floating')
来避免出错。 - ikegamimy $d_N_back = DateTime->today(time_zone=>"local")->add(days=>-$N);
(其中 $N
是数字)。现在这是一个可以使用的对象。如果您更喜欢获得一个准备好的字符串,请继续该链:my $str = DateTime->[as above]->ymd;
。或者,对于更具体的格式,使用 ->strftime(...)
。这是你的意思吗? - zdim$N_back = $today->clone->add(days=>-$N);
这样。这里的 clone
从 $today
制作另一个对象,因此您保留了 $today
并获得了一个新对象,即今天之前 $N
天。或者,要获取字符串,$N_back_str = $today->clone->add(days=>-$N)->ymd;
- zdim我建议使用DateTime(如ikegami的答案所述)。但是如果您不想安装CPAN模块,则此方法仅使用标准Perl安装中提供的功能。
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
use Time::Local;
use POSIX 'strftime';
# Get the current date/time
my ($sec, $min, $hr, $day, $mon, $yr) = localtime;
# Get the epoch seconds for midday today
# (we use midday to eliminate potential problems
# when entering or leaving daylight savings time)
my $midday = timelocal(0, 0, 12, $day, $mon, $yr);
# Subtract a day's worth of seconds from the epoch
my $midday_yesterday = $midday - (24 * 60 * 60);
# Convert that epoch value to a string date using
# localtime() and POSIX::strftime().
my $yesterday = strftime('%Y%m%d', localtime($midday_yesterday));
say $yesterday;
使用Time::Moment,只需获取昨天的日期:
use strict;
use warnings;
use Time::Moment;
my $yesterday = Time::Moment->now->minus_days(1)->strftime('%Y-%m-%d');
Time::Moment在瞬间和偏移量上工作,而不是时区,所以如果您想要与DateTime示例中的本地时间相同的“一天前”的确切日期和时间,您可以使用Time::Moment::Role::TimeZone。
最初的回答使用了DateTime,但是Time::Moment::Role::TimeZone可以更好地处理时区问题。
use strict;
use warnings;
use Time::Moment;
use Role::Tiny ();
my $class = Role::Tiny->create_class_with_roles('Time::Moment', 'Time::Moment::Role::TimeZone');
my $yesterday = $class->now->minus_days(1)->with_system_offset_same_local; # 1 day ago
my $yesterday = $class->now->minus_days(1)->with_system_offset_same_instant; # 24 hours ago
如果当前时间在本地时区的前一天不存在,则相同的警告适用。
最初的回答:
如果当前时间在先前一天的本地时区中不存在,那么同样的注意事项也适用。
use Time::Piece;
my ($t, $today, $yesterday);
$t = localtime();
$today = sprintf('%04d/%02d/%02d', $t->year, $t->mon, $t->mday);
$t = localtime(time() - 86400);
$yesterday = sprintf('%04d/%02d/%02d', $t->year, $t->mon, $t->mday);
localtime(time()) - 86400
或者只是localtime() - 86400
而不是localtime(time() - 86400)
)但是,这个模块鼓励这种错误的事实是这个模块存在问题的原因。 - ikegamimy $yesterday = `date -d yesterday +%Y%m%d-%H%M%S`;
20190309-110000
。) - ikegami
chomp
。 - zdim