共计 5696 个字符,预计需要花费 15 分钟才能阅读完成。
上回文章中咱们介绍了三个工夫日期相干的对象,不过它们的出镜频率并不是特地地高。明天学习的对象虽说可能不少人应用过,然而它的出镜频率也是非常低的。它们其实就是咱们十分罕用的那些面向过程的日期函数的面向对象式的封装。但,酒香不怕巷子深,好货色还是值得咱们去深刻的学习钻研的,当然更好的状况是能够在面对不同的业务场景时灵便地应用这些对象才是咱们学习的基本目标。
DateTime 对象
没错,明天咱们学习的就是 DateTime 对象。从名字就能够看出,它就是一个规范的日期工夫类。
$date = new DateTime('now', new DateTimeZone('Asia/Tokyo'));
echo $date->format('Y-m-d H:i:sP'), PHP_EOL;
// 2020-09-29 09:47:57+09:00
$date = new DateTime();
echo $date->format('Y-m-d H:i:sP'), PHP_EOL;
// 2020-09-29 10:22:45+08:00
咱们能够为它指定工夫,指定时区。在第一行的测试代码中,咱们指定了工夫为 now,也就是以后工夫,这里还能够传递字符串的工夫格局给这个参数。第二个参数就是指定时区,咱们传递了日本的区域时区,所以它的 P 格式化后输出的就是 +9:00,也就是东九区,比咱们的北京工夫东八区早 1 个小时。DateTime 实例化时不传递任何参数的话,默认状况就是以后的工夫以及 php.ini 中指定的时区。
还能够通过其它的形式来创立 DateTime 对象。
$date = DateTime::createFromFormat('Y 年 m 月 j 日 H 时 i 分 s 秒', '2020 年 09 月 22 日 22 时 13 分 35 秒');
echo $date->format('Y-m-d H:i:sP'), PHP_EOL;
// 2020-09-22 22:13:35+08:00
$date = DateTime::createFromImmutable(new DateTimeImmutable("2020-09-22 11:45"));
echo $date->format('Y-m-d H:i:sP'), PHP_EOL;
// 2020-09-22 11:45:00+08:00
createFromFormat() 静态方法是依照指定的格局来生成 DateTime 工夫对象。在这里咱们指定的格局是咱们中文罕用的格局,前面紧跟着具体的日期。createFromImmutable() 则是通过 DateTimeImmutable 对象来创立 DateTime 对象。
DateTime 与 DateTimeImmutable
DateTimeImmutable 是日期示意对象,它与 DateTime 根本没什么区别,办法、属性都和 DateTime 是一样的,惟一的区别就是在前面介绍的操作方法中它不会批改本身,而是返回一个新的对象。在 DateTimeImmutable 对象中也有一个静态方法 createFromMutable() 是从 DateTime 对象创立一个 DateTimeImmutable 对象。
$di = new DateTimeImmutable("2020-09-22 11:45");
var_dump($di);
// object(DateTimeImmutable)#1 (3) {// ["date"]=>
// string(26) "2020-09-22 11:45:00.000000"
// ["timezone_type"]=>
// int(3)
// ["timezone"]=>
// string(13) "Asia/Shanghai"
// }
var_dump($di->add(new DateInterval('P3D')));
// object(DateTimeImmutable)#4 (3) {// ["date"]=>
// string(26) "2020-09-25 11:45:00.000000"
// ["timezone_type"]=>
// int(3)
// ["timezone"]=>
// string(13) "Asia/Shanghai"
// }
$date = new DateTime("2020-09-22 11:45");
var_dump($date);
// object(DateTime)#4 (3) {// ["date"]=>
// string(26) "2020-09-22 11:45:00.000000"
// ["timezone_type"]=>
// int(3)
// ["timezone"]=>
// string(13) "Asia/Shanghai"
// }
var_dump($date->add(new DateInterval('P3D')));
// object(DateTime)#4 (3) {// ["date"]=>
// string(26) "2020-09-25 11:45:00.000000"
// ["timezone_type"]=>
// int(3)
// ["timezone"]=>
// string(13) "Asia/Shanghai"
// }
从下面的测试代码就能够看出 DateTimeImmutable 在应用 add() 办法之后返回的对象是一个新的对象,object(DateTimeImmutable)#1 (3) 变成了 object(DateTimeImmutable)#4 (3)。而 DateTime 则是在本身进行的批改,对象标识符并没有产生扭转。
DateTime 操作
上文中 add() 办法就是减少日期的办法,它须要一个 DateInterval 工夫距离对象作为参数,而后就会给对应的日期减少指定的工夫距离。
$date->add(new DateInterval('P3D'));
echo $date->format('Y-m-d H:i:sP'), PHP_EOL;
// 2020-09-29 09:22:45+08:00
这里咱们就是为以后的工夫减少了 3 天,对于 DateInterval 对象的内容能够查阅上篇文章中的介绍。当然,除了减少之外,还有缩小以及批改的办法。
$date->sub(new DateInterval('P3D'));
echo $date->format('Y-m-d H:i:sP'), PHP_EOL;
// 2020-10-02 09:22:45+08:00
$date->modify('+5 day');
echo $date->format('Y-m-d H:i:sP'), PHP_EOL;
// 2020-10-04 09:22:45+08:00
$date->modify('-4 day -4 hours');
echo $date->format('Y-m-d H:i:sP'), PHP_EOL;
// 2020-09-30 05:22:45+08:00
sub() 办法就是给一个工夫对象缩小指定的工夫距离,而 modify() 办法就是依据参数来间接批改日期,比方咱们这里测试了减少 5 天和缩小 4 天 4 小时的操作。
$origin = new DateTime('now');
$target = new DateTime('2020-09-11');
$interval = $origin->diff($target);
echo $interval->format('%a days'), PHP_EOL;
echo $interval->format('%R%a days'), PHP_EOL;
// 18 days
// -18 days
diff() 办法就是返回两个日期之间的差值,置信这个办法不少人应用过它的面向过程的函数,也就是 date_diff() 函数,绝对于其它办法来说,它的出镜率就十分高了。%R 返回的是符号位,如果是负号就是比指定的日期少了多少工夫距离。
设置日期工夫
除了操作日期工夫之外,咱们在实例化 DateTime 对象之后,也能够为它从新指定日期。
$date = new DateTime();
$date->setDate(2020, 9, 25);
echo $date->format('Y-m-d H:i:sP'), PHP_EOL;
// 2020-09-25 09:22:45+08:00
$date->setISODate(2020, 9, 25);
echo $date->format('Y-m-d H:i:sP'), PHP_EOL;
// 2020-03-19 09:22:45+08:00
$date->setTime(14, 55);
echo $date->format('Y-m-d H:i:sP'), PHP_EOL;
// 2020-10-03 14:55:00+08:00
$date->setDate(2020, 9, 33);
echo $date->format('Y-m-d H:i:sP'), PHP_EOL;
// 2020-10-03 09:22:45+08:00
$date->setTime(14, 63);
echo $date->format('Y-m-d H:i:sP'), PHP_EOL;
// 2020-10-03 15:03:00+08:00
setDate() 办法就是指定日期,setTime() 办法是指定工夫,它们是离开的两个办法哦。setISODate() 设置的是 ISO 规范工夫,这又是另一套日期工夫标准了,感兴趣的敌人能够自行查阅下相干的常识,这里就不多做赘述了。如果咱们设置的日期不是一个失常的日期格局,比方咱们在测试代码中设置了 9 月 33 号 这个日期,那么它会主动向后延,输入的后果就是 10 月 3 号 这个日期,包含 setTime() 办法也是能够这样顺延的。其实所有日期相干的对象、办法、函数都有这样的能力。
另外,咱们还能够通过工夫戳进行 DateTime 对象的日期工夫设置。同理,时区也是能够独自设置的。
$date->setTimestamp(time()-84400);
echo $date->format('U = Y-m-d H:i:s'), PHP_EOL;
// 1601258165 = 2020-09-28 09:56:05
$date->setTimezone(new DateTimeZone('Asia/Tokyo'));
echo $date->format('U = Y-m-d H:i:s'), PHP_EOL;
// 1601258165 = 2020-09-28 10:56:05
获取属性及错误信息
既然 DateTime 对象有这么多设置的货色,那么绝对应的它也有一些属性是能够让咱们获取的。
echo $date->getOffset(), PHP_EOL;
// 32400
echo $date->getTimestamp(), PHP_EOL;
// 1601258070
var_dump($date->getTimezone());
// object(DateTimeZone)#6 (2) {// ["timezone_type"]=>
// int(3)
// ["timezone"]=>
// string(10) "Asia/Tokyo"
// }
getOffset() 办法就是获取得咱们与标准时区的差值,也就是对应的北京相差 8 个小时的信息,这个在之前的文章中与 DateTimeZone 对象的同名办法的作用是相似的。getTimestamp() 和 getTimezone() 办法置信也不必多解释了,一个是返回以后 DateTime 对象对应的工夫戳,一个是返回一个时区对象。
最初,咱们再来看看 DateTime() 对象的错误处理。DateTime 对象其实也是能够用过程化的形式来写的,所以它提供了一个 getLastErrors() 办法,不过咱们在应用面向对象的形式时,DateTime 对象会以异样的模式进行抛出。
$date = date_create('asdfasdf');
print_r(DateTime::getLastErrors());
// Array
// (// [warning_count] => 1
// [warnings] => Array
// (// [6] => Double timezone specification
// )
// [error_count] => 1
// [errors] => Array
// (// [0] => The timezone could not be found in the database
// )
// )
try {$date = new DateTime('asdfasdf');
} catch (Exception $e) {echo $e->getMessage(), PHP_EOL;
}
// DateTime::__construct(): Failed to parse time string (asdfasdf) at position 0 (a): The timezone could not be found in the database
第一段代码就是以面向过程的函数形式来创立的一个 DateTime 对象,它不会抛出异样,这样咱们就能够通过 getLastErrors() 办法取得错误信息。然而当初还是更举荐以面向对象的形式来操作 DateTime,所以咱们应该尽量应用第二段代码的形式来处理错误信息。
总结
怎么样,DateTime 对象的是不是很有意思?思考一下,咱们日常的很多日期操作是不是也能够通过它来实现了。对于 DateTimeImmutable 的内容就不会再独自解说了,大家能够本人查阅一下相干的材料,因为内容其实都是和 DateTime 一样的,惟一的区别在上文中也曾经阐明了。
测试代码:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202009/source/13.PHP 中的日期相干函数(二).php
参考文档:
https://www.php.net/manual/zh/class.datetime.php
https://www.php.net/manual/zh/class.datetimeimmutable.php
各自媒体平台均可搜寻【硬核项目经理】