基础概念
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,这样保证计算出来的东西肯定不会错
代码示例一:不同时区之间的时间转换
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);
这一坨简单的代码和上面的图一结合,应该非常清楚的能明白 首先,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);
NSTimeInterval timeIntervel = [date6 timeIntervalSinceDate:date7];
NSLog(@
"NSDate(0时区标准时间 所在东八区,要减去八小时)----当前时间3昨天和明天时间间隔%.f",timeIntervel);
代码示例四:时间戳秒数转换NSDate注意点
NSDate *date8 = [
NSDate date];
NSTimeInterval time8 = [date8 timeIntervalSince1970];
NSLog(@
"%.f",time8);
NSDate *date9 = [
NSDate dateWithTimeIntervalSince1970:
1493968897];
NSLog(@
"%@",date9);
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
- (
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时区为准的