【日付セット】> 次の日 (paizaランク C 相当) [難易度: 1576 ±17]
※リンク先へ移動するためには[paiza]へのログインが必要です。
西暦y年m月d日の次の日を表示してください。
ただし、各月の日数は以下のように決まることに注意してください。
・4, 6, 9, 11月は30日
・2月は閏年ならば29日、そうでなければ28日
・それ以外の月は31日
ただし、閏年は次のような年のことをいいます。
・西暦が4で割り切れる年は閏年
・ただし、100で割り切れる年は平年
・ただし、400で割り切れる年は閏年
入力値(例)
2019 4 4
出力値(例)
2019 4 5
解答例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<?php list($y, $m, $d) = explode(" ", trim(fgets(STDIN))); if ($y % 4 == 0 && ($y % 100 != 0 || $y % 400 == 0) && $m == 2 && $d == 29) { printf("%d %d %d", $y, 3, 1); } else { if (($m == 4 || $m == 6 || $m == 9 || $m == 11) && $d == 30) { printf("%d %d %d", $y, $m+1, 1); } elseif ($m == 2 && $d == 28) { printf("%d %d %d", $y, 3, 1); } elseif ($m == 12 && $d == 31) { printf("%d %d %d", $y+1, 1, 1); } elseif ($d == 31) { printf("%d %d %d", $y, $m+1, 1); } else { printf("%d %d %d", $y, $m, $d+1); } } ?> |
別解(公式の解答をPHPに変換)
どうしても、ifでちまちま分岐しているのが納得いかなくて、公式の解答(C++)を参考に作ってみました。年末か月末で条件分岐していてすっきりしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<?php list($y, $m, $d) = explode(" ", trim(fgets(STDIN))); function isleap($y) { return ($y % 4 == 0 && $y % 100 != 0) || $y % 400 == 0; } if ($m == 12 && $d == 31) { printf("%d %d %d", $y+1, 1, 1); } else { $days_of_month = array(0, 31, isleap($y) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); $end_of_month = $days_of_month[$m] == $d; if ($end_of_month) { printf("%d %d %d", $y, $m+1, 1); } else { printf("%d %d %d", $y, $m, $d+1); } } ?> |