MySQL将时间戳转换为时区以进行搜索查询

问题描述 投票:1回答:1

我有一个MySQL数据库,该数据库具有一个名为orders的表和一个名为timestampcreated_at列]

所有时间戳均以UTC格式存储,并转换回前端的用户本地时间-当前设置为'欧洲/伦敦'

[伦敦在4月到11月之间有夏令时,这里的时钟是格林尼治标准时间(GMT + 1),例如,在当地时间27-10-2019 00:00创建的订单将保存为26-10-2019 23:00 UTC

用户可以搜索在某些日期之间创建的所有订单。在MySQL中,我可以使用以下函数将日期转换回本地时区以实现此目标,例如:

SELECT * 
  FROM orders 
 WHERE DATE(CONVERT_TZ(created_at, 'UTC','Europe/London')) >= '27-10-2019' 
   AND DATE(CONVERT_TZ(created_at, 'UTC','Europe/London')) <= '27-10-2019'

但是我在共享主机上,并且未加载MySQL时区表,因此无法使用命名时区。我只需要使用一个时区,您可能在想为什么不将所有时间戳都存储为Europe/London而不是UTC。我想将其保留为'UTC'以在将来适应其他时区。

是否存在不使用命名时区来返回正确结果的解决方法?

请注意,查询实际上是使用php中的laravels eloqeunt查询生成器编写的,如下所示:

if (isset($queryString['from_date'])) {
    $query = $query->whereRaw('DATE(orders.created_at) >= ?', [Carbon::parse($queryString['from_date'])->format('Y-m-d')]);
}

if (isset($queryString['to_date'])) {
    $query = $query->whereRaw('DATE(orders.created_at) <= ?', [Carbon::parse($queryString['to_date'])->format('Y-m-d')]);
}

起初,我认为解决方案是将用户输入的日期也转换为UTC,但是当我在以下日期创建订单时,结果将丢失第二条记录:

created_at
-------------------------------------------------------------
27-10-2019 00:00 (localtime) - saved as 26-10-2019 23:00 (UTC)
27-10-2019 01:00 (localtime) - saved as 27-10-2019 00:00 (UTC)

感谢任何帮助。

*更新*

通过增加结束日期(在DST无效时,用<而不是<=检查结果日期时间不起作用。在英国,DST于2019-10-27于今年关闭。Lets说您在以下日期创建了订单:

created_at (Europe/London)                   created_at (UTC) as saved in DB
------------------------------------         --------------------------------
2019-10-26 23:00                             2019-10-26 22:00  (UTC)
2019-10-27 03:00                             2019-10-27 03:00  (UTC)

用户想要列出在2019-10-27上创建的所有订单。使用2019-10-27作为用户选择的日期,使用php Carbon将开始日期变为2019-10-26

Carbon\Carbon::parse('27 Oct 2019', 'Europe/London')->timezone('UTC')->format('Y-m-d')
=> "2019-10-26"

结束日期变为2019-10-28

Carbon\Carbon::parse('27 Oct 2019', 'Europe/London')->addDay()->timezone('UTC')->format('Y-m-d')
=> "2019-10-28"

这意味着查询最终以:

WHERE created_at >= "2019-10-26"
  AND created_at < "2019-10-28"

因此,在上述情况下,您最终得到一个结果集,该结果集将包含在2019-10-26上创建的订单,而这并不是理想的结果。

我有一个MySQL数据库,该数据库带有一个名为orders的表和一个名为created_at的时间戳记列。所有时间戳记均以UTC格式存储并在前端转换回用户本地时间-...

mysql laravel datetime timezone php-carbon
1个回答
1
投票
您应该向您的托管服务提供商投诉。如果未安装时区表并保持最新状态,则实际上是MySQL的无效安装。
© www.soinside.com 2019 - 2024. All rights reserved.