【问题标题】:How to get year-sensitive calendar week ? date("W") gives back 52 for 1st of January如何获得对年份敏感的日历周? date("W") 在 1 月 1 日返回 52
【发布时间】:2012-07-26 13:48:29
【问题描述】:

正如标题所说,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 周。wikipedia article

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

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

【问题讨论】:

  • INFO:“一周的开始”因文化和国家/地区而异。例如,在北美,一周从星期日 (!) 开始。你们这些美国人到底怎么了,这周根本不是从星期日开始的? ;) Afaik 还有一些国家将星期三定义为“一周的第一天”。
  • 顺便说一句,一个类似的问题现在是 PHP 日期文档页面上投票率最高的评论php.net/manual/de/function.date.php#106974

标签: php date week-number


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    不,没有。

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

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

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

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

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

    ISO 8601 没有定义第 0 周。

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

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

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

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

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

    【讨论】:

    • 好吧,你只是重复了我说的话。 2012 年 1 月 1 日可能是第 52 周(2011 年),但它在几乎所有财务或技术计算中都完全没用。这就是为什么我要求 DATE() 的年份敏感版本。我没有说 date() 不正确。更清楚问题是什么:如果你得到一年中每一天的星期,你会遇到严重的麻烦,因为 1 月 1 日和 12 月 31 日都在“第 52 周”。
    • 顺便说一句:请不要再相信维基百科所说的每一行!这只是一个公共网站,每个人都可以复制/粘贴所有内容。维基百科不是官方来源。并且英文网站的内容不等于所有其他语言和国家。例如,一周有不同的财务定义,在“英寸”国家,它从星期日开始,afaik。
    • "我没有说 date() 不正确。"好吧,您说过,“PHP 的日期(“W”)在 2012 年 1 月 1 日返回 52,这是“错误的”。它应该是 0 或 null。但这并没有错,也没有“错”。它根据国际标准正确执行其记录的行为。 (耸肩)
    • "如果你得到一年中每一天的星期,你会遇到严重的麻烦,因为 1 月 1 日和 12 月 31 日都在 '第 52 周'。"这是否麻烦完全取决于应用程序。显然它正在困扰您的应用程序,因此您可能应该编写一个函数(或将数据存储在表中)来代替date("W")
    【解决方案3】:
    $d = new DateTime('first monday january '.date('Y'));
    echo $d->format("W");
    

    【讨论】:

    • 抱歉,这不是我要搜索的内容。
    • 是的,这会返回一年中第一个星期一的星期,这总是第 1 周。我正在寻找一个函数,它可以返回 2012 年第一天的正确星期(其中将是 0 或 null,而不是 52)
    • 我从未听说过“第 0”周数,“第 1”对我来说似乎是正确的。
    • @Panique - 该函数应该返回 0/null 直到一周/星期一开始?
    • @nickb ;) 我重写了这个问题。 2012 年 1 月 1 日不是第 52 周,但 date("W") 是这样说的。我应该是第 0 周或 null,因为 2012 年的第一周从 1 月 2 日星期一开始。这是定义日历周的官方方式,至少在大多数国家/地区(美国和英国除外)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-08
    • 1970-01-01
    • 2020-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多