当前位置: 首页 > 后端技术 > PHP

学习PHP中的国际日期格式化操作

时间:2023-03-29 18:49:08 PHP

对于国际化功能来说,日期相关的格式化操作也是重要的一环。毕竟,不同的时区和不同的国家有不同的日期表达方式。今天我们主要学习日期相关信息的国际化表示。日期格式化首先是最直接的格式化功能。$fmt=newIntlDateFormatter("en_US",IntlDateFormatter::FULL,IntlDateFormatter::FULL,'America/Los_Angeles',IntlDateFormatter::GREGORIAN);echo"en_US格式化结果为:".$fmt->format(time()),PHP_EOL;//en_US格式的结果是:太平洋标准时间2020年11月20日星期五下午4:45:06$fmt=newIntlDateFormatter("de-DE",IntlDateFormatter::FULL,IntlDateFormatter::FULL,'America/Los_Angeles',IntlDateFormatter::GREGORIAN);echo"de_DE格式化结果为:".$fmt->format(IntlCalendar::createInstance()),PHP_EOL;//de_DE格式化结果为:Freitag,20.November2020um16:45:06NordamerikanischeWestküsten-Normalzeit$fmt=newIntlDateFormatter("zh-CN",IntlDateFormatter::FULL,IntlDateFormatter::FULL,'Asia/Shanghai',IntlDateFormatter::GREGORIAN);echo"zh-CN格式化结果为:".$fmt->format(time()),PHP_EOL;//zh-CN格式化结果为:2020年11月21日星期六,中国标准时间上午8:45:06IntlDateFormatter对象是操作类用于国际化组件中的日期格式。它的构造参数很多,其实很简单。第一个参数是国家的区域设置,第二个和第三个参数是日期和星期的显示格式,我们将在下一段代码中演示。第四个参数是时区设置,第五个参数是时间规范,指定公历时间。使用format()方法格式化时间戳或日历对象的日期和时间。它只能接受这两种类型的参数并对其进行格式化。它会根据IntlDateFormatter对象设置的各种参数进行输出,比如输出语言为英文、德文、中文等,输出时间根据时区(中国8:00,中国4:00)美国)。对于日期和时间的显示格式,我们可以使用IntlDateFormatter类的几个常量来表示,主要有FULL、SHORT、MEDIUM、LONG。$fmt=newIntlDateFormatter("zh-CN",IntlDateFormatter::SHORT,IntlDateFormatter::LONG,'亚洲/上海',IntlDateFormatter::GREGORIAN);echo"zh-CN格式化结果为:".$fmt->format(time()),PHP_EOL;//zh-CN格式化结果为:2020/11/21GMT+88:45:06AM另外,构造函数的第六个参数是格式规则,可以指定格式。$fmt=newIntlDateFormatter("zh-CN",IntlDateFormatter::FULL,IntlDateFormatter::FULL,'Asia/Shanghai',IntlDateFormatter::GREGORIAN,'yyyy/MM/dd');echo"zh-CN格式化结果是:".$fmt->format(time()),PHP_EOL;//zh-CN格式化结果为:2020/11/21根据指定对象格式化日期。上面的format()方法我们只能看到UseTimestamp和Calendar对象类型。其实还有一个更强大的格式化方法,就是formatObject()方法。顾名思义,就是根据指定的对象格式化日期数据。$cal=IntlCalendar::createInstance(newDateTimeZone('Asia/Shanghai'));echoIntlDateFormatter::formatObject($cal),PHP_EOL;//2020年11月21日8:45:06AMechoIntlDateFormatter::formatObject($cal,IntlDateFormatter::FULL),PHP_EOL;//中国标准时间2020年11月21日星期六上午8:45:06/2020112108:45AMechoIntlDateFormatter::formatObject($cal,IntlDateFormatter::FULL,'zh-CN'),PHP_EOL;//2020年11月21日,星期六,中国标准时间上午8:45:06echoIntlDateFormatter::formatObject($cal,"d'of'MMMMy",'zh-CN'),PHP_EOL;//2020年11月21日最常用的还是格式化日历对象,可以看到formatObject()方法的参数比较多,也可以直接指定日期时间格式和相关语言设置。此外,它还可以指定丰富的输出规则。例如,我们输出的最后一段代码是该月的第几天。在这篇关于PHP国际化日历类的文章中,我们也使用了这种方法进行测试。有许多自定义语法规则。ICU的相关文件可以自行查阅。除了格式化日历类,formatObject()方法还可以输出日期格式的DateTime对象。$dt=newDateTime();echoIntlDateFormatter::formatObject($dt),PHP_EOL;//Nov21,2020,8:45:06AM不过需要注意的是,从官方文档的Note中,formatObject()速度很慢,PHP5和format()方法有10倍左右的差距,PHP7下有3倍左右的差距。所以,如果没有特殊需要,尽量不要使用formatObject()方法格式化日期时间。反解析日期字符串和我们学习PHP国际化数字格式处理时说的一样。我们可以将对象或时间戳格式化为标准字符串格式以供显示。可不可以把这个标准字符转换成字符串格式的数据再反转呢?$fmt=newIntlDateFormatter("en_US",IntlDateFormatter::FULL,IntlDateFormatter::FULL,'America/Los_Angeles',IntlDateFormatter::GREGORIAN);$arr=$fmt->localtime($fmt->format(time()));print_r($arr);//数组//(//[tm_sec]=>1//[tm_min]=>59//[tm_hour]=>16//[tm_year]=>120//[tm_mday]=>20//[tm_wday]=>5//[tm_yday]=>325//[tm_mon]=>10//[tm_isdst]=>0//)echo$fmt->parse("Thursday,November19,2020at5:05:41PMPacificStandardTime"),PHP_EOL;//1605834341localtime()方法用于解析内容给定的标准日期。根据IntlDateFormatter初始化的规则,将字符串内容倒过来输出一个数组,里面包含年月日时分秒等信息。parse()方法直接将给定的内容转换成对应的时间戳。$fmt=newIntlDateFormatter("zh-CN",IntlDateFormatter::FULL,IntlDateFormatter::FULL,'亚洲/上海',IntlDateFormatter::GREGORIAN);$arr=$fmt->localtime("2020年11月20日星期五CST8:54:08");print_r($arr);//数组//(//[tm_sec]=>8//[tm_min]=>54//[tm_hour]=>8//[tm_year]=>120//[tm_mday]=>20//[tm_wday]=>5//[tm_yday]=>325//[tm_mon]=>10//[tm_isdst]=>0//)echo$fmt->parse("2020年11月20日,星期五,8:54:08AMChinaStandardTime"),PHP_EOL;//1605833648支持中英文。相关属性获取和设置日历类型信息对于日历类型,只有两种日历,GREGORIAN和TRADITIONAL,分别对应公历和传统日历。在构造参数中,我们可以通过第五个参数指定,或者在对象使用过程中使用setCalendar()方法来设置。getCalendar()方法用于获取当前设置的日期类型信息。$fmt=newIntlDateFormatter("en_US",IntlDateFormatter::FULL,IntlDateFormatter::FULL,'America/Los_Angeles',IntlDateFormatter::GREGORIAN);echo$fmt->getCalendar(),PHP_EOL;//1$fmt->setCalendar(IntlDateFormatter::TRADITIONAL);echo$fmt->getCalendar(),PHP_EOL;//0日期和时间类型//获取和设置日期类型$fmt=newIntlDateFormatter("en_US",IntlDateFormatter::FULL,IntlDateFormatter::FULL,'America/Los_Angeles',IntlDateFormatter::GREGORIAN);echo$fmt->getDateType(),PHP_EOL;//0$fmt=newIntlDateFormatter("en_US",IntlDateFormatter::SHORT,IntlDateFormatter::FULL,'America/Los_Angeles',IntlDateFormatter::GREGORIAN);echo$fmt->getDateType(),PHP_EOL;//3//时间类型获取和设置echo$fmt->getTimeType(),PHP_EOL;//0$fmt=newIntlDateFormatter("en_US",IntlDateFormatter::SHORT,IntlDateFormatter::MEDIUM,'America/Los_Angeles',IntlDateFormatter::GREGORIAN);echo$fmt->getTimeType(),PHP_EOL;//2对于日期时间类型,我们只能通过构造函数的参数来指定,得到的也是对应常量区域语言信息的值echo$fmt->getLocale(),PHP_EOL;//enecho$fmt->getLocale(Locale::VALID_LOCALE),PHP_EOL;//en_US就不多解释了,在上一篇文章中这两种方法似乎都包含在国际化相关组件的类中。格式规则的获取和设置我们可以在构造函数的第六个参数中指定格式规则,也可以动态设置对象。echo$fmt->getPattern(),PHP_EOL;//M/d/yy,h:mm:ssa$fmt->setPattern('yyyyMMddhh:mm:ssz');echo$fmt->getPattern(),PHP_EOL;//yyyyMMddhh:mm:sszecho$fmt->format(time()),PHP_EOL;//2020112004:59:01PST使用setPattern()设置格式规则后,再次执行formar()以添加新的格式规则进行格式化。时区设置首先让我们看一下getTimezoneId()方法。直接获取时区的内容,是一个字符串。echo$fmt->getTimezoneId(),PHP_EOL;//美国/洛杉矶//$fmt->setTimeZoneId('CN');//PHP7已被删除//echo$fmt->getTimezoneId(),PHP_EOL;但是在PHP7中已经删除了setTimezoneId()方法,现在推荐使用setTimezone()方法来设置时区信息,我们一会儿来看看。var_dump($fmt->getTimezone());//object(IntlTimeZone)#4(4){//["valid"]=>//bool(true)//["id"]=>//字符串(19)"America/Los_Angeles"//["rawOffset"]=>//int(-28800000)//["currentOffset"]=>//int(-28800000)//}$fmt->setTimeZone('Asia/Shanghai');var_dump($fmt->getTimezone());//object(IntlTimeZone)#4(4){//["valid"]=>//bool(true)//["id"]=>//string(13)"Asia/Shanghai"//["rawOffset"]=>//int(28800000)//["currentOffset"]=>//int(28800000)//}$fmt->setTimeZone('GMT+00:30');var_dump($fmt->getTimezone());//object(IntlTimeZone)#4(4){//["valid"]=>//bool(true)//["id"]=>//string(9)"GMT+00:30"//["rawOffset"]=>//int(1800000)//["currentOffset"]=>//int(1800000)//}与getTimezoneId()方法的区别在于getTimezone()方法返回的是一个IntlTimeZone对象。这个对象的内容官方文档不全,很多方法参数都没有写。我不擅长猜测,所以我不会写关于这个对象的文章,你可以自己查看相关资料。但是对于简单的时区设置,setTimezone()方法可以直接使用字符串作为参数。例如,我们在上面的代码中将美国洛杉矶的时区更改为中国上海和GMT+00:30。相应的,如果我们再次用format()输出时间,输出的会以当前时区的标准时间为准。获取日历对象本身在格式化数据时,我们已经与日历对象打过很多交道。当然我们也可以通过IntlDateFormatter对象获取日历信息。$cal=$fmt->getCalendarObject();var_dump($cal->getType(),$cal->getTimeZone(),$cal->getLocale(Locale::VALID_LOCALE));//string(9)"公历"//object(IntlTimeZone)#3(4){//["valid"]=>//bool(true)//["id"]=>//string(9)"GMT+00:30"//["rawOffset"]=>//int(1800000)//["currentOffset"]=>//int(1800000)//}//string(5)"en_US"Tolerance最后,让我们看一下宽容能力其实是一种严格的运作方式。比如我们定义了一个错误的时间,IntlDateFormatter中的操作是不会报错的,因为它默认是可以容忍的。$fmt->setPattern('dd/mm/yyyy');var_dump($fmt->isLenient());//bool(true)echo$fmt->parse('35/13/1955'),PHP_EOL;//-470449020显然,这个日期是错误的日期。通过isLenient()方法可以获取当前状态是否宽松。我们现在取消宽大处理的能力,看看会发生什么。$fmt->setLenient(FALSE);echo$fmt->parse('35/13/1955'),PHP_EOL;//echo$fmt->getErrorCode(),PHP_EOL;//9echo$fmt->getErrorMessage(),PHP_EOL;//Dateparsingfailed:U_PARSE_ERRORparse()方法没有输出。同时,错误信息也是通过getErrorCode()和getErrorMessage()看到的。这是IntlDateFormatter对象中允许处理的主要功能。总结一下,今天学习的内容比较多,也比较零散,但主要还是IntlDateFormatter对象的内容。数字和日期格式是国际化相关功能中最重要的功能,也可以随时应用到我们日常的业务开发中。你可以学到很多关于他们的知识。测试代码:https://github.com/zhangyue0503/dev-blog/blob/master/php/202011/source/8。学习PHP中的国际日期格式化操作。PHP参考文档:https://www.php.net/manual/zh/class.intldateformatter.php============各媒体平台均可搜索【硬核项目经理】