2014-09-30 61 views
1

我想在日期之間進行比較,即使在夏令時變化後(即CEST到CET),它們也需要正確。問題是我無法使用Date::Manip::Obj來處理這個問題。Convert Date:Manip :: Obj to Time :: Piece or Class :: Date

在文檔中,他們說它可能與Time::Piece,我也測試過。

問題是我不能將Date::Manip解析對象轉換爲Time::Piece對象。我怎樣才能做到這一點?我有一個Date::Manip對象,因爲我需要使用此庫來解析OpenSSL數據包中的日期。

如果有人知道如何正確使用Date::Manip以適應Daylight更改時間,請告訴我。

這是測試比較的一些代碼。 LastUpdate變量只是過去的一個日期,因此我可以將它與現在進行比較,當從CEST轉到CET時。

#!/usr/bin/perl 

use strict; 
use warnings; 
use FindBin; 

use Date::Manip::Date; 
use Date::Manip::Delta; 
use Date::Manip::TZ; 
use Data::Dumper; 
use Time::Piece; 
use Time::Seconds; 

# To simulate checking a recently-published CRL against the current time, set a lastUpdate time 
# to now() - 1 minute (for instance). Then, using the OS date --set command, set the system date 
# to a few seconds before the DST rollover from CEST to CET (happens at 03:00:00 on the last sunday 
# of october -- 27 Oct in 2013), and then run the script. 

my $date = new Date::Manip::Date "now"; 
my $delta = $date->new_delta(); 
my $tz = new Date::Manip::TZ; 

$delta->parse("-00:01:00"); 

my $dmLastUpdate = $date->calc($delta); 
my $tpLastUpdate = Time::Piece->new; 
$tpLastUpdate -= ONE_MINUTE; 

my $now = $date->new_date(); 
while (1) 
{ 
    $now->parse("now"); 
    my $dmTz = $tz->curr_zone(); 
    my $dmNowLarger = $now->cmp($dmLastUpdate); 

    my $tpNow = Time::Piece->new; 
    my $tpTz = $tpNow->strftime("\%Z (\%z)"); 

    printf "\%-30s: \%s\n", "DateManip \$tz", (defined($dmTz) ? $dmTz : ""); 
    printf "\%-30s: \%s\n", "DateManip now ", $date->printf("%C"); 
    printf "\%-30s: \%s\n", "DateManip lastUpdate ", $dmLastUpdate->printf("%C"); 
    printf "\%-30s: \%s\n", "DateManip now > lastUpdate ", $dmNowLarger; 
    printf "\%-30s: \%s\n", "TimePiece \$tz ", $tpTz; 
    printf "\%-30s: \%s\n", "TimePiece now ", $tpNow->strftime(); 
    printf "\%-30s: \%s\n", "TimePiece lastUpdate ", $tpLastUpdate->strftime(); 
    printf "\%-30s: \%s\n", "TimePiece now > lastUpdate ", ($tpNow > $tpLastUpdate); 
    printf "-------------------------------------------------------\n"; 
    sleep (3); 
} 

當下夏令從夏天到冬天的時候改變(CEST凌晨3點至凌晨2點歐洲中部時間)它CMP()返回-1,這應該是1,因爲它實際上是以後如果你看一下時區。

用時:海賊王,是比較行之有效所以這就是爲什麼我要日期:: MANIP到時間轉換:一塊

+1

爲什麼不放棄使用Date :: Manip?多年來一直沒有推薦它。您可以使用'strptime'方法將日期直接解析到Time :: Piece對象中。 – 2014-09-30 12:48:36

+0

我現在正在嘗試。但是如果我添加一個特定的時區,例如GMT,並且打印時期,則該時代不在GMT時區,而是在我的系統時區中。 – Digihash 2014-09-30 13:00:40

+0

我不明白這意味着什麼。時代價值不在任何時區。這只是一個數字。無論你在哪個時區,它都是一樣的。 – 2014-09-30 13:16:10

回答

1

你可以通過新紀元的秒數​​作爲參數傳遞給new初始化Time::Piece對象:

my $tp = Time::Piece->new(123456789); 
say $tp->strftime(); 
say $tp->epoch(); 
## output: 
## Thu, 29 Nov 1973 21:33:09 BST 
## 123456789 

要獲得劃時代超時的Date::Manip::Date,你可以做到以下幾點:

$date->printf('%s'); 

你也可以使用Time::Piece->strptime解析時間:

my $tp2 = Time::Piece->strptime("1:24:08 PM 1996-02-03", "%H:%M:%S %p %Y-%m-%d"); 

注意,它並沒有出現可以設置時間::片使用特定的時區;如果使用new(它調用底層系統strptime函數),則使用系統時區;如果使用strptime,則使用UTC。如果您正在使用特定時區,則可能需要將系統設置爲您正在使用的時區,或使用其他模塊。