简介
近期在研究组的项目中,开发SDK时发现一个bug,bug的具体原因是未做时间戳转时间格式的本地化,导致时间校验失败。具体问题和解决方案描述如下。
现象描述
从服务器收到的返回信息中,包括有返回信息的有效时间,使用Java版本的SDK验证有效时间通过,使用C#版本的SDK验证有效时间不通过。
Debug
分别使用Eclipse和VS对SDK中从返回信息中提取时间的代码debug,发现Java版本的SDK和C#版本的SDK提取的时间戳相同,没有问题。
但C# SDK之后对时间有效性的验证是通过比对两个Datetime的变量实现的,Java SDK直接使用时间戳进行的对比,因此怀疑C#在将时间戳转为Datetime的过程中发生了错误。
监视C# SDK中将时间戳转为Datetime后的时间,发现比当前时间早8个小时,思考了一下,发现8个小时正好是北京相对格林尼治时间的调时。
搜索了一下资料,发现确实是之前C# SDK中已有代码没有在将时间戳转为Datetime时做时间本地化,而使用DateTime.Now获取的却是本地时间,导致时间有效性验证不通过。
代码
C# (错误原版)
Datetime validTime = new DateTime(1970, 1, 1).AddSeconds(time); // time为HTTP Response中提取出的时间戳
if(validTime < Datetime.Now)
return false; // 由于validTime早于真正时间8小时,总是执行该语句
else
return true; // 该语句不会被执行
C# (正确修正版)
Datetime validTime = new DateTime(1970, 1, 1).AddSeconds(time).ToLocalTime(); //时间戳转时间后进行本地化
if(validTime < Datetime.Now)
return false;
else
return true;
补充
- 高级语言中将时间戳转换为格式化时间的API中,并非都实现了对时间的本地化,因此遇到转换后的时间与预期的不同时,可以查看下时间的差值,是否因为时区问题造成;同时也要提防因为API提前做了本地化,导致转换后的时间非格林尼治时间的问题。
- 对时间的大小对比,直接使用时间戳这一不受环境印象的因素更好(当然,具体问题具体分析,不能一概而论)