Как я преобразовываю дату/время во время эпохи (время/секунды Unix с 1970) в Perl?

44
задан 13 revs, 5 users 89% 26 February 2018 в 11:16
поделиться

11 ответов

Это - самый простой способ получить время Unix:

use Time::Local;
timelocal($second,$minute,$hour,$day,$month-1,$year);

Примечание обратный порядок аргументов и в том январе месяц 0. Для значительно большего количества опций посмотрите модуль DateTime от CPAN.

Что касается парсинга, посмотрите Дата:: Синтаксический анализ модуль от CPAN. Если действительно необходимо стать необычными с парсингом даты, Дата:: Manip может быть полезным, хотя его собственная документация предупреждает Вас далеко от него, так как он несет много багажа (он знает вещи как общие бизнес-праздники, например), и другие решения намного быстрее.

, Если Вы, оказывается, знаете что-то о формате даты/времен, что Вы будете анализировать тогда простое регулярное выражение, может быть достаточным, но Вы - вероятно, более обеспеченное использование соответствующего модуля CPAN. Например, если Вы знаете, что даты всегда будут в порядке YMDHMS, использовать модуль CPAN DateTime:: Формат:: ISO8601.

<час>

Для моей собственной ссылки, если ничто иное, ниже не является функцией, я использую для приложения, где я знаю, что даты всегда будут в порядке YMDHMS со всеми или частью "на службе ее величества вооруженных сил Великобритании" дополнительной части. Это принимает любые разделители (например, "2009-02-15" или "2009.02.15"). Это возвращает соответствующее время Unix (секунды с тех пор 01.01.1970 0:00:00 GMT) или-1, если это не могло бы проанализировать его (что означает Вас лучше быть уверенным, что Вы никогда не должны будете законно анализировать дату 31.12.1969 23:59:59). Это также предполагает двухразрядные годы XX, до "69" относятся к "20XX", иначе "19XX" (например, "50-02-15" означает 15.02.2050, но "75-02-15" означает 15.02.1975).

use Time::Local;

sub parsedate { 
  my($s) = @_;
  my($year, $month, $day, $hour, $minute, $second);

  if($s =~ m{^\s*(\d{1,4})\W*0*(\d{1,2})\W*0*(\d{1,2})\W*0*
                 (\d{0,2})\W*0*(\d{0,2})\W*0*(\d{0,2})}x) {
    $year = $1;  $month = $2;   $day = $3;
    $hour = $4;  $minute = $5;  $second = $6;
    $hour |= 0;  $minute |= 0;  $second |= 0;  # defaults.
    $year = ($year<100 ? ($year<70 ? 2000+$year : 1900+$year) : $year);
    return timelocal($second,$minute,$hour,$day,$month-1,$year);  
  }
  return -1;
}
21
ответ дан 9 revs, 2 users 95% 26 November 2019 в 21:59
поделиться

Если Вы используете модуль DateTime , можно звонить эпоха () метод на объекте DateTime, так как это - то, о чем Вы думаете как время Unix.

Используя DateTimes позволяет Вам преобразовывать довольно легко с эпохи, к объектам даты.

Alternativly, localtime и gmtime преобразуют эпоху в массив, содержащий дневной месяц и год, и timelocal и timegm от Время:: Локальный модуль сделает противоположное, преобразовывая массив факторов времени (секунды, минуты..., дни, месяцы и т.д.) в эпоху.

34
ответ дан szabgab 26 November 2019 в 21:59
поделиться

Фильтр, преобразовывающий какие-либо даты в различных связанных с ISO форматах (и кто использовал бы что-либо еще после чтения записи из Могущественного Kuhn?) на стандартном входе к seconds-since-the-epoch времени на стандартном выводе мог бы служить для иллюстрирования обеих частей:

martind@whitewater:~$ cat `which isoToEpoch`
#!/usr/bin/perl -w
use strict;
use Time::Piece;
# sudo apt-get install libtime-piece-perl
while (<>) {
  # date --iso=s:
  # 2007-02-15T18:25:42-0800
  # Other matched formats:
  # 2007-02-15 13:50:29 (UTC-0800)
  # 2007-02-15 13:50:29 (UTC-08:00)
  s/(\d{4}-\d{2}-\d{2}([T ])\d{2}:\d{2}:\d{2})(?:\.\d+)? ?(?:\(UTC)?([+\-]\d{2})?:?00\)?/Time::Piece->strptime ($1, "%Y-%m-%d$2%H:%M:%S")->epoch - (defined ($3) ? $3 * 3600 : 0)/eg;
  print;
}
martind@whitewater:~$ 
-3
ответ дан Martin Dorey 26 November 2019 в 21:59
поделиться

Возможно один из лучших примеров 'существует больше чем Один Способ Сделать Это", с или без справки CPAN.

, Если Вы управляете тем, что Вы передаетесь как 'дата/время', я предложил бы идти маршрут DateTime, любой при помощи определенной Даты:: Время:: подкласс Формата или использование DateTime:: Формат:: Strptime, если нет того, поддерживающего Ваш дурацкий формат даты (см. дата и время FAQ для получения дополнительной информации). В целом, Дата:: Время является способом пойти, если Вы хотите сделать что-либо серьезное с результатом: немного классов на CPAN вполне как анально-сохраняющие и одержимо точные.

, Если Вы ожидаете странный материал свободной формы, бросьте его в Дата:: Синтаксический анализ str2time () метод, который получит Вас значение секунд начиная с эпохи, у Вас может тогда быть свой злой путь с без издержек Дата:: Manip.

2
ответ дан szabgab 26 November 2019 в 21:59
поделиться

На CPAN существует много модулей управления Датой. Мой конкретный фаворит DateTime, и можно использовать strptime модули для парсинга дат в произвольных форматах. Существуют также многие DateTime:: модули Формата на CPAN для обработки специализированных форматов даты, но strptime является самым универсальным.

2
ответ дан Shlomi Fish 26 November 2019 в 21:59
поделиться

Мой любимый синтаксический анализатор даты и времени DateTime:: Формат:: ISO8601, Как только у Вас есть та работа, Вы сделаете, чтобы DateTime возразил, легко конвертируемый к секундам эпохи с эпохой ()

2
ответ дан skiphoppy 26 November 2019 в 21:59
поделиться
$ENV{TZ}="GMT";
POSIX::tzset();
$time = POSIX::mktime($s,$m,$h,$d,$mo-1,$y-1900);
7
ответ дан ysth 26 November 2019 в 21:59
поделиться

Для парсинга даты посмотрите Дата:: Синтаксический анализ в CPAN.

17
ответ дан szabgab 26 November 2019 в 21:59
поделиться

Получают Дату:: Manip от CPAN, тогда:

use Date::Manip;
$string = '18-Sep-2008 20:09'; # or a wide range of other date formats
$unix_time = UnixDate( ParseDate($string), "%s" );

редактирование:

Дата:: Manip является крупным и медленным, но очень гибким в парсинге, и это - чистый жемчуг. Используйте его, если Вы спешите, когда Вы пишете код, и Вы знаете, что не будете спешить при выполнении его.

, например, Использование это для парсинга параметров командной строки однажды на запуске, но не используют его анализирующий большие объемы данных по занятому веб-серверу.

См. комментарии .

авторов

(Благодаря автору первого комментария ниже)

6
ответ дан szabgab 26 November 2019 в 21:59
поделиться

Если Вы просто ищете утилиту командной строки (т.е. не что-то, что назовут от других функций), испытайте этот сценарий. Это принимает существование даты GNU (подарок в в значительной степени любой системе Linux):

#! /usr/bin/perl -w

use strict;

$_ = (join ' ', @ARGV);
$_ ||= <STDIN>;

chomp;

if (/^[\d.]+$/) {
    print scalar localtime $_;
    print "\n";
}
else {
    exec "date -d '$_' +%s";
}

Вот то, как это работает:

$ Time now
1221763842

$ Time yesterday
1221677444

$ Time 1221677444
Wed Sep 17 11:50:44 2008

$ Time '12:30pm jan 4 1987'
536790600

$ Time '9am 8 weeks ago'
1216915200
-4
ответ дан raldi 26 November 2019 в 21:59
поделиться

Для дополнительной информации, один лайнер, который может применяться, например, в сценариях ! # / Bin / sh .

EPOCH="`perl -e 'use Time::Local; print timelocal('${SEC}','${MIN}','${HOUR}','${DAY}','${MONTH}','${YEAR}'),\"\n\";'`"

Только не забывайте избегать восьмеричных чисел!

2
ответ дан 26 November 2019 в 21:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: