Date and Time Programming Guide 1

Dates

Creating Time Objects

使用 initWithTimeIntervalSinceNow: 创建

NSTimeInterval secondsPerDay = 24*60*60;
NSDate *yesterday = [[NSDate alloc]initWithTimeIntervalSinceNow:secondsPerDay];
NSDate *tomorrow = [[NSDate alloc]initWithTimeIntervalSinceNow:-secondsPerDay];
NSLog(@"%@,%@",[CommonFunctions convertNSDateToFullNSString:yesterday],[CommonFunctions convertNSDateToFullNSString:tomorrow]);
//OUTPUT: 2015-06-13 11:16:58.873 XYZPersonTest[646:29191] 2015年6月14日 上午11:16,2015年6月12日 上午11:16

使用 dateByAddingTimeInterval:创建

NSTimeInterval timeInterVal = 24*60*60;
NSDate *thisDate = [NSDate date];
NSDate *yesterday, *tomorrow;
yesterday = [thisDate dateByAddingTimeInterval:-timeInterVal];
tomorrow = [thisDate dateByAddingTimeInterval:timeInterVal];
NSLog(@"%@",[CommonFunctions convertNSDateToFullNSString:yesterday]);
NSLog(@"%@",[CommonFunctions convertNSDateToFullNSString:tomorrow]);
/*
 OUTPUT:
 2015-06-13 11:35:04.255 XYZPersonTest[701:32958] 2015年6月12日 上午11:35
 2015-06-13 11:35:04.256 XYZPersonTest[701:32958] 2015年6月14日 上午11:35
 */


Basic Date Calculations

都拿出来试试:

NSTimeInterval secondsPerDay = 24*60*60;
NSTimeInterval secondsPerMin = 60;
NSDate *today = [NSDate date];
NSDate *yesterday, *tomorrow, *laterDate, *earlyDay;

yesterday = [today dateByAddingTimeInterval:-secondsPerDay];
tomorrow = [today dateByAddingTimeInterval:secondsPerDay];

NSLog(@"today is: %@",[CommonFunctions convertNSDateToFullNSString:today]);
NSLog(@"yesterday is: %@",[CommonFunctions convertNSDateToFullNSString:yesterday]);
NSLog(@"tomorrow is: %@",[CommonFunctions convertNSDateToFullNSString:tomorrow]);

BOOL bool1,bool2;
NSComparisonResult result1, result2;

bool1 = [today isEqualToDate:yesterday];
bool2 = [today isEqualToDate:today];

result1 = [today compare:yesterday];
result2 = [today compare:tomorrow];

NSLog(@"today compare yesterday:%ld, compare tomorrow:%ld",result1,result2);

laterDate = [today laterDate:yesterday];
earlyDay = [today earlierDate:tomorrow];

NSLog(@"laterDate of today & yesterday: %@",[CommonFunctions convertNSDateToFullNSString:laterDate]);

NSLog(@"earlyDate of today & tomorrow: %@",[CommonFunctions convertNSDateToFullNSString:earlyDay]);

if ([today timeIntervalSinceDate:yesterday]>secondsPerMin){
    NSLog(@"today - yesterday > 1min");
}


/*OUTPUT:
 2015-06-13 11:55:29.575 XYZPersonTest[737:38212] today is: 2015年6月13日 上午11:55
 2015-06-13 11:55:29.575 XYZPersonTest[737:38212] yesterday is: 2015年6月12日 上午11:55
 2015-06-13 11:55:29.575 XYZPersonTest[737:38212] tomorrow is: 2015年6月14日 上午11:55
 2015-06-13 11:55:29.576 XYZPersonTest[737:38212] today compare yesterday:1, compare tomorrow:-1
 2015-06-13 11:55:29.576 XYZPersonTest[737:38212] laterDate of today & yesterday: 2015年6月13日 上午11:55
 2015-06-13 11:55:29.576 XYZPersonTest[737:38212] earlyDate of today & tomorrow: 2015年6月13日 上午11:55
 2015-06-13 11:55:29.576 XYZPersonTest[737:38212] today - yesterday > 1min
 */

Calendars, Date Components, and Calendar Units

NSCalendar 提供很多中日历法 如:Buddhist, Gregorian, Hebrew, Islamic, and Japanese


Calendar Basics

NSCalendar *localCalendar = [NSCalendar currentCalendar];

NSCalendar *japaneseCalendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierJapanese];

//当前用户区域所使用的历法
NSCalendar *usersCanlendar = [[NSLocale currentLocale]objectForKey:NSLocaleCalendar];

//使用 NSCalendar currentCalendar 方法和 [[NSLocale current] objectForKey:NSLocaleCalendar]返回的结果是一样的
if  ([usersCanlendar isEqual:localCalendar]){
    NSLog(@"YES");
}else{
    NSLog(@"NO");
}
//OUTPUT: YES


Date Components and Calendar Units

NSDateComponents只是用来放带单位的时间值而已,并不会自己计算什么什么:

NSDateComponents *components = [NSDateComponents new];
[components setDay:15];
[components setMonth:5];
[components setYear:2005];
NSInteger weekday = [components weekday];

NSLog(@"%ld",weekday);
//OUTPUT: undefined


Converting between Dates and Date Components

NSDate *today = [NSDate date];

NSCalendar *chineseCalendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierChinese];

NSDateComponents *weekdayDateComponents = [chineseCalendar components:(NSCalendarUnitDay|NSCalendarUnitWeekday) fromDate:today];

NSUInteger day = [weekdayDateComponents day];
NSUInteger weekday = [weekdayDateComponents weekday];

NSLog(@"day: %ld, weekday: %ld",day,weekday);

//OUTPUT: 2015-06-13 15:47:18.221 XYZPersonTest[1030:87278] day: 13, weekday: 7

如果需要知道一天是一年中的第几天, 用NSCalendar 的 ordinalityOfUnit:inUnit:forDate:方法


也可以使用 NSDateComponent 实例里面保存的数据来创建 NSDate 的, 使用一个 NSCalendar 实例的方法 dateFromComponents方法就可以

需要注意的是, 如果这个 NSDateComponents 里面保存的时间数据不足以定义一个时间点, NSCalendar 将根据其 Locale 设置来将不定值赋值为0/1

如果这个 NSDateComponents 存储的时间数据有冲突, NSCalendar 将自动忽略其中一些有冲突的数据

NSCalendar *chineseCalendar = [NSCalendar currentCalendar];
NSDateComponents *components = [NSDateComponents new];

[components setMonth:5];
[components setYear:2011];
[components setWeekday:5];
[components setWeekdayOrdinal:1];

NSDate *thisDay = [chineseCalendar dateFromComponents:components];

NSLog(@"%@",[CommonFunctions convertNSDateToFullNSString:thisDay]);

//OUTPUT: 2015-06-13 16:33:53.117 XYZPersonTest[1117:99792] 2011年5月5日 上午12:00

可以直接省去设置年份直接创建 NSDate, NSCalendar一般会赋值1给 Year, 但是注意显示这个 Date 给用户看得时候需要使用 NSDateFormater 来省去这个默认 Year值

NSCalendar *chineseCalendar = [NSCalendar currentCalendar];
NSDateComponents *components = [NSDateComponents new];

[components setMonth:5];
[components setWeekday:5];
[components setWeekdayOrdinal:1];

NSDate *thisDay = [chineseCalendar dateFromComponents:components];

NSLog(@"%@",[CommonFunctions convertNSDateToFullNSString:thisDay]);

//OUTPUT: 2015-06-13 16:33:53.117 XYZPersonTest[1117:99792] 1年5月5日 上午12:00


这个我不太明白 mark 写来先:

Warning: Mixing and matching week-based calendar constants (NSWeekOfMonthCalendarUnit, NSWeekOfYearCalendarUnit, and NSYearForWeekOfYearCalendarUnit) with other week-oriented calendar constants (defined in the Calendar Units constants) will result in errors. Specifically, the calendar component NSYearCalendarUnit defines the ordinary calendar year, not the year in a week-based calendar. Using an NSCalendar with a calendar year and a weekday when using a calendar created using the week-based calendar constants results in ambiguous dates.


Converting from one Calendar to another

先转成 NSDate 然后再用新的 Calendar 就可以导出了

NSDateComponents *fromCompoents = [NSDateComponents new];
[fromCompoents setDay:6];
[fromCompoents setMonth:5];
[fromCompoents setYear:2004];

NSCalendar *gregorianCalendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierGregorian];

NSDate *thisDate = [gregorianCalendar dateFromComponents:fromCompoents];

NSCalendar *chineseCalendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierChinese];

NSDateComponents *toComponents = [NSDateComponents new];

toComponents = [chineseCalendar components:(NSCalendarUnitDay|NSCalendarUnitMonth|NSCalendarUnitYear) fromDate:thisDate];

NSUInteger day = [toComponents day];
NSUInteger month = [toComponents month];
NSUInteger year = [toComponents year];

NSLog(@"%ld-%ld-%ld",year,month,day);
//OUTPUT: 2015-06-13 16:50:37.489 XYZPersonTest[1137:105241] 21-3-18



Performing Calendar Calculations

Adding Components to Date

使用NSDateComponents进行时间计算

NSDateComponents *dateOffSet = [[NSDateComponents alloc]init];
//这里是可以设置负数的
[dateOffSet setMinute:20];
[dateOffSet setHour:1];

NSCalendar *gregorianCalendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierGregorian];

NSDate *today = [NSDate date];
NSLog(@"%@",[CommonFunctions convertNSDateToFullNSString:today]);

today = [gregorianCalendar dateByAddingComponents:dateOffSet toDate:today options:0];
NSLog(@"%@",[CommonFunctions convertNSDateToFullNSString:today]);

/**OUTPUT:
 2015-06-16 08:57:42.225 XYZPersonTest[573:9066] 2015年6月16日 上午8:57
 2015-06-16 08:57:42.225 XYZPersonTest[573:9066] 2015年6月16日 上午10:17
 */

计算这周的周日是哪天:

//周日是一周的第一天
NSCalendar *localeCalendar = [NSCalendar currentCalendar];
NSDate *today = [NSDate date];
NSLog(@"today is: %@",[CommonFunctions convertNSDateToFullNSString:today]);、
NSDateComponents *weekdayComponents = [localeCalendar components:NSCalendarUnitWeekday fromDate:today];
NSLog(@"weekday: %ld",[weekdayComponents weekday]);
NSDateComponents *dateComponentToSubtract = [[NSDateComponents alloc]init];
[dateComponentToSubtract setDay:0-([weekdayComponents weekday]-1)];
today = [localeCalendar dateByAddingComponents:dateComponentToSubtract toDate:today options:0];
NSLog(@"sunday of this week is: %@",[CommonFunctions convertNSDateToFullNSString:today]);

获取一周的第一天:(不明白...)

NSDate *today = [NSDate date];
NSDate *beginDay = nil;

BOOL ok = [tmpCalendar rangeOfUnit:NSCalendarUnitWeekday startDate:&beginDay interval:NULL forDate:today];

NSLog(@"%d",ok);
NSLog(@"%@",[CommonFunctions convertNSDateToFullNSString:beginDay]);

/*
 OUTPUT:
 2015-06-16 10:30:01.933 XYZPersonTest[860:32818] 1
 2015-06-16 10:30:01.934 XYZPersonTest[860:32818] 2015年6月16日 上午12:00
 */

Determing Temporal Differences

使用 NSCalendar 的components: fromDate: toDate: options:方法取出指定单位的时间间隔

NSTimeInterval secondsPerDay = 24*60*60;
//asume there're 31 days this month
NSTimeInterval secondsPrerMonth = secondsPerDay*31;
NSDate *yesterday = [NSDate dateWithTimeIntervalSinceNow:-secondsPerDay];
NSDate *nextMonthDate = [NSDate dateWithTimeIntervalSinceNow:secondsPrerMonth];
NSLog(@"yesterday: %@",[CommonFunctions convertNSDateToFullNSString:yesterday]);
NSLog(@"next Month this Day: %@",[CommonFunctions convertNSDateToFullNSString:nextMonthDate]);
NSCalendar *currentCalendar = [NSCalendar currentCalendar];
NSDateComponents *gapTimeComponents = [currentCalendar components:(NSCalendarUnitMonth|NSCalendarUnitWeekday) fromDate:yesterday toDate:nextMonthDate options:0];
NSLog(@"month diff: %ld",[gapTimeComponents month]);
NSLog(@"weekday diff: %ld",[gapTimeComponents weekday]);
/*
 OUTPUT:
 2015-06-16 10:44:25.332 XYZPersonTest[895:36941] yesterday: 2015年6月15日 上午10:44
 2015-06-16 10:44:25.333 XYZPersonTest[895:36941] next Month this Day: 2015年7月17日 上午10:44
 2015-06-16 10:44:25.333 XYZPersonTest[895:36941] month diff: 1
 2015-06-16 10:44:25.333 XYZPersonTest[895:36941] weekday diff: 2
 */


使用 ordinalityOfUnit:inUnit:forDate:


@interface NSCalendar (mySpecialCalculation)
-(NSInteger)daysWithinEraFromDay: (NSDate *)fromDate toDate:(NSDate *)toDate;
@end
@implementation NSCalendar (mySpecialCalculation)
-(NSInteger)daysWithinEraFromDay: (NSDate *)fromDate toDate:(NSDate *)toDate{
    NSInteger startDay = [self ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:fromDate];
    NSInteger endDay = [self ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:toDate];
    return endDay - startDay;
}
@end






标签:ios, object-c