应根据字段类型和时区需求选择:操作 date 类型或仅需“今天”判断时用 curdate() 更安全且语义清晰;涉及时间精度或 timestamp 字段时用 now() 或更标准的 current_timestamp;务必统一时区并明确字段定义。

CURDATE() 返回日期部分,NOW() 返回日期+时间——选哪个取决于你真正要存或比对的字段类型。
什么时候该用 CURDATE() 而不是 NOW()
当你操作的是 DATE 类型字段(比如生日、签约日、归档日),或者只需要做「今天」级别的判断时,CURDATE() 更安全、更语义清晰。
- 写入
DATE字段时报错:Incorrect datetime value: '2024-05-20 14:30:00' for column 'create_date'→ 这是把带时间的NOW()插进纯日期字段导致的 -
WHERE create_date = CURDATE()比= DATE(NOW())少一次函数调用,MySQL 可能更好利用索引(尤其在create_date有索引时) - 注意:
CURDATE()返回的是服务器本地时区的日期,不是 UTC
NOW() 的常见误用和时区陷阱
NOW() 看似方便,但容易在跨时区部署或与应用层时间逻辑混用时出问题。
- 默认返回服务器系统时区的时间,不是 UTC;如果应用用的是 UTC 时间戳,直接比对会偏差数小时
-
INSERT INTO log (ts) VALUES (NOW())和INSERT INTO log (ts) VALUES (UTC_TIMESTAMP())在非 UTC 服务器上结果不同 - 在复制环境中,主从服务器时区不一致时,
NOW()可能导致主从数据不一致(比如触发器里用了它) - 如果字段是
TIMESTAMP类型且没设DEFAULT CURRENT_TIMESTAMP,NOW()写入后不会自动随服务器时区变更而调整显示值
替代方案:用 CURRENT_DATE 和 CURRENT_TIMESTAMP 更明确
它们和 CURDATE()/NOW() 功能等价,但语义更强,SQL 标准兼容性更好,某些 ORM 或迁移工具更倾向识别这些关键字。
-
CURRENT_DATE≡CURDATE(),都返回YYYY-MM-DD -
CURRENT_TIMESTAMP≡NOW(),返回YYYY-MM-DD HH:MM:SS(精度可加括号指定,如CURRENT_TIMESTAMP(3)) - 建表时推荐显式写:
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,而不是依赖插入时手写NOW() - 如果字段定义为
TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,就不用在每次UPDATE时手动赋值
真正麻烦的不是函数本身,而是没想清楚字段类型、时区归属、以及是否需要自动更新——这三个点定下来,CURDATE() 和 NOW() 用哪个基本就没争议了。











