将Date :: Manip :: Obj转换为Time :: Piece或Class :: Date

时间:2014-09-30 10:15:37

标签: perl date time type-conversion

我想在日期之间进行比较,即使在夏令时变化后(例如CEST到CET),它们也需要正确。问题是我无法使用Date::Manip::Obj

在文档中,他们谈到Time::Piece可以实现这一点,我也对此进行了测试。

问题是我无法将Date::Manip已解析的对象转换为Time::Piece对象。我怎样才能做到这一点?我有一个Date::Manip对象,因为我需要使用这个库来解析OpenSSL包中的日期。

如果有人知道如何以适用于夏令时的方式正确使用Date::Manip,请告诉我。

这是测试比较的一些代码。 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);
}

当夏令时从夏天变为冬季(凌晨3点至凌晨2点)时,cmp()会返回-1,这应该是1,因为如果您查看时区,它实际上会更晚。

使用Time:Piece,这种比较效果很好,这就是为什么我想将date :: manip转换为Time:piece

1 个答案:

答案 0 :(得分:1)

您可以通过将纪元秒作为参数传递给Time::Piece来初始化new对象:

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" );

请注意,似乎无法将Time :: Piece设置为使用特定时区;如果使用new(调用底层系统strptime函数),则使用系统时区;如果使用strptime,则使用UTC。如果您使用的是特定时区,则可能需要将系统设置为您正在使用的时区,或使用其他模块。