一个潜伏了4年之久的简单bug终于浮出水面---理解夏令时并实践玩转它
2015-04-07 23:13
309 查看
最近清明节放了三天假(4月4/5/6), 国外某一版本在6号需要发布。 我呢, 刚好有事没去加班。 结果加班的同事发现了某时间显示出现了差一错误, 需要我在电话中定位,根据同事描述,我当时怀疑是夏令时问题。 下面, 我来简要描述一下。
问题现象: 某服务端给某客户端返回了一个时间, 客户端显示的时候, 发现多了一个小时。 奇怪的是, 同样的服务端和同样的客户端, 在中国国内就没有问题, 但是, 在国外就有问题。
问题原因: 服务端返回的时间已经考虑了夏令时, 而客户端把这个时间当成普通的时间, 又考虑了一次夏令时,所以结果多1个小时。
影响分析: 多了1个小时, 不准。
规避/解决办法: 服务端不变, 统一由它考虑夏令时问题, 客户端不进行转换, 仅负责简单显示。
由于这个bug比较简单, 所以我就不具体描述场景了。 这个问题潜伏了4年之久, 那么多测试的同事怎么没有发现呢? 主要是因为, 我们目前交付的多数是国内版本, 不存在什么夏令时问题, 即使交付了一些国外版本, 也可能刚好就处在非夏令时时段, 所以呢, 这个bug一直没有暴露。
下面, 我们来了解一下夏令时,我们以北京时间(GMT+8)为例, 运行下面程序:
结果为:
0
Data:
2015-04-07
Time:
22:31:35
好,我们以柏林时间为例吧。 把Windows时区设置为GMT+1的柏林时区(且打开夏令时), 运行上面相同的程序, 得到的结果为:
1
Data:
2015-04-07
Time:
16:32:09
按理说, 柏林时间应该比北京时间慢7个小时啊, 但为什么上面的结果显示才慢6个小时呢, 原来, 柏林地区进入了夏令时了, 时间会比以前快一个小时。 需要注意的是, 如果你在冬天运行这个程序, 那就是非夏令时时间了(柏林地区2015年的夏令时时间为3月29日到10月25日)
对于程序员来说, 夏令时是一个经常碰到的概念, 百度的介绍也很多, 我就不copy了, 下面, 我仅简要说说它的原理:
在柏林冬天的某一天, 上午9点, 阳光“刚刚好”, 你该上班了。 等到到了柏林夏天, 8点的阳光“刚刚好”, 这个时候本来你是不需要上班的, 因为没有到9点嘛, 但这样一来, 8点的"刚刚好"的阳光就被浪费了, 所以德国柏林强行规定, 把现在这个“刚刚好”的8点定义为9点, 这样修改后, 你还是9点开始上班, 而且阳光“刚刚好”。 所以, 我们说, 在夏天这段时间内, 柏林进入夏令时制, 时间比预定的快了一个小时, 有很多好处啊, 还是迎着朝阳上班, 阳光"刚刚好", 还是背着日落下班。
下面, 我们来玩转一下夏令时,亲自在Windows上做一下实验:
以柏林的2015年为例:
(1)将Windows设置为GMT+1的柏林时区, 将时间调到:2015年3月29日01点59分59秒, 再过一秒, 实际上到2015年3月29日03点00分00秒了, 而不是2015年3月29日02点00分00秒了, 这样就形成了一个小时的时间空缺。
(2)将Windows设置为GMT+1的柏林时区, 将时间调到:2015年10月25日01点59分59秒,再过一秒, 就是2015年10月25日02点00分00秒。 将时间调到:2015年10月25日02点59分59秒, 再过一秒,还是2015年10月25日02点00分00秒。这样一来, 实际上有两个小时点被挤在一起了。
我国也曾经采用过夏令时, 但后来被废止了, 也好, 不然现在的程序猿可又要麻烦很多
![](https://oscdn.geek-share.com/Uploads/Images/Content/201707/33c29e3268d66ef5c09858efe40a3635.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201707/33c29e3268d66ef5c09858efe40a3635.gif)
问题现象: 某服务端给某客户端返回了一个时间, 客户端显示的时候, 发现多了一个小时。 奇怪的是, 同样的服务端和同样的客户端, 在中国国内就没有问题, 但是, 在国外就有问题。
问题原因: 服务端返回的时间已经考虑了夏令时, 而客户端把这个时间当成普通的时间, 又考虑了一次夏令时,所以结果多1个小时。
影响分析: 多了1个小时, 不准。
规避/解决办法: 服务端不变, 统一由它考虑夏令时问题, 客户端不进行转换, 仅负责简单显示。
由于这个bug比较简单, 所以我就不具体描述场景了。 这个问题潜伏了4年之久, 那么多测试的同事怎么没有发现呢? 主要是因为, 我们目前交付的多数是国内版本, 不存在什么夏令时问题, 即使交付了一些国外版本, 也可能刚好就处在非夏令时时段, 所以呢, 这个bug一直没有暴露。
下面, 我们来了解一下夏令时,我们以北京时间(GMT+8)为例, 运行下面程序:
#include <stdio.h> #include <time.h> int main() { time_t t = 0; time(&t); struct tm *p = localtime(&t); printf("%d\n", p->tm_isdst); char szBuf[100] = {0}; strftime(szBuf, sizeof(szBuf),"Data:\n%Y-%m-%d\nTime:\n%H:%M:%S",p); printf("%s\n", szBuf); return 0; }
结果为:
0
Data:
2015-04-07
Time:
22:31:35
好,我们以柏林时间为例吧。 把Windows时区设置为GMT+1的柏林时区(且打开夏令时), 运行上面相同的程序, 得到的结果为:
1
Data:
2015-04-07
Time:
16:32:09
按理说, 柏林时间应该比北京时间慢7个小时啊, 但为什么上面的结果显示才慢6个小时呢, 原来, 柏林地区进入了夏令时了, 时间会比以前快一个小时。 需要注意的是, 如果你在冬天运行这个程序, 那就是非夏令时时间了(柏林地区2015年的夏令时时间为3月29日到10月25日)
对于程序员来说, 夏令时是一个经常碰到的概念, 百度的介绍也很多, 我就不copy了, 下面, 我仅简要说说它的原理:
在柏林冬天的某一天, 上午9点, 阳光“刚刚好”, 你该上班了。 等到到了柏林夏天, 8点的阳光“刚刚好”, 这个时候本来你是不需要上班的, 因为没有到9点嘛, 但这样一来, 8点的"刚刚好"的阳光就被浪费了, 所以德国柏林强行规定, 把现在这个“刚刚好”的8点定义为9点, 这样修改后, 你还是9点开始上班, 而且阳光“刚刚好”。 所以, 我们说, 在夏天这段时间内, 柏林进入夏令时制, 时间比预定的快了一个小时, 有很多好处啊, 还是迎着朝阳上班, 阳光"刚刚好", 还是背着日落下班。
下面, 我们来玩转一下夏令时,亲自在Windows上做一下实验:
以柏林的2015年为例:
(1)将Windows设置为GMT+1的柏林时区, 将时间调到:2015年3月29日01点59分59秒, 再过一秒, 实际上到2015年3月29日03点00分00秒了, 而不是2015年3月29日02点00分00秒了, 这样就形成了一个小时的时间空缺。
(2)将Windows设置为GMT+1的柏林时区, 将时间调到:2015年10月25日01点59分59秒,再过一秒, 就是2015年10月25日02点00分00秒。 将时间调到:2015年10月25日02点59分59秒, 再过一秒,还是2015年10月25日02点00分00秒。这样一来, 实际上有两个小时点被挤在一起了。
我国也曾经采用过夏令时, 但后来被废止了, 也好, 不然现在的程序猿可又要麻烦很多
![](https://oscdn.geek-share.com/Uploads/Images/Content/201707/33c29e3268d66ef5c09858efe40a3635.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201707/33c29e3268d66ef5c09858efe40a3635.gif)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201707/33c29e3268d66ef5c09858efe40a3635.gif)
相关文章推荐
- Asp.Net大型项目实践(8)-从最简单开始一个ExtJs做的登录页(附源码,在线demo)
- TNND终于确认了.Net 3.0中的一个“Bug”
- 【实践】一个简单却五脏俱全的JavaScript“类”例子
- J2EE实践第一部分-创建一个简单的JSF Web程序(简单网页计算器)
- (Java2D 学习笔记系列) (一)一个简单的图像填充实例及其分析理解
- 实践中Javascript使用RegExp.$1导致trim()自定义函数的一个Bug
- 交接工作不要只分析流程和看静态的看代码呀,一定要动手,增加一个功能,解决一个 BUG什么的,才能真正理解交接的工作内容呀!
- Silverlight学习笔记一(理解一下机制,使用一下布局,实现一个简单的用户登录)
- 菜鸟发问,请各位不吝赐教啊! 关于一个简单的程序的理解问题
- ExtJs实践(2)——ExtJs在IE下存在的一个bug
- hibernate3.2.6终于修复一个bug
- 单步执行遇到的离奇问题?一个简单的赋值语句都执行失败的bug
- 对Jena的简单理解和一个例子(下)
- 对Jena的简单理解和一个例子(上)
- JSP-一个理解MVC架构的简单的登陆、注册例子
- 最近做毕业设计发现市场上的Delphi书中关于TArrayField的一个错误理解,这里现简单的提一下以后有时间在好好的研究一下
- 对Jena的简单理解和一个例子
- [摘]终于找到一个有助理解left/right/full outer join的例子
- (Java2D 学习笔记系列) (一)一个简单的图像填充实例及其分析理解
- Spring框架讲解-一个简单的实践