2

有时在将 12 小时格式时间从时区转换为新时区时出现 错误

错误:

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

我的代码:

// $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;

问:哪里有问题!!?
PS:上面的代码是我的 udp 套接字的一部分,从 php cli 运行

4

1 回答 1

3

概括

简而言之,PHP 正在尝试(错误地,为了您的需要)读取AM为时区并且AM不是有效的时区。


细节

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

  • 10:39:6它识别为timelong24(带秒的 24 小时格式时间)
  • AM它识别为tz(时区)。

相反,10:39:06 AM它正确地将整个字符串解析为timelong12(带秒和 AM/PM 的 12 小时格式时间)。

无聊的钻头

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

时间长24

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

时间长12

"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格式(这是我们真正想要的),时间的部分必须是两位数。

于 2012-07-28T15:28:29.583 回答