Home>Article>PHP Framework> Let’s talk about the function and usage of Laravel Carbon extension package

Let’s talk about the function and usage of Laravel Carbon extension package

藏色散人
藏色散人 forward
2021-11-12 14:28:06 3344browse

The following column will introduce you to the Laravel Carbon expansion pack from theLaravel Tutorialcolumn. I hope it will be helpful to everyone!

  • Introduction

##Carbon *Inherits PHP’s *Datetime* class andJsonSerialiable. Therefore, methods not covered in *Carbon* but already implemented in *Datetime * andJsonSerializable* can be used.

class Carbon extends DateTime implements JsonSerializable { //code here}
The Carbon class is declared under the Carbon namespace. You can introduce the namespace instead of entering the complete class name each time.

Pay special attention to whether the correct time zone is used. For example, all difference comparisons use the time zone set by the system.
      

$dtToronto = Carbon::create(2012, 1, 1, 0, 0, 0, 'America/Toronto'); $dtVancouver = Carbon::create(2012, 1, 1, 0, 0, 0, 'America/Vancouver'); echo $dtVancouver->diffInHours($dtToronto); //
The above time comparison is performed in the provided

CarbonCompleted in the time zone where the instance is located. For example, the author's time zone is Tokyo time minus 13 hours, so it is after 1 p.m.Carbon::now('Asia/Tokyo')->isToday()will return false. If the time zone is set to Tokyo time zone when callingnow(), the following It is unjustifiable to use Tokyo time zone for all operations. So when comparing to instances created by *now() *, the default is done in the current time zone.

  • Instantiation

  • ##There are a few different ways to create a new
Carbon

Example. First is the constructor. It overrides the parent constructor, you'd better read thePHPmanual for the first parameter and understand what date/time string formats it accepts. You may find yourself rarely using constructors, instead relying on explicit static methods to improve readability

$carbon = new Carbon(); // 等同于 Carbon::now() $carbon = new Carbon('first day of January 2008', 'America/Vancouver'); echo get_class($carbon); // 'Carbon\Carbon' $carbon = Carbon::now(-5);//1表示英国伦敦,2表示法国巴黎
You will notice above that the

timezone(2nd)

parameters are Passed as strings and integers instead of\DateTimeZoneinstances. AllDateTimeZoneparameters have been enhanced so that you can pass a DateTimeZone instance, string, or integer offset toGMTand the time zone is created for you. This is shown again in the next example, which also introduces thenow()function.

$nowInLondonTz = Carbon::now(new \DateTimeZone('Europe/London')); // 或者以字符串形式只传时区 $nowInLondonTz = Carbon::now('Europe/London');// 或者在DST期间创建一个时区为+1到GMT的日期,然后传递一个整数echo Carbon::now(1)->tzName; // Europe/London
If you really like your dynamic method calls and are frustrated by the extra lines or ugly parentheses required when using constructors, you will like the

parse

approach.

echo (new Carbon('first day of December 2008'))->addWeeks(2); // 2008-12-15 00:00:00 echo Carbon::parse('first day of December 2008')->addWeeks(2); // 2008-12-15 00:00:00

NOTE*:BeforePHP 5.4*(new MyClass())->method( )will report a syntax error**,If you use **PHP 5.3,You need to create a variable and then call the method:

$date = new Carbon('first day of December 2008'); echo $date->addWeeks(2);
The string passed to

Carbon:::parse

ornew Carboncan represent relative time (next sunday, tomorrow, first day of next month, last year) or absolute time (first day of December 2008, 2017-01-06). You can useCarbon::hasRelativeKeywords()to test whether a string will produce a relative or absolute date.

$string = 'first day of next month'; if (strtotime($string) === false) { echo "'$string' is not a valid date/time string."; } elseif (Carbon::hasRelativeKeywords($string)) { echo "'$string' is a relative valid date/time string, it will returns different dates depending on the current date."; } else { echo "'$string' is an absolute date/time string, it will always returns the same date."; }
In order to cooperate with

now()

, there are also some static instantiation helpers to create well-known instances. The only thing to note here is thattoday(),tomorrow()andyesterday(), in addition to behaving as expected, all accept a time zone parameter, each The time values of the parameters are all set to 00:00:00.

$now = Carbon::now(); echo $now; // 2018-07-26 16:25:49 $today = Carbon::today(); echo $today; // 2018-07-26 00:00:00 $tomorrow = Carbon::tomorrow('Europe/London'); echo $tomorrow; // 2018-07-27 00:00:00 $yesterday = Carbon::yesterday(); echo $yesterday; // 2018-07-25 00:00:00
The next set of static helpers is the createXXX() function. Most static create functions allow you to provide many or few parameters and provide default values for all other parameters. Usually the default value is the current date, time, or time zone. Higher values will wrap appropriately, but invalid values will throw an

InvalidArgumentException

with a message. The error message is obtained from theDateTime:::getLastErrors()call.

Carbon::createFromDate($year, $month, $day, $tz); Carbon::createFromTime($hour, $minute, $second, $tz); Carbon::createFromTimeString("$hour:$minute:$second", $tz); Carbon::create($year, $month, $day, $hour, $minute, $second, $tz);

createFromDate()

The default value is the current time.createFromTime()The default value is today.create()If no parameters are passed Also the current time. As before, $tz is set to the current time zone by default, otherwise it can be aDateTimeZoneinstance or a string time zone value. The only special case of default values (emulating the underlying PHP library) occurs when an hour value is specified but no minutes or seconds, they will default to 0.

Note: ***createFromTime()**will default the date to today**. The editor printed out the actual code and found that the default value of**createFromTime()**is also the current time, not today (hours, minutes and seconds are not**00 :00:00**). ***

$xmasThisYear = Carbon::createFromDate(null, 12, 25); // Year默认值是今年 $Y2K = Carbon::create(2000, 1, 1, 0, 0, 0); // 等价于Carbon::createMidnightDate(2000, 1, 1) $alsoY2K = Carbon::create(1999, 12, 31, 24); $noonLondonTz = Carbon::createFromTime(12, 0, 0, 'Europe/London'); $teaTime = Carbon::createFromTimeString('17:00:00', 'Europe/London'); // A two digit minute could not be found try { Carbon::create(1975, 5, 21, 22, -2, 0); } catch(\InvalidArgumentException $x) { echo $x->getMessage()}
Create exception occurs on using negative values, not on overflow, to get exception on overflow, use

createSafe

()

echo Carbon::create(2000, 1, 35, 13, 0, 0);// 2000-02-04 13:00:00 //(1月有31天,4天自动加上去转换成了2月4号) try { Carbon::createSafe(2000, 1, 35, 13, 0, 0); } catch (\Carbon\Exceptions\InvalidDateException $exp) { echo $exp->getMessage(); }// 会报错:day : 35 is not a valid value.

NOTE1:2018-02-29会产生一个异常,而2020-02-29不会产生异常,因为2020年是闰年。

NOTE2:Carbon::createSafe(2014,3,30,1,30,0,’Europe/London’);从PHP 5.4开始也会产生一个异常,因为在夏令时跳过一个小时,但是在PHP 5.4之前,它只会创建这个无效的日期。

Carbon::createFromFormat($format, $time, $tz);

createFromFormat()是最基本的php函数DateTime:::createFromFormat的包装器。不同的是,$tz参数可以是DateTimeZone实例或字符串时区值。此外,如果格式有错误,这个函数将调用DateTime::getLastErrors()方法,然后抛出一个InvalidArgumentException,错误作为消息。如果您查看上面的createXX()函数的源代码,它们都会调用createFromFormat()。

echo Carbon::createFromFormat('Y-m-d H', '1975-05-21 22')->toDateTimeString(); // 1975-05-21 22:00:00

最后三个create函数用于使用unix时间戳。第一个将创建一个与给定的时间戳相等的Carbon实例,并将设置时区或默认为当前时区。第二个createFromTimestampUTC()是不同的,因为时区将保持UTC(GMT)。第二种方法与Carbon: createFromFormat(‘@’.$timestamp)的作用相同,但我只是让它更明确了一点。第三个是createFromTimestampMs(),它接受以毫秒而不是秒为单位的时间戳。也允许使用负时间戳。

echo Carbon::createFromTimestamp(-1)->toDateTimeString(); // 1969-12-31 18:59:59 echo Carbon::createFromTimestamp(-1, 'Europe/London')->toDateTimeString(); // 1970-01-01 00:59:59 echo Carbon::createFromTimestampUTC(-1)->toDateTimeString(); // 1969-12-31 23:59:59echo Carbon::createFromTimestampMs(1)->format('Y-m-d\THLet’s talk about the function and usage of Laravel Carbon extension packages.uP T'); // 1969-12-31T19:00:00.001000-05:00 EST echo Carbon::createFromTimestampMs(1, 'Europe/London')->format('Y-m-d\THLet’s talk about the function and usage of Laravel Carbon extension packages.uP T'); // 1970-01-01T01:00:00.001000+01:00 BST

您还可以copy()在现有Carbon实例上创建。如预期的那样,日期、时间和时区值都被复制到新实例。

$dt = Carbon::now(); echo $dt->diffInYears($dt->copy()->addYear()); // 1

// $dt 实例没有改变,任然是Carbon:now()

您可以在现有的Carbon实例上使用nowWithSameTz()来在相同的时区中获取一个新的实例。

$meeting = Carbon::createFromTime(19, 15, 00, 'Africa/Johannesburg');// 19:15 in Johannesburg echo 'Meeting starts at '.$meeting->format('H:i').' in Johannesburg.'; // Meeting starts at 19:15 in Johannesburg.// now in Johannesburg echo "It's ".$meeting->nowWithSameTz()->format('H:i').' right now in Johannesburg.'; // It's 09:37 right now in Johannesburg.

最后,如果您发现自己从另一个库继承了\DateTime实例,不要害怕!您可以通过友好的instance()方法创建一个Carbon实例。或者使用更灵活的方法make(),它可以从DateTimeCarbonstring返回一个新的Carbon实例,否则它只返回null。

$dt = new \DateTime('first day of January 2008'); // toDateTimeString(); // 2008-01-01 00:00:00

关于微秒的简要说明。PHPDateTime对象允许您设置一个微秒值,但是忽略它的所有日期数学。现在,1.12.0的Carbon在实例化或复制操作过程中支持微秒,并在默认情况下使用format()方法。

$dt = Carbon::parse('1975-05-21 22:23:00.123456'); echo $dt->micro; // echo $dt->copy()->micro; //

在PHP 7.1之前 DateTime微秒未添加到“now”实例,并且之后不能更改,这意味着:

$date = new DateTime('now'); echo $date->format('u'); // display current microtime in PHP >= 7.1 (expect a bug in PHP 7.1.3 only)// display 000000 before PHP 7.1 $date = new DateTime('2001-01-01T00:00:00.123456Z'); echo $date->format('u'); // display 123456 in all PHP versions$date->modify('00:00:00.987654');echo $date->format('u');// display 987654 in PHP >= 7.1// display 123456 before PHP 7.1

为了解决这个限制,我们在PHP = 7.1):

Carbon::useMicrosecondsFallback(false);var_dump(Carbon::isMicrosecondsFallbackEnabled()); // false echo Carbon::now()->micro; // 0 in PHP = 7.1Carbon::useMicrosecondsFallback(true); // default value var_dump(Carbon::isMicrosecondsFallbackEnabled()); // trueecho Carbon::now()->micro; // microtime in all PHP version

是否需要遍历一些日期以找到最早或最近的日期?不知道如何设置初始最大值/最小值?现在有两个助手可以帮助你做出简单的决定:

echo Carbon::maxValue(); // '9999-12-31 23:59:59'echo Carbon::minValue(); // '0001-01-01 00:00:00'

最小和最大值主要取决于系统(32位或64位)。

使用32位OS系统或32位版本的PHP(您可以在PHP中使用PHP_INT_SIZE == 4来检查它),最小值是0-unix-timestamp(1970-01-01 00:00:00),最大值是常量PHP_INT_MAX给出的时间戳。

使用64位OS系统和64位PHP版本,最小值为01-01 00:00,最大值为9999-12-31 23:59:59。

  • Localization

不幸的是,基类DateTime没有任何本地化支持。为了开始本地化支持,还添加了一个formatLocalized($format)方法。实现使用当前实例时间戳对strftime进行调用。如果您首先使用PHP函数setlocale()设置当前的语言环境,那么返回的字符串将被格式化为正确的语言环境。

$newLocale = setlocale(LC_TIME, 'German'); if ($newLocale === false) { echo '"German" locale is not installed on your machine, it may have a different name a different name on your machine or you may need to install it.'; }echo $dt->formatLocalized('%A %d %B %Y'); // Mittwoch 21 Mai 1975 setlocale(LC_TIME, 'English'); echo $dt->formatLocalized('%A %d %B %Y'); // Wednesday 21 May 1975 setlocale(LC_TIME, ''); // reset locale

diffForHumans()也被定位。您可以通过使用静态Carbon::setLocale()函数来设置Carbon locale(),并使用Carbon::getLocale()获取当前的设置。

Carbon::setLocale('de'); echo Carbon::getLocale(); // de echo Carbon::now()->addYear()->diffForHumans(); // in 1 Jahr Carbon::setLocale('en'); echo Carbon::getLocale(); // en

或者,您可以将一些代码与给定的语言环境隔离:

Carbon::executeWithLocale('de', function ($newLocale) { // You can optionally get $newLocale as the first argument of the closure // It will be set to the new locale or false if the locale was not found. echo Carbon::now()->addYear()->diffForHumans(); }); // in 1 Jahr // outside the function the locale did not change echo Carbon::getLocale(); // en // or same using a return statement$french = Carbon::executeWithLocale('fr', function () {return Carbon::now()->addYear()->diffForHumans();}); echo $french; // dans 1 an

有些语言需要打印utf8编码(主要以. utf8结尾的语言环境包)。在本例中,您可以使用静态方法"php

Carbon::setUtf8()对对utf8字符集的formatlocalized()调用的结果进行编码。 setlocale(LC_TIME, 'Spanish'); $dt = Carbon::create(2016, 01, 06, 00, 00, 00); Carbon::setUtf8(false); echo $dt->formatLocalized('%A %d %B %Y'); // mi�rcoles 06 enero 2016 Carbon::setUtf8(true); echo $dt->formatLocalized('%A %d %B %Y'); // miércoles 06 enero 2016 Carbon::setUtf8(false); setlocale(LC_TIME, '');

在Linux上

如果您在翻译方面有问题,请检查系统中安装的地区(本地和生产)。

区域设置-列出已启用的区域设置。

sudo locale-gen fr_FR。UTF-8安装一个新的语言环境。

sudo dpkg-reconfigure locale来发布所有启用的locale。

并重启系统。

您可以通过以下方式自定义现有语言:

Carbon::setLocale('en'); $translator = Carbon::getTranslator(); $translator->setMessages('en', array( 'day' => ':count boring day|:count boring days', )); $date1 = Carbon::create(2018, 1, 1, 0, 0, 0); $date2 = Carbon::create(2018, 1, 4, 4, 0, 0); echo $date1->diffForHumans($date2, true, false, 2); // 3 boring days 4 hours$translator->resetMessages('en'); // reset language customizations for en language

请注意,您还可以使用另一个转换器Carbon::setTranslator($custom),只要给定的转换器继承了Symfony\Component\Translation\TranslatorInterface。 因此,对格式本地化、getter(如localeMonth、localedayayofweek和短变体)的语言环境支持是由安装在操作系统中的语言环境驱动的。对于其他翻译,由于碳社区的支持,它在内部得到了支持。您可以使用以下方法检查支持的内容:

echo implode(', ', array_slice(Carbon::getAvailableLocales(), 0, 3)).'...'; // af, ar, ar_Shakl... // Support diff syntax (before, after, from now, ago) var_dump(Carbon::localeHasDiffSyntax('en')); // bool(true) var_dump(Carbon::localeHasDiffSyntax('zh_TW')); // bool(true) // Support 1-day diff words (just now, yesterday, tomorrow) var_dump(Carbon::localeHasDiffOneDayWords('en')); // bool(true) var_dump(Carbon::localeHasDiffOneDayWords('zh_TW')); // bool(false) // Support 2-days diff words (before yesterday, after tomorrow)var_dump(Carbon::localeHasDiffTwoDayWords('en')); // bool(true) var_dump(Carbon::localeHasDiffTwoDayWords('zh_TW')); // bool(false) // Support short units (1y = 1 year, 1mo = 1 month, etc.) var_dump(Carbon::localeHasShortUnits('en')); // bool(true)var_dump(Carbon::localeHasShortUnits('zh_TW')); // bool(false)// Support period syntax (X times, every X, from X, to X)var_dump(Carbon::localeHasPeriodSyntax('en')); // bool(true)var_dump(Carbon::localeHasPeriodSyntax('zh_TW')); // bool(false)

以下是最后一个碳版本支持的73个地区的概述:

注意,如果您使用Laravel 5.5+,语言环境将根据当前的最后一个App:setLocale execution自动设置。所以扩散人类将是透明的。您可能仍然需要在某些中间件中运行setlocale以使formatlocalizedworking正确。

  • Testing Aids

测试方法允许您在创建“现在”实例时设置要返回的Carbon实例(real或mock)。所提供的实例将在以下条件下具体返回:

对static now()方法的调用,例如Let’s talk about the function and usage of Laravel Carbon extension package:now()

当一个空(或空字符串)被传递给构造函数或parse()时,ex.new Carbon(空)

当字符串“now”传递给构造函数或parse()时,ex. new Carbon(‘now’)

给定的实例也将作为diff方法的默认相对时间。

$knownDate = Carbon::create(2001, 5, 21, 12); // create testing date Carbon::setTestNow($knownDate); // set the mock (of course this could be a real mock object) echo Carbon::getTestNow(); // 2001-05-21 12:00:00 echo Carbon::now(); // 2001-05-21 12:00:00 echo new Carbon(); // 2001-05-21 12:00:00 echo Carbon::parse(); // 2001-05-21 12:00:00 echo new Carbon('now'); // 2001-05-21 12:00:00 echo Carbon::parse('now'); // 2001-05-21 12:00:00 echo Carbon::create(2001, 4, 21, 12)->diffForHumans(); // 1 month agovar_dump(Carbon::hasTestNow()); // bool(true) Carbon::setTestNow(); // clear the mock var_dump(Carbon::hasTestNow()); // bool(false)echo Carbon::now(); // 2018-07-05 03:37:12

一个更有意义的完整例子:

class SeasonalProduct { protected $price; public function __construct($price) { $this->price = $price; } public function getPrice() { $multiplier = 1; if (Carbon::now()->month == 12) { $multiplier = 2; } return $this->price * $multiplier;}} $product = new SeasonalProduct(100); Carbon::setTestNow(Carbon::parse('first day of March 2000')); echo $product->getPrice(); //Carbon::setTestNow(Carbon::parse('first day of December 2000')); echo $product->getPrice(); // Carbon::setTestNow(Carbon::parse('first day of May 2000')); echo $product->getPrice(); // Carbon::setTestNow();

根据给定的“now”实例,还可以对相关短语进行嘲笑。

$knownDate = Carbon::create(2001, 5, 21, 12); // create testing date Carbon::setTestNow($knownDate); // set the mock echo new Carbon('tomorrow'); // 2001-05-22 00:00:00 ... notice the time ! echo new Carbon('yesterday'); // 2001-05-20 00:00:00 echo new Carbon('next wednesday'); // 2001-05-23 00:00:00 echo new Carbon('last friday'); // 2001-05-18 00:00:00 echo new Carbon('this thursday'); // 2001-05-24 00:00:00 Carbon::setTestNow(); // always clear it !

被认为是相对修饰语的单词列表如下:

  • +
  • -
  • ago
  • first
  • next
  • last
  • this
  • today
  • tomorrow
  • yesterday

请注意,与next()、previous()和modify()方法类似,这些相对修饰符中的一些将把时间设置为00:00。

Carbon: parse($time, $tz)和new Carbon($time, $tz)都可以将时区作为第二个参数。 echo Carbon::parse('2012-9-5 23:26:11.223', 'Europe/Paris')->timezone->getName(); // Europe/Paris
  • Getters

getter方法是通过PHP的__get()方法实现的。这使您能够像访问属性而不是函数调用那样访问值。

$dt = Carbon::parse('2012-10-5 23:26:11.123789'); // 这些getter方法都将返回int类型 var_dump($dt->year); // int(2012)var_dump($dt->month); // int(10) var_dump($dt->day); // int(5) var_dump($dt->hour); // int(23) var_dump($dt->minute); // int(26) var_dump($dt->second); // int(11)var_dump($dt->micro); // int(123789)// dayOfWeek 返回一个数值 0 (sunday) 到 6 (saturday) var_dump($dt->dayOfWeek); // int(5)// dayOfWeekIso 返回一个数值 1 (monday) 到 7 (sunday) var_dump($dt->dayOfWeekIso); // int(5) setlocale(LC_TIME, 'German');var_dump($dt->englishDayOfWeek); // string(6) "Friday"var_dump($dt->shortEnglishDayOfWeek); // string(3) "Fri"var_dump($dt->localeDayOfWeek); // string(7) "Freitag"var_dump($dt->shortLocaleDayOfWeek); // string(2) "Fr"var_dump($dt->englishMonth); // string(7) "October"var_dump($dt->shortEnglishMonth); // string(3) "Oct"var_dump($dt->localeMonth); // string(7) "Oktober"var_dump($dt->shortLocaleMonth); // string(3) "Okt"setlocale(LC_TIME, '');var_dump($dt->dayOfYear); // int(278)var_dump($dt->weekNumberInMonth);// weekNumberInMonth consider weeks from monday to sunday, so the week 1 will// contain 1 day if the month start with a sunday, and up to 7 if it starts with a mondayvar_dump($dt->weekOfMonth); // int(1)// weekOfMonth will returns 1 for the 7 first days of the month, then 2 from the 8th to// the 14th, 3 from the 15th to the 21st, 4 from 22nd to 28th and 5 above var_dump($dt->weekOfYear); // int(40) var_dump($dt->daysInMonth); // int(31) var_dump($dt->timestamp); // int(1349493971) var_dump(Carbon::createFromDate(1975, 5, 21)->age); // int(43) calculated vs now in the same tzvar_dump($dt->quarter); // int(4) // Returns an int of seconds difference from UTC (+/- sign included) var_dump(Carbon::createFromTimestampUTC(0)->offset); // int(0) var_dump(Carbon::createFromTimestamp(0)->offset); // int(-18000) // Returns an int of hours difference from UTC (+/- sign included) var_dump(Carbon::createFromTimestamp(0)->offsetHours); // int(-5)// Indicates if day light savings time is on var_dump(Carbon::createFromDate(2012, 1, 1)->dst); // bool(false) var_dump(Carbon::createFromDate(2012, 9, 1)->dst); // bool(true) // Indicates if the instance is in the same timezone as the local timezone var_dump(Carbon::now()->local); // bool(true)var_dump(Carbon::now('America/Vancouver')->local); // bool(false)// Indicates if the instance is in the UTC timezonevar_dump(Carbon::now()->utc); // bool(false) var_dump(Carbon::now('Europe/London')->utc); // bool(false) var_dump(Carbon::createFromTimestampUTC(0)->utc); // bool(true) // Gets the DateTimeZone instanceecho get_class(Carbon::now()->timezone); // DateTimeZone echo get_class(Carbon::now()->tz); // DateTimeZone// Gets the DateTimeZone instance name, shortcut for ->timezone->getName()echo Carbon::now()->timezoneName; // America/Toronto echo Carbon::now()->tzName; // America/Toronto
  • Setters

下面的setter是通过PHP的__set()方法实现的。值得注意的是,除了显式地设置时区之外,任何设置程序都不会更改实例的时区。具体地说,设置时间戳不会将相应的时区设置为UTC。

$dt = Carbon::now();$dt->year = 1975; $dt->month = 13; //强制 year++ 然后 month = 1 $dt->month = 5; $dt->day = 21; $dt->hour = 22; $dt->minute = 32; $dt->second = 5; $dt->timestamp = 169957925; // 这不会改变时区 // 通过DateTimeZone实例或字符串设置时区 $dt->timezone = new DateTimeZone('Europe/London');$dt->timezone = 'Europe/London';$dt->tz = 'Europe/London';
  • Fluent Setters

对于setter没有可选参数,但是函数定义中有足够的多样性,因此无论如何都不需要它们。值得注意的是,除了显式地设置时区之外,任何设置程序都不会更改实例的时区。具体地说,设置时间戳不会将相应的时区设置为UTC。

$dt = Carbon::now();$dt->year(1975)->month(5)->day(21)->hour(22)->minute(32)->second(5)->toDateTimeString(); $dt->setDate(1975, 5, 21)->setTime(22, 32, 5)->toDateTimeString(); $dt->setDate(1975, 5, 21)->setTimeFromTimeString('22:32:05')->toDateTimeString(); $dt->setDateTime(1975, 5, 21, 22, 32, 5)->toDateTimeString(); $dt->timestamp(169957925)->timezone('Europe/London'); $dt->tz('America/Toronto')->setTimezone('America/Vancouver');

您还可以将日期和时间与其他DateTime/Carbon对象分开设置:

$source1 = new Carbon('2010-05-16 22:40:10'); $dt = new Carbon('2001-01-01 01:01:01'); $dt->setTimeFrom($source1);echo $dt; // 2001-01-01 22:40:10 $source2 = new DateTime('2013-09-01 09:22:56');$dt->setDateFrom($source2);echo $dt; // 2013-09-01 22:40:10
  • IsSet

实现了PHP函数isset()。这是在一些外部系统(例如Twig)在使用属性之前验证属性的存在时完成的。这是使用isset()或empty()方法完成的。在PHP站点:isset()、isset()、empty()上,您可以阅读更多关于这些内容的信息。

var_dump(isset(Carbon::now()->iDoNotExist)); // bool(false) var_dump(isset(Carbon::now()->hour)); // bool(true) var_dump(empty(Carbon::now()->iDoNotExist)); // bool(true) var_dump(empty(Carbon::now()->year)); // bool(false)
  • String Formatting

所有可用的toXXXString()方法都依赖于基类方法DateTime: format()。您将注意到__toString()方法的定义,它允许在字符串上下文中使用时将一个Carbon实例打印为一个漂亮的日期时间字符串。

$dt = Carbon::create(1975, 12, 25, 14, 15, 16); var_dump($dt->toDateTimeString() == $dt); // bool(true) => uses __toString() echo $dt->toDateString(); // 1975-12-25 echo $dt->toFormattedDateString(); // Dec 25, 1975 echo $dt->toTimeString(); // 14:15:16 echo $dt->toDateTimeString(); // 1975-12-25 14:15:16 echo $dt->toDayDateTimeString(); // Thu, Dec 25, 1975 2:15 PM// ... of course format() is still availableecho $dt->format('l jS \\of F Y hLet’s talk about the function and usage of Laravel Carbon extension packages A'); // Thursday 25th of December 1975 02:15:16 PM // The reverse hasFormat method allows you to test if a string looks like a given format var_dump($dt->hasFormat('Thursday 25th December 1975 02:15:16 PM', 'l jS F Y hLet’s talk about the function and usage of Laravel Carbon extension packages A')); // bool(true)

您还可以设置默认的__toString()格式(默认为Y-m-d HLet’s talk about the function and usage of Laravel Carbon extension packages),这是在发生类型杂耍时使用的格式。

Carbon::setToStringFormat('jS \o\f F, Y gLet’s talk about the function and usage of Laravel Carbon extension packages a'); echo $dt; // 25th of December, 1975 2:15:16 pmCarbon::resetToStringFormat(); echo $dt; // 1975-12-25 14:15:16

NOTE:对于本地化支持,请参阅本地化部分。

  • Common Formats

下面是DateTime类中提供的公共格式的包装器。

$dt = Carbon::createFromFormat('Y-m-d HLet’s talk about the function and usage of Laravel Carbon extension packages.u', '2019-02-01 03:45:27.612584'); // $dt->toAtomString() is the same as $dt->format(DateTime::ATOM); echo $dt->toAtomString(); // 2019-02-01T03:45:27-05:00 echo $dt->toCookieString(); // Friday, 01-Feb-2019 03:45:27 EST echo $dt->toIso8601String(); // 2019-02-01T03:45:27-05:00 // Be aware we chose to use the full-extended format of the ISO 8601 norm // Natively, DateTime::ISO8601 format is not compatible with ISO-8601 as it// is explained here in the PHP documentation: // https://php.net/manual/class.datetime.php#datetime.constants.iso8601 // We consider it as a PHP mistake and chose not to provide method for this // format, but you still can use it this way: echo $dt->format(DateTime::ISO8601); // 2019-02-01T03:45:27-0500 echo $dt->toIso8601ZuluString(); // 2019-02-01T08:45:27Z echo $dt->toRfc822String(); // Fri, 01 Feb 19 03:45:27 -0500echo $dt->toRfc850String(); // Friday, 01-Feb-19 03:45:27 EST echo $dt->toRfc1036String(); // Fri, 01 Feb 19 03:45:27 -0500 echo $dt->toRfc1123String(); // Fri, 01 Feb 2019 03:45:27 -0500 echo $dt->toRfc2822String(); // Fri, 01 Feb 2019 03:45:27 -0500 echo $dt->toRfc3339String(); // 2019-02-01T03:45:27-05:00 echo $dt->toRfc7231String(); // Fri, 01 Feb 2019 08:45:27 GMT echo $dt->toRssString(); // Fri, 01 Feb 2019 03:45:27 -0500 echo $dt->toW3cString(); // 2019-02-01T03:45:27-05:00 var_dump($dt->toArray());/* array(12) { ["year"]=> int(2019) ["month"]=> int(2) ["day"]=> int(1) ["dayOfWeek"]=> int(5) ["dayOfYear"]=> int(31) ["hour"]=> int(3) ["minute"]=> int(45) ["second"]=> int(27) ["micro"]=> int(612584) ["timestamp"]=> int(1549010727) ["formatted"]=> string(19) "2019-02-01 03:45:27" ["timezone"]=> object(DateTimeZone)#118 (2) { ["timezone_type"]=> int(3) ["timezone"]=> string(15) "America/Toronto" } } */
  • Comparison

通过以下函数提供了简单的比较。请记住,比较是在UTC时区进行的,所以事情并不总是像看上去的那样。

echo Carbon::now()->tzName; // America/Toronto $first = Carbon::create(2012, 9, 5, 23, 26, 11); $second = Carbon::create(2012, 9, 5, 20, 26, 11, 'America/Vancouver'); echo $first->toDateTimeString(); // 2012-09-05 23:26:11 echo $first->tzName; // America/Toronto echo $second->toDateTimeString(); // 2012-09-05 20:26:11echo $second->tzName; // America/Vancouver var_dump($first->eq($second)); // bool(true)var_dump($first->ne($second)); // bool(false) var_dump($first->gt($second)); // bool(false)var_dump($first->gte($second)); // bool(true) var_dump($first->lt($second)); // bool(false)var_dump($first->lte($second)); // bool(true) $first->setDateTime(2012, 1, 1, 0, 0, 0); $second->setDateTime(2012, 1, 1, 0, 0, 0); // Remember tz is 'America/Vancouver' var_dump($first->eq($second)); // bool(false) var_dump($first->ne($second)); // bool(true) var_dump($first->gt($second)); // bool(false) var_dump($first->gte($second)); // bool(false) var_dump($first->lt($second)); // bool(true) var_dump($first->lte($second)); // bool(true) // All have verbose aliases and PHP equivalent code: var_dump($first->eq($second)); // bool(false) var_dump($first->equalTo($second)); // bool(false) var_dump($first == $second); // bool(false)var_dump($first->ne($second)); // bool(true) var_dump($first->notEqualTo($second)); // bool(true)var_dump($first != $second); // bool(true)var_dump($first->gt($second)); // bool(false) var_dump($first->greaterThan($second)); // bool(false)var_dump($first > $second); // bool(false) var_dump($first->gte($second)); // bool(false) var_dump($first->greaterThanOrEqualTo($second)); // bool(false) var_dump($first >= $second); // bool(false)var_dump($first->lt($second)); // bool(true)var_dump($first->lessThan($second)); // bool(true)var_dump($first lte($second)); // bool(true) var_dump($first->lessThanOrEqualTo($second)); // bool(true) var_dump($first 

这些方法使用PHP $date1 == $date2提供的自然比较,因此在PHP 7.1之前,所有方法都将忽略milli/micro-seconds,然后从7.1开始考虑它们。

要确定当前实例是否在其他两个实例之间,可以使用恰当命名的between()方法。第三个参数表示是否应该进行相等的比较。默认值是true,它决定了它的中间值还是等于边界。

 $first = Carbon::create(2012, 9, 5, 1); $second = Carbon::create(2012, 9, 5, 5); var_dump(Carbon::create(2012, 9, 5, 3)->between($first, $second)); // bool(true) var_dump(Carbon::create(2012, 9, 5, 5)->between($first, $second)); // bool(true) var_dump(Carbon::create(2012, 9, 5, 5)->between($first, $second, false)); // bool(false)

哇!你忘记了min()和max()了吗?不。这也被适当命名的min()和max()方法或minimum()和maximum()别名所覆盖。与往常一样,如果指定为null,则默认参数现在为。

$dt1 = Carbon::createMidnightDate(2012, 1, 1); $dt2 = Carbon::createMidnightDate(2014, 1, 30); echo $dt1->min($dt2); // 2012-01-01 00:00:00 echo $dt1->minimum($dt2); // 2012-01-01 00:00:00 $dt1 = Carbon::createMidnightDate(2012, 1, 1); $dt2 = Carbon::createMidnightDate(2014, 1, 30); echo $dt1->max($dt2); // 2014-01-30 00:00:00 echo $dt1->maximum($dt2); // 2014-01-30 00:00:00// now is the default param $dt1 = Carbon::createMidnightDate(2000, 1, 1); echo $dt1->max(); // 2018-07-05 03:37:12 echo $dt1->maximum(); // 2018-07-05 03:37:12$dt1 = Carbon::createMidnightDate(2010, 4, 1);$dt2 = Carbon::createMidnightDate(2010, 3, 28); $dt3 = Carbon::createMidnightDate(2010, 4, 16); // returns the closest of two date (no matter before or after) echo $dt1->closest($dt2, $dt3); // 2010-03-28 00:00:00 echo $dt2->closest($dt1, $dt3); // 2010-04-01 00:00:00 echo $dt3->closest($dt2, $dt1); // 2010-04-01 00:00:00 // returns the farthest of two date (no matter before or after) echo $dt1->farthest($dt2, $dt3); // 2010-04-16 00:00:00 echo $dt2->farthest($dt1, $dt3); // 2010-04-16 00:00:00. echo $dt3->farthest($dt2, $dt1); // 2010-03-28 00:00:00

为了处理最常用的情况,这里有一些简单的帮助函数,希望它们的名称能很明显地反映出来。对于以某种方式与now() (ex.istoday()))进行比较的方法,now()是在与实例相同的时区创建的。

$dt = Carbon::now(); $dt2 = Carbon::createFromDate(1987, 4, 23); $dt->isSameAs('w', $dt2); // w is the date of the week, so this will return true if $dt and $dt2 // the same day of week (both monday or both sunday, etc.) // you can use any format and combine as much as you want.$dt->isFuture(); $dt->isPast();$dt->isSameYear($dt2); $dt->isCurrentYear(); $dt->isNextYear(); $dt->isLastYear(); $dt->isLongYear(); // see https://en.wikipedia.org/wiki/ISO_8601#Week_dates $dt->isLeapYear();$dt->isSameQuarter($dt2); // same quarter (3 months) no matter the year of the given date$dt->isSameQuarter($dt2, true); // same quarter of the same year of the given date/* Alternatively, you can run Carbon::compareYearWithMonth() to compare both quarter and year by default, In this case you can use $dt->isSameQuarter($dt2, false) to compare ignoring the year Run Carbon::compareYearWithMonth(false) to reset to the default behavior Run Carbon::shouldCompareYearWithMonth() to get the current setting */$dt->isCurrentQuarter(); $dt->isNextQuarter(); // date is in the next quarter $dt->isLastQuarter(); // in previous quarter $dt->isSameMonth($dt2); // same month no matter the year of the given date $dt->isSameMonth($dt2, true); // same month of the same year of the given date/* As for isSameQuarter, you can run Carbon::compareYearWithMonth() to compare both month and year by default, In this case you can use $dt->isSameMonth($dt2, false) to compare ignoring the year Run Carbon::compareYearWithMonth(false) to reset to the default behavior Run Carbon::shouldCompareYearWithMonth() to get the current setting */ $dt->isCurrentMonth(); $dt->isNextMonth(); $dt->isLastMonth(); $dt->isWeekday();$dt->isWeekend(); $dt->isMonday(); $dt->isTuesday();$dt->isWednesday(); $dt->isThursday(); $dt->isFriday(); $dt->isSaturday(); $dt->isSunday();$dt->isDayOfWeek(Carbon::SATURDAY); // is a saturday$dt->isLastOfMonth(); // is the last day of the month $dt->isSameDay($dt2); // Same day of same month of same year $dt->isCurrentDay(); $dt->isYesterday(); $dt->isToday();$dt->isTomorrow(); $dt->isNextWeek();$dt->isLastWeek(); $dt->isSameHour($dt2); $dt->isCurrentHour();$dt->isSameMinute($dt2);$dt->isCurrentMinute();$dt->isSameSecond($dt2); $dt->isCurrentSecond();$dt->isStartOfDay(); // check if hour is 00:00:00$dt->isMidnight(); // check if hour is 00:00:00 (isStartOfDay alias) $dt->isEndOfDay(); // check if hour is 23:59:59 $dt->isMidday(); // check if hour is 12:00:00 (or other midday hour set with Carbon::setMidDayAt())$born = Carbon::createFromDate(1987, 4, 23);$noCake = Carbon::createFromDate(2014, 9, 26);$yesCake = Carbon::createFromDate(2014, 4, 23); $overTheHill = Carbon::now()->subYears(50);var_dump($born->isBirthday($noCake)); // bool(false) var_dump($born->isBirthday($yesCake)); // bool(true) var_dump($overTheHill->isBirthday()); // bool(true) -> default compare it to today!
  • Addition and Subtraction

默认的DateTime提供了几种不同的方法来方便地添加和减少时间。有modify()、add()和sub()。modify()使用一个魔术date/time格式字符串“last day of next month”,它解析并应用修改,而add()和sub()则期望一个不那么明显的日期间隔实例(例如新的\日期间隔(‘P6YT5M’)将意味着6年5分钟)。希望使用这些流畅的函数将会更加清晰,并且在几个星期内没有看到您的代码后更容易阅读。当然,我不会让您选择,因为基类函数仍然可用。

$dt = Carbon::create(2012, 1, 31, 0);echo $dt->toDateTimeString(); // 2012-01-31 00:00:00 echo $dt->addCenturies(5); // 2512-01-31 00:00:00 echo $dt->addCentury(); // 2612-01-31 00:00:00 echo $dt->subCentury(); // 2512-01-31 00:00:00 echo $dt->subCenturies(5); // 2012-01-31 00:00:00echo $dt->addYears(5); // 2017-01-31 00:00:00 echo $dt->addYear(); // 2018-01-31 00:00:00 echo $dt->subYear(); // 2017-01-31 00:00:00 echo $dt->subYears(5); // 2012-01-31 00:00:00 echo $dt->addQuarters(2); // 2012-07-31 00:00:00echo $dt->addQuarter(); // 2012-10-31 00:00:00 echo $dt->subQuarter(); // 2012-07-31 00:00:00 echo $dt->subQuarters(2); // 2012-01-31 00:00:00 echo $dt->addMonths(60); // 2017-01-31 00:00:00 echo $dt->addMonth(); // 2017-03-03 00:00:00 equivalent of $dt->month($dt->month + 1); so it wrapsecho $dt->subMonth(); // 2017-02-03 00:00:00 echo $dt->subMonths(60); // 2012-02-03 00:00:00 echo $dt->addDays(29); // 2012-03-03 00:00:00echo $dt->addDay(); // 2012-03-04 00:00:00 echo $dt->subDay(); // 2012-03-03 00:00:00echo $dt->subDays(29); // 2012-02-03 00:00:00echo $dt->addWeekdays(4); // 2012-02-09 00:00:00 echo $dt->addWeekday(); // 2012-02-10 00:00:00echo $dt->subWeekday(); // 2012-02-09 00:00:00 echo $dt->subWeekdays(4); // 2012-02-03 00:00:00 echo $dt->addWeeks(3); // 2012-02-24 00:00:00 echo $dt->addWeek(); // 2012-03-02 00:00:00 echo $dt->subWeek(); // 2012-02-24 00:00:00 echo $dt->subWeeks(3); // 2012-02-03 00:00:00 echo $dt->addHours(24); // 2012-02-04 00:00:00 echo $dt->addHour(); // 2012-02-04 01:00:00echo $dt->subHour(); // 2012-02-04 00:00:00 echo $dt->subHours(24); // 2012-02-03 00:00:00echo $dt->addMinutes(61); // 2012-02-03 01:01:00echo $dt->addMinute(); // 2012-02-03 01:02:00 echo $dt->subMinute(); // 2012-02-03 01:01:00 echo $dt->subMinutes(61); // 2012-02-03 00:00:00echo $dt->addSeconds(61); // 2012-02-03 00:01:01echo $dt->addSecond(); // 2012-02-03 00:01:02 echo $dt->subSecond(); // 2012-02-03 00:01:01 echo $dt->subSeconds(61); // 2012-02-03 00:00:00

为了好玩,您还可以将负值传递给addXXX(),实际上这就是subXXX()实现的方式。 附注:如果你忘记并使用addDay(5) 或subYear(3),我支持你; 默认情况下,Carbon依赖于底层父类PHP DateTime行为。因此,增加或减少月份可能会溢出,例如:

$dt = Carbon::create(2017, 1, 31, 0);echo $dt->copy()->addMonth(); // 2017-03-03 00:00:00 echo $dt->copy()->subMonths(2); // 2016-12-01 00:00:00

为了防止溢出Carbon:usemonthverflow (false)

Carbon::useMonthsOverflow(false); $dt = Carbon::createMidnightDate(2017, 1, 31); echo $dt->copy()->addMonth(); // 2017-02-28 00:00:00 echo $dt->copy()->subMonths(2); // 2016-11-30 00:00:00 // Call the method with true to allow overflow again Carbon::resetMonthsOverflow(); // same as Carbon::useMonthsOverflow(true);

方法Carbon:::shouldOverflowMonths()允许您知道当前是否启用了溢出。您也可以使用->addMonthsNoOverflow, ->subMonthsNoOverflow, ->addMonthsWithOverflow, -> submonth withoverflow(或单数方法,不含s至“month”),显式add/sub,无论当前模式如何,都可以添加或不添加溢出。

Carbon::useMonthsOverflow(false); $dt = Carbon::createMidnightDate(2017, 1, 31); echo $dt->copy()->addMonthWithOverflow(); // 2017-03-03 00:00:00 // plural addMonthsWithOverflow() method is also availableecho $dt->copy()->subMonthsWithOverflow(2); // 2016-12-01 00:00:00 // singular subMonthWithOverflow() method is also available echo $dt->copy()->addMonthNoOverflow(); // 2017-02-28 00:00:00 // plural addMonthsNoOverflow() method is also available echo $dt->copy()->subMonthsNoOverflow(2); // 2016-11-30 00:00:00 // singular subMonthNoOverflow() method is also available echo $dt->copy()->addMonth(); // 2017-02-28 00:00:00echo $dt->copy()->subMonths(2); // 2016-11-30 00:00:00Carbon::useMonthsOverflow(true);$dt = Carbon::createMidnightDate(2017, 1, 31); echo $dt->copy()->addMonthWithOverflow(); // 2017-03-03 00:00:00 echo $dt->copy()->subMonthsWithOverflow(2); // 2016-12-01 00:00:00 echo $dt->copy()->addMonthNoOverflow(); // 2017-02-28 00:00:00 echo $dt->copy()->subMonthsNoOverflow(2); // 2016-11-30 00:00:00echo $dt->copy()->addMonth(); // 2017-03-03 00:00:00 echo $dt->copy()->subMonths(2); // 2016-12-01 00:00:00Carbon::resetMonthsOverflow();

从1.23.0版本开始,在以下年份也可以使用溢出控制:

Carbon::useYearsOverflow(false); $dt = Carbon::createMidnightDate(2020, 2, 29); var_dump(Carbon::shouldOverflowYears()); // bool(false) echo $dt->copy()->addYearWithOverflow(); // 2021-03-01 00:00:00 // plural addYearsWithOverflow() method is also available echo $dt->copy()->subYearsWithOverflow(2); // 2018-03-01 00:00:00// singular subYearWithOverflow() method is also availableecho $dt->copy()->addYearNoOverflow(); // 2021-02-28 00:00:00// plural addYearsNoOverflow() method is also available echo $dt->copy()->subYearsNoOverflow(2); // 2018-02-28 00:00:00// singular subYearNoOverflow() method is also available echo $dt->copy()->addYear(); // 2021-02-28 00:00:00 echo $dt->copy()->subYears(2); // 2018-02-28 00:00:00Carbon::useYearsOverflow(true);$dt = Carbon::createMidnightDate(2020, 2, 29); var_dump(Carbon::shouldOverflowYears()); // bool(true) echo $dt->copy()->addYearWithOverflow(); // 2021-03-01 00:00:00 echo $dt->copy()->subYearsWithOverflow(2); // 2018-03-01 00:00:00echo $dt->copy()->addYearNoOverflow(); // 2021-02-28 00:00:00 echo $dt->copy()->subYearsNoOverflow(2); // 2018-02-28 00:00:00 echo $dt->copy()->addYear(); // 2021-03-01 00:00:00echo $dt->copy()->subYears(2); // 2018-03-01 00:00:00Carbon::resetYearsOverflow();
  • 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')); // $dtOttawa = Carbon::createMidnightDate(2000, 1, 1, 'America/Toronto'); $dtVancouver = Carbon::createMidnightDate(2000, 1, 1, 'America/Vancouver'); echo $dtOttawa->diffInHours($dtVancouver); //echo $dtVancouver->diffInHours($dtOttawa); // echo $dtOttawa->diffInHours($dtVancouver, false); // echo $dtVancouver->diffInHours($dtOttawa, false); // -3 $dt = Carbon::createMidnightDate(2012, 1, 31); echo $dt->diffInDays($dt->copy()->addMonth()); //echo $dt->diffInDays($dt->copy()->subMonth(), false); // -31$dt = Carbon::createMidnightDate(2012, 4, 30); echo $dt->diffInDays($dt->copy()->addMonth()); //echo $dt->diffInDays($dt->copy()->addWeek()); // $dt = Carbon::createMidnightDate(2012, 1, 1);echo $dt->diffInMinutes($dt->copy()->addSeconds(59)); // echo $dt->diffInMinutes($dt->copy()->addSeconds(60)); //echo $dt->diffInMinutes($dt->copy()->addSeconds(119)); // echo $dt->diffInMinutes($dt->copy()->addSeconds(120)); // echo $dt->addSeconds(120)->secondsSinceMidnight(); // $interval = $dt->diffAsCarbonInterval($dt->copy()->subYears(3), false); echo ($interval->invert ? 'minus ' : 'plus ') . $interval->years; // minus 3

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

$date = new DateTime('2014-03-30 00:00:00', new DateTimeZone('Europe/London')); // DST offecho $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 offecho $date->addRealHours(25)->format('H:i'); // 02:00 (DST on) echo $date->diffInRealHours('2014-03-30 00:00:00'); // echo $date->diffInHours('2014-03-30 00:00:00'); // echo $date->diffInRealMinutes('2014-03-30 00:00:00'); // echo $date->diffInMinutes('2014-03-30 00:00:00'); // echo $date->diffInRealSeconds('2014-03-30 00:00:00'); // echo $date->diffInSeconds('2014-03-30 00:00:00'); // 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; // $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; //$date = Carbon::now()->addSeconds(3666);echo $date->diffInSeconds(); // echo $date->diffInMinutes(); // echo $date->diffInHours(); //echo $date->diffInDays(); //$date = Carbon::create(2016, 1, 5, 22, 40, 32); echo $date->secondsSinceMidnight(); //echo $date->secondsUntilEndOfDay(); // $date1 = Carbon::createMidnightDate(2016, 1, 5);$date2 = Carbon::createMidnightDate(2017, 3, 15);echo $date1->diffInDays($date2); // echo $date1->diffInWeekdays($date2); //echo $date1->diffInWeekendDays($date2); // echo $date1->diffInWeeks($date2); // echo $date1->diffInMonths($date2); // echo $date1->diffInYears($date2); //

所有的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),周六返回falsevar_dump($sunday->isWeekend()); // bool(true)var_dump($monday->isWeekend()); // bool(true),周一返回trueCarbon::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 startvar_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天前更容易阅读。这是在大多数日期库中常见的函数,所以我也想在这里添加它。函数的唯一参数是另一个要对其进行diff的Carbon实例,当然,如果没有指定,它默认为now()。

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

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

1小时前

5个月前

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

从现在开始的1小时

从现在开始的5个月

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

前1小时

5个月前

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

1小时后

5个月后

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

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

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

$other实例可以是DateTime、Carbon实例或任何实现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 agoecho 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 nowecho 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_NOW,Carbon::ONE_DAY_WORDS和Carbon::TWO_DAY_WORDS现在只能使用en和fr语言,其他语言将会恢复到以前的行为,直到添加缺失的翻译。

使用管道操作符一次启用/禁用多个选项,例如Let’s talk about the function and usage of Laravel Carbon extension package: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(); // 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:00var_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:59var_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:00echo 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!'; }
  • Serialization

Carbon实例能被序列化的。

$dt = Carbon::create(2012, 12, 25, 20, 30, 00, 'Europe/Moscow'); echo serialize($dt); // O:13:"Carbon\Carbon":3:{s:4:"date";s:26:"2012-12-25 20:30:00.000000";s:13:"timezone_type";i:3;s:8:"timezone";s:13:"Europe/Moscow";} // 等同于:echo $dt->serialize(); // O:13:"Carbon\Carbon":3:{s:4:"date";s:26:"2012-12-25 20:30:00.000000";s:13:"timezone_type";i:3;s:8:"timezone";s:13:"Europe/Moscow";}$dt = 'O:13:"Carbon\Carbon":3:{s:4:"date";s:26:"2012-12-25 20:30:00.000000";s:13:"timezone_type";i:3;s:8:"timezone";s:13:"Europe/Moscow";}'; echo unserialize($dt)->format('Y-m-d\THLet’s talk about the function and usage of Laravel Carbon extension packages.uP T'); // 2012-12-25T20:30:00.000000+04:00 MSK// 等同于:echo Carbon::fromSerialized($dt)->format('Y-m-d\THLet’s talk about the function and usage of Laravel Carbon extension packages.uP T'); // 2012-12-25T20:30:00.000000+04:00 MSK
  • JSON

Carbon实例可以从JSON编码和解码(这些特性只能从PHP 5.4+中获得,参见下面关于PHP 5.3的注释)。

$dt = Carbon::create(2012, 12, 25, 20, 30, 00, 'Europe/Moscow'); echo json_encode($dt); // {"date":"2012-12-25 20:30:00.000000","timezone_type":3,"timezone":"Europe\/Moscow"} $json = '{"date":"2012-12-25 20:30:00.000000","timezone_type":3,"timezone":"Europe\/Moscow"}'; $dt = Carbon::__set_state(json_decode($json, true));echo $dt->format('Y-m-d\THLet’s talk about the function and usage of Laravel Carbon extension packages.uP T'); // 2012-12-25T20:30:00.000000+04:00 MSK

您可以使用serializeUsing()自定义序列化。

$dt = Carbon::create(2012, 12, 25, 20, 30, 00, 'Europe/Moscow'); Carbon::serializeUsing(function ($date) { return $date->getTimestamp(); }); echo json_encode($dt); /* 1356453000 */// Call serializeUsing with null to reset the serializerLet’s talk about the function and usage of Laravel Carbon extension package:serializeUsing(null);

jsonSerialize()方法返回中间通过“json_encode”将其转换为字符串,它还允许您使用PHP 5.3兼容性。

$dt = Carbon::create(2012, 12, 25, 20, 30, 00, 'Europe/Moscow'); echo json_encode($dt->jsonSerialize());// {"date":"2012-12-25 20:30:00.000000","timezone_type":3,"timezone":"Europe\/Moscow"} // This is equivalent to the first json_encode example but works with PHP 5.3. // And it can be used separately: var_dump($dt->jsonSerialize()); // array(3) { ["date"]=> string(26) "2012-12-25 20:30:00.000000" ["timezone_type"]=> int(3)["timezone"]=> string(13) "Europe/Moscow" }
  • Macro

如果您习惯于使用Laravel和对象(如响应或集合),您可能熟悉这个宏概念。Carbon macro()的工作方式与Laravel宏特性相同,它将方法名作为第一个参数,闭包作为第二个参数。这使得闭包操作可以作为一个具有给定名称的方法在所有Carbon实例(也可以作为Carbon static方法)上使用。

在PHP 5.4中,$this可用于闭包中引用当前实例。对于PHP 5.3的兼容性,我们还向闭包添加了一个“$self”属性。例子:

Carbon::macro('diffFromYear', function ($year, $self = null) {// 这个块是为了在独立的Carbon上与PHP版本diffForHumans(Carbon::create($year, 1, 1, 0, 0, 0), false, false, 3); }); echo Carbon::parse('2020-01-12 12:00:00')->diffFromYear(2019); // 1 year 1 week 4 days after

兼容性块允许您确保宏的完全兼容性。一个关于Illuminate\Support\Carbon (Laravel包装类)的宏将不会被定义,正如上面在PHP 5.3 $this中提到的,这个不会被定义。要使宏在任何地方都能工作,只需粘贴这个if语句测试如果它是定义的,而不是$self然后复制它,然后在函数体中使用$self。

不管您是否省略了一些可选参数,只要$self有这个名称,并且是最后一个参数:

Carbon::macro('diffFromYear', function ($year, $absolute = false, $short = false, $parts = 1, $self = null) { // compatibility chunk if (!isset($self) && isset($this)) { $self = $this; }return $self->diffForHumans(Carbon::create($year, 1, 1, 0, 0, 0), $absolute, $short, $parts); });echo Carbon::parse('2020-01-12 12:00:00')->diffFromYear(2019); // 1 year after echo Carbon::parse('2020-01-12 12:00:00')->diffFromYear(2019, true); // 1 year echo Carbon::parse('2020-01-12 12:00:00')->diffFromYear(2019, true, true); // 1yr echo Carbon::parse('2020-01-12 12:00:00')->diffFromYear(2019, true, true, 5); // 1yr 1w 4d 12h

还可以将宏分组到类中,并与mixin()一起应用

Class BeerDayCarbonMixin { public function nextBeerDay() { return function ($self = null) { // compatibility chunk if (!isset($self) && isset($this)) { $self = $this; }return $self->modify('next wednesday'); }; } public function previousBeerDay(){ return function ($self = null) {// compatibility chunkif (!isset($self) && isset($this)) {$self = $this; }return $self->modify('previous wednesday'); }; } }Carbon::mixin(new BeerDayCarbonMixin());$date = Carbon::parse('First saturday of December 2018'); echo $date->previousBeerDay(); // 2018-11-28 00:00:00 echo $date->nextBeerDay(); // 2018-12-05 00:00:00

您可以用hasMacro()检查是否可用宏(包括mixin)

var_dump(Carbon::hasMacro('previousBeerDay')); // bool(true) var_dump(Carbon::hasMacro('diffFromYear')); // bool(true) var_dump(Carbon::hasMacro('dontKnowWhat')); // bool(false)

你猜怎么着?在CarbonInterval和CarbonPeriod类上也可以使用所有的宏方法。

CarbonInterval::macro('twice', function ($self = null) { return $self->times(2); }); echo CarbonInterval::day()->twice()->forHumans(); // 2 days echo CarbonInterval::hours(2)->minutes(15)->twice()->forHumans(true); // 4h 30m CarbonPeriod::macro('countWeekdays', function ($self = null) { return $self->filter('isWeekday')->count(); }); echo CarbonPeriod::create('2017-11-01', '2017-11-30')->countWeekdays(); //echo CarbonPeriod::create('2017-12-01', '2017-12-31')->countWeekdays(); //

以下是社区提出的一些有用的宏:

Carbon::macro('isHoliday', function ($self = null) { // compatibility chunk if (!isset($self) && isset($this)) { $self = $this; } return in_array($self->format('d/m'), [ '25/12', // Christmas '01/01', // New Year// ... ]); }); var_dump(Carbon::createMidnightDate(2012, 12, 25)->isHoliday()); // bool(true)var_dump(Carbon::createMidnightDate(2017, 6, 25)->isHoliday()); // bool(false) var_dump(Carbon::createMidnightDate(2021, 1, 1)->isHoliday()); // bool(true)

检查cmixin/业务日以获得更完整的业务日处理程序。

Class CurrentDaysCarbonMixin { /** * Get the all dates of week . * * [[@return](https://learnku.com/users/31554)](https://learnku.com/users/31554) array */ public static function getCurrentWeekDays() { return function ($self = null) {// compatibility chunkif (!isset($self) && isset($this)) { $self = $this;} $startOfWeek = ($self ?: static::now())->startOfWeek()->subDay(); $weekDays = array(); for ($i = 0; $i addDay()->startOfDay()->copy(); } return $weekDays; }; }/** * Get the all dates of month * */public static function getCurrentMonthDays() {return function ($self = null) {// compatibility chunkif (!isset($self) && isset($this)) { $self = $this; }$startOfMonth = ($self ?: static::now())->startOfMonth()->subDay();$endOfMonth = ($self ?: static::now())->endOfMonth()->format('d'); $monthDays = array(); for ($i = 0; $i addDay()->startOfDay()->copy(); } return $monthDays; }; } } Carbon::mixin(new CurrentDaysCarbonMixin()); function dumpDateList($dates) {echo substr(implode(', ', $dates), 0, 100).'...'; }dumpDateList(Carbon::getCurrentWeekDays()); // 2018-07-02 00:00:00, 2018-07-03 00:00:00, 2018-07-04 00:00:00, 2018-07-05 00:00:00, 2018-07-06 00:00... dumpDateList(Carbon::getCurrentMonthDays()); // 2018-07-01 00:00:00, 2018-07-02 00:00:00, 2018-07-03 00:00:00, 2018-07-04 00:00:00, 2018-07-05 00:00... dumpDateList(Carbon::now()->subMonth()->getCurrentWeekDays()); // 2018-06-04 00:00:00, 2018-06-05 00:00:00, 2018-06-06 00:00:00, 2018-06-07 00:00:00, 2018-06-08 00:00... dumpDateList(Carbon::now()->subMonth()->getCurrentMonthDays()); // 2018-06-01 00:00:00, 2018-06-02 00:00:00, 2018-06-03 00:00:00, 2018-06-04 00:00:00, 2018-06-05 00:00... Carbon::macro('toAtomStringWithNoTimezone', function ($self = null) { // compatibility chunk if (!isset($self) && isset($this)) { $self = $this; } return $self->format('Y-m-d\THLet’s talk about the function and usage of Laravel Carbon extension packages'); }); echo Carbon::parse('2021-06-16 20:08:34')->toAtomStringWithNoTimezone(); // 2021-06-16T20:08:34 *Credit: afrojuju1 (#1063).* Carbon::macro('easterDate', function ($year) { return Carbon::createMidnightDate($year, 3, 21)->addDays(easter_days($year)); }); echo Carbon::easterDate(2015)->format('d/m'); // 05/04 echo Carbon::easterDate(2016)->format('d/m'); // 27/03 echo Carbon::easterDate(2017)->format('d/m'); // 16/04 echo Carbon::easterDate(2018)->format('d/m'); // 01/04 echo Carbon::easterDate(2019)->format('d/m'); // 21/04

查看cmixin/工作日以获得更完整的假日处理程序。

Carbon::macro('range', function ($startDate, $endDate) { return new DatePeriod($startDate, new DateInterval('P1D'), $endDate); }); foreach (Carbon::range(Carbon::createMidnightDate(2019, 3, 28), Carbon::createMidnightDate(2019, 4, 3)) as $date) { echo "$date\n"; } /* 2019-03-28 00:00:00 2019-03-29 00:00:00 2019-03-30 00:00:00 2019-03-31 00:00:00 . 2019-04-01 00:00:00 2019-04-02 00:00:00 */ class UserTimezoneCarbonMixin { public $userTimeZone; /** * Set user timezone, will be used before format function to apply current user timezone * * @param $timezone */ public function setUserTimezone() { $mixin = $this; return function ($timezone) use ($mixin) {$mixin->userTimeZone = $timezone; }; } /** * Returns date formatted according to given format. * * @param string $format . * * * @link http://php.net/manual/en/datetime.format.php */public function tzFormat() { $mixin = $this;return function ($format, $self = null) use ($mixin) { // compatibility chunk if (!isset($self) && isset($this)) { $self = $this; }if (!is_null($mixin->userTimeZone)) { $self->timezone($mixin->userTimeZone); } return $self->format($format); }; } }Carbon::mixin(new UserTimezoneCarbonMixin()); Carbon::setUserTimezone('Europe/Berlin'); echo Carbon::createFromTime(12, 0, 0, 'UTC')->tzFormat('H:i'); // 14:00echo Carbon::createFromTime(15, 0, 0, 'UTC')->tzFormat('H:i'); // 17:00 Carbon::setUserTimezone('America/Toronto'); echo Carbon::createFromTime(12, 0, 0, 'UTC')->tzFormat('H:i'); // 08:00 echo Carbon::createFromTime(15, 0, 0, 'UTC')->tzFormat('H:i'); // 11:00
  • CarbonInterval

CarbonInterval类继承了PHP DateInterval类。

你可以通过以下方式创建实例

echo CarbonInterval::year(); // 1 year echo CarbonInterval::months(3); // 3 monthsecho CarbonInterval::days(3)->seconds(32); // 3 days 32 seconds echo CarbonInterval::weeks(3); // 3 weeks echo CarbonInterval::days(23); // 3 weeks 2 days echo CarbonInterval::create(2, 0, 5, 1, 1, 2, 7); // 2 years 5 weeks 1 day 1 hour 2 minutes 7 seconds

如果您发现自己从另一个库继承了\DateInterval实例,不要害怕!您可以通过一个友好的instance()函数创建一个CarbonInterval实例。

$di = new \DateInterval('P1Y2M'); // 

其他的帮助程序,但是要注意实现提供了帮助程序来处理几周,但是只节省了几天。数周是根据当前实例的总天数计算的。

 echo CarbonInterval::year()->years; // echo CarbonInterval::year()->dayz; // echo CarbonInterval::days(24)->dayz; // echo CarbonInterval::days(24)->daysExcludeWeeks; // echo CarbonInterval::weeks(3)->days(14)->weeks; // 2 weeks; // echo CarbonInterval::minutes(3)->weeksAndDays(2, 5); // 2 weeks 5 days 3 minutesCarbonInterval扩展DateInterval,您可以使用ISO-8601的持续时间格式创建这两种格式: $ci = CarbonInterval::create('P1Y2M3D'); $ci = new CarbonInterval('PT0S');

借助fromString()方法,可以从友好的字符串创建Carbon intervals。

CarbonInterval::fromString('2 minutes 15 seconds'); CarbonInterval::fromString('2m 15s'); // or abbreviated

注意这个月缩写为“mo”以区别于分钟和整个语法不区分大小写。

它还有一个方便的for human(),它被映射为__toString()实现,用于为人类打印间隔。

CarbonInterval::setLocale('fr'); echo CarbonInterval::create(2, 1)->forHumans(); // 2 ans 1 mois echo CarbonInterval::hour()->seconds(3); // 1 heure 3 secondes CarbonInterval::setLocale('en');

如您所见,您可以使用CarbonInterval::setLocale(‘fr’)更改字符串的语言环境。

至于Carbon,您可以使用make方法从其他区间或字符串返回一个新的CarbonInterval实例:

$dateInterval = new DateInterval('P2D');$carbonInterval = CarbonInterval::month(); echo CarbonInterval::make($dateInterval)->forHumans(); // 2 days echo CarbonInterval::make($carbonInterval)->forHumans(); // 1 month echo CarbonInterval::make('PT3H')->forHumans(); // 3 hours echo CarbonInterval::make('1h 15m')->forHumans(); // 1 hour 15 minutes// Pass true to get short format echo CarbonInterval::make('1h 15m')->forHumans(true); // 1h 15m

本机DateInterval分别添加和相乘,因此:

$interval = CarbonInterval::make('7h 55m'); $interval->add(CarbonInterval::make('17h 35m')); $interval->times(3); echo $interval->forHumans(); // 72 hours 270 minutes

从单位到单位的输入中得到纯计算。将分钟级联成小时、小时级联成天等。使用级联方法:

echo $interval->forHumans(); // 72 hours 270 minutes echo $interval->cascade()->forHumans(); // 3 days 4 hours 30 minutes

默认的因素有:

1分钟= 60秒

1小时=60分钟

1天=24小时

1周= 7天

1个月= 4周

1年= 12个月

CarbonIntervals 没有上下文,所以它们不能更精确(没有DST、没有闰年、没有实际的月长或年长)。但是你可以完全定制这些因素。例如处理工作时间日志:

$cascades = CarbonInterval::getCascadeFactors(); // save initial factors CarbonInterval::setCascadeFactors(array( 'minute' => array(60, 'seconds') 'hour' => array(60, 'minutes'), 'day' => array(8, 'hours'), 'week' => array(5, 'days'), // in this example the cascade won't go farther than week unit )); echo CarbonInterval::fromString('20h')->cascade()->forHumans(); // 2 days 4 hours echo CarbonInterval::fromString('10d')->cascade()->forHumans(); // 2 weeks echo CarbonInterval::fromString('3w 18d 53h 159m')->cascade()->forHumans(); // 7 weeks 4 days 7 hours 39 minutes // You can see currently set factors with getFactor: echo CarbonInterval::getFactor('minutes', /* per */ 'hour'); // echo CarbonInterval::getFactor('days', 'week'); // 5 // And common factors can be get with short-cut methods: echo CarbonInterval::getDaysPerWeek(); //echo CarbonInterval::getHoursPerDay(); // echo CarbonInterval::getMinutesPerHours(); //echo CarbonInterval::getSecondsPerMinutes(); // CarbonInterval::setCascadeFactors($cascades); // restore original factors

是否可能将间隔转换为给定的单元(使用提供的级联因子)。

echo CarbonInterval::days(3)->hours(5)->total('hours'); // echo CarbonInterval::days(3)->hours(5)->totalHours; // echo CarbonInterval::months(6)->totalWeeks; //echo CarbonInterval::year()->totalDays; //

您还可以使用spec()获得inverval的ISO 8601规范

echo CarbonInterval::days(3)->hours(5)->spec(); // P3DT5H

也可以从DateInterval对象获取它,因为它是静态助手:

echo CarbonInterval::getDateIntervalSpec(new DateInterval('P3DT6M10S')); // P3DT6M10S

使用compare()和comparedateinterval()方法可以对日期间隔列表进行排序:

$halfDay = CarbonInterval::hours(12); $oneDay = CarbonInterval::day(); $twoDay = CarbonInterval::days(2); echo CarbonInterval::compareDateIntervals($oneDay, $oneDay); // echo $oneDay->compare($oneDay); // echo CarbonInterval::compareDateIntervals($oneDay, $halfDay); // echo $oneDay->compare($halfDay); // echo CarbonInterval::compareDateIntervals($oneDay, $twoDay); // -1 echo $oneDay->compare($twoDay); // -1 $list = array($twoDay, $halfDay, $oneDay);usort($list, array('Carbon\CarbonInterval', 'compareDateIntervals')); echo implode(', ', $list); // 12 hours, 1 day, 2 days

最后,通过使用互补参数调用toPeriod(),可以将一个CarbonInterval实例转换为一个CarbonPeriod实例。

我听到你问什么是CarbonPeriod 实例。哦!完美过渡到下一章。

  • CarbonPeriod

CarbonPeriod是一个友好的DatePeriod版本,具有许多快捷方式。

// Create a new instance: $period = new CarbonPeriod('2018-04-21', '3 days', '2018-04-27'); // Use static constructor: $period = CarbonPeriod::create('2018-04-21', '3 days', '2018-04-27'); // Use the fluent setters: $period = CarbonPeriod::since('2018-04-21')->days(3)->until('2018-04-27'); // Start from a CarbonInterval: $period = CarbonInterval::days(3)->toPeriod('2018-04-21', '2018-04-27');

CarbonPeriod可以通过多种方式构建:

开始日期、结束日期和可选间隔(默认为1天),

起始日期,递归次数和可选区间,

ISO 8601间隔规范。

日期可以是DateTime/Carbon实例,绝对字符串如“2007-10-15 15:00”或相对字符串,例如“next monday”。Interval可以作为DateInterval/CarbonInterval实例、ISO 8601的Interval规范(如“P4D”)或人类可读字符串(如“4 days”)给出。

默认构造函数和create()方法在参数类型和顺序方面都很容易理解,所以如果您想要更精确,建议使用fluent语法。另一方面,您可以将动态值数组传递给createFromArray(),它将使用给定的数组作为参数列表构造一个新实例。

CarbonPeriod实现迭代器接口。它意味着它可以直接传递给foreach循环:

$period = CarbonPeriod::create('2018-04-21', '3 days', '2018-04-27'); foreach ($period as $key => $date) { if ($key) { echo ', '; } echo $date->format('m-d'); }// 04-21, 04-24, 04-27// Here is what happens under the hood:$period->rewind(); // restart the iteration while ($period->valid()) { // check if current item is valid if ($period->key()) { // echo comma if current key is greater than 0 echo ', '; }echo $period->current()->format('m-d'); // echo current date$period->next(); // move to the next item }// 04-21, 04-24, 04-27

参数可以在迭代过程中进行修改:

$period = CarbonPeriod::create('2018-04-29', 7); $dates = array(); foreach ($period as $key => $date) { if ($key === 3) { $period->invert()->start($date); // invert() is an alias for invertDateInterval() } $dates[] = $date->format('m-d'); } echo implode(', ', $dates); // 04-29, 04-30, 05-01, 05-02, 05-01, 04-30, 04-29

和DatePeriod一样,CarbonPeriod也支持ISO 8601时间间隔规范。

请注意,本机日期周期将递归处理为多次重复间隔。因此,在排除开始日期时,它将减少一个结果。CarbonPeriod的自定义过滤器的引入使得知道结果的数量变得更加困难。由于这个原因,我们稍微改变了实现,递归被视为返回日期的总体限制。

// Possible options are: CarbonPeriod::EXCLUDE_START_DATE | CarbonPeriod::EXCLUDE_END_DATE // Default value is 0 which will have the same effect as when no options are given. $period = CarbonPeriod::createFromIso('R4/2012-07-01T00:00:00Z/P7D', CarbonPeriod::EXCLUDE_START_DATE); $dates = array(); foreach ($period as $date) { $dates[] = $date->format('m-d'); } echo implode(', ', $dates); // 07-08, 07-15, 07-22, 07-29

您可以从不同的getter中检索数据:

$period = CarbonPeriod::create('2010-05-06', '2010-05-25', CarbonPeriod::EXCLUDE_START_DATE); $exclude = $period->getOptions() & CarbonPeriod::EXCLUDE_START_DATE; echo $period->getStartDate(); // 2010-05-06 00:00:00 echo $period->getEndDate(); // 2010-05-25 00:00:00 echo $period->getDateInterval(); // 1 dayecho $exclude ? 'exclude' : 'include'; // exclude var_dump($period->isStartExcluded()); // bool(true)var_dump($period->isEndExcluded()); // bool(false)echo $period->toString(); // Every 1 day from 2010-05-06 to 2010-05-25 echo $period; /*implicit toString*/ // Every 1 day from 2010-05-06 to 2010-05-25

附加的getter允许您以数组的形式访问结果:

$period = CarbonPeriod::create('2010-05-11', '2010-05-13'); echo $period->count(); // 3, equivalent to count($period)echo implode(', ', $period->toArray()); // 2010-05-11 00:00:00, 2010-05-12 00:00:00, 2010-05-13 00:00:00 echo $period->first(); // 2010-05-11 00:00:00 echo $period->last(); // 2010-05-13 00:00:00

注意,如果您打算使用上述函数,将toArray()调用的结果存储为变量并使用它是一个好主意,因为每个调用在内部执行一个完整的迭代。

想要更改参数,可以使用setter方法:

$period = CarbonPeriod::create('2010-05-01', '2010-05-14', CarbonPeriod::EXCLUDE_END_DATE); $period->setStartDate('2010-05-11'); echo implode(', ', $period->toArray()); // 2010-05-11 00:00:00, 2010-05-12 00:00:00, 2010-05-13 00:00:00 // Second argument can be optionally used to exclude the date from the results. $period->setStartDate('2010-05-11', false); $period->setEndDate('2010-05-14', true); echo implode(', ', $period->toArray()); // 2010-05-12 00:00:00, 2010-05-13 00:00:00, 2010-05-14 00:00:00 $period->setRecurrences(2); echo implode(', ', $period->toArray()); // 2010-05-12 00:00:00, 2010-05-13 00:00:00 $period->setDateInterval('PT12H'); echo implode(', ', $period->toArray()); // 2010-05-11 12:00:00, 2010-05-12 00:00:00

您可以使用setOptions()更改选项以替换所有选项,但也可以分别更改:

$period = CarbonPeriod::create('2010-05-06', '2010-05-25');var_dump($period->isStartExcluded()); // bool(false) var_dump($period->isEndExcluded()); // bool(false) $period->toggleOptions(CarbonPeriod::EXCLUDE_START_DATE, true); // true, false or nothing to invert the option var_dump($period->isStartExcluded()); // bool(true) var_dump($period->isEndExcluded()); // bool(false) (unchanged) $period->excludeEndDate(); // specify false to include, true or omit to excludevar_dump($period->isStartExcluded()); // bool(true) (unchanged)var_dump($period->isEndExcluded()); // bool(true) $period->excludeStartDate(false); // specify false to include, true or omit to excludevar_dump($period->isStartExcluded()); // bool(false)var_dump($period->isEndExcluded()); // bool(true)

如前所述,根据ISO 8601规范,递归是重复间隔的数倍。因此,本机DatePeriod将根据开始日期的排除而改变返回日期的数量。与此同时,CarbonPeriod在输入和允许自定义过滤器方面更加宽容,将递归作为返回日期的总体限制:

$period = CarbonPeriod::createFromIso('R4/2012-07-01T00:00:00Z/P7D'); $days = array(); foreach ($period as $date) { $days[] = $date->format('d'); } echo $period->getRecurrences(); // echo implode(', ', $days); // 01, 08, 15, 22$days = array();$period->setRecurrences(3)->excludeStartDate();foreach ($period as $date) { $days[] = $date->format('d');} echo $period->getRecurrences(); // echo implode(', ', $days); // 08, 15, 22 $days = array(); $period = CarbonPeriod::recurrences(3)->sinceNow();foreach ($period as $date) {$days[] = $date->format('Y-m-d');} echo implode(', ', $days); // 2018-07-05, 2018-07-06, 2018-07-07

DatePeriod返回的日期可以很容易地过滤。例如,过滤器可以用于跳过某些日期或只在工作日或周末迭代。筛选函数应该返回true以接受日期,返回false以跳过日期,但继续搜索或CarbonPeriod::END_ITERATION以结束迭代。

$period = CarbonPeriod::between('2000-01-01', '2000-01-15'); $weekendFilter = function ($date) { return $date->isWeekend(); }; $period->filter($weekendFilter); $days = array();foreach ($period as $date) { $days[] = $date->format('m-d');} echo implode(', ', $days); // 01-01, 01-02, 01-08, 01-09, 01-15

您还可以跳过循环中的一个或多个值。

$period = CarbonPeriod::between('2000-01-01', '2000-01-10'); $days = array(); foreach ($period as $date) { $day = $date->format('m-d'); $days[] = $day; if ($day === '01-04') { $period->skip(3); } }echo implode(', ', $days); // 01-01, 01-02, 01-03, 01-04, 01-08, 01-09, 01-10

getFilters()允许您在一个时间段内检索所有存储的过滤器。但是要注意递归限制和结束日期将出现在返回的数组中,因为它们作为过滤器存储在内部。

$period = CarbonPeriod::end('2000-01-01')->recurrences(3);var_export($period->getFilters()); /* array ( 0 => array ( 0 => 'Carbon\\CarbonPeriod::filterEndDate', 1 => NULL, ), 1 => array ( 0 => 'Carbon\\CarbonPeriod::filterRecurrences', 1 => NULL, ), ) */

过滤器存储在堆栈中,可以使用一组特殊的方法进行管理:

$period = CarbonPeriod::between('2000-01-01', '2000-01-15'); $weekendFilter = function ($date) { return $date->isWeekend(); }; var_dump($period->hasFilter($weekendFilter)); // bool(false) $period->addFilter($weekendFilter); var_dump($period->hasFilter($weekendFilter)); // bool(true) $period->removeFilter($weekendFilter);var_dump($period->hasFilter($weekendFilter)); // bool(false) // To avoid storing filters as variables you can name your filters:$period->prependFilter(function ($date) { return $date->isWeekend();}, 'weekend');var_dump($period->hasFilter('weekend')); // bool(true) $period->removeFilter('weekend'); var_dump($period->hasFilter('weekend')); // bool(false)

添加过滤器的顺序会对性能和结果产生影响,因此您可以使用addFilter()在堆栈末尾添加过滤器;您可以使用prependFilter()在开始时添加一个。甚至可以使用setfilter()替换所有的过滤器。请注意,您必须保持堆栈的正确格式,并记住关于递归限制和结束日期的内部过滤器。或者,您可以使用resetFilters()方法,然后逐个添加新的过滤器。

例如,当您添加一个限制尝试日期数量的自定义过滤器时,如果您在工作日过滤器之前或之后添加它,那么结果将是不同的。

// Note that you can pass a name of any Carbon method starting with "is", including macros $period = CarbonPeriod::between('2018-05-03', '2018-05-25')->filter('isWeekday'); $attempts = 0;$attemptsFilter = function () use (&$attempts) { return ++$attempts prependFilter($attemptsFilter, 'attempts'); $days = array(); foreach ($period as $date) {$days[] = $date->format('m-d'); } echo implode(', ', $days); // 05-03, 05-04, 05-07 $attempts = 0; $period->removeFilter($attemptsFilter)->addFilter($attemptsFilter, 'attempts');$days = array(); foreach ($period as $date) { $days[] = $date->format('m-d'); } echo implode(', ', $days); // 05-03, 05-04, 05-07, 05-08, 05-09

注意,内置的递归过滤器不是这样工作的。相反,它基于当前键,每个条目只增加一次,无论在找到有效日期之前需要检查多少个日期。如果您将它放在堆栈的开头或末尾,那么这个技巧将使它的工作方式相同。

为了简化CarbonPeriod的构建,添加了一些别名:

// "start", "since", "sinceNow": CarbonPeriod::start('2017-03-10') == CarbonPeriod::create()->setStartDate('2017-03-10'); // Same with optional boolean argument $inclusive to change the option about include/exclude start date: CarbonPeriod::start('2017-03-10', true) == CarbonPeriod::create()->setStartDate('2017-03-10', true); // "end", "until", "untilNow": CarbonPeriod::end('2017-03-20') == CarbonPeriod::create()->setEndDate('2017-03-20'); // Same with optional boolean argument $inclusive to change the option about include/exclude end date: CarbonPeriod::end('2017-03-20', true) == CarbonPeriod::create()->setEndDate('2017-03-20', true); // "dates", "between": CarbonPeriod::dates(..., ...) == CarbonPeriod::create()->setDates(..., ...);// "recurrences", "times":CarbonPeriod::recurrences(5) == CarbonPeriod::create()->setRecurrences(5); // "options":CarbonPeriod::options(...) == CarbonPeriod::create()->setOptions(...);// "toggle":CarbonPeriod::toggle(..., true) == CarbonPeriod::create()->toggleOptions(..., true);// "filter", "push":CarbonPeriod::filter(...) == CarbonPeriod::create()->addFilter(...);// "prepend": CarbonPeriod::prepend(...) == CarbonPeriod::create()->prependFilter(...); // "filters":CarbonPeriod::filters(...) == CarbonPeriod::create()->setFilters(...); // "interval", "each", "every", "step", "stepBy":CarbonPeriod::interval(...) == CarbonPeriod::create()->setDateInterval(...);// "invert": CarbonPeriod::invert() == CarbonPeriod::create()->invertDateInterval();// "year", "months", "month", "weeks", "week", "days", "dayz", "day",// "hours", "hour", "minutes", "minute", "seconds", "second": CarbonPeriod::hours(5) == CarbonPeriod::create()->setDateInterval(new CarbonInterval::hours(5));

可以很容易地将CarbonPeriod转换为人类可读的字符串和ISO 8601规范:

$period = CarbonPeriod::create('2000-01-01 12:00', '3 days 12 hours', '2000-01-15 12:00'); echo $period->toString(); // Every 3 days 12 hours from 2000-01-01 12:00:00 to 2000-01-15 12:00:00 echo $period->toIso8601String(); // 2000-01-01T12:00:00-05:00/P3DT12H/2000-01-15T12:00:00-05:00

The above is the detailed content of Let’s talk about the function and usage of Laravel Carbon extension package. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:learnku.com. If there is any infringement, please contact admin@php.cn delete