// =========================================================================== // NSDate+Extra.m (c) 2006 __MyCompanyName__. All rights reserved. // // --------------------------------------------------------------------------- // Modification History: // // Created: 1/16/06 Pierce T. Wetter III // Last Modified: 1/16/06 Pierce T. Wetter III // // --------------------------------------------------------------------------- // // =========================================================================== #import "NSDate+Extra.h" @implementation NSDate (DayNumbers) - (int) hourOfDay { return [[NSCalendarDate dateWithTimeIntervalSinceReferenceDate: [self timeIntervalSinceReferenceDate]] hourOfDay]; } - (int) minuteOfHour { return [[NSCalendarDate dateWithTimeIntervalSinceReferenceDate: [self timeIntervalSinceReferenceDate]] minuteOfHour]; } - (NSCalendarDate *) dateBySettingDate: (NSDate *) newDate { NSCalendarDate *odate=[NSCalendarDate dateWithTimeIntervalSinceReferenceDate: [self timeIntervalSinceReferenceDate]]; NSCalendarDate *ndate=[NSCalendarDate dateWithTimeIntervalSinceReferenceDate: [newDate timeIntervalSinceReferenceDate]]; return [NSCalendarDate dateWithYear: [ndate yearOfCommonEra] month: [ndate monthOfYear] day: [ndate dayOfMonth] hour: [odate hourOfDay] minute: [odate minuteOfHour] second: [odate secondOfMinute] timeZone: [odate timeZone]]; } - (NSCalendarDate *) dateBySettingTime: (NSDate *) newDate { NSCalendarDate *odate=[NSCalendarDate dateWithTimeIntervalSinceReferenceDate: [self timeIntervalSinceReferenceDate]]; NSCalendarDate *ndate=[NSCalendarDate dateWithTimeIntervalSinceReferenceDate: [newDate timeIntervalSinceReferenceDate]]; return [NSCalendarDate dateWithYear: [odate yearOfCommonEra] month: [odate monthOfYear] day: [odate dayOfMonth] hour: [ndate hourOfDay] minute: [ndate minuteOfHour] second: [ndate secondOfMinute] timeZone: [odate timeZone]]; } - (NSCalendarDate *) dateBySettingHour: (int) hour { NSCalendarDate *odate=[NSCalendarDate dateWithTimeIntervalSinceReferenceDate: [self timeIntervalSinceReferenceDate]]; return [NSCalendarDate dateWithYear: [odate yearOfCommonEra] month: [odate monthOfYear] day: [odate dayOfMonth] hour: hour minute: [odate minuteOfHour] second: [odate secondOfMinute] timeZone: [odate timeZone]]; } - (NSCalendarDate *) dateBySettingMinute: (int) minute { NSCalendarDate *odate=[NSCalendarDate dateWithTimeIntervalSinceReferenceDate: [self timeIntervalSinceReferenceDate]]; return [NSCalendarDate dateWithYear: [odate yearOfCommonEra] month: [odate monthOfYear] day: [odate dayOfMonth] hour: [odate hourOfDay] minute: minute second: [odate secondOfMinute] timeZone: [odate timeZone]]; } // ------------------------------------------------------------------------------ // • sameDateAs // ------------------------------------------------------------------------------ // Compare two calendar dates, ignoring intraday time. Return YES if they // are both the same date. - (BOOL) sameDateAs:(NSDate *) other { BOOL retValue = YES; if (self != other) { retValue = ([self dayNumber] == [other dayNumber]); } return retValue; } // ------------------------------------------------------------------------------ // • dateIsToday // ------------------------------------------------------------------------------ // - (BOOL) isExpired { return [self dayNumber] < [[NSDate date] dayNumber]; } - (BOOL) isCurrent { return [self dayNumber] <= [[NSDate date] dayNumber]; } - (NSString *) dayOfWeekString { return [self descriptionWithCalendarFormat:@"%A" timeZone: nil locale:nil]; } - (BOOL) dateIsToday { return [self sameDateAs:[NSDate date]]; } - (BOOL) dateIsToday1 { return [self sameDateAs:[[NSDate date] dateByAddingDays:1]]; } - (BOOL) dateIsToday2 { return [self sameDateAs:[[NSDate date] dateByAddingDays:2]]; } - (BOOL) dateIsToday3 { return [self sameDateAs:[[NSDate date] dateByAddingDays:3]]; } - (BOOL) dateIsToday4 { return [self sameDateAs:[[NSDate date] dateByAddingDays:4]]; } - (BOOL) dateIsToday5 { return [self sameDateAs:[[NSDate date] dateByAddingDays:5]]; } - (BOOL) dateIsToday6 { return [self sameDateAs:[[NSDate date] dateByAddingDays:6]]; } - (BOOL) dateIsToday7 { return [self sameDateAs:[[NSDate date] dateByAddingDays:7]]; } - (BOOL) dateIsYesterday { return [self sameDateAs:[[NSDate date] dateByAddingDays:-1]]; } - (BOOL) dateIsYesterday1 { return [self sameDateAs:[[NSDate date] dateByAddingDays:-2]]; } - (BOOL) dateIsYesterday2 { return [self sameDateAs:[[NSDate date] dateByAddingDays:-3]]; } - (BOOL) dateIsYesterday3 { return [self sameDateAs:[[NSDate date] dateByAddingDays:-4]]; } - (BOOL) dateIsYesterday4 { return [self sameDateAs:[[NSDate date] dateByAddingDays:-5]]; } - (BOOL) dateIsYesterday5 { return [self sameDateAs:[[NSDate date] dateByAddingDays:-6]]; } - (BOOL) dateIsYesterday6 { return [self sameDateAs:[[NSDate date] dateByAddingDays:-7]]; } - (BOOL) dateIsYesterday7 { return [self sameDateAs:[[NSDate date] dateByAddingDays:-8]]; } // ------------------------------------------------------------------------------ // • dateByAddingDays: days // ------------------------------------------------------------------------------ // - (NSDate *) dateByAddingDays: (int) days { // Tricky: make sure that adding 1 day isn't affected by // daylight savings time. Note whether the // daytime hour has changed, and adjust appropriately. This way, 12:01am // becomes 12:01am the next day regardless of daylight savings time. // There is a known quirk in DST logic. There is no 02:00:00 throuh 02:59:59 // on the first day of DST. So if you have a time in this range // and adding a day puts you into DST, the time the next day will // be exactly 1 hour less. // Using the NSTimeZone object is about 20% faster than the old // implementation -- mlaster //NSTimeZone *tz = nil; //BOOL dstFlag = NO; NSDate *newDate = nil; //tz = [self timeZone]; newDate = [self addTimeInterval: (days*60*60*24)]; /*dstFlag = [tz isDaylightSavingTimeForDate:newDate]; if (dstFlag != [tz isDaylightSavingTimeForDate:self]) { if (dstFlag == YES) { newDate = [newDate addTimeInterval:-60*60]; } else { newDate = [newDate addTimeInterval:60*60]; } }*/ return newDate; } // ------------------------------------------------------------------------------ // • dayNumber // ------------------------------------------------------------------------------ // If two NSDates represent times on the same day (relative to the // receiver's time zone), they will have the same day number. - (long) dayNumber { return (long) floor(([self timeIntervalSinceReferenceDate] + [[NSTimeZone localTimeZone] secondsFromGMTForDate:self]) / (double)(60*60*24)); } // ------------------------------------------------------------------------------ // • compareDay // ------------------------------------------------------------------------------ // Compare two calendar dates (using the receiver's time zone). Dates are // considered equal if they are on the same day at any time. - (NSComparisonResult) compareDay:(NSDate *) other { NSComparisonResult retValue = NSOrderedSame; if (self != other) { long selfDay = 0; long otherDay = 0; selfDay = [self dayNumber]; otherDay = [other dayNumber]; if (selfDay < otherDay) { retValue = NSOrderedAscending; } else if (selfDay > otherDay) { retValue = NSOrderedDescending; } } return retValue; } @end