2017-12-08 7 views
4

このbashスクリプトを持っている:時間:: bashの日対ワンピース(localtimeの/ gmtimeは)計算

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の同じdiffを印刷するのですが、scalar localtimescalar gmtimeは異なった(そして正しい)文字列を印刷しますか?

EDIT:だから、主な質問は、perlを使ってbashと同じ結果を得る方法です。

答えて

6

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) 
+0

えーえ...だから、盲目的にドキュメントをコピーして、クラスメソッドとして 'strptime'を呼び出すと、問題の原因です。私は実現しませんでした。現時点では「localtime」と「gmtime」のobj.methodと呼ぶべきです - そして、あなたがコメントしたように、今は何かを考えていなければなりません。誰かがそれを明確に説明すると、シンプルな、:) :)ありがとう! – cajwine

+2

Time :: Piece-> strptime(またはgmtime-> Time :: Piece)は、結果のオブジェクトがUTC dtとしてマークされるようにします。 localtime-> strptimeはそれをローカルdtとしてマークします。 'localtime-> strptime'を実行する能力はかなり新しいものです。この動作は文書化されていませんが、内部的なことをせずに唯一の方法です。 – ikegami

+0

ハックはしばらくありました:https://stackoverflow.com/a/22678705/1733163彼らはちょうどこれを文書化したいと思います。 – Miller