NSDate​Components

NSDateComponents 类在Foundation的日期和时间API中扮演着重要的角色。其本身并没有什么令人印象深刻的特征,仅仅是一个日期信息的容器(信息包括:月,年,月中的某天,年中的某周,或者是否是闰月)。然而,值得一提的是,在其结合 NSCalendarNSDateComponents 类之后,日历格式的转换变得十分方便。

日期代表了时间中的某个特定时刻,而日期组件的表示则依赖于其所使用的日历系统。很多时候,这个表示形式会和我们大多数人使用的Gregorian Calendar有着很大的不同。例如Islamic Calendar一年有354或者355天,而Buddhist calendar一年会有354,355,384或者385天。

从日期中提取日期组件

NSDateComponents类能够被手动初始化,但是在大多数时候,会使用NSCalendar -components:fromDate:来提取某个日期的日期组件。

NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *date = [NSDate date];
[calendar components:(NSDayCalendarUnit | NSMonthCalendarUnit) fromDate:date];

其中components参数是一个用来获取日期组件值的掩码(bitmask),有下面这些值可以选择:

  • NSEraCalendarUnit
  • NSYearCalendarUnit
  • NSMonthCalendarUnit
  • NSDayCalendarUnit
  • NSHourCalendarUnit
  • NSMinuteCalendarUnit
  • NSSecondCalendarUnit
  • NSWeekCalendarUnit
  • NSWeekdayCalendarUnit
  • NSWeekdayOrdinalCalendarUnit
  • NSQuarterCalendarUnit
  • NSWeekOfMonthCalendarUnit
  • NSWeekOfYearCalendarUnit
  • NSYearForWeekOfYearCalendarUnit
  • NSCalendarCalendarUnit
  • NSTimeZoneCalendarUnit

由于其计算所有可能值的开销很大,所以随后的计算只使用指定的值(用|来分割两个不同的值,使用位运算“或”操作)。

计算相对日期

NSDateComponents对象可以用来计算相对日期。使用 NSCalendar -dateByAddingComponents:toDate:options:方法来确定昨天,下周或者5小时30分钟之后的日期。

NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *date = [NSDate date];

NSDateComponents *components = [[NSDateComponents alloc] init];
[components setWeek:1];
[components setHour:12];

NSLog(@"1 week and twelve hours from now: %@", [calendar dateByAddingComponents:components toDate:date options:0]);

用Components来创建日期

NSDateComponents类最强大的特性也许就是能够通过组件反向创建NSDate对象。NSCalendar -dateFromComponents:就是用来实现这个目的的:

NSCalendar *calendar = [NSCalendar currentCalendar];

NSDateComponents *components = [[NSDateComponents alloc] init];
[components setYear:1987];
[components setMonth:3];
[components setDay:17];
[components setHour:14];
[components setMinute:20];
[components setSecond:0];

NSLog(@"Awesome time: %@", [calendar dateFromComponents:components]);

特别有意思的地方在于,这个方法除了正常的月/日/年方式之外,也可以用某些信息来确定一个日期。只要提供的信息能够唯一确定一个日期,你就会得到一个结果。例如:指定2013年的第316天,那么就会返回一个2013年12月11日0点0分0秒的NSDate对象(如果没有指定时间,时间组件的默认值是0)。

请注意:如果传入了一些前后矛盾的组件,那么就会返回一个丢失了信息的结果或者nil


NSDateComponents及它跟NSCalendar的关系突显具有像Foundation一样严格的工程框架的明显优势。你也许不会每天做日历相关的计算,但当有这样的需要时,知道怎么使用NSDateComponents会让你从无数挫折中解脱出来。

作者 Mattt
Mattt

Mattt (@mattt) is a writer and developer in Portland, Oregon. He is the founder of NSHipster and Flight School, and the creator of several open source libraries, including AFNetworking and Alamofire.

翻译者
Candyan

Candyan 专业 iOS,业余 Android,偶尔捣鼓下Server的工程师。

下一篇文章

NSString 是基础类库中的佼佼者。 它虽然很强大,但是不提提它的可无缝转换的表兄弟 CFMutableString,或者更特殊的 CFStringTransform,是不负责任的。