Анализ даты и времени в строках
Проблема
Спецификация даты или времени читается в произвольном формате, однако ее требуется преобразовать в
отдельные компоненты (год, месяц и т. д.).
Решение
Если дата уже представлена в виде числа или имеет жесткий, легко анализируемый формат, воспользуйтесь
регулярным выражением (и, возможно, хэшем, связывающим названия месяцев с номерами) для извлечения
отдельных значений дня, месяца и года. Затем преобразуйте их в секунды с начала эпохи с помощью
функций timelocal и timegm стандартного модуля Time::Local.
use Time::Local;
# $date хранится в формате "1999-06-03" (ГГГГ-ММ-ДД).
($уууу, $mm, $dd) = ($date =~ /(\d+)-(\d+)-(\d+)/;
# Вычислить секунды с начала эпохи для полночи указанного дня
# в текущем часовом поясе
$epoch_seconds = timelocal(0, 0, 0, $dd, $mm, Syyyy);
Более гибкое решение — применение функции ParseDate из модуля Date::Manip с CPAN и последующее
извлечение отдельных компонентов с помощью UnixDate.
use Date::Manip qw(ParseDate UnixDate);
$date = ParseDate($STRING);
if (!$date) {
# Неверная дата
} else {
@VALUES = UnixDate($date, @FORMATS);
}
Комментарий
Универсальная функция ParseDate поддерживает различные форматы дат. Она даже преобразует такие
строки, как «today» («сегодня»), «2 weeks ago Friday» («в пятницу две недели назад») и «2nd Sunday in 1996»
(«2-е воскресенье 1996 года»), а также понимает форматы даты/времени в заголовках почты и новостей.
Расшифрованная дата возвращается в собственном формате — строке вида «ГГГГММДДЧЧ:ММ:СС».
Сравнение двух строк позволяет узнать, совпадают ли представленные ими даты, однако арифметические
операции выполняются иначе. Поэтому мы воспользовались функцией UnixDate для извлечения года, месяца и дня в нужном формате.
Функция UnixDate получает дату в виде строки, возвращаемой ParseDate, и список форматов. Она последовательно
применяет каждый формат к строке и возвращает результат. Формат представляет собой строку с описанием одного
или нескольких элементов даты/времени и способов оформления этих элементов, Например, формат %Y соответствует году,
состоящему из четырех цифр. Приведем пример:
use Date::Manip qw(ParseDate UnixDate);
while (<>) {
$date = ParseDate($_);
if (!$date) {
warn "Bad date string: $_\n";
next;
} else {
($year, $month, $day) = UnixDate($date, "%Y", "%m", "%d");
print "Date was $month/$day/$year\n";
}
}
См. также
Proverte kod v komentariyah gde pro list tam oshibki detskie
Оставить комментарий:
|
|