php - Laravel 未在日期时间字段上保存时区偏移量

标签 php mysql laravel timezone php-carbon

问题 - 时区未保存

我的 MYSQL 数据库中有一个名为 starts_at 的日期时间列。当我尝试保存带有时区的 Carbon 日期时,例如2021-12-31 13:00:00.0 UTC (+00:00),记录保存成功。

但是当我再次查询记录时,我发现时区未保存

相反,我看到“2021-12-31 13:00:00”,即 UTC (+00:00) 未保存。

我希望明确表明此列中的日期时间采用 UTC 格式。

代码片段

以下是正在发生的情况的示例:


// 1. Create a Carbon object that has a timezone of UTC
$first_of_jan_sydney = Carbon::create(2022, 1, 1, 0, 0, 0, 'Australia/Sydney');
$first_of_jan_sydney->setTimezone('UTC');

// => Carbon\Carbon @1640955600 {#4471
//      date: 2021-12-31 13:00:00.0 UTC (+00:00),
//    }


// 2. Set the starts_at field to the Carbon object
$food_item_availability = FoodItemAvailability::first();
$food_item_availability->starts_at = $first_of_jan_sydney;
$food_item_availability->save();

// 3. When I requery the starts_at column, I see that the timezone (UTC) was not saved
FoodItemAvailability::first()->starts_at; // "2021-12-31 13:00:00"

迁移

在创建表的迁移中,我使用了 dateTimeTz 例如

$table->dateTimeTz('starts_at')->nullable();

配置

在我的 app.php 中,我设置了时区,例如

'timezone' => 'UTC',

在我的database.php中,我设置了时区,例如

        'mysql' => [
            // ...
            'timezone'  => '+00:00',
        ],

最佳答案

dateTimeTztimestampTz遗憾的是并非所有数据库引擎都支持,例如 MySQL 就不支持。所以你必须将它存储在你身边的两列中。

实际上,它可以帮助更好地控制应用程序端,并避免依赖数据库进行时区处理,这在我看来更好。

我推荐:

$table->dateTime('starts_at')->nullable();
$table->string('starts_at_timezone')->nullable();

这里我使用CarbonImmutable而不是Carbon因此原始对象上的时区不会被修改。您还可以使用->copy()但是CarbonImmutable通常是处理日期的最安全方法:

$first_of_jan_sydney = CarbonImmutable::parse('2022-01-01 00:00 Australia/Sydney');


$food_item_availability = FoodItemAvailability::first();
$food_item_availability->starts_at_timezone = $first_of_jan_sydney->tzName;
$food_item_availability->starts_at = $first_of_jan_sydney->utc();
$food_item_availability->save();

// Reload later:
$item = FoodItemAvailability::first();
CarbonImmutable::parse($item->starts_at, 'UTC')->tz($item->starts_at_timezone);

PS:保留 UTC 和 +00:00 作为全局设置,这部分没问题。如果保留的话可以使用CarbonImmutable::parse($item->starts_at)->tz($item->starts_at_timezone);无需明确指定'UTC'作为时区参数。

关于php - Laravel 未在日期时间字段上保存时区偏移量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70536641/

相关文章:

php - laravel Eloquent 数组到字符串的转换

javascript - Laravel , Jquery 通过选择的下拉列表填充数据

php - CodeIgniter,将数据从模型传递到 Controller 以在 View 中使用

php - 无法让字符串数字变成 float 或整数 PHP

MySql count() 每月有多少类型,如果没有找到记录则返回 0

mysql 带条件多重连接对多表查询性能的影响

php - Codeigniter:如果有多个项目,如何对主机 url 进行分组并将其保存到数据库?

PHP 分页使用 count 和可能的 group by

mysql - 如何将此文件导入 MySQL?

sql - Laravel - 4 位小数的数字