最近碰到了一些关于时间的问题, 网上搜了一下后得到了很多时间处理的方法,在此和大家分享一下
首先了解一下两个标准时间
1.GMT和UTC
1.1 GMT
格林尼治标准时间 (Greenwich Mean Time,GMT)是指位于英国伦敦郊区的皇家格林尼治天文台当地的标准时间,因为本初子午线被定义为通过那里的经线。
自1924年2月5日开始,格林尼治天文台负责每隔一小时向全世界发放调时信息。
理论上来说,格林尼治标准时间的正午是指当太阳横穿格林尼治子午线时(也就是在格林尼治上空最高点时)的时间。但由于地球在它的椭圆轨道里的运动速度不均匀,这个时刻可能与实际的太阳时有误差,最大误差达16分钟。原因在于地球每天的自转是有些不规则的,而且正在缓慢减速,因此格林尼治时间基于天文观测本身的缺陷,已经不再被作为标准时间使用。现在的标准时间,是由原子钟报时的协调世界时(UTC)来决定。
1.2 UTC
协调世界时, 又称世界标准时间或世界协调时间,简称UTC(Coordinated Universal Time)是最主要的世界时间标准,其以原子时秒长为基础,在时刻上尽量接近于格林尼治标准时间。
协调世界时是世界上调节时钟和时间的主要时间标准,它与0度经线的平太阳时相差不超过1秒[1],并不遵守夏令时。协调世界时是最接近格林威治标准时间(GMT)的几个替代时间系统之一。对于大多数用途来说,UTC时间被认为能与GMT时间互换,但GMT时间已不再被科学界所确定。
如果本地时间比UTC时间快,例如中国大陆[a]、香港、澳门、台湾、蒙古国、新加坡、马来西亚、澳大利亚西部的时间比UTC快8小时,就会写作UTC+8,俗称东8区。相反,如果本地时间比UTC时间慢,例如夏威夷的时间比UTC时间慢10小时,就会写作UTC-10,俗称西10区。
以上是我从维基百科摘选下来的部分解释.可以了解一下
2.NSDate
2.1 NSDate使用方法
NSDate *date = [NSDate date];
NSLog(@"%@",currentDate);
NSLog(@“current date interval: %f”, [date timeIntervalSinceReferenceDate]);
输出后的结果:
2017-06-21 16:21:34.577 Time[44723:2002871] 2017-06-21 08:21:34 +0000
2017-06-21 16:21:34.578 Time[44723:2002871] current date interval: 519726094.576822
timeIntervalSinceReferenceDate返回的是距离参考时间的偏移量,这个偏移量的值为519726094秒,502945767/86400/365=15.9483056506,86400是一天所包含的秒数,365大致是一年的天数,15.94当然就是年数了,算出来刚好是此刻距离2001年的差值。
北京时间为UTC+8小时,所以当我们使用NSDate打印出当前的时间戳的时候,是当前的时间减去8小时.
并且NSDate受系统时间控制的,也就是说,当你修改了手机上的时间显示,NSDate获取当前时间的输出也会随之改变。在我们做App的时候,明白这一点,就知道NSDate并不可靠,因为用户可能会修改它的值。
2.2 转换格式
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSString *dateStr = [dateFormatter stringFromDate:date];
NSLog(@"字符串表示:%@",dateStr);
打印输出: 2017-06-21 16:45:54.405 Time[45415:2026413] 字符串表示:2017-06-21 16:45:54
2.3 获取北京时间,获取昨天此刻,获取明天此刻,昨天和今天的时间差 (NSDate -> NSDate)
//1.获取当前时间 零时区的时间
NSDate *date = [NSDate date];
NSLog(@"当前零时区时间 %@", date);
//2.获得本地时间 东八区 晚八个小时 以秒计时
NSDate *date1 = [NSDate dateWithTimeIntervalSinceNow:8 * 60 * 60];
NSLog(@"今天此时的时间 %@",date1);
//3.昨天此时的时间
NSDate *yesterdayDate = [NSDate dateWithTimeIntervalSinceNow:(-24 + 8) * 60 * 60];
NSLog(@"昨天此时的时间 %@",yesterdayDate);
//4.明天此刻
NSDate *tomorrowDate = [NSDate dateWithTimeInterval:24 * 60 * 60 sinceDate:date1];
NSLog(@"明天此刻的时间 %@",tomorrowDate);
//5.NSTimeInterval 时间间隔(单位:秒)
//昨天此时与明天此刻的时间间隔
NSTimeInterval timeInterval = [tomorrowDate timeIntervalSinceDate:yesterdayDate];
NSLog(@"昨日和明天此刻的时间(秒) %.0f",timeInterval);
打印输出的结果:
当前零时区时间 2017-06-21 08:59:40 +0000
今天此时的时间 2017-06-21 16:59:40 +0000
昨天此时的时间 2017-06-20 16:59:40 +0000
昨天此时的时间 2017-06-20 16:59:40 +0000
昨日和明天此刻的时间(秒) 172800
苹果官方文档关于NSDate的解释
3.gettimeofday
这个API也能返回一个描述当前时间的值
struct timeval time;
gettimeofday(&time,nil);
NSLog(@"gettimeofday: %ld,%d”,time.tv_sec,time.tv_usec);
使用gettimeofday获得的值是Unix Time
Unix Time: 是以UTC 1970年1月1号 00:00:00为基准时间,当前时间距离基准点偏移的秒数。上述API返回的值是1498036308,表示当前时间距离UTC 1970年1月1号 00:00:00一共过了1498036308秒。
实际上NSDate也有一个API能返回Unix time:
NSDate* date = [NSDate date];
NSLog(@”timeIntervalSince1970: %f”, [date timeIntervalSince1970]);
gettimeofday和NSDate,CFAbsoluteTimeGetCurrent()一样,都是受当前设备的系统时间影响。只不过是参考的时间基准点不一样而已。我们和服务器通讯的时候一般使用Unix time。
4.mach_absolute_time()
mach_absolute_time()可能用到的时候比较少,但这个概念非常重要。
前面提到我们需要找到一个均匀变化的属性值来描述时间,而在我们的iPhone上刚好有一个这样的值存在,就是CPU的时钟周期数(ticks)。这个tick的数值可以用来描述时间,而mach_absolute_time()返回的就是CPU已经运行的tick的数量。将这个tick数经过一定的转换就可以变成秒数,或者纳秒数,这样就和时间直接关联了。
不过这个tick数,在每次手机重启之后,会重新开始计数,而且iPhone锁屏进入休眠之后tick也会暂停计数。
mach_absolute_time()不会受系统时间影响,只受设备重启和休眠行为影响。
5.CACurrentMediaTime()
官方文档定义:
/* Returns the current CoreAnimation absolute time. This is the result of
* calling mach_absolute_time () and converting the units to seconds. */
CFTimeInterval CACurrentMediaTime (void)
CACurrentMediaTime()就是将上面mach_absolute_time()的CPU tick数转化成秒数的结果。以下代码
double mediaTime = CACurrentMediaTime();
NSLog(@"CACurrentMediaTime: %f", mediaTime);
返回的就是开机后设备一共运行了(设备休眠不统计在内)多少秒,另一个API也能返回相同的值:
NSTimeInterval systemUptime = [[NSProcessInfo processInfo] systemUptime];
NSLog(@"systemUptime: %f", systemUptime);
打印输出:
2017-06-21 17:23:14.682 NSDate博客Demo[46674:2065572] CACurrentMediaTime: 203416.680109
2017-06-21 17:23:14.682 NSDate博客Demo[46674:2065572] systemUptime: 203416.680286
CACurrentMediaTime()也不会受系统时间影响,只受设备重启和休眠行为影响。