PHP中时间处理类Carbon的用法详解

吾爱主题 阅读:120 2022-11-09 15:39:00 评论:0

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.作者投稿可能会经我们编辑修改或补充。

【腾讯云】云服务器产品特惠热卖中
搜索
标签列表
    关注我们

    了解等多精彩内容