我有3个值:
$timezone = new \DateTimeZone('America/New_York');
$year = 2019;
$week = 52;
然后我接受这3个值并通过脚本运行它:
$nowTime = new \DateTime('now', $timezone);
$currTime = clone $nowTime;
$currTime->setISODate($year, $week, 1);
$currTime->setTime(0,0,0);
如您所见,我将当前时间设定为2019年第52周的开始。
然后我试图获取下周的信息。
$nextTime = clone $currTime;
$nextTime->modify('+1 week');
$nextWeek = [
'year' => $nextTime->format('Y'),
'week' => $nextTime->format('W'),
];
这个脚本几乎适用于我找到的所有实例......
Hopever,在2019年的第52周,而不是在2020年作为第1周返回下一周,它将在2019年的第1周返回下一周......这使我及时向后退。
我该如何解决这个问题?这似乎发生在每年有53周的每年。
答案 0 :(得分:1)
您将两种日期格式(Y
和W
)组合在一起。 W是ISO周数,但Y是日历年。
2020年的第一个ISO周开始于 2019年12月30日,因此在该日期,W
返回1,但Y
仍然指日历年2019年。
PHP提供了o
日期修饰符,可用于代替代码中的Y
,在手册中定义为:
ISO-8601周编号年份。它具有与Y相同的值,除了如果ISO周数(W)属于上一年或下一年,则使用该年代。 (在PHP 5.1.0中添加)
因此您可以将代码更改为
$nextWeek = [
'year' => $nextTime->format('o'),
'week' => $nextTime->format('W'),
];
它应该按预期工作。
答案 1 :(得分:0)
根据任务的不同,有两种不同的方式可以处理周数。
周从星期一开始。每个星期都是格里高利年 星期四下降。因此,一年中的第一周 包含1月4日。因此ISO周年编号略有增加 在接近1月1日的某些日子里偏离了格里高利。
这些规则可能难以手动处理,这就是它成为标准PHP的一部分的原因,因此您只需使用'week' => $nextTime->format('W')
2019年的某一天确实可能属于2020年的一周。而且很容易证明:当你打开2019年/ 12月的日历时,你可能会注意到上周的情况。可以分享"从明年开始。为了防止重叠问题,当同一周属于不同年份但其数量不同时,例如, 2019年的第52周与2020年的第1周相同,他们决定制定一套规则:ISO。这些规则在会计中特别有用,可以防止"含糊不清的周数。
$nextWeek = [
'year' => $nextTime->format('Y'),
'week' => (int)(($nextTime->format('z')) / 7) + 1
];
z
格式化程序一年中的某一天(从0开始)这就是为什么我要添加" + 1"最后。
尽管它看起来可能是一种好方法,但它有一个缺点:2019年的第52周与2020年的第1周相同。