1

I looked a couple of questions with similar title but my case is quiet different. I am trying to move data from one table to another using laravel task. The table from which I want to copy the data from is using varchar for date while the table I am copying to has a date column type. So I must convert the string to valid carbon date before inserting into the new table. Unfortunately the old table has the dates mixed in different format so I have to check and convert before insert but I keep getting this error when dealing with a particular string format

Exception : DateTime::__construct(): Failed to parse time string (26/02/1991) at position 0 (2): Unexpected character

Here's what my code for converting the strings to date format looks like

if ($user->profile->date_of_birth === null) {  
    $dob = null;
    Log::info([$user->profile->date_of_birth, $dob]);
} else if (Carbon::parse($user->profile->date_of_birth)->toDateString() == true) {

    $dob = Carbon::parse($user->profile->date_of_birth)->toDateString();
    Log::info([$user->profile->date_of_birth, $dob]);
} else if (Carbon::createFromFormat('d/m/Y',   $user->profile->date_of_birth)->format('Y-m-d') == true) {

    $formattedDate = Carbon::createFromFormat('d/m/Y', $user->profile->date_of_birth)->format('Y-m-d');
    $dob = Carbon::parse($formattedDate)->toDateString();
    Log::info([$user->profile->date_of_birth, $dob]);
}

Using laravel's artisan tinker, I am actually able to convert the string to date format as can be seen here enter image description here

Why do I keep getting an error when I run my task and it encounters that particular string?

3 Answers 3

1

In Carbon, Carbon::parse('26/02/1991') does not support this format. Carbon consider it as ('m/d/Y'). That's why you getting an error when you want to parse it and convert to toDateString. I think you can change your $dob format before parse then it should be work.

// Error
Carbon::parse('26/02/1991')->toDateString() // Error: DateTime::__construct(): Failed to parse time string (20/02/1995) at position 0 (2): Unexpected character

// Solve
Carbon::parse('02/26/1991')->toDateString() // "1991-02-26"

You need to change the format of date_of_birth column in Profile model. So just add an accessor on your Profile model like that,

public function getDateOfBirthAttribute()
{
    [$day, $month, $year] = explode('/', $this->date_of_birth);
    return implode('/', [$month, $day, $year]);
}

Now, when you call $user->profile->date_of_birth it will call the accessor and get the desired format that will help to parse in Carbon.

Sign up to request clarification or add additional context in comments.

2 Comments

Changing the format is exactly what I am trying to do but since the actual live date is in the string format 26/02/1991 I tried converting it by specifying the format and that is failing. Is there another way of converting string formats?
Recently i update my code, create an accessor for re-format the date
1

Use ::createFromFormat('d/m/Y'...) instead of ::parse() like you did in the other places.

But it sounds like ->profile is a DB object, so I would highly recommend not to handle ->date_of_birth as a string, you should keep it as a Carbon instances by adding it in the $dates fields of your model; then use createFromFormat only when you get the input from the user.

Comments

0

I think the one that is failing is your

else if (Carbon::parse($user->profile->date_of_birth)->toDateString() == true)

I would enclose that in a try/catch instead. If it fails, try the next one.

4 Comments

From my logs I can see that block actually works correctly and the error message is specific about the string causing the problem.
Then don't use the Carbon::parse directly, simply specify the different possible formats and see which one works. BTW, when inserting into the DB, you don't have to specify the ->format('Y-m-d). , you can simply pass the Carbon object
How do you mean to specify the different format? Are you suggesting that I just pass the string representation of the date to my new table without converting it since the dob column is of data type? Or you mean converting each string format? If you meant to convert according to the various string format, than that is exactly the reason for the if else check. I would appreciate it if you could explain some more the approach you are suggesting. Thanks.
What are the different date formats on your text field on the old database?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.