when using strtotime("wednesday"), you will get different results whether you ask before or after wednesday, since strtotime always looks ahead to the *next* weekday.
strtotime() does not seem to support forms like "this wednesday", "wednesday this week", etc.
the following function addresses this by always returns the same specific weekday (1st argument) within the *same* week as a particular date (2nd argument).
function weekday($day="", $now="") {
$now = $now ? $now : "now";
$day = $day ? $day : "now";
$rel = date("N", strtotime($day)) - date("N");
$time = strtotime("$rel days", strtotime($now));
return date("Y-m-d", $time);
}
example use:
weekday("wednesday"); // returns wednesday of this week
weekday("monday, "-1 week"); // return monday the in previous week
ps! the ? : statements are included because strtotime("") without gives 1 january 1970 rather than the current time which in my opinion would be more intuitive...
strtotime
(PHP 4, PHP 5)
strtotime — Wandelt ein beliebiges in englischer Textform angegebenes Datum in einen UNIX-Zeitstempel (Timestamp) um
Beschreibung
$time
[, int $now
] )
Diese Funktion erwartet einen String mit einem Datum im Englischen
Datumsformat und versucht, dieses Format in einen Unix-Timestamp (die Anzahl
der Sekunden seit dem 01. Januar 1970 00:00:00 UTC) zu übersetzen. Die Angabe
wird relativ zum im now-Parameter übergebenen
Timestamp oder der aktuellen Zeit, sofern now nicht
übergeben wurde, ausgewertet.
Die Funktion verwendet, sofern diese verfügbar ist, die TZ-Umgebungsvariable um den Timestamp zu berechnen. Seit PHP 5.1.0 gibt es einfachere Wege, die zu verwendende Zeitzone festzulegen, die mit allen Datums- und Zeitfunktionen verwendet werden soll. Ausführlichere Erklärungen dazu finden Sie auf der date_default_timezone_get()-Manualseite.
Parameter-Liste
-
time -
Ein Datums/Zeit Zeichenkette. Gültige Formate werden unter Datums- und Zeitformate erläutert.
-
now -
Der Timestamp, der als Basis zur Berechnung relativer Daten verwendet wird.
Rückgabewerte
Gibt im Erfolgsfall einen Timestamp, andernfalls FALSE zurück. Vor PHP 5.1.0
gab die Funktion -1 im Fehlerfall zurück.
Fehler/Exceptions
Jeder Aufruf der Datums- und Zeitfunktionen
generiert eine E_NOTICE-Warnung,
wenn die Zeitzone ungültig ist und eine E_STRICT-Nachricht
oder eine E_WARNING-Warnung,
wenn die Systemeinstellung oder die TZ-Umgebungsvariable
genutzt wird. Siehe auch date_default_timezone_set()
Changelog
| Version | Beschreibung |
|---|---|
| 5.3.0 |
Vor PHP 5.3.0 war 24:00 keine korrekte Formatierung,
daher gab strtotime() FALSE zurück.
|
| 5.2.7 | Wird in PHP 5 vor Version 5.2.7 ein gegebenes Vorkommen eines angegebenen Wochentages eines Monats abgefragt, der der erste Tag des Monats ist, wird eine Woche zum zurückgegebenen Zeitstempel addiert. Dieser Fehler ist in Version 5.2.7 und später korrigiert. |
| 5.1.0 |
Im Fehlerfall wird FALSE statt -1 zurückgegeben.
|
| 5.1.0 |
Erzeugt nun |
| 5.0.2 | In PHP 5 bis 5.0.2 werden "now" und andere relative Zeitangaben fälschlicherweise ab dem Zeitpunkt des Datumswechsels berechnet. Dieses Verhalten unterscheidet sich von anderen Versionen, die diese Angaben in die korrekte aktuelle Zeit übersetzen. |
| 5.0.0 | Die Angabe von Mikrosekunden ist erlaubt, wird aber ignoriert. |
| 4.4.0 | In PHP-Versionen vor 4.4.0 wird "next" fälschlicherweise als +2 interpretiert. Eine einfache Lösung für dieses Problem ist, explizit +1 zu verwenden. |
Beispiele
Beispiel #1 Ein strtotime()-Beispiel
<?php
echo strtotime("now"), "\n";
echo strtotime("10 September 2000"), "\n";
echo strtotime("+1 day"), "\n";
echo strtotime("+1 week"), "\n";
echo strtotime("+1 week 2 days 4 hours 2 seconds"), "\n";
echo strtotime("next Thursday"), "\n";
echo strtotime("last Monday"), "\n";
?>
Beispiel #2 Test auf Fehler
<?php
$str = 'Not Good';
// vor PHP 5.1.0 wuerden Sie -1 statt false als Rueckgabewert erhalten
if (($timestamp = strtotime($str)) === false) {
echo "Die Zeichenkette ($str) ist nicht parsebar.";
} else {
echo "$str == " . date('l dS \o\f F Y h:i:s A', $timestamp);
}
?>
Anmerkungen
Hinweis:
Wenn die Jahreszahlenangabe zweistellig erfolgt, werden Werte zwischen 00 und 69 auf die Jahre 2000 bis 2069 gemappt, die Werte 70-99 ergeben die Jahreszahlen 1970-1999. Beachten Sie die folgenden Anmerkungen bezüglich der Unterschiede auf 32-Bit-Systemen (das Datum endet möglicherweise am 2038-01-19 03:14:07).
Hinweis:
Der gültige Bereich eines Timestamp liegt typischerweise zwischen Fri, 13 Dec 1901 20:45:54 UTC und Tue, 19 Jan 2038 03:14:07 UTC. (Das sind die Datumsangaben, die dem minimalen und maximalen Wert eines vorzeichenbehafteten 32-bit Integer entsprechen.) Zusätzlich unterstützen nicht alle Plattformen negative Werte eines Timestamps, deshalb könnte der Wertebereich eines Datums durch den Beginn der Unix Epoche begrenzt sein. Das bedeutet, dass z.B. Zeitangaben vor dem 1. Januar 1970 auf Windowssystemen, einigen Linuxdistributionen und einigen anderen Betriebssytemen nicht funktionieren. Die PHP-Versionen 5.1.0 und neuer heben diese Beschränkung auf.
Für 64 Bit Versionen von PHP ist der gültige Bereich für Timestamps praktisch unendlich groß, da 64 Bit etwa 293 Milliarden Jahre in beide Richtungen darstellen können.
Hinweis:
Daten im Format m/d/y oder d-m-y werden unterschieden anhand des genutzten Trennzeichens: Wenn ein Slash (/) genutzt wird, wird das Amerikanische Format m/d/y angenommen; wird stattdessen ein Minus (-) oder ein Punkt (.) genutzt, wird das Europäische Format d-m-y angenommen.
Um Mehrdeutigkeiten zu vermeiden sollten am besten ISO 8601 Daten (YYYY-MM-DD) genutzt werden oder aber die Methode DateTime::createFromFormat() verwendet werden.
Siehe auch
- DateTime::createFromFormat() - Returns new DateTime object formatted according to the specified format
- checkdate() - Prüft ein Gregorianisches Datum auf Gültigkeit
- strptime() - Parse a time/date generated with strftime
strtotime
07-Jul-2007 07:47
01-Jul-2007 04:54
To calculate the last Friday in the current month, use strtotime() relative to the first day of next month:
<?php
$lastfriday=strtotime("last Friday",mktime(0,0,0,date("n")+1,1));
?>
If the current month is December, this capitalises on the fact that the mktime() function correctly accepts a month value of 13 as meaning January of the next year.
01-Jun-2007 05:10
Note about strtotime() when trying to figure out the NEXT month...
strtotime('+1 months'), strtotime('next month'), and strtotime('month') all work fine in MOST circumstances...
But if you're on May 31 and try any of the above, you will find that 'next month' from May 31 is calculated as July instead of June....
13-May-2007 05:41
One more difference between php 4 and 5 (don't know when they changed this) but the string 15 EST 5/12/2007 parses fine with strtotime in php 4, but returns the 1969 date in php 5. You need to add :00 to make it 15:00 so php can tell those are hours. There's no change in php 4 when you do this.
08-Apr-2007 03:31
This function inputs a date sting and outputs an integer that is the internal representation of days that spreadsheets use. Post this value into a cell, then format that cell as a Date.
function conv_to_xls_date($Date) {
// Returns the Excel/Calc internal date integer from either an ISO date YYYY-MM-DD or MM/DD/YYYY formats.
return (int) (25569 + (strtotime("$Date 12:00:00") / 86400));
}
example:
$Date = "04-07-2007";
$Days = conv_to_xls_date($Date);
$Days will contain 39179
SQL datetime columns have a much wider range of allowed values than a UNIX timestamp, and therefore this function is not safe to use to convert a SQL datetime column to something usable in PHP4. Year 9999 is the limit for MySQL, which obviously exceeds the UNIX timestamp's capacity for storage. Also, dates before 1970 will cause the function to fail (at least in PHP4, don't know about 5+), so for example my boss' birthday of 1969-08-11 returned FALSE from this function.
[red. The function actually supports it since PHP 5.1, but you will need to use the new object oriented methods to use them. F.e:
<?php
$date = new DateTime('1969-08-11');
echo $date->format('m d Y');
?>
]
09-Feb-2007 09:29
Regarding the "NET" thing, it's probably parsing it as a time-zone. If you give strtotime any timezone string (like PST, EDT, etc.) it will return the time in that time-zone.
In any case, you shouldn't use strtotime to validate dates. It can and will give incorrect results. As just one shining example:
Date: 05/01/2007
To most Americans, that's May 1st, 2007. To most Europeans, that's January 5th, 2007. A site that needs to serve people around the globe cannot use strtotime to validate or even interpret dates.
The only correct way to parse a date is to mandate a format and check for that specific format (preg_match will make your life easy) or to use separate form fields for each component (which is basically the same thing as mandating a format).
23-Jan-2007 10:17
Somewhere between PHP5.0 and PHP5.1.6, strtotime started accepting '.' (period, dot) as well as ':' (colon) as a time separator.
before: "2.30pm" == -1
after: "2.30pm" == 14:30
[red.: This is working since PHP 5.1.0]
16-Jan-2007 11:47
A hint not to misunderstand the second parameter:
The parameter "[, int now]" is only used for strings which describe a time difference to another timestamp.
It is not possible to use strtotime() to calculate a time difference by passing an absolute time string, and another timestamp to compare to!
Correct:
$day_before = strtotime("+1 day", $timestamp);
# result is a timestamp relative to another
Wrong:
$diff = strtotime("2007-01-15 11:40:00", time());
# result it the timestamp for the date in the string;
# because the string contains an absolute date and time,
# the second parameter is ignored!
# instead, use:
$diff = time() - strtotime("2007-01-15 11:40:00");
Be careful, strtotime("+1 month", strtotime("2006-05-31"));
returns 2006-07-01!
05-Oct-2006 09:02
The following might produce something different than you might expect:
<?php
echo date('l, F jS Y', strtotime("third wednesday", strtotime("2006-11-01"))) . "<br>";
echo date('l, F jS Y', strtotime("third sunday", strtotime("2006-01-01")));
?>
Produces:
Wednesday, November 22nd 2006
Sunday, January 22nd 2006
The problem stems from strtotime when the requested day falls on the date passed to strtotime. If you look at your calendar you will see that they should return:
Wednesday, November 15th 2006
Sunday, January 15th 2006
Because the date falls on the day requested it skips that day.
11-May-2006 12:18
The GNU manual page has moved, the new address is
http://www.gnu.org/software/shishi/manual/html_node/Date-input-formats.html
11-Apr-2006 01:08
I have had some inconsistancies that was not immediately evident and suggested that strtotime treated my date formats in different ways.
I had trouble with the date format: d/m/Y
I eliminated the inconsistancies by changing the date format to one where (i guess) php does not try and guess the right format. In my case I changed it to the format (d-M-Y) in which case it worked.
Example when trying to find a person's age where:
//$date in format (d/m/Y) was inconsistant but fixed when in format (d-M-Y), e.g. (01-January-2001)
$age = (time() - strtotime($date))/(60*60*24*360);
24-Jan-2006 07:18
It looks like in the latest release of PHP 5.1, when passing to strtotime this string "12/32/2005", it will now return the date "12/31/1969". (The previous versions would return "1/1/2006".)
18-Jan-2006 01:32
Regarding the previous post on strtotime() being used to convert mysql datetime strings, I agree that this is not widely realized.
Part of the reason for this is that it is only a relatively recent addition. Prior to PHP 5.0, though it might have been an earlier version, strtotime() would return -1 on a mysql datetime string.
If you're on a server that doesn't have a recent PHP version test your result before assuming this one works.
11-Jan-2006 05:13
I'm posting these here as I believe these to be design changes, not bugs.
For those upgrading from PHP 4 to PHP 5 there are a number of things that are different about strtotime that I have NOT seen documented elsewhere, or at least not as clearly. I confirmed these with two separate fresh installations of PHP 4.4.1 and PHP 5.1.1.
1) Given that today is Tuesday: PHP4 "next tuesday" will return today. PHP5 "next tuesday" will actually return next tuesday as in "today +1week". Note that behavior has NOT changed for "last" and "this". For the string "last tuesday" both PHP4 and PHP5 would return "today -1week". For the string "this tuesday" both PHP4 and PHP5 would return "today".
2) You cannot include a space immediately following a + or - in PHP 5. In PHP4 the string "today + 1 week" works great. in PHP5 the string must be "today +1 week" to correctly parse.
3) (Partially noted in changelog.) If you pass php4 a string that is a mess ("asdf1234") it will return -1. If you in turn pass this to date() you'll get a warning like: Windows does not support dates prior to midnight. This is pretty useful for catching errors in your scripts. In PHP 5 strtotime will return FALSE which causes date() to return 12/31/69. Note that this is true of strings that might appear right such as "two weeks".
4) (Partially noted in changelog.) If you pass php4 an empty string it will error out with a "Notice: strtotime(): Called with empty time parameter". PHP5 will give no notice and return the current date stamp. (A much preferred behavior IMO.)
5) Some uppercase and mixed-case strings no longer parse correctly. In php4 "Yesterday" would parse correctly. In php5 "Yesterday" will return the infamous 1969 date. This is also true of Tomorrow and Today. [Red. This has been fixed in PHP already]
6. The keyword "previous" is supported in PHP5. (Finally!)
Good luck with your upgrades. :)
-Will
10-Jan-2006 03:10
@ nick at fortawesome dot co dot uk
regarding 'month' vs 'next month'
Not sure what version of PHP you found those results on, however with PHP 4.4.0,
<?PHP
$time1=strtotime('next month');
$time2=strtotime('month');
?>
produce the exact same result.
Note that by default strtotime( ) considers the string time like a local time.
If your input string time is GMT/UTC do :
<?php
$date = '2005-12-25 00:56:27 GMT' ; // Note the timezone specification
$time = strtotime($date) ;
echo date('d/m/Y H:i:s', $time) ; // $date will be correctly localized
// « 25/12/2005 01:56:27 » for France
?>
26-Oct-2005 04:03
The pluralization of "minute" or "minutes" for instance does not matter. In case you are dynamically using this function "+1 minutes" or "+2 minute" both do work.
26-Oct-2005 12:52
Note that strtotime('next month') will return 2 months from now, which may not be what you expect. strtotime('month') will do 1 month.
06-Oct-2005 11:34
Note strtotime() in PHP 4 does not support fractional seconds.
See http://bugs.php.net/bug.php?id=28717 especially if you happen to swap to ODBC for MS SQL Server and wonder what's happened!
28-Sep-2005 05:55
The PHP 5.1.0 change is a major backward compatibility break.
Now, that the returned value on failure has changed, the correct way to detect problems on all PHP versions is:
<?php
if (($time = strtotime($date)) == -1 || $time === false) {
die 'Invalid date';
}
?>
[red (derick): note, this is not 100% correct, as in this case 1969-12-31 23:59 will be thrown out as that timestamp is "-1"]
29-Aug-2005 03:25
One behavior to be aware of is that if you have "/" in the date then strtotime will believe the last number is the year, while if you use a "-" then the first number is the year.
12/4/03 will be evaluated to the same time as 03-12-4.
This is in the gnu documentation linked to in the article. I confirmed the behavior with strtotime and getdate.
Steve Holland
15-Aug-2005 08:49
When using multiple negative relative items, the result might be a bit unexpected:
<?php
$basedate = strtotime("15 Aug 2005 10:15:00");
$date1 = strtotime("-1 day 2 hours", $basedate);
$date2 = strtotime("-1 day -2 hours", $basedate);
echo date("j M Y H:i:s", $date1); // 14 Aug 2005 12:15:00
echo date("j M Y H:i:s", $date2); // 14 Aug 2005 08:15:00
?>
The minus sign has to be added to every relative item, otherwise they are interpreted as positive (increase in time). Other possibility is to use "1 day 2 hours ago".
15-Jul-2005 11:21
Maybe it saves others from troubles:
if you create a date (i.e. a certain day, like 30.03.2005, for a calendar for example) for which you do not consider the time, when using mktime be sure to set the time of the day to noon:
<?php
$iTimeStamp = mktime(12, 0, 0, $iMonth, $iDay, $iYear);
?>
Otherwhise
<?php
// For example
strtotime('-1 month', $iTimeStamp);
?>
will cause troubles when calculating the relative time. It often is one day or even one month off... After I set the time to noon "strtotime" calculates as expected.
Cheers
Denis
13-Jul-2005 01:13
relative dates..
echo date('d F Y', strtotime('last monday', strtotime('15 July 2005'))); // 11th
echo "<br>";
echo date('d F Y', strtotime('this monday', strtotime('15 July 2005'))); // 18th
echo "<br>";
echo date('d F Y', strtotime('next monday', strtotime('15 July 2005'))); // 25th
28-Jun-2005 02:14
This is an easy way to calculate the number of months between 2 dates (including the months in which the dates are themselves).
<?
$startDate = mktime(0,0,0, 6, 15, 2005);
$stopDate = mktime(0,0,0, 10, 8, 2006);
$nrmonths = ((idate('Y', $stopDate) * 12) + idate('m', $stopDate)) - ((idate('Y', $startDate) * 12) + idate('m', $startDate));
?>
Results in $nrmonths = 16.
09-May-2005 10:49
Here's a quick one-line function you can use to get the time difference for relative times. But default, if you put in a relative time (like "1 minute"), you get that relative to the current time. Using this function will give you just the time difference in seconds:
<?php function relative_time( $input ) { return strtotime($input) - time(); } ?>
For example "1 minute" will return 60, while "30 seconds ago" will return -30
Valid relative time formats can be found at http://www.gnu.org/software/tar/manual/html_chapter/tar_7.html#SEC115
22-Apr-2005 06:59
If you strtotime the epoch (Jan 1 1970 00:00:00) you will usually get a value, rather than the expected 0. So for example, if you were to try to use the epoch to calculate the difference in times (strtotime(Jan 1 1970 21:00:00)-strtotime(Jan 1 1970 20:00:00) for example) You get a value that depends strongly upon your timezone. If you are in EST for example, the epoch is actually shifted -5 to YOUR epoch is Jan 1 1970 19:00:00) In order to get the offset, simply use the following call to report the number of seconds you are away from the unix epoch. $offset=strtotime("1970-01-01 00:00:00"); Additionally, you can append GMT at the end of your strtotime calls so save yourself the trouble of converting relative to timezone.
I ran into the same problem with "last" as gabrielu at hotmail dot com (05-Apr-2005 10:45) when using strtotime() with getdate(). My only guess is that it has to do with daylight savings time as it seemed to be ok for most dates except those near the first Sunday in April and last Sunday in October.
I used strftime() with strtotime() and that gave me the result I was looking for.
05-Apr-2005 06:45
While working on an employee schedule application I noticed an issue with using strtotime('last...'). I ran tests on each weekday for each week within a year and noticed inconsistencies while using:
date('m/d/Y', strtotime('last Wednesday', '2005-04-05'))
Most calculations of the 'last Wednesday' for each week calculated accordingly however I noticed a problem with several dates, one being '04/05/2005' (April 5th 2005).
date('m/d/Y', strtotime('last Wednesday', '2005-04-05'))
The above should have returned '03/30/2005'. Instead, it returned '03/29/2005'. I don't understand why the function is returning this value. Regardless, my solution:
date('m/d/Y', strtotime('-1 week' ,strtotime('Wednesday', '2005-04-05')))
02-Apr-2005 12:56
Just a note ... there cannot be spaces between the + and the amount you want to add.
strtotime("{$myDate} -1 months") is correct.
strtotime("{$myDate} - 1 months") is not.
Caused me a headache ...
09-Dec-2004 05:12
Be warned that strtotime() tries to "guess what you meant" and will successfully parse dates that would otherwise be considered invalid:
<?php
$ts = strtotime('1999-11-40');
echo date('Y-m-d', $ts);
// outputs: 1999-12-10
?>
It is my understanding (I have not verified) that the lexer for strtotime() has been rewritten for PHP5, so these semantics may only apply for PHP4 and below.
17-Sep-2004 12:52
When you convert date string got by untrusted source (such as If-Modified-Since HTTP Header) don't forget to check if the date string is empty.
<? strtotime('') ?>
returns current timestamp on my php 4.3.8
20-Aug-2004 03:38
After a slight moment of frustration, and finding that I'm not the only one with this problem (see http://bugs.php.net/bug.php?id=28088 - it's a known bug) I decided to write a short workaround for dealing with the 00 hour problem.
The problem only seems to occur when inputting strings such as '08/20/2004 0047' and NOT '08/20/2004 00:47'. Hence, my fix:
<?php
$your_value ( preg_replace ('#^(\d+/\d+/?\d{2,4} )(00)(\d{2})$#', '$1$2:$3', $your_value() ));
?>
06-Apr-2004 08:39
I neglected to include the solution in my last post for using strtotime() with date-time data stored in GMT. Append the string "GMT" to all of your datetimes pulled from MySQL or other database that store date-times in the format "yyyy-mm-dd hh:ii:ss" just prior to converting them to a unix timestamp with strtotime(). This will ensure you get a valid GMT result for times during daylight savings.
EXAMPLE:
<?php
$date_time1 = strtotime("2004-04-04 02:00:00"); // returns bad value -1 due to DST
$date_time2 = strtotime("2004-04-04 02:00:00 GMT"); // works great!
?>
02-Jan-2004 12:24
I was having trouble parsing Apache log files that consisted of a time entry (denoted by %t for Apache configuration). An example Apache-date looks like: [21/Dec/2003:00:52:39 -0500]
Apache claims this to be a 'standard english format' time. strtotime() feels otherwise.
I came up with this function to assist in parsing this peculiar format.
<?php
function from_apachedate($date)
{
list($d, $M, $y, $h, $m, $s, $z) = sscanf($date, "[%2d/%3s/%4d:%2d:%2d:%2d %5s]");
return strtotime("$d $M $y $h:$m:$s $z");
}
?>
Hope it helps anyone else seeking such a conversion.