跳出NSDate,nsdate
感覺任何語言關於時間的格式化處理,時區的處理都是多的,最近被NSDate的各種問題坑了好久
先看看關於NSDate自己的問題
1.NSDate
NSDate擷取目前時間
NSDate *date=[NSDate date];
[NSDate date],輸出是GMT時間(GMT(Greenwich Mean Time)代表格林尼治標準時間),如果想擷取目前時間需要通過時間戳記進行轉換
+(NSDate *)GetLocalTimeNow:(NSDate *)date{ NSTimeZone *timezone=[NSTimeZone systemTimeZone]; NSInteger interval=[timezone secondsFromGMTForDate:date]; NSDate *localdate=[date dateByAddingTimeInterval:interval]; return localdate;}
初步看起來是沒有問題了,第一步擷取當前時區,第二步計算當前時區和GMT時區的差值,第三步通過時區差將時間增加差值擷取目前時間
輸出目前時間是
"2014-12-16 10:20:58 +0000"
看後面的+0000是不是感覺有不對了,假如當前時區是beijing,那麼時間是不對的了,應該是+0800,這裡我繞了個圈子,其實我們用[NSDate date]獲得的就是目前時間,只不過是GMT的時間,如果我們加自己時區的間隔只不過是把GMT時間添加了8個小時而已,其實相對我們來說吧GMT時間加8小時輸出,換算為我們本地時間的話也會增加8個小時,下面我們用NSString輸出試一下看看
2.NSDate與NSString的轉換
蘋果用NSDateFormatter進行NSDate和NSString之間的轉換,HH代表24小時制,hh代表12小時制
+(NSString *)MakedatetoStr:(NSDate *)date{ NSDateFormatter *datef=[[NSDateFormatter alloc]init]; [datef setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; NSString *datestr=[datef stringFromDate:date]; return datestr;}
這次我們輸入[NSDate date]的時間,看看輸出是不是目前時間
動手試一下,可以看到
2014-12-16 10:20:58
上下代碼是一起啟動並執行,所以可以看出,如果我們使用格式化字串的預設輸出就是本地時間,是不需要進行時間戳記換算的,如果需要時間轉換,只需設定時區就好了
比如
增加一行國外的時區
[datef setTimeZone:[NSTimeZone timeZoneWithName: @"America/Adak"]];
locatime:2014-12-16 11:31:38
GMT : 2014-12-16 03:31:38
America :2014-12-15 17:31:38
但是我想輸出時區怎麼辦呢,如果換了格式怎麼辦呢,我需要找出蘋果的格式化字串說明文檔,通過協助文檔居然找到了蘋果的ISO文檔
Date Field Symbol Table
根據zone格式化字元說明只需增加一個大“Z”即可,年月日小時分秒 時區均是分開的格式化字串,所以你可以隨便排列他們的順序
即
+(NSString *)MakedatetoStr:(NSDate *)date{ NSDateFormatter *datef=[[NSDateFormatter alloc]init]; NSDateFormatter *datef2=[[NSDateFormatter alloc]init]; [datef2 setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"]; [datef setDateFormat:@"Z yyyy-MM-dd HH:mm:ss}"]; [datef setTimeZone:[NSTimeZone timeZoneWithName: @"America/Adak"]]; NSString *datestr=[datef stringFromDate:date]; NSLog(@"locatime%@,GMT:%@,America:%@",[datef2 stringFromDate:date],date,datestr); return datestr;}
locatime2014-12-16 13:41:17 +0800
,GMT:2014-12-16 05:41:17 +0000,
America:-1000 2014-12-15 19:41:17
這樣我們也就能進行反方向的轉換了
+(NSDate *)GetLocalTimeNowFromstr:(NSString *)dateString{ NSDateFormatter *datef=[[NSDateFormatter alloc]init]; [datef setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"]; NSDate *date=[datef dateFromString:dateString]; return date;}
輸入
2014-12-16 13:41:17 +0800
輸出
2014-12-16 05:41:17 +0000
瞧又回到我們一開的GMT時區了
總結一下,其實我們在獲得時間的時候完全不需要在進行時區轉換,所有的地方按GMT時區來作為時間記錄,想用的時候做一下時區轉好就好了,本地時區的轉換又非常的方便
3.NSDate轉.net Json格式時間
通過上一篇介紹,.net格式化Json後的時間格式是/Date(xxxxxxxxxxxxx+xxxx)/,我試過無法通過AFNetwork直接按時間傳入,那麼只能格式化字串了
第一步擷取時間和1970的時間間隔,返回時秒需要換成毫秒,即*1000,但是還會多兩位,使用格式化字串“%0.0lf”來取消小數點
第二步擷取時區數字 獲得當前的時區,返回當前時區和標準時區的時間戳記,單位是秒,需要×100抵消小數點,因為需要的是4位元,需要用零填充%04ld表示不滿足4位用0填充
第三步 擷取時間,拼接字串,這個大家都會吧。。
+(NSString *)MakeJsonDate:(NSDate *)date{ NSTimeInterval interval=[date timeIntervalSince1970]*1000; NSString *datestr=[[NSString alloc]initWithFormat:@"%0.0lf",interval]; NSTimeZone *zone=[NSTimeZone systemTimeZone]; NSInteger zoneinterval=[zone secondsFromGMT]; NSInteger zonenum=zoneinterval/60/60*100; NSString *json=[[NSString alloc]initWithFormat:@"/Date(%@+%04ld)/",datestr,zonenum]; return json;}
至此終於解決這個頭疼的問題了
以後還是用字串來傳遞時間吧。。。。