Advanced Use Of PHP Function strtotime()

Finding the next day of the week from a given date can involve some complicated loops and if statements. In PHP it is made quite easy through the use of the strtotime() function. This function, which is part of the PHP core since version 4, can take just about any string representation of the time and convert it into a Unix timestamp.

The most common use of strtotime() is to convert a string into a time. Here are some random examples, the first two convert a date and the second two print more or less the same, but (obviously) will change with time. I say more or less as the "now" parameter will return the current timestamp whereas the "today" parameter will return the timestamp from the beginning of the current day.

echo strtotime("19 September 2009"); // prints 1253228400
echo strtotime("09/19/2009 12:00"); // prints 1253358000
echo strtotime("today"); // prints 1253314800
echo strtotime("now"); // prints 1253389683

As you can see strtotime() is quite robust in the sort of arguments that can be accepted. If you try to send a time to the function that it cannot parse then it will return false. Obviously, if you pass the function something like "cat" it's going to return false, but it is possible to break it without realising it by passing a non-US formatted date.

The strtotime() function expects the value you send to be formatted with the en_US time format of month/day/year and not day/month/year so if you tried the above example with that format the function will return false.

strtotime("18/09/2009 12:00") // returns false

On the face of it this might not seem like a problem, but if you were to pass this value into the date() function to print out the date you would find the date of 1/01/1970 being printed out. This effect can also lead to issues if the date appears to be valid. There is a great deal of difference between the dates 10/01/2009 and 01/10/2009 but strtotime() will always interpret them as 10 Jan 2009 and 1st Oct 2009 respectively as it will always base the dates on the en_US time format of mm/dd/yyyy. One way to get around this is to pass the date as yyyy/mm/dd or the ISO date format. In this case 2009/10/01 will cause the function to return 1st Oct 2009.

One other thing to remember is that if you want to enter a date for pre-1969 then you need to enter the 4 digit date. According to the documentation on this function if a two digit date is entered then it sets 00-69 as 2000-2069 and 70-99 as 1970-1999.

It is also possible to do simple maths with dates using the strtotime() function. To work out the next date from a given date just add "+1 day" to the end of the date string. It is also possible to use the plural of the time period as well as the singular.

echo date('r', strtotime('19 September 2009 12:00 +1 day'));

This will print out the string "Sun, 20 Sep 2009 12:00:00 +0100". The date string is actually optional, if you want to calculate the next day from today then just enter the string with any of the following:

echo date('r', strtotime('now +1 day')); // Prints Sun, 20 Sep 2009 23:15:29 +0100
echo date('r', strtotime('today +1 day')); // Prints Sun, 20 Sep 2009 00:00:00 +0100
echo date('r', strtotime('+1 day')); // Prints Sun, 20 Sep 2009 23:15:29 +0100

This has the same output as the function above (as long as you are running it on the same date). This will work with other values and time periods. Here are a few examples of this in action.

echo date('r', strtotime('19 September 2009 12:00 +23 seconds')); // Prints Sat, 19 Sep 2009 12:00:23 +0100
echo date('r', strtotime('19 September 2009 12:00 +28 minutes')); // Prints Sat, 19 Sep 2009 12:28:00 +0100
echo date('r', strtotime('19 September 2009 12:00 +1 hour')); // Prints Sat, 19 Sep 2009 13:00:00 +0100
echo date('r', strtotime('19 September 2009 12:00 +5 day')); // Prints Thu, 24 Sep 2009 12:00:00 +0100
echo date('r', strtotime('19 September 2009 12:00 +2 weeks')); // Prints Sat, 03 Oct 2009 12:00:00 +0100
echo date('r', strtotime('19 September 2009 12:00 +1 month')); // Prints Mon, 19 Oct 2009 12:00:00 +0100
echo date('r', strtotime('19 September 2009 12:00 +3 year')); // Prints Wed, 19 Sep 2012 12:00:00 +0100

The function also accepts the value "fortnights", which is a unit of time equivalent to 14 days, or two weeks.

echo date('r', strtotime('19 September 2009 12:00 +2 fortnights')); // Prints Sat, 17 Oct 2009 12:00:00 +0100

It is also possible to minus dates and times.

echo date('r', strtotime('19 September 2009 12:00 -3 hours')); // Prints Sat, 19 Sep 2009 09:00:00 +0100
echo date('r', strtotime('19 September 2009 12:00 -4 days')); // Prints Tue, 15 Sep 2009 12:00:00 +0100
echo date('r', strtotime('19 September 2009 12:00 -3 years')); // Prints Tue, 19 Sep 2006 12:00:00 +0100

The strtotime() function can take multiple values at the same time, of any combination you want to use.

echo date('r', strtotime('19 September 2009 12:00 +1 day +2 weeks')); // Prints Sun, 04 Oct 2009 12:00:00 +0100
echo date('r', strtotime('19 September 2009 12:00 -18 days -8 months -38 years -12 hours')); // Prints Fri, 01 Jan 1971 00:00:00 +0100

The following example block contains three examples, the first two will take the strtotime() function to the theoretical maximum and the third will break it. This is because it goes beyond the range of the Unix timestamp. Any dates before 13th December 1901 20:45:54 or after the 19th January 2038 03:14:07 might cause the function to return false. These figures represent the maximum and minimum possible values of a 32-bit signed integer. I say might as 64-bit systems will be able to go 292 billion years in either direction so if you are using 63-bit you have nothing to worry about in this case.

echo date('r', strtotime('19 September 2009 12:00 +28 years +1 months')); // Prints Fri, 01 Jan 1971 00:00:00 +0100
echo date('r', strtotime('19 September 2009 12:00 -107 years -9 months -5 days')); // Prints Mon, 19 Oct 2037 12:00:00 +0100
echo date('r', strtotime('19 September 2009 12:00 +3456 years')); // Prints Thu, 01 Jan 1970 01:00:00 +0100

One final feature of the strtotime() function is the use of the "next" and "last" parameters. These allow you to simply add or subtract 1 from the date, with whatever parameter you want. It is also possible to combine next and last with days of the week to determine what date the next or last day of the week was. Here are some examples of the next and last parameters in action.

echo date('r', strtotime('last month')); // Prints Wed, 19 Aug 2009 22:29:19 +0100
echo date('r', strtotime('next week')); // Prints Sat, 26 Sep 2009 22:29:19 +0100
echo date('r', strtotime('last Friday')); // Prints Fri, 18 Sep 2009 00:00:00 +0100
echo date('r', strtotime('next Friday')); // Prints Fri, 25 Sep 2009 00:00:00 +0100

You can also pass in a date with these parameters to determine the date from that date.

echo date('r', strtotime('19 September 2009 12:00 last month')); // Prints Wed, 19 Aug 2009 22:29:19 +0100

To speed things up I created a function that will allow you to get the date of the next selected day of the week. This function takes three parameters.

  • $day - This is a required parameter and it is simply the day of the week. The function will force you to enter this as the three letter shorthand (eg. Fri for Friday) but this can easily be changed.
  • $date - This is an optional second parameter that will make the function work out the date of the next day of the week from this date. If this parameter is not given then the current date is used.
  • $format - This is an optional parameter that allows you to set the return format of the date at runtime. This is set to yyyy/mm/dd.

Here is the function.

function nextDayDate($day, $date = null, $format = "Y/m/d") 
{
    // Normalise day
    $day = ucfirst(strtolower($day));
    
    // Make sure day exists
    $days = array('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun');
    if (!in_array($day, $days)) {
        return false;
    }
    
    // Convert date (if present)
    if ($date) {
        if (!is_int($date)) {
            $date = strtotime($date);
        }
    } else {
        $date = time();
    }
 
    // Work out date
    if (date("D", $date) == $day) {
        //today is friday
        $currentdate = date($format, $date);
    } else {
        $currentdate = date($format, strtotime("next " . $day . " " . date('Y/m/d', $date)));
    }
 
    return $currentdate;
}

Here are some examples of this function in action. Note that of you pass a day of the week that isn't valid the function will return false.

echo nextDayDate("Mon"); // Prints 2009/09/21
echo nextDayDate("Wed"); // Prints 2009/09/23
echo nextDayDate("Inv"); // Prints nothing
echo nextDayDate("Fri", time()); // Prints 2009/09/25
echo nextDayDate("Mon", '2009/09/18'); // Prints 2009/09/21
echo nextDayDate("Fri", '12/12/2000'); // Prints 2000/12/15
echo nextDayDate("Sat", '02/06/92'); // Prints 1992/02/08
echo nextDayDate("Sat", '', 'D'); // Prints Sat
echo nextDayDate("Sat", null, 'd/m/Y'); // Prints 19/09/2009
echo nextDayDate("Sat", '123456', 'r'); // Prints Sat, 19 Sep 2009 12:34:56 +0100

Finally there are two things to remember when using strtotime(). The first is that if you are not completely sure about the format of the time then you are probably best either introducing a proceeding step that parses the date string and reformats it, or just working the date out manually.

The second thing to be wary of is that previous versions of this function have got things wrong. There are errors that add one week to calculations when figuring out the weekday of a month if that day happens to lie on the first day of the month or that add +2 instead of +1 when using the next parameter. Things have got better with newer versions of PHP, but if you are relying on absolutely second perfect values for your calculations I think it is probably best just to figure out the value in seconds and add this to a timestamp, rather than let strtotime() handle things.

Comments

Thanks man for writing this function which is what exactly I was looking for.
Permalink
$date='05/13/2015 06:06 pm +0530'; $date_time = strtotime($date); and if i replace 'pm' with A,B,C,D..x,y,z ..i'm getting different times ...why is this not resulting in error if the parameter passed is wrong..?
Permalink

Wow! Finally I got a web site from where I know how to truly get useful information regarding my study and knowledge.

Permalink

What's up, I check your new stuff like every week. Your story-telling style is awesome, keep it up!

Permalink

Add new comment

The content of this field is kept private and will not be shown publicly.
CAPTCHA
5 + 0 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.