timostamm / doctrine-fixed-timezone
在 Doctrine 数据库中规范化时区。
v1.1.2
2021-04-29 20:25 UTC
Requires
- php: ^7.1|^8.0
- doctrine/dbal: ^2.7
Requires (Dev)
- phpunit/phpunit: ^7.5
README
问题
如果你的应用程序处理不同时区的日期,你有两种选择
1) 将每个日期的时区保存到数据库中
如果你以后需要知道时区,这是唯一的选择。
不幸的是,这使得对日期的查询几乎不可能: SELECT * FROM x WHERE x.date > CURRENT_TIMESTAMP()
将导致意外结果。CURRENT_TIMESTAMP 将使用数据库服务器的当前时间,而你提供的日期将被错误地解释为错误的时区。
2) 将数据库中保存的所有日期转换为同一时区
如果你将所有日期转换为数据库服务器的时区,你的查询将按预期工作。
不幸的是,Doctrine 并没有提供这样的转换选项。
本库提供的解决方案
本库提供了对 DBAL 类型 datetime
和 datetime_immutable
的替换,这些类型将自动将日期转换为数据库时区。
当读取 datetime
或 datetime_immutable
时,时区 不会转换为 PHP 时区。日期将指代正确的时间点,但具有数据库时区。
关于独立的日期和时间
没有时间的日期或没有日期的时间都不指代一个绝对的时间点。由于 PHP 没有表示独立时间或日期的类型,开发者使用 DateTime
对象来表示这些,但它们的时区应该被忽略。
因此,使用标准的 date
和 time
doctrine 类型应该是没有问题的。
如何使用
Symfony
doctrine: dbal: # ... types: datetime: TS\DoctrineExtensions\DBAL\FixedDbTimezone\DateTimeType datetime_immutable: TS\DoctrineExtensions\DBAL\FixedDbTimezone\DateTimeImmutableType
要设置数据库时区,定义一个常量 define('DATABASE_TIMEZONE', 'Europe/Berline');
或设置环境变量 DATABASE_TIMEZONE
。
否则,将使用 PHP 时区。