Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP DateTime ISO周的怪癖_Php_Datetime - Fatal编程技术网

PHP DateTime ISO周的怪癖

PHP DateTime ISO周的怪癖,php,datetime,Php,Datetime,我有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)

我有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'),
];
这个脚本在我发现的几乎所有实例中都有效

霍普韦尔,在2019年的第52周,它不再将下一周作为2020年的第1周返回,而是将下一周作为2019年的第1周返回。。。这让我在时间上倒退


我该如何解决这个问题?这种情况似乎每年都会发生,一年中有53周。

您将两种日期格式(
Y
W
)组合在一起没有意义。W是ISO周数,但Y是日历年

2020年的第一个ISO周开始于2019年12月30日,因此对于该日期,
W
返回1,但
Y
仍然指2019日历年

PHP提供了
o
date修饰符,可以用来代替代码中的
Y
,在手册中定义为:

ISO-8601周编号年份。该值与Y值相同,只是如果ISO周数(W)属于上一年或下一年,则使用该年。(在PHP 5.1.0中添加)

因此,您可以将代码更改为

$nextWeek = [
    'year' => $nextTime->format('o'),
    'week' => $nextTime->format('W'),
];

而且它应该按预期工作。

根据任务的不同,有两种不同的处理周数的方法

1. : 星期从星期一开始。每个星期的一年都是公历年 星期四就到了。因此,每年的第一周总是 包括1月4日。ISO周年编号 在接近1月1日的几天内偏离公历

这些规则可能很难手动处理,这就是为什么它是标准PHP的一部分,所以您只需使用
'week'=>$nextTime->format('W')

2019年的一天很可能属于2020年后的一周。而且很容易证明:当你打开2019/12月的日历时,你可能会注意到上周“可能与”明年的几天。为了防止重叠问题,当同一周属于不同年份但其数量不同时,例如2019年第52周与2020年第1周相同,他们决定制定一套规则:ISO。这些规则在会计中特别有用,可以防止“模糊周”

2.您只需要一个“数学”周数作为简单计数器:
z
formatter是一年中的一天(从0开始),这就是为什么我在末尾添加“+1”


尽管这看起来是一个不错的方法,但它也有一个缺点:2019年的第52周与2020年的第1周相同。

你的问题可能会更清晰!你可以问为什么
$myTime=newdatetime('2019/12/30');变量转储($myTime->format('Y-W')此代码返回的周为01,但不完美!这就是问题所在。
$nextWeek = [
    'year' => $nextTime->format('Y'),
    'week' => (int)(($nextTime->format('z')) / 7) + 1
];