8

正如标题所说,PHP 的 date("W") 函数返回日历周(当天)。不幸的是,它在大多数年份的第一天返回 52 或 53。以简单的思维方式,这是正确的,但非常烦人,因为 2012 年 1 月 1 日不是日历周 52,它不是当年的日历周。大多数日历将其定义为上一年的第 0 周或第 52 周。

当您按日历周对一年中的每一天进行分组时,这非常棘手:2012 年 1 月 1 日和 2012 年 12 月 31 日都放在同一个日历周组中。

所以我的问题是:PHP 的 date("W") 是否有(本机)年份敏感的替代方案?

编辑:我想我以一种非常不清楚的方式写了这个问题的第一个版本,所以这是我的编辑:我正在寻找一个函数,它可以在一年的第一天返回正确的日历周。PHP 的 date("W") 在 2012 年 1 月 1 日返回 52,这是“错误的”。它应该为 0 或 null。根据官方消息,一年中的第一个日历周从一年的第一个星期一开始。所以,如果一年的第一天不是星期一,那就不是第一周!这是第 0 周。维基百科的文章

如果 1 月 1 日在星期一、星期二、星期三或星期四,则在第 01 周。如果 1 月 1 日在星期五、星期六或星期日,则在上一年的第 52 周或第 53 周。

这变得很棘手,因为一年中的最后几天也在第 52/53 周。date("W") 不分为当年和上年。

4

3 回答 3

11

此解决方案将 12 月的多余部分转换为第 53 周,并将第 1 周之前的 1 月的所有部分转换为第 0 周。

$w=(int)date('W');
$m=(int)date('n');
$w=$w==1?($m==12?53:1):($w>=51?($m==1?0:$w):$w);

echo "week $w in ".date('Y');

2013-12-31 ==> 2013 年第 53 周

2014-01-01 ==> 2014 年第 1 周

2015-12-31 ==> 2015 年第 52 周

2016-01-01 ==> 2016 年第 0 周

和一个小测试运行,所以你可以自己看看;-)

$id=array(25,26,27,28,29,30,31,1,2,3,4,5,6,7,8);        
for($iy=2013;$iy<2067;++$iy){foreach($id as $k=>$v){if($k<7){$im=12;}else{$im=1;}
if($k==7){++$iy;echo '====<br>';}$tme=strtotime("$im/$v/$iy");
echo date('d-m-Y',$tme),'  * *  ';
//THE ACTUAL CODE =================
    $w=(int)date('W',$tme);
    $m=(int)date('n',$tme);
    $w=$w==1?($m==12?53:1):($w>=51?($m==1?0:$w):$w);
//THE ACTUAL CODE =================
echo '<b>WEEK: ',$w,' --- ','YEAR: ',date('Y',$tme),'</b><br>';}--$iy;
echo '----------------------------------<br>';}
于 2013-12-30T16:42:43.267 回答
2

PHP 的 date("W") 是否有(本机)年份敏感的替代方案?

不,没有。

根据官方消息,一年中的第一个日历周从一年的第一个星期一开始。

我不确定你指的是什么官方消息来源。

PHPdate("W")根据 ISO 8601 返回星期数。作为国际标准,ISO 8601 可能是许多“官方来源”之一。如果它对周数的定义不适合您的应用程序,您可以随意使用您喜欢的任何其他内容。

如果您使用“一年中的第一周”的非标准定义,或者如果您使用未被广泛认可的官方来源,则预计必须编写自己的函数来替换date("W"). (我很确定您需要编写一个函数。)

日期 2012-01-01 是星期日。ISO 8601、Wikipedia和 php 同意 2012-01-01 的 ISO 周数为 52。

ISO 8601 没有定义第 0 周。

所以,如果一年的第一天不是星期一,那就不是第一周!

ISO 和维基百科都没有这么说。ISO 8601 将第 1 周定义为包含一年中第一个星期四的那一周。对于 2012 年,第一个星期四是 1 月 5 日,因此第 1 周是 1 月 2 日至 1 月 8 日。2012-01-01 是上一年的最后一周,就 ISO 周而言。

如果你想要不同的东西,你可以玩算术、除法等等。(例如,尝试将 date("z") 除以 7。)或者您可以将这些数据存储在数据库中,并以您喜欢的方式安排您的星期。

如果您正在处理会计期间,我几乎肯定会将这些数据存储在数据库的表中。使用电子表格生成此类数据非常容易。

表格中的数据文本比 php 函数的文本更容易审计,无论该函数多么简单。对于任何访问它的程序,数据肯定是相同的,无论它是用什么语言编写的。(因此,如果有一天你的数据库有用 5 种不同语言编写的程序访问它,你不必编写、测试、并维护 5 个不同的函数来获取周数。)

于 2012-08-01T16:06:13.493 回答
1
$d = new DateTime('first monday january '.date('Y'));
echo $d->format("W");
于 2012-07-26T13:57:49.267 回答