CURDATE()返回当前日期(YYYY-MM-DD),类型为DATE,适用于仅需年月日的场景;与CURRENT_DATE等价,但不同于含时分秒的NOW();用于DATETIME字段比较时需用范围查询避免索引失效。

MySQL 用 CURDATE() 拿今天日期,但注意它不带时间
CURDATE() 返回的是纯日期(YYYY-MM-DD 格式),没有时分秒。如果你需要完整时间戳,别用它——这是最常踩的坑。
适用场景:做日期范围查询、插入默认日期、生成分区键等只要年月日就够了的地方。
- 返回值类型是
DATE,不是字符串,也不转成DATETIME - 在严格模式下,把它赋给
DATETIME字段会触发隐式转换,末尾补00:00:00,但不推荐依赖这种行为 - 跨时区无感知——它返回的是 MySQL 服务所在时区的“今天”,不是客户端时区
CURDATE() 和 NOW()、CURRENT_DATE 的区别在哪
三者看起来都“取当前”,但语义和精度不同:
-
CURDATE()和CURRENT_DATE完全等价,都是只取日期部分;官方文档里说后者更标准,但实际用哪个没差别 -
NOW()返回DATETIME,含时分秒甚至微秒(取决于定义精度),适合记录操作发生时刻 - 性能上没差异,都是轻量函数,不用怕频繁调用
- 如果字段是
DATE类型,用CURDATE()插入最干净;如果是TIMESTAMP,优先考虑NOW()或CURRENT_TIMESTAMP
WHERE 条件里用 CURDATE() 查今天的数据,为什么有时查不到
常见原因是字段类型和比较方式不匹配。比如:created_at 是 DATETIME,而你写 WHERE created_at = CURDATE(),那就永远为假——因为 CURDATE() 是 2024-05-20,而 created_at 是 2024-05-20 14:30:22。
- 正确写法是:
WHERE DATE(created_at) = CURDATE(),但注意这会让created_at索引失效 - 更高效的方式:
WHERE created_at >= CURDATE() AND created_at - 如果字段是
DATE类型(如stat_date),那直接= CURDATE()就行,索引能用上
在 INSERT 语句里设默认日期,CURDATE() 能不能直接当默认值
不能。MySQL 的列默认值只接受常量或特定函数(如 CURRENT_TIMESTAMP),CURDATE() 不在白名单里,建表时会报错:Invalid default value for 'xxx'。
- 想让
DATE字段自动填今天,得用DATE类型配合DEFAULT (CURDATE())(MySQL 5.7.6+ 支持生成列语法,但不是传统 DEFAULT) - 更通用的做法:省略该字段,在 INSERT 时不写它,改由应用层传
CURDATE()的结果,或用触发器 - 如果字段允许 NULL,且业务能接受空值,就别硬塞默认值,反而容易掩盖逻辑问题
CURDATE() 到底能不能跑通。










