strtotime

(PHP 4, PHP 5, PHP 7)

strtotime — Parse about any English textual datetime description into a Unix timestamp

Description

strtotime
( string$time
[, int$now = time()
] ) : int

The function expects to be given a string containing an English date format
and will try to parse that format into a Unix timestamp (the number of
seconds since January 1 1970 00:00:00 UTC), relative to the timestamp given
in now, or the current time if
now is not supplied.

Each parameter of this function uses the default time zone unless a
time zone is specified in that parameter. Be careful not to use
different time zones in each parameter unless that is intended.
See date_default_timezone_get() on the various
ways to define the default time zone.

Parameters

The timestamp which is used as a base for the calculation of relative
dates.

Return Values

Returns a timestamp on success, FALSE otherwise. Previous to PHP 5.1.0,
this function would return -1 on failure.

Errors/Exceptions

Every call to a date/time function will generate a E_NOTICE
if the time zone is not valid, and/or a E_STRICT
or E_WARNING message
if using the system settings or the TZ environment
variable. See also date_default_timezone_set()

Changelog

Version

Description

5.3.0

Prior to PHP 5.3.0, relative time formats supplied to the
time argument of strtotime()
such as this week, previous week,
last week, and next week were
interpreted to mean a 7 day period relative to the current date/time, rather
than a week period of Monday through Sunday.

5.3.0

Prior to PHP 5.3.0, 24:00 was not a valid format and
strtotime() returned FALSE.

5.2.7

In PHP 5 prior to 5.2.7, requesting a given occurrence of a
given weekday in a month where that weekday was the first day
of the month would incorrectly add one week to the returned
timestamp. This has been corrected in 5.2.7 and later
versions.

5.1.0

Now returns FALSE on failure, instead
of -1.

5.1.0

Now issues the E_STRICT and E_NOTICE
time zone errors.

5.0.2

In PHP 5 up to 5.0.2, "now" and other
relative times are wrongly computed from today's
midnight. This differs from other versions where it is
correctly computed from current time.

Notes

Note:

If the number of the year is specified in a two digit format, the values
between 00-69 are mapped to 2000-2069 and 70-99 to 1970-1999. See the notes
below for possible differences on 32bit systems (possible dates might end on
2038-01-19 03:14:07).

Note:

The valid range of a timestamp is typically from Fri, 13 Dec
1901 20:45:54 UTC to Tue, 19 Jan 2038 03:14:07 UTC. (These are
the dates that correspond to the minimum and maximum values for
a 32-bit signed integer.)

Prior to PHP 5.1.0, not all platforms support negative timestamps, therefore
your date range may be limited to no earlier than the Unix epoch. This
means that e.g. dates prior to Jan 1, 1970 will not work on Windows,
some Linux distributions, and a few other operating systems.

For 64-bit versions of PHP, the valid range of a timestamp is effectively
infinite, as 64 bits can represent approximately 293 billion years in either
direction.

Note:

Dates in the m/d/y or d-m-y formats
are disambiguated by looking at the separator between the various
components: if the separator is a slash (/), then the
American m/d/y is assumed; whereas if the separator is a
dash (-) or a dot (.), then the
European d-m-y format is assumed.
If, however, the year is given in a two digit format and the separator is a
dash (-), the date string is parsed as
y-m-d.

User Contributed Notes 39 notes

I've had a little trouble with this function in the past because (as some people have pointed out) you can't really set a locale for strtotime. If you're American, you see 11/12/10 and think "12 November, 2010". If you're Australian (or European), you think it's 11 December, 2010. If you're a sysadmin who reads in ISO, it looks like 10th December 2011.

The best way to compensate for this is by modifying your joining characters. Forward slash (/) signifies American M/D/Y formatting, a dash (-) signifies European D-M-Y and a period (.) signifies ISO Y.M.D.

One important thing you should remember is that the timestamp value returned by time() is time-zone agnostic and gets the number of seconds since 1 January 1970 at 00:00:00 UTC. This means that at a particular point in time, this function will return the same value in the US, Europe, India, Japan, ...

strtotime() will convert a string WITHOUT a timezone indication as if the string is a time in the default timezone ( date_default_timezone_set() ). So converting a UTC time like '2018-12-06T09:04:55' with strtotime() actually yields a wrong result. In this case use:

-------------------------------------------------------------------------------[ strtotime($utctime) - Converts $utctime as if it was in timezone Europe/Amsterdam because the string has no timezone specification ]PHP time: 1544083495--> (UTC) 2018-12-06 08:04:55--> (Europe/Amsterdam) 2018-12-06 09:04:55*/?>

Then I read the notes which said:if the separator is a slash (/), then the American m/d/y is assumed; whereas if the separator is a dash (-) or a dot (.), then the European d-m-y format is assumed. ***If, however, the year is given in a two digit format and the separator is a dash (-), the date string is parsed as y-m-d.***

Therefore, the above code does not work on 2 digit years - only 4 digit years

The "+1 month" issue with strtotime===================================As noted in several blogs, strtotime() solves the "+1 month" ("next month") issue on days that do not exist in the subsequent month differently than other implementations like for example MySQL.

In the above, using "next month" on January 31 will output "March" even though you might want it to output "February". ("+1 month" will give the same result. "last month", "-1 month" are similarly affected, but the results would be seen at beginning of March.)

The way to get what people would generally be looking for when they say "next month" even on Jan 30 and Jan 31 is to use "first day of next month":

The difference between 'today' and 'now' is the former strips off the time (setting it to 00:00, ie. midnight just past), and the latter includes the time - assuming UTC unless specified otherwise.

I run a theatre's website. Obviously, I need to ensure shows that have already happened do not appear on web pages, so I use something on the lines of:

$listIt = (strtotime($end_date) >= strtotime('today') ? 1 : 0);

where $end_date is the final date in a show series. So if tonight's show is the last, it will stay on the web page until 00:00 tomorrow.

I don't normally include performance times in the date field because some shows have matinées, others don't - so I use a free-form performance time field in the CMS instead (where even 'Time: TBD' is allowed). [The only instance where I DO include the time is when there are two different shows on the same day, to ensure they appear in chronological order.]

So strtotime($end_date) will always return the timestamp at 00:00 that day. If I instead used:

$listIt = (strtotime($end_date) >= strtotime('now') ? 1 : 0);

the function would return $listIt = 0 at all times today - something I don't want.

strtotime() also returns time by year and weeknumber. (I use PHP 5.2.8, PHP 4 does not support it.) Queries can be in two forms:
- "yyyyWww", where yyyy is 4-digit year, W is literal and ww is 2-digit weeknumber. Returns timestamp for first day of week (for me Monday)
- "yyyy-Www-d", where yyyy is 4-digit year, W is literal, ww is 2-digit weeknumber and dd is day of week (1 for Monday, 7 for Sunday)

You are not restricted to the same date ranges when running PHP on a 64-bit machine. This is because you are using 64-bit integers instead of 32-bit integers (at least if your OS is smart enough to use 64-bit integers in a 64-bit OS)

The following code will produce difference output in 32 and 64 bit environments.

var_dump(strtotime('1000-01-30'));

32-bit PHP: bool(false)64-bit PHP: int(-30607689600)

This is true for php 5.2.* and 5.3

Also, note that the anything about the year 10000 is not supported. It appears to use only the last digit in the year field. As such, the year 10000 is interpretted as the year 2000; 10086 as 2006, 13867 as 2007, etc

We can now do thing like this with strtotime:
<?php
$weekMondayTime = strtotime('Monday this week');
?>
However this works based on a week starting Sunday. I do not know if we can tweak this PHP behavior, anyone know?

If you want the timestamp of the start of the ISO Week (i.e. on Monday) as defined by ISO 8601, you can use this one liner:
<?php
$isoWeekStartTime = strtotime(date('o-\\WW')); // {isoYear}-W{isoWeekNumber}
?>

You can also find out the start of week of any time and format it into an ISO date with another one liner like this:
<?php
$isoWeekStartDate = date('Y-m-d', strtotime(date('o-\\WW', $time)));
?>

If you want to confront a date stored into mysql as a date field (not a datetime) and a date specified by a literal string, be sure to add "midnight" to the literal string, otherwise they won't match:

<?php//I.E.: today is 17/02/2011

echo strtotime('2011-01-01'); //1293836400echo strtotime('first day of last month'); //1293888128 Note: it's different from the previous one, since it computes also the seconds passed from midnight!!! So this one is always greater than simple '2011-01-01'echo strtotime('midnight first day of last monty');//1293836400 Note: it's the same as '2011-01-01'

Try to be as specific as you can with the string you pass in. For example

<?phpecho date('F', strtotime('February')); ?>

is not specific enough. Depending on the day of the month, you may get a different response. For a non-leap year, you'll get March if the _current day of the month_ is the 29th, 30th or 31st. If it's a leap year, you'll get March on the 30th or 31st of the month. The same thing will happen on the 31st of any month when you pass in the name of any month with less than 31 days. This happens because the strtotime() function will fill in missing parts from the current day.

Assuming today is July 31, the timestamp returned by strtotime('February') will ultimately be seen as February 31 (non-existant obviously), which then is interpreted as March 3, thus giving a month name of March.

Interestingly, adding the year or the day will give you back the expected month.

It was really pazzling to me to read about parsing a string into a Unix timestamp relative to both January 1 1970 00:00:00 UTC and the second parameter. Maybe it worth noting that the second parameter is for relative dates (like "+1 day").

It took me a while to notice that strtotime starts searching from just after midnight of the first day of the month. So, if the month starts on the day you search for, the first day of the search is actually the next occurrence of the day.

In my case, when I look for first Tuesday of the current month, I need to include a check to see if the month starts on a Tuesday.

<?php
if (date("l", strtotime("$thisMonth$thisYear"))=='Tuesday') {
echo "<p>This month starts on a Tuesday. Use \"$thisMonth$thisYear\" to check for first Tuesday.</p>\n";
} else {
echo "<p>This month does not start on a Tuesday. Use \"first tuesday $thisMonth$thisYear\" to check for first Tuesday.</p>\n";
}
?>

Be aware that if you are running 5.2.8, there is a memory leak with this function and it could cost someone valuable time finding out what the problem was. Per usual, running the latest (minor) version tends to be a good idea.

Be aware that you cannot rely on this function alone to validate a date, as it will accept insane dates like the 31st of February.

Also, the '... week' functionality by itself may not do what you expect. If used on a Sunday, 'next week' will not return a timestamp of the next Monday, but of the Monday after that. Similarly, a timestamp for the Monday of the current week is returned when 'previous/last week' is used and 'this week' returns a stamp of the Monday of the next week (i.e. the following day). This is not the 'week starts on Sunday' effect, as that would mean all the timestamps returned would have to be on a Sunday and none of them are.

when using PHP 5.3, you must use date_default_timezone_set() to set the time zone otherwise you will get warning similar to this (if you have display_errors=On)—

Warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'Asia/Dubai' for '4.0/no DST' instead in path/to/php/script.phpon line ##