ios 獲取時間--NSCalendar NSDateComponents NSDate

NSCalendar + NSDateComponents

  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實例化的方式

第一種:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//  先定義一個遵循某個曆法的日曆對象
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中添加了。

第二種:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//  先定義一個遵循某個曆法的日曆對象
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];
第三種:
?
1
2
3
4
5
6
//  先定義一個遵循某個曆法的日曆對象
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是大家比較容易渾淆的東西。

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

-(NSRange)rangeOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(NSDate *)date;
答疑解惑:
  1. Unit:單元

  2. NSRange:

    typedef struct _NSRange {

    ?
    1
    2
    NSUInteger location;
    NSUInteger length;

    } NSRange;

我們大致可以理解爲:某個時間點所在的“小單元”,在“大單元”中的數量(返回值range的location屬性變量的值一般是錯誤的)。例如:

?
1
2
3
4
//  當前時間對應的月份中有幾天
    [[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開始)。例如:

?
1
2
3
4
5
6
7
//  當前時間對應的周是當前年中的第幾周
    [[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;

我們大致可以理解爲:“某個時間點”所在的“單元”的起始時間,以及起始時間距離“某個時間點”的時差(單位秒)。例如:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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);


常用方法:

    NSDate *nowDate = [NSDate date];

    NSLog(@"now date is: %@", nowDate);

    

    NSCalendar *calendar = [NSCalendar currentCalendar];

    NSUInteger unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSWeekOfMonthCalendarUnit | NSWeekOfYearCalendarUnit | NSWeekdayCalendarUnit | NSWeekdayOrdinalCalendarUnit;

    NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:nowDate];


    NSInteger year = [dateComponent year];

    NSInteger month = [dateComponent month];

    NSInteger day = [dateComponent day];

    NSInteger hour = [dateComponent hour];

    NSInteger minute = [dateComponent minute];

    NSInteger second = [dateComponent second];

    

    NSInteger weekDay = [dateComponent weekday];

    NSInteger weekDayOrdinal = [dateComponent weekdayOrdinal];

    NSInteger weekOfMonth = [dateComponent weekOfMonth];

    NSInteger weekOfYear = [dateComponent weekOfYear];

    

    NSLog(@"year is: %ld", year);

    NSLog(@"month is: %ld", month);

    NSLog(@"day is: %ld", day);

    NSLog(@"hour is: %ld", hour);

    NSLog(@"minute is: %ld", minute);

    NSLog(@"second is: %ld", second);

    NSLog(@"weekDay is: %ld", weekDay);

    NSLog(@"weekDayOrdinal is: %ld", weekDayOrdinal);

    NSLog(@"weekDayOfMonth is: %ld", weekOfMonth);

    NSLog(@"weekDayOfYear is: %ld", weekOfYear);




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章