PHP中時間處理類Carbon的用法詳解
1.Introduction
Carbon 是php的日期處理類庫(A simple PHP API extension for DateTime.)。
Carbon 繼承了PHP的 Datetime 類,所以 Carbon 中沒有涉及到的,但在 Datetime 中已經(jīng)實現(xiàn)的方法都是可以使用的。
看代碼
<?php namespace Carbon; class Carbon extends \DateTime { // code here }
Carbon 類聲明在 Carbon 命名空間下,可以通過引入命名空間的方式來代替每次輸入完整的類名。
<?php use Carbon\Carbon;
Note:如果在使用 Carbon 時,沒有專門設(shè)置時區(qū)的話,默認(rèn)使用 America/Toronto 的時區(qū)。
要特別留意是否使用了正確的時區(qū),比如 Carbon 的所有差異比較都使用 UTC 或者系統(tǒng)設(shè)定的時區(qū)。
<?php $dtToronto = Carbon::createFromDate(2012, 1, 1, 'America/Toronto'); $dtVancouver = Carbon::createFromDate(2012, 1, 1, 'America/Vancouver'); echo $dtVancouver->diffInHours($dtToronto); // 3
以上進(jìn)行的時間比較是在提供的 Carbon 實例所在的時區(qū)下完成的。例如作者所在的時區(qū)為 東京時間減13 小時,因此在下午一點后。Carbon::now(‘Asia/Tokyo’)->isToday() 將會返回 false ,如果在調(diào)用 now() 時設(shè)置時區(qū)為東京時區(qū),接下來的操作都使用東京時區(qū)是說不過去的。所以在與 now() 創(chuàng)建的實例進(jìn)行比較時,默認(rèn)是在當(dāng)前時區(qū)下完成的。
2.Instantiation
有好幾種方式可以創(chuàng)建 Carbon 的實例,但是大家應(yīng)該更傾向于通過這種語義化的靜態(tài)方法來實現(xiàn)。
<?php $carbon = new Carbon(); // equivalent to Carbon::now() $carbon = new Carbon('first day of January 2008', 'America/Vancouver'); echo get_class($carbon); // 'Carbon\Carbon' $carbon = Carbon::now(-5);
值得注意的是,Carbon 構(gòu)造器的第二個參數(shù)被增強(qiáng)到了不僅限于\DateTimeZone 實例,還可以是 String、Integer (表示相對于GMT的偏移值)。舉個例子來說明下 now() 方法。
<?php $now = Carbon::now(); $nowInLondonTz = Carbon::now(new DateTimeZone('Europe/London')); // or just pass the timezone as a string $nowInLondonTz = Carbon::now('Europe/London'); // or to create a date with a timezone of +1 to GMT during DST then just pass an integer echo Carbon::now(1)->tzName; // Europe/London
你將會喜歡上用 parse() 方法來代替原有繁瑣的構(gòu)造方式
<?php 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
類似 now() 這樣直接返回 Carbon 實例的方法還有 today(), tomorrow(),yesterday(),他們都接受一個 timezone 類型的參數(shù),最后得到的結(jié)果時間部分都是 00:00:00
<?php $now = Carbon::now(); echo $now; // 2016-06-24 15:18:34 $today = Carbon::today(); echo $today; // 2016-06-24 00:00:00 $tomorrow = Carbon::tomorrow('Europe/London'); echo $tomorrow; // 2016-06-25 00:00:00 $yesterday = Carbon::yesterday(); echo $yesterday; // 2016-06-23 00:00:00
下面是一些其他的 creatXXX() 形式的靜態(tài)方法。絕大多數(shù)靜態(tài)方法的參數(shù)是可傳可不傳的,如果不傳的話會使用方法預(yù)設(shè)的默認(rèn)值,這些預(yù)設(shè)值一般都是針對當(dāng)前日期、時間、時區(qū)的。如果為傳遞某個必要參數(shù),會拋出一個 InvalidArgumentException 類型的異常,用 DateTime::getLastErrors() 方法可以得到異常的詳細(xì)信息。
<?php Carbon::createFromDate($year, $month, $day, $tz); Carbon::createFromTime($hour, $minute, $second, $tz); Carbon::create($year, $month, $day, $hour, $minute, $second, $tz);
createFromDate() 默認(rèn)返回當(dāng)前時間,createFromTime()日期默認(rèn)是今天。crete() 所有為 null 的參數(shù)都將默認(rèn)為當(dāng)前對應(yīng)的時間。同樣,時區(qū)也默認(rèn)是當(dāng)前時區(qū)。如果只設(shè)置了小時數(shù)沒有設(shè)置分秒那么分秒默認(rèn)是 0
<?php $xmasThisYear = Carbon::createFromDate(null, 12, 25); // Year defaults to current year $Y2K = Carbon::create(2000, 1, 1, 0, 0, 0); $alsoY2K = Carbon::create(1999, 12, 31, 24); $noonLondonTz = Carbon::createFromTime(12, 0, 0, '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(); }
<?php Carbon::createFromFormat($format, $time, $tz);
createFromFormat() 與php的DateTime::createFromFormat。不同之處是 $dt 參數(shù)可以是 DateTImeZone 的實例或者一個時區(qū)的字符串。并且可以會返回參數(shù)異常的提示。從createXX()的源碼可以看出,他們都調(diào)用了createFromFormat()方法。
<?php echo Carbon::createFromFormat('Y-m-d H', '1975-05-21 22')->toDateTimeString(); // 1975-05-21 22:00:00
最后提到的這兩個create方法都是處理Unix時間戳的。第一個將會返回一個等于預(yù)期時間戳的 Carbon 實例,時區(qū)可以設(shè)置也可以選用默認(rèn)值。第二個方法,createFromTimestampUTC() 與第一個不同的是時區(qū)將始終是 UTC(GMT) .第一個方法的第二個示例,只是為了讓這個函數(shù)的用法展現(xiàn)的更加明確。Negative timestamps are also allowed.
<?php 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:59
copy() 方法可以copy一個已經(jīng)存在的 Carbon 實例。對copy生成實例進(jìn)行修改并不會影響被copy對象的本身。
<?php $dt = Carbon::now(); echo $dt->diffInYears($dt->copy()->addYear()); // 1 // $dt was unchanged and still holds the value of Carbon:now()
最后,當(dāng)你正在使用的 DateTime 實例是通過實例化其他繼承了 \DateTime 庫而得到的,別怕!通過下邊的方式仍然可以極其友好創(chuàng)建 Carbon 實例。
<?php $dt = new \DateTime('first day of January 2008'); // <== instance from another API $carbon = Carbon::instance($dt); echo get_class($carbon); // 'Carbon\Carbon' echo $carbon->toDateTimeString(); // 2008-01-01 00:00:00
關(guān)于毫秒的一些處理。php自帶的 DateTime 類也可以設(shè)置毫秒,但是在進(jìn)行日期的數(shù)學(xué)預(yù)算時并不會考慮毫秒。從 Carbon 1.12.0版本起,實例化、copy也能像 format() 方法一樣支持毫秒(PHP默認(rèn)的只有 Datetime::format() 支持毫秒)。
<?php $dt = Carbon::parse('1975-05-21 22:23:00.123456'); echo $dt->micro; // 123456 echo $dt->copy()->micro; // 123456
獲取PHP支持的有效時間取值范圍:最早時間、最晚時間
<?php echo Carbon::maxValue(); // '2038-01-18 22:14:07' echo Carbon::minValue(); // '1901-12-13 15:45:52'
3.Localization
Carbon中,formatLocalized() 方法通過調(diào)用 strftime() 方法,彌補(bǔ)了php底層的 DateTime 類不支持區(qū)域化設(shè)置的缺陷。如果你已經(jīng)通過使用setlocale() 方法設(shè)置過當(dāng)前區(qū)域,formatLocalized($format) 方法將會按照設(shè)置的區(qū)域格式進(jìn)行返回。
<?php setlocale(LC_TIME, 'German'); echo $dt->formatLocalized('%A %d %B %Y'); // Mittwoch 21 Mai 1975 setlocale(LC_TIME, ''); echo $dt->formatLocalized('%A %d %B %Y'); // Wednesday 21 May 1975
diffForHumans() 的結(jié)果也會被轉(zhuǎn)化成區(qū)域語言。通過Carbon::setLocale() 方法可以設(shè)置 Carbon 的區(qū)域語言。
<?php Carbon::setLocale('de'); echo Carbon::now()->addYear()->diffForHumans(); // in 1 Jahr Carbon::setLocale('en');
注意:如果在linux系統(tǒng)中轉(zhuǎn)換出現(xiàn)了問題,請仔細(xì)檢查安裝在本地或生產(chǎn)系統(tǒng)中語言環(huán)境
locale -a 列舉出所有可用的語言環(huán)境
sudo locale-gen zh_CN.utf8 安裝新的語言環(huán)境
sudo dpkg-reconfigure locales 配置啟用新的語言環(huán)境,并重啟
4.Testing Aids()
通過測試方法可以得到一個模擬或真實的 Carbon 實例。只有在以下情況下,主動提供的 Carbon 實例才會被特殊處理:
- 調(diào)用靜態(tài)方法 now(),例如:Carbon::now()
- 傳給 construct 或 parse() 方法的是 null (或空字符串),例如:new Carbon(null)
- 當(dāng)傳給 construct 或 parse()的是字符串 now,例如:new Carbon(‘now’)
$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::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 var_dump(Carbon::hasTestNow()); // bool(true) Carbon::setTestNow(); // clear the mock var_dump(Carbon::hasTestNow()); // bool(false) echo Carbon::now();
有用的例子:
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(); // 100 Carbon::setTestNow(Carbon::parse('first day of December 2000')); echo $product->getPrice(); // 200 Carbon::setTestNow(Carbon::parse('first day of May 2000')); echo $product->getPrice(); // 100 Carbon::setTestNow();
一些相關(guān)的用法也可以得到一個模擬的 now 實例,返回相應(yīng)的模擬數(shù)據(jù)。
$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();
以下是當(dāng)前支持的時間轉(zhuǎn)換字
- this
- last
- next
- tomorrow
- yesterday
- +
- -
- first
- ago
值得注意的是像 next() , previous() 和 modify() 方法等相關(guān)的修改會把日期的時間部分設(shè)置成 00:00:00 。
5.Getters
獲取器通過PHP的 __get() 方式實現(xiàn)??梢灾苯油ㄟ^一下方式直接獲取到屬性的值。
$dt = Carbon::parse('2012-9-5 23:26:11.123789'); // These getters specifically return integers, ie intval() var_dump($dt->year); // int(2012) var_dump($dt->month); // int(9) 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) var_dump($dt->dayOfWeek); // int(3) var_dump($dt->dayOfYear); // int(248) var_dump($dt->weekOfMonth); // int(1) var_dump($dt->weekOfYear); // int(36) var_dump($dt->daysInMonth); // int(30) var_dump($dt->timestamp); // int(1346901971) var_dump(Carbon::createFromDate(1975, 5, 21)->age); // int(41) calculated vs now in the same tz var_dump($dt->quarter); // int(3) // 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 timezone var_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 instance echo 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
6.Setters
Setters 通過PHP的 __set() 方法實現(xiàn)。值得注意的是,通過這種方式設(shè)置時間戳?xí)r,時區(qū)不會相對于時間戳而改變。如果需要改變時區(qū)的話,需要針對時區(qū)單獨(dú)設(shè)置。
$dt = Carbon::now(); $dt->year = 1975; $dt->month = 13; // would force year++ and month = 1 $dt->month = 5; $dt->day = 21; $dt->hour = 22; $dt->minute = 32; $dt->second = 5; $dt->timestamp = 169957925; // This will not change the timezone // Set the timezone via DateTimeZone instance or string $dt->timezone = new DateTimeZone('Europe/London'); $dt->timezone = 'Europe/London'; $dt->tz = 'Europe/London';
7.Fluent Setters
此處 Setters 方法的參數(shù)是必選參數(shù),Carbon 提供了更多種設(shè)置方式可供使用。值得注意的是,所有對于時區(qū)的修改都會影響整個到 Carbon 實例。對時間戳進(jìn)行修改時不會自動轉(zhuǎn)換到時間戳對應(yīng)的時區(qū)。
$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->setDateTime(1975, 5, 21, 22, 32, 5)->toDateTimeString(); $dt->timestamp(169957925)->timezone('Europe/London'); $dt->tz('America/Toronto')->setTimezone('America/Vancouver');
8.IsSet
當(dāng)嘗試調(diào)用 Carbon 實例的屬性時,會首先檢查該屬性是否存在,存在返回 true,不存在返回 false。
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)
以上就是PHP中時間處理類Carbon的用法詳解的詳細(xì)內(nèi)容,更多關(guān)于PHP時間處理類Carbon的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
關(guān)于session在PHP5的配置文件中的詳細(xì)設(shè)置參數(shù)說明
關(guān)于session在PHP5的配置文件中的詳細(xì)設(shè)置參數(shù)說明,需要的朋友可以參考下。2011-04-04php連接Access數(shù)據(jù)庫錯誤及解決方法
前二天把一個asp+access的網(wǎng)站改成php+access的,在連連數(shù)據(jù)庫時可真讓我狠狠的郁悶了一把,通過百度了大量的相關(guān)文章終于解決了2013-06-06安裝PHP可能遇到的問題“無法載入mysql擴(kuò)展” 的解決方法
安裝PHP可能遇到的問題“無法載入mysql擴(kuò)展” 的解決方法...2007-04-04Warning:?require():?open_basedir?restriction?in?effect,
在linux服務(wù)器部署thinkphp5的時候PHP報了Warning:?require():?open_basedir?restriction?in?effect這個錯誤,是因為網(wǎng)站目錄配置錯誤,PHP不能引入其授權(quán)目錄上級及其以上的文件。下面詳細(xì)講解如何處理這個問題,需要的朋友可以參考下2022-11-11