Rework how dates are formatted in home view.

pull/1/head
Matthew Chen 7 years ago
parent b8f8a3017a
commit abba24988c

@ -45,6 +45,8 @@ extern const CGFloat kBubbleTextVInset;
- (void)updatePartnerViews; - (void)updatePartnerViews;
+ (CGFloat)minWidth;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

@ -239,6 +239,11 @@ const CGFloat kBubbleTextVInset = 10.f;
} }
} }
+ (CGFloat)minWidth
{
return (kBubbleHRounding * 2 + kBubbleThornSideInset);
}
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

@ -933,6 +933,9 @@ NS_ASSUME_NONNULL_BEGIN
cellSize.width = MAX(cellSize.width, textContentSize.width); cellSize.width = MAX(cellSize.width, textContentSize.width);
cellSize.height += textContentSize.height; cellSize.height += textContentSize.height;
// Make sure the bubble is always wide enough to complete it's bubble shape.
cellSize.width = MAX(cellSize.width, OWSBubbleView.minWidth);
OWSAssert(cellSize.width > 0 && cellSize.height > 0); OWSAssert(cellSize.width > 0 && cellSize.height > 0);
if (self.hasTapForMore) { if (self.hasTapForMore) {

@ -71,6 +71,7 @@ NS_ASSUME_NONNULL_BEGIN
[DebugUIMessages allQuotedReplyAction:thread], [DebugUIMessages allQuotedReplyAction:thread],
// Exemplary // Exemplary
[DebugUIMessages allFakeAction:thread], [DebugUIMessages allFakeAction:thread],
[DebugUIMessages allFakeBackDatedAction:thread],
]) { ]) {
[items addObject:[OWSTableItem itemWithTitle:action.label [items addObject:[OWSTableItem itemWithTitle:action.label
actionBlock:^{ actionBlock:^{
@ -108,6 +109,10 @@ NS_ASSUME_NONNULL_BEGIN
actionBlock:^{ actionBlock:^{
[DebugUIMessages selectQuotedReplyAction:thread]; [DebugUIMessages selectQuotedReplyAction:thread];
}], }],
[OWSTableItem itemWithTitle:@"Select Back-Dated"
actionBlock:^{
[DebugUIMessages selectBackDatedAction:thread];
}],
#pragma mark - Misc. #pragma mark - Misc.
@ -2656,6 +2661,7 @@ NS_ASSUME_NONNULL_BEGIN
[actions addObjectsFromArray:[self allFakeTextActions:thread includeLabels:includeLabels]]; [actions addObjectsFromArray:[self allFakeTextActions:thread includeLabels:includeLabels]];
[actions addObjectsFromArray:[self allFakeSequenceActions:thread includeLabels:includeLabels]]; [actions addObjectsFromArray:[self allFakeSequenceActions:thread includeLabels:includeLabels]];
[actions addObjectsFromArray:[self allFakeQuotedReplyActions:thread includeLabels:includeLabels]]; [actions addObjectsFromArray:[self allFakeQuotedReplyActions:thread includeLabels:includeLabels]];
[actions addObjectsFromArray:[self allFakeBackDatedActions:thread includeLabels:includeLabels]];
return actions; return actions;
} }
@ -2827,6 +2833,74 @@ NS_ASSUME_NONNULL_BEGIN
subactions:[self allFakeSequenceActions:thread includeLabels:YES]]; subactions:[self allFakeSequenceActions:thread includeLabels:YES]];
} }
#pragma mark - Back-dated
+ (DebugUIMessagesAction *)fakeBackDatedMessageAction:(TSThread *)thread
label:(NSString *)label
dateOffset:(int64_t)dateOffset
{
OWSAssert(thread);
return [DebugUIMessagesSingleAction
actionWithLabel:[NSString stringWithFormat:@"Fake Back-Date Message (%@)", label]
unstaggeredActionBlock:^(NSUInteger index, YapDatabaseReadWriteTransaction *transaction) {
NSString *messageBody =
[[@(index).stringValue stringByAppendingString:@" "] stringByAppendingString:self.randomText];
TSOutgoingMessage *message = [self createFakeOutgoingMessage:thread
messageBody:messageBody
fakeAssetLoader:nil
messageState:TSOutgoingMessageStateSentToService
isDelivered:NO
isRead:NO
quotedMessage:nil
transaction:transaction];
[message setReceivedAtTimestamp:(uint64_t)((int64_t)[NSDate ows_millisecondTimeStamp] + dateOffset)];
[message saveWithTransaction:transaction];
}];
}
+ (NSArray<DebugUIMessagesAction *> *)allFakeBackDatedActions:(TSThread *)thread includeLabels:(BOOL)includeLabels
{
OWSAssert(thread);
NSMutableArray<DebugUIMessagesAction *> *actions = [NSMutableArray new];
if (includeLabels) {
[actions addObject:[self fakeOutgoingTextMessageAction:thread
messageState:TSOutgoingMessageStateSentToService
text:@"⚠️ Back-Dated ⚠️"]];
}
[actions
addObject:[self fakeBackDatedMessageAction:thread label:@"One Minute Ago" dateOffset:-(int64_t)kMinuteInMs]];
[actions addObject:[self fakeBackDatedMessageAction:thread label:@"One Hour Ago" dateOffset:-(int64_t)kHourInMs]];
[actions addObject:[self fakeBackDatedMessageAction:thread label:@"One Day Ago" dateOffset:-(int64_t)kDayInMs]];
[actions
addObject:[self fakeBackDatedMessageAction:thread label:@"Two Days Ago" dateOffset:-(int64_t)kDayInMs * 2]];
[actions
addObject:[self fakeBackDatedMessageAction:thread label:@"Ten Days Ago" dateOffset:-(int64_t)kDayInMs * 10]];
[actions
addObject:[self fakeBackDatedMessageAction:thread label:@"400 Days Ago" dateOffset:-(int64_t)kDayInMs * 400]];
return actions;
}
+ (DebugUIMessagesAction *)allFakeBackDatedAction:(TSThread *)thread
{
OWSAssert(thread);
return [DebugUIMessagesGroupAction allGroupActionWithLabel:@"All Fake Back-Dated"
subactions:[self allFakeBackDatedActions:thread includeLabels:YES]];
}
+ (void)selectBackDatedAction:(TSThread *)thread
{
OWSAssertIsOnMainThread();
OWSAssert(thread);
[self selectActionUI:[self allFakeBackDatedActions:thread includeLabels:NO] label:@"Select Back-Dated"];
}
#pragma mark - #pragma mark -
+ (NSString *)randomOversizeText + (NSString *)randomOversizeText

@ -7,6 +7,7 @@
#import "Signal-Swift.h" #import "Signal-Swift.h"
#import <SignalMessaging/OWSFormat.h> #import <SignalMessaging/OWSFormat.h>
#import <SignalMessaging/OWSUserProfile.h> #import <SignalMessaging/OWSUserProfile.h>
#import <SignalMessaging/SignalMessaging-Swift.h>
#import <SignalServiceKit/OWSMessageManager.h> #import <SignalServiceKit/OWSMessageManager.h>
#import <SignalServiceKit/TSContactThread.h> #import <SignalServiceKit/TSContactThread.h>
#import <SignalServiceKit/TSGroupThread.h> #import <SignalServiceKit/TSGroupThread.h>
@ -26,12 +27,12 @@ const NSUInteger kHomeViewAvatarHSpacing = 12;
@property (nonatomic) UIView *payloadView; @property (nonatomic) UIView *payloadView;
@property (nonatomic) UILabel *nameLabel; @property (nonatomic) UILabel *nameLabel;
@property (nonatomic) UILabel *snippetLabel; @property (nonatomic) UILabel *snippetLabel;
@property (nonatomic) UILabel *timeLabel; @property (nonatomic) UILabel *dateTimeLabel;
@property (nonatomic) UIView *unreadBadge; @property (nonatomic) UIView *unreadBadge;
@property (nonatomic) UILabel *unreadLabel; @property (nonatomic) UILabel *unreadLabel;
@property (nonatomic) TSThread *thread; @property (nonatomic, nullable) TSThread *thread;
@property (nonatomic) OWSContactsManager *contactsManager; @property (nonatomic, nullable) OWSContactsManager *contactsManager;
@property (nonatomic, readonly) NSMutableArray<NSLayoutConstraint *> *viewConstraints; @property (nonatomic, readonly) NSMutableArray<NSLayoutConstraint *> *viewConstraints;
@ -93,13 +94,13 @@ const NSUInteger kHomeViewAvatarHSpacing = 12;
[self.nameLabel setContentHuggingHorizontalLow]; [self.nameLabel setContentHuggingHorizontalLow];
[self.nameLabel setCompressionResistanceHorizontalLow]; [self.nameLabel setCompressionResistanceHorizontalLow];
self.timeLabel = [UILabel new]; self.dateTimeLabel = [UILabel new];
[self.timeLabel setContentHuggingHorizontalHigh]; [self.dateTimeLabel setContentHuggingHorizontalHigh];
[self.timeLabel setCompressionResistanceHorizontalHigh]; [self.dateTimeLabel setCompressionResistanceHorizontalHigh];
UIStackView *topRowView = [[UIStackView alloc] initWithArrangedSubviews:@[ UIStackView *topRowView = [[UIStackView alloc] initWithArrangedSubviews:@[
self.nameLabel, self.nameLabel,
self.timeLabel, self.dateTimeLabel,
]]; ]];
topRowView.axis = UILayoutConstraintAxisHorizontal; topRowView.axis = UILayoutConstraintAxisHorizontal;
topRowView.spacing = 4; topRowView.spacing = 4;
@ -130,7 +131,7 @@ const NSUInteger kHomeViewAvatarHSpacing = 12;
self.unreadBadge.backgroundColor = [UIColor ows_materialBlueColor]; self.unreadBadge.backgroundColor = [UIColor ows_materialBlueColor];
[self.contentView addSubview:self.unreadBadge]; [self.contentView addSubview:self.unreadBadge];
[self.unreadBadge autoPinTrailingToSuperviewMarginWithInset:kHomeViewCellHMargin]; [self.unreadBadge autoPinTrailingToSuperviewMarginWithInset:kHomeViewCellHMargin];
[self.unreadBadge autoAlignAxis:ALAxisHorizontal toSameAxisOfView:self.timeLabel]; [self.unreadBadge autoAlignAxis:ALAxisHorizontal toSameAxisOfView:self.dateTimeLabel];
[self.unreadBadge setContentHuggingHigh]; [self.unreadBadge setContentHuggingHigh];
[self.unreadBadge setCompressionResistanceHigh]; [self.unreadBadge setCompressionResistanceHigh];
@ -193,12 +194,12 @@ const NSUInteger kHomeViewAvatarHSpacing = 12;
self.snippetLabel.attributedText = self.snippetLabel.attributedText =
[self attributedSnippetForThread:thread blockedPhoneNumberSet:blockedPhoneNumberSet]; [self attributedSnippetForThread:thread blockedPhoneNumberSet:blockedPhoneNumberSet];
self.timeLabel.attributedText = [self attributedStringForDate:thread.lastMessageDate]; self.dateTimeLabel.attributedText = [self attributedStringForDate:thread.lastMessageDate];
self.separatorInset self.separatorInset
= UIEdgeInsetsMake(0, kHomeViewAvatarSize + kHomeViewCellHMargin + kHomeViewAvatarHSpacing, 0, 0); = UIEdgeInsetsMake(0, kHomeViewAvatarSize + kHomeViewCellHMargin + kHomeViewAvatarHSpacing, 0, 0);
self.timeLabel.textColor = hasUnreadMessages ? [UIColor ows_materialBlueColor] : [UIColor ows_darkGrayColor]; self.dateTimeLabel.textColor = hasUnreadMessages ? [UIColor ows_materialBlueColor] : [UIColor ows_darkGrayColor];
NSUInteger unreadCount = [[OWSMessageUtils sharedManager] unreadMessagesInThread:thread]; NSUInteger unreadCount = [[OWSMessageUtils sharedManager] unreadMessagesInThread:thread];
if (unreadCount > 0) { if (unreadCount > 0) {
@ -298,10 +299,18 @@ const NSUInteger kHomeViewAvatarHSpacing = 12;
return [NSAttributedString new]; return [NSAttributedString new];
} }
NSDateFormatter *formatter = ([DateUtil dateIsToday:date] ? [DateUtil timeFormatter] : [DateUtil dateFormatter]); NSString *dateTimeString;
NSString *timeString = [formatter stringFromDate:date]; if (![DateUtil dateIsThisYear:date]) {
OWSAssert(timeString); dateTimeString = [[DateUtil dateFormatter] stringFromDate:date];
return [[NSAttributedString alloc] initWithString:timeString } else if ([DateUtil dateIsOlderThanOneWeek:date]) {
dateTimeString = [[DateUtil monthAndDayFormatter] stringFromDate:date];
} else if ([DateUtil dateIsOlderThanOneDay:date]) {
dateTimeString = [[DateUtil shortDayOfWeekFormatter] stringFromDate:date];
} else {
dateTimeString = [[DateUtil timeFormatter] stringFromDate:date];
}
return [[NSAttributedString alloc] initWithString:dateTimeString
attributes:@{ attributes:@{
NSForegroundColorAttributeName : [UIColor ows_darkGrayColor], NSForegroundColorAttributeName : [UIColor ows_darkGrayColor],
NSFontAttributeName : self.dateTimeFont, NSFontAttributeName : self.dateTimeFont,

@ -8,10 +8,13 @@ NS_ASSUME_NONNULL_BEGIN
+ (NSDateFormatter *)dateFormatter; + (NSDateFormatter *)dateFormatter;
+ (NSDateFormatter *)timeFormatter; + (NSDateFormatter *)timeFormatter;
+ (NSDateFormatter *)monthAndDayFormatter;
+ (NSDateFormatter *)shortDayOfWeekFormatter;
+ (BOOL)dateIsOlderThanOneDay:(NSDate *)date; + (BOOL)dateIsOlderThanOneDay:(NSDate *)date;
+ (BOOL)dateIsOlderThanOneWeek:(NSDate *)date; + (BOOL)dateIsOlderThanOneWeek:(NSDate *)date;
+ (BOOL)dateIsToday:(NSDate *)date; + (BOOL)dateIsToday:(NSDate *)date;
+ (BOOL)dateIsThisYear:(NSDate *)date;
+ (NSString *)formatPastTimestampRelativeToNow:(uint64_t)pastTimestamp + (NSString *)formatPastTimestampRelativeToNow:(uint64_t)pastTimestamp
isRTL:(BOOL)isRTL NS_SWIFT_NAME(formatPastTimestampRelativeToNow(_:isRTL:)); isRTL:(BOOL)isRTL NS_SWIFT_NAME(formatPastTimestampRelativeToNow(_:isRTL:));

@ -47,12 +47,46 @@ static NSString *const DATE_FORMAT_WEEKDAY = @"EEEE";
return formatter; return formatter;
} }
+ (NSDateFormatter *)monthAndDayFormatter
{
static NSDateFormatter *formatter;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
formatter = [NSDateFormatter new];
[formatter setLocale:[NSLocale currentLocale]];
formatter.dateFormat = @"MMM d";
});
return formatter;
}
+ (NSDateFormatter *)shortDayOfWeekFormatter
{
static NSDateFormatter *formatter;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
formatter = [NSDateFormatter new];
[formatter setLocale:[NSLocale currentLocale]];
formatter.dateFormat = @"E";
});
return formatter;
}
+ (BOOL)dateIsOlderThanOneDay:(NSDate *)date { + (BOOL)dateIsOlderThanOneDay:(NSDate *)date {
return [[NSDate date] timeIntervalSinceDate:date] > kDayInterval; NSDate *now = [NSDate date];
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;
} }
+ (BOOL)dateIsOlderThanOneWeek:(NSDate *)date { + (BOOL)dateIsOlderThanOneWeek:(NSDate *)date {
return [[NSDate date] timeIntervalSinceDate:date] > kWeekInterval; NSDate *now = [NSDate date];
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);
} }
+ (BOOL)date:(NSDate *)date isEqualToDateIgnoringTime:(NSDate *)anotherDate { + (BOOL)date:(NSDate *)date isEqualToDateIgnoringTime:(NSDate *)anotherDate {
@ -65,7 +99,18 @@ static NSString *const DATE_FORMAT_WEEKDAY = @"EEEE";
} }
+ (BOOL)dateIsToday:(NSDate *)date { + (BOOL)dateIsToday:(NSDate *)date {
return [self date:[NSDate date] isEqualToDateIgnoringTime:date]; NSDate *now = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
return ([calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:date] ==
[calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:now]);
}
+ (BOOL)dateIsThisYear:(NSDate *)date
{
NSDate *now = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
return (
[calendar component:NSCalendarUnitYear fromDate:date] == [calendar component:NSCalendarUnitYear fromDate:now]);
} }
+ (BOOL)dateIsYesterday:(NSDate *)date + (BOOL)dateIsYesterday:(NSDate *)date

@ -3,6 +3,7 @@
// //
#import "UtilTest.h" #import "UtilTest.h"
#import "DateUtil.h"
#import "TestUtil.h" #import "TestUtil.h"
#import <SignalMessaging/NSString+OWS.h> #import <SignalMessaging/NSString+OWS.h>
#import <SignalServiceKit/NSDate+OWS.h> #import <SignalServiceKit/NSDate+OWS.h>
@ -76,6 +77,109 @@
XCTAssertTrue([laterDate isAfterDate:firstDate]); XCTAssertTrue([laterDate isAfterDate:firstDate]);
} }
- (void)testDateComparators
{
NSDate *now = [NSDate new];
NSDate *oneSecondAgo =
[NSDate dateWithTimeIntervalSinceReferenceDate:[now timeIntervalSinceReferenceDate] - kSecondInterval];
NSDate *oneMinuteAgo =
[NSDate dateWithTimeIntervalSinceReferenceDate:[now timeIntervalSinceReferenceDate] - kMinuteInterval];
NSDate *oneDayAgo =
[NSDate dateWithTimeIntervalSinceReferenceDate:[now timeIntervalSinceReferenceDate] - kDayInterval];
NSDate *threeDaysAgo =
[NSDate dateWithTimeIntervalSinceReferenceDate:[now timeIntervalSinceReferenceDate] - kDayInterval * 3];
NSDate *tenDaysAgo =
[NSDate dateWithTimeIntervalSinceReferenceDate:[now timeIntervalSinceReferenceDate] - kDayInterval * 10];
NSDate *oneYearAgo =
[NSDate dateWithTimeIntervalSinceReferenceDate:[now timeIntervalSinceReferenceDate] - kYearInterval];
NSDate *twoYearsAgo =
[NSDate dateWithTimeIntervalSinceReferenceDate:[now timeIntervalSinceReferenceDate] - kYearInterval * 2];
NSDate *oneSecondAhead =
[NSDate dateWithTimeIntervalSinceReferenceDate:[now timeIntervalSinceReferenceDate] + kSecondInterval];
NSDate *oneMinuteAhead =
[NSDate dateWithTimeIntervalSinceReferenceDate:[now timeIntervalSinceReferenceDate] + kMinuteInterval];
NSDate *oneDayAhead =
[NSDate dateWithTimeIntervalSinceReferenceDate:[now timeIntervalSinceReferenceDate] + kDayInterval];
NSDate *threeDaysAhead =
[NSDate dateWithTimeIntervalSinceReferenceDate:[now timeIntervalSinceReferenceDate] + kDayInterval * 3];
NSDate *tenDaysAhead =
[NSDate dateWithTimeIntervalSinceReferenceDate:[now timeIntervalSinceReferenceDate] + kDayInterval * 10];
NSDate *oneYearAhead =
[NSDate dateWithTimeIntervalSinceReferenceDate:[now timeIntervalSinceReferenceDate] + kYearInterval];
NSDate *twoYearsAhead =
[NSDate dateWithTimeIntervalSinceReferenceDate:[now timeIntervalSinceReferenceDate] + kYearInterval * 2];
// These might fail around midnight.
XCTAssertTrue([DateUtil dateIsToday:oneSecondAgo]);
XCTAssertTrue([DateUtil dateIsToday:oneMinuteAgo]);
XCTAssertFalse([DateUtil dateIsToday:oneDayAgo]);
XCTAssertFalse([DateUtil dateIsToday:threeDaysAgo]);
XCTAssertFalse([DateUtil dateIsToday:tenDaysAgo]);
XCTAssertFalse([DateUtil dateIsToday:oneYearAgo]);
XCTAssertFalse([DateUtil dateIsToday:twoYearsAgo]);
// These might fail around midnight.
XCTAssertTrue([DateUtil dateIsToday:oneSecondAhead]);
XCTAssertTrue([DateUtil dateIsToday:oneMinuteAhead]);
XCTAssertFalse([DateUtil dateIsToday:oneDayAhead]);
XCTAssertFalse([DateUtil dateIsToday:threeDaysAhead]);
XCTAssertFalse([DateUtil dateIsToday:tenDaysAhead]);
XCTAssertFalse([DateUtil dateIsToday:oneYearAhead]);
XCTAssertFalse([DateUtil dateIsToday:twoYearsAhead]);
// These might fail around midnight.
XCTAssertFalse([DateUtil dateIsOlderThanOneDay:oneSecondAgo]);
XCTAssertFalse([DateUtil dateIsOlderThanOneDay:oneMinuteAgo]);
XCTAssertTrue([DateUtil dateIsOlderThanOneDay:oneDayAgo]);
XCTAssertTrue([DateUtil dateIsOlderThanOneDay:threeDaysAgo]);
XCTAssertTrue([DateUtil dateIsOlderThanOneDay:tenDaysAgo]);
XCTAssertTrue([DateUtil dateIsOlderThanOneDay:oneYearAgo]);
XCTAssertTrue([DateUtil dateIsOlderThanOneDay:twoYearsAgo]);
// These might fail around midnight.
XCTAssertFalse([DateUtil dateIsOlderThanOneDay:oneSecondAhead]);
XCTAssertFalse([DateUtil dateIsOlderThanOneDay:oneMinuteAhead]);
XCTAssertFalse([DateUtil dateIsOlderThanOneDay:oneDayAhead]);
XCTAssertFalse([DateUtil dateIsOlderThanOneDay:threeDaysAhead]);
XCTAssertFalse([DateUtil dateIsOlderThanOneDay:tenDaysAhead]);
XCTAssertFalse([DateUtil dateIsOlderThanOneDay:oneYearAhead]);
XCTAssertFalse([DateUtil dateIsOlderThanOneDay:twoYearsAhead]);
// These might fail around midnight.
XCTAssertFalse([DateUtil dateIsOlderThanOneWeek:oneSecondAgo]);
XCTAssertFalse([DateUtil dateIsOlderThanOneWeek:oneMinuteAgo]);
XCTAssertFalse([DateUtil dateIsOlderThanOneWeek:oneDayAgo]);
XCTAssertFalse([DateUtil dateIsOlderThanOneWeek:threeDaysAgo]);
XCTAssertTrue([DateUtil dateIsOlderThanOneWeek:tenDaysAgo]);
XCTAssertTrue([DateUtil dateIsOlderThanOneWeek:oneYearAgo]);
XCTAssertTrue([DateUtil dateIsOlderThanOneWeek:twoYearsAgo]);
// These might fail around midnight.
XCTAssertFalse([DateUtil dateIsOlderThanOneWeek:oneSecondAhead]);
XCTAssertFalse([DateUtil dateIsOlderThanOneWeek:oneMinuteAhead]);
XCTAssertFalse([DateUtil dateIsOlderThanOneWeek:oneDayAhead]);
XCTAssertFalse([DateUtil dateIsOlderThanOneWeek:threeDaysAhead]);
XCTAssertFalse([DateUtil dateIsOlderThanOneWeek:tenDaysAhead]);
XCTAssertFalse([DateUtil dateIsOlderThanOneWeek:oneYearAhead]);
XCTAssertFalse([DateUtil dateIsOlderThanOneWeek:twoYearsAhead]);
// These might fail around new year's.
XCTAssertTrue([DateUtil dateIsThisYear:oneSecondAgo]);
XCTAssertTrue([DateUtil dateIsThisYear:oneMinuteAgo]);
XCTAssertTrue([DateUtil dateIsThisYear:oneDayAgo]);
XCTAssertFalse([DateUtil dateIsThisYear:oneYearAgo]);
XCTAssertFalse([DateUtil dateIsThisYear:twoYearsAgo]);
// These might fail around new year's.
XCTAssertTrue([DateUtil dateIsThisYear:oneSecondAhead]);
XCTAssertTrue([DateUtil dateIsThisYear:oneMinuteAhead]);
XCTAssertTrue([DateUtil dateIsThisYear:oneDayAhead]);
XCTAssertFalse([DateUtil dateIsThisYear:oneYearAhead]);
XCTAssertFalse([DateUtil dateIsThisYear:twoYearsAhead]);
}
- (void)testObjectComparison - (void)testObjectComparison
{ {
XCTAssertTrue([NSObject isNullableObject:nil equalTo:nil]); XCTAssertTrue([NSObject isNullableObject:nil equalTo:nil]);

@ -5,12 +5,15 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
// These NSTimeInterval constants provide simplified durations for readability. // These NSTimeInterval constants provide simplified durations for readability.
//
// These approximations should never be used for strict date/time calcuations.
extern const NSTimeInterval kSecondInterval; extern const NSTimeInterval kSecondInterval;
extern const NSTimeInterval kMinuteInterval; extern const NSTimeInterval kMinuteInterval;
extern const NSTimeInterval kHourInterval; extern const NSTimeInterval kHourInterval;
extern const NSTimeInterval kDayInterval; extern const NSTimeInterval kDayInterval;
extern const NSTimeInterval kWeekInterval; extern const NSTimeInterval kWeekInterval;
extern const NSTimeInterval kMonthInterval; extern const NSTimeInterval kMonthInterval;
extern const NSTimeInterval kYearInterval;
#define kSecondInMs ((uint64_t)1000) #define kSecondInMs ((uint64_t)1000)
#define kMinuteInMs (kSecondInMs * 60) #define kMinuteInMs (kSecondInMs * 60)

@ -14,6 +14,7 @@ const NSTimeInterval kHourInterval = 60 * kMinuteInterval;
const NSTimeInterval kDayInterval = 24 * kHourInterval; const NSTimeInterval kDayInterval = 24 * kHourInterval;
const NSTimeInterval kWeekInterval = 7 * kDayInterval; const NSTimeInterval kWeekInterval = 7 * kDayInterval;
const NSTimeInterval kMonthInterval = 30 * kDayInterval; const NSTimeInterval kMonthInterval = 30 * kDayInterval;
const NSTimeInterval kYearInterval = 365 * kDayInterval;
@implementation NSDate (OWS) @implementation NSDate (OWS)

Loading…
Cancel
Save