ISO 8601 week dates
Back in 2009 I wrote that PHP calendar implementation uses the ISO 8601 calendar for year numbers. In the past few weeks I've seen a few bug reports in the PHP bug system (65694 and 65730) that deal with another aspect of this same calendar: week numbers.
Week numbers are defined in this same ISO 8601 standard. Each year has 52 or 53 weeks and weeks always start on a Monday. Week number 1 of each year is the first week in a year that has the first Thursday of the year, or in other words, the week containing January 4th.
With the year number (2012, 2013, etc), the week number (01-53) and the day number (1-7) you can describe a day. PHP supports the formats yyyy "W" ww
d where yyyy is the ISO 8601 year, "W" a delimiter, ww the week number and d the day of the week (with 1 being Monday, and 7 being Sunday). It is also possible to omit the day-of-week (yyyy "W" ww) to represent the start of the week (Monday) and to add - in the format (such as in yyyy "-W" ww "-" d. Examples are: 2013-W39-2 for today and 2013-W40 for next Monday.
Tuesday January 1st, 2013 is represented as 2013-W01-2, and Tuesday December 31st, 2013 as 2014-W01-2. As you see with December 31st, the ISO 8601 year (2014) is not the same as the calendar year (2013). The ISO year starts with (ISO) week 1, day 1, which is always a Monday. If you do the following in PHP, you get an unexpected answer:
<?php
$d = new DateTime("2013-12-31");
echo $d->format('Y-\WW-N'), "\n";
?>
Which outputs 2013-W01-2. The Y format specifier gives the calendar year which is not the same as the ISO 8601 year. To show the ISO 8601 year, you need to use the o specifier. See the following:
<?php
echo date_create("2013-12-28")->format('Y-m-d o-\WW-N'), "\n";
echo date_create("2013-12-29")->format('Y-m-d o-\WW-N'), "\n";
echo date_create("2013-12-30")->format('Y-m-d o-\WW-N'), "\n";
echo date_create("2013-12-31")->format('Y-m-d o-\WW-N'), "\n";
echo date_create("2014-01-01")->format('Y-m-d o-\WW-N'), "\n";
echo date_create("2014-01-02")->format('Y-m-d o-\WW-N'), "\n";
?>
This outputs:
2013-12-28 2013-W52-6 2013-12-29 2013-W52-7 2013-12-30 2014-W01-1 2013-12-31 2014-W01-2 2014-01-01 2014-W01-3 2014-01-02 2014-W01-4
Parsing an ISO year/week/day combination displays the same issues:
<?php
$d = new DateTime("2014-W01-2");
echo $d->format("Y-m-d"), "\n";
?>
Which outputs 2013-12-31. The ISO week date 2014-W01-2 is part of calendar year 2013.
In most ISO 8601 years, there are 52 weeks. But once in a while, there are 53. This is because a year is 52 weeks and one day (or two days for leap years). In every 400 years there are 71 years with 53 weeks (and 329 years with 52 weeks). The next year for which the ISO year has 53 weeks is 2015:
<?php
$d = new DateTime("2015-12-31");
echo $d->format('Y-\WW-N'), "\n";
?>
Week 53 in ISO year 2015 goes from Monday 2015-12-28 to Sunday
2016-01-03. In 2018 the ISO year and calendar year start on the same date— 2018-01-01 or 2018-W01-1.
As conlusion, this article shows that there are two ways representing dates in PHP. In the Gregorian1 calendar with year, month and day (of month), and in the ISO 8601 calendar with year, week and day (of week). The format characters for the two different years are either Y or o and they should not be confused.
Comments
The Wikipedia article on ISO week date attached to the erroneous bug reports (http://en.wikipedia.org/wiki/ISO_8601_week_date) uses the term ISO week-numbering year to denote the 2014 year in 2013-12-31. I think the term would suite better to this article as I got confused in thinking DateTime::ISO8601 would use the 'o' options instead f the 'Y' one.
Thank you indeed for the clarification. I've just bumped into this unexpected behaviour in PHP and I've started wondering whether it was an obvious bug and no one has been found it before. :-)
-
1
PHP uses a special form of the Gregorian calendar, where it includes the year 0. This is called "astronomical year numbering" (http://en.wikipedia.org/wiki/Astronomical_year_numbering). PHP's calendar also does not use the Julian calendar before 1582.
Life Line
Updated a restaurant
I walked 9.8km in 1h41m58s
@milh0use You were on the news!
But the best thing I saw on my stroll through London's Richmond Park yesterday, was finding a nest of Sparrowhawks.
There was one parent and two juveniles.
First they were soaring overhead, before one of them landed in a tree right in front of me.
A while later, I saw them in the air again, where one of them let go of some food, which another grabbed right from the air.
#BirdsOfFediverse #Birds #BirdPhotography #Nature #NaturePhotography #London #NoAI
I had a stroll through London's Richmond Park yesterday.
I found quite a few Green and Great-Spotted Woodpeckers!
#BirdsOfFediverse #Birds #BirdPhotography #Nature #NaturePhotography #London #NoAI
I walked 10.6km in 2h40m20s
I hiked 14.1km in 4h40m00s
Created a restaurant
I walked 1.6km in 23m28s
Merge branch 'xdebug_3_5'
Merged pull request #1099
Fixed issue #2435: Xdebug does not handle 'muiltiple_sessions' dbgp f…
I walked 6.2km in 1h5m12s
Merged pull request #1098
PHP 8.6: require et all no longer show the file names in error messag…
Created 2 gates, a bench, and a crossing; Updated 5 gates and 2 benches
I walked 6.1km in 1h19m29s
I walked 0.9km in 9m06s
Updated a restaurant
I walked 8.5km in 1h33m20s
I walked 7.0km in 1h12m36s
Staring Contest with an Owl
This Little Owl stared at me intensely for a fair amount of time in London's Bushy Park.
#BirdPhotography #BirdsOfFediverse #NaturePhotography #Photography #SuperbOwl #London #Birds
Updated an apartments building
I walked 6.8km in 1h6m55s
Little Owl owlet
This lovely owlet was quite easy to find in a London Park, with some help as they camouflage so well!
I saw its sibling too.
#BirdPhotography #BirdsOfFediverse #Photography #Nature #London #BirdsOfMastodon





Shortlink
This article has a short URL available: https://drck.me/week-ac0