聊聊Laravel Carbon擴展包的作用及用法

下面由laravel教程欄目帶大家推薦介紹關于laravel carbon 擴展包,希望對大家有所幫助!

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

  • Introduction

Carbon *繼承了PHP的 *Datetime *類和JsonSerialiable。所以 *Carbon *中沒有涉及到的,但在 *Datetime *和JsonSerializable*中已經實現的方法都是可以使用的。

 class  Carbon  extends  DateTime  implements  JsonSerializable   {   //code here}

Carbon 類聲明在 Carbon 命名空間下,可以通過引入命名空間的方式來代替每次輸入完整的類名。

  <?php use  CarbonCarbon;

要特別留意是否使用了正確的時區,比如的所有差異比較都使用或者系統設定的時區

 $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);  //

以上進行的時間比較是在提供的 Carbon 實例所在的時區下完成的。例如作者所在的時區為 東京時間減13 小時,因此在下午一點后。Carbon::now(‘Asia/Tokyo’)->isToday() 將會返回 false ,如果在調用 now() 時設置時區為東京時區,接下來的操作都使用東京時區是說不過去的。所以在與 *now() *創建的實例進行比較時,默認是在當前時區下完成的。

  • Instantiation

有幾種不同的方法可以創建一個新的Carbon實例。首先是構造函數。它覆蓋父構造函數,您最好閱讀PHP手冊中的第一個參數,并了解它所接受的日期/時間字符串格式。您可能會發現自己很少使用構造函數,而是依賴于顯式靜態方法來提高可讀性

 $carbon =  new  Carbon();  // 等同于 Carbon::now()   $carbon =  new  Carbon('first day of January 2008',  'America/Vancouver');  echo get_class($carbon);  // 'CarbonCarbon'  $carbon =  Carbon::now(-5);//1表示英國倫敦,2表示法國巴黎

您將在上面注意到,timezone(2nd)參數是作為字符串和整數而不是DateTimeZone實例傳遞的。所有DateTimeZone參數都已被增強,因此您可以將一個DateTimeZone實例、字符串或整型偏移量傳遞給GMT,并為您創建時區。在下一個示例中再次顯示了這一點,該示例還介紹了now()函數。

  $nowInLondonTz =  Carbon::now(new DateTimeZone('Europe/London'));    // 或者以字符串形式只傳時區    $nowInLondonTz =  Carbon::now('Europe/London');// 或者在DST期間創建一個時區為+1到GMT的日期,然后傳遞一個整數echo Carbon::now(1)->tzName;  // Europe/London

如果您真的喜歡您的動態方法調用,并且對使用構造函數時所需的額外的行或難看的括號感到失望,那么您將喜歡parse方法。

 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*:PHP 5.4* 之前(new MyClass())->method()會報語法錯誤**, 如果你使用**PHP 5.3, 你需要創建一個變量然后再調用方法:

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

傳遞給Carbon:::parsenew Carbon的字符串可以表示相對時間(next sunday, tomorrow, first day of next month, last year)或絕對時間(first day of December 2008, 2017-01-06)。您可以用Carbon::hasRelativeKeywords()測試一個字符串是否會產生一個相對或絕對日期。

  $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.";   }

為了配合now(),還存在一些靜態的實例化助手來創建廣為人知的實例。這里唯一需要注意的是,today()tomorrow()yesterday()除了按照預期的行為,都接受一個時區參數,每個參數的時間值都設置為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

下一組靜態助手是createXXX() 函數。大多數靜態create函數允許您提供許多個或少量的參數,并為所有其他參數提供默認值。通常默認值是當前日期、時間或時區。更高的值將適當地包裝,但無效的值將拋出一個InvalidArgumentException,并附帶一條信息。錯誤消息從DateTime:::getLastErrors()調用中獲取。

  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() 的默認值是當前時間. createFromTime() 默認值是今天. create()如果不傳參數也是當前時間. 與前面一樣,$tz默認設置為當前時區,否則可以是DateTimeZone實例,也可以是字符串時區值。默認值(模擬底層PHP庫)的唯一特殊情況發生在指定了小時值但沒有分鐘或秒時,它們將默認為0。

注:***createFromTime()** will default the date to today**。小編經實戰代碼打印出來發現**createFromTime()**的默認值也是當前時間,不是今天(時分秒并不是**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()}

創建異常發生在使用負值上,而不是在溢出上,要獲取溢出上的異常,請使用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  (CarbonExceptionsInvalidDateException $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-dTH:i:s.uP T');  // 1969-12-31T19:00:00.001000-05:00 EST   echo Carbon::createFromTimestampMs(1,  'Europe/London')->format('Y-m-dTH:i:s.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');  // <== instance from another API  $carbon =  Carbon::instance($dt);   echo get_class($carbon);  // 'CarbonCarbon'   echo $carbon->toDateTimeString();  // 2008-01-01 00:00:00

關于微秒的簡要說明。PHP DateTime對象允許您設置一個微秒值,但是忽略它的所有日期數學。現在,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.1, microtime 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),只要給定的轉換器繼承了SymfonyComponentTranslationTranslatorInterface。 因此,對格式本地化、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 Carbon擴展包的作用及用法

聊聊Laravel Carbon擴展包的作用及用法

聊聊Laravel Carbon擴展包的作用及用法

注意,如果您使用laravel 5.5+,語言環境將根據當前的最后一個App:setLocale execution自動設置。所以擴散人類將是透明的。您可能仍然需要在某些中間件中運行setlocale以使formatlocalizedworking正確。

  • Testing Aids

測試方法允許您在創建“現在”實例時設置要返回的Carbon實例(real或mock)。所提供的實例將在以下條件下具體返回:

對static now()方法的調用,例如聊聊Laravel Carbon擴展包的作用及用法: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 h:i:s 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 h:i:s A'));  // bool(true)

您還可以設置默認的__toString()格式(默認為Y-m-d H聊聊Laravel Carbon擴展包的作用及用法s),這是在發生類型雜耍時使用的格式。

Carbon::setToStringFormat('jS o F, Y g:i:s 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 H:i:s.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 < $second);  // bool(true)   var_dump($first->lte($second));  // bool(true)   var_dump($first->lessThanOrEqualTo($second));  // bool(true)   var_dump($first <= $second);  // bool(true)

這些方法使用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語言,其他語言將會恢復到以前的行為,直到添加缺失的翻譯。

使用管道操作符一次啟用/禁用多個選項,例如聊聊Laravel 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();  //   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:"CarbonCarbon":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:"CarbonCarbon":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:"CarbonCarbon":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-dTH:i:s.uP T');  // 2012-12-25T20:30:00.000000+04:00 MSK// 等同于:echo Carbon::fromSerialized($dt)->format('Y-m-dTH:i:s.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-dTH:i:s.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 serializer:Carbon::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版本< 5.4和Laravel兼容if  (!isset($self)  && isset($this))  {    $self = $this;    }    //兼容性塊的結束。    return $self->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

兼容性塊允許您確保宏的完全兼容性。一個關于IlluminateSupportCarbon (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 <  static::DAYS_PER_WEEK; $i++)  {   $weekDays[]  = $startOfWeek->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 < $endOfMonth; $i++)   {   $monthDays[]  = $startOfMonth->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-dTH:i:s');    });    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 ";    }   /*    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類。

 <?php class  CarbonInterval  extends DateInterval    {   // code here   }

你可以通過以下方式創建實例

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');  // <== instance from another API$ci =  CarbonInterval::instance($di);echo get_class($ci);  // 'CarbonCarbonInterval'   echo $ci;  // 1 year 2 months

其他的幫助程序,但是要注意實現提供了幫助程序來處理幾周,但是只節省了幾天。數周是根據當前實例的總天數計算的。

  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  <-- days setter overwrites the current value    echo CarbonInterval::weeks(3)->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('CarbonCarbonInterval',  '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 => 'CarbonCarbonPeriod::filterEndDate',    1 => NULL,    ),   1 =>   array (   0 => 'CarbonCarbonPeriod::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 <=  5  ?  true  :  CarbonPeriod::END_ITERATION;    };    $period->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 END
喜歡就支持一下吧
點贊5 分享