Doctrine ORM: NULL to DateTime conversion error - php

I use PHP7, Symfony 2.8 andDoctrine ORM 2.5.
I have an entity with a datetime field:
/** #ORM\Column(name="data_ordine", type="datetime", nullable=true) */
private $dataOrdine;
/**
* #param mixed $dataOrdine
*/
public function setDataOrdine($dataOrdine = null)
{
$this->dataOrdine = $dataOrdine;
}
/**
* #return mixed
*/
public function getDataOrdine()
{
return $this->dataOrdine;
}
When i try to get the $dataOrdine field ($ordine->getDataOrdine()) of a persisted entity on MySQL database if the dataOrdine column is NULL i got:
object(DateTime)#551 (3) {
["date"]=>
string(27) "-0001-11-30 00:00:00.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(13) "Europe/Berlin"
}
instead of NULL

I ran into the same issue some time ago. As #goto said your column is not coming as NULL because new DateTime(NULL) is a valid statement.
As this is exactly what happened to me I am entirely sure that the value for the problematic row is coming as 0000-00-00 00:00:00 which makes new DateTime('0000-00-00 00:00:00') to return the wrong date.
$null_date = new DateTime(null);
$wrong_date = new DateTime('0000-00-00 00:00:00');
var_dump($null_date);
var_dump($wrong_date);
object(DateTime)#1 (3) {
["date"]=>
string(26) "2018-01-17 13:22:01.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(10) "US/Pacific"
}
object(DateTime)#2 (3) {
["date"]=>
string(27) "-0001-11-30 00:00:00.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(10) "US/Pacific"
}
I've got a workaround which I didn't like at all and instead of what is posted and accepted as an answer I made the DBA to no allow NULL|invalid dates at those columns.
More info at: How to handle default values for a DateTime type in Doctrine2 SELECT query?

Some clients show null for 0000-00-00 00:00:00 values. So check via the command line client to be sure (CLI shows correct values). And then just update to null where the value is 0000-00-00 00:00:00

Related

How to get current DATE/TIME with microseconds in CI4?

Awkward problem -> I'm trying to get current date&time in ISO 8601 format (like this: 2022-02-11 12:30:02.846108).
When I run $time = new Time('now', 'Europe/Amsterdam') in CI4, $time returns this:
object(CodeIgniter\I18n\Time)#79 (6)
{ ["timezone":protected]=> object(DateTimeZone)#80 (2)
{ ["timezone_type"]=> int(3)
["timezone"]=> string(16) "Europe/Amsterdam"
}
["locale":protected]=> string(2) "en"
["toStringFormat":protected]=> string(19) "yyyy-MM-dd HH:mm:ss"
["date"]=> string(26) "2022-02-11 12:30:02.846108"
["timezone_type"]=> int(3)
["timezone"]=> string(16) "Europe/Amsterdam"
}
but when i try to get $time->date returns NULL.
Any ideea how to access date string in order to get the current time with microseconds?
Found out there is no ->date attribute in the DateTime object, which is why $time->date returns NULL.
The proper way to get the date with microseconds is:
$time->format('Y-m-d\TH:i:s.u')

Parse millisecond timestamp with DateTime in PHP

I want to create a DateTime object from a millisecond timestamp but that does not seem to work:
$timestamp_in_ms = 1546300800000; // int or string no difference
var_dump(DateTime::createFromFormat("Uv", $timestamp_in_ms));
var_dump(DateTime::getLastErrors());
This results in:
bool(false)
array(4) {
["warning_count"]=>
int(0)
["warnings"]=>
array(0) {
}
["error_count"]=>
int(1)
["errors"]=>
array(1) {
[13]=>
string(12) "Data missing"
}
}
However if I use a slightly different notation it does work:
$timestamp_in_ms = "1546300800.000";
var_dump(DateTime::createFromFormat("U\.v", $timestamp_in_ms));
var_dump(DateTime::getLastErrors());
object(DateTime)#1 (3) {
["date"]=>
string(26) "2019-01-01 00:00:00.000000"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+00:00"
}
Yes I can do something like this:
$timestamp_with_dot = $timestamp_in_ms / 1000 + "." + $timestamp_in_ms % 1000;
The documentation does not provide any insight in this. Both U and v are supported.
Anybody more info on this issue? I am running PHP 7.4.10
With a division by 1000 you can convert your millisecond timestamp as a float in seconds.
$msTimeStamp = 1600790571478;
$floatSec = $msTimeStamp/1000.0;
When using DateTime::createFromFormat, you can also use the "U.u" format. The "u" format should be exactly 6 characters. This can be done with sprintf().
$dateTime = DateTime::createFromFormat("U\.u", sprintf('%1.6F',$floatSec));
//test
echo $dateTime->format('Y-m-d H:i:s.u');
//2020-09-22 16:02:51.478000
//Timezone "+00:00" (UTC)
The millisecond timestamp can also be a float and also contain microseconds.
The above code works on 32-bit systems too.

The function setTimezone changes the timezone but not the date

I am trying to change the TimeZone of my date from Europe/Berlin to UTC before storing in it into the DB.
When I use the setTimezone() method of the DateTime object, it changes the timezone property but not the date itself.
Example code :
$dt = new \DateTime();
var_dump($dt);
$dt->setTimezone(new \DateTimeZone('Indian/Comoro'));
var_dump($dt);
$dt->setTimezone(new \DateTimeZone('UTC'));
var_dump($dt);
And the result :
object(DateTime)#1479 (3) { ["date"]=> string(26) "2019-02-18 14:12:37.521579" ["timezone_type"]=> int(3) ["timezone"]=> string(13) "Europe/Berlin" }
object(DateTime)#1479 (3) { ["date"]=> string(26) "2019-02-18 14:12:37.521579" ["timezone_type"]=> int(3) ["timezone"]=> string(13) "Indian/Comoro" }
object(DateTime)#1479 (3) { ["date"]=> string(26) "2019-02-18 14:12:37.521579" ["timezone_type"]=> int(3) ["timezone"]=> string(3) "UTC" }
Berlin is UTC+1 and Comoro is UTC+3, but the date doesn't change.
I'm working with Symfony 4 on Vagrant.
This test is made inside of a controller
Is it possible that my Timezones are all set to +00 ?
What kind of tests could I implement to find the cause of this problem ?
UPDATE
This returns me an offset of 0 in my controller.
It returns 3600 with php CLI.
$tz = new \DateTimeZone('Europe/Berlin');
var_dump($tz->getOffset(new \DateTime('now', new \DateTimeZone('UTC'))));
The problem was from the tzdata package which worked well after updating.
I had to restart apache to make it work in my app.
The timestamp value represented by the DateTime object is not modified when you set the timezone using this method. Only the timezone, and thus the resulting display formatting, is affected.
Try this (assuming the date is set to Europe/Berlin timezone by default):
$dt = new \DateTime();
Pass through the timezone UTC:
$timezone = new \DateTimeZone('UTC');
we then need to get the offset.
$offset = $timezone->getOffset($dt);
lastly, modify the date using the offset:
$dt->modify($offset . 'seconds');

PHP format date with milliseconds works but parse fails

I'm using the following format Y-m-d\TH:i:s.v\Z to follow the JavaScript toISOString implementation (2011-10-05T14:48:00.000Z).
Everything works fine if I have a DateTime and I want to format it, however I cannot parse a string that uses this format.
$format = 'Y-m-d\TH:i:s.v\Z';
$stringDateTime = (new \DateTime())->format($format);
var_dump(date_create_from_format($format,$stringDateTime));
I'm using PHP 7 and I have tested the code above with PHP 7.0,7.1 and 7.2. The return that I expect in line 3 is a DateTime class, however I'm getting a false due to there is a parse problem.
I hope someone can clarify this behavior.
Thanks
Datetime will handle it fine, you won't need to create from format.
<?php
$format = 'Y-m-d\TH:i:s.v\Z';
$stringDateTime = (new \DateTime())->format($format);
var_dump(date_create($stringDateTime));
https://3v4l.org/phLE1
Result:
object(DateTime)#1 (3) {
["date"]=>
string(26) "2018-03-13 18:07:30.005000"
["timezone_type"]=>
int(2)
["timezone"]=>
string(1) "Z"
}
This also works:
<?php
$format = 'Y-m-d\TH:i:s.u\Z';
$stringDateTime = (new \DateTime())->format($format);
var_dump(date_create_from_format($format, $stringDateTime));
$format = \DateTime::ISO8601;
$stringDateTime = (new \DateTime())->format($format);
var_dump(date_create_from_format($format, $stringDateTime));
https://3v4l.org/FcUqe
object(DateTime)#1 (3) {
["date"]=>
string(26) "2018-03-13 18:15:10.011717"
["timezone_type"]=>
int(3)
["timezone"]=>
string(16) "Europe/Amsterdam"
}
object(DateTime)#1 (3) {
["date"]=>
string(26) "2018-03-13 18:15:10.000000"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+01:00"
}

can't access php DateTime contents

I've got a variable that upon var_dump prints this.
It contains a date, but I just don't know how to access the date data, if I put
$myVariable[date] OR $myVariable["date"] OR $myVariable['date'] all result in error.
object(DateTime)#8 (3) {
["date"]=> string(19) "2011-07-25 00:00:00"
["timezone_type"]=> int(3)
["timezone"]=> string(16) "Europe/Stockholm"
}
I don't understand what the first number is either, the #8 right after the (DateTime)...
echo $myVariable->format('Y-m-d H:i:s');
(thanks to kmfk for that answer)

Categories