php datetime from string
DateTime::createFromFormat
(PHP 5 >= 5.3.0, PHP 7, PHP 8)
Описание
Список параметров
Для вставки в format буквенного символа, вы должны экранировать его с помощью обратного слеша( \ ).
Начало эпохи Unix 1970-01-01 00:00:00 UTC.
Строка, представляющая время.
Если timezone не указан или null и datetime не содержит часовой пояс, то будет использован текущий часовой пояс.
Параметр timezone и текущий часовой пояс будут проигнорированы, если параметр datetime также содержит метку времени UNIX (то есть timestamp вида 946684800 ) или же указанный часовой пояс (то есть 2010-01-28T15:00:00+02:00 ).
Возвращаемые значения
Возвращает созданный экземпляр класса DateTime или false в случае возникновения ошибки.
Список изменений
Примеры
Пример #1 Пример использования DateTime::createFromFormat()
Результат выполнения данных примеров:
Пример #2 Хитрости при использовании DateTime::createFromFormat()
Результатом выполнения данного примера будет что-то подобное:
Пример #3 Формат строки с буквенными символами
Результатом выполнения данного примера будет что-то подобное:
Смотрите также
User Contributed Notes 27 notes
Be warned that DateTime object created without explicitely providing the time portion will have the current time set instead of 00:00:00.
Be aware:
If the day of the month is not provided, creating a DateTime object will produce different results depending on what the current day of the year is.
This is because the current system date will be used where values are not provided.
// on August 1st
printMonth ( «April» );
// outputs April
// on August 31st
printMonth ( «April» );
// outputs May
?>
In this case, each and every character on that string has to be escaped as shown below.
createFromFormat(‘U’) has a strange behaviour: it ignores the datetimezone and the resulting DateTime object will always have GMT+0000 timezone.
?>
The problem is microtime() and time() returning the timestamp in current timezone. Instead of using time you can use ‘now’ but to get a DateTimeObject with microseconds you have to write it this way to be sure to get the correct datetime:
Parsing RFC3339 strings can be very tricky when their are microseconds in the date string.
Since PHP 7 there is the undocumented constant DateTime::RFC3339_EXTENDED (value: Y-m-d\TH:i:s.vP), which can be used to output an RFC3339 string with microseconds:
Note: the difference between «v» and «u» is just 3 digits vs. 6 digits.
echo phpversion ();
// 7.2.7-1+ubuntu16.04.1+deb.sury.org+12019-01-102019-01-01
Reportedly, microtime() may return a timestamp number without a fractional part if the microseconds are exactly zero. I.e., «1463772747» instead of the expected «1463772747.000000». number_format() can create a correct string representation of the microsecond timestamp every time, which can be useful for creating DateTime objects when used with DateTime::createFromFormat():
If you’re here because you’re trying to create a date from a week number, you want to be using setISODate, as I discovered here:
strtotime
(PHP 4, PHP 5, PHP 7, PHP 8)
strtotime — Parse about any English textual datetime description into a Unix timestamp
Description
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
A date/time string. Valid formats are explained in Date and Time Formats.
The timestamp which is used as a base for the calculation of relative dates.
Return Values
Returns a timestamp on success, false otherwise.
Errors/Exceptions
Every call to a date/time function will generate a E_WARNING if the time zone is not valid. See also date_default_timezone_set()
Changelog
Version | Description |
---|---|
8.0.0 | baseTimestamp is nullable now. |
Examples
Example #1 A strtotime() example
Example #2 Checking for failure
Notes
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).
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.)
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.
To avoid potential ambiguity, it’s best to use ISO 8601 ( YYYY-MM-DD ) dates or DateTime::createFromFormat() when possible.
See Also
User Contributed Notes 42 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.
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.
A strtotime também funciona quando concatenamos strings,
UK dates (eg. 27/05/1990) won’t work with strotime, even with timezone properly set.
[red., derick]: What you instead should do is:
WARNING when using «next month», «last month», «+1 month», «-1 month» or any combination of +/-X months. It will give non-intuitive results on Jan 30th and 31st.
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»:
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)
// Get timestamp of 32nd week in 2009.
strtotime ( ‘2009W32’ ); // returns timestamp for Mon, 03 Aug 2009 00:00:00
// Weeknumbers strtotime ( ‘2009W01’ ); // returns timestamp for Mon, 29 Dec 2008 00:00:00
// strtotime(‘2009W1’); // error! returns false
// See timestamp for Tuesday in 5th week of 2008
strtotime ( ‘2008-W05-2’ ); // returns timestamp for Tue, 29 Jan 2008 00:00:00
?>
Weeknumbers are (probably) computed according to ISO-8601 specification, so doing date(‘W’) on given timestamps should return passed weeknumber.
I tried using sams most popular example but got incorrect results.
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.***
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:
So strtotime($end_date) will always return the timestamp at 00:00 that day. If I instead used:
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.
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
For negative UNIX timestamps, strtotime seems to return the literal you passed in, or it may try to deduct the number of seconds from today’s date.
To work around this behaviour, it appears that the same behaviour as described in the DateTime classes applies:
Specifically this line here (in the EN manual):
Therefore strtotime(‘@-1000’) returns 1000 seconds before the epoch.
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.
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:
//I.E.: today is 17/02/2011
echo strtotime ( ‘2011-01-01’ ); //1293836400
echo 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’
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.
strtotime is awesome for converting dates.
in this example i will make an RSS date, an
ATOM date, then convert them to a human
readable m/d/Y dates.
[red.: This is a bug, and should be fixed. I have file an issue]
This comment apply to PHP5+
We can now do thing like this with strtotime:
= 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?
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:
Adding a note to an already long page:
Try to be as specific as you can with the string you pass in. For example
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.
strtotime() produces different output on 32 and 64 bit systems running PHP 5.3.3 (as mentioned previously). This affects the «zero date» («0000-00-00 00:00:00») as well as dates outside the traditional 32 date range.
In modern 64-bit systems (tested on mac) the old 1970 to 2038 date range limitations are gone.
strtotime(«0001-10-30») gives int(-62109540728)
strtotime(«6788-10-30») gives int(152067506400)
DateTime::__construct
(PHP 5 >= 5.2.0, PHP 7, PHP 8)
Description
Returns new DateTime object.
Parameters
A date/time string. Valid formats are explained in Date and Time Formats.
Return Values
Returns a new DateTime instance. Procedural style returns false on failure.
Errors/Exceptions
Emits Exception in case of an error.
Changelog
Version | Description |
---|---|
7.1.0 | From now on microseconds are filled with actual value. Not with ‘00000’. |
Examples
Example #1 DateTime::__construct() example
The above examples will output:
Example #2 Intricacies of DateTime::__construct()
The above example will output something similar to:
See Also
User Contributed Notes 18 notes
The theoretical limits of the date range seem to be «-9999-01-01» through «9999-12-31» (PHP 5.2.9 on Windows Vista 64):
Note that the DateTime ctor also accepts boolean false and empty strings, and treats them the same as NULL (i.e. result is current date and time). This may lead to unexpected results if you forward function return values without explicitly checking them first.
Empty arrays and boolean true trigger PHP warnings OTOH.
(checked with PHP 5.5.18)
// New Timezone Object
$timezone = new DateTimeZone ( ‘America/New_York’ );
It is worth noting:
If you have not setup a default timezone, an Exception (or error if PHP
If time cannot be parsed an exception of type Exception is thrown which can be caught, however an E_WARNING is emitted as well. This might be confusing if you are converting warnings to exceptions in your error or shutdown handler.
Be careful working with MySQL dates representing point of transition to Daylight Saving Time.
The constructor of DateTime will convert timezone abbreviation to DST but not the time.
= new DateTimeZone ( ‘Europe/Sofia’ );
$transitionToDst = ‘2014-03-30 03:00:00’ ;
Watch out – this means that these two are NOT equivalent, they result in different timezones (unless your current timezone is GMT):
About constructing a DateTime, instead of just using the year it seems working when date matches the pattern «YYYY-MM»
— Returns the year correctly: «YYYY-MM»
— Ignores the given input and returns the year from NOW: «YYYY»
RESULTS/SCOPE:
— Linux (May 24, 2019)
— PHP 7.2.17 (cli)
Using this in a try catch to verify a string is in a valid date format is unreliable. Single letter strings used for the first argument (time string) of the constructor allows a new instance of the class to be created, without any exception or error.
I’m surprised this hasn’t been mentioned, but when constructing a DateTime with just the year as a string, DateTime will pre-initialize itself with NOW and then replace the year, so if today is 7/12/2016:
print((new DateTime ( ‘2015’ ))-> modify ( ‘+1 day’ )-> format ( ‘Y-m-d’ ));
?>
results in 2016-07-13
This seems to work as expected, at least now:
Also forgot to mention, that MySQL «zeroed» dates do not throw an error but produce a non-sensical date:
?>
Another good reason to write your own class that extends from DateTime.
When passing a non US or SQL date string the date will be formatted incorrectly.
// UK date d/m/Y.
$date_time = «08/03/2016 00:00:00»;
$dt = new DateTime($date_time, new DateTimeZone(«Europe/London»));
Impossible times due to daylight savings are handled by this function in a way similar to impossible dates, with the difference that this is not an error (i.e. a consequent call to DateTime::getLastError() yields nothing).
For example:
In the timezone «Europe/Berlin» on Sunday, March 30 2014 there was no 02:30 am, because that our is being skipped due to daylight savings on that day.
/*
Yields:
array(4) <
‘warning_count’ =>
int(0)
‘warnings’ =>
array(0) <
>
‘error_count’ =>
int(0)
‘errors’ =>
array(0) <
>
>
The impossible time ‘2014-03-30T02:30:00’ is interpreted as: 2014-03-30T03:30:00+0200
*/
?>
That is similar to how, for example, Febuary 29, 2014 would be handled, which would be interpreted as March 1, 2014. The difference is, that with the date that would be an error, with the time it is not.
Ambigous times due to daylight savings are handled as the second possibility. For example the time 2:30 am occurred twice on October 26, 2014 in the timezone «Europe/Berlin».
/*
Yields:
The ambiguous time ‘2014-10-26T02:30:00’ is interpreted as: 2014-10-26T02:30:00+0100
*/
?>
Note that «2014-10-26T02:30:00+0200», one hour earlier, would be a correct answer as well.
Класс DateTime
(PHP 5 >= 5.2.0, PHP 7, PHP 8)
Введение
Обзор классов
Список изменений
Содержание
User Contributed Notes 26 notes
Set Timezone and formatting.
= time ();
$timeZone = new \ DateTimeZone ( ‘Asia/Tokyo’ );
DateTime supports microseconds since 5.2.2. This is mentioned in the documentation for the date function, but bears repeating here. You can create a DateTime with fractional seconds and retrieve that value using the ‘u’ format string.
// Instantiate a DateTime with microseconds.
$d = new DateTime ( ‘2011-01-01T15:03:01.012345Z’ );
There is a subtle difference between the following two statments which causes JavaScript’s Date object on iPhones to fail.
/**
On my local machine this results in:
Both of these strings are valid ISO8601 datetime strings, but the latter is not accepted by the constructor of JavaScript’s date object on iPhone. (Possibly other browsers as well)
*/
?>
Our solution was to create the following constant on our DateHelper object.
class DateHelper
<
/**
* An ISO8601 format string for PHP’s date functions that’s compatible with JavaScript’s Date’s constructor method
* Example: 2013-04-12T16:40:00-04:00
*
* PHP’s ISO8601 constant doesn’t add the colon to the timezone offset which is required for iPhone
**/
const ISO8601 = ‘Y-m-d\TH:i:sP’ ;
>
?>
Small but powerful extension to DateTime
class Blar_DateTime extends DateTime <
= new Blar_DateTime ( ‘1879-03-14’ );
Albert Einstein would now be 130 years old.
Albert Einstein would now be 130 Years, 10 Months, 10 Days old.
Albert Einstein was on 2010-10-10 131 years old.
Example displaying each time format:
$dateTime = new DateTime();
The above example will output:
At PHP 7.1 the DateTime constructor incorporates microseconds when constructed from the current time. Make your comparisons carefully, since two DateTime objects constructed one after another are now more likely to have different values.
This caused some confusion with a blog I was working on and just wanted to make other people aware of this. If you use createFromFormat to turn a date into a timestamp it will include the current time. For example:
if you’d like to print all the built-in formats,
This might be unexpected behavior:
#or use the interval
#$date1->add(new DateInterval(«P1M»));
#will produce 2017-10-1
#not 2017-09-30
A good way I did to work with millisecond is transforming the time in milliseconds.
function timeToMilliseconds($time) <
$dateTime = new DateTime($time);
If you have timezone information in the time string you construct the DateTime object with, you cannot add an extra timezone in the constructor. It will ignore the timezone information in the time string:
$date = new DateTime(«2010-07-05T06:00:00Z», new DateTimeZone(«Europe/Amsterdam»));
will create a DateTime object set to «2010-07-05 06:00:00+0200» (+2 being the TZ offset for Europe/Amsterdam)
To get this done, you will need to set the timezone separately:
$date = new DateTime(«2010-07-05T06:00:00Z»);
$date->setTimeZone(new DateTimeZone(«Europe/Amsterdam»);
This will create a DateTime object set to «2010-07-05 08:00:00+0200»
It isn’t obvious from the above, but you can insert a letter of the alphabet directly into the date string by escaping it with a backslash in the format string. Note that if you are using «double» speech marks around the format string, you will have to further escape each backslash with another backslash! If you are using ‘single’ speech marks around the format string, then you only need one backslash.
For instance, to create a string like «Y2014M01D29T1633», you *could* use string concatenation like so:
please note that using
setTimezone
setTimestamp
setDate
setTime
etc..
$original = new DateTime(«now»);
so a datetime object is mutable
(Editors note: PHP 5.5 adds DateTimeImmutable which does not modify the original object, instead creating a new instance.)
Create function to convert GregorianDate to JulianDayCount
Note that the ISO8601 constant will not correctly parse all possible ISO8601 compliant formats, as it does not support fractional seconds. If you need to be strictly compliant to that standard you will have to write your own format.
Bug report #51950 has unfortunately be closed as «not a bug» even though it’s a clear violation of the ISO8601 standard.
It seems like, due to changes in the DateTimeZone class in PHP 5.5, when creating a date and specifying the timezone as a a string like ‘EDT’, then getting the timezone from the date object and trying to use that to set the timezone on a date object you will have problems but never know it. Take the following code:
Be aware that DateTime may ignore fractional seconds for some formats, but not when using the ISO 8601 time format, as documented by this bug:
$dateTime = DateTime::createFromFormat(
DateTime::ISO8601,
‘2009-04-16T12:07:23.596Z’
);
// bool(false)
Be aware of this behaviour:
In my opinion, the former date should be adjusted to 2014/11/30, that is, the last day in the previous month.
Here is easiest way to find the days difference between two dates:
If you’re stuck on a PHP 5.1 system (unfortunately one of my clients is on a rather horrible webhost who claims they cannot upgrade php) you can use this as a quick workaround:
If you need DateTime::createFromFormat functionality in versions class DateClass extends DateTime <
<>
$regexpArray [ ‘Y’ ] = «(?P 19|20\d\d)» ;
$regexpArray [ ‘m’ ] = «(?P 06|1[012])» ;
$regexpArray [ ‘d’ ] = «(?P 04|[12]9|3[01])» ;
$regexpArray [ ‘-‘ ] = «[-]» ;
$regexpArray [ ‘.’ ] = «[\. /.]» ;
$regexpArray [ ‘:’ ] = «[:]» ;
$regexpArray [ ‘space’ ] = «[\s]» ;
$regexpArray [ ‘H’ ] = «(?P 05|15|21)» ;
$regexpArray [ ‘i’ ] = «(?P36)» ;
$regexpArray [ ‘s’ ] = «(?P55)» ;
Date/Time Functions
Table of Contents
User Contributed Notes 25 notes
I ran into an issue using a function that loops through an array of dates where the keys to the array are the Unix timestamp for midnight for each date. The loop starts at the first timestamp, then incremented by adding 86400 seconds (ie. 60 x 60 x 24). However, Daylight Saving Time threw off the accuracy of this loop, since certain days have a duration other than 86400 seconds. I worked around it by adding a couple of lines to force the timestamp to midnight at each interval.
When debugging code that stores date/time values in a database, you may find yourself wanting to know the date/time that corresponds to a given unix timestamp, or the timestamp for a given date & time.
The following script will do the conversion either way. If you give it a numeric timestamp, it will display the corresponding date and time. If you give it a date and time (in almost any standard format), it will display the timestamp.
All conversions are done for your locale/time zone.
For those who are using pre MYSQL 4.1.1, you can use:
TO_DAYS([Date Value 1])-TO_DAYS([Date Value 2])
For the same result as:
DATEDIFF([Date Value 1],[Date Value 2])
This dateDiff() function can take in just about any timestamp, including UNIX timestamps and anything that is accepted by strtotime(). It returns an array with the ability to split the result a couple different ways. I built this function to suffice any datediff needs I had. Hope it helps others too.
I needed a function that determined the last Sunday of the month. Since it’s made for the website’s «next meeting» announcement, it goes based on the system clock; also, if today is between Sunday and the end of the month, it figures out the last Sunday of *next* month. lastsunday() takes no arguments and returns the date as a string in the form «January 26, 2003». I could probably have streamlined this quite a bit, but at least it’s transparent code. =)
/* The two functions calculate when the next meeting will
be, based on the assumption that the meeting will be on
the last Sunday of the month. */
I wanted to find all records in my database which match the current week (for a call-back function). I made up this function to find the start and end of the current week :
Not really elegant, but tells you, if your installed timezonedb is the most recent:
Someone may find this info of some use:
Rules for calculating a leap year:
1) If the year divides by 4, it is a leap year (1988, 1992, 1996 are leap years)
2) Unless it divides by 100, in which case it isn’t (1900 divides by 4, but was not a leap year)
3) Unless it divides by 400, in which case it is actually a leap year afterall (So 2000 was a leap year).
In practical terms, to work out the number of days in X years, multiply X by 365.2425, rounding DOWN to the last whole number, should give you the number of days.
The result will never be more than one whole day inaccurate, as opposed to multiplying by 365, which, over more years, will create a larger and larger deficit.
I needed to calculate the week number from a given date and vice versa, where the week starts with a Monday and the first week of a year may begin the year before, if the year begins in the middle of the week (Tue-Sun). This is the way weekly magazines calculate their issue numbers.
Here are two functions that do exactly that:
Hope somebody finds this useful.
Use the mySQL UNIX_TIMESTAMP() function in your SQL definition string. i.e.
$sql= «SELECT field1, field2, UNIX_TIMESTAMP(field3) as your_date
FROM your_table
WHERE field1 = ‘$value'»;
The query will return a temp table with coulms «field1» «Field2» «your_date»
The «your_date» will be formatted in a UNIX TIMESTAMP! Now you can use the PHP date() function to spew out nice date formats.
Hope this helps someone out there!
//function like dateDiff Microsoft
//not error in year Bissesto