当前位置 主页 > 技术大全 >

    避开时区陷阱!详解 MySQL 获取当前时间的正确姿势与最佳实践

    栏目:技术大全 时间:2025-09-23 23:54

    在 MySQL 中获取当前日期和时间是非常常见的操作,主要用于数据记录、时间计算和过滤等场景。MySQL 提供了一系列函数来满足不同的精度和格式需求。
    以下是几种最核心和常用的方法。
    一、 核心函数概述
    MySQL 提供了多个函数来获取当前时间,区别在于返回值的格式和精度:
    | 函数 | 返回格式 | 描述 | 示例输出 |
    | : | : | : | : |
    | `NOW()` | `YYYY-MM-DD HH:MM:SS` | 返回当前的日期和时间(会话时区)。 | `2023-10-27 14:32:05` |
    | `CURRENT_TIMESTAMP()` | `YYYY-MM-DD HH:MM:SS` | `NOW()` 的同义词,功能完全相同。 | `2023-10-27 14:32:05` |
    | `CURDATE()` | `YYYY-MM-DD` | 返回当前的日期。 | `2023-10-27` |
    | `CURRENT_DATE()` | `YYYY-MM-DD` | `CURDATE()` 的同义词。 | `2023-10-27` |
    | `CURTIME()` | `HH:MM:SS` | 返回当前的时间。 | `14:32:05` |
    | `CURRENT_TIME()` | `HH:MM:SS` | `CURTIME()` 的同义词。 | `14:32:05` |
    | `SYSDATE()` | `YYYY-MM-DD HH:MM:SS` | 返回函数执行时的日期时间。 | `2023-10-27 14:32:05` |
    | `UTC_DATE()` | `YYYY-MM-DD` | 返回当前的 UTC 日期。 | `2023-10-27` |
    | `UTC_TIME()` | `HH:MM:SS` | 返回当前的 UTC 时间。 | `06:32:05` |
    | `UTC_TIMESTAMP()` | `YYYY-MM-DD HH:MM:SS` | 返回当前的 UTC 日期和时间。 | `2023-10-27 06:32:05` |
     
    二、 详细说明与示例
    1. 获取完整的日期和时间 (`NOW()` vs `SYSDATE()`)
    `NOW()` 返回语句开始执行时的时间。在一个 SQL 语句中,无论 `NOW()` 被调用多少次,它返回的值都是相同的。
    `SYSDATE()` 返回该函数被执行时的精确时间。这意味着在一个语句中多次调用 `SYSDATE()` 会得到不同的值。
    示例:
    ```sql
    SELECT NOW(), SLEEP(2), NOW();
    -- 结果:两个 NOW() 返回的时间完全相同,即使查询中间睡眠了2秒。
    -- | NOW() | SLEEP(2) | NOW() |
    -- ||-||
    -- | 2023-10-27 14:35:01 | 0 | 2023-10-27 14:35:01 |
    SELECT SYSDATE(), SLEEP(2), SYSDATE();
    -- 结果:两个 SYSDATE() 返回的时间相差2秒。
    -- | SYSDATE() | SLEEP(2) | SYSDATE() |
    -- ||-||
    -- | 2023-10-27 14:35:03 | 0 | 2023-10-27 14:35:05 |
    ```
    注意: 由于 `SYSDATE()` 的行为可能对复制(Replication)和确定性查询造成意想不到的影响,通常建议优先使用 `NOW()`。
     
    2. 获取日期或时间的部分
    如果你只需要当前日期或当前时间,可以使用相应的函数。
    示例:
    ```sql
    -- 插入一条记录,自动记录创建日期和时间
    INSERT INTO orders (product_id, quantity, created_at)
    VALUES (101, 2, NOW());
    -- 查询今天的所有订单
    SELECT FROM orders WHERE DATE(created_at) = CURDATE();
    -- 查询所有在下午2点之后创建的订单
    SELECT FROM orders WHERE TIME(created_at) > '14:00:00';
    ```
    3. 获取 UNIX 时间戳
    `UNIX_TIMESTAMP()` 函数通常用于获取一个 UNIX 时间戳(自 '1970-01-01 00:00:00' UTC 以来的秒数)。
    如果不带参数调用,它返回当前的 UNIX 时间戳。
    如果带一个日期时间参数,它返回该日期时间对应的 UNIX 时间戳。
    示例:
    ```sql
    SELECT UNIX_TIMESTAMP(); -- 输出类似:1698411725
    SELECT UNIX_TIMESTAMP('2023-10-27 14:32:05'); -- 将指定时间转换为时间戳
    ```
     
    三、 高级用法:时区的影响
    时间函数返回的值取决于 MySQL 的时区设置。
    `NOW()`, `CURDATE()` 等函数返回的是当前会话时区的时间。
    `UTC_DATE()`, `UTC_TIMESTAMP()` 等函数返回的是 UTC 时间。
    你可以查看和设置会话时区:
    ```sql
    -- 查看当前时区设置
    SELECT @@system_time_zone, @@session.time_zone;
    -- 设置当前会话的时区(例如,设置为东八区 - 北京时间)
    SET SESSION time_zone = '+08:00';
    ```
    示例:
    假设 MySQL 服务器位于伦敦(UTC时区),而你的会话时区设置为北京时间(UTC+8)。
    ```sql
    SET SESSION time_zone = '+08:00';
    SELECT NOW(), UTC_TIMESTAMP(), UNIX_TIMESTAMP();
    ```
    输出可能会是:
    ```
    ++++
    | NOW() | UTC_TIMESTAMP() | UNIX_TIMESTAMP() |
    ++++
    | 2023-10-27 22:00:00 | 2023-10-27 14:00:00 | 1698415200 |
    ++++
    ```
    `UNIX_TIMESTAMP()` 不受时区设置影响,它总是基于 UTC。
     
    总结与最佳实践
    1. 常用选择:
    记录数据创建/更新时间:在表结构设计中,通常使用 `TIMESTAMP` 或 `DATETIME` 类型的字段,并将其默认值设置为 `CURRENT_TIMESTAMP`(等同于 `NOW()`)。
    获取当前时间:优先使用 `NOW()`,而不是 `SYSDATE()`,除非你有特殊需求。
    只需要日期或时间部分:使用 `CURDATE()` 或 `CURTIME()`。
    2. 时区意识:
    如果你的应用是国际化的,务必注意时区问题。在存储时间时,可以考虑使用 UTC 时间(`UTC_TIMESTAMP()`)并在应用层根据用户所在地进行转换,或者确保会话时区设置正确。
    3. 表结构设计示例:
    ```sql
    CREATE TABLE logs (
    id INT AUTO_INCREMENT PRIMARY KEY,
    message TEXT,
    -- 设置默认值,在插入时自动写入当前时间
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    -- 使用 DATETIME 类型也可以,但语法略有不同
    updated_at DATETIME ON UPDATE CURRENT_TIMESTAMP
    );
    ```
    另外搭配便捷的MYSQL备份工具,可定时备份、异地备份,MYSQL导出导入。可本地连接LINUX里的MYSQL,简单便捷。可以大大地提高工作效率喔。

1分钟搞定MySQL部署!Docker最强实操指南,含所有常用命令和配置
忘记MySQL密码怎么办?别慌!用这一招跳过验证,轻松重置管理员权限
MySQL自增主键用完怎么办?从原理到实战,全面破解开发中的高频难题
MySQL权限混乱?这几个命令让你彻底理清用户清单与权限归属
你的数据库安全吗?读懂MySQL这几种日志,关键时刻能「救你一命」
MySQL性能上不去?八成是这里没配好!手把手教你搞定my.cnf核心配置
修改MySQL字段长度别乱来!这3个核心要点和1个致命陷阱,新手必看
MySQL单表卡爆怎么办?从策略到实战,一文掌握「分表」救命技巧
你的MySQL数据库为什么总是又慢又卡?掌握这五大优化法则,查询速度快十倍!(上篇)
你的MySQL数据库为什么总是又慢又卡?掌握这五大优化法则,查询速度快十倍!(下篇)