whereday() 仅匹配日期中的“日”部分(1–31),适用于查每月固定日(如生日5号),参数须为整数或纯日字符串;查具体某天全天数据应使用 wheredate()。

whereDay() 方法直接提取日期中的“日”部分做匹配
在 Laravel 的 Eloquent 中,whereDay() 是专为「查某月某日」设计的快捷方法,它会自动剥离年份和月份,只比对日期字段的 天数(1–31)。比如查所有生日是 5 号的用户,不管哪年哪月,用它最省事。
常见错误是误以为 whereDay() 能查“2024-05-05”,其实它只认 5 这个数字。写成 whereDay('created_at', '2024-05-05') 会报错或查不到——因为第二个参数必须是整数或字符串形式的纯日份数字。
-
whereDay('updated_at', 15)→ 查所有更新日是每月 15 号的记录 -
whereDay('birthday', '01')→ 字符串也行,但不能带年月 - 不支持范围,比如
whereDay('date', '>=', 10)会失效,得换whereRaw()
whereRaw() 配合数据库函数更灵活但需注意方言差异
当你要查「今天是几号」或者跨年比较(如所有 12 月 25 日),whereDay() 就不够用了,得上 whereRaw()。不同数据库提取“日”的函数名不一样:DAY()(MySQL)、EXTRACT(DAY FROM ...)(PostgreSQL)、strftime('%d', ...)(SQLite)。
例如 MySQL 下查今天创建的记录(只看日,忽略年月):whereRaw('DAY(created_at) = DAY(NOW())');但如果换到 PostgreSQL,就得写 whereRaw('EXTRACT(DAY FROM created_at) = EXTRACT(DAY FROM NOW())')。
- 本地开发用 SQLite?记得换成
strftime('%d', created_at) - 用
DB::raw()替代字符串拼接,避免 SQL 注入风险 - 别在
whereRaw()里直接插 PHP 变量,比如"DAY(created_at) = $day"—— 容易被注入
whereDate() 和 whereBetween() 更适合“某一天”的完整匹配
如果目标其实是「查 2024-05-05 全天的数据」,那 whereDay() 就不对路了——它会把 2023-05-05、2025-05-05 全拉出来。这时候该用 whereDate(),它按完整日期(Y-m-d)截断比对:
whereDate('created_at', '2024-05-05') 等价于 whereBetween('created_at', ['2024-05-05 00:00:00', '2024-05-05 23:59:59']),底层自动补时间范围。
-
whereDate()接受字符串(如'2024-05-05')、Carbon实例或时间戳 - 别用
where('created_at', '2024-05-05')—— 这是在比完整 datetime 字符串,几乎不可能命中 - 如果字段是
DATE类型而非DATETIME,whereDate()仍安全,但whereDay()也适用(只是语义不如前者清晰)
时区和数据库配置会影响结果一致性
PHP 应用时区(date_default_timezone_set())、Laravel 的 config/app.php 中 'timezone'、以及数据库服务器本身的时区,三者不一致时,whereDay() 和 whereDate() 返回的结果可能出人意料。比如数据库存的是 UTC 时间,而 PHP 认为自己在 Asia/Shanghai,whereDate('created_at', now()) 可能查不到刚插入的记录。
- 检查
DB::select('SELECT NOW()')和now()->toDateTimeString()输出是否一致 - 生产环境建议数据库也设为 UTC,应用层统一转时区
- 用
whereDate()时传入Carbon::parse('2024-05-05')->setTimezone('UTC')显式指定,比依赖默认值更稳
whereDate() 几乎零踩坑;前者用 whereDay() 最干净,但别指望它处理带年月的字符串。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











