其它:关于时间函数mktime函数夏令时的问题

在很多应用中,我们会用mktime函数进行时间准换操作,但这里面有一个夏令时的操作问题

我们的最终目的是把字符串格式的时间转换为内部使用的“日历时间”,即到UTC 1970年1月1日零时的秒数。这里就存在夏令时的问题。比如俄罗斯时间2008年10月26日2:30由于夏令时的跳变会经过两次,这两次所代表的“日历时间”明显不同。如果仍按照上面的程序,由mktime()函数来决定这个时间是否处于夏令时(它会根据当前时区自动判断,在没有发生时间重叠的情况下处理是正确的)就会有问题。这时我们不能使用ttm.tm_isdst = -1了,而是明确使用ttm_tm_isdst = 1来告知mktime()现在处于夏令时,明确使用ttm.tm_isdst = 0来告知未处于夏令时。
结论:使用字符串时间表示时一定要有标记表示这个时间是否处于夏令时,推荐在时间字符串后面添加DST或者加上时区。否则,无法正确处理夏令时情况。如果时间字符串表示的是UTC时间,则无需上述处理过程。

mktime各种情况测试一下

    在支持不支持夏令时时区,夏令时区间,非夏令时区间,切入夏令时丢失小时时,切出夏令时重复小时时。。tm_isdst 的不同作用

    mktime是用于生成指定的本地时刻的,多数情况下我们都会把tm_isdst设置为-1,这样子可以把指定时刻是否为夏令时交由系统判断.不过实际应用中发现,对于切出夏令时时出现的重复小时,一个小时处于夏令时,一个小时不处于夏令时,因为我们没有指定是否处于夏令时,这时得到的结果便不稳定,可能是处于夏令时的小时,也可能是处于非夏令时的小时.

    下面是测试结果:
    tm中tm_isdst分别为0,1,-1对mktime结果影响.
    tm_isdst = -1(由系统判断)
    对于切入夏令时丢失的小时前的小时,生成时间为指定时间.
    对于切入夏令时丢失的小时,生成时间为指定小时后面一个小时(不受前面mk结果影响)
    对于切入夏令时丢失的小时后的小时,生成时间为指定时间.

    对于切出夏令时重复的小时前的小时,生成时间为指定时间.
    对于切出夏令时重复的小时,生成时间受前面mk结果影响,倘若前次mk时间结果处于夏令时,则结果为处于夏令时的那个小时;倘若前次mk时间结果不处于夏令时,则结果为不处于夏令时的那个小时;
    对于切出夏令时重复的小时后的小时,生成时间为指定时间.

    tm_isdst = 0(指定为非夏令时)
    对于切入夏令时丢失的小时前的小时,生成时间为指定时间.
    对于切入夏令时丢失的小时,生成时间为指定小时后面一个小时(不受前面mk结果影响)
    对于切入夏令时丢失的小时后的小时,生成时间为指定时间后面一个小时.

    对于切出夏令时重复的小时前的小时,生成时间为指定时间后面一个小时.
    对于切出夏令时重复的小时,生成时间为不处于夏令时的那个小时;
    对于切出夏令时重复的小时后的小时,生成时间为指定时间.

    tm_isdst = 1(指定为夏令时)
    对于切入夏令时丢失的小时前的小时,生成时间为指定时间前面一个小时.
    对于切入夏令时丢失的小时,生成时间为指定小时后面一个小时(不受前面mk结果影响)
    对于切入夏令时丢失的小时后的小时,生成时间为指定时间.

    对于切出夏令时重复的小时前的小时,生成时间为指定时间.
    对于切出夏令时重复的小时,生成时间为处于夏令时的那个小时;
对于切出夏令时重复的小时后的小时,生成时间为指定时间前面一个小时.

 

    倘若mktime传入时间因为夏令时存在两个,那mktime会认为该时间可能处于夏令时也可能处于非夏令时。是否处于夏令时由mktime生成的上一个时间决定,倘若上一个时间处于夏令时则生成的该重复时间是处于夏令时的,否则生成的该重复时间是处于非夏令时的。程序内部的原因是它在mktime中用一个静态变量保存夏令时状态,下次生成时间是优先以保存的状态来生成时间。

    倘若mktime一个不存在的夏令时(出现夏令时切换时丢失的那个小时)会直接生成丢失小时的下一个小时。这个结果是确定的稳定的。

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tristan Tsai

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值