NSDateComponents和NSCalendar釋義

NSDateComponents封裝了具體年月日、時秒分、周、季度等

一、NSDateComponents相關方法:

1. NSCalendar對象的 - (NSDateComponents *)components:(NSUInteger)unitFlags fromDate:(NSDate *)date

取得一個NSDate對象的1個或多個部分,用NSDateComponents來封裝

NSCalendar *calendar = [NSCalendar currentCalendar];

NSDate *date = [NSDate date];

//NSDateComponents *compt = [calendar components:NSDayCalendarUnit fromDate:date];

NSDateComponents *compt = [calendar components:(NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit) fromDate:date];

NSLog(@"%d,%@",[compt year],date);

NSLog(@"%d,%@",[compt month],date);

NSLog(@"%d,%@",[compt day],date);

需要注意的是,只有明確指定了unitFlags,NSDateComponents相應的那一部分才有值。

2. NSCalendar對象的 - (NSDateComponents *)components:(NSUInteger)unitFlags fromDate:(NSDate *)startingDate toDate:(NSDate *)resultDate options : (NSUInteger)opts

取得兩個NSDate對象的時間間隔,用NSDateComponents來封裝

NSCalendar *calendar = [NSCalendar currentCalendar];

NSDate *date = [NSDate date];

NSDate *date2 = [NSDate dateWithTimeInterval:5*60*60+75sinceDate:date];

NSDateComponents *compt = [calendar components:(NSMinuteCalendarUnit|NSSecondCalendarUnit) fromDate:date toDate:date2 options:0];

NSLog(@"%d",[compt minute]);

NSLog(@"%d",[compt second]);

有幾點需要注意:

①得到的NSDateComponents對象可能會包含負數(shù)。例如:當toDate比fromDate晚10秒,second部分返回10;當toDate比fromDate早10秒,second部分返回-10

② 當指定unitFlags返回多個部分時,相隔的時間由多個部分共同組成(而不是獨立去表示)。例如:上面的例子時間相差5小時1分15秒,如果指定只返回second部分,將得到18075秒;如果指定返回minute和second部分,將得到301分15秒;如果指定返回hour、minute和second,將得到5小時1分15秒。

3. NSCalendar對象的 - (NSDate *)dateFromComponents:(NSDateComponents *)comps

根據(jù)NSDateComponents對象得到一個NSDate對象

NSDateComponents *compt = [[NSDateComponents alloc] init];

[compt setYear:2012];

[compt setMonth:5];

[compt setDay:11];

NSCalendar *calendar = [NSCalendar currentCalendar];

NSDate *date = [calendar dateFromComponents:compt];

//得到本地時間,避免時區(qū)問題

NSTimeZone *zone = [NSTimeZone systemTimeZone];

NSInteger interval = [zone secondsFromGMTForDate:date];

NSDate *localeDate = [date dateByAddingTimeInterval:interval];

NSLog(@"%@",localeDate);

4. NSCalendar對象的 - (NSDate *)dateByAddingComponents:(NSDateComponents *)comps toDate:(NSDate *)date options:(NSUInteger)opts

在參數(shù)date基礎上,增加一個NSDateComponents類型的時間增量

NSDateComponents *compt = [[NSDateComponents alloc] init];

[compt setDay:25];

[compt setHour:4];

[compt setMinute:66];

NSCalendar *calendar = [NSCalendar currentCalendar];

NSDate *date = [calendar dateByAddingComponents:compt toDate:[NSDate date] options:0];


//得到本地時間,避免時區(qū)問題

NSTimeZone *zone = [NSTimeZone systemTimeZone];

NSInteger interval = [zone secondsFromGMTForDate:date];

NSDate *localeDate = [date dateByAddingTimeInterval:interval];

NSLog(@"%@",localeDate);

當前時間的基礎上,增加25天4小時66秒


二、NSCalendar

1. + (id)currentCalendar / + (id)autoupdatingCurrentCalendar

這兩個類方法都將返回當前客戶端的邏輯日歷,區(qū)別在于:currentCalendar取得的值會一直保持在cache中,第一次用此方法實例化對象后,即使修改了系統(tǒng)日歷設定,這個對象也不會改變。而使用autoupdatingCurrentCalendar,當每次修改系統(tǒng)日歷設定,其實例化的對象也會隨之改變。

下面的代碼演示了區(qū)別所在,假設初始Calendar設定為NSGregorianCalendar(公歷),先用這兩個函數(shù)分別初始化兩個對象,然后修改系統(tǒng)日歷為NSJapaneseCalendar(日本和歷),再重新打印這兩個對象的信息:

NSCalendar *calendar;

NSCalendar *calendar2;

- (IBAction)doTest:(id)sender?

{

? ? calendar = [NSCalendar currentCalendar];

? ? calendar2 = [NSCalendar autoupdatingCurrentCalendar];


? ? NSLog(@"%@",calendar.calendarIdentifier);//print "gregorian"

? ? NSLog(@"%@",calendar2.calendarIdentifier);//print "gregorian"

}

- (IBAction)doAgain:(id)sender?

{

? ? NSLog(@"%@",calendar.calendarIdentifier);//print "gregorian"

? ? NSLog(@"%@",calendar2.calendarIdentifier);//print "japanese"

}

2. - (id)initWithCalendarIdentifier:(NSString *)string

根據(jù)提供的日歷標示符初始化

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSChineseCalendar];

NSLog(@"%@",calendar.calendarIdentifier);

系統(tǒng)中定義的日歷有:

NSGregorianCalendar --公歷

NSBuddhistCalendar --佛教日歷

NSChineseCalendar --中國農(nóng)歷

NSHebrewCalendar --希伯來日歷

NSIslamicCalendar --伊斯蘭歷

NSIslamicCivilCalendar --伊斯蘭教日歷

NSJapaneseCalendar --日本日歷

NSRepublicOfChinaCalendar --中華民國日歷(臺灣)

NSPersianCalendar --波斯歷

NSIndianCalendar --印度日歷

NSISO8601Calendar -- ISO8601

NSCalendar常用對象方法與類方法:

1. - (void)setLocale:(NSLocale *)locale

設置本地化信息

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

[calendar setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"]];

NSLog(@"%@",calendar.locale.localeIdentifier);

2. - (void)setTimeZone:(NSTimeZone *)tz

設置時區(qū)信息

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

[calendar setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"HKT"]];

NSLog(@"%@",calendar.timeZone);

3. - (void)setFirstWeekday:(NSUInteger)weekday

設置每周的第一天從星期幾開始,比如:1代表星期日開始,2代表星期一開始,以此類推。默認值是1

如圖所示,如果從星期天開始,日歷的表現(xiàn)形式:

如果從星期二開始,日歷的表現(xiàn)形式:

NSCalendar *calendar = [NSCalendar currentCalendar];

[calendar setFirstWeekday:3];

NSLog(@"%i",calendar.firstWeekday);

4. - (void)setMinimumDaysInFirstWeek:(NSUInteger)mdw

設置每年及每月第一周必須包含的最少天數(shù),比如:設定第一周最少包括3天,則value傳入3

NSCalendar *calendar = [NSCalendar currentCalendar];

[calendar setMinimumDaysInFirstWeek:3];

NSLog(@"%i",calendar.minimumDaysInFirstWeek);

5. - (NSUInteger)ordinalityOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(NSDate *)date

獲取一個小的單位在一個大的單位里面的序數(shù)

NSCalendarUnit包含的值有:

NSEraCalendarUnit --紀元單位。對于NSGregorianCalendar(公歷)來說,只有公元前(BC)和公元(AD);而對于其它歷法可能有很多,例如日本和歷是以每一代君王統(tǒng)治來做計算。

NSYearCalendarUnit --年單位。值很大,相當于經(jīng)歷了多少年,未來多少年。

NSMonthCalendarUnit --月單位。范圍為1-12

NSDayCalendarUnit --天單位。范圍為1-31

NSHourCalendarUnit --小時單位。范圍為0-24

NSMinuteCalendarUnit --分鐘單位。范圍為0-60

NSSecondCalendarUnit --秒單位。范圍為0-60

NSWeekCalendarUnit --周單位。范圍為1-53

NSWeekdayCalendarUnit --星期單位,每周的7天。范圍為1-7

NSWeekdayOrdinalCalendarUnit --沒完全搞清楚

NSQuarterCalendarUnit --幾刻鐘,也就是15分鐘。范圍為1-4

NSWeekOfMonthCalendarUnit --月包含的周數(shù)。最多為6個周

NSWeekOfYearCalendarUnit --年包含的周數(shù)。最多為53個周

NSYearForWeekOfYearCalendarUnit --沒完全搞清楚

NSTimeZoneCalendarUnit --沒完全搞清楚

下面是一些示例:

①當小單位為NSWeekdayCalendarUnit,大單位為NSWeekCalendarUnit時(即某個日期在這一周是第幾天),根據(jù)firstWeekday屬性不同,返回的結果也不同。

NSCalendar *calendar = [NSCalendar currentCalendar];

NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:10];? ?

//[calendar setFirstWeekday:2];

intcount = [calendar ordinalityOfUnit:NSWeekdayCalendarUnit inUnit:NSWeekCalendarUnit forDate:date];

NSLog(@"%d",count);

默認firstWeekday為1(星期天開始)的情況下,得到的結果是2,從下圖可以看到是第2天。

假如firstWeekday被設置為2(星期一開始)的情況下,得到的結果是1,從下圖可以看到是第1天

②當小單位為NSWeekCalendarUnit,大單位為NSYearCalendarUnit時(即某個日期在這一年中是第幾周),根據(jù)minimumDaysInFirstWeek屬性不同,返回的結果也不同。

NSDateComponents *compt = [[NSDateComponents alloc] init];

[compt setYear:2013];

[compt setMonth:1];

[compt setDay:20];

NSCalendar *calendar = [NSCalendar currentCalendar];

NSDate *date = [calendar dateFromComponents:compt];

//[calendar setMinimumDaysInFirstWeek:6];

intcount = [calendar ordinalityOfUnit:NSWeekCalendarUnit inUnit:NSYearCalendarUnit forDate:date];

NSLog(@"%d",count);

從上圖的日歷中可以看出,在沒有設置minimumDaysInFirstWeek的情況下,1月20日得到的結果是4(第四個周)。

默認情況下第一個周有5天,如果將minimumDaysInFirstWeek設置為6天,則原本是第一周的1月1日--1月5日被劃分到了上一年,返回0;而1月6日--1月12日升為第一周,1月13日--1月19日升為第二周。。依此類推。

所以需要關注的是minimumDaysInFirstWeek與實際第一周包含天數(shù)的大小比較,如果提供的minimumDaysInFirstWeek比實際第一周的天數(shù)小,則一切不變;否則統(tǒng)計"一年中第幾周"、"一個月中第幾周"會產(chǎn)生變化。

6. - (NSRange)rangeOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(NSDate *)date

根據(jù)參數(shù)提供的時間點,得到一個小的單位在一個大的單位里面的取值范圍

NSDateComponents *compt = [[NSDateComponents alloc] init];

[compt setYear:2013];

[compt setMonth:2];

[compt setDay:21];

[compt setHour:9];

[compt setMinute:45];

[compt setSecond:30];

NSCalendar *calendar = [NSCalendar currentCalendar];

NSDate *date = [calendar dateFromComponents:compt];

//得到本地時間,避免時區(qū)問題

NSTimeZone *zone = [NSTimeZone systemTimeZone];

NSInteger interval = [zone secondsFromGMTForDate:date];

NSDate *localeDate = [date dateByAddingTimeInterval:interval];

NSRange range = [calendar rangeOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit forDate:localeDate];

NSLog(@"%d -- %d",range.location,range.length);

調(diào)用這個方法要明確一點,取得的是"范圍"而不是"包含",下面是一些例子:

① 小單位是NSDayCalendarUnit,大單位是NSYearCalendarUnit,并不是要取這一年包含多少天,而是要取"天"(Day)這個單位在這一年(Year)的取值范圍。其實不管你提供的日期是多少,返回的值都是"1--31"。

②小單位是NSDayCalendarUnit,大單位是NSMonthCalendarUnit。要取得參數(shù)時間點所對應的月份下,"天"(Day)的取值范圍。根據(jù)參數(shù)時間的月份不同,值也不同。例如2月是1--28、3月是1--31、4月是1--30。

③小單位是NSWeekCalendarUnit,大單位是NSMonthCalendarUnit。要取得參數(shù)時間點所對應的月份下,"周"(Week)的取值范圍。需要注意的是結果會受到minimumDaysInFirstWeek屬性的影響。在默認minimumDaysInFirstWeek情況下,取得的范圍值一般是"1--5",從日歷上可以看出來這個月包含5排,即5個周。

④小單位是NSDayCalendarUnit,大單位是NSWeekCalendarUnit。要取得周所包含的"天"(Day)的取值范圍。下面是一個示例日歷圖:

在上圖的日期條件下,假如提供的參數(shù)是4月1日--4月6日,那么對應的week就是1(第一個周),可以看到第一個周包含有6天,從1號開始,那么最終得到的范圍值為1--6。

假如提供的參數(shù)是4月18日,那么對應的week是3(第三個周),第三個周包含有7天,從14號開始,那么最終得到的范圍值是14--7。

假如提供的參數(shù)是4月30日,那么對應的week是5(第五個周),第五個周只包含3天,從28號開始,那么最終得到的范圍值是28--3。

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

根據(jù)參數(shù)提供的時間點,返回所在日歷單位的開始時間。如果startDate和interval均可以計算,則返回YES;否則返回NO

unit -- 日歷單位

datep --

開始時間,通過參數(shù)返回

tip --

日歷單位所對應的秒數(shù),通過參數(shù)返回

date --

時間點參數(shù)

NSDate *dateOut = nil;

NSTimeInterval count =0;

NSDateComponents *compt = [[NSDateComponents alloc] init];

[compt setYear:2013];

[compt setMonth:3];

[compt setDay:22];

NSCalendar *calendar = [NSCalendar currentCalendar];

NSDate *date = [calendar dateFromComponents:compt];

BOOL b = [calendar rangeOfUnit:NSMonthCalendarUnit startDate:&dateOut interval:&count forDate:date];

if(b)

{

? ? //得到本地時間,避免時區(qū)問題

? ? NSTimeZone *zone = [NSTimeZone systemTimeZone];

? ? NSInteger interval = [zone secondsFromGMTForDate:dateOut];

? ? NSDate *localeDate = [dateOut dateByAddingTimeInterval:interval];


? ? NSLog(@"%@",localeDate);

? ? NSLog(@"%f",count);

}

else

{

? ? NSLog(@"無法計算");

}

上面的例子要求返回2013年3月22日當月的起始時間,以及當月的秒數(shù)。得到的結果是:2013-03-01 00:00:00 +0000,2678400。(2678400 = 31天* 24小時* 60分* 60秒)。

假如將上面的日歷單位改為NSWeekCalendarUnit,那么得到的結果是:2013-03-17 00:00:00 +0000,604800。當周的第一天是3月17日。(604800 = 7天* 24小時* 60分* 60秒)。

假如將上面的日歷單位改為NSYearCalendarUnit,那么得到的結果是:2013-01-01 00:00:00 +0000,31536000。這一年的第一天是1月1日,(31536000 = 365天* 24小時* 60分* 60秒)。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 之前一篇文章寫的是時間與日期處理的簡單模式,這篇文章就算是拓展的模式吧。 上一篇文章的地址是——IOS開發(fā)之時間與...
    這位網(wǎng)友閱讀 2,289評論 8 1
  • 主要是對ios平臺NSDate時間類中的方法的用法解釋,以備不時之需: 一、NSDate用來表示公歷的GMT時間(...
    飛龍之城閱讀 2,427評論 0 1
  • ######先說下需求:選擇日期彈出日歷(跟途牛,攜程等差不多就行。。。行) 初識NSCalendar到寫完日歷的...
    只是個少年閱讀 1,180評論 0 0
  • 創(chuàng)建//獲取到的是當前時間 格林尼治 時間 +0000 表示0時區(qū)NSDate *date1 = [NSDate...
    JokerVxc閱讀 3,632評論 1 8
  • .h文件 #import #define D_MINUTE60 #define D_HOUR3600 #defin...
    屈涯閱讀 685評論 2 0

友情鏈接更多精彩內(nèi)容