如何获得对年份敏感的日历周?date(“W”) 为 1 月 1 日返回 52


How to get year-sensitive calendar week ? date("W") gives back 52 for 1st of January

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

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

所以我的问题是:是否有一个(本地(年份敏感的替代PHP的日期("W"(?

编辑:我想我以一种

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

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

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

此解决方案将 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>';}

是否有一个(本地(年份敏感的替代PHP的日期("W"(?

不,没有。

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

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

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

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

2012-01-01的日期是星期日。ISO 8601、维基百科和 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 周而言。

如果你想要不同的东西,你可以玩算术、除法等。(例如,尝试将日期("z"(除以 7。或者,您可以将该数据存储在数据库中,并以您喜欢的任何方式度过您的几周。

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

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

$d = new DateTime('first monday january '.date('Y'));
echo $d->format("W");

谷歌把我带到这里,我想发布以下内容来帮助像我这样的人......

我在美国,使用DayPilot,它的工作原理如下:

  1. 一周从周日开始,而不是周一。
  2. 1 月 1 日始终是第 1 周。
  3. 如果 1 月 1 日不是星期日,则第 1 周少于 7 天。

这一切对我来说都很重要!

这是我复制该行为的 PHP 函数:

      function ProperWeekNum($inDate)
       {$outNum = $inDate->format('W');
        //Make week start on Sunday
        if ($inDate->format('D') == 'Sun') {$outNum++;}
        //Fix begining of year 
        if (($outNum >= 52) && ($inDate->format('M') == 'Jan')) {$outNum = 1;}
        //Fix WEEK #1 is 1-day (Sat)
        else //...without this 2022 was off by 1 all year
         {$jan1st = new DateTime($inDate->format('Y').'-01-01');
          if ($jan1st->format('D') == 'Sat') {$outNum++;}
         }
        //Return without leading zero
        return ltrim($outNum, '0');
       }

我按如下方式使用该功能,因此当我单击DayPilot时,我的自定义弹出窗口的周#始终与DayPilot的周#匹配:

      $weeknum = ProperWeekNum($startdate);
      if ($weeknum != ProperWeekNum($enddate))
         {$weeknum .= '-'.ProperWeekNum($enddate);}

可能不会帮助 OP,但希望它能帮助某人。