В Perl, как я могу убедиться, что строка соответствует действительной дате? - PullRequest
5 голосов
/ 24 февраля 2012

Мне было интересно, есть ли в Perl простой способ убедиться, что строка даты соответствует действительной дате.

Например, 2012 02 30 неверно, поскольку его не существует.

Ответы [ 6 ]

7 голосов
/ 24 февраля 2012

Модуль DateTime будет проверять даты при создании нового объекта.

$ perl -we 'use DateTime; my $dt; 
    eval { $dt = DateTime->new( 
        year => 2012, 
        month => 2, 
        day => 30);
    }; print "Error: $@" if $@;'

Error: Invalid day of month (day = 30 - month = 2 - year = 2012) at -e line 1

Он также динамически работает с данным объектом DateTime:

$dt->set(day => 30);
3 голосов
/ 24 февраля 2012

Примерно так: Class :: Date должен работать

perl testit.pl Проверка диапазона по дате или времени не удалась

use Class::Date;


my $d=Class::Date->new('2021-02-30');
unless ( $d->error ) {
  print "good date\n";
} else {
   print $d->errstr(). "\n";
}
exit;
1 голос
/ 25 февраля 2012

Вы также можете использовать Время :: Местное :

#!/usr/bin/env perl

use strict; use warnings;
use Carp qw( croak );
use Time::Local qw( timegm );

my @to_check = ('1927 06 18', '2012 02 30');

for my $date ( @to_check ) {
    printf "'%s' is %s\n", $date, check_date($date) ? 'valid' : 'invalid';
}

sub check_date {
    my ($date) = @_;

    my ($year, $month, $mday) = split ' ', $date;

    my $ret;

    eval {
        $ret = timegm(0, 0, 0, $mday, $month - 1, $year - 1900);
    };

    return $ret && $ret;
}
1 голос
/ 24 февраля 2012

Вы можете сделать это с помощью POSIX mktime, но, очевидно, только если у вас достаточно гибкая реализация mktime.

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

my ( $y, $m, $d ) = split ' ', $date_string;
die "$date_string is not a valid date!" 
    unless ( $d == ( localtime mktime( 0, 0, 0, $d, $m - 1, $y - 1900 ))[3] )
    ; 

Видите ли, в версиях mktime, к которым я привык, mktime( 0, 0, 0, 30, 1, 112 ) будет составлять '2012-03-01' и 30 != 1

1 голос
/ 24 февраля 2012

Проверьте здесь: http://www.perlmonks.org/?node_id=564594

Я верю, что вы получите ответы, которые вы ищете от мудрых монахов.

0 голосов
/ 24 февраля 2012

Может быть, это тоже поможет:

use Time::Piece; #in perl CORE distro since 5.10
use 5.010;
say Time::Piece->strptime("2011-02-29","%Y-%m-%d")->strftime("%Y-%m-%d");
#2011-03-01
say Time::Piece->strptime("2012-02-29","%Y-%m-%d")->strftime("%Y-%m-%d");
#2012-02-29
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...