I'm off by one day. How can I fix it?

Below is a screenshot of a calendar I'm building. Check it out:

screenshot.JPG
Every column is labeled according to the date that particular week begins, which is a Sunday. At least, that's the idea.

Here's what I'm using to craft those dates:

First, I look to see if the week_number is embedded in the URL. If not, we calculate the beginning date of this week according to today's date:

	if(!isset($_GET['week_number']))
		{
			$day = date('w');
			$week_start = date('c', strtotime('-'.$day.' days'));
		}
		else
		{
			$date = date_create();
			date_isodate_set($date, $this_year, $_GET['week_number']);
			$week_start= date_format($date, 'Y-m-d');
		}

Open in new window


Now I either add or subtract weeks to get my column headings. Like this:

$this_week = date('c', strtotime($week_start));
		$week_one = date('c', strtotime("$this_week - 6 weeks"));
		$week_two = date('c', strtotime("$this_week - 5 weeks"));
		$week_three = date('c', strtotime("$this_week - 4 weeks"));
		$week_four = date('c', strtotime("$this_week - 3 weeks"));
		$week_five = date('c', strtotime("$this_week - 2 weeks"));
		$week_six = date('c', strtotime("$this_week - 1 week"));
		//$week_seven is documented as $week_start
		$week_eight = date('c', strtotime("$this_week + 1 week"));
		$week_nine = date('c', strtotime("$this_week + 2 weeks"));
		$week_ten = date('c', strtotime("$this_week + 3 weeks"));
		$week_eleven = date('c', strtotime("$this_week + 4 weeks"));
		$week_twelve = date('c', strtotime("$this_week + 5 weeks"));
		$week_thirteen = date('c', strtotime("$this_week + 6 weeks"));

Open in new window


Thing is, I'm off by one day. If you look at my screenshot, instead of the day of this week being 9/13/2015, it's 9/14/2015. How can I fix that?
Bruce GustPHP DeveloperAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Ray PaseurCommented:
Here's how I might do it... Just get all of the Sundays into an array (or all of the days of the year - it's still a short array) then you can reduce the amount of code and get accurate information from the PHP date/time algorithms.  Be careful about your timezone settings, too.  Some of the PHP algorithms will assume you're in UTC unless you tell them otherwise with a timezone setting.  I'm several hours away from UTC and this can cause the appearance of the wrong date during some parts of the day.
Ray PaseurCommented:
This will ensure that you're working with good data.  And with OOP notation you can get of all the fiddly quotation marks!
<?php // demo/temp_brucegust.php

/**
 * http://www.experts-exchange.com/questions/28714666/How-can-I-add-a-week-to-this-date.html
 * http://www.experts-exchange.com/articles/201/Handling-Date-and-Time-in-PHP-and-MySQL.html
 * http://www.experts-exchange.com/articles/20920/Handling-Date-and-Time-in-PHP-and-MySQL-OOP-Version.html
 * http://php.net/manual/en/datetime.setisodate.php
 * http://php.net/manual/en/datetime.format.php
 * http://php.net/manual/en/function.date.php
 */
error_reporting(E_ALL);
echo '<pre>';

// WE WILL USE THE OOP DATE OBJECT
$date = new DateTime();

// WE SILL CREATE OUR OWN CLASS TO HOLD THE PROPERTIES WE NEED FOR EACH DATE
Class MyDate
{
    // STORES THE PROPERTIES FROM THE DATETIME->FORMAT()
    public $Y, $m, $d, $w;     // YEAR  see PHP date()
    public $D, $l, $z;         // DAY   D == abbrev, ell == full day name, z == index number
    public $M, $F, $t;         // MONTH M == abbrev, F == full month name, t == number of days

    public function __Construct($datetime)
    {
        $this->Y = $datetime->format('Y');
        $this->m = $datetime->format('m');
        $this->d = $datetime->format('d');
        $this->w = $datetime->format('w');
        $this->D = $datetime->format('D');
        $this->l = $datetime->format('l');
        $this->z = $datetime->format('z');
        $this->M = $datetime->format('M');
        $this->F = $datetime->format('F');
        $this->t = $datetime->format('t');
    }
}

$array = [];
$alpha = new DateTime('2015-01-01');
$omega = new DateTime('2015-12-31');
$intvl = new DateInterval('P1D');
while ($alpha <= $omega)
{
    $array[] = new MyDate($alpha);
    $alpha->add($intvl);
}
print_r($array);

Open in new window

Ray PaseurCommented:
Hmm... Or maybe this will help.  ISO Week numbers are somewhat quirky.
<?php // demo/temp_brucegust.php

/**
 * http://www.experts-exchange.com/questions/28714666/How-can-I-add-a-week-to-this-date.html
 *
 * http://www.experts-exchange.com/articles/201
 * http://www.experts-exchange.com/articles/20920
 * http://php.net/manual/en/datetime.setisodate.php
 * http://php.net/manual/en/datetime.format.php
 * http://php.net/manual/en/function.date.php
 */
error_reporting(E_ALL);
echo '<pre>';


// IF WE HAVE A REQUEST
$get
= !empty($_GET['d'])
? $_GET['d']
: 'TODAY'
;


// USE THE REQUEST OR, ON FAILURE, USE "TODAY"
try
{
    $dateobj = new DateTime($get);
}
catch(Exception $e)
{
    $dateobj = new DateTime('TODAY');
}

$get = $dateobj->format('Y-m-d');


// SHOW THE REPRESENTATION OF THE REQUESTED WEEK
$thing = weekly_calendar($get);
print_r($thing);


function weekly_calendar($input='TODAY')
{
    $dateobj = new DateTime($input);

    // WE WILL NEED TO ADD ONE DAY TO OUR OBJECTS
    $intvl_p1d = new DateInterval('P1D');

    // NORMALIZE TO THE ISO-8601 DATE WITHOUT TIME
    $ymd = $dateobj->format('Y-m-d');
    $day = $dateobj->format('D');

    // THE WEEKLY CALENDAR WILL START ON SUNDAY AND END ON SATURDAY
    if ($day == 'Sun')
    {
        $alphaobj = new DateTime($ymd);
        $alpha    = $ymd;
    }
    else
    {
        $alphaobj = new DateTime($dateobj->format('Y-m-d') . ' LAST SUNDAY');
        $alpha    = $alphaobj->format('Y-m-d');
    }

    $omegaobj = new DateTime($alphaobj->format('Y-m-d') . ' SATURDAY');
    $omega    = $omegaobj->format('Y-m-d');

    // THE PREV AND NEXT WEEKS WILL BE COMPUTED FROM THE CURRENT DAY
    $prevobj = new DateTime($ymd . ' - 1 WEEK');
    $prev    = $prevobj->format('Y-m-d');
    $nextobj = new DateTime($ymd . ' + 1 WEEK');
    $next    = $nextobj->format('Y-m-d');

    // MAKE THE URLS
    $prev_uri = $_SERVER['PHP_SELF'] . "?d=$prev";
    $next_uri = $_SERVER['PHP_SELF'] . "?d=$next";

    // MAKE THE LINK TEXTS
    $prev_lnk = '<a href="' . $prev_uri . '">Prev</a>';
    $next_lnk = '<a href="' . $next_uri . '">Next</a>';

    // MAKE THE REPRESENTATION OF THE WEEK
    $week['prev'] = $prev_lnk;
    while ($alphaobj <= $omegaobj)
    {
        // A TEXT VERSION OF THE WEEKDAY
        $day = $alphaobj->format('D');
        $txt = $alphaobj->format('D m/d');
        $ymd = $alphaobj->format('Y-m-d');

        // URL AND LINK TEXT
        $curr_uri = $_SERVER['PHP_SELF'] . "?d=$ymd";
        $curr_lnk = '<a href="' . $curr_uri . '">' . $txt . '</a>';

        $week[$day] = $curr_lnk;

        // ON TO THE NEXT DAY
        $alphaobj->add($intvl_p1d);
    }
    $week['next'] = $next_lnk;

    return $week;
}

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Bruce GustPHP DeveloperAuthor Commented:
That's the ticket, Ray!

Thank you, sir!
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.