I came across this problem recently while developing a time tracking application.

Typically, I have found that when viewing time sheets people prefer to be able to see the week at a glance. For this reason I will normally store them in a database with three int (day (From 1-7), Week (From 1-53) and year (From 0001 to 9999)). This allows me to easily pull a two-dimensional array from the database for output into the virtual time sheet

SELECT * FROM `timesheet` WHERE `week`=26 AND `year`=2008 ORDER BY `day` ASC, `start_time` ASC

Now, this is all well and good, and it’s fine for most of us. But generally a customer will want to see something like:

Time sheet for week beginning 23rd of June 08

This also makes it easier from a useability perspective when displaying monthly or annual views. If you are looking to track down a time sheet for last February, it’s easier to jump to it if you are looking at it by date and not by number.

Looking at the php date related functions, there is no real obvious way to handle this. But don’t worry. We can do it!

The international standards for dealing with dates and times are covered by ISO 8601, and here is an easy to understand Wikipedia article on it.

So if you take a look at the week dates part of it, it gives us some mutually equivalent definitions for week 01

  • the week with the year’s first Thursday in it.
  • the week with 4 January in it.
  • the first week with the majority (four or more) of its days in the starting year.
  • the week starting with the Monday in the period 29 December – 4 January.

So, the easiest way to work with this from PHP, is to find out what date Jan 4th + $week_number weeks is. Assuming your current week number is stored in the variable $week, and the current year is stored in the variable $year this can be done as follows.

$time = strtotime($year . ’0104 +’ . ($week – 1) . ‘ weeks’);

strtotime() is a very handy function that allows you to turn a variety of human readable date formats into UNIX timestamps. As you can see above it also allows you to perform additions and subtractions on it.

To breakdown that line, what I am doing is getting the time-stamp for the 4th of January this year + this week (less 1) weeks. The reason I subtract 1 up above is because January 4th is in week 1, not week 0.

So now we have a date in this week, but it’s not necessarily the Monday. But that’s fairly easy to find out from here with the following line.

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

All I am doing there is saying “Give me a time stamp for this date – (However many days we are past Monday) days.”.

So now we have our time stamp for the Monday of the relevant week. So let’s clean it up a bit and stick it in a function.

<?php
function getWeekStartDate($week, $year, $format = dS F, Y) { 

$time = strtotime($year . 0104 + . ($week  1) .  weeks); 

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

return date($format, $mondayTime); 

}
?>

Now, all I have done here is added in functionality to get it to return a nice easy to read date. Just pass it the exact same formatting you would send to the php date() function.

Hope this helps someone out there!

Ian McCarthy

A 30 something year old Irish developer

killarneyman
killarneyman


Published