iOS时间格式转换总结

在iOS程序开发中,有时需要将时间转换成我们需要的格式。如果服务器返回的时间格式是时间戳,转换起来相对比较简单;但是如果给的不是时间戳转换起来可能稍微麻烦一点。返回的什么格式可以协商,返回的时间的样式要统一,不要这里返回时间戳,那里返回标准时间。

UTC、GMT和时间戳简介

GMT

格林尼治标准时间(Greenwich Mean Time,GMT)是指位于英国伦敦郊区的皇家格林尼治天文台的标准时间,即本初子午线时间。

由于地球在它的椭圆轨道里的运动速度不均匀,这个时刻可能与实际的太阳时有误差,最大误差达16分钟。

地球每天的自转是有些不规则的,而且正在缓慢减速,因此格林尼治时间已经不再被作为标准时间使用。

UTC

协调世界时间(又称世界标准时间),与 GMT 一样都是本初子午线时间,只不过 UTC 是经过协调后的世界时间,比 GMT 更加准确。

全球共有二十四个时区,格林尼治时间指本初子午线时间(东经和西经交界处),北京位于东八区。

时区差东为正,西为负。因此,把东八区时区差记为 +0800。

时间戳

时间戳是指格林尼治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。

代码部分

时间处理类简介

NSDate

用于描述一个特定的时间点,可以获取时间,但没法单独获取年,月,日等信息。 提供方法来获得时间(过去,当前,未来都可以),计算两个时间之间的间隔,比较时间,描述时间内容。

1
2
// 获取当前时间
NSDate *date = [NSDate date];

NSDateFormatter

用于描述 date 的显示格式,配合 NSDate 使用。可以设置时间显示格式,日期格式,时间格式,还有时区等等,最方便的是,你还可以设置AM/PM,月份,星期的显示内容。

NSDateComponents

可以得到我们比较熟悉的年月日时分秒信息,在一些计算显示场合很有用处,用NSDate类是无法单独来获得每一个元素信息的,必须使用这个NSDateComponents类。

NSCalendar

用来描述一种特定的日历。同时还提供了大部分基于时间计算的接口,并且把NSDate类和NSDateComponents类联系了起来。

字符说明

(:)

时间分隔符。在某些区域设置中,可以使用其他字符表示时间分隔符。时间分隔符在格式化时间值时分隔小时、分钟和秒。格式化输出中用作时间分隔符的实际字符由您的应用程序的当前区域性值确定。

(/)

日期分隔符。在某些区域设置中,可以使用其他字符表示日期分隔符。日期分隔符在格式化日期值时分隔日、月和年。格式化输出中用作日期分隔符的实际字符由您的应用程序的当前区域性确定。

(%)

用于表明不论尾随什么字母,随后字符都应该以单字母格式读取。也用于表明单字母格式应以用户定义格式读取。有关更多详细信息,请参见下面的内容。

d

将日显示为不带前导零的数字(如 1)。如果这是用户定义的数字格式中的唯一字符,请使用 %d。

dd

将日显示为带前导零的数字(如 01)。

EEE

将日显示为缩写形式(例如 Sun)。

EEEE

将日显示为全名(例如 Sunday)。

M

将月份显示为不带前导零的数字(如一月表示为 1)。如果这是用户定义的数字格式中的唯一字符,请使用 %M。

MM

将月份显示为带前导零的数字(例如 01/12/01)。

MMM

将月份显示为缩写形式(例如 Jan)。

MMMM

将月份显示为完整月份名(例如 January)。

gg

显示时代/纪元字符串(例如 A.D.)

h

使用 12 小时制将小时显示为不带前导零的数字(例如 1:15:15 PM)。如果这是用户定义的数字格式中的唯一字符,请使用 %h。

hh

使用 12 小时制将小时显示为带前导零的数字(例如 01:15:15 PM)。

H

使用 24 小时制将小时显示为不带前导零的数字(例如 1:15:15)。如果这是用户定义的数字格式中的唯一字符,请使用 %H。

HH

使用 24 小时制将小时显示为带前导零的数字(例如 01:15:15)。

m

将分钟显示为不带前导零的数字(例如 12:1:15)。如果这是用户定义的数字格式中的唯一字符,请使用 %m。

mm

将分钟显示为带前导零的数字(例如 12:01:15)。

s

将秒显示为不带前导零的数字(例如 12:15:5)。如果这是用户定义的数字格式中的唯一字符,请使用 %s。

ss

将秒显示为带前导零的数字(例如 12:15:05)。

S(SS,SSS)

显示毫秒

aa(a)

对于使用 12 小时制的区域设置,对中午之前任一小时显示大写的 AM,对中午到 11:59 P.M 之间的任一小时显示大写的 PM。

对于使用 24 小时制的区域设置,不显示任何字符。

y

将年份 (0-9) 显示为不带前导零的数字。如果这是用户定义的数字格式中的唯一字符,请使用 %y。

yy

以带前导零的两位数字格式显示年份(如果适用)。

yyy

以四位数字格式显示年份。

yyyy

以四位数字格式显示年份。

z

显示不带前导零的时区偏移量(如 -8)。如果这是用户定义的数字格式中的唯一字符,请使用 %z。

zz

显示带前导零的时区偏移量(例如 -08)

zzz

显示完整的时区偏移量(例如 -08:00)

格式显示

M/d/yy —–> 12/7/58

d-MMM —–> 7-Dec

d-MMMM-yy —–> 7-December-58

d MMMM —–> 7 December

MMMM yy —–> December 58

hh:mm tt —–> 08:50 PM

h:mm:ss t —–> 8:50:35 P

H:mm —–> 20:50

H:mm:ss —–> 20:50:35

M/d/yyyy H:mm —–> 12/7/1958 20:50

yyyy-MM-dd HH:mm:ss.SSS —–> 2014-09-10 09:12:10.000

yyyy-MM-dd HH:mm:ss —–> 2014-09-10 09:12:10

yyyy-MM-dd —–> 2014-09-10

MM dd yyyy —–> 09 10 2014

EEE, yyyy-MM-dd HH:mm:ss —–> Tue 2014-09-10 09:12:10

使用实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// 获取当前时间
NSDate *date = [NSDate date];

// 根据时间戳获取时间
NSDate *date = [NSDate dateWithTimeIntervalSince1970:timeInterval];

// 距离当前时间 timeInterval 秒的时间
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:timeInterval];

// 将 Jul 22, 2014 9:00:00 AM 格式的时间转换成时间戳
NSString *time = @"Jul 22, 2014 9:00:00 AM";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"MMM dd, yyyy hh:mm:ss aa"];
[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]];
// 使用系统默认的会有8个小时的时差
// [dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
// 使用这种方式也可以
// [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:8]];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]]; // 或GMT
NSDate *date = [dateFormatter dateFromString:time];
NSLog(@"date:%@",date);
NSTimeInterval timeInterval = [date timeIntervalSince1970];
NSLog(@"%f",timeInterval);

// 将20110826134106转换成特定的时间字符串
NSString *time = @"20110826134106";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyyMMddHHmmss"];
[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];
NSDate *date = [dateFormatter dateFromString:time];
NSLog(@"date:%@",date);
[dateFormatter setDateFormat:@"EEE, yyyy-MM-dd HH:mm:ss"];
NSString *string = [dateFormatter stringFromDate:date];
NSLog(@"string:%@",string);

// 将Wed, 05 May 2011 10:50:00 +0800转换成特定的时间字符串
NSString *time = @"Wed, 05 May 2011 10:50:00 +0800";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"EEE, dd MM yyyy HH:mm:ss ZZZ"];
[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]];
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
NSDate *date = [dateFormatter dateFromString:time];
NSLog(@"date:%@",date);
[dateFormatter setDateFormat:@"EEE, yyyy-MM-dd HH:mm:ss"];
NSString *string = [dateFormatter stringFromDate:date];
NSLog(@"string:%@",string);

// 获取年、月、日、星期等
NSString *time = @"2016-06-01 11:00:00";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];
NSDate *date = [dateFormatter dateFromString:time];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comps = [[NSDateComponents alloc] init];
NSInteger unitFlags = NSYearCalendarUnit |NSMonthCalendarUnit |NSDayCalendarUnit |NSWeekdayCalendarUnit |NSHourCalendarUnit |NSMinuteCalendarUnit |NSSecondCalendarUnit;
comps = [calendar components:unitFlags fromDate:date];
NSInteger week = [comps weekday];
NSInteger year = [comps year];
NSInteger month = [comps month];
NSInteger day = [comps day];

// 判断日期是否在本周内
-(BOOL)isDateThisWeek:(NSDate *)date {

NSDate *start;
NSTimeInterval extends;

NSCalendar *cal=[NSCalendar autoupdatingCurrentCalendar];
NSDate *today=[NSDate date];

BOOL success= [cal rangeOfUnit:NSWeekCalendarUnit startDate:&start interval: &extends forDate:today];

if(!success)
return NO;

NSTimeInterval dateInSecs = [date timeIntervalSinceReferenceDate];
NSTimeInterval dayStartInSecs= [start timeIntervalSinceReferenceDate];

if(dateInSecs > dayStartInSecs && dateInSecs < (dayStartInSecs+extends)){
return YES;
}
else {
return NO;
}
}

比较两个日期相差多少时,一般使用时间戳进行比较。(如果你有更好的方法,欢迎分享一下)

NSDateFormatter创建比较慢,最好使用单例。
如果觉得写的不错,那就打赏一下吧!