ios 獲取當前準確時間

獲取當前時間:(之前做倒計時時發現一些bug,這裏對獲取當前時間進行總結)

啓動app時發送服務器時間請求獲取當前最新時間,存儲到內存;

退到後臺或鎖屏手機後再進入前臺情況下最新時間:

這裏處理的方案是將(啓動app時獲取到的服務器時間 - 當時獲取服務器時間時處系統運行時長 + 現在的系統運行時長)

這裏只要能得到系統運行時長即可:

瞭解下ios關於時間的處理:

1.NSDate對象描述的是時間線上的一個絕對的值,和時區和文化無關,它參考的值是:以UTC爲標準的,2001年一月一日00:00:00這一刻的時間絕對值。

NSDate輸出的是絕對的UTC時間(而北京時間的時區爲UTC+8,輸出+8個小時)和市區和文化無關,所以要展示具體格式的時間,我們需要NSDateFormatter和NSTimeZone的輔助。NSDate是受手機系統時間控制的。

2.CFAbsoluteTimeGetCurrent()的概念和NSDate非常相似,只不過參考點是:以GMT爲標準的,2001年一月一日00:00:00這一刻的時間絕對值。也會跟着當前設備的系統時間一起變化。

3.gettimeofday獲得的值是Unix time,Unix time是以UTC 1970年1月1號 00:00:00爲基準時間,當前時間距離基準點偏移的秒數。NSDate也有一個API能返回Unix time:

NSDate* date = [ NSDatedate];

NSLog( @"timeIntervalSince1970: %f", [date timeIntervalSince1970]);

 

gettimeofday和NSDate,CFAbsoluteTimeGetCurrent()一樣,都是受當前設備的系統時間影響。只不過是參考的時間基準點不一樣而已。我們和服務器通訊的時候一般使用Unix time。

 

4.mach_absolute_time()返回的就是CPU已經運行的CPU的時鐘週期數(ticks)。tick的數量可以用來描述時間,將這個tick數經過一定的轉換就可以變成秒數,或者納秒數,這樣就和時間直接關聯了。不過這個tick數,在每次手機重啓之後,會重新開始計數,而且iPhone鎖屏進入休眠之後tick也會暫停計數。mach_absolute_time()不會受系統時間影響,只受設備重啓和休眠行爲影響。

5.CACurrentMediaTime()就是將上面mach_absolute_time()的CPU tick數轉化成秒數的結果。以下代碼:

doublemediaTime = CACurrentMediaTime();

NSLog( @"CACurrentMediaTime: %f", mediaTime);

返回的就是開機後設備一共運行了(設備休眠不統計在內)多少秒,另一個API也能返回相同的值:(原來做倒計時用的就是該API)

NSTimeIntervalsystemUptime = [[NSProcessInfo processInfo] systemUptime];

NSLog( @"systemUptime: %f", systemUptime);

CACurrentMediaTime()也不會受系統時間影響,只受設備重啓和休眠行爲影響。

6.sysctl記錄了上次設備重啓的時間。可以通過如下API調用獲取:#include <sys/sysctl.h>

- ( long)bootTime{

#define MIB_SIZE 2intmib[MIB_SIZE]; size_t size;

structtimeval boottime;

mib[ 0] = CTL_KERN; mib[ 1] = KERN_BOOTTIME;

 size = sizeof(boottime);

if(sysctl(mib, MIB_SIZE, &boottime, &size, NULL, 0) != - 1) {

returnboottime .tv_sec; }

return0;}

返回的值是上次設備重啓的Unix time。

這個API返回的值也會受系統時間影響,用戶如果修改時間,值也會隨着變化。

 

結合上面描述這裏獲取運行時長:

- ( NSTimeInterval)uptime{

structtimeval boottime;

intmib[ 2] = {CTL_KERN, KERN_BOOTTIME};

 size_t size = sizeof(boottime);

structtimeval now;

structtimezone tz;

 gettimeofday(&now, &tz);

doubleuptime = - 1;

if(sysctl(mib, 2, &boottime, &size, NULL, 0) != - 1&& boottime .tv_sec!= 0) {

 uptime = now .tv_sec- boottime .tv_sec;

 uptime += ( double)(now .tv_usec- boottime .tv_usec) / 1000000.0; }

returnuptime;}

gettimeofday和sysctl都會受系統時間影響,但他們二者做一個減法所得的值,就和系統時間無關了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章