2017-10-02 13 views
2

Ich habe ein Problem mit Carbon und HTML5-Eingang input[type=datetime-local], weil dieser Eingang sendet Zeit im Format Y-m-d\TH:i (zB 2016-11-20T11:45).Carbon unerwartete Datum-Zeit-Format in Laravel

Ich habe Methode in meinem Controller:

public function store(ModelStoreFormRequest $request) 
{ 
    $model = new Model($request->all()); 
    $model->save(); 
    return redirect->action(/*...*/); 
} 

Und ich Ausnahme:

InvalidArgumentException in Carbon.php line 582: Data Missing 
1. in Carbon.php line 582 
2. at Carbon::createFromFormat('Y-m-d H:i:s', '2016-11-20T11:45') in HasAttributes.php line 709 

So habe ich dieses Problem gelöst, indem nächste Funktion in meinem Modell zu erstellen:

public function setStartedAtAttribute($startedAt) 
{ 
    if($startedAt instanceof Carbon) { 
     $this->attributes['started_at'] = $startedAt; 
     return; 
    } 

    if(strpos($startedAt, 'T')) { 
     $this->attributes['started_at'] = Carbon::createFromFormat('Y-m-d\TH:i', $startedAt); 
     return; 
    } 

    $this->attributes['started_at'] = Carbon::createFromFormat('Y-m-d H:i:s', $startedAt); 
} 

Aber ich mag diese Lösung nicht, ich frage mich, ob es elegantere Lösung gibt? Ich denke ModelStoreFormRequest::prepareForValidation() Methode zu verwenden und es zu überprüfen, ob Format Datum ist: Y-m-d\TH:i Datetime-Wert-Format zu ändern: Y-m-d H:i:s, oder vielleicht Carbon::parse() Methode wie folgt zu verwenden:

protected function prepareForValidation() 
{ 
    $input = $this->all(); 
    $input['started_at'] = \Carbon\Carbon::parse($input['started_at']); 
    $this->replace($input); 
} 

Aber ich weiß noch nicht, ist Diese Lösung ist in Ordnung. Ich versuche, Anliegen und Verpflichtungen jeder Klasse zu trennen ... Was schlägst du vor? Irgendeine andere elegantere Lösung oder bleib bei der aktuellen?

+0

Was mit mit 'neuen Carbon-falsch ($ starteAt) '? –

+0

@MarkBaker Das ist in Ordnung, aber mein Problem ist, dass Laravel standardmäßig 'Carbon :: createFromFormat ('Ymd H: i: s')' 'nennt, aber was du vorschlägst ist,' 'new carbon'' anstatt 'Carbon :: parse() ', kaufe immer noch lässt mich mit problem sollte das in setter,' FormRequest :: preapreForValidation' oder woanders ... – clzola

+0

Stellen Sie ein Problem unter https://github.com/laravel/framework, wenn Laravel Datumsangaben nicht verarbeiten kann, formatiert nach dem ISO 8601-Standard out-of-the-box. – sisve

Antwort

1

Statt benutzerdefinierte Funktion für Format der Erstellung ändern oder Bearbeitung jede Basis von Laravel hier ist die einfache Lösung versuchen, diese

$startedAt= Carbon::createFromFormat('Y-m-d\TH:i','2016-11-20T11:45'); 

kehren Sie diese:

2016-11-20 11:45:00 

Sie jetzt für Ihr Anliegen Ich empfehle Ihnen, es im Controller zu verwenden, wenn Sie in Zukunft an mehreren Orten nicht brauchen werden.

Sie können es auch als ein Mutatoren in Ihrem Modell verwenden, wenn Sie Datum in diesem Format in db speichern müssen und nicht an mehreren Orten wie dieser

Mutatoren

public static $snakeAttributes = false; // because you have camel case here 
public function setStartedAtAttribute($value) 
{ 
    $this->attributes['startedAt'] = Carbon::createFromFormat('Y-m-d\TH:i',$value);; 
} 

benötigt werden Accessoren

public function getStartedAtAttribute() 
    { 
     $startedAt = $this->attributes['startedAt']; 
     return $startedAt 
    } 

Sie können ein separates Merkmal erstellen für Ihre Funktion, wenn Sie sie an mehreren Orten verwenden müssen, die ich empfehle, ist eine Best Practice.

trait YourTraitName{ 
    public function yourfunction(){ 
$startedAt= Carbon::createFromFormat('Y-m-d\TH:i','2016-11-20T11:45'); 
return $startedAt; 
    } 
} 

ausschließen Middle sind Middle lesen here

Weitere Carbon ähnliche Operation über Middleware allgemein für Authentifizierungsprüfung verwendet, um Sie here und Test lesen here

+0

Ich weiß, dass ich das verwenden kann, wie Sie sehen, verwende ich es bereits, aber meine Sorge ist, wo dieser Teil des Codes geht, sollte ich es als Setter in meinem Modell, in Formularanforderung, Middleware oder woanders setzen ... – clzola

+0

Nun, es hängt von Ihrem Bedarf ab, wenn Sie das Datum in diesem Format in db speichern möchten. Sie können Mutatoren für diese Middleware verwenden, ist das nicht eine gute Wahl, bis Sie es in mehreren Routen verwenden. oder wenn Sie es nur einmal verwenden, können Sie es in Controller selbst verwenden. Wahl basiert auf Ihrer Anforderung –

+0

Danke, ich denke, der beste Platz ist in Controller – clzola