手记

Carbon中文使用手册(中)

·         Difference

由于Carbon继承了DateTime,它继承了它的方法,如diff(),它将第二个date对象作为参数,并返回一个DateInterval实例。

我们还提供了diffAsCarbonInterval(),类似于diff(),但返回一个CarbonInterval实例。检查CarbonInterval 章节了解更多信息。每个单元的Carbon添加了diff方法,如diffInYears()diffInMonths()等。diffAsCarbonInterval()diffIn*()方法都可以使用两个可选参数:date to compare with(如果缺失,now是默认值),以及一个绝对布尔选项(默认为true),无论哪个日期大于另一个,该方法都返回一个绝对值。如果设置为false,则在调用方法的实例大于比较日期(第一个参数或now)时返回负值。注意,diff()原型是不同的:它的第一个参数(date)是强制性的,第二个参数(绝对选项)默认为false

这些函数总是返回在指定的时间内表示的总差异。这与基类diff()函数不同,该函数的时间间隔为122秒,通过DateInterval实例返回2分零2秒。diffInMinutes()函数只返回2,而diffInSeconds()将返回122。所有的值都被截断而不是四舍五入。下面的每个函数都有一个默认的第一个参数,该参数是要比较的Carbon实例,如果您想使用now(),则为null。第二个参数也是可选的,如果您希望返回值是绝对值,或者如果传递的日期小于当前实例,则返回值可能具有-()符号的相对值。这将默认为true,返回绝对值。

echo Carbon::now('America/Vancouver')->diffInSeconds(Carbon::now('Europe/London')); // 0

$dtOttawa = Carbon::createMidnightDate(2000, 1, 1, 'America/Toronto');
$dtVancouver = Carbon::createMidnightDate(2000, 1, 1, 'America/Vancouver');
echo $dtOttawa->diffInHours($dtVancouver);                             // 3
echo $dtVancouver->diffInHours($dtOttawa);                             // 3

echo $dtOttawa->diffInHours($dtVancouver, false);                      // 3
echo $dtVancouver->diffInHours($dtOttawa, false);                      // -3

$dt = Carbon::createMidnightDate(2012, 1, 31);
echo $dt->diffInDays($dt->copy()->addMonth());                         // 31
echo $dt->diffInDays($dt->copy()->subMonth(), false);                  // -31

$dt = Carbon::createMidnightDate(2012, 4, 30);
echo $dt->diffInDays($dt->copy()->addMonth());                         // 30
echo $dt->diffInDays($dt->copy()->addWeek());                          // 7

$dt = Carbon::createMidnightDate(2012, 1, 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

echo $dt->addSeconds(120)->secondsSinceMidnight();                     // 120

$interval = $dt->diffAsCarbonInterval($dt->copy()->subYears(3), false);
echo ($interval->invert ? 'minus ' : 'plus ') . $interval->years;      // minus 3

关于夏令时(DST)的重要注意,默认情况下,PHP DateTime不考虑DST,这意味着,像2014330日这样只有23小时的一天在伦敦将被计算为24小时。

$date = new DateTime('2014-03-30 00:00:00', new DateTimeZone('Europe/London')); // DST off
echo $date->modify('+25 hours')->format('H:i');                   // 01:00 (DST on, 24 hours only have been actually added)

Carbon也遵循这种行为,增加/减少/降低秒/分钟/小时。但是我们提供了使用时间戳进行实时工作的方法:

$date = new Carbon('2014-03-30 00:00:00', 'Europe/London');    // DST off
echo $date->addRealHours(25)->format('H:i');             // 02:00 (DST on)
echo $date->diffInRealHours('2014-03-30 00:00:00');               // 25
echo $date->diffInHours('2014-03-30 00:00:00');                   // 26
echo $date->diffInRealMinutes('2014-03-30 00:00:00');             // 1500
echo $date->diffInMinutes('2014-03-30 00:00:00');                 // 1560
echo $date->diffInRealSeconds('2014-03-30 00:00:00');             // 90000
echo $date->diffInSeconds('2014-03-30 00:00:00');                 // 93600
echo $date->subRealHours(25)->format('H:i');             // 00:00 (DST off)

同样的方法可以使用addRealMinutes()subRealMinutes()addRealSeconds()subRealSeconds()和所有它们的唯一快捷方式:addRealHour()subRealHour()addrealmin()subRealMinute()addRealSecond()subRealSecond()

还有特殊的过滤器函数diffindaysfilter()diffinhoursfilter()difffilter(),以帮助您按天数、小时或自定义间隔过滤差异。例如,计算两个实例之间的周末天数:

$dt = Carbon::create(2014, 1, 1);
$dt2 = Carbon::create(2014, 12, 31);
$daysForExtraCoding = $dt->diffInDaysFiltered(function(Carbon $date) {
    return $date->isWeekend();
}, $dt2);

echo $daysForExtraCoding;      // 104

$dt = Carbon::create(2014, 1, 1)->endOfDay();
$dt2 = $dt->copy()->startOfDay();
$littleHandRotations = $dt->diffFiltered(CarbonInterval::minute(), function(Carbon $date) {
    return $date->minute === 0;
}, $dt2, true); // true as last parameter returns absolute value

echo $littleHandRotations;     // 24

$date = Carbon::now()->addSeconds(3666);

echo $date->diffInSeconds();                       // 3666
echo $date->diffInMinutes();                       // 61
echo $date->diffInHours();                         // 1
echo $date->diffInDays();                          // 0

$date = Carbon::create(2016, 1, 5, 22, 40, 32);

echo $date->secondsSinceMidnight();                // 81632
echo $date->secondsUntilEndOfDay();                // 4767

$date1 = Carbon::createMidnightDate(2016, 1, 5);
$date2 = Carbon::createMidnightDate(2017, 3, 15);

echo $date1->diffInDays($date2);                   // 435
echo $date1->diffInWeekdays($date2);               // 311
echo $date1->diffInWeekendDays($date2);            // 124
echo $date1->diffInWeeks($date2);                  // 62
echo $date1->diffInMonths($date2);                 // 14
echo $date1->diffInYears($date2);                  // 1

所有的diffIn*滤波方法都采用1个可调用滤波器作为必要参数,一个date对象作为可选的第二个参数,如果缺失,使用now。您也可以将true作为第三个参数传递,以获得绝对值。

对于周/周末的高级处理,使用以下工具:

echo implode(', ', Carbon::getDays());                 // Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday

$saturday = new Carbon('first saturday of 2019');
$sunday = new Carbon('first sunday of 2019');
$monday = new Carbon('first monday of 2019');

echo implode(', ', Carbon::getWeekendDays());                // 6, 0
var_dump($saturday->isWeekend());                            // bool(true)
var_dump($sunday->isWeekend());                              // bool(true)
var_dump($monday->isWeekend());                              // bool(false)

Carbon::setWeekendDays(array(
    Carbon::SUNDAY,
    Carbon::MONDAY,
));                                                          //
自定义设置“周末”

echo implode(', ', Carbon::getWeekendDays());           // 0, 1
var_dump($saturday->isWeekend());                            // bool(false),周六返回false
var_dump($sunday->isWeekend());                              // bool(true)
var_dump($monday->isWeekend());                              // bool(true),周一返回true

Carbon::setWeekendDays(array(
    Carbon::SATURDAY,
    Carbon::SUNDAY,
));
// weekend days and start/end of week or not linked
Carbon::setWeekStartsAt(Carbon::FRIDAY);
Carbon::setWeekEndsAt(Carbon::WEDNESDAY); // and it does not need neither to precede the start

var_dump(Carbon::getWeekStartsAt() === Carbon::FRIDAY);      // bool(true)
var_dump(Carbon::getWeekEndsAt() === Carbon::WEDNESDAY);     // bool(true)
echo $saturday->copy()->startOfWeek()->toRfc850String();     // Friday, 06-Jul-18 00:00:00 EDT
echo $saturday->copy()->endOfWeek()->toRfc850String();       // Wednesday, 11-Jul-18 23:59:59 EDT

Carbon::setWeekStartsAt(Carbon::MONDAY);
Carbon::setWeekEndsAt(Carbon::SUNDAY);

echo $saturday->copy()->startOfWeek()->toRfc850String();     // Monday, 02-Jul-18 00:00:00 EDT
echo $saturday->copy()->endOfWeek()->toRfc850String();       // Sunday, 08-Jul-18 23:59:59 EDT

·         Difference for Humans

对人类来说,一个月前比30天前更容易阅读。这是在大多数日期库中常见的函数,所以我也想在这里添加它。函数的唯一参数是另一个要对其进行diffCarbon实例,当然,如果没有指定,它默认为now()

此方法将在相对于实例的差值和传入实例的差值之后添加短语。有4个可能性:

当将过去的值与现在的默认值进行比较时:

1小时前

5个月前

当将未来的值与现在的默认值进行比较时:

从现在开始的1小时

从现在开始的5个月

当比较一个过去的值与另一个值时:

1小时

5个月前

当比较未来的价值与另一个价值时:

1小时后

5个月后

您还可以将true作为第二个参数传递,以便从现在开始删除修饰符,等等:diffforhuman ($other, true)

如果在所使用的语言环境:diffforhuman ($other, false, true)中可用,您可以将true作为第三个参数传递给它,以使用简短语法。

您可以将16之间的数字作为第4个参数传递给diffforhuman ($other, false, false, 4)

$other实例可以是DateTimeCarbon实例或任何实现DateTimeInterface的对象,如果传递了一个字符串,它将被解析为获取一个Carbon实例,如果传递了null,那么将使用Carbon: now()

// The most typical usage is for comments
// The instance is the date the comment was created and its being compared to default now()
echo Carbon::now()->subDays(5)->diffForHumans();               // 5 days ago

echo Carbon::now()->diffForHumans(Carbon::now()->subYear());   // 1 year after

$dt = Carbon::createFromDate(2011, 8, 1);

echo $dt->diffForHumans($dt->copy()->addMonth());                        // 1 month before
echo $dt->diffForHumans($dt->copy()->subMonth());                        // 1 month after

echo Carbon::now()->addSeconds(5)->diffForHumans();                      // 5 seconds from now

echo Carbon::now()->subDays(24)->diffForHumans();                        // 3 weeks ago
(21-27都返回这个,一个周的单位是7天,小于7直接舍去)
echo Carbon::now()->subDays(24)->diffForHumans(null, true);    // 3 weeks(21-27都返回这个,一个周的单位是7天,小于7直接舍去)


echo Carbon::parse('2019-08-03')->diffForHumans('2019-08-13');           // 1 week before(时间间隔7-13天都是返回这个,一个周的单位是7天,小于7直接舍去)
echo Carbon::parse('2000-01-01 00:50:32')->diffForHumans('@946684800');  // 5 hours after(同理,都是舍去的)

echo Carbon::create(2018, 2, 26, 4, 29, 43)->diffForHumans(Carbon::create(2016, 6, 21, 0, 0, 0), false, false, 6); // 1 year 8 months 5 days 4 hours 29 minutes 43 seconds after

您还可以在调用diffforhuman()之前使用Carbon::setLocale('fr')更改字符串的locale。有关更多细节,请参见本地化部分。

可以通过以下方式启用/禁用diffforhuman()选项:

Carbon::enableHumanDiffOption(Carbon::NO_ZERO_DIFF);
var_dump((bool) (Carbon::getHumanDiffOptions() & Carbon::NO_ZERO_DIFF)); // bool(true)
Carbon::disableHumanDiffOption(Carbon::NO_ZERO_DIFF);
var_dump((bool) (Carbon::getHumanDiffOptions() & Carbon::NO_ZERO_DIFF)); // bool(false)

可用的选项是:

Carbon::NO_ZERO_DIFF(默认启用):将空diff变为1

Carbon::JUST_NOW在默认情况下是禁用的):从现在开始变为刚才

Carbon:ONE_DAY_WORDS(默认禁用):从现在/之前1变为昨天/明天

Carbon::TWO_DAY_WORDS(默认禁用):从现在/之前2变为昨天/之后

Carbon::JUST_NOWCarbon::ONE_DAY_WORDSCarbon::TWO_DAY_WORDS现在只能使用enfr语言,其他语言将会恢复到以前的行为,直到添加缺失的翻译。

使用管道操作符一次启用/禁用多个选项,例如:Carbon::ONE_DAY_WORDS | Carbon::TWO_DAY_WORDS

您还可以使用setHumanDiffOptions($options)禁用所有选项,然后只激活作为参数传递的选项。

·         Modifiers

这些方法组对当前实例进行了有益的修改。他们中的大多数方法的名字都是不言自明的……或者至少应该是这样。您还会注意到startOfXXX()next()previous()方法将时间设置为00:00,endOfXXX()方法将时间设置为23:59:59

唯一稍有不同的是average()函数。它将实例移动到其本身和提供的碳参数之间的中间日期。

$dt = Carbon::create(2012, 1, 31, 15, 32, 45);
echo $dt->startOfMinute();                         // 2012-01-31 15:32:00

$dt = Carbon::create(2012, 1, 31, 15, 32, 45);
echo $dt->endOfMinute();                           // 2012-01-31 15:32:59

$dt = Carbon::create(2012, 1, 31, 15, 32, 45);
echo $dt->startOfHour();                           // 2012-01-31 15:00:00

$dt = Carbon::create(2012, 1, 31, 15, 32, 45);
echo $dt->endOfHour();                             // 2012-01-31 15:59:59

$dt = Carbon::create(2012, 1, 31, 15, 32, 45);
echo Carbon::getMidDayAt();                        // 12
获取正午时间
echo $dt->midDay();                                // 2012-01-31 12:00:00
Carbon::setMidDayAt(13);                     //设置正午时间为13点
echo Carbon::getMidDayAt();                        // 13
echo $dt->midDay();                                // 2012-01-31 13:00:00
Carbon::setMidDayAt(12);

$dt = Carbon::create(2012, 1, 31, 12, 0, 0);
echo $dt->startOfDay();                            // 2012-01-31 00:00:00

$dt = Carbon::create(2012, 1, 31, 12, 0, 0);
echo $dt->endOfDay();                              // 2012-01-31 23:59:59

$dt = Carbon::create(2012, 1, 31, 12, 0, 0);
echo $dt->startOfMonth();                          // 2012-01-01 00:00:00

$dt = Carbon::create(2012, 1, 31, 12, 0, 0);
echo $dt->endOfMonth();                            // 2012-01-31 23:59:59

$dt = Carbon::create(2012, 1, 31, 12, 0, 0);
echo $dt->startOfYear();                           // 2012-01-01 00:00:00

$dt = Carbon::create(2012, 1, 31, 12, 0, 0);
echo $dt->endOfYear();                             // 2012-12-31 23:59:59

$dt = Carbon::create(2012, 1, 31, 12, 0, 0);
echo $dt->startOfDecade();                         // 2010-01-01 00:00:00 十年(“年代?”)的开始1990,2000,2010,2010

$dt = Carbon::create(2012, 1, 31, 12, 0, 0);
echo $dt->endOfDecade();                           // 2019-12-31 23:59:59

$dt = Carbon::create(2012, 1, 31, 12, 0, 0);
echo $dt->startOfCentury();                        // 2001-01-01 00:00:00 世纪的开始?为什么不是2000-01-01 00:00:00???可能老外就是这个定义的吧……

$dt = Carbon::create(2012, 1, 31, 12, 0, 0);
echo $dt->endOfCentury();                          // 2100-12-31 23:59:59 世纪的结束?为什么不是2099-12-31 23:59:59???

$dt = Carbon::create(2012, 1, 31, 12, 0, 0);
echo $dt->startOfWeek();                           // 2012-01-30 00:00:00
var_dump($dt->dayOfWeek == Carbon::MONDAY);        // bool(true) : ISO8601 week starts on Monday ISO8601标准每周的开始是周一,老外好像认为每周的开始是周日……

$dt = Carbon::create(2012, 1, 31, 12, 0, 0);
echo $dt->endOfWeek();                             // 2012-02-05 23:59:59
var_dump($dt->dayOfWeek == Carbon::SUNDAY);        // bool(true) : ISO8601 week ends on Sunday

$dt = Carbon::create(2012, 1, 31, 12, 0, 0);
echo $dt->next(Carbon::WEDNESDAY);                 // 2012-02-01 00:00:00 传了参数表示“下一个周三”,不传表示“明天”
var_dump($dt->dayOfWeek == Carbon::WEDNESDAY);     // bool(true)

$dt = Carbon::create(2012, 1, 1, 12, 0, 0);
echo $dt->next();                                  // 2012-01-08 00:00:00

$dt = Carbon::create(2012, 1, 31, 12, 0, 0);
echo $dt->previous(Carbon::WEDNESDAY);             // 2012-01-25 00:00:00 传了参数表示“上一个周三”,不传表示“昨天”
var_dump($dt->dayOfWeek == Carbon::WEDNESDAY);     // bool(true)

$dt = Carbon::create(2012, 1, 1, 12, 0, 0);
echo $dt->previous();                              // 2011-12-25 00:00:00

$start = Carbon::create(2014, 1, 1, 0, 0, 0);
$end = Carbon::create(2014, 1, 30, 0, 0, 0);
echo $start->average($end);                        // 2014-01-15 12:00:00 (1+30)/2 = 15 int运算

echo Carbon::create(2014, 5, 30, 0, 0, 0)->firstOfMonth();                       // 2014-05-01 00:00:00 这个月的第一天
echo Carbon::create(2014, 5, 30, 0, 0, 0)->firstOfMonth(Carbon::MONDAY);         // 2014-05-05 00:00:00 这个月的第一个周一
echo Carbon::create(2014, 5, 30, 0, 0, 0)->lastOfMonth();                        // 2014-05-31 00:00:00 这个月的最后一天
echo Carbon::create(2014, 5, 30, 0, 0, 0)->lastOfMonth(Carbon::TUESDAY);         // 2014-05-27 00:00:00 这个月的最后一个周二
echo Carbon::create(2014, 5, 30, 0, 0, 0)->nthOfMonth(2, Carbon::SATURDAY);      // 2014-05-10 00:00:00 这个月的第“2”个“周六”,2和周六是参数

echo Carbon::create(2014, 5, 30, 0, 0, 0)->firstOfQuarter();                     // 2014-04-01 00:00:00 这个季度的第一天(5月是第二个季度,所以是4月1号)
echo Carbon::create(2014, 5, 30, 0, 0, 0)->firstOfQuarter(Carbon::MONDAY);       // 2014-04-07 00:00:00 这个季度的第一个周一
echo Carbon::create(2014, 5, 30, 0, 0, 0)->lastOfQuarter();                      // 2014-06-30 00:00:00 这个季度的最后一天
echo Carbon::create(2014, 5, 30, 0, 0, 0)->lastOfQuarter(Carbon::TUESDAY);       // 2014-06-24 00:00:00 这个季度的最后一个周二
echo Carbon::create(2014, 5, 30, 0, 0, 0)->nthOfQuarter(2, Carbon::SATURDAY);    // 2014-04-12 00:00:00 这个季度的第“2”个“周六”,2和周六是参数
echo Carbon::create(2014, 5, 30, 0, 0, 0)->startOfQuarter();                     // 2014-04-01 00:00:00 这个季度的开始
echo Carbon::create(2014, 5, 30, 0, 0, 0)->endOfQuarter();                       // 2014-06-30 23:59:59 这个季度的结束

echo Carbon::create(2014, 5, 30, 0, 0, 0)->firstOfYear();                        // 2014-01-01 00:00:00 同上……
echo Carbon::create(2014, 5, 30, 0, 0, 0)->firstOfYear(Carbon::MONDAY);          // 2014-01-06 00:00:00
echo Carbon::create(2014, 5, 30, 0, 0, 0)->lastOfYear();                         // 2014-12-31 00:00:00
echo Carbon::create(2014, 5, 30, 0, 0, 0)->lastOfYear(Carbon::TUESDAY);          // 2014-12-30 00:00:00
echo Carbon::create(2014, 5, 30, 0, 0, 0)->nthOfYear(2, Carbon::SATURDAY);       // 2014-01-11 00:00:00

echo Carbon::create(2018, 2, 23, 0, 0, 0)->nextWeekday();                        // 2018-02-26 00:00:00 下周一
echo Carbon::create(2018, 2, 23, 0, 0, 0)->previousWeekday();                    // 2018-02-22 00:00:00 这周的上一个工作日
echo Carbon::create(2018, 2, 21, 0, 0, 0)->nextWeekendDay();                     // 2018-02-24 00:00:00 即将要过的周末的第一天(即这星期的周六,如果今天是周六,则结果是周日)
echo Carbon::create(2018, 2, 21, 0, 0, 0)->previousWeekendDay();                 // 2018-02-18 00:00:00 刚过完的周末的最后一个(即上一周的周日,如果今天是周日,则结果是周六)

·         Constants

下面的常数是在Carbon中定义的。

// These getters specifically return integers, ie intval()
var_dump(Carbon::SUNDAY);                          // int(0)
var_dump(Carbon::MONDAY);                          // int(1)
var_dump(Carbon::TUESDAY);                         // int(2)
var_dump(Carbon::WEDNESDAY);                       // int(3)
var_dump(Carbon::THURSDAY);                        // int(4)
var_dump(Carbon::FRIDAY);                          // int(5)
var_dump(Carbon::SATURDAY);                        // int(6)

var_dump(Carbon::YEARS_PER_CENTURY);               // int(100)
var_dump(Carbon::YEARS_PER_DECADE);                // int(10)
var_dump(Carbon::MONTHS_PER_YEAR);                 // int(12)
var_dump(Carbon::WEEKS_PER_YEAR);                  // int(52)
var_dump(Carbon::DAYS_PER_WEEK);                   // int(7)
var_dump(Carbon::HOURS_PER_DAY);                   // int(24)
var_dump(Carbon::MINUTES_PER_HOUR);                // int(60)
var_dump(Carbon::SECONDS_PER_MINUTE);              // int(60)

$dt = Carbon::createFromDate(2012, 10, 6);
if ($dt->dayOfWeek === Carbon::SATURDAY) {
    echo 'Place bets on Ottawa Senators Winning!';
}



英文原档:https://carbon.nesbot.com/docs/#api-interval

翻译有问题的地方还请斧正~


1人推荐
随时随地看视频
慕课网APP