MySQL - 查询创建的记录 "today",但日期为 UTC
MySQL - Querying for records created "today", but date is in UTC
我目前以 UTC 格式存储我的日期时间,出于所有目的,到目前为止它运行良好。但是现在我想查询在我自己的东部时区的特定日期(例如今天)创建的记录。
由于时差,我现在正在创建的记录将有明天的日期。例如,在我的时区中,日期部分当前为 2016-06-20
,但 UTC 为 2016-06-21
。
当记录存储为 UTC 时,我如何准确地获取我自己时区中特定日期的记录?我在想我可以使用 convert_tz
函数将存储的值转换为 Eastern,并将其用作我的 where
子句的一部分。这样日期就匹配了。这是一个可靠的解决方案吗?
CONVERT_TZ 函数正是您所需要的。但我不同意:
I could use the convert_tz function to convert the stored value to
Eastern, and use that as part of my where clause.
因为在 WHERE
子句上使用函数 可能会 降低性能。
如果您使用存储过程,我建议您先转换输入日期,然后在 SELECT
语句中使用它们。它看起来像这样:
SET @fromDate = CONVERT_TZ(@fromDate, ...) --Convert to UTC
SET @toDate = CONVERT_TZ(@toDate, ...) --Convert to UTC
SELECT *
FROM TableA A
WHERE A.FromDate BETWEEN @fromDate AND @toDate
http://ee1.php.net/manual/en/class.datetime.php
$foo = new DateTime("today", new DateTimeZone("America/Vancouver"));
var_dump($foo->format('c'), $foo->format('U'));
$foo->setTimeZone(new DateTimeZone("UTC"));
var_dump($foo->format('c'), $foo->format('U'), $foo->format('Y-m-d H:i:s'));
输出:
string(25) "2016-06-20T00:00:00-07:00"
string(10) "1466406000"
string(25) "2016-06-20T07:00:00+00:00"
string(10) "1466406000"
string(19) "2016-06-20 07:00:00"
将您正在搜索的日期时间边界转换为 UTC。
CONVERT_TZ功能很方便。像这样:
WHERE my_utc_date_time_col >= CONVERT('2016-02-20','EST5EDT','+00:00')
AND my_utc_date_time_col < CONVERT('2016-02-20','EST5EDT','+00:00') + INTERVAL 1 DAY
(假设您已填充 MySQL 时区 tables,因此支持命名时区。)
这实际上相当于:
WHERE my_utc_date_time_col >= '2016-02-20' + INTERVAL 4 HOUR
AND my_utc_date_time_col < '2016-02-20' + INTERVAL 4 HOUR + INTERVAL 1 DAY
或
WHERE my_utc_date_time_col >= '2016-02-20 04:00:00'
AND my_utc_date_time_col < '2016-02-21 04:00:00'
如果您想引用 NOW()
等函数来获取当前日期,那么 MySQL 连接的时区将很重要,因为返回的日期时间值将在MySQL 连接的 time_zone。
SHOW VARIABLES LIKE 'time_zone' ;
请注意,我们更喜欢在 文字 侧而不是在列上进行转换,因为如果我们在列上进行转换,则会强制 MySQL对 table 中的 每个 行执行转换,并比较文字。当我们在文字方面进行转换时,这允许 MySQL 有效地使用索引范围扫描操作(具有可用的适当索引。)
https://dev.mysql.com/doc/refman/8.0/en/time-zone-support.html
SELECT DATE(CONVERT_TZ(NOW(), 'UTC', 'America/Vancouver')) as VancouverToday;
我并不是说这是优化的、快速的等等。我只是说如果你存储了 UTC 值 and/or 你的服务器是 UTC 并且你正在寻找今天的比较,这显示“今天”已针对您的时区进行了调整。
我目前以 UTC 格式存储我的日期时间,出于所有目的,到目前为止它运行良好。但是现在我想查询在我自己的东部时区的特定日期(例如今天)创建的记录。
由于时差,我现在正在创建的记录将有明天的日期。例如,在我的时区中,日期部分当前为 2016-06-20
,但 UTC 为 2016-06-21
。
当记录存储为 UTC 时,我如何准确地获取我自己时区中特定日期的记录?我在想我可以使用 convert_tz
函数将存储的值转换为 Eastern,并将其用作我的 where
子句的一部分。这样日期就匹配了。这是一个可靠的解决方案吗?
CONVERT_TZ 函数正是您所需要的。但我不同意:
I could use the convert_tz function to convert the stored value to Eastern, and use that as part of my where clause.
因为在 WHERE
子句上使用函数 可能会 降低性能。
如果您使用存储过程,我建议您先转换输入日期,然后在 SELECT
语句中使用它们。它看起来像这样:
SET @fromDate = CONVERT_TZ(@fromDate, ...) --Convert to UTC
SET @toDate = CONVERT_TZ(@toDate, ...) --Convert to UTC
SELECT *
FROM TableA A
WHERE A.FromDate BETWEEN @fromDate AND @toDate
http://ee1.php.net/manual/en/class.datetime.php
$foo = new DateTime("today", new DateTimeZone("America/Vancouver"));
var_dump($foo->format('c'), $foo->format('U'));
$foo->setTimeZone(new DateTimeZone("UTC"));
var_dump($foo->format('c'), $foo->format('U'), $foo->format('Y-m-d H:i:s'));
输出:
string(25) "2016-06-20T00:00:00-07:00"
string(10) "1466406000"
string(25) "2016-06-20T07:00:00+00:00"
string(10) "1466406000"
string(19) "2016-06-20 07:00:00"
将您正在搜索的日期时间边界转换为 UTC。
CONVERT_TZ功能很方便。像这样:
WHERE my_utc_date_time_col >= CONVERT('2016-02-20','EST5EDT','+00:00')
AND my_utc_date_time_col < CONVERT('2016-02-20','EST5EDT','+00:00') + INTERVAL 1 DAY
(假设您已填充 MySQL 时区 tables,因此支持命名时区。)
这实际上相当于:
WHERE my_utc_date_time_col >= '2016-02-20' + INTERVAL 4 HOUR
AND my_utc_date_time_col < '2016-02-20' + INTERVAL 4 HOUR + INTERVAL 1 DAY
或
WHERE my_utc_date_time_col >= '2016-02-20 04:00:00'
AND my_utc_date_time_col < '2016-02-21 04:00:00'
如果您想引用 NOW()
等函数来获取当前日期,那么 MySQL 连接的时区将很重要,因为返回的日期时间值将在MySQL 连接的 time_zone。
SHOW VARIABLES LIKE 'time_zone' ;
请注意,我们更喜欢在 文字 侧而不是在列上进行转换,因为如果我们在列上进行转换,则会强制 MySQL对 table 中的 每个 行执行转换,并比较文字。当我们在文字方面进行转换时,这允许 MySQL 有效地使用索引范围扫描操作(具有可用的适当索引。)
https://dev.mysql.com/doc/refman/8.0/en/time-zone-support.html
SELECT DATE(CONVERT_TZ(NOW(), 'UTC', 'America/Vancouver')) as VancouverToday;
我并不是说这是优化的、快速的等等。我只是说如果你存储了 UTC 值 and/or 你的服务器是 UTC 并且你正在寻找今天的比较,这显示“今天”已针对您的时区进行了调整。