【问题标题】:Time::Piece (localtime/gmtime) calculation vs bash dateTime::Piece (localtime/gmtime) 计算与 bash 日期
【发布时间】:2017-12-09 07:02:54
【问题描述】:

有这个bash 脚本:

future="${1:-Dec 08 2017 22:00:00}"
t1=$(date -j -f "%b %d %Y %H:%M:%S" "$future" +%s)  #using OS X
t0=$(date +%s)

echo "Current: $(date)"
echo "Future : $future"
echo "Diff   : $(( $t1 - $t0 )) secs"

打印出来:

Current: pi   8. december 2017 21:25:25 CET
Future : Dec 08 2017 22:00:00
Diff   : 2075 secs

结果(差异)是正确的。

现在尝试使用 perl 做同样的事情:

use strict;
use warnings;
use feature 'say';

use Time::Piece;

my $format = '%b %d %Y %H:%M:%S';

my $future = shift // 'Dec 08 2017 22:00:00';
say "Future: $future";

say "localtime: ", scalar localtime();
say "gmtime   : ", scalar gmtime();

my $tf = Time::Piece->strptime($future, $format);
say 'localtime-diff : ', $tf-localtime();
say 'gmtime-diff    : ', $tf-gmtime();

打印出来

Future: Dec 08 2017 22:00:00
localtime: Fri Dec  8 21:27:45 2017  #correct
gmtime   : Fri Dec  8 20:27:45 2017  #correct
localtime-diff : 5535 #incorrect (expecting 3600 secs less)
gmtime-diff    : 5535 #ok

怎么了?意思是,为什么它为localtimegmtime 打印相同的差异,但scalar localtimescalar gmtime 打印不同(和正确)的字符串?

编辑:所以,主要问题是:如何使用 perl 获得与 bash 相同的结果?

【问题讨论】:

    标签: perl


    【解决方案1】:

    localtime()gmtime() 都返回一个代表现在的对象。


    你正在做:

    2017-12-08T22:00:00+00:00 - 2017-12-08T21:25:25+01:00   # $tf-localtime()
    2017-12-08T22:00:00+00:00 - 2017-12-08T20:25:25+00:00   # $tf-gmtime()
    

    看起来你想做

    2017-12-08T22:00:00+01:00 - 2017-12-08T21:25:25+01:00
    

    使用时间::件数:

    use Time::Piece qw( localtime );
    
    my $future_str = 'Dec 08 2017 23:00:00';
    
    my $format = '%b %d %Y %H:%M:%S';
    
    my $future_dt = localtime->strptime($future_str, $format);
    say $future_dt - localtime();  # 2241 (instead of 5841)
    

    使用日期时间:

    use DateTime::Format::Strptime qw( );
    
    my $future_str = 'Dec 08 2017 23:00:00';
    
    my $format = DateTime::Format::Strptime->new(
       pattern   => '%b %d %Y %H:%M:%S',
       locale    => 'en',
       time_zone => 'local',
       on_error  => 'croak',
    );
    
    my $future_dt = $format->parse_datetime($future_str);
    say $future_dt->epoch - time();  # 2241 (instead of 5841)
    

    【讨论】:

    • Ahhhh.. 所以,盲目地复制文档,并将strptime 作为类方法调用是问题的根源。 :( 我没有意识到,我应该(并且可以)在 localtimegmtime 上将其称为 obj.method - 并考虑 now 是什么(就像你评论)。这很简单,当有人清楚地解释它时.. :) :) 非常感谢!
    • Time::Piece->strptime(或 gmtime->Time::Piece)导致生成的对象被标记为 UTC dt。 localtime->strptime 将其标记为本地 dt。执行localtime->strptime 的能力相当新,这种行为没有记录在案,但它是唯一不会弄乱内部结构的方法。
    • 黑客已经存在了一段时间:stackoverflow.com/a/22678705/1733163希望他们能记录下来。
    • @Miller,大多数人使用 5.14 和它附带的 Time::Piece,它比那个帖子更老。
    • @ikegami 点头。那篇文章使用的是 Perl 5.10.1。不过,我从不费心做一个全面的版本支持清单。
    猜你喜欢
    • 1970-01-01
    • 2017-07-07
    • 1970-01-01
    • 1970-01-01
    • 2020-02-18
    • 1970-01-01
    • 2021-08-29
    • 2011-07-21
    • 1970-01-01
    相关资源
    最近更新 更多