DateTime format expects parameter 1 to be string, Object given - Symfony2 - php

I'm having some troubles using the format function in Symfony2 when trying to insert a date interval into a table, for the purpose of setting due dates for created invoices.
Here is what I have:
$today = new \DateTime();
$interval = $today->add(new \DateInterval('P1M'));
$invoice->setDueDate($interval->format('Y-m-d H:i:s'));
However, when I hover over the format parameter in PHPStorm, it tells me that it's expecting a DateTime object not a string, and I get the following error in my profiler:
Error: Call to a member function format() on string
So, I changed the line to this:
$invoice->setDueDate($interval->format(new \DateTime()));
But when I run that, my profiler gives this error:
Warning: DateTime::format() expects parameter 1 to be string, object given
It almost seems like a catch 22 situation! I am really baffled, do I use a string or a DateTime object, because either one fails yet warns me I need to use one or the other..
Any ideas?

I’d guess that $invoice->setDueDate() is the one expecting a DateTime instance. So the line should be $invoice->setDueDate($interval);

Related

Object of class DateTime could not be converted

I can see that there are many questions along these lines but I am very confused as to why the following does not work, taken straight from the PHP docs:
$tempDate = DateTime::createFromFormat('j-M-Y', '15-Feb-2009');
echo $tempDate;
The error:
PHP Catchable fatal error: Object of class DateTime could not be converted to string.
In fact every example in the docs gives me this error. Any ideas?
You can't echo the DateTime object directly. You have to use the format method to get the date and / or time part:
$tempDate = DateTime::createFromFormat('j-M-Y', '15-Feb-2009');
echo $tempDate->format('Y-m-d H:i:s');
// NOT echo $tempDate!!!
demo: http://ideone.com/IyqRWj
If you want to see the details of the object (for debug) you can use var_dump:
$tempDate = DateTime::createFromFormat('j-M-Y', '15-Feb-2009');
var_dump($tempDate);
The error message:
PHP Catchable fatal error: Object of class DateTime could not be converted to string.
is self-explanatory. The statement:
echo $tempDate;
attempts to print a DateTime object. The echo() language construct expects a string, you pass it a DateTime object. The DateTime class does not implement the __toString() magic method and PHP doesn't know how to convert a DateTime object to string.
There are so many ways to represent a DateTime object as string and all of them are handled by the DateTime::format() method.
In fact every example in the docs gives me this error.
In fact, every example in the documentation of DateTime::createFromFormat() reads:
echo $date->format('Y-m-d');
which is a different thing that echo $date;.
Any ideas?
Read the documentation of DateTime and DateTime::format() carefully.

Laravel5 Eloquent default date mutator fails with JSON date input

I've a model with date mutators, such as created_at. Let's say a generic timestamp property.
When passing data from the client in JSON format, i'll get
{
timestamp: "2016-06-07T22:00:00.000Z"
}
That property will be used to set some model like so:
$model = new Foo();
$model->timestamp = Input::get('timestamp');
Since this will trigger the date mutator, php Carbon gets called and fails with
InvalidArgumentException in Carbon.php line 425
Unexpected data found.
Trailing data
Now, that's not an issue with Carbon itself, that is able to handle JSON formats. If you'll try
new Carbon('2016-06-07T22:00:00.000Z');
you'd infact get the expected result.
From what i see, the problem origins from a weird Eloquent behaviour. See this trace from the above mentioned InvalidArgumentException in Carbon.php line 425:
in Carbon.php line 425
at Carbon::createFromFormat('Y-m-d H:i:s', '2016-06-07T22:00:00.000Z') in Model.php line 2915
at Model->asDateTime('2016-06-07T22:00:00.000Z') in Model.php line 2871
at Model->fromDateTime('2016-06-07T22:00:00.000Z') in Model.php line 2826
at Model->setAttribute('timestamp', '2016-06-07T22:00:00.000Z') in Model.php line 3351
Eloquent is trying to createFromFormat passing a bad format which doesnt mirror the actual JSON format, that is causing the Carbon exception.
On the other hand, a simple call like the above mentioned new Carbon($jsonDate) would work fine in this case.
How should i approach to solve this?
Isn't this supposed to be an Eloquent bug?
== EDIT ==
I didn't code any mutator myself. I'm using default date mutators like so:
public function getDates() {
return ['timestamp'];
}
Eloquent analyses the date you give it, when the attribute is set in the getDates function.
In it's analyses it has four steps: (see Modal.php asDateTime method for clarification, the code is pretty well commented: https://github.com/illuminate/database/blob/master/Eloquent/Model.php#L2898)
If it is already a Carbon instance, use that
If it is an instance implementing DateTimeInterface, use that
If it is numeric, parse as a Unix timestamp
If it is a simple year month day format (tried by regex) use that
If none of the above, create a Carbon instance with the format you specify as default
In you case, 1-4 don't match, so it tries 5.
You have no custom dateFormat specified on the model, so it uses the default date format applicable to the type of database connection you are using. You can override this by adding a $dateFormat variable to the model:
protected $dateFormat = 'U';
But your normal timestamps are probably in the correct format already. So this solution would not work for you.
In your case I would just do:
$model->timestamp = Carbon::parse(Input::get('timestamp'));
Or use Carbon::createFromFormat() with the appropriate format.
I don't exactly know why they don't just parse it with Carbon directly. I guess it is more error prone and less controllable. With different international formats you might get an unexpected outcome (month and day switched etc). It might also be slower than their current approach.

Can't use variable in DateTime's modify() function. I'm getting an error: Object of class DateInterval could not be converted to string

I managed to dynamically load and compare several time values in PHP.
Right now I am stuck here:
$additional_time = $entry_start->diff($compare_from_timeformat);
$additional_time ->format("H:i");
$avaliabletime->modify('+1 hours');
I want to replace the +1 with $avaliabletime but if i try something like this:
$avaliabletime->modify('+'.$additional_time.' hours');
I get this error:
Catchable fatal error: Object of class DateInterval could not be converted to string
So I got 2 questions now.
is there a way to use a variable with the modify part ?
can I also add minutes in the same string ? for example $avaliabletime->modify('+01:45 hours'); ?
$additional_time is a DateInterval object, not a DateTime object or string. To modify your DateTime object by the amount that DateInterval represents use DateTime::add():
$additional_time = $entry_start->diff($compare_from_timeformat);
$avaliabletime->add($additional_time);
If you want to add additional time then you can use DateTime::modify():
$additional_time = $entry_start->diff($compare_from_timeformat);
$avaliabletime->add($additional_time);
$avaliabletime->modify('+45 minutes');

Trouble using MSSQL datetime in PHP (via SQLSRV)

I am going round in circles with this one! I'm doing the following:
Retrieving a date from an MSSQL datetime field via SQL/PHP
Sending the date to a new PHP page via the querystring
Trying to use that date in a new SQL query
I'm hitting problems here.
If I use echo:
echo $_REQUEST['rSessionDate'];
output: 15/10/2012
Which is fine, but when I use it in a SQL query I'm not getting the results I expect, so I thought the best thing to do would be to make sure it's being recognised as a date first.
If I use date_format():
echo date_format($_REQUEST['rSessionDate'],'Y-m-d');
output: Warning: date_format() expects parameter 1 to be DateTime, string given in ...
If I use strtotime():
echo strtotime($_REQUEST['rSessionDate']);
output: (nothing)
If I use date():
echo date('Y-m-d H:i',$_REQUEST['rSessionDate']);
output: Notice: A non well formed numeric value encountered in ...
If I use date() with strtotime():
echo date('Y-m-d H:i',strtotime($_REQUEST['rSessionDate']));
output: 1970-01-01 01:00
I'm sure I'm totally missing something simple.
EDIT: I've tried a few new functions I found:
$rSessionDate = new DateTime($_REQUEST['rSessionDate']);
echo $rSessionDate->format('Y-m-d H:i:s');
output: Fatal error: Uncaught exception 'Exception' with message 'DateTime::__construct(): Failed to parse time string (15/10/2012) at position 0 (1): Unexpected character'
and:
$rSessionDate = date_create($_REQUEST['rSessionDate']);
echo date_format($rSessionDate, 'Y-m-d H:i:s');
output: Warning: date_format() expects parameter 1 to be DateTime, boolean given i
EDIT 2:
I have tried using CAST:
SELECT fCourseCode ,fCourseTitle FROM tCourses WHERE fCourseCode = '4B' AND (ISNULL(fValidStart, 0) <= CAST('2012-10-15 00:00:00' as DATETIME))
But this fails with error "The conversion of a varchar data type to a datetime data type resulted in an out-of-range value"
These might help to shed some light on what you're looking for.
http://www.ozzu.com/programming-forum/php-mssql-datetime-field-not-pulling-correctly-t106226.html
http://af-design.com/blog/2010/03/13/microsoft-sql-server-driver-for-php-returns-datetime-object/
strtotime() is returning an epoch timestamp in your example above.
or check CAST and CONVERT (refers to MSSQL2000 but may still help you)
http://msdn.microsoft.com/en-us/library/aa226054%28SQL.80%29.aspx
if the date was retrieved from an MSSQL table and you want to use strtotime() in PHP and also don't want to change the date format to yyyy-mm-dd then you can use
CONVERT(VARCHAR(30), DateFromMSSQL, 121) as DateFromMSSQL

How to create DateTime object from string in symfony2/php

In a DB table I have several fields with datetime as field type. So I need to persist data only as date time object.
From a form I get date time as string like
2012-10-05 17:45:54
Now when ever I persist my entity I get following error:
Fatal error: Call to a member function format() on a non-object in
..\DateTimeType.php on line 44
I tried with
$protocol->setStartedAt(strtotime($post['started_at']));
or
$from = \DateTime::createFromFormat('yy-mm-dd hh:mm:ss', $post['started_at']);
$protocol->setStartedAt($from);
or just
$from = new \DateTime($post['started_at']);
$protocol->setStartedAt($from);
The last code works but it does not uses the timestamp passed as arguement but just gets the current time.
Any ideas?
I always create a DateTime object with its constructor, in your case it would be:
$protocol->setStartedAt(new \DateTime($post['started_at']));
if this works but does not use the timestamp posted you probably do not have the value in $post['started_at']. Try debugging it or just do the dirty trick:
die($post['started_at']);
For the sake of future readers who surely will someday encounter this problem (this is the first post if you google "symfony 2 datetime from string"), keep in mind that in Symfony 2 the DateTime object does NOT accept a string with that format : "d/m/Y H:i:s", and probably doesn't support many others either.
For the sake of not becoming mad at that, I've actually found out that the easiest and safest solution to avoid such errors is this one:
First, get your date string from whatever kind of request you are doing (In my case a generic AJAX request) and convert it to a DateTime Object, this example assumes that we need to create a dateTime object for 25/04/2015 15:00, which is the format of the jQuery UI italian DateTimePicker (that's just an example):
$literalTime = \DateTime::createFromFormat("d/m/Y H:i","25/04/2015 15:00");
(note: use \ to use php's DateTime object, else you will be using Symfony's datetime object that will throw you an exception)
Then, once you did it, create a date string using the comfort format function, by giving to the first parameter the output format expected (Y-m-d H:i:s):
$expire_date = $literalTime->format("Y-m-d H:i:s");
In this way you are 100% sure that whatever kind of format you are passing or receiving this will properly be converted and you won't get any kind of exception from the DateTime symfony object, as long as you provide what you are expecting as an input.
Knowing that this post is actually quite old, I've just decided to post that because I didn't find any other valuable source but this one to understand where the problem could have been.
Please note that the best solution is still to send the datetime string in the correct format already, but if you literally have no ways to do that the safest way to convert such a string is the one above.
How about createFromFormat?
http://uk.php.net/manual/en/datetime.createfromformat.php
$from = DateTime::createFromFormat($post['started_at'], 'Y-m-d H:i:s');

Categories