ios時間那點事--NSCalendar NSDateComponents

#iOS時間那點事.net

##NSCalendar + NSDateComponentscode

  1. 曆法能令人類肯定每一日再無限的時間中的確切位置並記錄歷史。
  2. 日曆,曆法,通常曆法都是遵循固定的規則的,具備週期性。日曆都是已知的或可預測的。
  3. 任何一種具體的歷法,首先必須明確規定起始點,即開始計算的年代,這叫「紀元」;以及規定一年的開端,這叫「歲首」。此外,還要規定每一年所含的日數,如何劃分月份,每個月有多少天等等。
  4. NSCalendar對世界上現存的經常使用的歷法進行了封裝,既提供了不一樣曆法的時間信息,又支持日曆的計算。
  5. NSDateFomatter表示的時間默認以公曆(即陽曆)爲參考,能夠經過設置calendar屬性變量得到特定曆法下的時間表示。
  6. NSDate是獨立與任何曆法的,它只是時間相對於某個時間點的時間差;NSDate是進行日曆計算的基礎。
  7. NSDateComponents將時間表示成適合人類閱讀和使用的方式,經過NSDateComponents能夠快速而簡單地獲取某個時間點對應的「年」,「月」,「日」,「時」,「分」,「秒」,「周」等信息。固然一旦涉及了年月日時分秒就要和某個曆法綁定,所以NSDateComponents必須和NSCalendar一塊兒使用,默認爲公曆。
  8. NSDateComponents除了像上面說的表示一個時間點外,還能夠表示時間段,例如:兩週,三個月,20年,7天,10分鐘,50秒等等。時間段用於日曆的計算,例如:獲取當前曆法下,三個月前的某個時間點。
  9. 能夠說,要獲取某個時間點在某個曆法下的表示,須要NSDateComponents;要計算當前時間點在某個曆法下對應的一個時間段前或後的時間點,須要NSDateComponents。
  10. NSDateComponents返回的day, week, weekday, month, year這一類數據都是從1開始的。由於日曆是給人看的,不是給計算機看的,從0開始就是個錯誤。

####NSDateComponents實例化的方式component

#####第一種:orm

<!-- lang: cpp -->
//	先定義一個遵循某個曆法的日曆對象
NSCalendar *greCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
//	經過已定義的日曆對象,獲取某個時間點的NSDateComponents表示,並設置須要表示哪些信息(NSYearCalendarUnit, NSMonthCalendarUnit, NSDayCalendarUnit等)
NSDateComponents *dateComponents = [greCalendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSWeekCalendarUnit | NSWeekdayCalendarUnit | NSWeekOfMonthCalendarUnit | NSWeekOfYearCalendarUnit fromDate:[NSDate date]];
NSLog(@"year(年份): %i", dateComponents.year);
NSLog(@"quarter(季度):%i", dateComponents.quarter);
NSLog(@"month(月份):%i", dateComponents.month);
NSLog(@"day(日期):%i", dateComponents.day);
NSLog(@"hour(小時):%i", dateComponents.hour);
NSLog(@"minute(分鐘):%i", dateComponents.minute);
NSLog(@"second(秒):%i", dateComponents.second);

//	Sunday:1, Monday:2, Tuesday:3, Wednesday:4, Friday:5, Saturday:6
NSLog(@"weekday(星期):%i", dateComponents.weekday);

//	蘋果官方不推薦使用week
NSLog(@"week(該年第幾周):%i", dateComponents.week);
NSLog(@"weekOfYear(該年第幾周):%i", dateComponents.weekOfYear);
NSLog(@"weekOfMonth(該月第幾周):%i", dateComponents.weekOfMonth);

若獲取dateComponents對象時,設置components的時候未添加NSYearCalendarUnit,dateComponents.year將返回錯誤的數值,其餘的也同樣,因此使用NSDateComponents表示時間時,要確保須要使用的數據都在componets中添加了。對象

#####第二種:blog

<!-- lang: cpp -->
//	先定義一個遵循某個曆法的日曆對象
NSCalendar *greCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

//	定義一個NSDateComponents對象,設置一個時間點
NSDateComponents *dateComponentsForDate = [[NSDateComponents alloc] init];
[dateComponentsForDate setDay:6];
[dateComponentsForDate setMonth:5];
[dateComponentsForDate setYear:2004];

//	根據設置的dateComponentsForDate獲取曆法中與之對應的時間點
//	這裏的時分秒會使用NSDateComponents中規定的默認數值,通常爲0或1。
NSDate *dateFromDateComponentsForDate = [greCalendar dateFromComponents:dc];




//	定義一個NSDateComponents對象,設置一個時間段
NSDateComponents *dateComponentsAsTimeQantum = [[NSDateComponents alloc] init];
[dateComponentsForDate setDay:6];

//	在當前曆法下,獲取6天后的時間點
NSDate *dateFromDateComponentsAsTimeQantum = [greCalendar dateByAddingComponents:dateComponentsAsTimeQantum toDate:[NSDate date] options:0];

#####第三種:ip

<!-- lang: cpp -->
//	先定義一個遵循某個曆法的日曆對象
NSCalendar *greCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

//	根據兩個時間點,定義NSDateComponents對象,從而獲取這兩個時間點的時差
NSDateComponents *dateComponents = [greCalendar components:NSYearCalendarUnit fromDate:[NSDate dateWithTimeIntervalSince1970:0] toDate:[NSDate date] options:0];
NSLog(@"number of years:%i", dateComponents.year);

####NSCalendar中比較重要的方法和概念 #####firstWeekday開發

firstWeekday是你們比較容易渾淆的東西。get

你們在使用dateComponents.weekday獲取某天對應的星期時,會發現,星期日對應的值爲1,星期一對應的值爲2,星期二對應的值爲3,依次遞推,星期六對應的值爲7,這與咱們平時理解的方式不同。而後,咱們就開始找是否是能夠設置這種對應關係。終於,咱們在NSCalendar中發現了firstWeekday這個變量,從字面意思上看貌似就是咱們尋找的那個東西。但是,設置過firstWeekday後,咱們又發現徹底沒有做用,真是鬱悶啊!其實,你們沒必要鬱悶,由於鬱悶也沒用,iOS中規定的就是週日爲1,週一爲2,週二爲3,週三爲4,週四爲5,週五爲6,週六爲7,沒法經過某個設置改變這個事實的,只能在使用的時候注意一下這個規則了。那firstWeekday是幹什麼用的呢?你們設置一下firstWeekday,再獲取一下dateComponents.weekOfYear或dateComponents.weekOfMonth,看看返回的數據是否發生了變化。firstWeekday的做用確實是修改當前曆法中周的起始位置,可是不能修改週日對應的數值,只能修改一年或一個月中周的數量,以及周的次序。it

#####-(NSRange)rangeOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(NSDate *)date;

######答疑解惑:

  1. Unit:單元

  2. NSRange:

    typedef struct _NSRange { NSUInteger location; NSUInteger length; } NSRange;

咱們大體能夠理解爲:某個時間點所在的「小單元」,在「大單元」中的數量(返回值range的location屬性變量的值通常是錯誤的)。例如:

<!-- lang: cpp -->
	//	當前時間對應的月份中有幾天
	[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:[NSDate date]].length;
	//	當前時間對應的月份中有幾周(前面說到的firstWeekday會影響到這個結果)
	[[NSCalendar currentCalendar] rangeOfUnit:NSWeekCalendarUnit inUnit:NSMonthCalendarUnit forDate:[NSDate date]].length;

#####-(NSUInteger)ordinalityOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(NSDate *)date;

咱們大體能夠理解爲:某個時間點所在的「小單元」,在「大單元」中的位置(從1開始)。例如:

<!-- lang: cpp -->
	//	當前時間對應的周是當前年中的第幾周
	[[NSCalendar currentCalendar] ordinalityOfUnit:NSWeekOfYearCalendarUnit inUnit:NSYearCalendarUnit forDate:self];
	[[NSCalendar currentCalendar] ordinalityOfUnit:NSWeekCalendarUnit inUnit:NSYearCalendarUnit forDate:[NSDate date]];
	
	//	當前時間對應的周是當前月中的第幾周
	[[NSCalendar currentCalendar] ordinalityOfUnit:NSWeekOfMonthCalendarUnit inUnit:NSYearCalendarUnit forDate:self];
	[[NSCalendar currentCalendar] ordinalityOfUnit:NSWeekCalendarUnit inUnit:NSMonthCalendarUnit forDate:[NSDate date]];

在這裏:NSWeekOfYearCalendarUnit, NSWeekOfMonthCalendarUnit與NSWeekCalendarUnit的使用結果相同,爲了不渾淆,建議在此處使用NSWeekCalendar,而定義NSDateComponents時使用NSWeekOfYearCalendarUnit和NSWeekOfMonthCalendarUnit。

#####-(BOOL)rangeOfUnit:(NSCalendarUnit)unit startDate:(NSDate **)datep interval:(NSTimeInterval *)tip forDate:(NSDate *)date;

咱們大體能夠理解爲:「某個時間點」所在的「單元」的起始時間,以及起始時間距離「某個時間點」的時差(單位秒)。例如:

<!-- lang: cpp -->
	NSDate *startDateOfYear;
	NSDate *startDateOfMonth;
	NSDate *startDateOfWeek;
	NSDate *startDateOfDay;
	NSTimeInterval TIOfYear;
	NSTimeInterval TIOfMonth;
	NSTimeInterval TIOfWeek;
	NSTimeInterval TIOfDay;
	[[NSCalendar currentCalendar] rangeOfUnit:NSYearCalendarUnit startDate:&startDateOfYear interval:&TIOfYear forDate:[NSDate date]];
	[[NSCalendar currentCalendar] rangeOfUnit:NSMonthCalendarUnit startDate:&startDateOfMonth interval:&TIOfMonth forDate:[NSDate date]];
	[[NSCalendar currentCalendar] rangeOfUnit:NSWeekCalendarUnit startDate:&startDateOfWeek interval:&TIOfWeek forDate:[NSDate date]];
	[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&startDateOfDay interval:&TIOfDay forDate:[NSDate date]];
	NSLog(@"firstDateOfYear:%@, FirstDateOfMonth:%@, FirstDateOfWeek:%@, FirstDateOfDay:%@", startDateOfYear, startDateOfMonth, startDateOfWeek, startDateOfDay);
    NSLog(@"TIOfYear:%f, TIOfMonth:%f, TIOfWeek:%f, TIOfDay:%f", TIOfYear, TIOfMonth, TIOfWeek, TIOfDay);

關於NSCalendar和NSDateComponents的介紹暫時說到這裏。 到目前爲止,已經將iOS開發中關於時間的基本知識介紹完畢,欠缺之處請各位積極批評。

###本系列其餘文章不斷更新中:

  1. iOS時間那點事--NSDate
  2. iOS時間那點事--NSDateFormatter
  3. iOS時間那點事--NSTimeZone
  4. iOS時間那點事--NSLocale
  5. iOS時間那點事--NSCalendar NSDateComponents
相關文章
相關標籤/搜索