diff --git a/Signal/src/util/DateUtil.m b/Signal/src/util/DateUtil.m index d22255f41..168728be2 100644 --- a/Signal/src/util/DateUtil.m +++ b/Signal/src/util/DateUtil.m @@ -78,11 +78,8 @@ static NSString *const DATE_FORMAT_WEEKDAY = @"EEEE"; + (BOOL)dateIsOlderThanToday:(NSDate *)date now:(NSDate *)now { - NSCalendar *calendar = [NSCalendar currentCalendar]; - - NSUInteger dateDayOfEra = [calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:date]; - NSUInteger nowDayOfEra = [calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:now]; - return dateDayOfEra < nowDayOfEra; + NSInteger dayDifference = [self daysFromFirstDate:date toSecondDate:now]; + return dayDifference > 0; } + (BOOL)dateIsOlderThanOneWeek:(NSDate *)date @@ -92,11 +89,8 @@ static NSString *const DATE_FORMAT_WEEKDAY = @"EEEE"; + (BOOL)dateIsOlderThanOneWeek:(NSDate *)date now:(NSDate *)now { - NSCalendar *calendar = [NSCalendar currentCalendar]; - - NSUInteger dateDayOfEra = [calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:date]; - NSUInteger nowDayOfEra = [calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:now]; - return dateDayOfEra < (nowDayOfEra - 6); + NSInteger dayDifference = [self daysFromFirstDate:date toSecondDate:now]; + return dayDifference > 6; } + (BOOL)dateIsToday:(NSDate *)date @@ -106,9 +100,8 @@ static NSString *const DATE_FORMAT_WEEKDAY = @"EEEE"; + (BOOL)dateIsToday:(NSDate *)date now:(NSDate *)now { - NSCalendar *calendar = [NSCalendar currentCalendar]; - return ([calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:date] == - [calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:now]); + NSInteger dayDifference = [self daysFromFirstDate:date toSecondDate:now]; + return dayDifference == 0; } + (BOOL)dateIsThisYear:(NSDate *)date @@ -129,10 +122,27 @@ static NSString *const DATE_FORMAT_WEEKDAY = @"EEEE"; } + (BOOL)dateIsYesterday:(NSDate *)date now:(NSDate *)now +{ + NSInteger dayDifference = [self daysFromFirstDate:date toSecondDate:now]; + return dayDifference == 1; +} + +// Returns the difference in days, ignoring hours, minutes, seconds. +// If both dates are the same date, returns 0. +// If firstDate is a day before secondDate, returns 1. +// +// Note: Assumes both dates use the "current" calendar. ++ (NSInteger)daysFromFirstDate:(NSDate *)firstDate toSecondDate:(NSDate *)secondDate { NSCalendar *calendar = [NSCalendar currentCalendar]; - return ([calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:date] == - [calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:now] - 1); + NSCalendarUnit units = NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay; + NSDateComponents *comp1 = [calendar components:units fromDate:firstDate]; + NSDateComponents *comp2 = [calendar components:units fromDate:secondDate]; + [comp1 setHour:12]; + [comp2 setHour:12]; + NSDate *date1 = [calendar dateFromComponents:comp1]; + NSDate *date2 = [calendar dateFromComponents:comp2]; + return [[calendar components:NSCalendarUnitDay fromDate:date1 toDate:date2 options:0] day]; } + (NSString *)formatPastTimestampRelativeToNow:(uint64_t)pastTimestamp isRTL:(BOOL)isRTL diff --git a/Signal/test/util/UtilTest.m b/Signal/test/util/UtilTest.m index 4091725f9..308d3ae39 100644 --- a/Signal/test/util/UtilTest.m +++ b/Signal/test/util/UtilTest.m @@ -214,6 +214,58 @@ XCTAssertFalse([DateUtil dateIsThisYear:twoYearsAhead now:now]); } +- (NSDate *)dateWithYear:(NSInteger)year + month:(NSInteger)month + day:(NSInteger)day + hour:(NSInteger)hour + minute:(NSInteger)minute +{ + NSDateComponents *components = [NSDateComponents new]; + components.year = year; + components.month = month; + components.day = day; + components.hour = hour; + components.minute = minute; + return [[NSCalendar currentCalendar] dateFromComponents:components]; +} + +- (void)testDateComparators_timezoneVMidnight +{ + NSDateFormatter *formatter = [NSDateFormatter new]; + formatter.dateStyle = NSDateFormatterLongStyle; + formatter.timeStyle = NSDateFormatterLongStyle; + + NSDate *yesterdayBeforeMidnight = [self dateWithYear:2015 month:8 day:10 hour:23 minute:55]; + NSLog(@"yesterdayBeforeMidnight: %@", [formatter stringFromDate:yesterdayBeforeMidnight]); + + NSDate *todayAfterMidnight = [self dateWithYear:2015 month:8 day:11 hour:0 minute:5]; + NSLog(@"todayAfterMidnight: %@", [formatter stringFromDate:todayAfterMidnight]); + + NSDate *todayNoon = [self dateWithYear:2015 month:8 day:11 hour:12 minute:0]; + NSLog(@"todayNoon: %@", [formatter stringFromDate:todayNoon]); + + // Before Midnight, after Midnight. + XCTAssertFalse([DateUtil dateIsToday:yesterdayBeforeMidnight now:todayAfterMidnight]); + XCTAssertTrue([DateUtil dateIsYesterday:yesterdayBeforeMidnight now:todayAfterMidnight]); + XCTAssertTrue([DateUtil dateIsOlderThanToday:yesterdayBeforeMidnight now:todayAfterMidnight]); + XCTAssertFalse([DateUtil dateIsOlderThanOneWeek:yesterdayBeforeMidnight now:todayAfterMidnight]); + XCTAssertTrue([DateUtil dateIsThisYear:yesterdayBeforeMidnight now:todayAfterMidnight]); + + // Before Midnight, noon. + XCTAssertFalse([DateUtil dateIsToday:yesterdayBeforeMidnight now:todayNoon]); + XCTAssertTrue([DateUtil dateIsYesterday:yesterdayBeforeMidnight now:todayNoon]); + XCTAssertTrue([DateUtil dateIsOlderThanToday:yesterdayBeforeMidnight now:todayNoon]); + XCTAssertFalse([DateUtil dateIsOlderThanOneWeek:yesterdayBeforeMidnight now:todayNoon]); + XCTAssertTrue([DateUtil dateIsThisYear:yesterdayBeforeMidnight now:todayNoon]); + + // After Midnight, noon. + XCTAssertTrue([DateUtil dateIsToday:todayAfterMidnight now:todayNoon]); + XCTAssertFalse([DateUtil dateIsYesterday:todayAfterMidnight now:todayNoon]); + XCTAssertFalse([DateUtil dateIsOlderThanToday:todayAfterMidnight now:todayNoon]); + XCTAssertFalse([DateUtil dateIsOlderThanOneWeek:todayAfterMidnight now:todayNoon]); + XCTAssertTrue([DateUtil dateIsThisYear:todayAfterMidnight now:todayNoon]); +} + - (void)testObjectComparison { XCTAssertTrue([NSObject isNullableObject:nil equalTo:nil]);