iOS 关于NSDate的时区转换差值问题和转换字符串时间

16 篇文章 0 订阅

1、标准时间也叫格林尼治时间,北京所在的东八区时间比标准时间快八个小时。
例如:标准时间为 2000年1月1日 00:00:00
对应的北京时间为2000年1月1日 08:00:00
2 、iOS系统中直接生成的时间都是格林尼治时间,比当前时间(北京时间)小八个小时。

通过Date.init()生成的时间为当前时区的时间所对应的格林尼治时间
通过UIDatePicker所选择的时间为当前时区的时间所对应的格林尼治时间

3、当将NSdate使用DateFormatter转换成字符串时,传入的是格林尼治时间的date,系统会自动转换成当前时区的date,再转换成字符串,转换后的字符串时间对应当前时区的时间,代码如下

//nowDate对应格林尼治时间的date
//dateStr对应当前时区的时间
let nowDate = Date.init()
let f = DateFormatter()
f.dateFormat = "yyyy年MM月dd日 HH:MM:ss"
let dateStr = f.string(from: nowDate)

4、使用NSTimeZone将格林尼治的date转换为当前时区的date

//将格林尼治时间转换为本时区时间
func changeDate(_ oldDate:Date) -> Date {
        let timeZone = NSTimeZone.system
        let seconds = timeZone.secondsFromGMT(for: oldDate)
        return oldDate.addingTimeInterval(TimeInterval(seconds))
}

5、在计算两个date的时间差时,发现一个奇怪的问题,发现UIDatePicker选择范围在86年8月到91年8月之间的日期时,返回的格林尼治时间跟当前时间相差9个小时,而不是8个小时。
如果打印datepicker返回的date,和转换后的字符串比较,就会发现这一时间范围差值为9小时,而不是八小时,
可以在datepicker的valuechanged响应方法里做转换,代码如下

//valuechanged响应方法
 @IBAction func changed(_ sender: UIDatePicker) {
        let date = sender.date

        let f = DateFormatter()
        f.dateFormat = "yyyy年MM月dd日 HH:mm:ss"
        let dateStr = f.string(from: date)

        print("\n 格林尼治时间     \(date) \n 转换后当前时区时间\(dateStr)" )

    }

log输出如下:
 格林尼治时间     2016-06-13 03:52:32 +0000 
 转换后当前时区时间2016061311:52:32

 格林尼治时间     2015-06-13 03:52:32 +0000 
 转换后当前时区时间2015061311:52:32

 格林尼治时间     2014-06-13 03:52:32 +0000 
 转换后当前时区时间2014061311:52:32

这几组是正常的时间,看到转换前后相差8小时,下面把UIDatePicker拨动到86年到91年之间的一个时间范围,

 格林尼治时间     1993-06-13 03:52:32 +0000 
 转换后当前时区时间1993061311:52:32

 格林尼治时间     1992-06-13 03:52:32 +0000 
 转换后当前时区时间1992061311:52:32

 格林尼治时间     1991-06-13 02:52:32 +0000 
 转换后当前时区时间1991061311:52:32

 格林尼治时间     1990-06-13 02:52:32 +0000 
 转换后当前时区时间1990061311:52:32

可以看到93 92年还是相差8小时,但是91 90年就是相差9个小时。

这说明,在这一个范围内,格林尼治时间和当前时区时间错开了一个小时,
如果我们要计算两个date之间的时间间隔,就要先用第4条中的方法将这两个date转换成当前时区的date,再计算时间间隔,否则计算出的时间间隔就多出一个小时。

自己可以用在线计算时间间隔试下。
如图,92年的间隔正常,91年的间隔多了一个小时
92年的间隔正常

91年的间隔多了一个小时

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值