您的位置:首页 > 其它

一个潜伏了4年之久的简单bug终于浮出水面---理解夏令时并实践玩转它

2015-04-07 23:13 309 查看
        最近清明节放了三天假(4月4/5/6),  国外某一版本在6号需要发布。 我呢, 刚好有事没去加班。 结果加班的同事发现了某时间显示出现了差一错误, 需要我在电话中定位,根据同事描述,我当时怀疑是夏令时问题。 下面, 我来简要描述一下。

        问题现象: 某服务端给某客户端返回了一个时间, 客户端显示的时候, 发现多了一个小时。 奇怪的是, 同样的服务端和同样的客户端, 在中国国内就没有问题, 但是, 在国外就有问题。

        问题原因: 服务端返回的时间已经考虑了夏令时, 而客户端把这个时间当成普通的时间, 又考虑了一次夏令时,所以结果多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秒。这样一来, 实际上有两个小时点被挤在一起了。

        我国也曾经采用过夏令时, 但后来被废止了, 也好, 不然现在的程序猿可又要麻烦很多




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐