【问题标题】:MySQL - Querying for records created "today", but date is in UTCMySQL - 查询“今天”创建的记录,但日期为 UTC
【发布时间】:2016-10-22 10:11:53
【问题描述】:

我目前以 UTC 格式存储我的日期时间,并且出于所有目的,到目前为止它运行良好。但是现在我想在我自己的时区(东部时区)查询在特定日期(例如今天)创建的记录。

由于时间不同,我现在创建的记录将有明天的日期。例如,在我的时区中,日期部分当前是 2016-06-20,但 UTC 是 2016-06-21

当记录存储为 UTC 时,如何在我自己的时区准确获取特定日期的记录?我在想我可以使用convert_tz 函数将存储的值转换为东部,并将其用作我的where 子句的一部分。这样日期匹配。这是一个可靠的解决方案吗?

【问题讨论】:

  • 您可以访问您的问题历史记录并在适当的时候开始接受答案。对于任何想要回答的人来说,这不是一个有希望的景象。
  • 我明白了。谢谢你的提醒。

标签: php mysql laravel datetime php-carbon


【解决方案1】:

CONVERT_TZ 函数实际上就是您所需要的。但我不同意:

我可以使用 convert_tz 函数将存储的值转换为 东部,并将其用作我的 where 子句的一部分。

因为在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

【讨论】:

    【解决方案2】:

    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"
    

    【讨论】:

      【解决方案3】:

      将您要搜索的日期时间边界转换为 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 时区表,因此支持命名时区。)

      这实际上相当于:

      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' ; 
      

      请注意,我们更喜欢在 literal 一侧而不是在列上进行转换,因为如果我们在列上进行转换,这会迫使 MySQL 为 every 表中的行,并比较字面量。当我们在字面上进行转换时,这允许 MySQL 有效地使用索引范围扫描操作(有适当的可用索引。)

      【讨论】:

      • 感谢您的意见。我做了与你提到的类似的事情,所以我在文字方面进行转换并将其与列进行比较。
      【解决方案4】:

      https://dev.mysql.com/doc/refman/8.0/en/time-zone-support.html

          SELECT DATE(CONVERT_TZ(NOW(), 'UTC', 'America/Vancouver')) as VancouverToday;
      

      我并不是说这是优化、快速等。我只是说如果您存储了 UTC 值和/或您的服务器是 UTC 并且您正在寻找今天的比较,这表明您“今天”已根据您的时区进行了调整。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-12-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-03
        • 1970-01-01
        • 2015-12-24
        • 1970-01-01
        相关资源
        最近更新 更多