PHP: How to create a timestamp from pattern H:i (17:45)? - php

my current code:
<?php
$timestamp = DateTime::createFromFormat("d.m.Y H:i", $_POST["datetime"]);
echo $timestamp; // works!
?>
Now I've a form with two fields: date and time, separated.
<?php
$timestamp = DateTime::createFromFormat("d.m.Y", $_POST["date"]);
echo $timestamp; // works!
$timestamp = DateTime::createFromFormat("H:i", $_POST["time"]);
echo $timestamp; // doesn't work (error below)!
// Edit:
/* Fatal error: Call to a member function getTimestamp() on a non-object in */
?>
I would like to avoid using explode() with mktime(). That feels dirty and I think there could be another, clean way.
How would you create the timestamp from format?
Thanks in advance!

You can't. The timestamp requires a date in order to be calculated, and there isn't one available to use.

If you want to get the date and time from $_POST["date"] and $_POST["time"] Use following
DateTime::createFromFormat("d.m.Y H:i", $_POST["date"]." ".$_POST["time"]);
If you want to kow the number of seconds from midnight for that particular time you can however use this,
DateTime::createFromFormat("Ymd H:i", date("Ymd")." ".$_POST["time"]);

Use Date time's settime method
$timestamp = \DateTime::createFromFormat("d.m.Y", '10.10.2012');
$timestamp->setTime(17,12);
var_dump($timestamp);
Gives
object(DateTime)#1142 (3) { ["date"]=> string(19) "2012-10-10 17:12:00" ["timezone_type"]=> int(3) ["timezone"]=> string(3) "UTC" }

Related

parse int to datetime with carbon

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")

Why convert Timestamp '2016-10-06T09:50:54.000Z' with php

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.

compare datetime with different timezone_type php

I'm trying to compare to DateTime objects in PHP.
$Time1 = DateTime::createFromFormat('UP', '1409900072+0200');
$Time2 = new DateTime('2014-09-05 07:54:32');
The Time2 use the defoult which is Europe/Copenhagen, comparing yields the following
if ($Time2 > $Time1){
echo "true \n";
} else {
echo "false \n";
}
true
object(DateTime)#1 (3) {
["date"]=>
string(19) "2014-09-05 06:54:32"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+02:00"
}
object(DateTime)#2 (3) {
["date"]=>
string(19) "2014-09-05 07:54:32"
["timezone_type"]=>
int(3)
["timezone"]=>
string(17) "Europe/Copenhagen"
}
The way I understand it is the actual local time for Time1 is 08:54:32, so how can I get the comparison at the same timezone?
Thanks in advance
The really weird part is your initial value of 1409900072+0200. If 1409900072 is a UNIX timestamp, passing a particular timezone with it makes little sense. And it seems to cause PHP to create the instance incorrectly; it creates the instance with the time set to the UTC value (6:54), but the timezone offset of +0200 (where the time should actually be 8:54).
Arguably this should be filed as a bug report; but arguably the input data is nonsensical to begin with.
If you're feeding in a UNIX timestamp, then ignore any timezone information it may contain and explicitly set the timezone to UTC, then it all works as expected:
$t1 = DateTime::createFromFormat('U+', '1409900072+0200', new DateTimeZone('UTC'));
$t2 = new DateTime('2014-09-05 07:54:32', new DateTimeZone('Europe/Copenhagen'));
var_dump($t1 > $t2); // true
Note that PHP before 5.3.9 seems to have problems with the createFromFormat call; you'll probably have to filter out the trailing timezone by hand if you need to support those versions.
Convert both DateTimes to UTC (setTimeZone('UTC')) and then compare them.
<?php
$Time1 = DateTime::createFromFormat('UP', '1409900072+0200');
$Time2 = new DateTime('2014-09-05 07:54:32');
// convert
$utc = new DateTimeZone('UTC');
$time1_utc = clone $Time1;
$time1_utc->setTimeZone($utc);
$time2_utc = clone $Time2;
$time2_utc->setTimeZone($utc);
var_dump($Time1,$Time2);
var_dump($time1_utc,$time2_utc);

How to parse YouTube returned date to timestamp?

YouTube returns the Updated date and Submitted on date as follows: 2010-08-22T04:46:18.000Z
Is there a PHP function, or a date mask that parses this?
$dt = DateTime::createFromFormat("Y-m-d\TH:i:s.uP", "2010-08-22T04:46:18.000Z");
var_dump($dt);
// object(DateTime)#1 (3) {
// ["date"]=>
// string(26) "2010-08-22 04:46:18.000000"
// ["timezone_type"]=>
// int(2)
// ["timezone"]=>
// string(1) "Z"
// }
This uses the DateTime class. It is timezone and fractional seconds aware. To display the date use the format method:
echo $dt->format("Y-m-d H:i:s e");
// 2010-08-22 04:46:18 Z
To convert the date to local timezone use the setTimezone method:
$dt->setTimezone(new DateTimeZone(date_default_timezone_get()));
echo $dt->format("Y-m-d H:i:s e");
// 2010-08-21 21:46:18 America/Los_Angeles
sounds like strtotime is what you're looking for.
EDIT: if this doesn't work, take a look at the Date and Time classes - there are methods for parsing dates in specified formats (like this - doesn't return a timestamp directly, but if you construct a DateTime from this, you can use it's getTimestamp-method)
Try this:
$date=substr("2010-08-22T04:46:18.000z",0,strlen("2010-08-22T04:46:18.000z")-1);
$stamp=strtotime($date);
The "z" at the end seems to be the problem for strtotime.

PHP DateTime::createFromFormat doesn't parse ISO 8601 date time

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.

Categories