概述
基础概念
1.GMT 0:00 格林威治标准时间; UTC +00:00 校准的全球时间; CCD
+08:00 中国标准时间
2.iOS中的时间类NSDate中存储的时间,都是相对于GMT的,我们使用NSDate
时(NSDate必须是0时区的,UTC格式的),会根据App设置的当前时区设置返回
与时区对应的数据。
3.iOS中的时区表示方法:GMT+0800 GMT-0800。(+:东区 -:西区 08:小
时数 00:分钟数)。 GMT+0830就是指比GMT早8小时外加30分钟的时区。
4.世界标准时间,国际协调时间,简称UTC。不属于任意时区
5.系统认为NSDate是0时区的,NSString是东八区的
简单说下个人的理解 根据时区可以看到,我们在东八区,时间点比国际标准时间快八小时,而LA在在西7区,时间慢7小时,因此,同一时间下,你切换手机坐标,你获取的时间戳美国比中国的大,因为时间戳的计算都是根据0时区来算的,中国的要减去,美国自然要加上了,有个简单的例子,如果你默认NSDate TimeZone下,你切换计算时间戳是没有问题,但是如果你用东八区的时间戳去使用,肯定比实际上多出来八小时,这个时候如果要上传给服务器,那就尴尬了哈。。。如果你手动切换时区,记得算好时间戳。下面会给例子,有个很重要的思想就是,显示的时候用NSString,但是内部涉及到计算,比较,时间戳的问题,都是要NSDate,这样保证计算出来的东西肯定不会错
代码示例一:不同时区之间的时间转换
// 获取usr/share/zoneinfo目录下所有已知的时区
NSArray *arr = [NSTimeZone knownTimeZoneNames];
// 获取所有时区的缩写
NSDictionary *dict = [NSTimeZone abbreviationDictionary];
NSLog(@"%@",dict);
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd"];
NSString *timeStr = @"2017-05-10";
NSDate *currentDate = [dateFormatter dateFromString:timeStr];
NSLog(@"需要格式化的时区--->%@,格式后的Date--->%@",dateFormatter.timeZone,currentDate);
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];
NSDate *currentDate1 = [dateFormatter dateFromString:timeStr];
NSLog(@"需要格式化的时区--->%@,格式后的Date--->%@",dateFormatter.timeZone,currentDate1);
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"America/Los_Angeles"]];
NSDate *currentDate2 = [dateFormatter dateFromString:timeStr];
NSLog(@"需要格式化的时区--->%@,格式后的Date--->%@",dateFormatter.timeZone,currentDate2);
/*
2017-05-05 14:32:13.893 NSData[10583:4643459] 需要格式化的时区--->Asia/Shanghai (GMT+8) offset 28800,格式后的Date--->2017-05-09 16:00:00 +0000
个人理解:
时间信息都是针对于GMT标准时区来的,那么NSDate是根据当前设置的时区来进行计算的,那么例如上面的时间,默认是上海东八区的话就是向前移动8小时就是0时区的时间,所以打印出来的就是少8小时
OK,我们来设置下dateFormatter的时区为GMT和PDT(美国洛杉矶西七区),也就是NSDate默认为你就在标准时区的坐标下,你给出来的时间根本不需要进行时区的转换,直接显示出来接即可,但是PDT的情况下是西区,时间比0区小,因此要加上7小时
2017-05-05 15:01:52.121 NSData[10996:4659886] 需要格式化的时区--->GMT (GMT) offset 0,格式后的Date--->2017-05-10 00:00:00 +0000
2017-05-05 15:01:52.124 NSData[10996:4659886] 需要格式化的时区--->America/Los_Angeles (PDT) offset -25200 (Daylight),格式后的Date--->2017-05-10 07:00:00 +0000
*/
这一坨简单的代码和上面的图一结合,应该非常清楚的能明白
首先,NSDate是计算0时区的时间,默认情况下NSDateFormmater是获取当前手机设置的时区(咱们的是东八区),因此,这就解释了默认情况下你转换的时间NSDate比字符串少了八个小时,但是如果你手动表示,你就在GMT,那就不需要转换了,直接显示字符串时间,但是如果你说你在LA,西区,自然要加上7小时了
代码示例二:String和Date转换
// 最简单的NSDate和NSString的转换
NSString *timeStr1 = @"2017-5-20";
NSDateFormatter *dateFormatter1 = [[NSDateFormatter alloc] init];
[dateFormatter1 setDateFormat:@"yyyy-MM-dd"];
NSDate *date1 = [dateFormatter1 dateFromString:timeStr1];
// 加上了这句话 转换的时候无需再算上时区,直接转换
// [dateFormatter1 setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];
NSString *resultStr = [dateFormatter1 stringFromDate:date1];
NSLog(@"%@,%@",date1,resultStr);
这简单例子告诉我们,默认不设置时区的情况下,如果你在天朝东八区,你用的时间字符串,转换成NSDate(无论如何算出来的都是GMT/UTC国际标准时间0时期的时间)的时候会减去八小时,但是转换成NSString的时候又会转换成GMT标准时间下的(加上了八小时当前时期东八区)字符串,系统认为NSDate是0时区的,NSString是东八区的
代码示例三:反面教材,可以用TimeZone进行时区切换操作更好
NSDate *date3 = [NSDate date];
NSLog(@"NSDate(0时区标准时间 所在东八区,要减去八小时)----当前时间1%@",date3);
NSDate *date4 = [NSDate dateWithTimeIntervalSinceNow:0];
NSLog(@"NSDate(0时区标准时间 所在东八区,要减去八小时)----当前时间2%@",date4);
NSDate *date5 = [NSDate dateWithTimeIntervalSinceNow:8*60*60];
NSLog(@"NSDate(0时区标准时间 所在东八区,要减去八小时)----当前时间3加上今天此刻时间%@",date5);
NSDate *date6 = [NSDate dateWithTimeIntervalSinceNow:(8-24)*60*60];
NSLog(@"NSDate(0时区标准时间 所在东八区,要减去八小时)----当前时间3昨天此刻时间%@",date6);
NSDate *date7 = [NSDate dateWithTimeIntervalSinceNow:(8+24)*60*60];
NSLog(@"NSDate(0时区标准时间 所在东八区,要减去八小时)----当前时间3明天此刻时间%@",date7);
// 参数1比参数2小返回的是负数
NSTimeInterval timeIntervel = [date6 timeIntervalSinceDate:date7];
NSLog(@"NSDate(0时区标准时间 所在东八区,要减去八小时)----当前时间3昨天和明天时间间隔%.f",timeIntervel);
代码示例四:时间戳秒数转换NSDate注意点
/*
不转换的时候NSDate出来的肯定是没有问题的0时区的时间
*/
NSDate *date8 = [NSDate date];
NSTimeInterval time8 = [date8 timeIntervalSince1970];
NSLog(@"%.f",time8);
NSDate *date9 = [NSDate dateWithTimeIntervalSince1970:1493968897];
NSLog(@"%@",date9);
// 这个例子只是说明,如果你用东八区的时间,然后你又手动修改了你当前的时区,你该到了GMT 0时区,这个时候的时间戳肯定比0时区多出八小时了,
// 你只要明白,正确的时间戳都针对GMT 0时区的国际标准时间为准的,如果前后台需要涉及到时间上传交互,你如果你手动切换了时区,需要注意时区
NSDate *date10 = [NSDate date];
NSDateFormatter *fotmatter10 = [[NSDateFormatter alloc] init];
[fotmatter10 setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSString *string10 = [fotmatter10 stringFromDate:date10];
[fotmatter10 setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];
NSDate *date100 = [fotmatter10 dateFromString:string10];
NSTimeInterval time10 = [date100 timeIntervalSince1970];
NSLog(@"%.f",time10);
NSDate *date11 = [NSDate dateWithTimeIntervalSince1970:1493998268];
NSLog(@"%@",date11);
代码示例五:时间转换格式不对等兼容问题
NSString *timeStringA = @"2017-05-05";
NSDateFormatter *formatterA = [[NSDateFormatter alloc] init];
[formatterA setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSDate *dateA = [formatterA dateFromString:timeStringA];
NSString *timeStringB = @"2017-05-05 00:00:00";
NSDateFormatter *formatterB = [[NSDateFormatter alloc] init];
[formatterB setDateFormat:@"yyyy-MM-dd"];
NSDate *dateB = [formatterB dateFromString:timeStringB];
NSLog(@"-----%@",dateA);---> (null)
NSLog(@"-----%@",dateB);--->(null)
NSDate *dateC = [formatterB dateFromString:[self dateFormatWithoutTimeWithFormatString:@"yyyy-MM-dd" timesString:timeStringB]];
NSLog(@"%@",dateC);2017-05-04 16:00:00 +0000
// 当时间格式和formatter格式不对等的时候会出现null的情况,这个时候你对比时间计算就会出问题
- (NSString *)dateFormatWithoutTimeWithFormatString:(NSString *)formatString timesString:(NSString *)timeStr
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];
NSDateFormatter *dateFormatterNoYearAndSeconds = [[NSDateFormatter alloc] init];
[dateFormatterNoYearAndSeconds setDateFormat:formatString];
[dateFormatterNoYearAndSeconds setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];
return [dateFormatterNoYearAndSeconds stringFromDate:[dateFormatter dateFromString:timeStr]]?:timeStr;
}
很简单的知识点记录下而已,网上有很多关于NSDate的扩展,很多都包装好了,最近处理时间的时候打印看到了一些问题,就仔细看了下,一般来说都不会有问题,只是更加了解下时间时区之前的切换问题,明白一点就够了,NSDate就是0时区的时间点,如果你不手动设置时区,默认咱们就是东八区,时间转换成NSDate就会小八小时,但是转换成NSString默认又会加上时区差,还有一点,切换时间的时候,从默认时区修改成了其他时区,你小心你的时间戳会有时区上的差异,记得最后比较下你转换前的时区和转换后的时区,默认的时间戳也是0时区为准的
最后
以上就是耍酷大雁为你收集整理的关于NSDate,NSDateFormatter,NSTimeZone的一些通俗理解的全部内容,希望文章能够帮你解决关于NSDate,NSDateFormatter,NSTimeZone的一些通俗理解所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复