轉載自:http://www.cnblogs.com/wujian1360/archive/2011/09/05/2168007.html
NSCalendar用於處理時間相關問題。比如比較時間前後、計算日期所的周別等。
1. 創建或初始化可用以下方法
+ (id)currentCalendar;
取得當前用戶的邏輯日曆(logical calendar)
+ (id)autoupdatingCurrentCalendar;
取得當前用戶的邏輯日曆(logical calendar), ......
- (id)initWithCalendarIdentifier:(NSString *)identifier;
初始化爲各種日曆。identifier的範圍可以是:
NSGregorianCalendar 陽曆
NSBuddhistCalendar 佛曆
NSChineseCalendar 中國日曆
NSHebrewCalendar 希伯來日曆
NSIslamicCalendar 伊斯蘭日曆
NSIslamicCivilCalendar 伊斯蘭民事日曆
NSJapaneseCalendar 日本日曆
2. 使用前若有必要可以先做以下設定
- (void)setLocale:(NSLocale *)locale;
設置區域
- (void)setTimeZone:(NSTimeZone *)tz;
設置時區
- (void)setFirstWeekday:(NSUInteger)value;
設定每週的第一天從星期幾開始,比如:
. 如需設定從星期日開始,則value傳入1
. 如需設定從星期一開始,則value傳入2
. 以此類推
詳細信息請參閱FirstWeekday屬性
- (void)setMinimumDaysInFirstWeek:(NSUInteger)value;
設定作爲(每年及每月)第一週必須包含的最少天數,比如:
. 如需設定第一週最少包括7天,則value傳入7
詳細信息請參閱MinimumDaysInFirstWeek屬性
3. 取回設定信息用以下方法
- (NSString *)calendarIdentifier
返回日曆標示符(identifier)。有效的日曆標示符包括:
NSGregorianCalendar
NSBuddhistCalendar
NSChineseCalendar
NSHebrewCalendar
NSIslamicCalendar
NSIslamicCivilCalendar
NSJapaneseCalendar
- (NSLocale *)locale;
返回日曆指定的地區信息。它將影響???
- (NSTimeZone *)timeZone;
返回日曆指定的時區信息。它將影響???
- (NSUInteger)firstWeekday;
返回日曆指定的每週的第一天從星期幾開始。缺省爲星期天,即firstWeekday = 1
當方法[NSCalendar ordinalityOfUnit: inUnit: fromDate:]
的ordinalityOfUnit參數爲NSWeekdayCalendarUnit,inUnit參數爲NSWeekCalendarUnit時,
firstWeekday屬性影響它的返回值。具體說明如下:
. 當firstWeekday被指定爲星期天(即 = 1)時,它返回的值與星期幾對應的數值保持一致。比如:
fromDate傳入的參數是星期日,則函數返回1
fromDate傳入的參數是星期一,則函數返回2
. 當firstWeekday被指定爲其它值時(即 <> 1)時,假設firstWeekday被指定爲星期一(即 = 2),那麼:
fromDate傳入的參數是星期一,則函數返回1
fromDate傳入的參數是星期二,則函數返回2
fromDate傳入的參數是星期日,則函數返回7
- (NSUInteger)minimumDaysInFirstWeek;
返回日曆指定的第一週必須包含的最少天數。缺省爲1,即minimumDaysInFirstWeek = 1。
當方法[NSCalendar ordinalityOfUnit: inUnit: fromDate:]
的ordinalityOfUnit參數爲NSWeekCalendarUnit,inUnit參數爲NSYearCalendarUnit時,
minimumDaysInFirstWeek屬性影響它的返回值。具體說明如下:
2005年1月
日 一 二 三 四 五 六
--------------------------------
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
2005年1月第一週包括1號。
a. 如果將minimumDaysInFirstWeek設定 = 1
則fromDate傳入1月1號,方法均返回1 ==> 滿足minimumDaysInFirstWeek指定的天數(最少1天),所以方法將其歸爲2005年的第1周
則fromDate傳入1月2-8號,方法均返回2
則fromDate傳入1月9-15號,方法均返回3
......
b. 如果將minimumDaysInFirstWeek設定爲 > 1,比如2
則fromDate傳入1月1號,方法均返回53 ==> 不足2天,所以方法將其歸爲2004年的第53周
則fromDate傳入1月2-8號,方法均返回1
則fromDate傳入1月9-15號,方法均返回2
......
2008年1月
日 一 二 三 四 五 六
---------------------------------
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
2005年1月第一週包括1-5號共5天。
a. 如果將minimumDaysInFirstWeek設定爲 <= 5時
則fromDate傳入1月1-5號,方法均返回1 ==> 滿足minimumDaysInFirstWeek指定的天數,所以方法將其歸爲2008年的第1周
則fromDate傳入1月6-12號,方法均返回2
則fromDate傳入1月13-19號,方法均返回3
......
b. 如果將minimumDaysInFirstWeek設定爲 > 5,比如6
則fromDate傳入1月1-5號,方法均返回53 ==> 當週不足6天,所以方法將其歸爲2007年的第53周
則fromDate傳入1月2-8號,方法均返回1
則fromDate傳入1月9-15號,方法均返回2
......
當方法[NSCalendar ordinalityOfUnit: inUnit: fromDate:]
的ordinalityOfUnit參數爲NSWeekCalendarUnit,inUnit參數爲NSMonthCalendarUnit時,
minimumDaysInFirstWeek屬性影響它的返回值。以2008年4月爲例, 具體說明如下:
2008年4月
日 一 二 三 四 五 六
---------------------------------
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
2008年4月第一週包括1、2、3、4、5號。
1. 如果將minimumDaysInFirstWeek設定爲小於或等於5的數
則fromDate傳入4月1-5號,方法均返回1
則fromDate傳入4月6-12號,方法均返回2
則fromDate傳入4月13-19號,方法均返回3
....
2. 如果將minimumDaysInFirstWeek設定爲大於5的數
則fromDate傳入1-5號,方法均返回0
則fromDate傳入6-12號,方法均返回1
則fromDate傳入13-19號,方法均返回2
....
Cocoa中對日期和時間的處理 NSCalendar (二)
其他方法的說明
- (NSRange)maximumRangeOfUnit:(NSCalendarUnit)unit;
返回單元的最大範圍。就Gregorian來說有:
NSEraCalendarUnit => 0 - 2
NSYearCalendarUnit => 1 - 10000
NSMonthCalendarUnit = 1 - 12
NSDayCalendarUnit = 1 - 31
NSHourCalendarUnit = 0 - 24
NSMinuteCalendarUnit = 0 - 60
NSSecondCalendarUnit = 0 - 60
NSWeekCalendarUnit = 1 - 53
NSWeekdayCalendarUnit = 1 - 7
NSWeekdayOrdinalCalendarUnit = ? (2147483647 - 2147483647)
(NSNotFound - NSNotFound)
- (NSRange)minimumRangeOfUnit:(NSCalendarUnit)unit;
返回單元的最小範圍。就Gregorian來說有:
NSEraCalendarUnit => 0 - 2
NSYearCalendarUnit => 1 - 10000
NSMonthCalendarUnit = 1 - 12
NSDayCalendarUnit = 1 - 28 ***
NSHourCalendarUnit = 0 - 24
NSMinuteCalendarUnit = 0 - 60
NSSecondCalendarUnit = 0 - 60
NSWeekCalendarUnit = 1 - 52 ***
NSWeekdayCalendarUnit = 1 - 7
NSWeekdayOrdinalCalendarUnit = ? (2147483647 - 2147483647)
(NSNotFound - NSNotFound)
- (NSUInteger)ordinalityOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(NSDate *)date
返回某個特定時間(date)其對應的小的時間單元(smaller)在大的時間單元(larger)中的順序,比如:
. 要取得2008/11/12在當月的第幾周則可以這樣調用該方法:
[calendar ordinalityOfUnit:NSWeekOrdinalCalendarUnit inUnit: NSWeekCalendarUnit forDate: someDate];
注: someDate存放了2008/11/12
. 要取得1:50分在一天中處於第幾個小時,則可以這樣調用該方法:
[calendar ordinalityOfUnit:NSHourCalendarUnit inUnit: NSDayCalendarUnit forDate: someTime];
注: someTime存放了1:50
. 其它請參照firstWeekday和minimumDaysInFirstWeek中的說明
- (NSRange)rangeOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(NSDate *)date
返回某個特定時間(date)其對應的小的時間單元(smaller)在大的時間單元(larger)中的範圍,比如:
. 要取得2008/11/12在所在月份的日期範圍則可以這樣調用該方法:
[calendar ordinalityOfUnit:NSDayCalendarUnit inUnit: NSMonthCalendarUnit forDate:fDate];
則返回1-31。注: fDate存放了2008/11/12
. 要取得2008/02/20在所在月份的日期範圍則可以這樣調用該方法:
[calendar ordinalityOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:fDate];
則返回1-29。注: fDate存放了2008/11/12
- (BOOL)rangeOfUnit:(NSCalendarUnit)unit startDate:(NSDate **)sDate interval:(NSTimeInterval *)unitSecs forDate:(NSDate *)date;
用於返回日期date(參數)所在的那個日曆單元unit(參數)的開始時間(sDate)。其中參數unit指定了日曆單元,參數sDate用於返回日曆單元的第一天,參數unitSecs用於返回日曆單元的長度(以秒爲單位),參數date指定了一個特定的日期。
如果startDate和interval均爲可計算的,那麼函數返回YES否則返回NO.比如:
. 要計算2008/01/08日所在的周的第一天:
...
NSDate *dateOut = [NSDate date];
NSDate **sDate = &dateOut;
NSDateComponents *dc = [[NSDateComponents alloc] init];
[dc setYear: 2008];
[dc setMonth: 1];
[dc setDay: 8];
NSDate *date = [calendar dateFromComponents:dc];
NSTimeInterval intOut;
NSTimeInterval *intervalOut = &intOut;
if ([calendar rangeOfUnit:NSMonthCalendarUnit startDate:sDate interval:interval0 forDate:date]){
NSLog(@"%@", [*sDate description]);
NSLog(@"%f", *intervalOut);
}
else{
NSLog(@"Can not be calculated!");
}
...
在控制檯窗口上可以看到:
2008-01-06 00:00:00 +0800
604800.000000
注: 2008-01-06是2008/01/08所在周的第一天,604800是一週7天的秒數。
. 要計算2008/01/05日所在的周的第一天,在控制檯窗口上可以看到:
2007-12-30 00:00:00 +0800
604800.000000
. 要計算2008/02/06日所在的月的第一天,在控制檯窗口上可以看到:
2007-02-01 00:00:00 +0800
2505600.000000
注: 2505600是二月29天的秒數。