如何在Laravel和PHP中使用Carbon管理DateTime
介绍
在 PHP 中处理日期和时间可能很复杂。 我们必须处理 strtotime、格式问题、大量计算等等。
Carbon 包可以帮助在 PHP 中处理日期和时间变得更加容易和语义化,从而使我们的代码变得更具可读性和可维护性。
Carbon 是 Brian Nesbit 的一个包,它扩展了 PHP 自己的 DateTime 类。
它提供了一些很好的功能来处理 PHP 中的日期。 具体如下:
- 处理时区。
- 轻松获取当前时间。
- 将日期时间转换为可读的东西。
- 将英文短语解析为日期时间 (
"first day of January 2016")。 - 加减日期(
"+ 2 weeks"、"-6 months")。 - 处理日期的语义方式。
在本文中,您将安装 Carbon 并探索它提供的特性和功能。
先决条件
要遵循本指南,您需要满足以下先决条件:
- 一个工作的 Laravel 开发环境。 要进行设置,您可以按照我们关于 如何在 Ubuntu 20.04 上安装和配置 Laravel 应用程序的指南进行操作。 或者,按照 Larvel 安装文档进行操作。 如果你选择 Laravel Sail 方法,你将需要 Docker。
本教程已使用 PHP v8.0.5、Composer v2.0.13、MySQL 8.0.24、Laravel v8.40.0 和 Carbon v2.31 进行了验证。
设置项目
为了使用 Carbon,您需要从 Carbon 命名空间导入 Carbon。 幸运的是,Carbon 已经包含在 Laravel 中。
每当我们需要使用 Carbon 时,我们可以像这样导入它:
<?php use Carbon\Carbon;
导入之后,我们来探索一下 Carbon 提供了什么。
获取特定日期和时间
获取当前时间:
$current = Carbon::now();
当前时间也可以用这个实例化来检索:
$current2 = new Carbon();
获取今天的日期:
$today = Carbon::today();
获取昨天的日期:
$yesterday = Carbon::yesterday();
获取明天的日期:
$tomorrow = Carbon::tomorrow();
解析一个特定的字符串:
$newYear = new Carbon('first day of January 2016');
这将返回:
Output2016-01-01 00:00:00
这些助手为频繁的日期和时间需求提供人类可读的请求,例如 today()、yesterday() 和 tomorrow()。
创建具有更细粒度控制的日期
除了定义日期和时间的快速方法之外,Carbon 还让我们根据特定数量的参数创建日期和时间。
createFromDate() 接受 $year、$month、$day、$tz(时区):
Carbon::createFromDate($year, $month, $day, $tz);
createFromTime() 接受 $hour、$minute、$second 和 $tz(时区):
Carbon::createFromTime($hour, $minute, $second, $tz);
create() 接受 $year、$month、$day、$hour、$minute、$second、[ X84X](时区):
Carbon::create($year, $month, $day, $hour, $minute, $second, $tz);
当您以 Carbon 通常无法识别的格式获取某种日期或时间时,这些非常有用。 如果您为这些属性中的任何一个传入 null,它将默认为当前。
操作日期和时间
在处理日期时,获取日期和时间并不是您唯一需要做的事情。 您经常需要操纵日期或时间。
例如,在为用户创建试用期时,您会希望试用期在一定时间后到期。 假设我们有 30 天的试用期。 我们可以用 Carbon 的 add 和 subtract 来计算时间。
对于此示例,我们可以使用 addDays() 来确定试用期何时到期:
// get the current time $current = Carbon::now(); // add 30 days to the current time $trialExpires = $current->addDays(30);
来自 Carbon 文档,这里有一些可供我们使用的其他 add() 和 sub() 方法。
考虑一个设置为 2012 年 1 月 31 日的日期:
$dt = Carbon::create(2012, 1, 31, 0); echo $dt->toDateTimeString();
这将返回:
Output2012-01-31 00:00:00
使用 addYears() 和 subYears() 修改日期将导致以下结果:
| 命令 | 输出 |
|---|---|
echo $dt->addYear();
|
2012-01-31 00:00:00 |
echo $dt->addYears(5);
|
2017-01-31 00:00:00 |
echo $dt->subYear();
|
2011-01-31 00:00:00 |
echo $dt->subYears(5);
|
2007-01-31 00:00:00 |
使用 addMonths() 和 subMonths() 修改日期将导致以下结果:
| 命令 | 输出 |
|---|---|
echo $dt->addMonth();
|
2012-03-03 00:00:00 |
echo $dt->addMonths(60);
|
2017-01-31 00:00:00 |
echo $dt->subMonth();
|
2011-12-31 00:00:00 |
echo $dt->subMonths(60);
|
2007-01-31 00:00:00 |
请注意在“1 月 31 日”中添加一个月如何导致“3 月 3 日”而不是“2 月 28 日”。 如果您不想进行翻转,可以使用 addMonthWithoutOverflow()。
使用 addDays() 和 subDays() 修改日期将导致以下结果:
| 命令 | 输出 |
|---|---|
echo $dt->addDay();
|
2012-02-01 00:00:00 |
echo $dt->addDays(29);
|
2012-02-29 00:00:00 |
echo $dt->subDay();
|
2012-01-30 00:00:00 |
echo $dt->subDays(29);
|
2012-01-02 00:00:00 |
使用 addWeekdays() 和 subWeekdays() 修改日期将导致以下结果:
| 命令 | 输出 |
|---|---|
echo $dt->addWeekday();
|
2012-02-01 00:00:00 |
echo $dt->addWeekdays(4);
|
2012-02-06 00:00:00 |
echo $dt->subWeekday();
|
2012-01-30 00:00:00 |
echo $dt->subWeekdays(4);
|
2012-01-25 00:00:00 |
使用 addWeeks() 和 subWeeks() 修改日期将导致以下结果:
| 命令 | 输出 |
|---|---|
echo $dt->addWeek();
|
2012-02-07 00:00:00 |
echo $dt->addWeeks(3);
|
2012-02-21 00:00:00 |
echo $dt->subWeek();
|
2012-01-24 00:00:00 |
echo $dt->subWeeks(3);
|
2012-01-10 00:00:00 |
使用 addHours() 和 subHours() 修改日期将导致以下结果:
| 命令 | 输出 |
|---|---|
echo $dt->addHour();
|
2012-01-31 01:00:00 |
echo $dt->addHours(24);
|
2012-02-01 00:00:00 |
echo $dt->subHour();
|
2012-01-30 23:00:00 |
echo $dt->subHours(24);
|
2012-01-30 00:00:00 |
使用 addMinutes() 和 subMinutes() 修改日期将导致以下结果:
| 命令 | 输出 |
|---|---|
echo $dt->addMinute();
|
2012-01-31 00:01:00 |
echo $dt->addMinutes(61);
|
2012-01-31 01:01:00 |
echo $dt->subMinute();
|
2012-01-30 23:59:00 |
echo $dt->subMinutes(61);
|
2012-01-30 22:59:00 |
使用 addSeconds() 和 subSeconds() 修改日期将导致以下结果:
| 命令 | 输出 |
|---|---|
echo $dt->addSecond();
|
2012-01-31 00:00:01 |
echo $dt->addSeconds(61);
|
2012-01-31 00:01:01 |
echo $dt->subSecond();
|
2012-01-30 23:59:59 |
echo $dt->subSeconds(61);
|
2012-01-30 23:58:59 |
使用 Carbon 的 add 和 subtract 工具可以为您提供调整后的日期和时间。
使用 Getter 和 Setter
另一种读取或操作时间的方法是使用 Carbon 的 getter 和 setter。
使用 getter 读取值:
$dt = Carbon::now(); var_dump($dt->year); var_dump($dt->month); var_dump($dt->day); var_dump($dt->hour); var_dump($dt->second); var_dump($dt->dayOfWeek); var_dump($dt->dayOfYear); var_dump($dt->weekOfMonth); var_dump($dt->daysInMonth);
使用设置器更改值:
$dt = Carbon::now(); $dt->year = 2015; $dt->month = 04; $dt->day = 21; $dt->hour = 22; $dt->minute = 32; $dt->second = 5; echo $dt;
我们甚至可以将一些二传手链接在一起。
这是前面使用 year()、month()、day()、hour()、minute() 和 second() 的示例:
$dt->year(2015)->month(4)->day(21)->hour(22)->minute(32)->second(5)->toDateTimeString();
这是使用 setDate() 和 setTime() 的相同示例:
$dt->setDate(2015, 4, 21)->setTime(22, 32, 5)->toDateTimeString();
这是使用 setDateTime() 的相同示例:
$dt->setDateTime(2015, 4, 21, 22, 32, 5)->toDateTimeString();
所有这些方法都会产生相同的结果:2015-04-21 22:32:05。
格式化日期和时间
PHP 的 toXXXString() 方法可用于以预定义格式显示日期和时间:
| 命令 | 输出 |
|---|---|
echo $dt->toDateString();
|
2015-04-21 |
echo $dt->toFormattedDateString();
|
2015 年 4 月 21 日 |
echo $dt->toTimeString();
|
22:32:05 |
echo $dt->toDateTimeString();
|
2015-04-21 22:32:05 |
echo $dt->toDayDateTimeString();
|
2015 年 4 月 21 日星期二晚上 10:32 |
也可以使用 PHP 的 DateTime format() 进行自定义格式:
echo $dt->format('l jS \of F Y h:i:s A');
l:星期几的完整文本表示。jS: 没有前导零的月份中的某天。 日期的英文序号后缀,2 个字符。F:一个月的完整文本表示。Y:年份的完整数字表示,4 位数字。h:i:s: 带前导零的小时的 12 小时格式。 带前导零的分钟。 带前导零的秒数。A:大写的 Ante meridiem 和 Post meridiem。
此代码将产生以下结果:
OutputTuesday 21st of April 2015 10:32:05 PM
使用 Carbon 的格式化工具可以显示日期和时间以满足您的需求。
计算相对时间
Carbon 还允许我们使用 diff() 方法相对显示时间。
例如,假设我们有一个博客,想要显示 3 hours ago 的发布时间。 我们可以用这些方法做到这一点。
寻找差异
考虑以下示例,其中包含未来时间和过去时间:
$dt = Carbon::create(2012, 1, 31, 0); $future = Carbon::create(2012, 1, 31, 0); $past = Carbon::create(2012, 1, 31, 0); $future = $future->addHours(6); $past = $past->subHours(6);
以下是使用 diffInHours() 的结果:
| 命令 | 输出 |
|---|---|
echo $dt->diffInHours($future);
|
6
|
echo $dt->diffInHours($past);
|
6
|
考虑以下示例,其中包含未来的日期和过去的日期:
$dt = Carbon::create(2012, 1, 31, 0); $future = Carbon::create(2012, 1, 31, 0); $past = Carbon::create(2012, 1, 31, 0); $future = $future->addMonth(); $past = $past->subMonths(2);
以下是使用 diffInDays() 的结果:
| 命令 | 输出 |
|---|---|
echo $dt->diffInDays($future);
|
31
|
echo $dt->diffInDays($past);
|
61
|
显示人类的差异
相对显示时间有时对读者来说比日期或时间戳更有用。
例如,不会像 8:12 AM 那样显示帖子的时间,而是将时间显示为 3 hours ago。
diffForHumans() 方法用于计算差异并将其转换为人类可读的格式。
考虑以下示例,其中包含未来的日期和过去的日期:
$dt = Carbon::create(2012, 1, 31, 0); $future = Carbon::create(2012, 1, 31, 0); $past = Carbon::create(2012, 1, 31, 0); $future = $future->addMonth(); $past = $past->subMonth();
以下是使用 diffForHumans() 的结果:
| 命令 | 输出 |
|---|---|
echo $dt->diffForHumans($future);
|
1 month before
|
echo $dt->diffForHumans($past);
|
1 month after
|
结论
在本文中,您安装了 Carbon 并探索了它提供的特性和功能。
如果您想了解有关 Laravel 的更多信息,请查看 我们的 Laravel 主题页面 以获取练习和编程项目。 如果您想了解有关 PHP 的更多信息,请查看 我们的 PHP 主题页面 以获取练习和编程项目。