刚才在论坛里看到一个朋友说:“这个月(2010.10)有五个星期五,五个星期六,五个星期日。听说823年才能碰一次。”
在 Google 中搜索“五个星期五,五个星期六,五个星期日”,几十页的结果,都是说 823 年才有一次。
猛一看,很稀奇。但一较真,就经不起推敲了。这个823年是怎么算来的?为什么不是 822 年或者 824 年而一定是 823 年?想想就知道:只要有一个月是大月份(31天),那么必定有三个连续的星期单位,会被重复五次。因为: 31 = 4 x 7 + 3。
而要出现 五个星期五,五个星期六,五个星期日,一点也不难,只要满足下面两个条件:
1. 当月是大月份(天数是 31 天)
2. 当月的1号,是星期五
一年中有7个大月份(1,3,5,7,8,10,12),一个星期有7天。显然,从概率上来讲,大月1号是星期五的概率,每年能出现一次,而不是 823 年才出现一次。:D
我刚写了段 php 程序验证了一下,2000年-2030年这30年来,就有29个这样的月份。其中,就在不远的过去, 2010的元月也是一个这样的月份。:)
php 代码:
<?php $t_iStartYear = 2000; $t_iEndYear = 2030; echo 'Start Year: ',$t_iStartYear,"<br>End Year: ",$t_iEndYear,"<br>"; for($t_iCount = 0, $i = $t_iStartYear; $i< $t_iEndYear; $i++) { for($j=1; $j<13; $j++) { $t_strDate = sprintf('%04d-%02d-01', $i, $j); if ( (5==date('w',strtotime($t_strDate))) && (1==$j||3==$j||5==$j||7==$j||8==$j||10==$j||12==$j)) echo '[',$t_iCount++,'] ',$t_strDate,': Friday',"<br>"; } } ?>
php 程序的输出结果:
Start Year: 2000 End Year: 2030 [0] 2000-12-01: Friday [1] 2002-03-01: Friday [2] 2003-08-01: Friday [3] 2004-10-01: Friday [4] 2005-07-01: Friday [5] 2006-12-01: Friday [6] 2008-08-01: Friday [7] 2009-05-01: Friday [8] 2010-01-01: Friday [9] 2010-10-01: Friday [10] 2011-07-01: Friday [11] 2013-03-01: Friday [12] 2014-08-01: Friday [13] 2015-05-01: Friday [14] 2016-01-01: Friday [15] 2016-07-01: Friday [16] 2017-12-01: Friday [17] 2019-03-01: Friday [18] 2020-05-01: Friday [19] 2021-01-01: Friday [20] 2021-10-01: Friday [21] 2022-07-01: Friday [22] 2023-12-01: Friday [23] 2024-03-01: Friday [24] 2025-08-01: Friday [25] 2026-05-01: Friday [26] 2027-01-01: Friday [27] 2027-10-01: Friday [28] 2028-12-01: Friday
Quote:
procedure TForm1.btn1Click(Sender: TObject); var beginYear,EndYear:Integer; j,k:Integer; begin DateSeparator := '/'; beginYear := 2000; EndYear := 2100; for j := beginYear to EndYear do begin for k := 1 to 12 do begin if (k = 1) or (k = 3) or (k = 5) or (k = 7 ) or (k = 8) or (k = 10) or (k = 12) then begin if DayOfWeek(StrToDate(IntToStr(j)+'/'+IntToStr(k)+'/01')) = 6 then mmo1.Lines.Add(IntToStr(j) + '--' + IntToStr(k)); end; end; end; end;