Как сравнить строковую дату и время в Perl? - PullRequest
5 голосов
/ 22 ноября 2011

У меня есть формат даты и времени в строке "11:56:41, 22.11.2011".

Вот что я хочу:

Сравните две строки даты и времени, как.

$date1 = "11:56:41, 11/22/2011";
$date2 = "11:20:41, 11/20/2011";
if($date2 < $date1) {
    do something...
} else {
    do nothing...
}

Любые идеи, как я могу добиться этого в Perl?

Ответы [ 6 ]

13 голосов
/ 22 ноября 2011

Еще одно решение, которое использует перегруженные сравнения после преобразования времени в Time::Piece объекты. Создание объектов может быть излишним из-за чего-то простого, но они могут стать очень полезными, если вам нужно делать другие вещи со временем.

use Time::Piece;

my $dateformat = "%H:%M:%S, %m/%d/%Y";

my $date1 = "11:56:41, 11/22/2011";
my $date2 = "11:20:41, 11/20/2011";

$date1 = Time::Piece->strptime($date1, $dateformat);
$date2 = Time::Piece->strptime($date2, $dateformat);

if ($date2 < $date1) {
    do something...
} else {
    do nothing...
}
11 голосов
/ 22 ноября 2011

Эффективный метод - переупорядочить поля во что-то лексически сопоставимое.

sub to_comparable {
   my ($date) = @_;
   my ($H,$M,$S,$d,$m,$Y) = $date =~ m{^([0-9]{2}):([0-9]{2}):([0-9]{2}), ([0-9]{2})/([0-9]{2})/([0-9]{4})\z}
      or die;
   return "$Y$m$d$H$M$S";
}

if (to_comparable($date2) lt to_comparable($date1)) {
   ...
} else {
   ...
}
5 голосов
/ 22 ноября 2011

Что, уже 4 часа и ни одного DateTime (все приветствуют могучего DateTime ) в поле зрения? Вы расслабляетесь, подписчиков ... ☻

use DateTime::Format::Strptime qw();
my $p = DateTime::Format::Strptime->new(pattern => '%T, %D', on_error => 'croak',);

my $date1 = $p->parse_datetime('11:56:41, 11/22/2011');
my $date2 = $p->parse_datetime('11:20:41, 11/20/2011');

if($date2 < $date1) {
    say "$date2 comes before $date1";
} else {
    say "$date2 does not come before $date1";
}

Метод parse_datetime возвращает экземпляры DateTime, чьи операторы сравнения и строковое преобразование перегружены в DTRT.

2 голосов
/ 01 апреля 2014

Я использую unixtime. :)

Я конвертирую оба раза в unixtime, а затем у меня есть два целых числа для сравнения, поэтому я могу использовать операторы <, ==,> и т. Д.

например. преобразовать в unixtime следующим образом

my $timestamp = "2014-03-25 12:33:32";  # (We assume localtime)

# 
# To split on the space character, it's best to use the regex / /
# 
my ($date, $time) = split (/ /, $timestamp);
my ($year, $mon, $mday) = split ('-', $date);
my ($hour, $min, $sec) = split (':', $time);

my $unixtime = timelocal($sec, $min, $hour, $mday, $mon-1, $year);
1 голос
/ 22 ноября 2011

В этом случае я всегда использовал Date::Calc:

use Date::Calc;

my $date1 = "11:56:41, 11/22/2011";
my $date2 = "11:20:41, 11/20/2011";

my @date1arr=split /[^\d]/, $date1 if($date1 =~ m!\d{2}:\d{2}:\d{2}, \d{2}/\d{2}/\d{4}!;
my @date2arr=split /[^\d]/, $date2 if($date2 =~ m!\d{2}:\d{2}:\d{2}, \d{2}/\d{2}/\d{4}!;

my @diff = Delta_DHMS(@date1arr, @date2arr);
my $less;
foreach my $d ( @diff ) { $less = 1 if $d < 0; }

if($less) { ... }
1 голос
/ 22 ноября 2011

Преобразование даты и времени (в вашем случае это локальные даты и время, потому что у них нет часовых поясов) в ISO8601, тогда вы можете выполнять регулярное сравнение строк.

Чтобы выполнить преобразование, вы должны извлечь шесть компонентов из вашегоотформатируйте

HH:MM:SS, mm/DD/YYYY

и соберите их в ISO 8601:

YYYY-MM-DDTHH:MM:SS

Тогда будет работать нормальное лексикографическое сравнение.

См. http://codepad.org/berle9um

Повторяется здесь:

sub my_format_to_iso8601 {
    $_[0] =~ /(\d\d):(\d\d):(\d\d), (\d\d)\/(\d\d)\/(\d\d\d\d)/;
    return "$6-$4-$5T$1:$2:$3";
}

$date1 = "11:56:41, 11/22/2011";
$date2 = "11:20:41, 11/20/2011";
$d1 = my_format_to_iso8601($date1);
$d2 = my_format_to_iso8601($date2);
print "first is $d1\n";
print "second is $d2\n";
if ($d2 < $d1) {
    print "second is earlier\n";
} else {
    print "first is earlier\n";
}

ADDENDUM

  • Perl-код ikegami намного лучше.
  • Здесь вам подойдет библиотека дат;просто укажите строку формата и используйте функцию анализа библиотеки, чтобы получить объект даты, который он затем сможет сравнивать напрямую.(Тем не менее, всегда интересно отметить, что ISO8601 по своей конструкции сортируется в строковой форме.)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...