PHP中IntlDateFormatter与DateTime时间戳不一致问题咨询
IntlDateFormatter与DateTime时间戳差异问题分析
问题描述
PHP的IntlDateFormatter()函数解析得到的时间戳与DateTime()函数结果存在差异:格式化后的字符串完全一致,但解析出的时间戳却不匹配。测试代码如下:
$formatter = new IntlDateFormatter( 'en_GB', IntlDateFormatter::SHORT, IntlDateFormatter::SHORT, 'Europe/London', IntlDateFormatter::GREGORIAN, 'dd MMMM YYYY, HH:mm' ); $now = new DateTime('01-03-2023 17:00'); echo '<b>DateTime() String:</b> ' . $now->format('d F Y, H:i') . '<br/>'; echo '<b>IntlDateFormatter() String:</b> ' . $formatter->format( $now ) . '<br/><br/>'; echo '<b>DateTime() Timestamp:</b> ' . $now->getTimestamp() . '<br/>'; echo '<b>IntlDateFormatter() Timestamp:</b> ' . $formatter->parse( $formatter->format( $now ) );
输出结果
- DateTime() String: 01 March 2023, 17:00
- IntlDateFormatter() String: 01 March 2023, 17:00
- DateTime() Timestamp: 1677690000
- IntlDateFormatter() Timestamp: 1672074000
异常原因
问题出在日期格式字符串的YYYY上:
- PHP的
DateTime::format()方法中,Y代表常规公历年,即日常认知的年份。 - 但
IntlDateFormatter遵循ICU日期规则,其中YYYY代表周年度(Week Year)——指该日期所在周对应的年度,这个年度可能和公历年不一致(比如1月上旬部分日期会归属到上一年的周年度)。
你的代码中,IntlDateFormatter用YYYY格式化时,输出字符串显示为2023,但解析时ICU会按周年度规则处理,导致生成错误的时间戳;而DateTime的Y对应ICU规则中的yyyy(公历年),两者规则不匹配才出现差异。
解决方法
将IntlDateFormatter格式字符串中的YYYY替换为yyyy,让解析逻辑与DateTime保持一致:
$formatter = new IntlDateFormatter( 'en_GB', IntlDateFormatter::SHORT, IntlDateFormatter::SHORT, 'Europe/London', IntlDateFormatter::GREGORIAN, 'dd MMMM yyyy, HH:mm' // 替换YYYY为yyyy ); $now = new DateTime('01-03-2023 17:00'); echo '<b>DateTime() String:</b> ' . $now->format('d F Y, H:i') . '<br/>'; echo '<b>IntlDateFormatter() String:</b> ' . $formatter->format( $now ) . '<br/><br/>'; echo '<b>DateTime() Timestamp:</b> ' . $now->getTimestamp() . '<br/>'; echo '<b>IntlDateFormatter() Timestamp:</b> ' . $formatter->parse( $formatter->format( $now ) );
修改后,两者解析出的时间戳会完全一致。
内容的提问来源于stack exchange,提问作者X9DESIGN
相关产品推荐
相关产品推荐

