iOS時(shí)間戳雜談

前言

在iOS中我們經(jīng)常需要使用到時(shí)間戳,但在iOS下獲取“時(shí)間”的方法有很多。不過總的來說,我們可以在iOS中獲取的時(shí)間戳主要有兩類----絕對時(shí)間與相對時(shí)間。下面將總結(jié)一下這些方法之間的關(guān)系。

1、絕對時(shí)間

絕對時(shí)間是指那些以固定時(shí)間為參考系的時(shí)間戳。

常用的有Foundation框架中的
[[NSDate date] timeIntervalSinceReferenceDate];
以及CoreFoundation框架中的
CFAbsoluteTimeGetCurrent();

上述兩種方法是等價(jià)的,所參考的起始時(shí)間都是世界時(shí)間(UTC)2001年1月1日凌晨,所返回的double類型的結(jié)果都是從參考時(shí)間至今經(jīng)過的秒數(shù)。

除了剛才提到的參考時(shí)間,還有以世界時(shí)間(UTC)1970年1月1日凌晨為參考系的
[[NSDate date] timeIntervalSince1970];

    //打印結(jié)果
    NSLog(@"%f", CFAbsoluteTimeGetCurrent());
    NSLog(@"%f", [[NSDate date] timeIntervalSinceReferenceDate]);
    NSLog(@"%f", [[NSDate date] timeIntervalSince1970]);
    2016-11-29 10:50:35.737 TidusWWDemo[192:4266] 502080635.736519  
    2016-11-29 10:50:35.740 TidusWWDemo[192:4266] 502080635.740338
    2016-11-29 10:50:35.740 TidusWWDemo[192:4266] 1480387835.740696

由于參考系是固定的,顯然每次通過這些方法獲取的時(shí)間戳都將是不同的。但絕對不變的參考系并不意味著絕對可靠的結(jié)果,實(shí)際上當(dāng)用戶手動(dòng)改變了設(shè)備上的系統(tǒng)時(shí)間后,基于系統(tǒng)時(shí)鐘的上述方法返回的結(jié)果也會一同改變。

假如我們想獲取一種不會被用戶手動(dòng)修改而影響的時(shí)間戳,該怎么辦?答案是相對時(shí)間。

2、相對時(shí)間

相對時(shí)間是指以非固定時(shí)間為參考系返回的時(shí)間戳

常用的有Foundation框架中的
[[NSProcessInfo processInfo] systemUptime];
和QuartzCore框架中的
CACurrentMediaTime();

    //打印結(jié)果(一臺剛重啟沒多久的設(shè)備)
    NSTimeInterval systemUptime = [[NSProcessInfo processInfo] systemUptime];
    CFTimeInterval currentTime = CACurrentMediaTime();
    NSLog(@"%f", systemUptime);
    NSLog(@"%f", currentTime);
    2016-11-29 10:50:35.762 TidusWWDemo[192:4266] 487.083420
    2016-11-29 10:50:35.762 TidusWWDemo[192:4266] 487.099180

上面兩種方法獲取到的都是設(shè)備自最近一次啟動(dòng)至今經(jīng)過的時(shí)間戳。CFAbsoluteTimeGetCurrent()方法調(diào)用底層的mach_absolute_time()方法后將結(jié)果轉(zhuǎn)換成秒返回。該結(jié)果是設(shè)備自最近一次啟動(dòng)至今經(jīng)過的時(shí)間,不隨系統(tǒng)時(shí)間改變而改變,但當(dāng)設(shè)備重啟后,該方法返回的結(jié)果也會重置。

3、優(yōu)劣

兩類時(shí)間戳都有各自的特點(diǎn):
絕對時(shí)間參考固定的時(shí)間點(diǎn)返回時(shí)間戳但結(jié)果會受系統(tǒng)時(shí)鐘的影響;
相對時(shí)間在設(shè)備不重啟的情況下總能正確返回某一時(shí)間段內(nèi)流逝的時(shí)間;
所以具體要使用哪種方法獲取時(shí)間戳需要結(jié)合不同的需求場景去選擇。

4、NSDate

獲取到了時(shí)間戳,也許我們需要利用它來轉(zhuǎn)換為時(shí)間并以一定的格式去展示,NSDate轉(zhuǎn)NSString的方法網(wǎng)上有很多,在這里就不再敘述。需要注意的一點(diǎn)是,獲取到絕對時(shí)間戳是以世界時(shí)間(UTC)為準(zhǔn)的,NSDate中保存的日期也是以世界時(shí)間(UTC)為準(zhǔn)的,所以在通過NSDateFormatter轉(zhuǎn)換為NSString的時(shí)候一定要注意當(dāng)前的時(shí)區(qū)。

    NSTimeInterval intervalSince1970 = [[NSDate date] timeIntervalSince1970];
    NSDate *date = [NSDate dateWithTimeIntervalSince1970:intervalSince1970];
    NSLog(@"date中保存的是UTC時(shí)間:%@", date);
    
    //顯示時(shí)需要注意時(shí)區(qū)
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss z"];
    //設(shè)置時(shí)區(qū)
    [formatter setTimeZone:[NSTimeZone timeZoneWithName:@"zh"]];
    NSString *datestring = [formatter stringFromDate:date];
    NSLog(@"北京所在時(shí)區(qū)為東八區(qū):%@", detesting);

    //打印結(jié)果
    2016-11-30 15:35:40.078 TidusWWDemo[59040:21040031] date中保存的是UTC時(shí)間:2016-11-30 07:35:40 +0000
    2016-11-30 15:35:40.079 TidusWWDemo[59040:21040031] 北京所在時(shí)區(qū)為東八區(qū):2016-11-30 15:35:40 GMT+8

5、最后

如果App本身對獲取的時(shí)間精度要求很高,還是直接通過網(wǎng)絡(luò)從服務(wù)器獲取時(shí)間戳?xí)容^保險(xiǎn)。當(dāng)網(wǎng)絡(luò)可用時(shí),直接從服務(wù)器獲取;網(wǎng)絡(luò)不可用時(shí),且設(shè)備沒有被重啟過,可以根據(jù)上一次獲取服務(wù)器時(shí)間戳的時(shí)刻到此時(shí)的時(shí)間差來推算出正確的時(shí)間。

參考資料

all-in-the-timing-keeping-track-of-time-passed-on-ios

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 前言 在iOS開發(fā)過程中,經(jīng)常會和時(shí)間打交道。例如用戶在一個(gè)頁面停留的時(shí)間、兩個(gè)方法哪個(gè)執(zhí)行更快等等。之前對于這部...
    WQ_UESTC閱讀 3,377評論 0 12
  • 做App避免不了要和時(shí)間打交道,關(guān)于時(shí)間的處理,里面有不少門道,遠(yuǎn)不是一行API調(diào)用,獲取當(dāng)前系統(tǒng)時(shí)間這么簡單。我...
    MrPeak閱讀 4,651評論 0 42
  • 轉(zhuǎn)自:iOS關(guān)于時(shí)間的處理 做App避免不了要和時(shí)間打交道,關(guān)于時(shí)間的處理,里面有不少門道,遠(yuǎn)不是一行API調(diào)用,...
    咖啡綠茶1991閱讀 698評論 0 0
  • 在iOS開發(fā)中,經(jīng)常會遇到各種各樣的時(shí)間問題,8小時(shí)時(shí)差,時(shí)間戳,求時(shí)間間隔,農(nóng)歷等等。解決辦法網(wǎng)上比比皆是,但大...
    真巧了_嘿閱讀 2,807評論 0 7
  • 在APP開發(fā)中我們經(jīng)常涉及到時(shí)間這一塊,在請求時(shí)服務(wù)端數(shù)據(jù)時(shí),有時(shí)候會帶上時(shí)間戳,因?yàn)榭蛻舳说臅r(shí)間不是很靠譜(用戶...
    小盟城主閱讀 2,478評論 0 2