Php Euler项目19代码似乎是正确的。我错过了什么?

Php Euler项目19代码似乎是正确的。我错过了什么?,php,Php,问题19: <?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 .

问题19:

<?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>";
?>
您将获得以下信息,但您可能更愿意这样做 自己研究

1900年1月1日是星期一

三十天有九月、四月、六月和九月 十一月

除二月外,其余的都有三十一个 无论晴雨,他都有二十八岁。闰年是29岁

闰年发生在可以被4整除的任何一年,但不是在一年中 除非它能被400整除

在二十世纪(1901年1月1日至2000年12月31日),有多少个星期日是在月的第一天?

我认为使用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>";
?>
然后,我使用@MadaraUchiha的代码生成一个包含171个正确日期的数组

在比较了他的日期和我的日期后,以下是错过的两个日期:

1901-09-01 1901-12-01

编辑3

这些日期不是星期天(但它们确实应该是)

我确信这些日期被正确地解释为YYYY-MM-DD,因为我的代码提供给解决方案的其中一个日期是2000-10-01,如果10是月,而不是日,则该日期只能是星期日

编辑4

因此,显然,如果在32位系统上,Unix时间戳不会超出范围:

Tue, 19 Jan 2038 03:14:07 GMT

通过使用DateTime对象,我得到了171(更短、可读性更强)代码:


使用DateTime对象时,您将日期视为日期,而不是数字字符串。与其他任何方法相比,这给了您巨大的灵活性优势。

它在某些使用时间戳的系统上可能不起作用的原因是,在32位系统上,Unix时间戳的范围是从1901年12月13日星期五20:45:54 GMT到2038年1月19日星期二03:14:07 GMT,因此您几乎错过了第一年的所有月份


64位系统有更大的整数,这使得范围更大(在PHP中)。

这段代码的问题是行

$date=$month。"/1/" . $年份

这应该是

$date=“1/”$month./”$年份


您混合了月份和天数的位置。

这可能与以下注释有关:“在5.2.7之前的PHP 5中,如果请求某个月内某个给定工作日的某个给定事件,而该工作日是该月的第一天,则会错误地将一周添加到返回的时间戳中。这已在5.2.7及更高版本中得到更正。”?我运行的是PHP版本5.3.10,所以我怀疑它是另外一个版本。事实证明,这与PHP完全无关。正是20世纪的定义引起了混乱。请参阅关于线程的讨论。但是,我想知道人们是怎么得到171的。维基百科对范围的定义不同。ProjEuler可能使用了一个定义和不同的答案。@goldenparrot其实并不含糊。原始问题说明日期范围:1901年1月1日至2000年12月31日。也许我误解了你所说的“困惑”是什么意思?我放弃了。即使是从1900年到2000年的数字也显示出169.Hi。谢谢您的代码在我的系统上也运行良好。然而,我很好奇你是否能告诉我为什么在我的代码中2个月看起来是“跳过的”?干杯。这似乎涵盖了两次约会。Apache在我的系统上运行64位。这就是您所说的64位系统吗?请检查
PHP\u INT\u MAX
。在我的64位系统上是
9223372036854775807
。在我的系统上,PHP_INT_MAX是2147483647。我想这就是我一直在寻找的答案!
Tue, 19 Jan 2038 03:14:07 GMT
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";