SNMP DateAndTime十六进制字符串在PHP中转换为人工日期
当我想通过SNMP获取cablemodem事件日志时,我会使用“mib-2.69.1.5.8.1”oid,但我遇到了问题,因为SNMP将每个事件日期存储为称为格式的“特殊”十六进制字符串 (在我的例子中,这是一个8字节的十六进制字符串,如下所示:07 B2 01 01 00 0A 14 00) 我想转换为人类日期,如下所示(1970.01.01.00:10),因此我编写了一个PHP函数:SNMP DateAndTime十六进制字符串在PHP中转换为人工日期,php,date,snmp,Php,Date,Snmp,当我想通过SNMP获取cablemodem事件日志时,我会使用“mib-2.69.1.5.8.1”oid,但我遇到了问题,因为SNMP将每个事件日期存储为称为格式的“特殊”十六进制字符串 (在我的例子中,这是一个8字节的十六进制字符串,如下所示:07 B2 01 01 00 0A 14 00) 我想转换为人类日期,如下所示(1970.01.01.00:10),因此我编写了一个PHP函数: function hex2date( $hexstring ) { $date = ""; $p
function hex2date( $hexstring ) {
$date = "";
$p = unpack( "H*", substr( $hexstring, 0, 2 ) ); // year (2 byte)
$date .= hexdec( $p[1] ).".";
$p = unpack( "H*", substr( $hexstring, 2, 1 ) ); // month (1 byte)
$date .= sprintf( "%02s", hexdec( $p[1] ) ).".";
$p = unpack( "H*", substr( $hexstring, 3, 1) ); // day (1 byte)
$date .= sprintf( "%02s", hexdec( $p[1] ) ).". ";
$p = unpack( "H*", substr( $hexstring, 4, 1 ) ); // hour (1 byte)
$date .= sprintf( "%02s", hexdec( $p[1] ) ).":";
$p = unpack( "H*", substr( $hexstring, 5, 1 ) ); // minute (1 byte)
$date .= sprintf( "%02s", hexdec( $p[1] ) );
return ($date);
}
这是工作,但出于某种原因,我认为这不是最优雅的解决方案。
我说得对吗?对于来自谷歌的旅行者,在这种情况下,设备发送一个8字节的SNMP DateAndTime值,而不包含时区信息。检查我在下面链接的手册。然而,获取时区信息遵循相同的原则
您的代码应该如下所示:
// Prepare test data
$binstring = "\x07\xB2\x01\x01\x00\x0A\x14\x00";
$values = unpack('nyear/Cmonth/Cday/Chour/Cminute/Csecond/Cdecisecond', $binstring);
var_dump($values);
输出:
数组(7){
“年”=>
国际(1970年)
“月”=>
int(1)
“天”=>
int(1)
“小时”=>
int(0)
“分钟”=>
国际(10)
“秒”=>
国际(20)
“分秒”=>
int(0)
}
请参阅以下手册页:
unpack()
的功能比你想象的要强大。是的,我知道时区信息丢失了,但我只是从调制解调器中获得了这么多数据。我将尝试你的版本,但是我认为你的$hextime变量并不是函数的十六进制输入。我猜你没有说你是在使用二进制数据,而不是你在问题中发布的十六进制字符串。不是吗?如果您使用的是二进制数据,只需一个解包调用,不需要substr和hexdec。让我知道你的意见是否正确。然后,我将在这里展示如何正确使用解包。是的,输入是十六进制(二进制)数据,正如您所说的,因此您的版本不起作用。这是snmpwalk输出,我只是这样命名(十六进制字符串)。SNMPv2 SMI::mib-2.69.1.5.8.1.3.33=十六进制字符串:07 B2 01 00 1E 00。对不起,当我准备一些东西时,你可以看看我写的hextump库。。我相信这会对你有帮助。