php strtotime "last monday" if today is monday?
Asked Answered
M

8

47

I want to use strtotime("last Monday").

The thing is, if today IS MONDAY, what does it return? It seems to be returning the date for the monday of last week. How can I make it return today's date in that case?

Marishamariska answered 11/11, 2010 at 0:31 Comment(0)
H
73

How can I make it return today's date in that case?

pseudocode:

if (today == monday)
    return today;
else
    return strtotime(...);

Btw, this trick also could work:

strtotime('last monday', strtotime('tomorrow'));
Hungarian answered 11/11, 2010 at 0:43 Comment(9)
@nute: well, I've checked all possible cases: any middle-week day, and edges: sunday & monday. All returns expected result. I think there are no problems, except of semantics ;-)Hungarian
Also see the answer by dotjon to this question only for a more elegant solution.Mahaffey
@Gopal Aggarwal: I remember there are some edge cases when this in strtotime points to now what you want. Cannot provide any particular example thoughHungarian
@Hungarian Sorry, but I am not getting your point. Kindly elaborate.Mahaffey
@Gopal Aggarwal: from what I remember, there are cases when this may refer to a former week, not to thisHungarian
@Hungarian Okay. Well, I am putting my faith in core PHP's abilities :) And if there are certain edge-cases, I am hopeful they will be found and resolved in coming versions.Mahaffey
@GopalAggarwal: your faith is misplaced :) "this week" does not work for Sundays. Example, today is Sunday 2015-03-01, but "Sunday this week" will return 2015-03-08. See: #13798526 and bugs.php.net/bug.php?id=63740&thanks=6Cockpit
@Cockpit Thanks for the heads-up and the links. I hope you do not mean what you say. If PHP as a language and a community cannot (or cannot hope to in a reasonable time) better its core functions once a bug has been reproduced, then maybe we should listen to 'PHP sucks' and move elsewhere.Mahaffey
If you're calling this repeatedly, try strtotime('last monday', time() + 86400);. Does exactly the same thing but saves a call to the expensive strtotime function.Atlanta
S
149

If you read the manual, there is an great example that describes exactly what you want to do https://www.php.net/manual/en/datetime.formats.php#datetime.formats.relative

strtotime('Monday this week');

Update: There appears to be a bug introduced in newer versions of PHP where this week returns the wrong week when ran on Sundays. You can vote on the bug here: https://bugs.php.net/bug.php?id=63740

Update 2: As of May 18th 2016, this has been fixed in PHP 5.6.22, PHP 7.0.7 and PHP 7.1-dev (and hopefully remains fixed in subsequent releases) as seen here: https://bugs.php.net/bug.php?id=63740#1463570467

Stephanstephana answered 24/1, 2012 at 3:41 Comment(9)
I don't get why the other answer was accepted. For further readers, this solution is better, it does exactly what is being asked.Arleenarlen
Very useful for e.g. Drupal and Views where you can only input a date string.Idelson
This is clever piece of code imho, but it may be not selected because it lacks 'generalization', which can be important for people coming from Google.Betteanne
@EralpB, there's nothing clever about it. It's core PHP, widely supported, bug free, and semantically correct! :)Stephanstephana
@Jose Garrido. Perhaps because this answer was given 2 years later?Lobster
If the day is Sunday, this will return the date of Monday of next week, rather than the Monday of the current week.Exserviceman
@chap, turns out this week returns a Monday if run on a Sunday. It's a ridiculous bug: bugs.php.net/bug.php?id=63740Stephanstephana
5.6.23, 7.0.8 Weeks always start on monday. Formerly, sunday would also be considered to start a week.Psittacosis
Good luck relying on "this week" outside the US of A.Openandshut
H
73

How can I make it return today's date in that case?

pseudocode:

if (today == monday)
    return today;
else
    return strtotime(...);

Btw, this trick also could work:

strtotime('last monday', strtotime('tomorrow'));
Hungarian answered 11/11, 2010 at 0:43 Comment(9)
@nute: well, I've checked all possible cases: any middle-week day, and edges: sunday & monday. All returns expected result. I think there are no problems, except of semantics ;-)Hungarian
Also see the answer by dotjon to this question only for a more elegant solution.Mahaffey
@Gopal Aggarwal: I remember there are some edge cases when this in strtotime points to now what you want. Cannot provide any particular example thoughHungarian
@Hungarian Sorry, but I am not getting your point. Kindly elaborate.Mahaffey
@Gopal Aggarwal: from what I remember, there are cases when this may refer to a former week, not to thisHungarian
@Hungarian Okay. Well, I am putting my faith in core PHP's abilities :) And if there are certain edge-cases, I am hopeful they will be found and resolved in coming versions.Mahaffey
@GopalAggarwal: your faith is misplaced :) "this week" does not work for Sundays. Example, today is Sunday 2015-03-01, but "Sunday this week" will return 2015-03-08. See: #13798526 and bugs.php.net/bug.php?id=63740&thanks=6Cockpit
@Cockpit Thanks for the heads-up and the links. I hope you do not mean what you say. If PHP as a language and a community cannot (or cannot hope to in a reasonable time) better its core functions once a bug has been reproduced, then maybe we should listen to 'PHP sucks' and move elsewhere.Mahaffey
If you're calling this repeatedly, try strtotime('last monday', time() + 86400);. Does exactly the same thing but saves a call to the expensive strtotime function.Atlanta
M
5

If today is Monday, strtotime("last Monday") will return a date 7 days in the past. Why don't you just check if today is Monday and if yes, return today's date and if not, return last week?

That would be a foolproof way of doing this.

if (date('N', time()) == 1) return date('Y-m-d');
else return date('Y-m-d', strtotime('last Monday'));

https://www.php.net/manual/en/function.date.php

Michigan answered 11/11, 2010 at 0:46 Comment(4)
just curious, what if it was Now, 8th 23:59:59.999 in your if() clause and when interpreter reach return clause - it is already Now, 9th (tuesday)? ;-)Hungarian
Ha, I was trying to keep it short. Personally I would declare today and last Monday first and then make the comparisons to avoid the race condition. I'm a bigger fan of your working back from tomorrow method.Michigan
yeah, race condition is the most weird bug to detect. Sorry if my comment looks rude.Hungarian
Not at all. Don't worry about it.Michigan
F
3

As it was correctly outlined in the previous answer, this trick works, but also had caveats prior to PHP 5.6.22, PHP 7.0.7 and PHP 7.1-dev:

strtotime('last monday', strtotime('tomorrow'));

// or this one, which is shorter, but was buggy:
strtotime('Monday this week');

To those, who prefer the "Jedy-way", to work with objects of the DateTime class, the solution is next:

(new \DateTime())->modify('tomorrow')->modify('previous monday')->format('Y-m-d');

or even shorter notation:

\DateTime('Monday this week')

Be carefull, because if you do the same on SQL, you don't need to have any of these tricks in with addition of "tomorrow". Here's how the solution will look:

SELECT DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY) as last_monday;
Footstall answered 20/2, 2017 at 10:12 Comment(0)
B
1

Late answer, but I thought I would post up this answer (which is actually from a different but related question). It handles the scenario in the question:

function last_monday($date) {
    if (!is_numeric($date))
        $date = strtotime($date);
    if (date('w', $date) == 1)
        return $date;
    else
        return strtotime(
            'last monday',
             $date
        );
}

echo date('m/d/y', last_monday('8/14/2012')); // 8/13/2012 (tuesday gives us the previous monday)
echo date('m/d/y', last_monday('8/13/2012')); // 8/13/2012 (monday throws back that day)
echo date('m/d/y', last_monday('8/12/2012')); // 8/06/2012 (sunday goes to previous week)

try it: http://codepad.org/rDAI4Scr

... or a variation that has sunday return the following day (monday) rather than the previous week, simply add a line:

 elseif (date('w', $date) == 0)
    return strtotime(
        'next monday',
         $date
    );

try it: http://codepad.org/S2NhrU2Z

You can pass it a timestamp or a string, you'll get back a timestamp

Documentation

Banking answered 2/8, 2012 at 5:0 Comment(0)
W
0

Depending on exactly what you're using it for, this may be useful. Since one second's ambiguity is OK for my requirements, I use:

date( 'Y-m-d 23:59:59', strtotime( 'last sunday' ))

to get midnight on the most recent Monday (or today if today IS Monday).

Whipsaw answered 1/2, 2013 at 12:47 Comment(0)
C
0

My aproach:

date_default_timezone_set('Europe/Berlin');
function givedate($weekday, $time) {
$now = time();
$last = strtotime("$weekday this week $time");
$next = strtotime("next $weekday $time");
    if($now > $last) {
        $date = date("d.m.Y - H:i",$next);
    }
    else {
        $date = date("d.m.Y - H:i",$last);
    }
    return $date;
}

echo givedate('Wednesday', '00:52');

Or monthly

    function givedate_monthly($weekday, $time) {
    $now = time();
    $last = strtotime("first $weekday of this month $time");
    $next = strtotime("first $weekday of next month $time");
        if($now > $last) {
            $date = date("d.m.Y - H:i",$next);
        }
        else {
            $date = date("d.m.Y - H:i",$last);
        }
        return $date;
}

echo givedate_monthly('Wednesday', '01:50');
Conceited answered 6/8, 2013 at 23:8 Comment(0)
L
-1
$monday = strtotime('Monday last week');
$sunday = strtotime('+6 days', $monday);
Lotetgaronne answered 12/12, 2012 at 8:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.