1. 在 MySQL 中获取当前时间(要点:最简 SQL 速查表)
如果你想在 MySQL 中获取当前时间,只需记住少数几个 SQL 函数。
下面是针对搜索关键词 “MySQL get current time” 的 最简答案。
1.1 MySQL 当前日期和时间:NOW() / CURRENT_TIMESTAMP
返回当前的 日期 + 时间 (YYYY-MM-DD HH:MM:SS)。
SELECT NOW();
SELECT CURRENT_TIMESTAMP;
示例输出
2025-02-01 15:30:45
NOW()和CURRENT_TIMESTAMP通常返回相同的结果。- 两者都返回当前的日期和时间。
- 如果需要毫秒,请使用以下方式。
SELECT NOW(3);
注意事项(常见错误)
- 取决于服务器的时区设置。
- 在 UTC 环境下,可能会得到 UTC 时间而非日本时间。
- 在查询执行期间,它基本上返回相同的时间(在单个语句内固定)。
1.2 MySQL 当前日期:CURDATE()
仅返回日期(不含时间)。
SELECT CURDATE();
示例输出
2025-02-01
使用场景
- 查询今天的数据
- 日期比较(例如,仅过滤今天的记录)
注意事项
- 返回值为
DATE类型。 - 当需要处理时间(时分秒)时不适用。
1.3 MySQL 当前时间:CURTIME()
仅返回时间。
SELECT CURTIME();
示例输出
15:30:45
使用场景
- 检查营业时间
- 根据时间窗口进行分支逻辑
注意事项
- 不包含日期信息。
- 不能与
DATE类型的列进行比较。
1.4 MySQL 当前 UTC 时间:UTC_TIMESTAMP()
返回 UTC(协调世界时)时间,不受服务器时区设置影响。
SELECT UTC_TIMESTAMP();
示例输出
2025-02-01 06:30:45
何时使用
- 全球化服务
- 需要统一以 UTC 存储日志的设计
常见错误
- 与
NOW()混用会导致时间偏移 - 若应用假设为日本时间(JST),会出现 9 小时的差异
1.5 MySQL 带毫秒的当前时间:NOW(3) / CURRENT_TIMESTAMP(3)
MySQL 5.6 及以上版本支持小数秒。
SELECT NOW(3);
SELECT CURRENT_TIMESTAMP(3);
示例输出
2025-02-01 15:30:45.123
存储注意事项
你的列也必须支持小数秒。
DATETIME(3)
TIMESTAMP(3)
如果存入不支持的小数秒的列,小数部分将被截断。
1.6 按用途快速速查表
| Purpose | SQL |
|---|---|
| Current date and time | SELECT NOW(); |
| Get UTC | SELECT UTC_TIMESTAMP(); |
| Date only | SELECT CURDATE(); |
| Time only | SELECT CURTIME(); |
| Get milliseconds | SELECT NOW(3); |
常见陷阱汇总
- 时间偏移是因为未确认时区
- 在没有支持毫秒的列上使用
NOW(3) - 混用 UTC 与本地时间
- 未理解 DATETIME 与 TIMESTAMP 的区别

MySQL DATETIME 与 TIMESTAMP 的区别(比较是否进行时区转换)
2. MySQL NOW() 与 CURRENT_TIMESTAMP 的区别
NOW() 和 CURRENT_TIMESTAMP 看起来相似,但 误解它们的使用场景和行为很容易导致 bug。这里我们整理了它们的区别、正确用法以及常见陷阱。
2.1 应该使用哪一个?(SELECT 用法 / DEFAULT 用法)
■ 在 SELECT 中检索当前日期/时间时
SELECT NOW();
SELECT CURRENT_TIMESTAMP;
通常,两者返回相同的结果。
- 它们是等价的(同义词)
- 返回值等同于
DATETIME - 受时区设置影响
实用要点
- 更注重可读性 →
NOW() - 更倾向标准 SQL 风格 →
CURRENT_TIMESTAMP
■ 在设置列默认值时
CREATE TABLE logs (
id INT AUTO_INCREMENT PRIMARY KEY,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
关键点在于:
对于默认值,通常使用
CURRENT_TIMESTAMP。
.某些环境也允许使用 NOW(),但 行为可能因 MySQL 版本和 SQL 模式而异。更安全的选择是 CURRENT_TIMESTAMP。
2.2 DEFAULT / ON UPDATE 的正确用法
如果你想自动更新 “updated at” 时间戳:
CREATE TABLE logs (
id INT AUTO_INCREMENT PRIMARY KEY,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP
);
行为
- 在 INSERT 时 → 为 created_at / updated_at 设置当前时间
- 在 UPDATE 时 → 仅更新 updated_at
常见错误
- 使用
DATETIME时未匹配小数秒精度 - 遇到旧版 MySQL 对多个 TIMESTAMP 列的限制(MySQL 5.6 及更早版本有此限制)
2.3 NOW() 与 SYSDATE() 的区别(重要)
容易忽视的一点是与 SYSDATE() 的区别。
SELECT NOW(), SYSDATE();
■ 行为差异
NOW()→ 在查询开始时固定时间SYSDATE()→ 返回调用时的时间
示例:
SELECT NOW(), SLEEP(3), NOW();
NOW() 返回相同的值。
SELECT SYSDATE(), SLEEP(3), SYSDATE();
SYSDATE() 显示出 3 秒的差异。
2.4 应该使用哪一个?
| Function | Behavior | Recommended use |
|---|---|---|
| NOW() | Fixed within a query | Logging, consistency-focused |
| SYSDATE() | Call-time value | Precise real-time retrieval |
为什么在实际系统中常推荐使用 NOW()
- 在事务内部保持一致性(事务是一种一次处理多个 SQL 语句的机制)
- 在复制环境中更安全
2.5 常见误解与问题
❌ “NOW() 和 CURRENT_TIMESTAMP 完全相同,所以不需要考虑它们。”
→ 根据环境的不同,差异可能会体现在默认值或更新行为上。
❌ “SYSDATE() 更精确,所以总是更好。”
→ 在复制环境中可能会导致问题。
❌ 未验证时区
SHOW VARIABLES LIKE '%time_zone%';
如果在未检查的情况下使用它,可能会出现时间偏移。
2.6 实用最佳实践
- SELECT 检索 →
NOW() - 列默认值 →
CURRENT_TIMESTAMP - 自动更新 →
ON UPDATE CURRENT_TIMESTAMP - 注重一致性 → 默认使用
NOW() - 基于 UTC 的设计 → 使用
TIMESTAMP并以 UTC 存储
- MySQL 当前时间格式化 (DATE_FORMAT / TIME_FORMAT)
在 MySQL 中检索当前时间后,更改显示格式是非常常见的。
对于搜索意图“MySQL current time format”,最重要的是理解DATE_FORMAT()函数。
3.1 MySQL 日期时间格式化:DATE_FORMAT(NOW(), …)
基本语法:
SELECT DATE_FORMAT(target_datetime, 'format_string');
示例:格式化当前时间
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s');
示例输出
2025-02-01 15:30:45
常用格式说明符
说明符
含义
示例
%Y
年(4 位数字)
2025
%m
月(2 位数字)
02
%d
日(2 位数字)
01
%H
小时(24 小时制)
15
%h
小时(12 小时制)
03
%i
分钟
30
%s
秒
45
%p
AM/PM
PM
3.2 转换为日式格式或 12 小时制
■ 日式格式
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i');
示例输出:
2025-02-01 15:30
■ 12 小时制 + AM/PM
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %h:%i:%s %p');
示例输出:
2025-02-01 03:30:45 PM
3.3 MySQL 仅时间格式化:TIME_FORMAT()
专用于TIME类型数据的格式化函数。
SELECT TIME_FORMAT(CURTIME(), '%H:%i');
示例输出:
15:30
注意
TIME_FORMAT()仅适用于TIME类型
对于DATETIME,使用DATE_FORMAT()
3.4 字符串 → 日期时间转换:STR_TO_DATE()
将字符串数据转换为日期时间类型:
SELECT STR_TO_DATE('2025-02-01 15:30:45', '%Y-%m-%d %H:%i:%s');
示例输出:
2025-02-01 15:30:45
常见错误
格式不匹配将返回 NULL
混淆%m和%c(带零填充的月 vs 不带零填充的月)
3.5 生产环境中的重要要点
❌ 不要在格式化后进行比较
不良示例:
WHERE DATE_FORMAT(created_at, '%Y-%m-%d') = '2025-02-01';
这不推荐,因为索引会失效(查询性能下降)。
推荐:
WHERE created_at >= '2025-02-01' AND created_at < '2025-02-02';
❌ 不要在数据库端过度格式化
在 Web 应用中,显示格式化通常在应用端更灵活
数据库应专注于“存储和计算”
3.6 带毫秒的格式化
SELECT DATE_FORMAT(NOW(3), '%Y-%m-%d %H:%i:%s.%f');
%f表示微秒(6 位数字)。
注意
如果列不是DATETIME(3)或类似类型,小数部分将被截断
MySQL 5.6 及更高版本可用
3.7 按格式化目的总结
目的
函数
更改显示格式
DATE_FORMAT
仅格式化时间
TIME_FORMAT
字符串 → 日期时间转换
STR_TO_DATE
显示毫秒
%f - MySQL 日期和时间加减 (DATE_ADD / DATE_SUB)
即使可以检索当前时间,如果没有“X 天后”或“X 小时前”等日期/时间计算,也无法在生产环境中有效使用它。
这里解释如何在 MySQL 中使用DATE_ADD()和DATE_SUB()与当前时间。
4.1 MySQL 日期时间加法:DATE_ADD()
基本语法:
SELECT DATE_ADD(base_datetime, INTERVAL value unit);
示例:7 天后
SELECT DATE_ADD(NOW(), INTERVAL 7 DAY);
示例:2 小时后
SELECT DATE_ADD(NOW(), INTERVAL 2 HOUR);
常用单位
单位
含义
SECOND
秒
MINUTE
分钟
HOUR
小时
DAY
天
MONTH
月
YEAR
年
4.2 MySQL 日期时间减法:DATE_SUB()
基本语法:
SELECT DATE_SUB(base_datetime, INTERVAL value unit);
示例:30 天前
SELECT DATE_SUB(NOW(), INTERVAL 30 DAY);
示例:1 小时前
SELECT DATE_SUB(NOW(), INTERVAL 1 HOUR);
使用场景
到期检查
删除旧日志
提取最近数据
4.3 常见生产模式
■ 检索过去 24 小时的数据
SELECT * FROM logs WHERE created_at >= DATE_SUB(NOW(), INTERVAL 1 DAY);
■ 设置 7 天后的截止日期
INSERT INTO tasks (deadline) VALUES (DATE_ADD(NOW(), INTERVAL 7 DAY));
4.4 常见错误与注意事项
❌ 对列使用函数
错误示例:
WHERE DATE(created_at) = CURDATE();
这会导致索引失效(查询性能优化受影响)。
推荐做法:
WHERE created_at >= CURDATE() AND created_at < DATE_ADD(CURDATE(), INTERVAL 1 DAY);
❌ 忽略时区
NOW() 基于服务器时区
如果使用 UTC 存储,请以 UTC_TIMESTAMP() 为基准
示例:
SELECT DATE_ADD(UTC_TIMESTAMP(), INTERVAL 1 DAY);
❌ 月份加法的陷阱
SELECT DATE_ADD('2025-01-31', INTERVAL 1 MONTH);
→ 由于月末调整,日期可能会变化。
(结果可能会变为 2025-02-28,取决于运行环境。)
在使用基于月份的计算前,请先了解规范。
4.5 毫秒级加法
SELECT DATE_ADD(NOW(3), INTERVAL 500 MILLISECOND);
※ MySQL 不直接支持 MILLISECOND。
请使用微秒指定:
SELECT DATE_ADD(NOW(3), INTERVAL 500000 MICROSECOND);
4.6 最佳实践
统一使用 NOW() 或 UTC_TIMESTAMP() 作为基准
不要在 WHERE 子句中对列使用函数
了解基于月份加法的行为
如果需要更高精度,请使用 DATETIME(3) 或更高版本
5. MySQL 中的日期/时间差值计算(DATEDIFF / TIMESTAMPDIFF)
在生产系统中,仅获取当前时间往往不够。
通常需要计算已经过去了多少天或还剩多少小时。
5.1 计算日期差值:DATEDIFF()
DATEDIFF() 计算两个日期之间的天数差。
SELECT DATEDIFF('2025-02-10', '2025-02-01');
结果
9
关键点
- 仅返回 天数 差值
- 忽略时间部分
- 结果可能为负数
示例:计算自创建以来的天数
SELECT DATEDIFF(NOW(), created_at)
FROM users;
5.2 按单位计算差值:TIMESTAMPDIFF()
TIMESTAMPDIFF() 允许指定差值单位。
SELECT TIMESTAMPDIFF(unit, start_datetime, end_datetime);
示例:小时差值
SELECT TIMESTAMPDIFF(HOUR, '2025-02-01 10:00:00', '2025-02-01 15:00:00');
结果
5
常用单位
| Unit | Meaning |
|---|---|
| SECOND | Seconds |
| MINUTE | Minutes |
| HOUR | Hours |
| DAY | Days |
| MONTH | Months |
| YEAR | Years |
示例:计算自登录以来的分钟数
SELECT TIMESTAMPDIFF(MINUTE, login_at, NOW())
FROM users;
5.3 生产环境使用案例
- 会话超时检查
- 订阅到期检查
- 计算日志中的耗时
- 限流逻辑
5.4 常见错误
❌ 在需要时间精度时使用 DATEDIFF
DATEDIFF() 会忽略小时和分钟。
❌ 参数顺序颠倒
顺序应为:
TIMESTAMPDIFF(unit, start, end)
如果颠倒顺序,结果会变为负数。
❌ 忽略时区
如果混用 UTC 与本地时间,计算结果可能不正确。
5.5 最佳实践
- 在需要时间精度时使用
TIMESTAMPDIFF() - 对于简单的天数计算使用
DATEDIFF() - 确保时区使用一致
- 在分布式系统中统一使用 UTC
6. 使用当前时间的日期范围查询
最常见的实际需求之一是检索特定时间范围内的记录,例如:
- 当天记录
- 最近 7 天
- 最近 24 小时
- 本月
6.1 检索当天记录(索引友好)
SELECT *
FROM logs
WHERE created_at >= CURDATE()
AND created_at < DATE_ADD(CURDATE(), INTERVAL 1 DAY);
为什么这样写是正确的
- 列上未使用函数
- 索引仍可使用
- 高效的范围查询
6.2 最近 7 天
SELECT *
FROM logs
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY);
6.3 最近 24 小时
SELECT *
FROM logs
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 1 DAY);
6.4 本月
SELECT *
FROM logs
WHERE created_at >= DATE_FORMAT(NOW(), '%Y-%m-01')
AND created_at < DATE_ADD(DATE_FORMAT(NOW(), '%Y-%m-01'), INTERVAL 1 MONTH);
在生产系统中,通常更好在应用程序端计算边界并将其作为参数传递。
6.5 常见性能错误
❌ 对索引列应用函数
WHERE DATE(created_at) = CURDATE();
这会阻止使用索引并导致全表扫描。
❌ 不慎使用 BETWEEN
BETWEEN 是包含性的,可能导致秒级的越界问题。
6.6 最佳实践摘要
- 始终在日期过滤时使用范围条件
- 避免对索引列应用函数
- 在全球系统中优先使用 UTC 存储
- 明确时区假设


