Вычислить NUM дней из UNION временных диапазонов (с DateTime :: Span) - PullRequest
1 голос
/ 29 марта 2012

У меня есть набор временных диапазонов, и мне нужно получить количество дней из этого набора. Я сделал это с DateTime::Span следующим образом:

use DateTime;
use DateTime::Span;

sub printHash {
    my $hash = shift;
    foreach my $key (keys %{$hash}) {
        print "$key: $hash->{$key}\n";
    }
}

$date1 = DateTime->new( year => 2002, month => 3, day => 11 );
$date2 = DateTime->new( year => 2002, month => 4, day => 12 );
$date3 = DateTime->new( year => 2003, month => 8, day => 26 );
$date4 = DateTime->new( year => 2003, month => 9, day => 15 );
$date5 = DateTime->new( year => 2004, month => 7, day => 6 );
$date6 = DateTime->new( year => 2004, month => 10, day => 15 );

$set1 = DateTime::Span->from_datetimes( start => $date1, end => $date2 );
$set2 = DateTime::Span->from_datetimes( start => $date3, end => $date4 );
$set3 = DateTime::Span->from_datetimes( start => $date5, end => $date6 );

$set123 = $set1->union( $set2, $set3 );

printHash(\%$set123);

#--------------------------------

set123:
set: [2002-03-11T00:00:00..2002-04-12T00:00:00],[2003-08-26T00:00:00..2003-09
T00:00:00],[2004-07-06T00:00:00..2004-10-15T00:00:00]

Есть ли способ извлечь количество дней в этом $set123? Большое спасибо!

Обновление: Я могу сделать это с delta_days, но на самом деле мне нужен СОЮЗ из диапазонов времени, чтобы найти количество дней в этом наборе СОЮЗ. Я считаю, DateTime::Span хорошо работает, чтобы найти СОЮЗ, но мне просто нужно знать, как извлечь количество дней в нем. Поскольку мне нужно решение в спешке, пожалуйста, помогите! Спасибо!

Ответы [ 2 ]

2 голосов
/ 29 марта 2012

Во-первых, вы звоните union неправильно. Требуется только один аргумент.

$set1->union($set2)->union($set3);

Во-вторых, результатом union на самом деле является DateTime :: SpanSet , а не DateTime :: Span .

my $spanset = $set1->union($set2)->union($set3);

Наконец, оба: :: Span и :: SpanSet предоставляют метод с именем duration, который возвращает DateTime :: Duration объект.

my $dur = $spanset->duration();

К сожалению, он не возвращает результат в виде дней, и невозможно преобразовать то, что он возвращает, в дни. Это означает, что вам нужно перебирать промежутки, составляющие набор промежутков, и суммировать их размер.

my $days = 0;
my $iter = $spanset->iterator();
while ( my $span = $iter->next ) {
   my $date1 = $span->start;
   my $date2 = $span->end;
   $days += $date2->delta_days($date1)->in_units('days');
}

print("$days\n");  # 153
1 голос
/ 29 марта 2012

На самом деле вам не нужно использовать DateTime::Span. Метод delta_days из DateTime прекрасно справляется с задачей:

use strict;
use warnings;
use DateTime;
my $dt1=DateTime->new(year=>2002,month=>3,day=>11,time_zone=>"local");
my $dt2=DateTime->new(year=>2002,month=>4,day=>11,time_zone=>"local");

print $dt2->delta_days($dt1)->in_units("days") . "\n"; #31
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...