Iggy Ma
Iggy Ma

Reputation: 1469

Get first day of week in PHP?

Given a date MM-dd-yyyy format, can someone help me get the first day of the week?

Upvotes: 146

Views: 275643

Answers (30)

artemiuz
artemiuz

Reputation: 464

$mondayForWeek = clone $someDate;

if ($mondayForWeek->format('N') > 1) $mondayForWeek->sub(new \DateInterval('P'.($date->format('N')-1).'D'));

var_dump($mondayForWeek);

Upvotes: 0

Asain Kujovic
Asain Kujovic

Reputation: 1829

Just to note that timestamp math can also be a solution. If you have in mind that 01.jan 1970 was a Thursday, then start of a week for any given date can be calculated with:

function weekStart($dts)
{   $res = $dts - ($dts+date('Z',$dts)+259200)%604800;
    return $res + 3600*(date('I',$dts)-date('I',$res));
}

It is predictable for any timestamp and php version, using date-func ('Z', 'I') only for timezone and daylight-saving offsets. And it produces same results as:

strtotime(date('Y-m-d', $dts).' - '.(date('N', $dts)-1.' days');

and with (the best and the most elegant) mentioned:

strtotime('monday this week', $dts); 

Upvotes: 1

job3dot5
job3dot5

Reputation: 900

Keep it simple :

<?php    
$dateTime = new \DateTime('2020-04-01');
$monday = clone $dateTime->modify(('Sunday' == $dateTime->format('l')) ? 'Monday last week' : 'Monday this week');
$sunday = clone $dateTime->modify('Sunday this week');    
?>

Source : PHP manual

NB: as some user commented the $dateTime value will be modified.

Upvotes: 57

FiliusBonacci
FiliusBonacci

Reputation: 104

just simply oneline answer ;)

$mondayThisWeek = new Date($date . 'this week monday');

Upvotes: -3

Poupoudoum
Poupoudoum

Reputation: 31

In order to have the simplest code and have weeks starting on monday, I used this method:

$day = (date('w')+6)%7; //transform week start from sunday to monday
$time = strtotime('-'.$day.' days');

Upvotes: 0

Syed Urooj Waqar
Syed Urooj Waqar

Reputation: 41

$string_date = '2019-07-31';
echo $day_of_week = date('N', strtotime($string_date));
echo $week_first_day = date('Y-m-d', strtotime($string_date . " - " . ($day_of_week - 1) . " days"));
echo $week_last_day = date('Y-m-d', strtotime($string_date . " + " . (7 - $day_of_week) . " days"));

Upvotes: 4

AgmLauncher
AgmLauncher

Reputation: 7270

EDIT: the below link is no longer running on the version of PHP stated. It is running on PHP 5.6 which improves the reliability of strtotime, but isn't perfect! The results in the table are live results from PHP 5.6.

For what it's worth, here is a breakdown of the wonky behavior of strtotime when determining a consistent frame of reference:

http://gamereplays.org/reference/strtotime.php

Basically only these strings will reliably give you the same date, no matter what day of the week you're currently on when you call them:

strtotime("next monday");
strtotime("this sunday");
strtotime("last sunday"); 

Upvotes: 20

David Baucum
David Baucum

Reputation: 2250

Here's a one liner for the first day of last week, and the last day of last week as a DateTime object.

$firstDay = (new \DateTime())->modify(sprintf('-%d day', date('w') + 7))
                             ->setTime(0, 0, 0);
$lastDay = (new \DateTime())->modify(sprintf('-%d day', date('w') + 1))
                            ->setTime(23, 59, 59);

Upvotes: 1

mpen
mpen

Reputation: 282885

Should work:

/**
 * Returns start of most recent Sunday.
 * 
 * @param null|int $timestamp
 * @return int
 */
public static function StartOfWeek($timestamp = null) {
    if($timestamp === null) $timestamp = time();
    $dow = idate('w', $timestamp); // Sunday = 0, Monday = 1, etc.
    return mktime(0, 0, 0, idate('m', $timestamp), idate('d', $timestamp) - $dow, idate('Y', $timestamp));
}

Input and output are unix timestamps. Use date to format.

Upvotes: 0

onin
onin

Reputation: 5760

A smart way of doing this is to let PHP handle timezone differences and Daylight Savings Time (DST). Let me show you how to do this.

This function will generate all days from Monday until Friday, inclusive (handy for generating work week days):

class DateTimeUtilities {
    public static function getPeriodFromMondayUntilFriday($offset = 'now') {
        $now = new \DateTimeImmutable($offset, new \DateTimeZone('UTC'));
        $today = $now->setTime(0, 0, 1);

        $daysFromMonday = $today->format('N') - 1;

        $monday = $today->sub(new \DateInterval(sprintf('P%dD', $daysFromMonday)));
        $saturday = $monday->add(new \DateInterval('P5D'));

        return new \DatePeriod($monday, new \DateInterval('P1D'), $saturday);
    }
}

foreach (DateTimeUtilities::getPeriodFromMondayUntilFriday() as $day) {
    print $day->format('c');
    print PHP_EOL;
}

This will return datetimes Monday-Friday for current week. To do the same for an arbitrary date, pass a date as a parameter to DateTimeUtilities ::getPeriodFromMondayUntilFriday, thus:

foreach (DateTimeUtilities::getPeriodFromMondayUntilFriday('2017-01-02T15:05:21+00:00') as $day) {
    print $day->format('c');
    print PHP_EOL;
}

//prints 
//2017-01-02T00:00:01+00:00
//2017-01-03T00:00:01+00:00
//2017-01-04T00:00:01+00:00
//2017-01-05T00:00:01+00:00
//2017-01-06T00:00:01+00:00

Only interested in Monday, as the OP asked?

$monday = DateTimeUtilities::getPeriodFromMondayUntilFriday('2017-01-02T15:05:21+00:00')->getStartDate()->format('c');
print $monday;
// prints
//2017-01-02T00:00:01+00:00

Upvotes: 2

Kondziutek
Kondziutek

Reputation: 135

Just use date($format, strtotime($date,' LAST SUNDAY + 1 DAY'));

Upvotes: 4

shasi kanth
shasi kanth

Reputation: 7094

Assuming Monday as the first day of the week, this works:

echo date("M-d-y", strtotime('last monday', strtotime('next week', time())));

Upvotes: 12

Yevgeniy Afanasyev
Yevgeniy Afanasyev

Reputation: 41360

You can use Carbon library as well

$dateString = '02-21-2015'; // example in format MM-dd-yyyy
$date = Carbon::createFromFormat('m-d-Y', $dateString);
$date->hour(0)->minute(0)->second(0)->startOfWeek();
$dateString = $date->Format('m-d-Y'); // and you have got a string value "02-16-2015"

Upvotes: 0

Henry Weber
Henry Weber

Reputation: 681

If you want Monday as the start of your week, do this:

$date = '2015-10-12';
$day = date('N', strtotime($date));
$week_start = date('Y-m-d', strtotime('-'.($day-1).' days', strtotime($date)));
$week_end = date('Y-m-d', strtotime('+'.(7-$day).' days', strtotime($date)));

Upvotes: 2

dipser
dipser

Reputation: 442

This is the shortest and most readable solution I found:

    <?php
    $weekstart = strtotime('monday this week');
    $weekstop = strtotime('sunday this week 23:59:59');
    //echo date('d.m.Y H:i:s', $weekstart) .' - '. date('d.m.Y H:i:s', $weekstop);
    ?>

strtotime is faster than new DateTime()->getTimestamp().

Upvotes: 4

zanderwar
zanderwar

Reputation: 3730

I found this quite frustrating given that my timezone is Australian and that strtotime() hates UK dates.

If the current day is a Sunday, then strtotime("monday this week") will return the day after.

To overcome this:

Caution: This is only valid for Australian/UK dates

$startOfWeek = (date('l') == 'Monday') ? date('d/m/Y 00:00') : date('d/m/Y', strtotime("last monday 00:00"));
$endOfWeek = (date('l') == 'Sunday') ? date('d/m/Y 23:59:59') : date('d/m/Y', strtotime("sunday 23:59:59"));

Upvotes: 1

Anton Popov
Anton Popov

Reputation: 191

The easiest way to get first day(Monday) of current week is:

strtotime("next Monday") - 604800;

where 604800 - is count of seconds in 1 week(60*60*24*7).

This code get next Monday and decrease it for 1 week. This code will work well in any day of week. Even if today is Monday.

Upvotes: 1

I use it:

$firstDate = date( 'Y-m-d', strtotime( 'Last Monday', strtotime('-1 week') ));
$lastDate = date( 'Y-m-d', strtotime( 'First Sunday', strtotime('-1 week') ));

Hope this help you!

Upvotes: 0

Raja Ram T
Raja Ram T

Reputation: 9071

Very simple to use strtotime function:

echo date("Y-m-d", strtotime('monday this week')), "\n";   

echo date("Y-m-d", strtotime('sunday this week')), "\n";

It differs a bit across PHP versions:

Output for 5.3.0 - 5.6.6, php7@20140507 - 20150301, hhvm-3.3.1 - 3.5.1

2015-03-16
2015-03-22

Output for 4.3.5 - 5.2.17

2015-03-23
2015-03-22

Output for 4.3.0 - 4.3.4

2015-03-30
2015-03-29

Comparing at Edge-Cases

Relative descriptions like this week have their own context. The following shows the output for this week monday and sunday when it's a monday or a sunday:

$date = '2015-03-16'; // monday
echo date("Y-m-d", strtotime('monday this week', strtotime($date))), "\n";   
echo date("Y-m-d", strtotime('sunday this week', strtotime($date))), "\n";

$date = '2015-03-22'; // sunday
echo date("Y-m-d", strtotime('monday this week', strtotime($date))), "\n";   
echo date("Y-m-d", strtotime('sunday this week', strtotime($date))), "\n";

Againt it differs a bit across PHP versions:

Output for 5.3.0 - 5.6.6, php7@20140507 - 20150301, hhvm-3.3.1 - 3.5.1

2015-03-16
2015-03-22
2015-03-23
2015-03-29

Output for 4.3.5 - 5.0.5, 5.2.0 - 5.2.17

2015-03-16
2015-03-22
2015-03-23
2015-03-22

Output for 5.1.0 - 5.1.6

2015-03-23
2015-03-22
2015-03-23
2015-03-29

Output for 4.3.0 - 4.3.4

2015-03-23
2015-03-29
2015-03-30
2015-03-29

Upvotes: 100

Fedy Venom
Fedy Venom

Reputation: 399

$monday = date('d-m-Y',strtotime('last monday',strtotime('next monday',strtotime($date))));

You have to get next monday first then get the 'last monday' of next monday. So if the given date is monday it will return the same date not last week monday.

Upvotes: 3

NotJay
NotJay

Reputation: 4076

I was searching for a solution similar to this and I finally came up with something that will return each day of the current week.

//set current timestamp
$today = time();
//calculate the number of days since Monday
$dow = date('w', $today);
  $offset = $dow - 1;
if ($offset < 0) {
  $offset = 6;
  }
//calculate timestamp for Monday and Sunday
$monday = $today - ($offset * 86400);
$tuesday = $monday + (1 * 86400);
$wednesday = $monday + (2 * 86400);
$thursday = $monday + (3 * 86400);
$friday = $monday + (4 * 86400);
$saturday = $monday + (5 * 86400);
$sunday = $monday + (6 * 86400);
//print dates for Monday and Sunday in the current week
print date("Y-m-d", $monday) . "\n";
print date("Y-m-d", $tuesday) . "\n";
print date("Y-m-d", $wednesday) . "\n";
print date("Y-m-d", $thursday) . "\n";
print date("Y-m-d", $friday) . "\n";
print date("Y-m-d", $saturday) . "\n";
print date("Y-m-d", $sunday) . "\n";

Thank you to dbunic who posted this here: http://www.redips.net/php/week-list-current-date/#comments

Upvotes: 0

Jacek Pietal
Jacek Pietal

Reputation: 2019

this one is prepared for today is monday

function lastMonday(\DateTime $date) {

    $timestamp = $date->getTimestamp();

    $monday = ( 1 == date( 'N', $timestamp ));

    if ($monday) {
        return $timestamp;
    } else {
        return strtotime( 'last monday', $timestamp );
    }
}

if you want it to get timestamp instead of DateTime change first two lines (get rid of date->getTimestamp) change them to just this

function lastMonday($timestamp) {

and if you want it to input string change first two lines to this

function lastMonday($dateString) {

    $timestamp = strtotime($dateString);

Upvotes: 0

sweaty
sweaty

Reputation: 389

I found this solution helpful. Just subtract if it isn't monday to get the previous Monday. I am using $lower_date as the date I pulled from a query that I then need to reconcile to the previous Monday.

//set this up to go backwards until you find monday
while(date('D',strtotime($lower_date))!='Mon'){
    $lower_date = date('Y-m-d', strtotime($lower_date . ' - 1 day')); //increase the upper spec
}

Upvotes: 0

ThEBiShOp
ThEBiShOp

Reputation: 516

This is what I am using to get the first and last day of the week from any date. In this case, monday is the first day of the week...

$date = date('Y-m-d') // you can put any date you want
$nbDay = date('N', strtotime($date));
$monday = new DateTime($date);
$sunday = new DateTime($date);
$monday->modify('-'.($nbDay-1).' days');
$sunday->modify('+'.(7-$nbDay).' days');

Upvotes: 8

Michael Pawlowsky
Michael Pawlowsky

Reputation: 172

Another way to do it....

$year = '2014';
$month = '02';
$day = '26';

$date = DateTime::createFromFormat('Y-m-d H:i:s', $year . '-' . $month . '-' . $day . '00:00:00');
$day = date('w', $date->getTimestamp());

// 0=Sunday 6=Saturday
if($day!=0){

   $newdate = $date->getTimestamp() - $day * 86400;  //86400 seconds in a day

   // Look for DST change 
   if($old = date('I', $date->getTimestamp()) != $new = date('I', $newdate)){
       if($old == 0){
           $newdate -= 3600;  //3600 seconds in an hour
       } else {
           $newdate += 3600;
       }
   }

   $date->setTimestamp($newdate);
}

echo $date->format('D Y-m-d H:i:s');

Upvotes: 1

vascowhite
vascowhite

Reputation: 18440

This question needs a good DateTime answer:-

function firstDayOfWeek($date)
{
    $day = DateTime::createFromFormat('m-d-Y', $date);
    $day->setISODate((int)$day->format('o'), (int)$day->format('W'), 1);
    return $day->format('m-d-Y');
}

var_dump(firstDayOfWeek('06-13-2013'));

Output:-

string '06-10-2013' (length=10)

This will deal with year boundaries and leap years.

Upvotes: 20

user195257
user195257

Reputation: 3316

$today_day = date('D'); //Or add your own date
$start_of_week = date('Ymd');
$end_of_week = date('Ymd');

if($today_day != "Mon")
    $start_of_week = date('Ymd', strtotime("last monday"));

if($today_day != "Sun")
                    $end_of_week = date('Ymd', strtotime("next sunday"));

Upvotes: 2

David Jashi
David Jashi

Reputation: 4511

Given PHP version pre 5.3 following function gives you a first day of the week of given date (in this case - Sunday, 2013-02-03):

<?php
  function startOfWeek($aDate){
    $d=strtotime($aDate);
    return strtotime(date('Y-m-d',$d).' - '.date("w",$d).' days');
  }

  echo(date('Y-m-d',startOfWeek("2013-02-07")).'
');
?>

Upvotes: 2

CoffeJunky
CoffeJunky

Reputation: 1087

What about:

$date = "2013-03-18"; 
$searchRow = date("d.m.Y", strtotime('last monday',strtotime($date." + 1 day")));
echo "for date " .$date ." we get this monday: " ;echo $searchRow; echo '<br>';

Its not the best way but i tested and if i am in this week i get the correct monday, and if i am on a monday i will get that monday.

Upvotes: 0

JadedCore
JadedCore

Reputation: 2011

Here is what I am using...

$day = date('w');
$week_start = date('m-d-Y', strtotime('-'.$day.' days'));
$week_end = date('m-d-Y', strtotime('+'.(6-$day).' days'));

$day contains a number from 0 to 6 representing the day of the week (Sunday = 0, Monday = 1, etc.).
$week_start contains the date for Sunday of the current week as mm-dd-yyyy.
$week_end contains the date for the Saturday of the current week as mm-dd-yyyy.

Upvotes: 170

Related Questions