上一篇介绍了三个时间日期相关的对象,不过它们的出现频率都不是特别高。今天研究的对象虽然可能被很多人用过,但它的出现频率也很低。它们实际上是我们非常常用的面向过程的日期函数的面向对象封装。不过,酒香不怕巷子深,好东西值得我们深入学习和研究。当然,面对不同的业务场景,能够灵活使用这些对象就更好了。这是我们学习的根本目的。DateTime对象没错,我们今天学习的就是DateTime对象。从名字就可以看出,它是一个标准的日期时间类。$date=newDateTime('now',newDateTimeZone('Asia/Tokyo'));echo$date->format('Y-m-dH:i:sP'),PHP_EOL;//2020-09-2909:47:57+09:00$date=newDateTime();echo$date->format('Y-m-dH:i:sP'),PHP_EOL;//2020-09-2910:22:45+08:00us可以给它指定一个时间,指定一个时区。在第一行的测试代码中,我们指定时间为now,即当前时间,这里也可以将字符串的时间格式传递给该参数。第二个参数是指定的时区。我们通过了日本的区域时区,所以它的P格式输入是+9:00,也就是东九区,比我们的北京时间东八区早1个小时。如果实例化DateTime时不传递任何参数,则默认为当前时间和php.ini中指定的时区。DateTime对象也可以通过其他方式创建。$date=DateTime::createFromFormat('Y年m月j日H小时i分s秒','2020年9月22日22:13:35');echo$date->format('Y-m-dH:i:sP'),PHP_EOL;//2020-09-2222:13:35+08:00$date=DateTime::createFromImmutable(newDateTimeImmutable("2020-09-2211:45"));echo$date->format('Y-m-dH:i:sP'),PHP_EOL;//2020-09-2211:45:00+08:00createFromFormat()静态方法是根据生成一个DateTime时间对象指定的格式。我们这里指定的格式是中文常用的格式,后面是具体的日期。createFromImmutable()通过DateTimeImmutable对象创建一个DateTime对象。DateTime和DateTimeImmutableDateTimeImmutable是一个日期表示对象。它与DateTime基本相同。方法和属性与DateTime相同。唯一不同的是,它不会在后面介绍的操作方法中修改自己,而是返回一个新的对象。DateTimeImmutable对象中还有一个静态方法createFromMutable()用于从DateTime对象创建一个DateTimeImmutable对象。$di=newDateTimeImmutable("2020-09-2211:45");var_dump($di);//object(DateTimeImmutable)#1(3){//["date"]=>//string(26)"2020-09-2211:45:00.000000"//["timezone_type"]=>//int(3)//["timezone"]=>//string(13)"Asia/Shanghai"//}var_dump($di->add(newDateInterval('P3D')));//object(DateTimeImmutable)#4(3){//["date"]=>//string(26)"2020-09-2511:45:00.000000"//["timezone_type"]=>//int(3)//["timezone"]=>//string(13)"Asia/Shanghai"//}$date=newDateTime("2020-09-2211:45");var_dump($date);//object(DateTime)#4(3){//["date"]=>//string(26)"2020-09-2211:45:00.000000"//["timezone_type"]=>//int(3)//["timezone"]=>//string(13)"Asia/Shanghai"//}var_dump($date->add(newDateInterval('P3D')));//object(DateTime)#4(3){//["date"]=>//string(26)"2020-09-2511:45:00.000000"//["timezone_type"]=>//int(3)//["timezone"]=>//string(13)"Asia/Shanghai"//}从上面的测试代码可以看出DateTimeImmutable在使用add()方法后返回的对象是一个newobject,object(DateTimeImmutable)#1(3)变为object(DateTimeImmutable)#4(3)并且DateTime是自己修改的,对象标识没有变。DateTime操作上面的add()方法就是添加日期的方法。它需要一个DateInterval时间间隔对象作为参数,然后将指定的时间间隔添加到对应的日期上。$date->add(newDateInterval('P3D'));echo$date->format('Y-m-dH:i:sP'),PHP_EOL;//2020-09-2909:22:45+08:00在这里,我们只是将当前时间增加3天。DateInterval对象的内容可以参考上一篇文章的介绍。当然,除了增加之外,还有减少和修改的方法。$date->sub(newDateInterval('P3D'));echo$date->format('Y-m-dH:i:sP'),PHP_EOL;//2020-10-0209:22:45+08:00$date->modify('+5day');echo$date->format('Y-m-dH:i:sP'),PHP_EOL;//2020-10-0409:22:45+08:00$date->modify('-4天-4小时');echo$date->format('Y-m-dH:i:sP'),PHP_EOL;//2020-09-3005:22:45+08:00sub()方法是对一个时间对象减少指定的时间间隔,modify()方法是直接根据参数修改日期。比如我们这里测试了增加5天,减少4天4小时的操作。$origin=newDateTime('现在');$target=newDateTime('2020-09-11');$interval=$origin->diff($target);echo$interval->format('%adays'),PHP_EOL;echo$interval->format('%R%adays'),PHP_EOL;//18days//-18daysdiff()方法是返回两个日期之间的差异,相信这种方法并不少人用过它的面向过程的功能,即date_diff()函数。与其他方法相比,它的出镜率非常高。%R返回符号位,如果是负号,表示距离指定日期还有多少时间间隔。设置日期和时间除了对日期和时间进行操作外,我们还可以在实例化DateTime对象后,将日期重新赋值给它。$date=new日期时间();$date->setDate(2020,9,25);echo$date->format('Y-m-dH:i:sP'),PHP_EOL;//2020-09-2509:22:45+08:00$date->setISODate(2020,9,25);echo$date->format('Y-m-dH:i:sP'),PHP_EOL;//2020-03-1909:22:45+08:00$date->setTime(14,55);echo$date->格式('Y-m-dH:i:sP'),PHP_EOL;//2020-10-0314:55:00+08:00$date->setDate(2020,9,33);echo$date->format('Y-m-dH:i:sP'),PHP_EOL;//2020-10-0309:22:45+08:00$date->setTime(14,63);echo$date->format('Y-m-dH:i:sP'),PHP_EOL;//2020-10-0315:03:00+08:00setDate()方法是指定日期,setTime()方法是指定时间,它们是两个独立的方法。setISODate()设置ISO标准时间,这是另一组日期和时间规范。有兴趣的朋友可以自行查阅相关知识,这里不再赘述。如果我们设置的日期不是正常的日期格式,比如我们在测试代码中设置了9月33日的日期,那么会自动顺延,输出结果为10月3日的日期,包括setTime()的方法也可以这样扩展。事实上,所有与日期相关的对象、方法和函数都具有这种能力。另外,我们还可以通过时间戳来设置DateTime对象的日期和时间。同样,时区也可以单独设置。$date->setTimestamp(time()-84400);echo$date->format('U=Y-m-dH:i:s'),PHP_EOL;//1601258165=2020-09-2809:56:05$date->setTimezone(newDateTimeZone('Asia/Tokyo'));echo$date->format('U=Y-m-dH:i:s'),PHP_EOL;//1601258165=2020-09-2810:56:05获取属性和错误信息由于DateTime对象有这么多的设置,它也有一些我们可以获取的属性。echo$date->getOffset(),PHP_EOL;//32400echo$date->getTimestamp(),PHP_EOL;//1601258070var_dump($date->getTimezone());//对象(DateTimeZone)#6(2){//["timezone_type"]=>//int(3)//["timezone"]=>//string(10)"Asia/Tokyo"//}getOffset()方法是获取我们和standardtimezoneValue,即北京时差8小时的对应信息,与上一篇DateTimeZone对象同名方法的作用类似。getTimestamp()和getTimezone()方法不需要太多解释。一种是返回当前DateTime对象对应的时间戳,另一种是返回一个时区对象。最后,让我们看看DateTime()对象的错误处理。DateTime对象其实可以用过程化的方式来写,所以它提供了getLastErrors()方法,但是当我们使用面向对象的方法时,DateTime对象会以异常的形式抛出。$date=date_create('asdfasdf');print_r(DateTime::getLastErrors());//数组//(//[warning_count]=>1//[warnings]=>数组//(//[6]=>双时区规范//)//[error_count]=>1//[errors]=>Array//(//[0]=>在数据库中找不到时区//)//)try{$date=newDateTime('asdfasdf');}catch(Exception$e){echo$e->getMessage(),PHP_EOL;}//DateTime::__construct():解析时间字符串(asdfasdf)失败position0(a):thetimezonecouldnotfoundinthedatabase第一段代码是以面向过程的函数方式创建的DateTime对象,它不会抛出异常,所以我们可以通过getLastErrors()获取方法错误信息。但是现在还是建议用面向对象的方式来操作DateTime,所以应该尽量使用第二种代码来处理错误信息。总结一下,DateTime对象是不是很有趣?想一想,我们日常的很多日期操作是不是也可以通过它来实现。DateTimeImmutable的内容就不单独解释了。可以自己去查相关资料,因为内容其实和DateTime是一样的,唯一的区别上面已经说明了。测试代码:https://github.com/zhangyue0503/dev-blog/blob/master/php/202009/source/13。PHP(2).php中日期相关函数参考文档:https://www.php.net/manual/zh/class.datetime.phphttps://www.php.net/manual/zh/class.datetimeimmutable。php各媒体平台均可搜索【硬核项目经理】
