PHP get start and end date of a week by weeknumber

PhpDate

Php Problem Overview


I've seen some variants on this question but I believe this one hasn't been answered yet.

I need to get the starting date and ending date of a week, chosen by year and week number (not a date)

example:

input:

getStartAndEndDate($week, $year);

output:

$return[0] = $firstDay;
$return[1] = $lastDay;

The return value will be something like an array in which the first entry is the week starting date and the second being the ending date.

OPTIONAL: while we are at it, the date format needs to be Y-n-j (normal date format, no leading zeros.

I've tried editing existing functions that almost did what I wanted but I had no luck so far.

Please help me out, thanks in advance.

Php Solutions


Solution 1 - Php

Using DateTime class:

function getStartAndEndDate($week, $year) {
  $dto = new DateTime();
  $dto->setISODate($year, $week);
  $ret['week_start'] = $dto->format('Y-m-d');
  $dto->modify('+6 days');
  $ret['week_end'] = $dto->format('Y-m-d');
  return $ret;
}

$week_array = getStartAndEndDate(52,2013);
print_r($week_array);

Returns:

Array
(
    [week_start] => 2013-12-23
    [week_end] => 2013-12-29
)

Explained:

  • Create a new DateTime object which defaults to now()
  • Call setISODate to change object to first day of $week of $year instead of now()
  • Format date as 'Y-m-d' and put in $ret['week_start']
  • Modify the object by adding 6 days, which will be the end of $week
  • Format date as 'Y-m-d' and put in $ret['week_end']

A shorter version (works in >= php5.3):

function getStartAndEndDate($week, $year) {
  $dto = new DateTime();
  $ret['week_start'] = $dto->setISODate($year, $week)->format('Y-m-d');
  $ret['week_end'] = $dto->modify('+6 days')->format('Y-m-d');
  return $ret;
}

Could be shortened with class member access on instantiation in >= php5.4.

Solution 2 - Php

Many years ago, I found this function:

function getStartAndEndDate($week, $year) {
  $dto = new DateTime();
  $dto->setISODate($year, $week);
  $ret['week_start'] = $dto->format('Y-m-d');
  $dto->modify('+6 days');
  $ret['week_end'] = $dto->format('Y-m-d');
  return $ret;
}

$week_array = getStartAndEndDate(52,2013);
print_r($week_array);

Solution 3 - Php

We can achieve this easily without the need for extra computations apart from those inherent to the DateTime class.

function getStartAndEndDate($year, $week)
{
   return [
      (new DateTime())->setISODate($year, $week)->format('Y-m-d'), //start date
      (new DateTime())->setISODate($year, $week, 7)->format('Y-m-d') //end date
   ];
}

The setISODate() function takes three arguments: $year, $week, and $day respectively, where $day defaults to 1 - the first day of the week. We therefore pass 7 to get the exact date of the 7th day of the $week.

Solution 4 - Php

Slightly neater solution, using the "[year]W[week][day]" strtotime format:

function getStartAndEndDate($week, $year) {
  // Adding leading zeros for weeks 1 - 9.
  $date_string = $year . 'W' . sprintf('%02d', $week);
  $return[0] = date('Y-n-j', strtotime($date_string));
  $return[1] = date('Y-n-j', strtotime($date_string . '7'));
  return $return;
}

Solution 5 - Php

shortest way to do it:

function week_date($week, $year){
	$date = new DateTime();
	return "first day of the week is ".$date->setISODate($year, $week, "1")->format('Y-m-d')
	."and last day of the week is ".$date->setISODate($year, $week, "7")->format('Y-m-d'); 
}
echo week_date(12,2014);

Solution 6 - Php

You can get the specific day of week from date as bellow that I get the first and last day

$date = date_create();

// get the first day of the week
date_isodate_set($date, 2019, 1);
    
    //convert date format and show     
    echo date_format($date, 'Y-m-d') . "\n";

// get the last date of the week
date_isodate_set($date, 2019, 1, 7);
     
     //convert date format and show        
     echo date_format($date, 'Y-m-d') . "\n";

>Output =>

>2018-12-31

>2019-01-06

Solution 7 - Php

The calculation of Roham Rafii is wrong. Here is a short solution:

// week number to timestamp (first day of week number)
function wn2ts($week, $year) {
	return strtotime(sprintf('%dW%02d', $year, $week));
}

if you want the last day of the week number, you can add up 6 * 24 * 3600

Solution 8 - Php

This is an old question, but many of the answers posted above appear to be incorrect. I came up with my own solution:

function getStartAndEndDate($week, $year){
    $dates[0] = date("Y-m-d", strtotime($year.'W'.str_pad($week, 2, 0, STR_PAD_LEFT)));
    $dates[1] = date("Y-m-d", strtotime($year.'W'.str_pad($week, 2, 0, STR_PAD_LEFT).' +6 days'));
    return $dates;
}

Solution 9 - Php

First we need a day from that week so by knowing the week number and knowing that a week has seven days we are going to do so the

$pickADay = ($weekNo-1) * 7 + 3;

this way pickAday will be a day in our desired week.

Now because we know the year we can check which day is that. things are simple if we only need dates newer than unix timestamp We will get the unix timestamp for the first day of the year and add to that 24*3600*$pickADay and all is simple from here because we have it's timestamp we can know what day of the week it is and calculate the head and tail of that week accordingly.

If we want to find out the same thing of let's say 12th week of 1848 we must use another approach as we can not get the timestamp. Knowing that each year a day advances 1 weekday meaning (1st of november last year was on a sunday, this year is on a monday, exception for the leap years when it advances 2 days I believe, you can check that ). What I would do if the year is older than 1970 than make a difference between it and the needed year to know how many years are there, calculate the day of the week as my pickADay was part of 1970, shift it back one weekday for each. $shiftTimes = ($yearDifference + $numberOfLeapYears)%7, in the difference. shift the day backwords $shiftTimes, then you will know what day of the week was that day those years ago, then find the weekhead and weektail. Same thing can be used also for the future if it seems simpler. Try it if it works and tell me if it does not.

Solution 10 - Php

For documentation (since Google ranks this question first when searching for "php datetime start end this week").

If you need the startdate and enddate for the current week (using DateTime):

$dateTime = new DateTime('now');
$monday = clone $dateTime->modify(('Sunday' == $dateTime->format('l')) ? 'Monday last week' : 'Monday this week');
$sunday = clone $dateTime->modify('Sunday this week');

var_dump($monday->format('Y-m-d')); // e.g. 2018-06-25
var_dump($sunday->format('Y-m-d')); // e.g. 2018-07-01

Hope this will help.

Solution 11 - Php

Have you tried PHP relative dates? It might work.

Solution 12 - Php

Even if you dont want to use a specific date you cannot escape it. You can calculate a week based on the date ONLY.

Steps:

  1. get the first day of the year
  2. decide when the first week starts ( there are some rules that include first Thursday if I remember.
  3. add some number of weeks (your first param). Zend_Date has an add() function where you can add weeks for example. This will give you the first day of the week.
  4. offset and get the last day.

I would recommend working with a consistent dates sistem like Zend_Date or Pear Date.

Solution 13 - Php

function getStartAndEndDate($week, $year)
	{
		$week_start = new DateTime();
		$week_start->setISODate($year,$week);
		$return[0] = $week_start->format('d-M-Y');
		$time = strtotime($return[0], time());
		$time += 6*24*3600;
		$return[1] = date('d-M-Y', $time);
		return $return;
	}
	

Solution 14 - Php

$dateParam = '2018-06-10';
$week = date('w', strtotime($dateParam));
$date = new DateTime($dateParam);
$firstWeek = $date->modify("-".$week." day")->format("Y-m-d H:i:s");
$endWeek = $date->modify("+6 day")->format("Y-m-d H:i:s");
echo $firstWeek."<br/>";
echo $endWeek;

will print

2018-06-10 00:00:00
2018-06-16 00:00:00

hopefully will help

Solution 15 - Php

The "first day of the week" is subjective. Some cultures use "Monday" others "Sunday", maybe others something else?

For my purposes, I want the first day of the week to be "Sunday" and the last day of the week to be "Saturday".

Also, using DateTime with no arguments will default to "now" which includes the current time. The following method will disregard the current time by specifying "today" in the DateTime constructor.

Furthermore the string "sunday this week" does not seem to be reliable. It actually will return Sunday the next week (according to my view of what a week is).

I've built a method which returns a PHP object containing two DateTime objects. One for the first day (Sunday) of the given week, the second for the last day (Saturday) of the given week.

function get_first_and_last_day_of_week( $year_number, $week_number ) {
	// we need to specify 'today' otherwise datetime constructor uses 'now' which includes current time
	$today = new DateTime( 'today' );

	return (object) [
		'first_day' => clone $today->setISODate( $year_number, $week_number, 0 ),
		'last_day'  => clone $today->setISODate( $year_number, $week_number, 6 )
	];
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPieter888View Question on Stackoverflow
Solution 1 - Phpuser3108829View Answer on Stackoverflow
Solution 2 - PhpRoham RafiiView Answer on Stackoverflow
Solution 3 - PhpHenry OhangaView Answer on Stackoverflow
Solution 4 - Phptripper54View Answer on Stackoverflow
Solution 5 - PhpClaudiu CreangaView Answer on Stackoverflow
Solution 6 - PhpNasser Ali KarimiView Answer on Stackoverflow
Solution 7 - PhpFirePantherView Answer on Stackoverflow
Solution 8 - PhpbezzView Answer on Stackoverflow
Solution 9 - PhpCatalin MarinView Answer on Stackoverflow
Solution 10 - PhpAvatarView Answer on Stackoverflow
Solution 11 - PhpMikelView Answer on Stackoverflow
Solution 12 - PhpElzo ValugiView Answer on Stackoverflow
Solution 13 - PhpCBSUAView Answer on Stackoverflow
Solution 14 - Phpuser2963512View Answer on Stackoverflow
Solution 15 - PhpjeremysawesomeView Answer on Stackoverflow