2013-07-25 1 views
-2

Я хочу сгенерировать массив раз в формате hh: mm с учетом интервала и количества точек времени, начиная с нуля. Таким образом, 3 момента времени в 10 минут выйдут (00:00, 00:10, 00:20). Я нашел это очень хорошие сниппаю для приращения и форматирования времени в час теперь:Время инкремента Perl начиная с 00:00

perl -e '@d=localtime time() + 600 - localtime time(); 
printf "%02d:%02d%s\n",$d[2]%12,$d[1]' 

Как я могу «сейчас» заменить «00:00»? Бонусные баллы за использование базовых модулей Perl.

Спасибо, L.

+3

Где бы вы ни находили этот фрагмент, вы должны вернуть его обратно. – mob

+0

Теперь данные и время. Он не может быть заменен только временем. Вам также нужна дата, потому что не все дни всех часовых поясов имеют 1:10 или даже 0:10. Вы хотите использовать сегодняшнюю дату? – ikegami

+0

Возможно, вы сможете использовать [это] (http://stackoverflow.com/questions/17112977/converting-numbers-to-kmgt-and-days-hours-min/17115544#17115544) как часть для решения вашей проблемы , –

ответ

1

Алгоритм достаточно прост; вот функция, которая принимает два аргумента, интервал длины в течение нескольких минут и количество интервалов, чтобы вернуться, и возвращает ссылку на массив, содержащий заданные интервалы, выраженные в желаемом формате времени:

sub intervals { 
    my $interval = shift(); # interval length in minutes 
    my $n_points = shift(); # number of intervals to return 
    die "intervals() takes two arguments\n" 
      unless $interval and $n_points; 

    my @now_tm = localtime(); 

    # check DST delta per @ikegami 
    my $dst_delta = 0; 
    my @yesterday_tm = localtime(time() - 86400); 
    if ($yesterday_tm[8] && !$now_tm[8]) { 
      # "fall back" - today is an hour shorter 
      $dst_delta = -3600; 
    } 
    elsif (!$yesterday_tm[8] && $now_tm[8]) { 
      # "spring forward" - today is an hour longer 
      $dst_delta = 3600; 
    }; 

    # find timestamp for 00:00 today 
    my $now_ts = time(); 
    my $then_ts = $now_ts 
      + $dst_delta   # apply any dst correction required 
      - ($now_tm[2] * 3600) # subtract hours since midnight 
      - ($now_tm[1] * 60) # ...and minutes 
      - $now_tm[0];   # ...and seconds 

    # generate actual intervals, starting at midnight 
    my @interval_times =(); 
    for (my $point = 0; $point < $n_points; $point++) { 
      my $interval_ts = $then_ts + (($interval * 60) * $point); 
      my @interval_tm = localtime($interval_ts); 
      my $interval_formatted = sprintf("%0.2d:%0.2d", 
              $interval_tm[2], 
              $interval_tm[1]); 
      push @interval_times, $interval_formatted; 
    }; 

    return [@interval_times]; 
}; 

называется intervals(10, 20), она возвращает следующие:

0 ARRAY(0xd284e40) 
    0 '00:00' 
    1 '00:10' 
    2 '00:20' 
    3 '00:30' 
    4 '00:40' 
    5 '00:50' 
    6 '01:00' 
    7 '01:10' 
    8 '01:20' 
    9 '01:30' 
    10 '01:40' 
    11 '01:50' 
    12 '02:00' 
    13 '02:10' 
    14 '02:20' 
    15 '02:30' 
    16 '02:40' 
    17 '02:50' 
    18 '03:00' 
    19 '03:10' 

И не требуются модули Perl, будь то ядро ​​или иное.

+0

Ваш код не работает в течение определенных дней года из-за пропущенных или вставленных часов из-за DST. '$ now_tm [2]' не количество часов с полуночи. – ikegami

+0

@ikegami Отличная точка; Я изменил функцию для обработки этого углового футляра. (По крайней мере, в США поправки DST вставляются в 0200, что, я думаю, означает, что '(time() - 86400)' всегда заканчивается вчера, даже в день «спада», который составляет 23 часа. Коррекция алгоритм для областей, где '(time() - 86400)' не может полагаться на то, чтобы всегда заканчиваться в какой-то момент вчера, остается в качестве упражнения для заинтересованного читателя.) –

+0

Аарон: Он говорит, чтобы не поблагодарить, вы, но я очень ценю этот код! – LKramer

Смежные вопросы