项目中使用了大华、汉邦高科、天地伟业、海康威视、景阳等国产品牌的IPC设备,都出现了显示时间错误的问题,并且不同品牌的设备时间都不一样,经分析是时区的问题。
现象:
对IPC设备设置格林威治时间 (GMT),以及北京时区(GMT+8:00:00)后,大华摄像头时间正常,汉邦的时间比正常时间少8小时;
admin
wd/TdI3Vx+CQJv34o3jhSKc90nY=
LTE4NzgwMDkzNjU=
2017-11-22T08:00:43Z
Manual
false
GMT+8:00
2017
11
22
HTTP/1.1 200 OK
Server: gSOAP/2.8
Content-Type: application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver10/device/wsdl/SetSystemDateAndTime"
Content-Length: 2269
Connection: close
大华显示2017.11.22 16:00:43,汉邦显示2017.11.22 08:00:43
时区 | 汉邦 | 大华 |
GMT+8:00:00 | -8h | +8h |
GMT-8:00:00 | +8h | -8h |
CCT+8:00:00 | -8h | -8h |
CCT-8:00:00 | +8h | +8h |
设置格林威治时间 (GMT),时区统一为CCT-8:00:00。
int OnvifSetTime(char *deviceAddr, char *user, char *password, int timeOut)
{
int retval = 0;
struct SOAP_ENV__Header header;
struct soap *soap;
if ((soap = Initsoap(&header, NULL, NULL, timeOut)) == NULL)
{
DPRINT(ONVIF_ERR, "Initsoap error!\n");
return RETURN_FAIL;
}
DPRINT(ONVIF_INFO, "\n-------------------OnvifSetTime--------------\n\n");
soap_wsse_add_UsernameTokenDigest_ex(soap, "user", user, password);
time_t now;
struct tm *timenow;
time(&now);
timenow = gmtime(&now);
DPRINT(ONVIF_INFO, "year:%d month:%d day:%d hour:%d min:%d sec:%d \r\n", timenow->tm_year, timenow->tm_mon, timenow->tm_mday, timenow->tm_hour, timenow->tm_min, timenow->tm_sec);
struct _tds__SetSystemDateAndTime setReq;
struct _tds__SetSystemDateAndTimeResponse setResponse;
soap_default__tds__SetSystemDateAndTime(soap, &setReq);
setReq.DateTimeType = 0;
setReq.DaylightSavings = 0;
char *timez = "CCT-8:00:00";
struct tt__TimeZone timeZTmp;
timeZTmp.TZ = timez;
setReq.TimeZone = &timeZTmp;
struct tt__DateTime datatimeTmp;
struct tt__Date dataTmp;
struct tt__Time timeTmp;
dataTmp.Year = timenow->tm_year + 1900;
dataTmp.Month = timenow->tm_mon + 1;
dataTmp.Day = timenow->tm_mday;
timeTmp.Hour = timenow->tm_hour;
timeTmp.Minute = timenow->tm_min;
timeTmp.Second = timenow->tm_sec;
datatimeTmp.Date = &dataTmp;
datatimeTmp.Time = &timeTmp;
setReq.UTCDateTime = &datatimeTmp;
soap_call___tds__SetSystemDateAndTime(soap, deviceAddr, NULL, &setReq, &setResponse);
if (soap->error) {
DPRINT(ONVIF_ERR, "[%s][%d]--->>> soap error: %d, %s, %s\n", __func__, __LINE__, soap->error, *soap_faultcode(soap), *soap_faultstring(soap));
retval = RETURN_FAIL;
}
else{
retval = RETURN_SUCCESS;
}
Deletesoap(soap);
return retval;
}