NSDate辕录、NSTimeZone、NSCalendar和 NSDateFormatter

相關(guān)資源

cocoachina日歷
本篇日歷簡單代碼

NSDate 秒紧、NSTimeZone 幻工、NSCalendar 和 NSDateFormatter

NSDate 、NSTimeZone 效五、NSCalendar和NSDateFormatter這四個類或者說對象都是相互獨立的地消,他們之間有一定的關(guān)系,一定要認清畏妖。

  1. NSDate
// 獲取現(xiàn)在時間脉执,這個時間是現(xiàn)在的格林威治標準時間,和時區(qū)戒劫、語言都沒有關(guān)系
[NSDate date];
  1. NSTimeZone
@property (class, readonly, copy) NSTimeZone *systemTimeZone;
@property (class, copy) NSTimeZone *defaultTimeZone;
@property (class, readonly, copy) NSTimeZone *localTimeZone

說明

  1. defaultTimeZone設置之前半夷,和systemTimeZone共享一個timeZone對象
  2. defaultTimeZone設置之后,會影響NSDateFormatter和NSCalendar的默認時區(qū)(除非單獨設置)迅细。當你獲取defaultTimeZone之后巫橄,獲取的zone就是一個獨立的對象了,即使你重新setDefaultTimeZone:也不會影響它茵典。
  3. localTimeZone更像是一個單例對象(程序范圍內(nèi))湘换,這個實例變量值會跟隨defaultTimeZone的設置而變化。
  1. NSDateFormatter

// 時間戳轉(zhuǎn)換成時間的方法(返回字符串)

  • (NSString *)timeStrWithInterval:(NSString *)interval {
    NSDate *date = [NSDate dateWithTimeIntervalSince1970:[interval doubleValue]/1000.0];
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    formatter.timeZone = [NSTimeZone timeZoneWithName:@"Asia/Shanghai"];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSString *timeString = [formatter stringFromDate:date];
    return timeString;
    }
 > 這里可以看到date格式化會受到時區(qū)影響统阿,反向格式化也一樣彩倚。

4.  NSCalendar
> 1. 日歷,歷法扶平,一般歷法都是遵循固定的規(guī)則的帆离,具有周期性。日歷都是已知的或可預測的结澄。

> 2. NSDate是獨立與任何歷法的哥谷,它只是時間相對于某個時間點的時間差岸夯;NSDate是進行日歷計算的基礎。

> 3. 下面的兩個例子(在**獲取日歷一周索引值**標題下)们妥,已經(jīng)清晰反映了TimeZone和日歷的關(guān)系猜扮。
> 通過[[NSCalendar currentCalendar] setTimeZone:[NSTimeZone localTimeZone]]對日歷設置時區(qū);


**其他重要API**

// 當前時間對應的星期幾(索引)
[[NSCalendar currentCalendar] ordinalityOfUnit:NSCalendarUnitWeekday inUnit:NSCalendarUnitWeekOfMonth forDate:[NSDate date]];

// 當前時間對應的周是當前月中的第幾周
[[NSCalendar currentCalendar] ordinalityOfUnit:NSCalendarUnitWeekOfMonth inUnit:NSCalendarUnitYear forDate:[NSDate date]];
[[NSCalendar currentCalendar] ordinalityOfUnit:NSCalendarUnitWeekOfMonth inUnit:NSCalendarUnitMonth forDate:[NSDate date]];

// 當前時間對應的周是當前年中的第幾周
[[NSCalendar currentCalendar] ordinalityOfUnit:NSCalendarUnitWeekOfYear inUnit:NSCalendarUnitYear forDate:[NSDate date]];

#### 獲取日歷一周索引值

NSCalendar *calendar = [NSCalendar currentCalendar]; // 
NSLog(@"FirstWeekday = %ld",calendar.firstWeekday);//默認值 是 1。
[calendar setFirstWeekday:1]; //  設定日歷每周的第一天從星期幾開始王悍,比如:如需設定從星期日開始(“開始”意味著日歷的第一天(索引為1)對應的是星期天)破镰,則value傳入1 ,如需設定從星期一開始压储,則value傳入2 鲜漩,以此類推。


// 這里到天day和hour
NSDateComponents *comp = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour fromDate:date];
NSLog(@"date = %@",date); // 2017-05-18 11:27:37 +0000
NSLog(@"dayComponet = %ld",comp.day);// 打印結(jié)果是18
NSLog(@"HourComponet = %ld",comp.hour);// 14H
// 從打印結(jié)果可以看出集惋,calendar先把date加了3個小時孕似,再處理component

// newDate
NSDate *newDate = [calendar dateFromComponents:comp];
NSLog(@"newDate = %@", newDate);// 2017-05-18 11:00:00 +0000 ,也就是說從calendar取出來的date是受NSTimeZone限制的。
// 從打印結(jié)果分析刮刑,calendar先components取出數(shù)值喉祭,再減去3小時。

// 設置為這個月的第一天
[comp setDay:1]; // 把comp的day屬性設置為一號雷绢,即comp是5月1號14H
NSLog(@"dateComponet = %ld",comp.day);// 打印結(jié)果是1
NSDate *firstDayOfMonthDate = [calendar dateFromComponents:comp];
NSLog(@"firstDayOfMonthDate = %@",firstDayOfMonthDate);// 2017-05-01 11:00:00 +0000
NSDateFormatter *fommatter = [[NSDateFormatter alloc] init];
[fommatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSString *timeString = [fommatter stringFromDate:firstDayOfMonthDate];
NSLog(@"timeStr = %@",timeString);// 2017-05-01 14:00:00,這里可以看出fommatter也受時區(qū)影響泛烙。

// 經(jīng)測試firstDayOfMonthDate 取值在2017-04-40 21:00:00 +0000 ~ 2017-05-01 21:00:00 +0000(不包括)之間,下面方法返回結(jié)果都一樣翘紊,所以Calendar 受TimeZone影響蔽氨,會給date自動加3小時。
NSUInteger firstWeekday = [calendar ordinalityOfUnit:NSCalendarUnitWeekday inUnit:NSCalendarUnitWeekOfMonth forDate:firstDayOfMonthDate]; // 這個月第一天在當前日歷的順序
// 返回某個特定時間(date)其對應的小的時間單元(smaller)在大的時間單元(larger)中的順序位置(索引值)

// 如果這里值是2帆疟,因為前面設置的周日是第一位置鹉究,所以這里的索引2,對應的應該是周一踪宠。
NSLog(@"firstWeekday = %ld",firstWeekday);
> 本次代碼分析的是component保留hour的情況自赔,下面gif圖是本人在第二天的運行的截圖,上面代碼分析是在18號柳琢。
> ![Calendar1.gif](http://upload-images.jianshu.io/upload_images/3448645-af67f4a9d587bd54.gif?imageMogr2/auto-orient/strip)


NSCalendar *calendar = [NSCalendar currentCalendar];
NSLog(@"FirstWeekday = %ld",calendar.firstWeekday);//默認值 是 1绍妨。
[calendar setFirstWeekday:2];

NSLog(@"date = %@",date); // 如果是5月31號21:00到6.1號21點(不包括)
// 這里只到天day
NSDateComponents *comp = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:date];
NSLog(@"dateComponet = %ld",comp.day);// 打印結(jié)果是1,component 是6.1

// newDate
NSDate *newDate = [calendar dateFromComponents:comp];
NSLog(@"newDate = %@",newDate);// 這里的結(jié)果會是5月31號 21:00:00 +0000

// 設置為這個月的第一天
[comp setDay:1]; // 把comp的day屬性設置為一號染厅,即comp是6月1號
NSLog(@"dateComponet = %ld",comp.day);// 打印結(jié)果是1
NSDate *firstDayOfMonthDate = [calendar dateFromComponents:comp];
NSLog(@"date = %@",firstDayOfMonthDate);// 05-31 21:00:00 +0000

// 經(jīng)測試firstDayOfMonthDate 取值在2017-04-40 21:00:00 +0000 ~ 2017-05-01 21:00:00 +0000(不包括)之間痘绎,下面方法返回結(jié)果都一樣。date會加3個小時肖粮,變成6月份的日歷。
NSUInteger firstWeekday = [calendar ordinalityOfUnit:NSCalendarUnitWeekday inUnit:NSCalendarUnitWeekOfMonth forDate:firstDayOfMonthDate]; // 這個月第一天在當前日歷的順序
// 返回某個特定時間(date)其對應的小的時間單元(smaller)在大的時間單元(larger)中的順序位置(索引值)

// 這里值是1尔苦,因為前面設置的周一是第一位置涩馆,所以這里的索引1行施,對應的就是周一。
NSLog(@"firstWeekday = %ld",firstWeekday);

> 本次代碼分析的是component只保留到day的情況 魂那。下面gif圖是本人在第二天的運行的截圖蛾号,上面代碼分析是在18號。
> ![Calendar.gif](http://upload-images.jianshu.io/upload_images/3448645-e90a6a4e3710ebb9.gif?imageMogr2/auto-orient/strip)

> 上面兩個例子都沒有問題涯雅,關(guān)鍵是
> 
> 1. 涉及到TimeZone鲜结,對TimeZone對象的分析很關(guān)鍵。[NSTimeZone setDefaultTimeZone:[NSTimeZone timeZoneWithName:@"Europe/Vilnius"]]的設置沒在上面代碼中顯示活逆,這是歐洲東時區(qū)三區(qū)的一個設置精刷,也可以通過單獨設置日歷的時區(qū)對象屬性。
> 2. 第二個關(guān)鍵部分是:找到對應月份和當前月對應的第一天蔗候,只要確保月份沒有找錯(component對應的月份就是最關(guān)鍵的月份)怒允,邏輯上就是對的。 如果date(格林威治標準時間GMT([NSDate date]))是5月31號21:00锈遥,component對應的數(shù)字就是6(month)和1(day)纫事,日歷內(nèi)部對應的“日期”就是6月1號00:00(以東三時區(qū)為例);component設置第一天對應的相關(guān)數(shù)值也是6(month)和1(day)所灸,然后用日歷轉(zhuǎn)化為date就是5月31號21:00丽惶,日歷內(nèi)部對應的“日期”就是6月1號00:00。

> 3. 第三個關(guān)鍵部分是:找到第一個“日期”對應的星期數(shù)爬立,用的時間(NSDate)可能是上個月的時間钾唬,比如:date(格林威治標準時間GMT([NSDate date]))是5月31號21:00,然而時間對應“日期”(6月1號00:00)才是日歷要查詢的依據(jù)(日歷會根據(jù)TimeZone自動調(diào)整date成“日期”)懦尝。

**找到日期對應月的第一天日期(更直接的方法)**
> 下面方法更直接知纷,但是通過上面的代碼,我們可以更好地分析本月第一天會是上個月的日期的情況陵霉。

  • (NSDate *)firstDayOfCurrentMonthForDate:(NSDate *)date {
    NSDate *startDate = nil;
    BOOL ok = [[NSCalendar currentCalendar] rangeOfUnit:NSMonthCalendarUnit startDate:&startDate interval:NULL forDate:date];
    return startDate;
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末琅轧,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子踊挠,更是在濱河造成了極大的恐慌乍桂,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件效床,死亡現(xiàn)場離奇詭異睹酌,居然都是意外死亡,警方通過查閱死者的電腦和手機剩檀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門憋沿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人沪猴,你說我怎么就攤上這事辐啄〔烧拢” “怎么了?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵壶辜,是天一觀的道長悯舟。 經(jīng)常有香客問我,道長砸民,這世上最難降的妖魔是什么抵怎? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮岭参,結(jié)果婚禮上反惕,老公的妹妹穿的比我還像新娘。我一直安慰自己冗荸,他們只是感情好承璃,可當我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蚌本,像睡著了一般盔粹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上程癌,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天舷嗡,我揣著相機與錄音,去河邊找鬼嵌莉。 笑死进萄,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的锐峭。 我是一名探鬼主播中鼠,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼沿癞!你這毒婦竟也來了援雇?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤椎扬,失蹤者是張志新(化名)和其女友劉穎惫搏,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蚕涤,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡筐赔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了揖铜。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片茴丰。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出较沪,到底是詐尸還是另有隱情鳞绕,我是刑警寧澤失仁,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布尸曼,位于F島的核電站,受9級特大地震影響萄焦,放射性物質(zhì)發(fā)生泄漏控轿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一拂封、第九天 我趴在偏房一處隱蔽的房頂上張望茬射。 院中可真熱鬧,春花似錦冒签、人聲如沸在抛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽刚梭。三九已至,卻和暖如春票唆,著一層夾襖步出監(jiān)牢的瞬間朴读,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工走趋, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留衅金,地道東北人。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓簿煌,卻偏偏與公主長得像氮唯,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子姨伟,可洞房花燭夜當晚...
    茶點故事閱讀 43,612評論 2 350

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

  • iOS開發(fā)中惩琉,經(jīng)常會遇到各種各樣的時間問題,8小時時差授滓,時間戳琳水,求時間間隔,農(nóng)歷等等般堆。解決辦法網(wǎng)上比比皆是在孝,但大多...
    小李龍彪閱讀 6,310評論 1 6
  • 在iOS開發(fā)中,經(jīng)常會遇到各種各樣的時間問題淮摔,8小時時差私沮,時間戳,求時間間隔和橙,農(nóng)歷等等仔燕。解決辦法網(wǎng)上比比皆是造垛,但大...
    真巧了_嘿閱讀 2,764評論 0 7
  • GitHub: https://github.com/GardenerYunEmail: gardeneryun@...
    園丁云閱讀 5,360評論 3 38
  • 小喬初嫁周郎,三國廝殺正酣晰搀。青春敗給煙火五辽,宅男摔了鍵盤。
    王摩詰閱讀 204評論 0 0