Problems with formatting a date in Symfony - php

I am implementing the Bootstrap Date Range Picker on my Symfony CRM, in order for my client to choose a range of dates for a particular holiday season.
However, when it comes to adding the data to the database, it needs to be in the format of Start Date and End Date. The database expects a DateTime object, but I want it to be more readable on the front end for the client.
This is what gets passed back to the Controller once submitted:
20/5/2017 - 20/7/2017
In my Controller, I use the following code:
$dates = $form['startDate']->getData();
$date_bits = explode(" - ",$dates);
$startDate = \DateTime::createFromFormat('Y-m-d',$date_bits[0]);
$endDate = \DateTime::createFromFormat('Y-m-d',$date_bits[1]);
Except when I persist to the database I get this error:
Fatal error: Call to a member function format() on boolean in
/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeType.php on line
53
So I tried this method instead:
$startDate = new \DateTime(str_replace("/","-",$date_bits[0]));
$endDate = new \DateTime(str_replace("/","-",$date_bits[1]));
$startDate = $startDate->format('Y-m-d');
$endDate = $endDate->format('Y-m-d');
But I receive the same error. What am I doing wrong here?
EDIT: Actually for the second code block, the error states I am calling format() on a string.

DateTime::createFromFormat() returning false means that whatever string representing the date you're submitting to it does not match the format you have provided.
The first parameter of DateTime::createFromFormat should be the format that you are submitting to it, in this case "d/m/Y". You can then do $startDate->format('Y-m-d') to get the date formatted the way you want it.
$dates = $form['startDate']->getData();
$date_bits = explode(" - ",$dates);
$startDate = \DateTime::createFromFormat('d/m/Y',$date_bits[0])->format('Y-m-d'); // 2017-05-20
$endDate = \DateTime::createFromFormat('d/m/Y',$date_bits[1])->format('Y-m-d'); // 2017-07-20
NB: Don't use->format() if you want it to remain as a DateTime object. Format always returns a string.

Usually with date I'm using this:
$startDate = new \Datetime($date_bits[0]);
$endDate = new \Datetime($date_bits[1]);
if you want to use CreateFromFormat try this please:
$startDate = new \DateTime::createFromFormat('d/m/Y', $date_bits[0])->format('Y-m-d');
$endDate = new \DateTime::createFromFormat('d/m/Y', $date_bits[1])->format('Y-m-d');

The error message:
Fatal error: Call to a member function format() on boolean in /vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeType.php on line 53
is generated by code that attempts to call DateTime::format() on something that is not a DateTime object but a boolean (FALSE, to be more specific).
It is actually the value of $startDate, returned by DateTime::__construct() that doesn't know how to parse your input string.
You pass it a date like 20/5/2017. Obviously, its format is 'd/m/Y'.
DateTime::__construct() and strftime() do not understand it. They expect either m/d/Y or Y/m/d. It is impossible for them to tell apart d/m/Y from m/d/Y without any hint and the PHP programmers have chosen to ignore d/m/Y because m/d/Y is used more.
However, for date & time formats not understood directly, there always exists the function DateTime::createFromFormat(). It allows you to tell the engine what date & time components to search for into the string and in which order.
All you have to do is to use it properly:
$startDate = \DateTime::createFromFormat('d/m/Y',$date_bits[0]);

Related

The separation symbol could not be found Data missing

I'm working with Laravel 5.8 and I wanted to show a popup message if the UNIX timestamp of the current date is equal to the defined Unix timestamp of the popup.
So in order to do that, I added this at the Controller:
$date1= $popup->datep; // returns 1636403400
$date1 = Carbon::createFromFormat('Y-m-d H:i:s', $date1);
dd($date1);
But instead of getting the result of $date1, I get this error:
The separation symbol could not be found Data missing
So what's going wrong here? How can I solve this issue?
You are specifying a format that is clearly not an unix timestamp. Use method for the timestamp.
$date = Carbon::createFromTimestamp($popup->datep);
If you want to compare it to be the same date, you should do the following. I don't assume you want to compare it by the hour or second, that those will almost never match.
$date->startOfDay()->eq(now()->startOfDay());
Regarding Carbon Docs:
createFromFormat() is mostly a wrapper for the base php function DateTime::createFromFormat.
which is means that your second parameter must be a valid date/time format, not a timestamp.
The DateTime::create docs:
$datetime
String representing the time.
Instead, you need to use the createFromTimestamp instantiator.
$date1 = Carbon::createFromTimestamp($date1);

Laravel - format date to store it on MySQL database

I am using Laravel and I have to get some dates and store it on MySQL database.
When I create the date like this:
$date_sol = Carbon::createFromFormat("Y-m-d H:i:s","2020-12-10 01:00:00");
The date is properly stored on the database. However, I have to get the date from an input.
I am trying to get the date and then format it like this:
$novaData = $request->input('solicitacao_data') . ' 15:16:17';
$sol->data = Carbon::parse($novaData)->format("Y-m-d H:i:s");
However, I get the error:
DateTime::__construct(): Failed to parse time string (28/03/2020
15:16:17) at position 0 (2): Unexpected character
The error is at the line $sol->data = Carbon::parse($novaData)->format("Y-m-d H:i:s");
How do I make the formating conversion properly? I am new using Laravel. I am not sure about it.
For date format 'd/m/Y' try this.
Carbon::createFromFormat('d/m/Y', '22/02/2020')->toDateTimeString();
Similarly for date format Y-m-d try this
Carbon::createFromFormat('Y-m-d', '2020-02-22')->toDateTimeString();
output will be in format (Y-m-d H:i:s)
"2020-02-22 21:05:13"
Let's say you receive something as input.
Well, ideally you should first sanitize it, to make sure you received a string that can be interpreted as a date. For that, I would suggest you to have a look there :
php date validation
So, you assign the input to a var and append a string representing some time to it:
$novaData = $request->input('solicitacao_data'). ' 15:16:17';
From here, the easiest is to convert the string into a timestamp. Which can be achieved this way:
$time = strtotime($novaData);
And now, you can use Carbon to format the date the way you want :
$sol->data = Carbon::createFromTimestamp($time)->format("Y-m-d H:i:s");

PHP DateTime error; cannot parse string

I have this DateTime cannot parse string error in php. i have tried applying solutions I read online but none has worked so far. My question is, is it possible for DateTime() to be disabled. Even the simplest code
$date = new DateTime('2010-5-5');
echo $date->format('Y-m-d);
Does not work.
I also tried using the static function createFromFormat(). And also I am not calling the DateTime class from a Class..so I do not need a back slash. What can I do please
Use this one for date format, So you can give the input format and get output format also
$date = DateTime::createFromFormat('d/m/Y', $date);
$fromdate = $date->format('Y-m-d');

Fatal error: Call to a member function format() on boolean passing in Wordpress ACF Datepicker to template

Here is my code:
$original_date = get_field('event_date');
$date = DateTime::createFromFormat('lFdY', strtotime($original_date));
$new_date = $date->format('l, F d, Y');
This code is in a custom post loop in a shortcode and called in the Wordpress admin.
I have also tried it without the strtotime. I am using PHP 5.6.
The event_date field is from an Advance Custom Fields date picker.
If I just pass the field, I get my intended output (the input from the custom post admin page), but without whitespace and commas. I also set this, save and display values in the acf in WP.
This is the error:
Fatal error: Call to a member function format() on boolean on the line
with $new_date variable.
Then if I use:
$date = date("l, F d, Y", strtotime($original_date));
The loop throws an error, undefined variable, for each instance of the post.
You should pass the string directly to the createFromFormat method:
$date = DateTime::createFromFormat('lFdY', $original_date);
The boolean you're receiving is because createFromFormat is failing and returning false.
If you're still receiving an error, get_field() is likely not returning what you think it is.
Try using this .. <?php echo date('l, F d, Y', strtotime(get_field('event_date')));?> it is working at my end
Make sure your get_field('event_date') returns you the date in 20160113 format If not then change the return format from ACF setting in WP back-end.
DateTime::createFromFormat returns false if it fails to convert the input string using the format specified.
In your case, you're taking an $original_date, converting it to a numeric timestamp, and trying to pass that in to DateTime::createFromFormat, which isn't going to work, hence the error. You'll need to pass in the original date instead:
$date = DateTime::createFromFormat('lFdY', $original_date);
PHP currently can not parse that specific format string. You can demonstrate this with an easy case that should "obviously" work. This:
DateTime::createFromFormat('lFdY', date('lFdY', time()));
returns false. The issue is specifically because of the lack of space between l and F in the format string and between the day-of-week and month in your input string.
You should use a different date format. If you can remove the text representation of the day-of-week (because it's not actually necessary to disambiguate the date), or at least get a space between the day-of-week and the month, that would be best.
Since you have existing data in your database in an unhelpful format, you could write a relatively simple pre-processor to remove the day-of-week from the input string:
$new_date = substr($original_date, strpos($original_date, 'y') + 1);
$date = DateTime::createFromFormat('FdY', $new_date);
(This example assumes always english day names, in lowercase, and the input is always valid. You may need more complicated code for your actual data.)
Nitty, gritty details: When PHP processes the l formatter (day of week), it requires seeing one of the characters in: ,;:/.-(), a space, tab, or end-of-string as an indication of where to stop reading.
So, if your date string is FridayJuly082016, because there are no spaces whatsoever in the input date, the code continues reading the entire string, and then fails because (literally) FridayJuly082016 is not in the list of days of the week.
Unfortunately for your particular case, this is also not likely to be "fixed". You have an extremely unusual date format, and making this particular case work in the code would make it considerably more complicated, for a questionable and rare use case.
#jbafford I found a solution.
First I save the date format to yymmdd in the ACF datepicker field
Then I used this code to extract the year month and date separately and then formatted the strtotime result:
$odate = get_field('event_date');
$y = substr($odate, 0, 4); $m = substr($odate, 4, 2); $d = substr($odate, 6, 2);
$new_date = date('l, F j, Y', strtotime("{$d}-{$m}-{$y}"));
What confused me I think and got me hung up was the presumption that I had to pass l or the day into the strtotime and that I had to match input with the intended formatted output. PHP date doesn't need that much info to accomplish the task. Thanks for all of your input!

Laravel: saving date to MySQL

In my controller, when I create an event, it saves perfectly fine. The user enters a date in dd-mm-yyyy and it gets saved in MySQL DATETIME format. Then the details view renders it completely fine, just like the edit view via model binding.
As soon as I try to save from the edit form, the date somehow fails and returns 1970-01-01 00:00:00.
I am not really sure why this only happens on my update method, as my store method is in essence the same.
$input = Input::all();
$input['plannedTime'] = date('Y-m-d H:i:s', strtotime(Input::get('plannedTime')));
How comes the update method returns no error, validation is alright, but it still won't save it correctly?
The value of 'plannedTime' is a string of date format d-m-Y H:i:s.
There's your problem. PHP's strtotime does its best, but 04-05-2015 00:00:00 could be either April 5 or May 4, depending where you live.
As an example, on my install, strtotime('04-13-2014 00:00:00') fails (which'll get converted to 0, which'll get converted to 1970-01-01).
Laravel's date validation expects a value that strtotime can handle. If you're using an ambiguous date format, use createFromFormat to parse it, then format to spit it out in a more standard format.
$date = DateTime::createFromFormat('d-m-Y H:i:s', Input::get('plannedTime'));
$usableDate = $date->format('Y-m-d H:i:s');
MySQL never returns any error for invalid dates as far as i can remember, it just sets it to EPOCH and thats it!
You should enforce your dates to be always converted to a "Y-m-d H:i:s" format when communicating with your site and display the date in "d-m-Y" only on the output side.
You should try and use
public static DateTime DateTime::createFromFormat ( string $format , string $time [, DateTimeZone $timezone ] )
To create a datetime object from a format. If you know your format such as in this case, then provide the format and get a date object back which will be persisted correctly!

Categories