【PHP/演習問題】関数と戻り値[5]

【PHP/演習問題】関数と戻り値[5]

問題

日付の曜日を出力するプログラムを作成してください。
なお、下記条件を満たすものとします。

  • 年、月、日はコマンドライン引数で与える
    ※ 年は1873以上で与えられるものとします(暦の関係上)
    ※ 1873年1月1日は水曜日(We)です
  • 閏年判定のアルゴリズムはグレゴリオ暦に従う
  • 曜日は英語で出力する
    日 → Su
    月 → Mo
    火 → Tu
    水 → We
    木 → Th
    金 → Fr
    土 → Sa
  • 曜日を求めるday_of_week関数を作成する
    引数:年、月、日
    戻り値:曜日を示す値
    → 日(0)/ 月(1)/ 火(2)/ 水(3)/ 木(4)/ 金(5)/ 土(6)
$ php practice.php 2022 1 1
2022年1月1日 : Sa
$ php practice.php 2024 2 29
2024年2月29日 : Th
$ php practice.php 2027 7 12
2027年7月12日 : Mo
$ php practice.php 2029 2 28
2029年2月28日 : We

解答例

<?php

function is_leap_year( $year ) {
    
    if( $year % 4 == 0 && ( $year % 100 != 0 || $year % 400 == 0 ) ) {
        return true;
    }
    
    return false;
}

function days_in_year( $year ) {
    
    $days = 365;
    if( is_leap_year($year) ) $days = 366;
    
    return $days;
}

function last_day_of_month( $year, $month ) {
    
    $last_day_map = [
        1 => 31, 2 => 28, 3 => 31, 4 => 30, 5 => 31, 6 => 30,
        7 => 31, 8 => 31, 9 => 30, 10 => 31, 11 => 30, 12 => 31,
    ];
    
    $last_day = $last_day_map[$month];
    if( is_leap_year($year) && $month == 2 ) $last_day = 29;
    
    return $last_day;
}

function day_of_week( $year, $month, $day ) {
    
    $days_elapsed = 0;
    for( $i = 1873; $i < $year; $i++ ) {
        $days_elapsed += days_in_year($i);
    }
    for( $i = 1; $i < $month; $i++ ) {
        $days_elapsed += last_day_of_month($year, $i);
    }
    $days_elapsed += $day;
    
    return ( $days_elapsed + 2 ) % 7;
}

$year = $argv[1];
$month = $argv[2];
$day = $argv[3];

$last_day = day_of_week($year, $month, $day);
$dws = [
    'Su','Mo','Tu','We','Th','Fr','Sa',
];

echo $year.'年'.$month.'月'.$day.'日 : '.$dws[$last_day]."\n";

?>