1. Perl
  2. Date/Time

Determine if the date exists

To easily determine if a date exists, use the Time::Local module.

The timelocal function of Time::Local is a function that converts the specified date to the elapsed seconds from the epoch, but throws an exception if a date that does not exist is specified.

By using this, it is possible to determine the existing date.

use strict;
use warnings;

use Time::Local 'timelocal';

print "(1) Check if the date exists.\n";
# Perl treats the time as the number of years since 1900
# Draw 1900.
my $year = 2008 -1900;

# The month starts from 0, so subtract 1 from the month you want to find.
my $mon = 10 - 1;

# There should be no such day.
my $mday = 32;

# If you specify a day that does not exist, an exception will be thrown, so catch it with eval
eval {
  timelocal (0, 0, 0, $mday, $mon, $year);
};

# Restore
$year += 1900;
$mon ++;

# $@Is set when an exception occurs.
if ($@) {
  print "$year year $mon month $mday day does not exist.\n\n";
}
else {
  print "$year year $mon month $mday day exists.\n\n";
}


print "(2) Make date judgment a function.\n";
if (day_exist ($year, $mon, $mday)) {
  print "$year year $mon month $mday day exists.\n";
}
else {
  print "$year year $mon month $mday day does not exist.\n";
}

# Function to determine if a date exists
sub day_exist {
  my ($year, $mon, $mday) = @_;
  $year-= 1900;
  $mon-;
    
  require Time::Local;
  eval {
    Time::Local::timelocal (0, 0, 0, $mday, $mon, $year);
  };
  return $@? 0: 1;
}

(Reference) eval

Check if the date exists.

Notes on handling dates

Perl's builtin functions treat years as the number of years since 1900. The month starts from 0, such as 0 in January and 1 in February.

You need to take this into account when passing arguments to the timelocal function of the Time::Local module.

# Perl treats the time as the number of years since 1900
# Draw 1900.
my $year = 2008 -1900;

# The month starts from 0, so subtract 1 from the month you want to find.
my $mon = 10 - 1;

# There should be no such day.
my $mday = 32;

Determine if the date exists

Use the timelocal function of the Time::Local module to determine the date.

Since the arguments of the timelocal function must be specified in the order of "seconds, minutes, hours, days, months, and years", 0 is passed as a dummy for seconds, minutes, and hours.

If the date does not exist, the timelocal function throws an exception, so catch it with eval. If an exception occurs, the content will be set in $@, so the judgment will be made with this.

use Time::Local 'timelocal';
eval {
  timelocal (0, 0, 0, $mday, $mon, $year);
};

if ($@) {
  print "$year year $mon month $mday day does not exist.\n\n";
}
else {
  print "$year year $mon month $mday day exists.\n\n";
}

Create a function to determine if a date exists.

Since the judgment method is quite complicated as described above, it is convenient to create a date judgment function that can specify the argument by "year/month/day".

sub day_exist {
  my ($year, $mon, $mday) = @_;
  $year-= 1900;
  $mon-;
    
  require Time::Local;
  eval {
    Time::Local::timelocal (0, 0, 0, $mday, $mon, $year);
  };
  return $@? 0: 1;
}

Related Informatrion