【PHP8.x】checkdate関数の使い方

作成日: 更新日:

checkdate関数は、グレゴリオ暦の日付の妥当性を検証する関数です。具体的には、与えられた月、日、年が、有効な日付範囲内にあるかをチェックします。この関数は、日付に関連する処理を行う際に、入力された日付が正しいかどうかを確認するために非常に役立ちます。

checkdate関数は、monthdayyearの3つの整数型の引数を取ります。monthは月を表し、1から12の範囲である必要があります。dayは日を表し、指定された月と年における有効な日数の範囲内である必要があります。yearは年を表し、1から32767の範囲である必要があります。これらの引数が有効な範囲内にない場合、関数はfalseを返します。

例えば、checkdate(12, 31, 2023)は、2023年12月31日が有効な日付であるため、trueを返します。一方、checkdate(2, 29, 2023)は、2023年2月29日がうるう年ではないため無効な日付となり、falseを返します。

システム開発において、ユーザーからの入力データや外部データソースから取得した日付データが、アプリケーションで正しく処理できる形式であるかを検証することは重要です。checkdate関数を使用することで、無効な日付データによるエラーを未然に防ぎ、システムの信頼性を向上させることができます。日付の検証を行う際には、この関数を積極的に活用することが推奨されます。

基本的な使い方

構文(syntax)

<?php
checkdate(int $month, int $day, int $year): bool
?>

引数(parameters)

int $month, int $day, int $year

  • int $month: 確認する月を指定する整数 (1から12)
  • int $day: 確認する日を指定する整数 (1から31)
  • int $year: 確認する年を指定する整数

戻り値(return)

bool

指定された月、日、年が有効なグレゴリオ暦の日付である場合に true を返します。無効な日付の場合は false を返します。

サンプルコード

PHP checkdate バグ修正と日付検証

<?php

/**
 * checkdate() 関数の使用例と、うるう年の月末日のバグについて。
 *
 * checkdate() は、指定された日付がグレゴリオ暦で有効かどうかを検証します。
 * しかし、PHP 5.3.0 より前のバージョンには、うるう年の2月29日の月末日判定にバグがありました。
 * この例では、そのバグの修正方法と、現在のバージョンでの使用例を示します。
 */

/**
 * 日付の有効性をチェックする関数。
 *
 * @param int $month 月
 * @param int $day   日
 * @param int $year  年
 *
 * @return bool 有効な日付の場合は true、そうでない場合は false
 */
function validateDate(int $month, int $day, int $year): bool
{
    // PHP 5.3.0 より前のバージョンにおけるうるう年の月末日のバグを考慮した修正
    if ($year % 4 == 0 && ($year % 100 != 0 || $year % 400 == 0) && $month == 2) {
        $maxDay = 29; // うるう年の2月
    } elseif ($month == 2) {
        $maxDay = 28; // 平年の2月
    } elseif (in_array($month, [4, 6, 9, 11])) {
        $maxDay = 30; // 小の月
    } else {
        $maxDay = 31; // 大の月
    }

    if ($month < 1 || $month > 12 || $day < 1 || $day > $maxDay) {
        return false;
    }

    // 現在の PHP バージョンでは checkdate() で十分
    return checkdate($month, $day, $year);
}

// 使用例
$year = 2024; // うるう年
$month = 2;
$day = 29;

if (validateDate($month, $day, $year)) {
    echo "$year-$month-$day は有効な日付です。\n";
} else {
    echo "$year-$month-$day は無効な日付です。\n";
}

$year = 2023; // 平年
$month = 2;
$day = 29;

if (validateDate($month, $day, $year)) {
    echo "$year-$month-$day は有効な日付です。\n";
} else {
    echo "$year-$month-$day は無効な日付です。\n";
}

checkdate()関数は、指定された日付(月、日、年)がグレゴリオ暦において有効かどうかを判定し、結果をboolean値(trueまたはfalse)で返します。引数 $month は月、$day は日、$year は年を表す整数値を指定します。

サンプルコードでは、checkdate()関数の使用例と、PHP 5.3.0より前のバージョンに存在した、うるう年の2月29日の月末日判定に関するバグについて解説しています。

古いPHPバージョンでのバグに対応するため、validateDate()関数を定義し、うるう年の判定ロジックを実装しています。具体的には、年が4で割り切れ、かつ100で割り切れない、または400で割り切れる場合に、2月の日数を29日と判定しています。

ただし、現在のPHPバージョンでは、checkdate()関数自体が修正されているため、validateDate()関数内で最終的にcheckdate()を呼び出すことで、日付の有効性を確認しています。

サンプルコードの実行例では、うるう年である2024年2月29日と、平年である2023年2月29日をvalidateDate()関数に渡し、それぞれの日付が有効かどうかを判定しています。有効な日付の場合は「有効な日付です」、無効な日付の場合は「無効な日付です」と表示されます。このサンプルを通じて、checkdate()関数の基本的な使い方と、過去のPHPバージョンにおけるバグへの対応方法を理解することができます。

checkdate()関数は、日付の妥当性を検証する便利な関数です。引数の順序は「月、日、年」である点に注意してください。PHP 5.3.0より前のバージョンでは、うるう年の2月29日判定にバグがありましたが、現在のバージョンでは修正されています。サンプルコードでは、過去のバージョンでのバグを考慮した日付検証の代替ロジックを示していますが、現在のPHPではcheckdate()のみで十分です。validateDate()関数のように、古いバグに対応したコードが残っている場合は、PHPのバージョンを確認し、不要な処理を削除することでコードを簡潔に保てます。引数に無効な値(例えば、存在しない月や負の日付)を渡すとfalseが返ります。

PHP checkdate関数で日付を検証する

<?php

/**
 * PHPのcheckdate関数の基本的な使い方を示すサンプルコードです。
 * 指定された月、日、年の組み合わせが有効な日付であるかを判定します。
 *
 * @param int $month 月 (1から12の範囲)
 * @param int $day   日 (1から31の範囲。月の種類やうるう年によって有効な範囲は異なります)
 * @param int $year  年
 * @return void
 */
function demonstrateCheckdateUsage(int $month, int $day, int $year): void
{
    echo "--- 日付の検証: {$year}{$month}{$day}日 ---\n";

    // checkdate関数を使って日付の有効性をチェックします。
    if (checkdate($month, $day, $year)) {
        echo "  この日付は有効です。\n";
    } else {
        echo "  この日付は無効です。\n";
    }
    echo "\n";
}

// --- サンプル実行例 ---

// 例1: 有効な日付(2024年はうるう年なので2月29日は有効)
demonstrateCheckdateUsage(2, 29, 2024);

// 例2: 無効な日付(2023年はうるう年ではないので2月29日は無効)
demonstrateCheckdateUsage(2, 29, 2023);

// 例3: 有効な日付(一般的な日付)
demonstrateCheckdateUsage(12, 25, 2023);

// 例4: 無効な日付(月が範囲外: 13月)
demonstrateCheckdateUsage(13, 1, 2023);

// 例5: 無効な日付(日が範囲外: 32日)
demonstrateCheckdateUsage(1, 32, 2023);

// 例6: 無効な日付(日が0)
demonstrateCheckdateUsage(1, 0, 2023);

// 例7: 無効な日付(月が0)
demonstrateCheckdateUsage(0, 1, 2023);

PHPのcheckdate関数は、指定された月、日、年の組み合わせがカレンダー上で実際に存在する有効な日付であるかを判定します。この関数は、引数として整数で月(1から12)、日(1から31)、年をこの順に受け取ります。例えば、2月がうるう年で29日まであるか、あるいは4月が30日までといった各月の正しい日数を自動的に考慮して検証を行います。

関数は、日付が有効な場合はtrueを、無効な場合はfalseを真偽値として戻り値で返します。サンプルコードでは、2024年の2月29日が有効(うるう年)と判定される一方、2023年の2月29日は無効と判定される例が示されています。また、月が13や日が32といった日付としてありえない値の場合も、checkdate関数が正しく無効と判断する様子が確認できます。この関数を使うことで、システム開発においてユーザーからの日付入力のバリデーションなどを簡単かつ正確に行うことができます。

checkdate関数を使う際の最も重要な注意点は、引数の順番です。日本の日付表記とは異なり、「月、日、年」の順番で指定する必要があります。この順番を間違えると意図しない結果になるため注意してください。また、年は1から32767、月は1から12の整数が有効な範囲です。0や負の数など範囲外の値を与えると、日付として無効と判定されます。この関数はうるう年も自動で考慮するため、2月29日のような日付も正確に検証できます。ユーザーからの入力値を扱う際は、事前に数値かどうかを確認し、整数に変換してから使用すると、より安全なコードになります。

PHP checkdate関数:うるう年を考慮した日付チェック

<?php

/**
 * checkdate関数は、指定された年月日が有効な日付であるかをチェックします。
 * 特に、うるう年を考慮して2月の日数(28日または29日)を正しく判定します。
 *
 * 構文: checkdate(int $month, int $day, int $year): bool
 */

echo "--- checkdate関数による日付の有効性チェック ---" . PHP_EOL;
echo PHP_EOL;

// 2024年はうるう年です(4で割り切れる年)。
echo "2024年2月29日: ";
var_dump(checkdate(2, 29, 2024)); // true (うるう年なので有効)

echo "2024年2月30日: ";
var_dump(checkdate(2, 30, 2024)); // false (2月は29日まで)
echo PHP_EOL;

// 2023年は平年です(4で割り切れない年)。
echo "2023年2月29日: ";
var_dump(checkdate(2, 29, 2023)); // false (平年なので無効)

echo "2023年2月28日: ";
var_dump(checkdate(2, 28, 2023)); // true (平年なので有効)
echo PHP_EOL;

// 2000年はうるう年です(100で割り切れるが400でも割り切れる年)。
echo "2000年2月29日: ";
var_dump(checkdate(2, 29, 2000)); // true (うるう年なので有効)
echo PHP_EOL;

// 1900年は平年です(100で割り切れるが400で割り切れない年)。
echo "1900年2月29日: ";
var_dump(checkdate(2, 29, 1900)); // false (平年なので無効)
echo PHP_EOL;

// その他の日付の有効性チェック
echo "1月31日 (有効な日付): ";
var_dump(checkdate(1, 31, 2024)); // true

echo "11月31日 (無効な日付、11月は30日まで): ";
var_dump(checkdate(11, 31, 2024)); // false

echo "13月1日 (無効な月): ";
var_dump(checkdate(13, 1, 2024)); // false

echo "1月0日 (無効な日): ";
var_dump(checkdate(1, 0, 2024)); // false

PHPのcheckdate関数は、指定された年月日がカレンダー上で有効な日付であるかをチェックするための重要な機能です。この関数は、引数として整数型の月($month)、日($day)、年($year)の3つを受け取ります。そして、指定された日付が実際に存在すればtrueを、存在しない無効な日付であればfalseを真偽値(bool)として返します。

この関数の大きな特徴は、うるう年を正確に考慮して日付の有効性を判定する点です。例えば、2024年のように4で割り切れるうるう年では2月29日を有効と判断しますが、2023年のような平年では2月29日を無効と判断します。また、1900年のように100で割り切れるが400で割り切れない年は平年として扱い、2000年のように400で割り切れる年はうるう年として正しく判定します。さらに、月の範囲(1月~12月)や各月の最大日数を超えた日付、例えば11月31日や13月1日なども無効とみなします。これにより、プログラムで日付の入力や処理を行う際に、意図しない誤った日付が使われることを防ぎ、信頼性の高いシステム構築に役立ちます。

checkdate関数は、指定された年月日が実際に存在するかを厳密にチェックします。特に、グレゴリオ暦におけるうるう年のルール(例:2月29日が存在するか)を正確に考慮して判定します。月の値は1から12、日の値はその月の最大日数内(1から開始)、そして年が妥当な範囲内にあるかを検証します。不正な月や日、存在しない日付(例:11月31日、2月30日など)に対してはfalseを返すため、ユーザーからの日付入力をプログラムで安全に扱う際の必須のチェックとして活用できます。

PHPのcheckdate関数で日付文字列を検証する

<?php

/**
 * 指定された日付文字列が有効な日付であるかをチェックします。
 *
 * この関数は、日付文字列(例: "YYYY-MM-DD"形式)を解析し、
 * PHPのcheckdate関数を使用して日付の妥当性を検証します。
 * checkdateは、月の範囲(1-12)、日の範囲(1-31)、年の範囲(1-32767)を正確にチェックし、
 * うるう年における2月の日数も考慮します。
 *
 * @param string $dateString 検証する日付文字列(例: "2023-01-31")
 * @return bool 有効な日付であれば true、そうでなければ false を返します。
 */
function validateDateString(string $dateString): bool
{
    // 日付文字列をハイフン (-) で分割します。
    // 例: "2023-01-31" は ["2023", "01", "31"] となります。
    $parts = explode('-', $dateString);

    // 分割された要素が3つ(年、月、日)でなければ、不正な形式と見なします。
    if (count($parts) !== 3) {
        return false;
    }

    // 各部分を整数に変換します。
    // PHPのcheckdate関数は引数の順序が (月, 日, 年) であることに注意してください。
    $year = (int) $parts[0];
    $month = (int) $parts[1];
    $day = (int) $parts[2];

    // checkdate関数を呼び出して日付の妥当性を検証します。
    return checkdate($month, $day, $year);
}

// --- サンプルコードの実行例 ---

// 有効な日付のチェック
$validDate1 = "2023-01-31";
if (validateDateString($validDate1)) {
    echo "日付 '" . $validDate1 . "' は有効です。\n";
} else {
    echo "日付 '" . $validDate1 . "' は無効です。\n";
}

$validDate2 = "2024-02-29"; // 2024年はうるう年なので2月29日は有効
if (validateDateString($validDate2)) {
    echo "日付 '" . $validDate2 . "' は有効です。\n";
} else {
    echo "日付 '" . $validDate2 . "' は無効です。\n";
}

// 無効な日付のチェック
$invalidDate1 = "2023-02-29"; // 2023年はうるう年ではないので2月29日は無効
if (validateDateString($invalidDate1)) {
    echo "日付 '" . $invalidDate1 . "' は有効です。\n";
} else {
    echo "日付 '" . $invalidDate1 . "' は無効です。\n";
}

$invalidDate2 = "2023-13-01"; // 月が1から12の範囲外なので無効
if (validateDateString($invalidDate2)) {
    echo "日付 '" . $invalidDate2 . "' は有効です。\n";
} else {
    echo "日付 '" . $invalidDate2 . "' は無効です。\n";
}

$invalidDate3 = "2023-01-32"; // 日がその月の範囲外なので無効
if (validateDateString($invalidDate3)) {
    echo "日付 '" . $invalidDate3 . "' は有効です。\n";
} else {
    echo "日付 '" . $invalidDate3 . "' は無効です。\n";
}

$invalidDate4 = "不正な形式の文字列"; // 日付形式に合わない文字列なので無効
if (validateDateString($invalidDate4)) {
    echo "日付 '" . $invalidDate4 . "' は有効です。\n";
} else {
    echo "日付 '" . $invalidDate4 . "' は無効です。\n";
}

$invalidDate5 = "2023/01/01"; // ハイフン区切りではないので無効
if (validateDateString($invalidDate5)) {
    echo "日付 '" . $invalidDate5 . "' は有効です。\n";
} else {
    echo "日付 '" . $invalidDate5 . "' は無効です。\n";
}

PHPのcheckdate関数は、与えられた月、日、年の値がカレンダー上で有効な日付であるかを厳密に確認する関数です。この関数は、引数として整数型の$month(1〜12)、$day(1〜31)、$year(1〜32767)をこの順で受け取ります。そして、月の正しい範囲、日と月の組み合わせ(例: 30日しかない月や31日、2月の日数)、うるう年を正確に考慮して検証を行います。検証結果は真偽値で返され、有効な日付であればtrue、そうでなければfalseとなります。

サンプルコードでは、checkdate関数をより実用的に利用するため、"YYYY-MM-DD"形式の日付文字列を検証するカスタム関数validateDateStringが実装されています。この関数は、まず引数で受け取った日付文字列をハイフンで年、月、日に分割します。その後、各部分を整数型に変換し、変換した月、日、年の順でcheckdate関数に渡して妥当性を確認しています。例えば、"2023-01-31"やうるう年の"2024-02-29"は有効と判定されますが、"2023-02-29"(2023年はうるう年ではない)、"2023-13-01"(月が範囲外)、"2023-01-32"(日が範囲外)、また"不正な形式の文字列"などは無効と判定される様子が示されており、日付入力の正確なバリデーションに役立ちます。

PHPのcheckdate関数は、引数の順序が月、日、年の順であることに特に注意が必要です。一般的な日付の並びと異なるため、誤って年、月、日の順で渡さないようにしてください。サンプルコードのvalidateDateString関数は、YYYY-MM-DD形式の文字列日付を検証するために作られています。そのため、この関数を利用する際は、入力される日付文字列が必ずハイフン区切りのこの形式であることを前提としてください。スラッシュ区切りなど、他の形式の日付文字列を検証する場合には、コードを修正するか、PHPのDateTimeクラスなど、より汎用的な日付処理機能の利用を検討することが安全かつ推奨されます。文字列から数値への変換や、文字列の形式チェックは、checkdate関数へ渡す前の重要な前処理となります。

【PHP8.x】checkdate関数の使い方 | いっしー@Webエンジニア