2017-07-17 60 views
0

我的最終目標是將當前日期和時間與ISO8601格式的TVMaze API返回的日期和時間進行比較,以確定是否播放了新的電視節目。如何解析ISO8601兼容字符串到perl的DateTime對象?

use strict; 
use warnings; 
use feature 'say'; 
use DateTime; 
my $curmytime = DateTime->now()->format_cldr("yyyy-MM-dd'T'HH:mm:ssZ"); 
# Output is: Time now in UTC:2017-07-17T10:44:52+0000 
say "Time now in UTC:". $curmytime; 
my $strtobeparsed = '2017-04-09T21:00:00-0400'; 
# Next, parse the string "2017-04-09T21:00:00-0400" to a DateTime object 

如何解析字符串爲DateTime對象?

+0

該格式似乎不被默認的DateTime ::格式:: ISO8601被包括在內。請參閱https://metacpan.org/pod/distribution/DateTime-Format-ISO8601/lib/DateTime/Format/ISO8601.pod#5.4.1。最簡單的方法是推出自己的解析器。 – simbabque

+0

以* extended *格式(帶有連字符和冒號分隔符)和* basic *格式的時區具有日期和時間是非常奇怪的。你確定不應該是'-04:00'嗎? – Borodin

+0

@Borodin,是的,'format_cldr(「yyyy-MM-dd'T'HH:mm:ssZ」)'沒有冒號就返回它。我不得不從API字符串中刪除冒號來比較兩者。 – Droidzone

回答

2

DateTime does not parse dates and times。爲此,您需要使用DateTime :: Format :: namespace中的許多模塊之一。如果沒有可用的,你可以簡單地使用DateTime::Format::Strptime。給它一個pattern並交給它一個字符串,它會爲你創建一個DateTime對象。

use DateTime::Format::Strptime; 
my $format = DateTime::Format::Strptime->new(pattern => '%FT%T%z'); 
my $dt = $format->parse_datetime('2017-04-09T21:00:00-0400'); 

然後,您可以將它與另一個DateTime進行比較。

print "ok" if $dt < DateTime->now; 

如果你想將其轉換成自己的類,這是相當微不足道了。

package DateTime::Format::TVMaze; 
use strict; 
use warnings; 
use DateTime; 
use parent 'DateTime::Format::Strptime'; 

sub new { 
    my $class = shift; 
    my %params = @_; 

    $params{pattern} = '%FT%T%z'; 

    return $class->SUPER::new(%params); 
} 

現在你可以使用它像這樣

my $dt = DateTime::Format::TVMaze->new->parse_datetime('2017-04-09T21:00:00-0400'); 
+1

謝謝。模塊POD似乎表明它必須首先轉換爲UTC,然後才能比較日期。 – Droidzone

+0

@Droidzone很有可能。 – simbabque

+0

@ikegami是的。在這種情況下,已經有DateTime :: Format :: ISO8601準備好了,但缺少的冒號是這裏的問題。鮑羅廷在對這個問題發表評論時提到。 – simbabque