如何使用Perl将localtime转换为YYYY-MM-DD

时间:2018-05-09 19:44:51

标签: perl

我有这个代码,无论当前日期是什么,它都会获得最近的星期五:

for(my $i = 1; $i < 8; $i++) {
     my $t = time() + $i * 24 * 3600;
     next unless (localtime($t))[6] == 5; # friday                                                                                               
     $nextfri = scalar(localtime($t));                                                                                                           
     last;                                                                                                                                        
}

以日期格式返回日期:Fri May 11 13:47:24 2018

但是,II必须将此日期用于SQL查询,因此我必须使用以下格式的日期:YYYY-MM-DD

我尝试过使用Time :: Piece:

 print STDERR "Time::Piece: " . Time::Piece->strptime("$nextfri", '%Y %m %d'), "\n";

但我收到此错误:Error parsing time at /usr/local/lib/perl/5.18.2/Time/Piece.pm line 481, <DATA> line 1.

如何更改日期格式?

2 个答案:

答案 0 :(得分:5)

使用POSIX::strftime将本地时间部分转换为格式化字符串。

use strict;
use warnings;

use POSIX qw{strftime};

my $nextfri;
for (my $i = 1; $i < 8; $i++) {
  my @t = localtime(time() + $i * 24 * 3600);
  next unless $t[6] == 5; # friday
  $nextfri = strftime '%Y %m %d', @t;
  last;
}

但是我建议您使用像DateTime这样的库,因为上面的代码会导致错误的结果,因为它假设每天都有24小时。

use strict;
use warnings;

use DateTime;

my $nextfri = DateTime->now;
do {
  $nextfri->add(days => 1);
} until ($nextfri->day_of_week == 5);

print $nextfri->ymd(' '); # or '-'

答案 1 :(得分:3)

您的代码假设每天都有24小时,这是错误的。修正:

use Time::Local qw( timegm );

# This returns 4pm UTC if it's 4pm localtime.
# We do this because UTC doesn't have DST,
# so we can safely do date math.
my $time = timegm(localtime());

while (1) {
   $time += 24*60*60;
   last if ( gmtime($time) )[6] == 5;  # Sun=0, Fri=5
}

这可以优化:

use Time::Local qw( timegm );

# This returns 4pm UTC if it's 4pm localtime.
# We do this because UTC doesn't have DST.
# so we can safely do date math.
my $time = timegm(localtime());

my $dow = ( gmtime($time) )[6];  # Sun = 0
my $days = ( 5 - $dow ) % 7;     # Days until Friday
$days += 7 if !$days;            # Days until next Friday
$time += $days * 24*60*60;

现在回答你的问题

use POSIX qw( strftime );

say strftime("%Y-%m-%d", gmtime($time));

你可以使用Time :: Piece,它使用与上面相同的技巧(内部)。

use Time::Piece   qw( localtime );
use Time::Seconds qw( ONE_DAY );

my $tp = localtime;

my $dow = $tp->day_of_week;    # Sun = 0
my $days = ( 5 - $dow ) % 7;   # Days until Friday
$days += 7 if !$days;          # Days until next Friday
$time += $days * ONE_DAY;

say $tp->ymd;   # Or $tp->strftime("%Y-%m-%d")

就个人而言,我尽量避免Time :: Piece。弄错事太容易了(就像你做的那样)。

use DateTime qw( );

my $dt = DateTime->now( time_zone => 'local' );

my $dow = $dt->day_of_week;    # Sun = 0
my $days = ( 5 - $dow ) % 7;   # Days until Friday
$days += 7 if !$days;          # Days until next Friday
$dt->add( days => $days );

say $dt->ymd;   # Or $dt->strftime("%Y-%m-%d")