You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何提前知晓Carbon::parse()支持的有效相对日期格式?

问题解决:Carbon::parse()相对日期字符串解析异常与可靠格式指南

问题核心

在Laravel/Vue项目中使用Carbon::parse()处理用户输入的相对日期字符串时,发现部分格式虽能通过解析但返回错误结果:

  • 当前日期为2023-10-26时,'first day of next month'返回正确的2023-11-01
  • 但'first day of next week'返回错误的2023-09-01,'first day of next year'返回错误的2023-10-01

同时存在两个疑问:

  1. Carbon::hasRelativeKeywords()是否仅识别文档列举的格式?
  2. 哪些相对日期格式能保证解析结果正确?

解析异常原因

Carbon的parse()方法底层依赖PHP原生的strtotime()函数,而'first day of next week'和'first day of next year'并不是strtotime()支持的标准语法。这类非标准格式会被函数误解析,导致结果不符合预期。

'first day of next month'是strtotime()明确支持的格式,因此能得到正确结果。

解决方案

1. 自定义非标准格式的解析逻辑

针对无法被正确解析的格式,手动编写逻辑实现预期效果:

// 处理'first day of next week'
$nextWeekFirstDay = Carbon::now()->startOfWeek()->addWeek();

// 处理'first day of next year'
$nextYearFirstDay = Carbon::now()->startOfYear()->addYear();

2. 构建输入验证白名单

只允许用户输入经过验证的可靠相对日期格式,避免解析异常:

$validRelativeFormats = [
    'tomorrow', 'yesterday', 'today',
    'next sunday', 'last monday', 'this friday',
    'next month', 'last year',
    'first day of this month', 'last day of previous month',
    '+3 days', '-2 weeks', '+1 year'
];

// 验证用户输入是否在白名单内
if (!in_array(strtolower($userInput), $validRelativeFormats)) {
    // 抛出验证错误
}

3. 相对日期的二次校验

结合Carbon::hasRelativeKeywords()判断输入为相对日期后,对解析结果做逻辑校验:

$input = 'first day of next year';
if (Carbon::hasRelativeKeywords($input)) {
    $date = Carbon::parse($input);
    // 校验是否为下一年的1月1日
    if ($date->year !== Carbon::now()->year + 1 || $date->month !== 1 || $date->day !== 1) {
        // 解析结果不符合预期,触发错误处理
    }
}

可靠的相对日期格式清单

以下是Carbon官方文档明确支持且经过验证的相对日期格式:

  • 基础时间点:tomorrow、yesterday、today
  • 星期相关:next [weekday](如next sunday)、last [weekday](如last monday)、this [weekday](如this friday)
  • 月份/年份相关:next month、last year、first day of this month、last day of previous month、last day of this year
  • 间隔式:+[n] days(如+3 days)、-[n] weeks(如-2 weeks)、+[n] year(如+1 year)

关于Carbon::hasRelativeKeywords()的说明

该方法仅检查字符串中是否包含Carbon预定义的相对关键字(如next、last、tomorrow、yesterday等),不验证格式是否能被正确解析。即使返回true,也不代表parse()会得到正确结果,必须结合实际解析后的逻辑校验。

内容的提问来源于stack exchange,提问作者Ronald Baljeu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 00:38:34