Это - самый простой способ получить время 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;
}
Если Вы используете модуль DateTime , можно звонить эпоха () метод на объекте DateTime, так как это - то, о чем Вы думаете как время Unix.
Используя DateTimes позволяет Вам преобразовывать довольно легко с эпохи, к объектам даты.
Alternativly, localtime и gmtime преобразуют эпоху в массив, содержащий дневной месяц и год, и timelocal и timegm от Время:: Локальный модуль сделает противоположное, преобразовывая массив факторов времени (секунды, минуты..., дни, месяцы и т.д.) в эпоху.
Фильтр, преобразовывающий какие-либо даты в различных связанных с 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:~$
Возможно один из лучших примеров 'существует больше чем Один Способ Сделать Это", с или без справки CPAN.
, Если Вы управляете тем, что Вы передаетесь как 'дата/время', я предложил бы идти маршрут DateTime, любой при помощи определенной Даты:: Время:: подкласс Формата или использование DateTime:: Формат:: Strptime, если нет того, поддерживающего Ваш дурацкий формат даты (см. дата и время FAQ для получения дополнительной информации). В целом, Дата:: Время является способом пойти, если Вы хотите сделать что-либо серьезное с результатом: немного классов на CPAN вполне как анально-сохраняющие и одержимо точные.
, Если Вы ожидаете странный материал свободной формы, бросьте его в Дата:: Синтаксический анализ str2time () метод, который получит Вас значение секунд начиная с эпохи, у Вас может тогда быть свой злой путь с без издержек Дата:: Manip.
На CPAN существует много модулей управления Датой. Мой конкретный фаворит DateTime, и можно использовать strptime модули для парсинга дат в произвольных форматах. Существуют также многие DateTime:: модули Формата на CPAN для обработки специализированных форматов даты, но strptime является самым универсальным.
Мой любимый синтаксический анализатор даты и времени DateTime:: Формат:: ISO8601, Как только у Вас есть та работа, Вы сделаете, чтобы DateTime возразил, легко конвертируемый к секундам эпохи с эпохой ()
$ENV{TZ}="GMT";
POSIX::tzset();
$time = POSIX::mktime($s,$m,$h,$d,$mo-1,$y-1900);
Для парсинга даты посмотрите Дата:: Синтаксический анализ в CPAN.
Получают Дату:: 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 является крупным и медленным, но очень гибким в парсинге, и это - чистый жемчуг. Используйте его, если Вы спешите, когда Вы пишете код, и Вы знаете, что не будете спешить при выполнении его.
, например, Использование это для парсинга параметров командной строки однажды на запуске, но не используют его анализирующий большие объемы данных по занятому веб-серверу.
См. комментарии .
авторов(Благодаря автору первого комментария ниже)
Если Вы просто ищете утилиту командной строки (т.е. не что-то, что назовут от других функций), испытайте этот сценарий. Это принимает существование даты 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
Для дополнительной информации, один лайнер, который может применяться, например, в сценариях ! # / Bin / sh
.
EPOCH="`perl -e 'use Time::Local; print timelocal('${SEC}','${MIN}','${HOUR}','${DAY}','${MONTH}','${YEAR}'),\"\n\";'`"
Только не забывайте избегать восьмеричных чисел!