我想知道这是否可能,所以假设我有一个这样的模型:
MyModel
SomeDate - Carbon
现在,我也有一个当前用户的时区,如下所示:
User
MyTimezone
存储在数据库中的时区始终以 UTC 格式存储(以确保一切一致),并且输出的日期应始终格式化为特定时区(但时区因用户而异),例如 America/Chicago 用于 User1 和 America/ User2 的丹佛。
有没有办法在输出之前将每个 Carbon 实例的时区自动格式化为给定的时区,还是我必须遍历集合并相应地设置每个时区?
设置app.timezone
不起作用,因为它还会导致 Carbon 实例保存到app.timezone
时区的数据库中,而数据库中的所有日期都应该是 UTC,因此我失去了一致性。
我目前已app.timezone
在 App 配置中设置为 UTC,但我也被迫在输出之前将所有 Carbon 实例转换为正确的时区。有没有更好的方法,也许是在 Carbon 变成字符串之前捕获执行并在那里执行?
编辑:
我尝试过的事情:
覆盖 setAttribute & getAttribute:
public function setAttribute($property, $value) {
if ($value instanceof Carbon) {
$value->timezone = 'UTC';
}
parent::setAttribute($property, $value);
}
public function getAttribute($key) {
$stuff = parent::getAttribute($key);
if ($stuff instanceof Carbon) {
$stuff->timezone = Helper::fetchUserTimezone();
}
return $stuff;
}
覆盖 asDateTime:
protected function asDateTime($value)
{
// If this value is an integer, we will assume it is a UNIX timestamp's value
// and format a Carbon object from this timestamp. This allows flexibility
// when defining your date fields as they might be UNIX timestamps here.
$timezone = Helper::fetchUserTimezone();
if (is_numeric($value))
{
return Carbon::createFromTimestamp($value, $timezone);
}
// If the value is in simply year, month, day format, we will instantiate the
// Carbon instances from that format. Again, this provides for simple date
// fields on the database, while still supporting Carbonized conversion.
elseif (preg_match('/^(\d{4})-(\d{2})-(\d{2})$/', $value))
{
return Carbon::createFromFormat('Y-m-d', $value, $timezone)->startOfDay();
}
// Finally, we will just assume this date is in the format used by default on
// the database connection and use that format to create the Carbon object
// that is returned back out to the developers after we convert it here.
elseif ( ! $value instanceof DateTime)
{
$format = $this->getDateFormat();
return Carbon::createFromFormat($format, $value, $timezone);
}
return Carbon::instance($value);
}