iOS中對時間的理解

經(jīng)常出現(xiàn)的8小時

在代碼中寫到關(guān)于時間的問題時經(jīng)常遇到一個惹人煩的8小時問題,這個就是因為我們是在東八區(qū) ,而有時候后端返給我們的時間是零時區(qū)的時間,東八區(qū)比零時區(qū)要早8小時,比如現(xiàn)在東八區(qū)是中午十二點,零時區(qū)就是凌晨四點,那么我們就需要把零時區(qū)的時間轉(zhuǎn)化為東八區(qū)的時間。
首先看一個例子,獲取當(dāng)前時間字符串:

//通過[NSDate date]返回的一定是零時區(qū)的時間
NSDate *date = [NSDate date];

NSLog(@"date時間 = %@", date);
//如果沒有規(guī)定formatter的時區(qū),那么formatter默認的就是當(dāng)前時區(qū),比如現(xiàn)在在北京就是東八區(qū),在東京就是東九區(qū)
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
//最結(jié)尾的Z表示的是時區(qū),零時區(qū)表示+0000,東八區(qū)表示+0800
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"];
使用formatter轉(zhuǎn)換后的date字符串變成了當(dāng)前時區(qū)的時間
NSString *dateStr = [formatter stringFromDate:date];

NSLog(@"字符串時間 = %@", dateStr);

輸出:

2018-05-31 14:43:07.011223+0800 TimeDemo[4674:167771] date時間 = 2018-05-31 06:43:07 +0000
2018-05-31 14:43:07.011777+0800 TimeDemo[4674:167771] 字符串時間 = 2018-05-31 14:43:07 +080

很重要的一點就是,[NSDate date]返回的是零時區(qū)的時間!返回的是零時區(qū)的時間!返回的是零時區(qū)的時間!

打印結(jié)果前面的時間是北京時間,為2018-05-31 14:43:07.011223,而通過[NSDate date]得到的時間是2018-05-31 06:43:07 +0000,后面的+0000就表示了這個時間是零時區(qū)的時間,這個時間對應(yīng)的東八區(qū)的時間就是2018-05-31 14:43:07.011223 +0800了。這兩個時間是同一個時間,只不過時區(qū)不一樣。

formatter在不特意設(shè)置時區(qū)的情況下,默認時區(qū)是當(dāng)前地區(qū)的時區(qū),比如我們?nèi)绻谥袊?dāng)前時區(qū)就是東八區(qū),我們?nèi)绻咽謾C拿到東京,當(dāng)前時區(qū)就是東九區(qū)。經(jīng)過formatter轉(zhuǎn)化為時間字符串后時間就變成了當(dāng)前時區(qū)也就是東八區(qū)的時間2018-05-31 14:43:07 +080,也就沒有了8小時的誤差。

轉(zhuǎn)字符串時間的時區(qū)設(shè)置

上面例子中NSDate時間轉(zhuǎn)字符串時間時,NSDateFormatter并沒有設(shè)置時區(qū),而是使用當(dāng)前地區(qū)的時區(qū),這和設(shè)置系統(tǒng)系統(tǒng)時區(qū)formatter.timeZone = [NSTimeZone systemTimeZone]的效果是一樣的。我們也可以規(guī)定一定使用某一個時區(qū):

NSDate *date = [NSDate date];
    
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    
 [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    
   formatter.timeZone = [NSTimeZone timeZoneWithName:@"Asia/Shanghai"];//東八區(qū)時間
    
NSString *dateStr = [formatter stringFromDate:date];
    
NSLog(@"字符串時間 = %@", dateStr);

這樣不管我們的手機是在哪里,打印出來的時間都是東八區(qū)的時間。
還有如下的時區(qū)指定:

formatter.timeZone = [NSTimeZone timeZoneWithName:@"Asia/Tokyo"];//東九區(qū)時間

formatter.timeZone = [NSTimeZone timeZoneWithName:@"GMT"];//零區(qū)時間
formatter.timeZone = [NSTimeZone timeZoneWithName:@"UTC"];//零區(qū)時間,和GMT一樣

字符串時間轉(zhuǎn)NSDate

字符串時間轉(zhuǎn)NSDate也會有時間問題,看下面的例子:

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"];
    
    NSDate *newDate = [formatter dateFromString:@"2016-12-07 14:06:24 +0800"];
    
    NSLog(@"newDate = %@", newDate);

打印結(jié)果:

2018-05-31 15:22:11.878915+0800 TimeDemo[5236:189492] newDate = 2016-12-07 06:06:24 +0000

我們看到這樣轉(zhuǎn)化后就出現(xiàn)了問題轉(zhuǎn)后之后得到的時間的時區(qū)又變成了零時區(qū)。問題就出在,凡是返回結(jié)果為NSDate類型的,得到的時間都是零時區(qū),都是零時區(qū)!都是零時區(qū)!
如果上面給出的字符串時間是@"2016-12-07 14:06:24 +0000",也就是這個時間字符串的時區(qū)是零時區(qū),那么得到的結(jié)果就不會有變化。
NSDateFormatter的格式為@"yyyy-MM-dd HH:mm:ss Z",這里面的Z表示的就是時區(qū),我們在傳遞時間字符串的時候也要按照這個規(guī)則在時間后面加上+0800或者+0000這樣表示時區(qū)的。
當(dāng)不指定字符串的時區(qū)時,即NSDateFormatter的格式為@"yyyy-MM-dd HH:mm:ss",這樣傳遞進來的字符串的時區(qū)默認為當(dāng)前時區(qū),轉(zhuǎn)化為NSDate是零時區(qū)時間。

當(dāng)前時間轉(zhuǎn)時間戳

時間戳是指1970年1月1日0時0分0秒到當(dāng)前時間的秒數(shù)。注意這里的當(dāng)前時間是指零時區(qū)的NSDate時間。

NSDate *date = [NSDate date];

NSTimeInterval timeIn = [date timeIntervalSince1970];

NSLog(@"時間戳 = %.0f", timeIn);

打印結(jié)果:

2018-05-31 15:49:48.165702+0800 TimeDemo[5635:205558] 時間戳 = 1527752988

NSDate轉(zhuǎn)當(dāng)前時區(qū)的NSDate時間

NSDate *date = [NSDate date];

NSTimeZone *zone = [NSTimeZone systemTimeZone];
//獲得當(dāng)前時區(qū)和零時區(qū)的秒數(shù)偏移量
NSInteger interval = [zone secondsFromGMTForDate:date];

NSDate *localDate = [date  dateByAddingTimeInterval:interval];

NSLog(@"localDate = %@",localDate);

時間戳和時間字符串的相互轉(zhuǎn)換

時間戳轉(zhuǎn)時間字符串

- (NSString *)convertToTimeStringWithTimeInterval:(NSTimeInterval)timeInterval{
    
    NSDate *date = [NSDate dateWithTimeIntervalSince1970:timeInterval];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"];
    
    NSString *dateStsring = [dateFormatter stringFromDate:date];
    return dateStsring;
}

時間字符串轉(zhuǎn)時間戳

- (NSTimeInterval)convertToTimeIntervalWithTimeString:(NSString *)timeString{
    
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"];
    
    NSDate *date = [dateFormatter dateFromString:timeString];
    NSTimeInterval timeInterval = [date timeIntervalSince1970];
    return timeInterval;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • iOS開發(fā)中,經(jīng)常會遇到各種各樣的時間問題,8小時時差,時間戳,求時間間隔,農(nóng)歷等等。解決辦法網(wǎng)上比比皆是,但大多...
    小李龍彪閱讀 6,742評論 1 6
  • 在iOS開發(fā)中,經(jīng)常會遇到各種各樣的時間問題,8小時時差,時間戳,求時間間隔,農(nóng)歷等等。解決辦法網(wǎng)上比比皆是,但大...
    真巧了_嘿閱讀 2,927評論 0 7
  • 主要有以下幾個類: NSDate:表示一個具體的絕對的時間點。NSTimeZone:表示時區(qū)信息。NSLocale...
    獻國閱讀 5,430評論 0 4
  • 畢業(yè)后進入了圖書出版行業(yè),對象主要是高校教,但是總覺得應(yīng)該還不錯,整天和老師打交道。起初的時候很難,我不...
    mi婭的coffee閱讀 241評論 0 0

友情鏈接更多精彩內(nèi)容