Skip to content

Instantly share code, notes, and snippets.

@stecman
Last active June 24, 2022 10:13
Show Gist options
  • Star 17 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save stecman/0203410aa4da0ef01ea9 to your computer and use it in GitHub Desktop.
Save stecman/0203410aa4da0ef01ea9 to your computer and use it in GitHub Desktop.
Reliable PHP function to return Monday for week (pre-PHP 7.1)
<?php
/**
* Find the starting Monday for the given week (or for the current week if no date is passed)
*
* This is required as strtotime considers Sunday the first day of a week,
* making strtotime('Monday this week') on a Sunday return the adjacent Monday
* instead of the previous one.
*
* @param string|\DateTime|null $date
* @return \DateTime
*/
function getStartOfWeekDate($date = null)
{
if ($date instanceof \DateTime) {
$date = clone $date;
} else if (!$date) {
$date = new \DateTime();
} else {
$date = new \DateTime($date);
}
$date->setTime(0, 0, 0);
if ($date->format('N') == 1) {
// If the date is already a Monday, return it as-is
return $date;
} else {
// Otherwise, return the date of the nearest Monday in the past
// This includes Sunday in the previous week instead of it being the start of a new week
return $date->modify('last monday');
}
}
@haziqAhmed7
Copy link

great piece of code...
you save my day buddy!!!

@tianmarin
Copy link

Just AWESOME!
very simple, but does what it must

@achasseux
Copy link

👍

@panmitz
Copy link

panmitz commented Mar 25, 2018

Thanks mate. Nice snippet.

@dkimery256
Copy link

Thanks!

@shraddha27
Copy link

Thank you so much. You saved my day. May God Bless You always

@abePdIta
Copy link

abePdIta commented Dec 4, 2020

This is great, thank you, but I think that it can be significantly simplified.
E. g. no need to setTime(): changing time never changes date in PHP.

function getStartOfWeekDate($date = null)
{
    if ($date instanceof \DateTime) {
        $date = clone $date;
    } else {
        // If date is falsy, it won't harm
        $date = new \DateTime($date);
    }
    
    return $date->modify('monday this week');
}

@stecman
Copy link
Author

stecman commented Dec 7, 2020

Thanks @abePdIta - it looks like the interpretation of "monday this week" may have been properly fixed from about PHP 7.1 onwards. This snippet was written in 2014 against PHP 5.5 when this was definitely a problem.

Your version, with2020-12-06 as an input (tool):

Output for 5.6.23 - 5.6.40, 7.0.8 - 7.0.33, 7.1.0 - 7.1.33, 7.2.0 - 7.2.34, 7.3.0 - 7.3.25, 7.4.0 - 7.4.13, 8.0.0
> 2020-11-30

Output for 5.3.0 - 5.3.29, 5.4.0 - 5.4.45, 5.5.0 - 5.5.38, 5.6.0 - 5.6.22, 7.0.0 - 7.0.7
> 2020-12-07

The original, with 2020-12-06 as an input (tool):

Output for 5.3.0 - 5.3.29, 5.4.0 - 5.4.45, 5.5.0 - 5.5.38, 5.6.0 - 5.6.40, 7.0.0 - 7.0.33, 7.1.0 - 7.1.33, 7.2.0 - 7.2.34, 7.3.0 - 7.3.25, 7.4.0 - 7.4.13, 8.0.0
> 2020-11-30

I couldn't pin down one single patch that addresses this issue, but good to know that the "monday this week" behaviour is consistent in actively supported versions of PHP 👍

Regarding setTime(), the week technically starts at midnight on Monday. The original code leveraged this to test for equality between output DateTime objects, but you're correct that it's not strictly required.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment