目录

Carbon 时间扩展

概述

Carbon 是一个简单的 PHP 时间扩展,在 PHP 中是一个时间处理利器。继承 PHP 的 DateTime 类。在 Laravel 中自带该扩展,其他项目可以通过 composer require nesbot/carbon 或 直接加载所有类和依赖项方式引入。

基础用法

通常先获取或者创一个 Carbon 对象,然后进行一系列操作后生成最终想要的数据。

1
2
3
4
5
6
/**
 * Carbon\Carbon @1652339837 {#3558
 *  date: 2022-05-12 15:17:27.577118 PRC (+08:00),
 * }
 */
Carbon::now(); // 获取当前时间,包含时分秒,结果是一个对象
1
2
3
4
5
6
 /**
 * Carbon\Carbon @1652284800 {#3545
 * date: 2022-05-12 00:00:00.0 PRC (+08:00),
 * }
 */
Carbon::today(); // 获取当天时间,不含时分秒,结果是一个对象
1
2
3
4
5
6
/**
 *Carbon\Carbon @1652371200 {#3552
 * date: 2022-05-13 00:00:00.0 PRC (+08:00),
 * }
 */
Carbon::tomorrow(); // 获取明日时间,不含时分秒,结果是一个对象
1
2
3
4
5
6
/**
 *Carbon\Carbon @1652198400 {#3557
 * date: 2022-05-11 00:00:00.0 PRC (+08:00),
 * }
 */
Carbon::yesterday(); // 获取昨日时间,不含时分秒,结果是一个对象

对象转常用数据

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// string
Carbon::now()->toDateString(); // string(10) "2022-05-12"
Carbon::now()->toTimeString(); // string(8) "15:51:55"
Carbon::now()->toDateTimeString(); // string(19) "2022-05-12 15:51:55"
Carbon::now()->toAtomString(); // string(25) "2022-05-12T15:51:55+08:00"
Carbon::now()->format('Y-m-d\TH:i:s.uP')); // string(32) "2022-05-12T15:51:55.360305+08:00"
(string)Carbon::now(); // string(19) "2022-05-12 15:51:55"

// int
Carbon::now()->getTimestamp(); // int(1652341915)
Carbon::now()->getTimestampMs(); // int(1652341915360) php >= 7.1

测试辅助类

Carbon 允许使用指定的时间生成一个测试数据。后续从 Carbon 检索任何相对应的时间,比如明天、昨天、下个小时等,将使用指定测试类的时间。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
Carbon::setTestNow('2022-05-12T16:16:16.123456+08:00'); // 设置一个测试时间点

var_dump((string)Carbon::getTestNow()); // string(19) "2022-05-12 16:16:16"
var_dump((string)Carbon::now());        // string(19) "2022-05-12 16:16:16"
var_dump(Carbon::hasTestNow());         // bool(true)
Carbon::setTestNow();                   // 解除测试时间
var_dump(Carbon::hasTestNow());         // bool(false)
var_dump((string)Carbon::getTestNow()); // string(0) ""
var_dump((string)Carbon::now());        // string(19) "2022-05-12 16:25:20"

// 通过闭包方式设置测试时间
Carbon::withTestNow('2022-05-12T16:16:16.123456+08:00', static function () {
    var_dump((string)Carbon::now()); // string(19) "2022-05-12 16:16:16"
});

创建 Carbon 对象

通过一些函数创建 Carbon 对象

1
2
3
4
5
6
7
8
9
// 基于时间点 2022-05-12T16:16:16.123456+08:00

// 等同 Carbon::now(); 
$carbon = new Carbon(); // 2022-05-12 16:16:16  

Carbon::now();       // 2022-05-12 16:16:16
Carbon::today();     // 2022-05-12 00:00:00
Carbon::tomorrow();  // 2022-05-13 00:00:00
Carbon::yesterday(); // 2022-05-11 00:00:00

通过指定时间创建 Carbon 对象

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
Carbon::create(2022, 5, 12, 16, 16, 16, 'Asia/Shanghai');   // 2022-05-12 16:16:16
// 注意:未指定的时间将由当前时间替代
// 秒位置 为 null 时,毫秒也取当前时间毫秒否则都是 000
Carbon::create(2022, 5, 12, null, 16, 16, 'Asia/Shanghai'); // 2022-05-12 16:16:16

// 其他未指定时间会获取当前时分秒,并且包含毫秒。
Carbon::createFromDate(2022, 5, 12); // 2022-05-12 16:16:16
// 秒位置 为 null 时,毫秒也取当前时间毫秒,否则都是 000
Carbon::createFromTime(16, 16, 16); // 2022-05-12 16:16:16
// 创建指定日期 0 点时间对象
Carbon::createMidnightDate(2022, 5, 12); // 2022-05-12 00:00:00

// 注意:未指定的时间将由当前时间替代,毫秒为 000
Carbon::createFromFormat('Y-m-d H', '2022-05-16 16');       // 2022-05-16 16:16:16

// 通过时间戳创建对象
Carbon::createFromTimestamp(1652688976);                    // 2022-05-16 16:16:16
Carbon::createFromTimestampMs(1652688976123);               // 2022-05-16 16:16:16
1
2
3
4
5
6
7
8
9
// parse 传入参数 int 类型会被当成时间戳解析,但是需要手动指定时区。

Carbon::parse('2022-05-12');     // 2022-05-12 00:00:00
Carbon::parse('2022-05-12 16');  // 2022-05-12 16:16:16

// 2022051216 会报错
Carbon::parse('20220512');       // 2022-05-12 00:00:00
Carbon::parse('202205121616');   // 2022-05-12 16:16:00
Carbon::parse('20220512161616'); // 2022-05-12 16:16:16

时间日历比较

注意:在使用两个日期 first == second 比较的时候,PHP >= 7.1 后会对比微妙。如只传入年月日时分秒来比较 Carbon::now() 可能得不到预期的结果。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$first = Carbon::create(2022, 5, 12, 16, 16, 16);
$second = Carbon::create(2022, 5, 12, 16, 16, 16);

$first->eq($second)      // true
$first->equalTo($second) // true
$first == $second        // true

$first->ne($second)         // false
$first->notEqualTo($second) // false
$first != $second           // false

$first->gt($second)          // false
$first->greaterThan($second) // false
$first->isAfter($second)     // false
$first > $second             // false

$first->gte($second)                  // true
$first->greaterThanOrEqualTo($second) // true
$first >= $second                     // true

$first->lt($second)       // false
$first->lessThan($second) // false
$first->isBefore($second) // false
$first < $second          // false

$first->lte($second)               // true
$first->lessThanOrEqualTo($second) // true
$first <= $second                  // true

// 默认闭区间,通过第三个参数为 false 来设置开区间。
Carbon::create(2022, 5, 12, 16, 16, 16)->between($first, $second)       // true
Carbon::create(2022, 5, 12, 16, 16, 16)->between($first, $second,false) // false

为了处理一些常用的情况,还有一些简单的辅助比较日期的函数。这里列举一些比较常用的。

详细:Carbon - A simple PHP API extension for DateTime. (nesbot.com)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
$dt1 = Carbon::now(); // 2022-05-12 星期四
$dt2 = Carbon::createFromDate(2022, 5, 19); // 星期四

// 判断是否为同为星期几,可自由组合第一个传入的参数,比如是否为同一个月等
$dt1->isSameAs('w', $dt2) // true

// 判断日期是否为闰年
$dt2->isLeapYear() // false

// 是否为工作日,周一到周五
$dt2->isWeekday() // true

// 是否为周末,周六周日
$dt2->isWeekend() // false

// 判断周几,常量中可以获取到全部星期
$dt2->isDayOfWeek(Carbon::THURSDAY) // true
$dt2->isMonday()    // 星期一 false
$dt2->isTuesday()   // 星期二 false
$dt2->isWednesday() // 星期三 false
$dt2->isThursday()  // 星期四 true
$dt2->isFriday()    // 星期五 false
$dt2->isSaturday()  // 星期六 false
$dt2->isSunday()    // 星期日 false

// 判断是否为本月的最后一天
$dt2->isLastOfMonth() // false

// is 比较
$dt1->is('2022')     //true
$dt1->is('5-12')     //true
$dt1->is('16:16')    //true
$dt1->is('Thursday') //true
$dt1->is('May')      //true

// 判断年月日是否相同
$dt1->isSameDay($dt2) //false
// 判断年月日是否为今天
$dt1->isToday()       //true

时间加减

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// 年份加减
echo $dt->addYear(); // 2023-05-12 16:16:16
echo $dt->subYear(); // 2022-05-12 16:16:16
echo $dt->addYears(2); // 2024-05-12 16:16:16
echo $dt->subYears(2); // 2022-05-12 16:16:16

// 月份加减
echo $dt->addMonth(); // 2022-06-12 16:16:16
echo $dt->subMonth(); // 2022-05-12 16:16:16
echo $dt->addMonths(2); // 2022-07-12 16:16:16
echo $dt->subMonths(2); // 2022-05-12 16:16:16

// 天数加减
echo $dt->addDay(); // 2022-05-13 16:16:16
echo $dt->subDay(); // 2022-05-12 16:16:16
echo $dt->addDays(2); // 2022-05-14 16:16:16
echo $dt->subDays(2); // 2022-05-12 16:16:16

// 星期加减 ,(加减七天)
echo $dt->addWeek(); // 2022-05-19 16:16:16
echo $dt->subWeek(); // 2022-05-12 16:16:16
echo $dt->addWeeks(2); // 2022-05-26 16:16:16
echo $dt->subWeeks(2); // 2022-05-12 16:16:16

// 小时加减
echo $dt->addHour(); // 2022-05-12 17:16:16
echo $dt->subHour(); // 2022-05-12 16:16:16
echo $dt->addHours(2); // 2022-05-12 18:16:16
echo $dt->subHours(2); // 2022-05-12 16:16:16

// 分钟加减
echo $dt->addMinute(); // 2022-05-12 16:17:16
echo $dt->subMinute(); // 2022-05-12 16:16:16
echo $dt->addMinutes(2); // 2022-05-12 16:18:16
echo $dt->subMinutes(2); // 2022-05-12 16:16:16

// 秒钟加减
echo $dt->addSecond(); // 2022-05-12 16:16:17
echo $dt->subSecond(); // 2022-05-12 16:16:16
echo $dt->addSeconds(2); // 2022-05-12 16:16:18
echo $dt->subSeconds(2); // 2022-05-12 16:16:16

获取时间差异

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// 默认是取绝对值,第二个参数默认为 true
echo $dt->diffInDays($dt->copy()->subDays()); // 1
// 当第二个参数传入 false,区分日期比较的大小
echo $dt->diffInDays($dt->copy()->subDays(), false); // -1

// 所有判断的值不会四舍五入,而是直接截断
echo $dt->diffInMinutes($dt->copy()->addSeconds(59)); // 0
echo $dt->diffInMinutes($dt->copy()->addSeconds(60)); // 1
echo $dt->diffInMinutes($dt->copy()->addSeconds(119)); // 1
echo $dt->diffInMinutes($dt->copy()->addSeconds(120)); // 2

时间修饰

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
echo $dt->toDateTimeString(); // 2022-05-12 16:16:16
// 毫秒也会对应改变
echo $dt->startOfDay(); // 2022-05-12 00:00:00
echo $dt->endOfDay(); // 2022-05-12 23:59:59

echo $dt->startOfMonth(); // 2022-05-01 00:00:00
echo $dt->endOfMonth(); // 2022-05-31 23:59:59
echo $dt->lastOfMonth(); // 2022-05-31 00:00:00

echo $dt->startOfHour(); // 2022-05-12 16:00:00
echo $dt->endOfHour(); // 2022-05-12 16:59:59

// 星期一
echo $dt->startOfWeek(); // 2022-05-09 00:00:00
// 星期日
echo $dt->endOfWeek(); // 2022-05-15 23:59:59

时间周期

Carbon - A simple PHP API extension for DateTime. (nesbot.com)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$period = CarbonPeriod::create('2022-05-12', '2022-05-20');
foreach ($period as $date) {
    echo $date . PHP_EOL;
}
/**
 * 2022-05-12 00:00:00
 * 2022-05-13 00:00:00
 * 2022-05-14 00:00:00
 * 2022-05-15 00:00:00
 * 2022-05-16 00:00:00
 * 2022-05-17 00:00:00
 * 2022-05-18 00:00:00
 * 2022-05-19 00:00:00
 * 2022-05-20 00:00:00
 */


$period = CarbonPeriod::create('2022-05-12', '3 days', '2022-05-20');
foreach ($period as $date) {
    echo $date . PHP_EOL;
}
/**
 * 2022-05-12 00:00:00
 * 2022-05-15 00:00:00
 * 2022-05-18 00:00:00
 */
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$period = Carbon::parse('2022-05-12 16:16:16')->toPeriod('2022-05-20');
foreach ($period as $date) {
    echo $date . PHP_EOL;
}
/**
 * 2022-05-12 16:16:16
 * 2022-05-13 16:16:16
 * 2022-05-14 16:16:16
 * 2022-05-15 16:16:16
 * 2022-05-16 16:16:16
 * 2022-05-17 16:16:16
 * 2022-05-18 16:16:16
 * 2022-05-19 16:16:16
 */

// $period = Carbon::parse('2022-05-12 16:16:16')->toPeriod('2022-05-20', '3 days');
$period = Carbon::parse('2022-05-12 16:16:16')->toPeriod('2022-05-20', '3', 'days');
foreach ($period as $date) {
    echo $date . PHP_EOL;
}
/**
 * 2022-05-12 16:16:16
 * 2022-05-15 16:16:16
 * 2022-05-18 16:16:16
 */
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// $period = Carbon::parse('2022-05-12')->daysUntil('2022-05-20');
$period = Carbon::parse('2022-05-12')->daysUntil('2022-05-20', 3);
foreach ($period as $date) {
    echo $date . PHP_EOL;
}
/**
 * 2022-05-12 00:00:00
 * 2022-05-15 00:00:00
 * 2022-05-18 00:00:00
 */
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$period = CarbonPeriod::create('2022-05-12', 5);
foreach ($period as $date) {
    echo $date . PHP_EOL;
}
/**
 * 2022-05-12 00:00:00
 * 2022-05-13 00:00:00
 * 2022-05-14 00:00:00
 * 2022-05-15 00:00:00
 * 2022-05-16 00:00:00
 */


$period = CarbonPeriod::create('2022-05-12', 5);
$dates = [];
foreach ($period as $key => $date) {
    if ($key === 3) {
        // invert() is an alias for invertDateInterval()
        $period->invert()->start($date); 
    }
    $dates[] = $date->format('Y-m-d');
}

//2022-05-12, 2022-05-13, 2022-05-14, 2022-05-15, 2022-05-14
echo implode(', ', $dates);
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
$period = CarbonPeriod::between('2022-05-01', '2022-05-10');
$days = [];
foreach ($period as $date) {
    $day = $date->format('m-d');
    $days[] = $day;
    if ($day === '05-04') {
        $period->skip(3);
    }
}
// 05-01, 05-02, 05-03, 05-04, 05-08, 05-09, 05-10
echo implode(', ', $days);
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
$start = Carbon::create('2022-05-12');
$interval = CarbonInterval::createFromDateString('-1 day');

$period = CarbonPeriod::create($start, $interval, 5);

foreach ($period as $date) {
    echo $date . PHP_EOL;
}
/**
 * 2022-05-12 00:00:00
 * 2022-05-11 00:00:00
 * 2022-05-10 00:00:00
 * 2022-05-09 00:00:00
 * 2022-05-08 00:00:00
 */

参考地址

Carbon - A simple PHP API extension for DateTime. (nesbot.com)

briannesbitt/Carbon: A simple PHP API extension for DateTime. (github.com)