PHP - 将12小时格式时间转换为新时区时出错

时间:2012-07-28 14:14:58

标签: php time timezone

我将12小时格式时间从时区转换为新格式时出现错误某时 TimeZone

错误:

Fatal error: Uncaught exception 'Exception' with message 'DateTime::__construct(): Failed to parse time string (00:00:31 AM) at position 9 (A): The timezone could not be found in the database' in C:\xampp\php\udp.php:105
Stack trace:
#0 C:\xampp\php\udp.php(105): DateTime->__construct('00:00:31 AM', Object(DateTimeZone))
#1 {main}  thrown in C:\xampp\php\udp.php on line 105

MyCodes:

// $gps_time = "9:43:52"; 
$gps_time      = $time_hour.":".$time_min.":".$time_sec;
// $time_received = "01:45:04 2012-07-28"; 
$time_received = date('H:i:s Y-m-d');

$utc = new DateTimeZone("UTC"); 
$moscow = new DateTimeZone("Europe/Moscow"); 

//Instantiate both AM and PM versions of your time 
$gps_time_am = new DateTime("$gps_time AM", $utc); 
$gps_time_pm = new DateTime("$gps_time PM", $utc); 

//Received time 
$time_received = new DateTime($time_received, $moscow); 

//Change timezone to Moscow 
$gps_time_am->setTimezone($moscow); 
$gps_time_pm->setTimezone($moscow); 

//Check the difference in hours. If it's less than 1 hour difference, it's the correct one. 
if ($time_received->diff($gps_time_pm)->h < 1) { 

$correct_time = $gps_time_pm->format("H:i:s Y-m-d");
} 
else { 

$correct_time = $gps_time_am->format("H:i:s Y-m-d");
}

echo $correct_time;

问题: 问题出在哪里!!? P.S:上面代码是我的udp套接字的一部分,从php cli运行

1 个答案:

答案 0 :(得分:3)

摘要

简单地说,PHP正在尝试(错误地,根据您的需要)将AM作为时区阅读,AM不是有效时区。


详细

10:39:6 AM分为以下几部分

  • 10:39:6它识别为timelong24(24小时格式化时间,以秒为单位)
  • AM它识别为tz(时区)。

相反,对于10:39:06 AM,它正确地将整个字符串解析为timelong12(12小时格式化时间,秒和上午/下午)。

无聊位

这种奇怪行为的原因在于日期解析逻辑(source)。相关模式是:

<强> timelong24

't'?
[01]?[0-9] | "2"[0-4]              # hour24
[:.]
[0-5]?[0-9]                        # minute
[:.]
[0-5]?[0-9] | "60"                 # second;

<强> timelong12

"0"?[1-9] | "1"[0-2]               # hour12
[:.]
[0-5]?[0-9]                        # minute
[:.]
[0-5][0-9] | "60"                  # secondlz
[ \t]*                             # space?
([AaPp] "."? [Mm] "."?) [\000\t ]  # meridian;

正如您所看到的,要匹配timelong12格式(这是我们真正想要的),部分必须加倍位数。