我最近偶然发现了PHP v7.0.4的问题。在尝试格式化过去的某些日期时。
我在一个项目上工作,其中有一个名为"空日期",基本上是" 1800-01-01" (用来代替NULL值)。我使用GMT + 1,"欧洲/柏林"。
在处理它的过程中,并且涉及到日期本地化,IntlDateFormatter开始提出一些问题,如果日期是< = 1893-04-01(4月初的傻瓜?),我就把它们追赶到例外。
您可以在下面看到一些有趣的例子。有人可以确认他们在他们的系统上遇到同样的问题吗?它应该可以重现:
$formatter = new \IntlDateFormatter('en_US', \IntlDateFormatter::MEDIUM, \IntlDateFormatter::LONG);
echo $formatter->format(new \DateTime("1893-04-01 00:00:00")) . '<br />';
echo $formatter->format(new \DateTime("1893-04-02 00:00:00")) . '<br />';
应返回:
"Mar 31, 1893, 11:53:28 PM GMT+0:53:28" and
"Apr 2, 1893, 12:00:00 AM GMT+1"
或者更明显的行为&#34;改变&#34;:
echo $formatter->format(new \DateTime("1893-04-01 00:06:31")) . '<br />';
echo $formatter->format(new \DateTime("1893-04-01 00:06:32")) . '<br />';
应返回:
"Mar 31, 1893, 11:59:59 PM GMT+0:53:28" and
"Apr 1, 1893, 12:06:32 AM GMT+1"
我认为它与时区的历史变化有关(类似这样:https://github.com/eggert/tz/blob/2017b/asia#L891,虽然这是关于亚洲的,我使用GMT + 1)。
如果我们假设我真的需要使用这个日期,01.01.1800 - 任何人都会看到任何&#34;正常&#34;解决这个&#34;问题&#34;?
答案 0 :(得分:1)
你是对的,它与historical change of the timezone有关。欧洲/柏林的格林尼治标准时间偏差为+0:53:28,直到1893年4月,它才会达到+1。
因此,它的第一个GMT + 1是:
之前的第二个是:
基本上这意味着1893年4月1日00:00:00到00:06:31不存在。
避免这种混乱的常见方法是仅在UTC中工作并处理时区转换仅用于显示。例如:
date_default_timezone_set('UTC');
$formatter = new \IntlDateFormatter(
'en_US',
\IntlDateFormatter::MEDIUM,
\IntlDateFormatter::LONG,
'Europe/Berlin'
);
echo $formatter->format(new \DateTime("1800-01-01 00:00:00")) , "\n";
echo $formatter->format(new \DateTime("1893-03-31 23:06:31")) , "\n";
echo $formatter->format(new \DateTime("1893-03-31 23:06:32")) , "\n";
echo $formatter->format(new \DateTime("1893-04-01 00:00:00")) , "\n";
输出:
Jan 1, 1800, 12:53:28 AM GMT+0:53:28
Mar 31, 1893, 11:59:59 PM GMT+0:53:28
Apr 1, 1893, 12:06:32 AM GMT+1
Apr 1, 1893, 1:00:00 AM GMT+1
如果你更愿意,你也可以强迫IntlDateFormatter
使用GMT + 1而不是你的时区:
$formatter = new \IntlDateFormatter(
'en_US',
\IntlDateFormatter::MEDIUM,
\IntlDateFormatter::LONG,
'GMT+01:00'
);