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