当前位置: 首页 > 知识库问答 >
问题:

Laravel/Carbon中的多重时间划分

仲孙小云
2023-03-14

我想知道这是否可能,所以假设我有一个这样的模型:

MyModel
   SomeDate - Carbon

现在,我还为当前用户设置了一个时区,如下所示:

User
   MyTimezone

存储在数据库中的时区总是以UTC格式存储(以确保一切是一致的),输出的日期应该始终格式化为特定的时区(但每个用户的时区不同),例如User1的America/Chicago和User2的America/Denver。

是否有一种方法可以在输出之前自动将每个Carbon实例的时区格式化为给定的时区,或者我必须循环收集并相应地设置每个时区?

设置app.timezone无效,因为它还会导致碳实例保存到app.timezone时区中的数据库中,而数据库中的所有日期都应以UTC为单位,因此我失去了一致性。

我目前有app.timezone在App配置中设置为UTC,但我也被迫在输出之前将所有Carbon实例转换为正确的时区。有没有更好的方法,也许在碳变成字符串之前捕获执行并在那里执行

编辑:

我尝试过的事情:

覆盖集合属性

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);
}

共有2个答案

娄德运
2023-03-14

如果我理解正确,你试图实现的是将时区从A格式转换为B格式并将其发送给用户,其中A格式存储在数据库中,B格式在从数据库检索记录后转换为。

这里有一个简单的方法。

在需要转换的模型中,例如UserMyModel,在模型中添加一个函数:

public function getConversionAttribute()
{
    $conversion = Convert($this->SomeDate);
    //Convert is the customized function to convert data format
    //SomeDate is the original column name of dates stored in your database
    return $conversion;
}

现在,如果您使用$user=User::find(1)查询User Model或MyModel,您现在可以通过使用$user-访问转换属性来获取转换后的日期

干杯

但是,以这种方式添加的属性不会包含在转换的数组中。您需要在模型中添加另一个函数。

public function toArray()
{
    $array = parent::toArray();
    //if you want to override the original attribute
    $array['SomeDate'] = $this->conversion;
    //if you want to keep both the original format and the current format
    //use this: $array['Conversion'] = $this->conversion;
    return $array;
}

一般版本:

public function toArray() {
    $array = parent::toArray();
    //if you want to override the original attribute
    $dates = $this->getDates();

    foreach ($dates as $date) {
        $local = $this->{$date}->copy();
        $local->timezone = ...
        $array[$date] = (string)$local;
    }
    //if you want to keep both the original format and the current format
    //use this: $array['Conversion'] = $this->conversion;
    return $array;
}

郎诚
2023-03-14

在我的应用程序中遇到了同样的问题,远程网站将以UTC存储日期,我必须根据登录用户显示实际日期,我提出了覆盖Laravel Elount模型的方法。

只需扩展照明\数据库\雄辩\模型,如下所示:

<?php namespace Vendor\Package;

use Illuminate\Database\Eloquent\Model as EloquentModel;

class Model extends EloquentModel
{

    /**
    * Return a timestamp as a localized DateTime object.
    *
    * @param  mixed  $value
    * @return \Carbon\Carbon
    */
    protected function asDateTime($value)
    {
        $carbon = parent::asDateTime($value);
        // only make localized if timezone is known
        if(Auth::check() && Auth::user()->timezone)
        {
            $timezone = new DateTimeZone(Auth::user()->timezone);
            // mutates the carbon object immediately
            $carbon->setTimezone($timezone);
        }

        return $carbon;
    }
    /**
    * Convert a localized DateTime to a normalized storable string.
    *
    * @param  \DateTime|int  $value
    * @return string
    */
    public function fromDateTime($value)
    {
        $save = parent::fromDateTime($value);

        // only make localized if timezone is known
        if(Auth::check() && Auth::user()->timezone)
        {
            // the format the value is saved to
            $format = $this->getDateFormat();

            // user timezone
            $timezone = new DateTimeZone(Auth::user()->timezone);

            $carbon = Carbon::createFromFormat($format, $value, $timezone);
            // mutates the carbon object immediately
            $carbon->setTimezone(Config::get('app.timezone'));

            // now save to format
            $save = $carbon->format($format);
        }

        return $save;
    }
}

也许这对其他在这个问题上结结巴巴的人是有用的。

作为参考

  • laravel 5(2015-03-18):照明\数据库\雄辩\模型:2809-2889
  • laravel 4.2(2015-03-18):照明\数据库\雄辩\模型:2583-2662
 类似资料:
  • 我有一个主要基于CET地区的项目。我在配置/app.php中设置了CET,但是基中的所有枢轴时间戳都存储在UTC时间? 如何设置时间戳的“全局”时区? 我做了这个测试: 结果是这样的: TNX Y

  • 我想用西班牙文打印当前日期,并用以下格式打印:2018年8月31日,但我只得到2018年10月31日星期三。 我已经用过: 以及: 在配置/app.php中,我尝试了: 我还尝试了es_-es、es_-MX、es_-US、es_-MX.utf8,但它一直以英语返回日期。我正在Linux上工作,我已经添加了所需的区域设置。 有人知道如何解决这个问题吗?

  • 我试图找到一个解决方案,如何将存储在数据库中的日期时间转换为yyyyy-mm-dd HH-mm-ss,并给它时区美国/Los_Angeles。 如果我更改时区,Carbon将自动从时间中减去7小时,这就是将时间从UTC更改为PST时发生的情况,但我的DB中的时间设置为PST时间。例如,我希望时间是今天上午10点,但如果我改变时区,碳将转换为今天凌晨3点。 如果时区改为PST,但仍然保持上午10点的

  • 问题内容: 我有一个数据集: 我想基本上在一个小时内“拆分”这些时间间隔,例如: 到目前为止,这是我的代码(该想法的积分发给@DumitrescuBogdan,将通话数据分为15分钟间隔): 后半部分(在“全部合并”之后)不产生任何结果,前半部分产生以下结果: 谢谢,我是初学者。我了解第一部分;坦白地说,我不明白下半场 我愿意接受其他解决方案。 我正在使用MS-Access 2010 问题答案:

  • 我知道在Kafka中不可能对多个分区进行排序,并且分区排序只能保证组内的单个使用者(对于单个分区)。然而,用Kafka流0.10现在有可能实现这一点吗?如果我们使用时间戳特性,使每个分区中的每个消息都保持顺序,那么在消费者端,假设使用Kafka Streams0.10,这现在是可能的吗?假设我们收到了所有的消息,我们是否可以根据消耗的时间戳对所有的分区进行排序,并可能将它们转发到一个单独的主题以供

  • 简介 你见过推特上面的 这 些 代码 图片 吗? 虽然这些代码图片给人印象深刻,但就审美程度来说还有可改进的地方。Carbon 可以很容易的为你的代码创建漂亮的图片。那么还等什么呢?用这个新学到的美化设计给你的 followers 秀一秀吧。 可以访问 carbon.now.sh或者浏览 博客文章 了解关于这个项目更多的内容。 特性 GitHub gist 导入. 只需要在 url 后面加上 gi