主要有3个类:
NSDate:表示一个绝对的时间点
NSCalendar:允许你展示一个特殊的日历,比如Gregorian(公历)或Hebrew历(包括中国农历),它提供了大部分的日期计算接口,并且允许你在NSDate和NSDateComponents之间转换
NSDateComponents允许你展示一个特殊日期的不同部分,比如hour,minute,day,year等等。
NSTimeZone表示时区信息
NSDateFormatter用来在日期和字符串之间转换
可以认为NSDate表示的是绝对的数值,而NSCalendar,NSTimeZone和NSDateFormatter则表示了怎么来解释这个数值。
NSDate:
NSDate是一个抽象的概念,独立于locals,timezones和calendars,也可以认为它表示的就是公历的GMT时间 (NSLog打印的时候都会显示GMT时间)。它的单位是NSTimeInterval,用秒来表示。NSDate用相对于2001年1月1日(GMT) 的秒来计算时间,早于这个时间用负值来表示,晚于这个时间为正值。NSDate的方法timeIntervalSinceReferen
指相对于这个日期的秒数。
Listing 1
NSTimeInterval secondsPerDay = 24 * 60 * 60;
|
NSDate *tomorrow = [[NSDate alloc]
|
initWithTimeIntervalSinc
|
NSDate *yesterday = [[NSDate alloc]
|
initWithTimeIntervalSinc
|
[tomorrow release];
|
[yesterday release];
|
Listing 2
NSTimeInterval secondsPerDay = 24 * 60 * 60;
|
NSDate *today = [[NSDate alloc] init];
|
NSDate *tomorrow, *yesterday;
|
|
tomorrow = [today dateByAddingTimeInterval
|
yesterday = [today dateByAddingTimeInterval
|
[today release];
|
比较时间用isEqualToDate:
, compare:
, laterDate:和
earlierDate:方法,两个时间之间的间隔用timeIntervalSince...方法
NSCalendar和NSDateComponents:
Listing 3
NSCalendar *currentCalendar = [NSCalendar currentCalendar];
|
|
NSCalendar *japaneseCalendar = [[NSCalendar alloc]
|
initWithCalendarIdentifi
|
|
NSCalendar *usersCalendar =
|
[[NSLocale currentLocale] objectForKey:NSLocaleCalendar];
|
currentCalendar和usersCalendar都是用户本地的日历
Listing 4
NSDateComponents *components = [[NSDateComponents alloc] init];
|
[components setDay:6];
|
[components setMonth:5];
|
[components setYear:2004];
|
|
NSInteger weekday = [components weekday]; // Undefined (== NSUndefinedDateComponent
|
在Dates和Date Components之间转换:
Listing 5
NSDate *today = [NSDate date];
|
NSCalendar *gregorian = [[NSCalendar alloc]
|
initWithCalendarIdentifi
|
NSDateComponents *weekdayComponents =
|
[gregorian components:(NSDayCalendarUnit | NSWeekdayCalendarUnit) fromDate:today];
|
NSInteger day = [weekdayComponents day];
|
NSInteger weekday = [weekdayComponents weekday];
|
你需要用Calendar Units这个常量来指定要获取的部分。
NSCalendar的ordinalityOfUnit:inUnit:forDate:方法用来获取一个小的单位在一个大的单位里面的序数,比如你可以查看一个日期在一年中的天数。
Listing 6
NSDateComponents *components = [[NSDateComponents alloc] init];
|
[components setWeekday:2]; // Monday
|
[components setWeekdayOrdinal:1]; // The first Monday in the month
|
[components setMonth:5]; // May
|
[components setYear:2008];
|
NSCalendar *gregorian = [[NSCalendar alloc]
|
initWithCalendarIdentifi
|
NSDate *date = [gregorian dateFromComponents:components];
|
技术上来说不存在没有年的日期,如果你只想表示生日也可以不指定year:
Listing 7
NSDateComponents *components = [[NSDateComponents alloc] init];
|
[components setMonth:11];
|
[components setDay:7];
|
NSCalendar *gregorian = [[NSCalendar alloc]
|
initWithCalendarIdentifi
|
NSDate *birthday = [gregorian dateFromComponents:components];
|
不过这样以后你取components的时候就要记得不能指定year。
Listing 8
NSDateComponents *comps = [[NSDateComponents alloc] init];
|
[comps setDay:6];
|
[comps setMonth:5];
|
[comps setYear:2004];
|
|
NSCalendar *gregorian = [[NSCalendar alloc]
|
initWithCalendarIdentifi
|
NSDate *date = [gregorian dateFromComponents:comps];
|
[comps release];
|
[gregorian release];
|
|
NSCalendar *hebrew = [[NSCalendar alloc]
|
initWithCalendarIdentifi
|
NSUInteger unitFlags = NSDayCalendarUnit | NSMonthCalendarUnit |
|
NSYearCalendarUnit;
|
NSDateComponents *components = [hebrew components:unitFlags fromDate:date];
|
|
NSInteger day = [components day]; // 15
|
NSInteger month = [components month]; // 9
|
NSInteger year = [components year]; // 5764
|
日期计算:
你可以用dateByAddingComponents:toDate:options:方法给一个date增加一个date的部分(比如小时或者分钟)
Listing 9
NSDate *today = [[NSDate alloc] init];
|
NSCalendar *gregorian = [[NSCalendar alloc]
|
initWithCalendarIdentifi
|
NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
|
[offsetComponents setHour:1];
|
[offsetComponents setMinute:30];
|
// Calculate when, according to Tom Lehrer, World War III will end
|
NSDate *endOfWorldWar3 = [gregorian dateByAddingComponents:offsetComponents
|
toDate:today options:0];
|
Listing 10
NSDate *today = [[NSDate alloc] init];
|
NSCalendar *gregorian = [[NSCalendar alloc]
|
initWithCalendarIdentifi
|
|
// Get the weekday component of the current date
|
NSDateComponents *weekdayComponents = [gregorian components:NSWeekdayCalendarUnit
|
fromDate:today];
|
|
NSDateComponents *componentsToSubtract = [[NSDateComponents alloc] init];
|
[componentsToSubtract setDay: 0 - ([weekdayComponents weekday] - 1)];
|
|
NSDate *beginningOfWeek = [gregorian dateByAddingComponents:componentsToSubtract
|
toDate:today options:0];
|
|
NSDateComponents *components =
|
[gregorian components:(NSYearCalendarUnit | NSMonthCalendarUnit |
|
NSDayCalendarUnit) fromDate: beginningOfWeek];
|
beginningOfWeek = [gregorian dateFromComponents:components];
|
NSCalendar的rangeOfUnit:startDate:interval:forDate:方法可以按照rangeOfUnit指定的单位查找初始值,比如:
Listing 11
NSDate *today = [[NSDate alloc] init];
|
NSDate *beginningOfWeek = nil;
|
BOOL ok = [gregorian rangeOfUnit:NSWeekCalendarUnit startDate:&beginningOfWeek
|
interval:NULL forDate: today];
|
Listing 12
the difference between two dates
NSDate *startDate = ...;
|
NSDate *endDate = ...;
|
|
NSCalendar *gregorian = [[NSCalendar alloc]
|
initWithCalendarIdentifi
|
|
NSUInteger unitFlags = NSMonthCalendarUnit | NSDayCalendarUnit;
|
|
NSDateComponents *components = [gregorian components:unitFlags
|
fromDate:startDate
|
toDate:endDate options:0];
|
NSInteger months = [components month];
|
NSInteger days = [components day];
|
Listing 15
-(BOOL)isDateThisWeek:(NSDate *)date {
|
NSDate *start;
|
NSTimeInterval extends;
|
NSCalendar *cal=[NSCalendar autoupdatingCurrentCalen
|
NSDate *today=[NSDate date];
|
BOOL success= [cal rangeOfUnit:NSWeekCalendarUnit startDate:&start
|
interval: &extends forDate:today];
|
if(!success)return NO;
|
NSTimeInterval dateInSecs = [date timeIntervalSinceReferen
|
NSTimeInterval dayStartInSecs= [start timeIntervalSinceReferen
|
if(dateInSecs > dayStartInSecs && dateInSecs < (dayStartInSecs+extends)){
|
return YES;
|
}
|
else {
|
return NO;
|
}
|
}
|
Time Zones:
time zone会影响从calendar计算的date components,你可以设置NSCalendar的time zone。NSCalendar默认使用应用程序的时区。可以从timeZoneWithName:, timeZoneWithAbbreviation
knownTimeZoneNames]方法获取所有time zone的数组。
可以用setDefaultTimeZone:方法设置默认的时区,用localTimeZone方法始终返回默认的时区。
Listing 16
NSCalendar *gregorian=[[NSCalendar alloc] initWithCalendarIdentifi
|
[gregorian setTimeZone:[NSTimeZone timeZoneWithAbbreviation
|
NSDateComponents *timeZoneComps=[[NSDateComponents alloc] init];
|
[timeZoneComps setHour:16];
|
//specify whatever day, month, and year is appropriate
|
NSDate *date=[gregorian dateFromComponents:timeZoneComps];
|
Date Formatters
有两个基本的方法:dateFromString: 和 stringFromDate:用来在日期和字符串之间转换
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setTimeZone:[NSTimeZone systemTimeZone]];
[formatter setDateFormat:@"yyyy-MM-dd"];
NSDate *date = [formatter dateFromString:string];
[formatter release];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setTimeZone:[NSTimeZone systemTimeZone]];
[formatter setDateFormat:@"yyyy-MM-dd"];
NSString *dateString = [formatter stringFromDate:date];
[formatter release];