2014-09-30 3 views
1

Я хочу делать сравнения между датами, и они должны быть правильными даже после изменения летнего времени (например, CEST to CET). Проблема в том, что я не могу заставить это работать с Date::Manip::Obj.Convert Date :: Manip :: Obj to Time :: Piece или 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); 
} 

В момент сохранения изменений времени с летнего на зимнее время (переход к 3 утра CEST 2 утра мск) он CMP() возвращает -1, и это должно быть 1, потому что это на самом деле позже, если вы посмотрите на часовых поясов.

со временем: Кусок, что сравнение хорошо работает, так что именно поэтому я хочу, чтобы преобразовать дату :: Manip к времени: штучный

+1

Почему бы не просто отказаться от использования Date :: Manip? Это не рекомендуется в течение многих лет. Вы можете анализировать свои даты непосредственно в объектах Time :: Piece, используя метод 'strptime'. –

+0

Я сейчас пытаюсь это сделать. Но если я добавлю определенный часовой пояс, такой как GMT и я печатаю эпоху, эпоха не находится в часовом поясе GMT, а в моем часовом поясе системы. – Digihash

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

Обратите внимание, что это не представляется возможным установить время :: Кусок использовать определенный часовой пояс; он принимает системный часовой пояс при использовании new (который вызывает базовую функцию strptime системы) и UTC, если используется strptime. Если вы работаете с определенным часовым поясом, вам может потребоваться либо настроить вашу систему на часовой пояс, с которым вы работаете, либо использовать другой модуль.