2014-09-30 66 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。如果您正在使用特定时区,则可能需要将系统设置为您正在使用的时区,或使用其他模块。