Laravel no guarda el desplazamiento horario en un campo de fecha y hora.
El problema: no se guarda la zona horaria
Tengo una columna de tipo datetime en mi base de datos MYSQL llamada starts_at
. Cuando intento guardar una fecha Carbon con una zona horaria, por ejemplo 2021-12-31 13:00:00.0 UTC (+00:00)
, el registro se guarda correctamente.
Pero cuando consulto el registro nuevamente, veo que no se guardó la zona horaria.
En su lugar, veo "2021-12-31 13:00:00"
, es decir, no se guardó la zona horaria UTC (+00:00).
Quiero que quede explícito que las fechas en esta columna están en UTC.
Fragmento de código
Aquí tienes un ejemplo de lo que está sucediendo:
// 1. Crear un objeto Carbon con una zona horaria de UTC
$first<em>of</em>jan<em>sydney = Carbon::create(2022, 1, 1, 0, 0, 0, 'Australia/Sydney');
$first</em>of<em>jan</em>sydney->setTimezone('UTC');
// => Carbon\Carbon @1640955600 {#4471
// date: 2021-12-31 13:00:00.0 UTC (+00:00),
// }
// 2. Establecer el campo starts<em>at con el objeto Carbon
$food</em>item<em>availability = FoodItemAvailability::first();
$food</em>item<em>availability->starts</em>at = $first<em>of</em>jan<em>sydney;
$food</em>item_availability->save();
// 3. Cuando vuelvo a consultar la columna starts<em>at, veo que no se guardó la zona horaria (UTC)
FoodItemAvailability::first()->starts</em>at; // "2021-12-31 13:00:00"
Migración
En la migración que creó la tabla, utilicé dateTimeTz
, por ejemplo:
php
$table->dateTimeTz('starts_at')->nullable();
Configuración
En mi archivo app.php
, he establecido la zona horaria, por ejemplo:
php
'timezone' => 'UTC',
En mi archivo database.php
, he establecido la zona horaria, por ejemplo:
php
'mysql' => [
// ...
'timezone' => '+00:00',
],
davy.ai
Solución – Establecer explícitamente la zona horaria
El problema de que la zona horaria no se guarde se debe al hecho de que el tipo de columna
dateTimeTz
en MySQL incluye la información de zona horaria, pero la biblioteca Carbon de Laravel solo almacena la información de fecha y hora de forma predeterminada.Para resolver este problema, debemos establecer explícitamente la zona horaria para el objeto Carbon antes de guardarlo en la base de datos. Podemos hacer esto llamando al método
setTimezone
en el objeto Carbon y pasando la zona horaria deseada, que en este caso es UTC.Aquí tienes un fragmento de código actualizado que establece explícitamente la zona horaria:
Observa que en el paso 2, llamamos al método
toDateTimeString
en el objeto Carbon para obtener una cadena formateada que representa la fecha y hora con la zona horaria incluida, y guardamos esa cadena en el campostarts_at
.Con este cambio, al consultar la columna
starts_at
, veremos que la zona horaria (UTC) se guardó explícitamente, como2021-12-31 13:00:00 UTC
.Al establecer explícitamente la zona horaria para el objeto Carbon, estamos asegurando que se guarde la información de zona horaria correcta en la base de datos y que se pueda recuperar correctamente al consultar la columna.
Esto debería resolver el problema de que la zona horaria no se guarde para la columna
starts_at
en la base de datos MySQL.