PHP中时间处理类Carbon的用法详解
1.Introduction
Carbon 是php的日期处理类库(A simple PHP API extension for DateTime.)。
Carbon 继承了PHP的 Datetime 类,所以 Carbon 中没有涉及到的,但在 Datetime 中已经实现的方法都是可以使用的。
看代码
?1 2 3 4 5 6 7 | <?php namespace Carbon; class Carbon extends \DateTime { // code here } |
Carbon 类声明在 Carbon 命名空间下,可以通过引入命名空间的方式来代替每次输入完整的类名。
?1 2 | <?php use Carbon\Carbon; |
Note:如果在使用 Carbon 时,没有专门设置时区的话,默认使用 America/Toronto 的时区。
要特别留意是否使用了正确的时区,比如 Carbon 的所有差异比较都使用 UTC 或者系统设定的时区。
?1 2 3 4 5 | <?php $dtToronto = Carbon::createFromDate(2012, 1, 1, 'America/Toronto' ); $dtVancouver = Carbon::createFromDate(2012, 1, 1, 'America/Vancouver' ); echo $dtVancouver ->diffInHours( $dtToronto ); // 3 |
以上进行的时间比较是在提供的 Carbon 实例所在的时区下完成的。例如作者所在的时区为 东京时间减13 小时,因此在下午一点后。Carbon::now(‘Asia/Tokyo’)->isToday() 将会返回 false ,如果在调用 now() 时设置时区为东京时区,接下来的操作都使用东京时区是说不过去的。所以在与 now() 创建的实例进行比较时,默认是在当前时区下完成的。
2.Instantiation
有好几种方式可以创建 Carbon 的实例,但是大家应该更倾向于通过这种语义化的静态方法来实现。
?1 2 3 4 5 | <?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 构造器的第二个参数被增强到了不仅限于\DateTimeZone 实例,还可以是 String、Integer (表示相对于GMT的偏移值)。举个例子来说明下 now() 方法。
?1 2 3 4 5 6 7 8 9 10 | <?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() 方法来代替原有繁琐的构造方式
?1 2 3 | <?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 类型的参数,最后得到的结果时间部分都是 00:00:00
?1 2 3 4 5 6 7 8 9 | <?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() 形式的静态方法。绝大多数静态方法的参数是可传可不传的,如果不传的话会使用方法预设的默认值,这些预设值一般都是针对当前日期、时间、时区的。如果为传递某个必要参数,会抛出一个 InvalidArgumentException 类型的异常,用 DateTime::getLastErrors() 方法可以得到异常的详细信息。
?1 2 3 4 | <?php Carbon::createFromDate( $year , $month , $day , $tz ); Carbon::createFromTime( $hour , $minute , $second , $tz ); Carbon::create( $year , $month , $day , $hour , $minute , $second , $tz ); |
createFromDate() 默认返回当前时间,createFromTime()日期默认是今天。crete() 所有为 null 的参数都将默认为当前对应的时间。同样,时区也默认是当前时区。如果只设置了小时数没有设置分秒那么分秒默认是 0
?1 2 3 4 5 6 7 8 9 10 11 12 | <?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(); } |
1 2 | <?php Carbon::createFromFormat( $format , $time , $tz ); |
createFromFormat() 与php的DateTime::createFromFormat。不同之处是 $dt 参数可以是 DateTImeZone 的实例或者一个时区的字符串。并且可以会返回参数异常的提示。从createXX()的源码可以看出,他们都调用了createFromFormat()方法。
?1 2 | <?php echo Carbon::createFromFormat( 'Y-m-d H' , '1975-05-21 22' )->toDateTimeString(); // 1975-05-21 22:00:00 |
最后提到的这两个create方法都是处理Unix时间戳的。第一个将会返回一个等于预期时间戳的 Carbon 实例,时区可以设置也可以选用默认值。第二个方法,createFromTimestampUTC() 与第一个不同的是时区将始终是 UTC(GMT) .第一个方法的第二个示例,只是为了让这个函数的用法展现的更加明确。Negative timestamps are also allowed.
?1 2 3 4 | <?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一个已经存在的 Carbon 实例。对copy生成实例进行修改并不会影响被copy对象的本身。
?1 2 3 4 5 | <?php $dt = Carbon::now(); echo $dt ->diffInYears( $dt -> copy ()->addYear()); // 1 // $dt was unchanged and still holds the value of Carbon:now() |
最后,当你正在使用的 DateTime 实例是通过实例化其他继承了 \DateTime 库而得到的,别怕!通过下边的方式仍然可以极其友好创建 Carbon 实例。
?1 2 3 4 5 | <?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 |
关于毫秒的一些处理。php自带的 DateTime 类也可以设置毫秒,但是在进行日期的数学预算时并不会考虑毫秒。从 Carbon 1.12.0版本起,实例化、copy也能像 format() 方法一样支持毫秒(PHP默认的只有 Datetime::format() 支持毫秒)。
?1 2 3 4 | <?php $dt = Carbon::parse( '1975-05-21 22:23:00.123456' ); echo $dt ->micro; // 123456 echo $dt -> copy ()->micro; // 123456 |
获取PHP支持的有效时间取值范围:最早时间、最晚时间
?1 2 3 | <?php echo Carbon::maxValue(); // '2038-01-18 22:14:07' echo Carbon::minValue(); // '1901-12-13 15:45:52' |
3.Localization
Carbon中,formatLocalized() 方法通过调用 strftime() 方法,弥补了php底层的 DateTime 类不支持区域化设置的缺陷。如果你已经通过使用setlocale() 方法设置过当前区域,formatLocalized($format) 方法将会按照设置的区域格式进行返回。
?1 2 3 4 5 | <?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() 的结果也会被转化成区域语言。通过Carbon::setLocale() 方法可以设置 Carbon 的区域语言。
?1 2 3 4 5 | <?php Carbon::setLocale( 'de' ); echo Carbon::now()->addYear()->diffForHumans(); // in 1 Jahr Carbon::setLocale( 'en' ); |
注意:如果在linux系统中转换出现了问题,请仔细检查安装在本地或生产系统中语言环境
locale -a 列举出所有可用的语言环境
sudo locale-gen zh_CN.utf8 安装新的语言环境
sudo dpkg-reconfigure locales 配置启用新的语言环境,并重启
4.Testing Aids()
通过测试方法可以得到一个模拟或真实的 Carbon 实例。只有在以下情况下,主动提供的 Carbon 实例才会被特殊处理:
- 调用静态方法 now(),例如:Carbon::now()
- 传给 construct 或 parse() 方法的是 null (或空字符串),例如:new Carbon(null)
- 当传给 construct 或 parse()的是字符串 now,例如:new Carbon(‘now’)
1 2 3 4 5 6 7 8 9 10 11 | $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(); |
有用的例子:
?1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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(); |
一些相关的用法也可以得到一个模拟的 now 实例,返回相应的模拟数据。
?1 2 3 4 5 6 7 8 | $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(); |
以下是当前支持的时间转换字
- this
- last
- next
- tomorrow
- yesterday
- +
- -
- first
- ago
值得注意的是像 next() , previous() 和 modify() 方法等相关的修改会把日期的时间部分设置成 00:00:00 。
5.Getters
获取器通过PHP的 __get() 方式实现。可以直接通过一下方式直接获取到属性的值。
?1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | $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() 方法实现。值得注意的是,通过这种方式设置时间戳时,时区不会相对于时间戳而改变。如果需要改变时区的话,需要针对时区单独设置。
?1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | $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 方法的参数是必选参数,Carbon 提供了更多种设置方式可供使用。值得注意的是,所有对于时区的修改都会影响整个到 Carbon 实例。对时间戳进行修改时不会自动转换到时间戳对应的时区。
?1 2 3 4 5 6 7 8 9 | $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
当尝试调用 Carbon 实例的属性时,会首先检查该属性是否存在,存在返回 true,不存在返回 false。
?1 2 3 4 | 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的用法详解的详细内容,更多关于PHP时间处理类Carbon的资料请关注服务器之家其它相关文章!
原文链接:https://mp.weixin.qq.com/s/RkhJWv9KEpmsS9f6ooylAA
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。