tzzz


ISO 8601 week number to date (timestamp) in PHP
August 14, 2006, 12:21 pm
Filed under: date, ISO8601, PHP, weekNumber

How do I convert an ISO 8601 week number to a timestamp or date?

Here’s a handy function for PHP that returns an array with seven timestamps, one for each day in week $weekNumber.

function getDaysInWeek ($weekNumber, $year) {
  // Count from '0104' because January 4th is always in week 1
  // (according to ISO 8601).
  $time = strtotime($year . '0104 +' . ($weekNumber - 1)
                    . ' weeks');
  // Get the time of the first day of the week
  $mondayTime = strtotime('-' . (date('w', $time) - 1) . ' days',
                          $time);
  // Get the times of days 0 -> 6
  $dayTimes = array ();
  for ($i = 0; $i < 7; ++$i) {
    $dayTimes[] = strtotime('+' . $i . ' days', $mondayTime);
  }
  // Return timestamps for mon-sun.
  return $dayTimes;
}

A simple way to test if it works:

$dayTimes = getDaysInWeek(33, 2006);
foreach ($dayTimes as $dayTime) {
  echo (strftime('%a %Y%m%d', $dayTime) . "n");
}

I had some trouble with making this work on my local computer. A good guess is that this has something to do with my locales, so beware! Run the test on the computer that hosts your application before you rely on it.


30 Comments so far
Leave a comment

Thank you, just what I needed, good tip about using strtotime to make these calculations!

I had to change the string used by strtotime to “4 January 2006 + 33 weeks” to make it work for me, probably locale settings.

Comment by Rune

perfect. thank you very much.

Comment by safeen

This always works:

function getFirstDayOfWeek($year, $weeknr)
{
$offset = date(‘w’, mktime(0,0,0,1,1,$year));
$offset = ($offset

Comment by Patrick Nijs

Again, in valid HTML:

function getFirstDayOfWeek($year, $weeknr)
{
$offset = date(‘w’, mktime(0,0,0,1,1,$year));
$offset = ($offset < 5) ? 1-$offset : 8-$offset;
$monday = mktime(0,0,0,1,1+$offset,$year);

return strtotime(‘+’ . ($weeknr – 1) . ‘ weeks’, $monday);
}

Comment by Patrick Nijs

Brilliant!

Comment by Dandelion

What does Rune mean by “I had to change the string used by strtotime to “4 January 2006 + 33 weeks” to make it work for me, probably locale settings.”

Comment by Rajan

That instead of using:

$time = strtotime($year . '0104 +' . ($weekNumber - 1) . ' weeks');

He had to use:

$time = strtotime('4 January ' . $year . ' +' . ($weekNumber - 1) . ' weeks');

Comment by tzzz

@Patrick Nijs… This is just what I was looking for! Thanks

Comment by batfastad

Here is another way to do it:
$date = date(‘m/d/Y’, strtotime(‘1 january 2007 + 33 weeks’));

Comment by John

Also,
$date = date(‘m/d/Y’, strtotime(‘2007W011’));

Where:
2007 = year
W01 = week one (W04 = week 4, etc)
1 = day of week to get date for (in this case, monday)

Comment by John

or u can try this function

function getDaysInWeek ($weekNumber, $year)
{
$date_object = date_create( “0 January $year” );
$date_object->modify( “+$weekNumber weeks” );
$dayTimes = $date_object->format( “d-m-Y” );
$date_object->modify( “-6 days” );
$dayTimes = $date_object->format( “d-m-Y” ).” – “.$dayTimes;
return $dayTimes;
}

Comment by gigel

KISS solution based on Johns entry:

/**
* Get the start of a given week (in this case monday is first day = W)
*
* @param integer $iWeekNumber
* @param string $sFormat
* @param integer $iYear
* @return mixed Datetime or UNIX time depending on format
*/
public static function getDatetimeWeekStart( $iWeekNumber, $iYear = null, $sFormat = ‘d\.m\.Y’)
{
if ( is_null($iYear) ) $iYear = date(“Y”);
if ( $iWeekNumber < 10 ) $iWeekNumber = “0”.$iWeekNumber;
$iTime = strtotime($iYear.’W’.$iWeekNumber);
return date($sFormat, $iTime);
}

Example this week:
print getDatetimeWeekStart(date(‘W’));

Example week 10 in 2006:
print getDatetimeWeekStart(10, 2006);

Example week 52 in 2009 in unixtime:
print getDatetimeWeekStart(52, 2009, ‘U’);

Best regards
Jesper HorsMark

Comment by HorsMark

[…]   return $dayTimes; }  aus: ISO 8601 week number to date (timestamp) in PHP Er gibt dir einen Array mit 7 Eintrgen zurck, fr jeden Tag einen. Davon brauchst du eben nur […]

Pingback by Erster Tag einer Woche - PHP @ tutorials.de: Forum, Tutorial, Anleitung, Schulung & Hilfe

Patrick Nijs’s code does not work every time. For example, year 2008, week number 1
Week 1 starts in last year, 31.12.2007 to be exact. Patrick’s code does not understand that and says that first day of the first week is 1.1.2008.

Comment by Jasmo

Very useful for me, just what i wanted.
Thanks!

Comment by centerax

[…] So, i searched on google and found this as first result: https://tzzz.wordpress.com/2006/08/14/8/ […]

Pingback by Get timestamps out of week no. and year. | Rene's PHP Blog

Thanks for the code! It was very usefull.

I posted someting on my blog to show you how i used it. And a backlink to this blogpost!

Comment by Rene

I think he made mistakes in finding the $mondayTime
You can test that with week 52 year 2008 and week 1 year 2009.

This is the revised code:

function getDaysInWeek ($weekNumber, $year) {
// Count from ‘0104’ because January 4th is always in week 1
// (according to ISO 8601).
$time = strtotime($year . ‘0104 +’ . ($weekNumber – 1)
. ‘ weeks’);
// Get the time of the first day of the week
$diff = (date(‘w’, $time) – 1 >= 0) ? (date(‘w’, $time) – 1) : 6;
$mondayTime = strtotime(‘-‘ . $diff . ‘ days’, $time);
// Get the times of days 0 -> 6
$dayTimes = array ();
for ($i = 0; $i < 7; ++$i) {
$dayTimes[] = strtotime(‘+’ . $i . ‘ days’, $mondayTime);
}
// Return timestamps for mon-sun.
return $dayTimes;
}

Comment by nkonx

Also for week 53 year 2009 and week 1 year 2010…

Comment by nkonx

Here is a function for finding the number of weeks in a year:

function datetime_nweek_in_year($year) {
// Count from ‘1228’ because December 28th is always in last week
// (according to ISO 8601).
$n = intval(date(‘W’, strtotime($year.’1228′)));
return $n;
}

Comment by nkonx

function week2date($year, $week, $weekday=7) {
$time = mktime(0, 0, 0, 1, (4 + ($week-1)*7), $year);
$this_weekday = date(“N”, $time);
return mktime(0, 0, 0, 1, (4 + ($week-1) * 7 + ($weekday – $this_weekday)), $year);
}

Comment by Ramsed

I would be so happy if anyone could help me.

This scripts belives that there’s 53 weeks in year 2008

it’s only 52 ofc. så week 1 in 2009 is week 2 IRL.
and week 2 is week 3 and so on. Why does this occur? i’ve tryed to solve it. but i cant 😥

PLEASE!! COntact me @ patrik@quick-bemanning.se
I would be so greatfull for any solution!

Comment by Patrik

Loved this, thans a lot :D.

Comment by Severo

Fixed the years with 29 february
if (($year -1)/ 4 == intval(($year -1)/ 4)) $time = $time – 172800;

Comment by Juan Guzman

Leap year fix in previous comment unfortunately doesn’t really work in my script … I did, however, manage to fix the problem temporarily by writing ‘1 January’ instead of ‘4 January’. Will be re-set again for 2010 and following years. thx!

Comment by ahhoi

I’ve try this script and for unfortunately concidence, this year the 20090104 is sunday.
So the script fail to calculate $mondayTime = strtotime(‘– 1 days’, $time); don’t work!
This is the fix
if ((date(“w”, $time) == 0))
{
$mondayTime = strtotime(“-6 days”, $time);
}
else
{
$mondayTime = strtotime(“-” . (date(“w”, $time) – 1) . ” days”, $time);
}

Comment by Alessandro bellisai

John’s solutions (and thus HorsMark’s KISS one) won’t work because
1) in the first case it won’t be the Monday of the given week;
2) the second case needs ISO weeknumber year for the input not the usual Gregorian year (which is the case).

Comment by Janis

I think nobody noticed one mistake in the code…

$mondayTime = strtotime(‘-‘ . (date(‘w’, $time) – 1) . ‘ days’, $time);

Which is totally wrong, according to PHP.net. If we handle weeks in ISO 8601 format, we have to do the same, according to days, arn’t we?

We have to use date(‘N’) to handle days in ISO format, instead of date(‘w’)…

So it should be:

$mondayTime = strtotime(‘-‘ . (date(‘N’, $time) – 1) . ‘ days’, $time);

Comment by DjZoNe

cleanest way:

function getDaysInWeek($week, $year) {
$week = sprintf(‘%02d’,$week); //format as a 2 digit number. eg: 05

// set up ISO week date, eg: 2006W527, sunday(7), week 52 of 2006
$daysInWeek = array();
for ($day = 1; $day <= 7; $day++) {
$ISOweekDate = $year . "W" . $week . $day;
$daysInWeek[] = strtotime($ISOweekDate);
}

return $daysInWeek;
}

Comment by crockysam

[…] a comment » I needed a script to list the days, given a week and a year. I found this: https://tzzz.wordpress.com/2006/08/14/8/ But that seemed to be off by a […]

Pingback by PHP: getting days in a week « Crockysam's personal blog




Leave a comment