Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Laravel localised DateTimes with UTC Database storage
@props(['date', 'relative', 'classes'])
<time datetime="{{ $date->toIso8601String() }}">
@unless($relative)
{{ $date }}
@else
{{ $date->diffForHumans(now()) }}
@endunless
</time>
<?php
namespace App\View\Components;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Carbon;
use Illuminate\View\Component;
class DateTime extends Component
{
public function __construct(
public Carbon $date,
public bool $relative = false,
public string $classes = '',
) {
// Use either the User's preferred timezone or the app configured one
$timezone = auth()->user()->timezone ?? config('app.timezone');
// Extract locale from request header or the app configured one
[ $locale ] = explode(
',',
request()->header('Accept-Language', config('app.locale'))
);
// Apply User's prefences
$this->date
->timezone($timezone)
->locale($locale);
}
/**
* Get the view / contents that represent the component.
*
* @return \Illuminate\Contracts\View\View|\Closure|string
*/
public function render(): View
{
return view('components.date-time');
}
}
<?php
namespace App\Models\Traits;
use Carbon\Carbon;
trait DateTime
{
/**
* If Carbon - Set the timezone to `app.timezone` configuration
*
* @param mixed $value
*
* @return \Carbon\Carbon|mixed
*/
protected function asDateTime($value)
{
if($value instanceof Carbon) {
$value->timezone(config('app.timezone'));
}
return parent::asDateTime($value);
}
/**
* If Carbon - Set the timezone to `app.timezone` configuration
*
* @param mixed $value
*
* @return \Carbon\Carbon|mixed
*/
public function fromDateTime($value)
{
if($value instanceof Carbon) {
$value->timezone(config('app.timezone'));
}
return parent::fromDateTime($value);
}
}
<?php
namespace App\Models;
use App\Models\Traits\DateTime;
use Illuminate\Database\Eloquent\Model;
// [...]
class ExampleModel extends Model
{
use DateTime;
// [...]
/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'a_date' => 'datetime',
'anoter_date' => 'datetime',
];
// [...]
}
<x-date-time :date="App\Models\ExampleModel::find(1)->a_date" />
<x-date-time :relative="true" :date="App\Models\ExampleModel::find(1)->a_date" />
@Illizian
Copy link
Author

Illizian commented Sep 28, 2021

Cannot include / in filenames on Gist, so updated Class names to indicate type, and you can use namespaces to assign directory structure

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment