Tôi đã tự hỏi nếu có một cách đơn giản trong Perl để đảm bảo rằng một chuỗi ngày tương ứng với một ngày hợp lệ. Ví dụ: 2012 02 30
không chính xác vì không tồn tại.Trong Perl, làm thế nào tôi có thể đảm bảo rằng một chuỗi tương ứng với một ngày hợp lệ?
Trả lời
Kiểm tra ở đây: http://www.perlmonks.org/?node_id=564594
Tôi tin rằng bạn sẽ nhận được câu trả lời mà bạn tìm kiếm từ các nhà sư khôn ngoan.
Something như thế này sử dụng Class :: ngày nên làm việc
perl testit.pl séc Phạm vi về ngày hay giờ thất bại
use Class::Date;
my $d=Class::Date->new('2021-02-30');
unless ($d->error) {
print "good date\n";
} else {
print $d->errstr(). "\n";
}
exit;
Module DateTime sẽ xác nhận ngày khi tạo một đối tượng mới.
$ perl -we 'use DateTime; my $dt;
eval { $dt = DateTime->new(
year => 2012,
month => 2,
day => 30);
}; print "Error: [email protected]" if [email protected];'
Error: Invalid day of month (day = 30 - month = 2 - year = 2012) at -e line 1
Nó cũng làm việc năng động trên cho DateTime
đối tượng:
$dt->set(day => 30);
Có thể điều này sẽ giúp quá:
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
Bạn có thể làm điều này thông qua việc sử dụng của POSIX mktime
, nhưng dường như chỉ khi bạn có flexi thực hiện đủ máu của mktime
.
Điều tôi làm là cắm các số vào và sau đó sử dụng thời gian cục bộ để lấy lại chúng và nếu tôi nhận được cùng một giá trị ngày, thì đó là số hợp lệ. Vì vậy, với chuỗi của bạn:
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])
;
Xem, trong các phiên bản của mktime
mà tôi đang sử dụng để, mktime(0, 0, 0, 30, 1, 112)
sẽ làm cho '2012-03-01'
và 30 != 1
Bạn cũng có thể sử dụng Time::Local:
#!/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;
}
Đỗ lưu ý rằng những bài đăng đó là 6 tuổi. – TLP
Lịch có thay đổi nhiều trong 6 năm không? – Benoit
@Benoit Bạn có thể nói về mọi thứ. Đã bao nhiêu năm thay đổi nhiều từ năm 1999 đến năm 2000? Nó có lẽ không phải là một việc lớn (nó không phải là downvote của tôi) và hầu hết các mã có lẽ sẽ vẫn làm việc, nhưng nó là đáng chú ý. – TLP