8

問題 19:

次の情報が提供されますが、自分で調査することをお勧めします。

1900 年 1 月 1 日は月曜日でした。

30 日間には、9 月、4 月、6 月、11 月があります。

残りはすべて 31 で、2 月だけを保存します。これには 28 があります。そしてうるう年には、29。

閏年は 4 で割り切れる年に発生しますが、400 で割り切れない世紀には発生しません。

20 世紀 (1901 年 1 月 1 日から 2000 年 12 月 31 日まで) の月の最初の日曜日は何回ありましたか?

PHPには非常に多くの組み込みの時刻と日付関数があるため、これにPHPを使用するのは簡単だと思いました。私のコードは非常に単純なので、自分が何をしているのかが間違っていることを理解するのに苦労しています。

私のコード:

<?php
    echo "<pre>";
    $sunday_count = 0;
    for( $year = 1901; $year <= 2000; $year++ ) {
        for( $month = 1; $month <= 12; $month++ ) {
            // Produces a date in format: 1/1/2000
            $date = $month . "/1/" . $year;
            $time = strtotime( $date );
            $is_sunday = ( date( 'l', $time ) == "Sunday" );
            echo "$date "
               . ( $is_sunday ? 'was a Sunday. ' : '' )
               . "<br>";
            if( $is_sunday ) $sunday_count++;
        }
    }
    echo "Answer: $sunday_count";
    echo "</pre>";
?>

私のコードが思いつく解決策は 169 ですが、これは正しくありません。何か案が?

編集 1

解は 171 になるはずです。

Wolfram Alpha と私の Windows クロックを使用して、私のコードが報告する日曜日のいくつかを二重にチェックしました。全部チェックアウトOK。

したがって、私のコードは有効で正当な日曜日を報告しているように見えますが、どういうわけかそのうちの 2 つを見逃しています。

編集 2

コードの日付の書式設定に次の小さな変更を加えました。

$date = sprintf('%d-%02d-01', $year, $month); // formats yyyy-mm-dd

次に @MadaraUchiha のコードを使用して、171 の正しい日付を含む配列を生成しました。

彼の日付と私の日付を比較した後、これらは2つの逃した日付です:

1901-09-01 1901-12-01

編集 3

Codepad は、これらの日付が日曜日ではないことも示しています (実際には日曜日であるべきです)。

そして、私のコードがソリューションに提供する日付の 1 つが 2000-10-01 であるため、日付が正しく YYYY-MM-DD として解釈されていると確信しています。これは、10 が日ではなく月の場合にのみ日曜日になります.

編集 4

したがって、明らかに 32 ビット システムでは、Unix タイムスタンプは範囲外では機能しません。

Fri, 13 Dec 1901 20:45:54 GMT

Tue, 19 Jan 2038 03:14:07 GMT
4

3 に答える 3

4

タイムスタンプを使用する一部のシステムで機能しない理由は、32 ビット システムでの Unix タイムスタンプの範囲が からFri, 13 Dec 1901 20:45:54 GMTまでTue, 19 Jan 2038 03:14:07 GMTであるため、最初の年のほぼすべての月を見逃してしまうからです。

64 ビット システムでは整数が大きくなり、範囲が大きくなります (PHP の場合)。

于 2012-11-07T05:34:52.687 に答える
2

DateTime オブジェクトを使用して、この (はるかに短く、より読みやすい) コードで 171 を取得します。

header("Content-type: text/plain"); //Browser display

$time = new DateTime("1901-01-01");
$end = new DateTime("2000-12-31");

$counter = 0;

while (!$time->diff($end)->invert) { //$time isn't greater than $end
    $time->modify("+1 month");
    if ($time->format("l") == "Sunday") {
        $counter++;
        echo $time->format("Y-m-d") . " was a Sunday!\n";
    }
}

echo "\nTotal number of Sundays: $counter";

DateTime オブジェクトを使用する場合、日付を数値文字列としてではなく、日付として扱います。これにより、他のどのアプローチよりも柔軟性が大幅に向上します。

于 2012-11-06T22:39:47.430 に答える
0

このコードの問題は次の行です

$date = $month . "/1/" . $year;

これはあるべきです

$date = "1/".$month."/" . $year;

あなたは月と日の場所を混ぜました。

于 2015-03-07T09:43:38.620 に答える