当前位置: 首页 > 面试题库 >

CakePHP 3时间列获取添加的日期

仲孙诚
2023-03-14
问题内容

我在MySQL数据库中将许多列定义为“时间”。也就是说,他们有时间,但没有日期。当CakePHP 3 ORM读取它们时,它们将被转换为Cake \ I18n
\ Time对象(通过Cake \ Database \ Type \
TimeType类),但是结果中始终带有日期和时间,并且日期设置为当前日期。例如,如果值为“
20:00:00”,debug($record['start_time'])将生成:

object(Cake\I18n\Time) {
    'time' => '2015-06-21T20:00:00+0000',
    'timezone' => 'UTC',
    'fixedNowTime' => false
}

当我在模板中回显它时(未使用过setToStringFormat),我得到类似的信息6/21/15 8:00 PM。当然,我可以使用$this->Time->format它来将其重新设置为仅时间格式,但是似乎很奇怪。为什么Cake忽略了这 只是
一个时间这一事实,更重要的是,有没有办法使它停止?


问题答案:

日期/时间值都被强制转换为相同的基本结构,即DateTimeDateTimeImmutable对象,因此,仅日期值会自然地加上时间值(00:00:00),而仅时间值会附带日期(当前日期)

CakePHP将根据SQL数据类型使用特定的子类,即

  • \Cake\I18n\Time\Cake\I18n\FrozenTimeTIMETIMESTAMPDATETIME
  • \Cake\I18n\Date\Cake\I18n\FrozenDateDATE

在早期的CakePHP 3版本中,只有\Cake\I18n\Time

如果有一个单独的仅用于时间类型的类,这将是很好的,它会设置适当的仅时间的默认输出格式,但是在添加类似的东西之前,您必须自己照顾输出格式。

在您的视图中格式化

如何显示此视图取决于您。您可以轻松使用类实例的i18nFormat()方法Time

$record['start_time']->i18nFormat(
    [\IntlDateFormatter::NONE, \IntlDateFormatter::SHORT]
)

Time助手,仅显示时间部分

$this->Time->i18nFormat(
    $record['start_time'],
    [\IntlDateFormatter::NONE, \IntlDateFormatter::SHORT]
)

猜想,如果bake根据列的类型生成类似的代码,那不会有什么坏处,您可能会
建议将其作为增强功能
。如前所述,对于仅时间列使用其他类(或选项)可能也值得考虑。

使用自定义时间类别

如果您希望在使用对象的字符串表示形式的任何地方都需要这种行为,而不必手动调用格式化程序,则可以使用带有重写属性的扩展\Cake\I18n\Time\Cake\I18n\FrozenTime$_toStringFormat,以便对日期进行相应的格式化。

src / I18n / FrozenTimeOnly.php

namespace App\I18n;

use Cake\I18n\FrozenTime;

class FrozenTimeOnly extends FrozenTime
{
    protected static $_toStringFormat = [
        \IntlDateFormatter::NONE,
        \IntlDateFormatter::SHORT
    ];
}

src / config / bootstrap.php

use Cake\Database\Type\TimeType;
use App\I18n\FrozenTimeOnly;
TimeType::$dateTimeClass = FrozenTimeOnly::class;

// remove the default `useImmutable()` call, you may however
// want to keep further calls for formatting and stuff
Type::build('time'); 
// ...

现在,这几乎应该是自解释的,time正在映射到的列TimeTypeApp\I18n\FrozenTimeOnly代替默认值使用Cake\I18n\Time

DateTimeType::$dateTimeClass 不推荐使用

为了解决这个问题,将需要一个自定义的数据库类型,这也非常简单。

src /数据库/类型/TimeOnlyType.php

namespace App\Database\Type;

use App\I18n\FrozenTimeOnly;
use Cake\Database\Type\TimeType;

class TimeOnlyType extends TimeType
{
    public function __construct($name)
    {
        parent::__construct($name);
        $this->_setClassName(FrozenTimeOnly::class, \DateTimeImmutable::class);
    }
}

应当注意,当前这将实例化数据/时间类两次,因为父构造函数也将调用_setClassName()该实例,在此实例化给定类的实例。

src / config / bootstrap.php

use App\Database\Type\TimeOnlyType;
Type::map('time', TimeOnlyType::class);

因此,这将覆盖默认time类型映射以使用自定义\App\Database\Type\TimeOnlyType类,而自定义类将\App\I18n\TimeOnly在将数据库值转换为PHP对象时使用该类,当将其转换为字符串时,将使用仅时间格式。

也可以看看

  • 食谱 >时间>设置默认语言环境和格式字符串
  • 食谱 >数据库访问和ORM>数据库基础>添加自定义类型


 类似资料:
  • 问题内容: 在我的表我有,列。 示例:和 如何将此列添加到我的列中,这样我就可以 我尝试了这个: 但它不起作用。 谢谢你,史蒂夫 问题答案: 据我了解,您想将前两位数字添加为小时,将后两位数字添加为分钟-但您并未在通话中执行此操作- 您要将两个部分都添加为-请尝试以下操作: 在这里,我使用了两个嵌套-内部添加小时,外部添加分钟到添加小时的结果上。 另外:在SQL Server中是 基于1的 ,例如

  • 问题内容: 使用标准的mysql函数可以编写查询,该查询将返回两个日期之间的天数列表。 例如,给定2009-01-01和2009-01-13,它将返回一个具有以下值的列表: 编辑:看来我还不清楚。我要生成此列表。我在数据库中存储了值(按日期时间),但希望将它们在左外部联接中汇总到上述日期列表中(我希望这种联接的某些右侧在几天内会为null并将对此进行处理) )。 问题答案: 我将使用此存储过程将所

  • 问题内容: 我知道我可以使用momentjs做任何事情,还可以做一些涉及日期的事情。但是令人尴尬的是,我很难去做一件看起来很简单的事情:得到两次之间的差。 例: 我试过的 我不知道那里的“ 10”是什么。我住在巴西,所以如果相关的话,我们是utc-0300。 结果是持续时间正确的内部值: 所以,我想我的问题是:如何将momentjs持续时间转换为时间间隔?我肯定可以用 但我觉得有一些更 优雅 ,我

  • 问题内容: 我想获取所有尚未结束的事件 运作良好。 这是我在()中的值 我尝试使用 我收到一个错误 DbArithmeticExpression参数必须具有数字通用类型。 如何在Entity Framework中编写此查询? 问题答案: 这是因为你尝试添加有,这是不允许的。为此,请尝试使用类似以下内容的方法: 或如果这是LINQ to Entities: 编辑: 由于您是,因此您应该使用: 或者

  • 有多种方法可以添加一天,例如: 这个的问题是答案是:2016-12-06 16:52:44.679431我只需要2016-12-06。我可以通过执行像split这样的字符串操作很容易地得到它。我想知道是否有直接做这件事的方法。 其次: 从我从文档中读到的内容来看,以下两种方法应该可以给我时区的时间,但这两种方法都不能。 结果:时间。结构时间(tm_year=2016,tm_mon=12,tm_da

  • 问题内容: 这是我要传递时间戳的Under函数,我只需要从时间戳返回的日期,而不是小时和秒。通过以下代码,我得到了- 这是我得到的输出。 但是我只需要这样的日期 有什么建议? 问题答案: 改用SimpleDateFormat: 更新 :Java 8解决方案: