Carbon PHP:无分钟格式营业时间转时间戳及对比报错问题
解决Carbon解析无分钟营业时间的问题
嘿,我懂你遇到的麻烦了——Carbon没法直接解析那种不带分钟的12小时制营业时间字符串(比如8 pm、2 am这类格式),因为它默认需要完整的时间格式(比如8:00 pm)。下面给你几个实用的解决方案,一步步帮你搞定和当前时间的对比:
方案1:先补充分钟,再用Carbon解析
这是最直接的办法,先把原始的营业时间字符串处理成Carbon能识别的格式,手动补全:00的分钟部分,再进行解析。
具体代码示例:
// 假设你从数据库拿到的营业时间是$barDays->hours,比如"8 pm - 2 am"或者"8pm to 2am" $hours = $barDays->hours; // 先分割开营业开始和结束时间,兼容"to"和"-"两种分隔符 $timeSegments = preg_split('/\s*(to|-)\s*/', $hours); $openStr = trim($timeSegments[0]); $closeStr = trim($timeSegments[1]); // 给没有分钟的时间补全":00" if (!str_contains($openStr, ':')) { $openStr .= ':00'; } if (!str_contains($closeStr, ':')) { $closeStr .= ':00'; } // 解析成Carbon实例,记得带上当前时区 $now = Carbon::now(); $openTime = Carbon::parse($openStr, $now->timezone); $closeTime = Carbon::parse($closeStr, $now->timezone); // 重点处理跨天情况!比如2am是第二天的时间,所以如果关门时间早于开门时间,就加一天 if ($closeTime->lessThan($openTime)) { $closeTime->addDay(); } // 现在就可以轻松对比当前时间是否在营业时段内了 if ($now->between($openTime, $closeTime)) { echo "这家店现在正在营业哦"; } else { echo "这家店已经打烊啦"; }
方案2:用createFromFormat指定精确格式
如果你的营业时间格式很固定(都是数字 am/pm的形式),可以直接用Carbon的createFromFormat方法,精准匹配格式,不用额外处理字符串:
$now = Carbon::now(); // g 代表12小时制的小时(不带前导零),a 代表小写的am/pm;如果是大写就用A $openTime = Carbon::createFromFormat('g a', $openStr, $now->timezone); $closeTime = Carbon::createFromFormat('g a', $closeStr, $now->timezone); // 同样要处理跨天情况 if ($closeTime->lt($openTime)) { $closeTime->addDay(); }
方案3:优化数据库存储(长期推荐)
如果可以的话,建议你把营业时间拆成两个独立字段,比如open_time和close_time,存储成24小时制的时间字符串(比如20:00、02:00)或者数据库的TIME类型。这样后续用Carbon解析会更省心,再也不用处理各种格式的字符串了:
// 直接解析存储的时间 $openTime = Carbon::parse($barDays->open_time, $now->timezone); $closeTime = Carbon::parse($barDays->close_time, $now->timezone);
内容的提问来源于stack exchange,提问作者Zach Handley
相关产品推荐
相关产品推荐

