一、介绍
DateTools 是一个用于处理日期和时间的 O-C 库。它包含 3 个子库:
NSDate+DateTools、Time Periods、Time Periods Group。
1、NSDate+DateTools
不知道你们是否有这种感觉,O-C 提供的 NSDate 似乎和其他语言的日期类不太一样,它更像是由 timeIntervalSince... 方法构造的 Unix 时间,另外在加上一个日历功能。但有时候我们更希望以日期组件“年、月、日”的方式来访问日期。这就是 NSDate+DateTools 要为我们提供的。它主要提供了一下几个功能。
1) Time ago
这部分实际上是Kevin Lawler 写的 NSDate+TimeAgo 库,现在已被正式纳入到 DateTools 库中。
顾名思义,Time ago 就是将日期转变为相对日期的形式,即我们常用的“昨天、今天、明天、几天前,一周以后……”这样的表述方式。它有“长、短”两种格式,后者是前者的更简短的描述。例如:
NSDate *timeAgoDate = [NSDatedateWithTimeIntervalSinceNow:-4];
NSLog(@"Time Ago: %@",timeAgoDate.timeAgoSinceNow);
NSLog(@"Time Ago: %@",timeAgoDate.shortTimeAgoSinceNow);
以上代码分别输出:
Time Ago: 4 seconds ago
Time Ago: 4s
当然,DateTools 提供了多达33种语言的支持,当然也包括简体/繁体中文。
2) 访问日期组件
以前,我们要读取一个 NSDate 的年月日,必须这样做:
//Create calendar
NSCalendar *calendar =[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
unitFlags = NSYearCalendarUnit |NSMonthCalendarUnit;
NSDateComponents *dateComponents= [calendar components:unitFlags fromDate:date];
//Get components
NSInteger year =dateComponents.year;
NSInteger month =dateComponents.month;
但是,使用 DateTools,只需要:
NSInteger year = date.year;
NSInteger month = date.month;
如果采用了非格鲁吉亚日历,只需这样:
NSInteger day = [datedayWithCalendar:calendar];
还可以将整个 DateTools 默认的日历由格鲁吉亚日历修改为其它,则可以修改 NSDate+DateTools.m文件中的 defaultCalendar 方法。
3) 日期的运算
以前,要想将既有日期上加/减一年形成新的日期,我们必须:
//Create calendar
NSCalendar *calendar =[[NSCalendar alloc] initWithCalendarIdentifier:[NSDate defaultCalendar]];
NSDateComponents *components =[[NSDateComponents alloc] init];
//Make changes
[components setYear:1];
//Get new date with updated year
NSDate *newDate = [calendardateByAddingComponents:components toDate:date options:0];
使用 DateTools 则可以用:
NSDate *newDate = [datedateByAddingYears:1];
如果是减去一年,则可以用dateBySubtractingYears 方法。
4) 比较运算
NSDate 有 4 种基本的比较运算:
isEqualToDate:
earlierDate:
laterDate:
compare:
DateTools 则将它们改成了:
isEarlierThan
isEarlierThanOrEqualTo
isLaterThan
isLaterThanOrEqualTo
除此之外,DateTools 还提供了更多的操作:
· yearsFrom:, yearsUntil, yearsAgo, yearsEarlierThan:,yearsLaterThan:
· monthsFrom:, monthsUntil, monthsAgo,monthsEarlierThan:, monthsLaterThan:
· weeksFrom:, weeksUntil, weeksAgo, weeksEarlierThan:,weeksLaterThan:
· daysFrom:, daysUntil, daysAgo, daysEarlierThan:,daysLaterThan:
· hoursFrom:, hoursUntil, hoursAgo, hoursEarlierThan:,hoursLaterThan:
· minutesFrom:, minutesUntil, minutesAgo,minutesEarlierThan:, minutesLaterThan:
· secondsFrom:, secondsUntil, secondsAgo,secondsEarlierThan:, secondsLaterThan:
这样,你可以很轻易地知道两个日期相差有多少年/月/日:
NSInteger yearsApart =[firstDate yearsFrom:secondDate];
5) 格式化日期字串
DateTools 简化了格式化日期字串的操作,即formattedDateWithStyle:和formattedDateWithFormat: 方法。
2、时段
时段即时间段,包括一段连续的时间,DateTools 使用 DTTimePeriod 来表示。 DTTimePeriod 类包括一系列初始化方法、以及关于时段的运算和比较操作。
1) 创建
时段的创建(初始化方法)有两种。
时段包括一个起始时间和一个结束时间。这也体现在它的初始化方法中:
DTTimePeriod *timePeriod =[[DTTimePeriod alloc] initWithStartDate:startDate endDate:endDate];
当然,你也可以不指定结束时间,结束时间可以由开始时间和时段的长度得到。例如下面的时段由开始时间和长度为5个小时的时长来描述:
DTTimePeriod *timePeriod =[DTTimePeriod timePeriodWithSize:DTTimePeriodSizeHour amount:5startingAt:[NSDate date]];
2) 时段的属性
· hasStartDate - 如果该时段拥有开始时间,返回 Yes
· hasEndDate - 如果该时段拥有结束时间,返回 Yes
· isMoment - 如果时段的开始时间等于结束时间,返回 Yes
· durationIn.... - 以指定的单位返回时长。
3) 运算
时段支持3种运算:移动、增加时长、减少时长。
移动是将时段开始时间提前或后延的操作。使用方法shiftEarlierWithSize:amount:和shiftLaterWithSize:amount: 进行。
增加时长或减少时长可以分为两种情况。一种是固定开始时间,然后增加/减少时长,最终会改变结束时间;一种是固定结束时间,然后增加/减少时长,最终会改变开始时间。例如:
DTTimePeriod *timePeriod = [DTTimePeriodtimePeriodWithSize:DTTimePeriodSizeMinute endingAt:[NSDate date]];
[timePeriodlengthenWithAnchorDate:DTTimePeriodAnchorEnd size:DTTimePeriodSizeMinuteamount:1];
上述代码将时长由1分钟增加为2分钟,固定结束时间,因此开始时间被提前了1分钟。
4) 关系运算
对于两个时段,我们经常会这样考虑二者的关系:它们是否是相同的?是否一个在另一个的范围之内?
DTTimePeriod 支持5种基本的关系运算:
isEqualToPeriod: 相等
isInside: 被包含
contains: 包含
overlapsWith:重叠,部分相同
intersects:相交,在重叠的基础上再增加两种情况:前者结束时间=后者开始时间,前者开始时间=后者结束时间。
3、时段组
即时段集合,包括两个类:DTTimePeriodCollection和DTTimePeriodChain。二者的最大不同,是后者不允许集合中时段有重叠。