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

Perl 将Date::Manip::Obj转换为Time::Piece或Class::Date,perl,date,time,type-conversion,Perl,Date,Time,Type Conversion,我想在日期之间进行比较,即使在夏令时发生变化(如CEST到CET)之后,它们也需要正确。问题是我不能让它工作 在文档中,他们说这是可能的,我也测试了这一点 问题是我无法将已解析的对象转换为Time::Piece对象。我该怎么做?我有一个Date::Manip对象,因为我需要使用这个库来解析OpenSSL数据包中的日期 如果有人知道如何正确使用Date::Manip来处理日光变化时间,请告诉我 这是一些测试比较的代码。LastUpdate变量只是过去的一个日期,所以当从CEST到CET时,我可以将

我想在日期之间进行比较,即使在夏令时发生变化(如CEST到CET)之后,它们也需要正确。问题是我不能让它工作

在文档中,他们说这是可能的,我也测试了这一点

问题是我无法将已解析的对象转换为
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);
}
夏令时从夏季变为冬季(cest凌晨3点到cet凌晨2点)的那一刻,cmp()返回-1,这应该是1,因为如果您查看时区,它实际上是较晚的


对于Time:Piece,这种比较非常有效,因此我想将date::manip转换为Time:Piece

您可以通过将历元秒作为参数传递给
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->strtime
解析时间:

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

请注意,似乎无法将Time::Piece设置为使用特定时区;如果使用
new
(调用基础系统strtime函数),则采用系统时区;如果使用
strtime
,则采用UTC。如果您使用的是特定时区,您可能需要将系统设置为您使用的时区,或者使用不同的模块。

为什么不放弃使用Date::Manip?它已经好几年没有被推荐了。您可以使用
strtime
方法将日期直接解析为Time::Piece对象。我现在正在尝试。但是如果我加上一个特定的时区,比如GMT,然后打印历元,历元不是在GMT时区,而是在我的系统时区。我不明白这意味着什么。历元值不在任何时区中。这只是一个数字。无论你在哪个时区,它都是一样的。你是在计算你的时区,还是在计算另一个时区?Time::Piece似乎被本地化为您所在的时区——如果使用
strtime
解析日期,或者使用
new
构造函数,它会将时区设置为您的系统设置为的任何时区。你最好改用DateTime之类的东西。是我一直用的和日期或时间有关的东西。它可以接受不同格式的日期/时间,您可以使用它进行计算,因此它应该可以很好地满足您的需要。