【问题标题】:Can MySQL convert a stored UTC time to local timezone?MySQL 可以将存储的 UTC 时间转换为本地时区吗?
【发布时间】:2011-01-12 08:32:12
【问题描述】:

MySQL 可以直接在普通的 select 语句中将存储的 UTC 时间转换为本地时区时间吗?

假设您有一些带有时间戳 (UTC) 的数据。

CREATE TABLE `SomeDateTable` (
  `id`    int(11) NOT NULL auto_increment,
  `value` float NOT NULL default '0',
  `date`  datetime NOT NULL default '0000-00-00 00:00:00',
  PRIMARY KEY  (`id`)
)

然后当我

"select value, date from SomeDateTable";

我当然会以存储的 UTC 格式获取所有日期。

但是假设我想让它们在另一个时区(使用 DST), 然后我可以在选择查询中添加一些魔法,以便我在所选时区中获取所有日期吗?

"select value, TIMEZONE(date, "Europe/Berlin") from SomeDateTable";

或者我必须在顶部的其他层中执行此操作,例如在某些 php 代码中? (这似乎是大多数人解决这个问题的方法)。


如果您的 MySQL 安装允许您使用 CONVERT_TZ 这是一个非常干净的解决方案, 这个例子展示了如何使用它。

SELECT CONVERT_TZ( '2010-01-01 12:00', 'UTC', 'Europe/Stockholm' )

但是我不知道这是否是一个好方法,因为某些 MySQL 安装缺少此功能,请谨慎使用。

【问题讨论】:

    标签: mysql sql timezone convert-tz


    【解决方案1】:

    是的,有convert_tz 函数。

    【讨论】:

    • 似乎是正确的,但我直接遇到了这个错误:bugs.mysql.com/bug.php?id=12445我的服务器缺少时区数据...
    • mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql
    【解决方案2】:

    对于那些无法配置 mysql 环境(例如,由于缺乏 SUPER 访问权限)以使用“美国/丹佛”或“GMT”等人性化时区名称的人,您还可以使用带有数字偏移量的函数,如下所示:

    CONVERT_TZ(date,'+00:00','-07:00')
    

    【讨论】:

    • 如果该时区有夏令时 (timeanddate.com/time/dst),那将不起作用,因为夏季和冬季会有不同的偏移量,并且还有一些示例,夏令时 30 分钟...
    • 有趣.. 在我的情况下,我必须从 PHP 运行一些查询,并且不想对 PHP 中的结果进行任何 TZ 处理,但我可以轻松更改选择中的数值询问。谢谢
    【解决方案3】:
    select convert_tz(now(),@@session.time_zone,'+03:00')
    

    仅用于获取时间:

    time(convert_tz(now(),@@session.time_zone,'+03:00'))
    

    【讨论】:

      【解决方案4】:

      一个人可以轻松使用

      CONVERT_TZ(your_timestamp_column_name, 'UTC', 'your_desired_timezone_name')
      

      例如:

      CONVERT_TZ(timeperiod, 'UTC', 'Asia/Karachi')
      

      Plus 这也可以在 WHERE 语句中使用并比较时间戳,我将在 Where 子句中使用以下内容:

      WHERE CONVERT_TZ(timeperiod, 'UTC', '{$this->timezone}') NOT BETWEEN {$timeperiods['today_start']} AND {$timeperiods['today_end']}
      

      【讨论】:

      • 当我在 mysql 中执行“WHERE CONVERT_TZ”查询时,它会进行整个表扫描,即使我使用索引列作为“时间段”并使用绝对时间戳值作为“开始和结束之间”。我读过在“WHERE”或“HAVING”子句中使用列函数通常不是一个好主意。
      • 您可能是对的,但另一方面,如果您不在 where 类中使用它,那么我们将如何比较值?
      • 好点,我对此的唯一建议是要非常小心 WHERE 子句,以最小化/减轻表空间扫描。在“时间段”上对表进行分区可能在该区域有所帮助。或者,可以使用服务器端语言进行时区转换,但这可能超出了 OP 的问题范围。
      【解决方案5】:

      1。正确设置您的服务器:

      在服务器上,su 到 root 并执行以下操作:

      # mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql mysql
      

      (请注意,末尾的 command 当然是 mysql ,并且,您将其发送到恰好有 table同名mysql。)

      接下来,您现在可以# ls /usr/share/zoneinfo

      使用该命令查看 ubuntu 或几乎任何 unixish 服务器上的所有时区信息。

      (顺便说一句,这是找到某个时区的确切官方名称的便捷方式。)

      2。然后在 mysql 中是微不足道的:

      例如

      mysql> select ts, CONVERT_TZ(ts, 'UTC', 'Pacific/Tahiti') from example_table ;
      +---------------------+-----------------------------------------+
      | ts                  | CONVERT_TZ(ts, 'UTC', 'Pacific/Tahiti') |
      +---------------------+-----------------------------------------+
      | 2020-10-20 16:59:57 | 2020-10-20 06:59:57                     |
      | 2020-10-20 17:02:59 | 2020-10-20 07:02:59                     |
      | 2020-10-20 17:30:08 | 2020-10-20 07:30:08                     |
      | 2020-10-20 18:36:29 | 2020-10-20 08:36:29                     |
      | 2020-10-20 18:37:20 | 2020-10-20 08:37:20                     |
      | 2020-10-20 18:37:20 | 2020-10-20 08:37:20                     |
      | 2020-10-20 19:00:18 | 2020-10-20 09:00:18                     |
      +---------------------+-----------------------------------------+
      

      【讨论】:

        【解决方案6】:

        我建议使用

        SET time_zone = 'proper timezone';
        

        连接到数据库后立即完成一次。之后,所有时间戳都会在选择它们时自动转换。

        【讨论】:

        • 请注意,这不会自动转换 DATE、TIME 和 DATETIME 字段。这只会对 TIMESTAMP 字段进行自动转换,并影响 NOW() 和 CURDATE() 函数的结果。
        • 如果你希望这个是永久的,你也可以改变time_zone参数。
        猜你喜欢
        • 1970-01-01
        • 2019-05-31
        • 2015-11-07
        • 2014-10-05
        • 2019-03-09
        • 1970-01-01
        • 2013-07-09
        • 2011-03-01
        相关资源
        最近更新 更多