在iOS开发中,经常会遇到各种各样的时间问题,8小时时差,时间戳,求时间间隔,农历等等。解决办法网上比比皆是,但大多零零散散,很多资料并没有说明其中问题。这里集中总结一下,以便于以后查阅和供大家参考。有我自己的理解,错漏之处请大家吐槽。
NSDate的8小时问题
-
NSDate转字符串时间
初始化一个NSDate时间[NSDate date],获取的是零时区的时间(格林尼治的时间: 年-月-日 时:分:秒: +时区),而北京时间是东八区时间,因为时区不同,所以打印的时间相差了8小时。此刻表示的时间是一样的。
1
2
3
4
5
6
7
|
NSDate *date = [NSDate date];
NSLog(@
"date时间 = %@"
, date);
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@
"yyyy-MM-dd HH:mm:ss Z"
];
NSString *dateStr = [formatter stringFromDate:date];
NSLog(@
"字符串时间 = %@"
, dateStr);
|
打印结果:
1
2
|
2016-12-07 10:44:24.470 timeTest[32743:2995134] date时间 = 2016-12-07 02:44:24 +0000
2016-12-07 10:44:24.471 timeTest[32743:2995134] 字符串时间 = 2016-12-07 10:44:24 +0800
|
打印结果前面的时间是北京时间:2016-12-07 10:44:24.470。而date打印出来的时间显示少了8小时,因为它表示的是零时区(+0000)时间02:44:24。此刻对应东八区的北京时间就是10:44:24。只是时区不同,表示的时间点是一样的。好比1公斤和2斤,重量是一样的。[NSDate date]获取的时间单位是零时区(+0000),我们所要的北京时间的单位是东八区(+0800)。
系统会默认[NSDate date]获取的时间为零时区时间,而经过NSDateFormatter转化为字符串时间就是当前所在时区的准确时间,并没有8小时误差。
-
转字符串时间的时区设定
上文中NSDate时间转为字符串时间并没有设置NSDateFormatter的timeZone。不设置会默认使用当前所在的时区,与设置系统时区formatter.timeZone = [NSTimeZone systemTimeZone]的效果是一样的。
也可以设置时区,获取指定时区的字符串时间
1
2
3
4
5
6
|
NSDate *date = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@
"yyyy-MM-dd HH:mm:ss"
];
formatter.timeZone = [NSTimeZone timeZoneWithName:@
"Asia/Shanghai"
];
//东八区时间
NSString *dateStr = [formatter stringFromDate:date];
NSLog(@
"字符串时间 = %@"
, dateStr);
|
这时获取的时间就是东八区时间,哪怕手机拿到零时区的格林尼治,获取的也是东八区的时间,因为这里指定时区了。也有如下时区指定:
1
2
|
formatter.timeZone = [NSTimeZone timeZoneWithName:@
"Asia/Tokyo"
];
//东九区时间
formatter.timeZone = [NSTimeZone timeZoneWithName:@
"GMT"
];
//零区时间
|
通过下面方法可得到系统支持的时区对应的字符串常量:
1
2
3
4
|
NSArray *zones = [NSTimeZone knownTimeZoneNames];
for
(NSString *zone
in
zones) {
NSLog(@
"时区名 = %@"
, zone);
}
|
时区对照表
-
字符串时间转NSDate
字符串时间转为NSDate时间也会有时区问题。也会遇到有所谓的8小时误差,其实就是时区不同。比如下面的例子:
1
2
3
4
|
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@
"yyyy-MM-dd HH:mm:ss Z"
];
NSDate *newDate = [formatter dateFromString:@
"2016-12-07 14:06:24 +0800"
];
NSLog(@
"newDate = %@"
, newDate);
|
打印结果:
1
|
|