Validate PHP Dates and Leap Years Using checkdate()

In PHP, validating a calendar date to ensure it is accurate—especially when accounting for leap years—is a fundamental task for developers. This article explains how to use the built-in PHP checkdate() function to easily verify month, day, and year combinations, ensuring that invalid dates like February 29th on non-leap years are correctly flagged as invalid.

Understanding the checkdate() Function

PHP provides a native function called checkdate() specifically designed to validate Gregorian dates. The function automatically handles the varying number of days in each month and accurately accounts for leap years.

Syntax

checkdate(int $month, int $day, int $year): bool

The function accepts three arguments: * $month: The month of the date (must be an integer between 1 and 12). * $day: The day of the date (must be an integer within the valid range for the specified month). * $year: The year of the date (must be an integer between 1 and 32767).

The function returns true if the date is valid, and false if it is not.

How checkdate() Handles Leap Years

A major benefit of checkdate() is its built-in leap year logic. You do not need to write custom algorithms to check if a year is divisible by 4, 100, or 400. The function automatically recognizes that February has 29 days in a leap year and only 28 days in a standard year.

Code Example

Here is a practical PHP script demonstrating how checkdate() handles regular dates, leap years, and non-leap years:

<?php

// 1. Validating a standard correct date (July 15, 2023)
$isValidStandard = checkdate(7, 15, 2023); 
var_dump($isValidStandard); // Returns: bool(true)

// 2. Validating February 29th on a Leap Year (2024)
$isValidLeapYear = checkdate(2, 29, 2024); 
var_dump($isValidLeapYear); // Returns: bool(true)

// 3. Validating February 29th on a Non-Leap Year (2023)
$isInvalidLeapYear = checkdate(2, 29, 2023); 
var_dump($isInvalidLeapYear); // Returns: bool(false)

// 4. Validating an impossible date (April 31, 2023)
$isInvalidDate = checkdate(4, 31, 2023); 
var_dump($isInvalidDate); // Returns: bool(false)

?>

Creating a Reusable Validation Function

When processing user input (such as date strings from a form), you often need to split the input before passing it to checkdate(). Below is a helper function that takes a date string in YYYY-MM-DD format and validates it:

<?php

function validateDateString(string $dateString): bool {
    // Expected format: YYYY-MM-DD
    $parts = explode('-', $dateString);
    
    if (count($parts) !== 3) {
        return false;
    }
    
    $year = (int)$parts[0];
    $month = (int)$parts[1];
    $day = (int)$parts[2];
    
    return checkdate($month, $day, $year);
}

// Usage examples:
var_dump(validateDateString('2024-02-29')); // true (Leap Year)
var_dump(validateDateString('2025-02-29')); // false (Non-Leap Year)
var_dump(validateDateString('invalid-date-format')); // false