Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

saadaan's avatar

Carbon dates parsing wrong on import

Hi,

I am parsing data from an excel file import, and putting them in variables. The validation for a date is not triggering the error. This is the parsing code I have:

'date_of_application' => Carbon::parse($value->date_of_application)->format('Y-m-d');

The problem is that, if I give some false value (e.g. 01/01/0019), Carbon parsing does not throw an error, but instead it puts the value of today in the variable. I have few checks ahead in the code, but they are never triggered since Carbon already replaces the date with the current date.

Please note that in excel import, 01/01/2019 is an acceptable format which Carbon parses as 2019-01-01 successfully. It just looks like 01/01/2019 when opened in excel. So the format is not the issue.

Any good way to handle this? Ideally, Carbon should throw error on encountering 0019 as year... Or at least not replace it with today's date if 0019 is a valid programming date.

Thanks, Saad

0 likes
20 replies
Nakov's avatar

Hey @saadaan, don't know if this will fix it, but you can create a carbon instance from a format, for example:

Carbon::createFromFormat('d/m/Y', $value->date_of_application)->format('Y-m-d')

try that or use the validator.

Checkout this answer as well

https://stackoverflow.com/a/19271434/1457270

Snapey's avatar

Thats not the behavior I see in tinker;

>>> Carbon\Carbon::parse('01/01/0019')
=> Carbon\Carbon @-61567603200 {#3110
     date: 0019-01-01 00:00:00.0 UTC (+00:00),
   }
>>> 

There may be some other fault

By the way;

The problem is that, if I give some false value (e.g. 01/01/0019), Carbon parsing does not throw an error

01/01/0019 is a perfectly valid date. Why should it throw an error?

saadaan's avatar

OK, I am using maatwebsite excel export/parser. So when I make the excel file and write date in it (any format), it displays as 12/31/2019 (mm/dd/yyyy). However, without doing anything, when I import this data in laravel, the format is absolutely fine, as laravel parses it as 2019-12-31. The code I use is the same I pasted:

'date_of_application' => Carbon::parse($value->date_of_application)->format('Y-m-d');

So, the issue is not related to slashes or date format, it's working OK. I am concerned that even if 01/01/0019 is a valid format, why does Carbon puts today's date instead of this value? Please note that Carbon works very fine for so many other date values, I have tested.

jlrdw's avatar

Why do you use or need carbon, I import a non profits data from bank and just use

            $tdate = new \DateTime($array[$i][2]);  // a csv field
            $ndate = $tdate->format('Y-m-d');

$ndate is inserted. And note, carbon just uses php date time functions.

Note bank format is 12/6/2019

I store 2019-12-06

saadaan's avatar

I am doing the same in the csv import script I have, forcing the user to use a standard format Y-m-d. However, for the ease of users, I have to make the excel import work. In Excel, no matter what format of date you enter, if/when excel realizes that your entered data is date, it automatically formats it as mm/dd/yyyy, perhaps only for display. The thing is that excel import is being implemented for the ease of users, so I cannot really pass on an instruction set (again!) to the users to convert the date column into text (so that excel doesn't interfere with data formatting) and follow the Y-m-d format. This basically kills the ease I am trying to offer to the users.

In summary, I am stuck with it, and have to move forward from here :)

jlrdw's avatar

My above answer is excel. See my edited part, it takes the date and formats it correctly. You need to trust php knows how to deal with dates.

saadaan's avatar

And yes, IRONICALLY (:-) ), I am bringing in Carbon so that it could save me from a lot of date-validation checks, in case the input is not a valid date. Funny, isn't it! :-)

jlrdw's avatar

Don't let the user enter a date, force they use a popup calendar. Then at least you have a valid date. May be wrong date, but a date.

As a developer you have only 3 main rules:

  • Never trust user input
  • Never trust user input
  • Never trust user input
saadaan's avatar
Object of class DateTime could not be converted to string
jlrdw's avatar

Did you put backslash. And I am getting ready to try it in latest laravel, I had earlier version.

Works in latest laravel, I have php 7.3.1-0

And it should be for inserting data into db, I don't get the string thing.

Edit: Can you somewhere echo or dd just the

echo $value->date_of_application;

Just what format is it in.

saadaan's avatar

Yes I did. I am working on version 5.8.35. PHP is 7.3.6.

jlrdw's avatar

This works, try it in a controller method:

       $mydate = "12/6/2019";
        $tdate = new \DateTime($mydate);  // a csv field
        $ndate = $tdate->format('Y-m-d');
        echo $ndate;
        exit();

And run that in browser.

saadaan's avatar

OK, so I made the parsing syntax you mentioned to work. However, it still does not catch the erroneous dates. I tried 11/31/2019, and instead of error, it went through by giving me today's date in that variable! Same issue that I started with.

jlrdw's avatar

Yes, because November has 30 days, try a correct date. As I said force users to use a popup calendar.

saadaan's avatar

Seemingly not possible to force the user. They are copy/pasting into excel files from many sources. I can only force them to fix "DATA ON LINE X" once I detect in the logic that some date is wrong, which is currently not happening since it doesn't throw error at all!

Snapey's avatar

When you use parse you are basically asking carbon to try and make something from a date input. There is not really a wrong answer.

Better to be more prescriptive and use createFromFormat and pass it the expected format. Carbon will then throw an exception if the date does not work

Test it with Tinker so that you know how it behaves

jlrdw's avatar

@snapey I just tried your suggestion with @saadaan test wrong date:

        $mydate = "11/31/2019";
        $ndate = Carbon::createFromFormat('m/d/Y', $mydate);
        echo $ndate;
        exit();

No error, it just returned the next day:

2019-12-01 22:44:01

You would think it would "flag" that as wrong date entered.

saadaan's avatar

Seems that Carbon is a bit too helpful because it tries to make sense from every input given, and does not throw error at all :-)

Please or to participate in this conversation.