I have an example value of : 20160530105130
Which I want to convert to a datetime.
I have tried Carbon::createFromFormat('Ym',$value)
But that just errors.
I also tried with timestamp, but again error.
Anyone have an idea how I can achive this?
Create a DateTime or Carbon object from the string and use the year and month there.
$str = '20160530105130';
$dt = DateTime::createFromFormat('!Ym????????',$str);
var_dump($dt);
//object(DateTime)#2 (3) { ["date"]=> string(26) "2016-05-01 00:00:00.000000"
Demo: https://3v4l.org/bOJdU
With carbon:
$str = '20160530105130';
$dt = Carbon::createFromFormat('!Ym????????',$str);
echo $dt; //2016-05-01 00:00:00
Alternatively, the string can also be completely parsed with DateTime. The day and time can then be set to the desired values using the modify method. This variant makes it easier to read what is being done.
$str = '20160530105130';
$dt = date_create($str)->modify('first day of this month 00:00');
//object(DateTime)#2 (3) { ["date"]=> string(26) "2016-05-01 00:00:00.000000"
Carbon::createFromFormat('YmdHis', "$value")
This question already has answers here:
Convert one date format into another in PHP
(17 answers)
Closed 3 years ago.
I face this problem to integrate bKash Online Payment Gateway API.
The Documentation is here - https://developer.bka.sh/docs/create-payment-1.
In 'Create Payment' section bKash return paymentCreateTime string as following format.
2020-01-07T11:55:34:438 GMT+0600
How can I convert it to 2020-01-07 11:55:34 to save in MySQL?
I find a solution like following way.
$input = "2020-01-07T11:55:34:438 GMT+0600" // "2020-01-07T11:55:34:438 GMT+0600"
$timestamp = substr($input,0,19); // "2020-01-07T11:55:34"
$mysql = date_format(date_create($timestamp),'Y-m-d H:i:s'); // "2020-01-07 11:55:34"
But I need a solution without substr() function.
You can use createFromFormat() to directly parse your string.
Importantly, you'll need to escape T and GMT.
Everything else in https://www.php.net/manual/en/datetime.createfromformat.php
$input = '2020-01-07T11:55:34:438 GMT+0600';
$date = DateTime::createFromFormat('Y-m-d\Th:i:s:u \G\M\TO', $input);
echo $date->format('Y-m-d h:i:s');
This will cleanly deliver an object that you can format however you like.
Here is a demonstration:
$date = new DateTime("now");
echo $date->format('Y-m-d\Th:i:s:u \G\M\TO');
echo "\n---\n";
$input = '2020-01-07T11:55:34:438 GMT+0600';
echo $input;
echo "\n---\n";
$date = DateTime::createFromFormat('Y-m-d\Th:i:s:u \G\M\TO', $input);
echo $date->format('Y-m-d h:i:s');
echo "\n===\n";
var_dump($date);
Demonstration Output:
2020-01-07T10:12:53:000245 GMT+0100
---
2020-01-07T11:55:34:438 GMT+0600
---
2020-01-07 11:55:34
===
object(DateTime)#2 (3) {
["date"]=>
string(26) "2020-01-07 11:55:34.438000"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+06:00"
}
You can use it like this
date_default_timezone_set("Asia/Dhaka");
$mysql1 = date_format(date_create(strtotime($input)),'Y-m-d H:i:s');
it will print 2020-01-07 09:17:23
This code :
$timestamp = 2016-10-06T09:50:54.000Z;
How do I separate or convert from the timestamp into a date and time?
example :
TimeStamp 2016-10-06T09:50:54.000Z
Date 2016-10-06
Jam(GMT +7) 04:55:45
Please help to solve this problem. Thanks
$d = new DateTime('2016-10-06T09:50:54.000Z');
echo $d->format('Y-m-d\TH:i:s.u'); // 2016-10-06T09:50:54.000000
echo $d->format('Y-m-d'); // 2016-10-06
// convert to GMT+7 timezone
$d->setTimezone(new DateTimeZone('GMT+7'));
echo $d->format('h:i:s'); // 04:50:54
<?php
$timestamp = "2016-10-06T09:50:54.000Z";
$datetime = new Datetime('2016-10-06T09:50:54.000Z');
echo "Date".$datetime->format('Y-m-d')."<br>";
echo "Jam".$datetime->format('H:i:s');
?>
Take a look at this short example:
<?php
$datetime = new Datetime('2016-10-06T09:50:54.000Z');
var_dump($datetime->format('Y-m-d H:i:s'));
The output obviously is: string(19) "2016-10-06 09:50:54"
Using different format strings you can convert your date time object into whatever representation you want to. 'Y-m-d' will give the date in international format for example.
Take a look at the great documentation: http://php.net/manual/en/class.datetime.php
Not much of a mystery:
<?php
$timestamp = '2016-10-06T09:50:54.000Z';
$dt = new DateTime($timestamp);
var_dump($dt);
$dt->setTimezone(new DateTimeZone('Asia/Jakarta'));
var_dump($dt);
object(DateTime)#1 (3) {
["date"]=>
string(26) "2016-10-06 09:50:54.000000"
["timezone_type"]=>
int(2)
["timezone"]=>
string(1) "Z"
}
object(DateTime)#1 (3) {
["date"]=>
string(26) "2016-10-06 16:50:54.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(12) "Asia/Jakarta"
}
Unlike strings, giving format to a proper date is trivial.
I don't know what time zone Jam is but I suggest you assign a city so you can account for DST (I've used Asia/Jakarta in my sample code, the complete list can be found at List of Supported Timezones). Just relying on a UTC offset like +7 may make your code unreliable during the summer.
I am having trouble with the following string which is supposed to be a datetime (response from an api).
2013-03-08T19:11:11.234+0000
I need to convert the string to ISO 8601.
The exact format should look like:
2016-03-01T12:00:00+00:00
If someone could help me do this in php would be great but I would be already more than happy if someone could identify the format (like yyyy-mm-ddThh:mm:ss).
It seems the API returns the time with milliseconds.
Try this:
$date = '2013-03-08T19:11:11.234+0000';
$format = 'Y-m-d\TH:i:s.uO';
$dt = DateTime::createFromFormat($format, $date);
echo $dt->format(DateTime::ISO8601);
Result:
2013-03-08T19:11:11+0000
EDIT
Based on comments on your answer, you need to convert such a time:
2016-03-01T11:01:51.126044 00:00
Since it's not possible to parse this format with DateTime, you need to make it readable first.
There are many ways to do this. What we need is to add a + before timezone, so that my code above work.
If you are sure the date you get from the API is always this format, and that there will always be only 1 space in the string, just replace the string with a space:
$date = '2016-03-01T11:01:51.126044 00:00';
str_replace(' ', '+', $date);
$format = 'Y-m-d\TH:i:s.uP';
$dt = DateTime::createFromFormat($format, $date);
echo $dt->format(DateTime::ISO8601);
This should work (note that here the timezone mask is P since there is a colon)
You can also use preg_replace() instead of DateTime, if you don't need the date for calculations:
$date = '2016-03-01T11:01:51.126044 00:00';
$date = preg_replace('`(\.[0-9]+\s)`', '+', $date);
echo $date;
This produces:
2016-03-01T11:01:51+00:00
If you need the date for calculation, just convert it to DateTime after:
$date = '2016-03-01T11:01:51.126044 00:00';
$date = preg_replace('`(\.[0-9]+\s)`', '+', $date);
$date = DateTime::createFromFormat(DateTime::ISO8601, $date);
var_dump($date);
This produces:
object(DateTime)#1 (3) {
["date"]=>
string(26) "2016-03-01 11:01:51.000000"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+00:00"
}
I suggest you to use Carbon: http://carbon.nesbot.com/docs/
echo Carbon::parse('2013-03-08T19:11:11.234+0000')->toAtomString();
Also, the format you want is ATOM, not ISO 8601. You could do #Arcesilas way, it should work too.
Code speaks a million words:
php > echo strtotime("2010-12-07T23:00:00.000Z");
1291762800
echo date('c', 1291762800);
2010-12-08T00:00:00+01:00
php > var_dump(DateTime::createFromFormat('c', "2010-12-07T23:00:00.000Z"));
bool(false)
php > var_dump(DateTime::createFromFormat(DateTime::ISO8601, "2010-12-07T23:00:00.000Z"));
bool(false)
Any idea what's going on?
Btw, yes, new DateTime("2010-12-07T23:00:00.000Z") works fine. But I prefer to know what input I am getting.
There's a bug report that exactly describes your problem :)
https://bugs.php.net/bug.php?id=51950
Since 2016-08-07, the bug report has been marked as "not a bug". You need to use strtotime or new DateTime instead.
The constants that have been defined apply to both formatting and parsing in the same way, which forces your ways.
Parsing ISO8601 date, and also switching timezone:
// create ISO8601 dateTime
$date = DateTime::createFromFormat(DateTime::ISO8601, '2016-07-27T19:30:00Z');
// set to user's timezone
$date -> setTimeZone('Asia/Singapore');
echo $date -> format(DateTime::ISO8601);
// prints '2016-07-28T03:30:00+0800'
Nobody mentioned to use DATE_ATOM which is as far as i know phps most correct implementation of ISO 8601. It should at least work for the last 3 of these:
<?php
$dates = array(
"2010-12-07T23:00:00.000Z",
"2010-12-07T23:00:00",
"2010-12-07T23:00:00Z",
"2010-12-07T23:00:00+01:00",
(new \DateTime("now"))->format(DATE_ATOM)
);
foreach($dates as $d) {
$res = \DateTime::createFromFormat(DATE_ATOM, $d);
echo "try $d: \n";
var_dump($res);
echo "\n\n";
}
?>
To be able to parse all of them i wrote a tiny function:
<?php
function parse_iso_8601($iso_8601_string) {
$results = array();
$results[] = \DateTime::createFromFormat("Y-m-d\TH:i:s",$iso_8601_string);
$results[] = \DateTime::createFromFormat("Y-m-d\TH:i:s.u",$iso_8601_string);
$results[] = \DateTime::createFromFormat("Y-m-d\TH:i:s.uP",$iso_8601_string);
$results[] = \DateTime::createFromFormat("Y-m-d\TH:i:sP",$iso_8601_string);
$results[] = \DateTime::createFromFormat(DATE_ATOM,$iso_8601_string);
$success = array_values(array_filter($results));
if(count($success) > 0) {
return $success[0];
}
return false;
}
// Test
$dates = array(
"2010-12-07T23:00:00.000Z",
"2010-12-07T23:00:00",
"2010-12-07T23:00:00Z",
"2010-12-07T23:00:00+01:00",
(new \DateTime("now"))->format(DATE_ATOM)
);
foreach($dates as $d) {
$res = parse_iso_8601($d);
echo "try $d: \n";
var_dump($res);
echo "\n\n";
}
?>
As #Glutexo mentioned it works only if there are only 1 to 6 precision digits for the decimal part, too. Feel free to improve it.
try this:
DateTime::createFromFormat('Y-m-d\TH:i:sP', $date)
It is very strange and disappointing that this bug is still actual.
Here is a right pattern for parsing date with microseconds in decimal part of seconds:
Y-m-d\TH:i:s.uO
Usage:
$dateStr = '2015-04-29T11:42:56.000+0400'
$ISO = 'Y-m-d\TH:i:s.uO'
$date = DateTime::createFromFormat($ISO, $dateStr)
Simply :
$dt = new DateTime('2018-04-07T16:32:44Z');
$dt->format('Ymd'); // 20180407
Use DATE_ATOM rather than 'c' when formatting like #Steven said. This is how you work with ISO 8601 in PHP.
<?php
$now_date = new DateTime();
$now_iso_8601 = $now_date->format(DATE_ATOM);
echo "Now in ISO 8601 format: {$now_iso_8601}\n";
$date_from_string_and_format = date_create_from_format(DATE_ATOM, $now_iso_8601);
echo "ISO 8601 formatted string, back to DateTime object:\n";
var_dump($date_from_string_and_format);
prints
Now in ISO 8601 format: 2018-09-05T08:17:35-10:00
ISO 8601 formatted string, back to DateTime object:
object(DateTime)#2 (3) {
["date"]=>
string(26) "2018-09-05 08:17:35.000000"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "-10:00"
}
For the answer listed here https://stackoverflow.com/a/14849503/2425651
we can use this format "Y-m-d\TH: i: s.u+" to keep the microseconds.
$format = 'Y-m-d\TH:i:s.u+';
$value = '2017-09-21T10:11:19.026Z'; // jsDate.toUTCString();
var_dump(\DateTime::createFromFormat($format, $value));
This one works for me:
$date = (new DateTime)->setTimestamp(strtotime('2017-12-31T23:00:00.000Z'));
I've experienced this issue with POSTGRES default Time with timezone format and this was the format that fixed it for me:
Y-m-d H:i:s.uO
This works for me:
$timeStamp = "2020-12-10T14:54:25.618Z";
var_dump(DateTime::createFromFormat('Y-m-d\TH:i:s.v\Z', $timeStamp));
object(DateTime)#1 (3) {
["date"]=>
string(26) "2020-12-10 14:54:25.618000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(3) "UTC"
}
I am using follow function that allow multiple ISO8601 formats:
function fromISO8601($time, \DateTimeZone $timezone = null) {
// valid ISO time 2019-04-01T00:00:00.000+02:00
$t = \DateTime::createFromFormat('Y-m-d\TH:i:s.uO', $time) or
// ISO time without millis 2019-04-01T00:00:00+02:00
$t = \DateTime::createFromFormat('Y-m-d\TH:i:sO', $time) or
// ISO time without timezone 2019-04-01T00:00:00.000
$t = \DateTime::createFromFormat('Y-m-d\TH:i:s.u', $time, $timezone) or
// ISO time without millis and timezone 2019-04-01T00:00:00.000+02:00
$t = \DateTime::createFromFormat('Y-m-d\TH:i:s', $time, $timezone);
return $t;
}
here are all supported dates
var_dump(
fromISO8601('2019-04-01T00:00:00.000+02:00'),
fromISO8601('2019-04-01T00:00:00+02:00'),
fromISO8601('2019-04-01T00:00:00.000'),
fromISO8601('2019-04-01T00:00:00')
);
This code is benevolent for missing timezone and milliseconds and works in older php versions.