pgee70
pgee70

Reputation: 4004

PHP, date not displaying 53rd week in date format

php -v
PHP 7.3.11 (cli) (built: Oct 30 2019 17:24:42) ( NTS )

i am trying to understand and issue i have with dates:

$dt = new DateTime('2019-01-01 02:31:13', new DateTimeZone('UTC'));
echo $dt->format('YW'); // expect 201901 get 201901

$dt = new DateTime('2019-12-30 02:31:13', new DateTimeZone('UTC'));
echo $dt->format('D');  // Mon 
echo $dt->format('YW'); // expect 201953 get 201901

$dt = new DateTime('2018-12-20 0:0:0', new DateTimeZone('UTC'));
for($i = 0 ; $i < 400; $i++){
  echo $dt->format('Y-m-d YW')."\n";
  $dt->modify('+1 day');
}


output:
2018-12-20 201851
2018-12-21 201851
2018-12-22 201851
...
2019-12-25 201952
2019-12-26 201952
2019-12-27 201952
2019-12-28 201952
2019-12-29 201952
2019-12-30 201901  // don't understand this...
2019-12-31 201901  // don't understand this...
2020-01-01 202001
2020-01-02 202001
2020-01-03 202001
2020-01-04 202001
2020-01-05 202001
...

the manual states that W should give me the ISO week of year, which starts on Monday, so i would have assumed that the format('YW') would output 201953, even 202001 would have been acceptable.

the ISO 8601 from wikipedia states:

As a consequence, if 1 January is on a Monday, Tuesday, Wednesday or Thursday, it is in week 01. If 1 January is on a Friday, Saturday or Sunday, it is in week 52 or 53 of the previous year (there is no week 00). 28 December is always in the last week of its year.

In 2020, 1st jan was a Wednesday, so the Monday of the preceding year should have been week 53 right?

can anyone shed light on this?

Upvotes: 1

Views: 425

Answers (3)

pgee70
pgee70

Reputation: 4004

ok, think i have worked out the solution to my issue:

i thought the 'Y' parameter was the ISO year. it is the gregorian year, i needed the 'o' parameter. which by the way is not documented here: https://www.php.net/manual/en/datetime.formats.date.php

to explain:

$dt = new DateTime('2018-12-20 0:0:0', new DateTimeZone('UTC'));
for($i = 0 ; $i < 400; $i++){
  echo $dt->format('Y-m-d oW')."\n";
  $dt->modify('+1 day');
}

gives output:
...
2019-12-25 201952
2019-12-26 201952
2019-12-27 201952
2019-12-28 201952
2019-12-29 201952
2019-12-30 202001
2019-12-31 202001
2020-01-01 202001
2020-01-02 202001
2020-01-03 202001
2020-01-04 202001
2020-01-05 202001
...

the 'o' parameter shows the iso year, which gives my required output.

Upvotes: 2

Styx
Styx

Reputation: 10076

1st Jan was a Wednesday that means the week that contains 1st Jan is the first week. This weeks starts on Monday, 30th Dec, like it shown in your output.

The source of your confusion though is that you use YW incorrectly. You should use oW instead:

o: ISO-8601 week-numbering year. This has the same value as Y, except that if the ISO week number (W) belongs to the previous or next year, that year is used instead.

This way it would correctly show you 2019-12-30 202001 and so on.

Upvotes: 1

Jim
Jim

Reputation: 3589

It is based on the ISO standard which includes calculating leap years when calculating the number of weeks in a year.

In short, here is a simplified statement from the link:

On average, a year has 53 weeks every ​400⁄71 = 5.6338… years, and these long ISO years are 43 × 6 years apart, 27 × 5 years apart, and once 7 years apart (between years 296 and 303).

Upvotes: 1

Related Questions