web-dev-qa-db-fra.com

Données Carbone Laravel manquantes

Dans mon modèle, j'ai les éléments suivants:

protected $dates = [
    'start',
    'end',
    'created_at',
    'updated_at'
];

J'utilise un sélecteur de date/heure pour insérer les dates de début et de fin, au format suivant:

2016-01-23 22:00

Sans les secondes. Quand je le fais comme ça, j'obtiens cette erreur:

InvalidArgumentException in Carbon.php line 425:
Data missing
at Carbon::createFromFormat('Y-m-d H:i:s', '2016-01-23 22:00') in Model.php line 3015

Si j'inclus les secondes, cela fonctionne. Les secondes ne sont pas importantes pour moi et je ne souhaite pas les inclure dans mes champs de sélecteur de date/heure. N'importe comment pour que je puisse toujours utiliser ces champs comme champs de date?

19
Hardist

tl; dr

Votre chaîne de date et votre format de date sont différents, vous devez modifier la chaîne de format ou modifier la chaîne de date afin qu'ils correspondent.

Explication

Le problème

Cette erreur se produit lorsque la fonction createFromFormat de Carbon reçoit une chaîne de date qui ne correspond pas à la chaîne de format transmise. Plus précisément, cela provient de la fonction DateTime::createFromFormat , car Carbon appelle simplement cela:

public static function createFromFormat($format, $time, $tz = null)
{
    if ($tz !== null) {
        $dt = parent::createFromFormat($format, $time, static::safeCreateDateTimeZone($tz));
    } else {
        $dt = parent::createFromFormat($format, $time); // Where the error happens.
    }

    if ($dt instanceof DateTime) {
        return static::instance($dt);
    }

    $errors = static::getLastErrors();
    throw new InvalidArgumentException(implode(PHP_EOL, $errors['errors'])); // Where the exception was thrown.
}

Pas assez de données

Si votre chaîne de date est "plus courte" que la chaîne de format comme dans ce cas:

Carbon::createFromFormat('Y-m-d H:i:s', '2017-01-04 00:52');

Carbon va lancer:

InvalidArgumentException dans la ligne 425 de Carbon.php:
Données manquantes

Trop de données

Si votre chaîne de date est "plus longue" que la chaîne de format comme dans ce cas:

 Carbon::createFromFormat('Y-m-d H:i', '2017-01-02 00:27:00');

Carbon va lancer:

InvalidArgumentException dans la ligne 425 de Carbon.php:
Données de suivi

Sous la capuche

Selon la documentation sur les mutateurs , le format de date par défaut est: 'Y-m-d H:i:s'. Le traitement de la date s'effectue dans la fonction asDateTime du modèle . Dans la dernière condition, la fonction getDateFormat est appelée, d'où le format personnalisé. Le format par défaut est défini dans la classe Grammar de la base de données .

Solution

Vous devez vous assurer que la chaîne de date correspond à la chaîne de format.

Changer la chaîne de format

Vous pouvez remplacer la chaîne de format par défaut comme ceci:

class Event extends Model {
    protected $dateFormat = 'Y-m-d H:i';
}

Il y a deux problèmes avec cette approche:

  • Cela s'appliquera à tous les champs définis dans le tableau $dates du modèle.
  • Vous devez stocker les données dans ce format dans la base de données.

Modifier et formater les chaînes de date

Ma solution recommandée est que le format de date reste le 'Y-m-d H:i:s' par défaut et que vous complétiez les parties manquantes de la date, comme ceci:

public function store(Request $request) {
    $requestData = $request->all();
    $requestData['start_time'] .= ':00';
    $requestData['end_time'] .= ':00';
    $event = new Event($requestData);
    $event->save();
}

Et lorsque vous souhaitez utiliser la date, vous devez la formater:

public function show(Request request, $eventId) {
    $event = Event::findOrFail($eventId);
    $startTime = $event->start_time->format('Y-m-d H:i');
    $endTime = $event->end_time->format('Y-m-d H:i');
}

Bien sûr, les champs doivent être mutés aux dates:

class Event extends Model {
    protected $dates = [
        'start_time',
        'end_time',
        'created_at',
        'updated_at',
        'deleted_at',
    ];
}
45
totymedli

Vous pouvez définir le $ dateFormat dans votre modèle comme le dit Christian, mais si vous ne souhaitez pas impliquer les champs updated_at et created_at dans l'opération, vous pouvez utiliser des événements pour "corriger" l'objet datetime avant de l'enregistrer dans la base de données.

Ici vous avez le doc officiel à ce sujet: https://laravel.com/docs/5.2/eloquent#events

4
subzeta

Des modèles

Cette fonction désactivée, les émulations de carbone dans Datetimes https://laravel.com/docs/5.0/eloquent#date-mutators

public function getDates()
{
    return [];
}
4

Vous devez définir protected $dateFormat sur 'Y-m-d H:i 'dans votre modèle, voir https://laravel.com/docs/5.2/eloquent-mutators#date-mutators

3
mazedlx

Assurez-vous de ne pas omettre les champs "created_at" ou "updated_at" de certaines lignes de votre base de données, qui sont obligatoires. si tel est le cas, supprimez les enregistrements contenant ces champs vides ou entrez une valeur au format d'horodatage valide, par exemple '2018-09-01 15:18:53'.

0
davidprogramador01