我一直在玩日期格式化,并想出了一个简单的测试,看看它是否按预期工作。它创建了一些从当前开始的日期,并在每次迭代时间内返回15分钟。然后测试输出格式化日期和实际日期数据进行比较:
- (void)testDateFormatting {
NSDate *date;
NSDateFormatter *formatter = [NSDateFormatter new];
[formatter setLocale:[NSLocale localeWithLocaleIdentifier:@"ru_RU" ]];
[formatter setDateFormat:@"HH:mm EE dd.MM"];
for (NSUInteger i = 0; i < 500; i++) {
NSTimeInterval time = - (60.0 * i * 15);
date = [NSDate dateWithTimeIntervalSinceNow:time];
NSString *formattedDateString = [SCRBDateFormatter stringFormattedToXAgoFromDate:date];
NSLog(@"%@ - %@", formattedDateString, [formatter stringFromDate:date]);
XCTAssert(formattedDateString, @"TEST_ERROR: stringFormattedToXAgoFromDate: returned nil.");
}
}
当我将迭代次数增加到500时,我注意到1%的输出被弄乱了。
更新:密切关注输出我注意到即使序列不对,这怎么可能? (将时间间隔从15改为1分钟,以便看到更好的序列)
2015-09-16 16:28:42.292 ScoreBook[5081:666920] 35 МИН. НАЗАД - 15:53 ср 16.09
2015-09-16 16:28:42.293 ScoreBook[5081:666920] 36 МИН. НАЗАД - 15:52 ср 16.09
2015-09-16 16:28:42.293 ScoreBook[5081:666920] 37 МИН. НАЗАД - 15:51 ср 16.09
2015-09-16 16:28:42.294 ScoreBook[5081:666920] 38 МИН. НАЗАср 16.09
2015-09-16 16:28:42.293 ScoreBook[5081:666920] 36 МИН. НАЗАД - 15:52 ср 16.09
2015-09-16 16:28:42.293 ScoreBook[5081:666920] 37 МИН. НАЗАД - 15:51 ср 16.09
2015-09-16 16:28:42.294 ScoreBook[5081:666920] 38 МИН. НАЗА\320Д - 15:50 ср 16.09
2015-09-16 16:28:42.294 ScoreBook[5081:666920] 39 МИН. НАЗАД - 15:49 ср 16.09
2015-09-16 16:28:42.294 ScoreBook[5081:666920] 40 МИН. НАЗАД - 15:48 ср 16.09
2015-09-16 16:28:42.295 ScoreBook[5081:666920] 41 МИН. НАЗАД - 15:47 ср 16.09
当然输出应该是相同的。我不确定导致这种情况的原因。似乎打印过程中正在更改打印的字符串。我以为所有这些方法都是同步的。知道在哪里看?
实际应用似乎没有这个问题,它们只在测试中出现。
这是格式化代码。我现在知道它的优化程度非常差,并且有很多返回语句,这不是重点。
+ (NSString *)stringFormattedToXAgoFromDate:(NSDate *)date {
NSString *result = nil;
static NSCalendar *calendar = nil;
if (!calendar) {
calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
}
NSTimeInterval timeGap = [[NSDate date] timeIntervalSince1970] - [date timeIntervalSince1970];
if (timeGap < 0) {
NSLog(@"SCRB_ERROR: scrb_formatDateToXTimeAgoString: cannot format date. Date argument is later than current date.");
return nil;
}
NSDateComponents *components = [calendar components:NSCalendarUnitMinute | NSCalendarUnitHour | NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitSecond | NSCalendarUnitYear fromDate:date toDate:[NSDate date] options:0];
static NSDateFormatter *formatter = nil;
if (!formatter) {
formatter = [NSDateFormatter new];
NSLocale *_ruLocale = [NSLocale localeWithLocaleIdentifier:kRuLocaleIdentifier];
[formatter setLocale:_ruLocale];
}
if (timeGap < 60) {
result = @"ТОЛЬКО ЧТО";
return result;
}
if (timeGap < 60*60) {
result = [NSString stringWithFormat:@"%td МИН. НАЗАД", components.minute];
return result;
}
if (timeGap < 60*60 * 5) {
result = [NSString stringWithFormat:@"%td Ч. НАЗАД", components.hour];
return result;
}
if (timeGap < 60*60 * 24 * 2) {
if ([calendar isDateInToday:date]) {
[formatter setDateFormat:@"HH:mm"];
result = [formatter stringFromDate:date];
return result;
} else if ([calendar isDateInYesterday:date]) {
return @"ВЧЕРА";
}
}
if (timeGap < 60*60*24 * 7) {
[formatter setDateFormat:@"EEEE"];
result = [[formatter stringFromDate:date] uppercaseString];
return result;
}
if (components.year < 1) {
[formatter setDateFormat:@"dd MMM"];
result = [[formatter stringFromDate:date] uppercaseString];
return result;
}
if (components.year >= 0) {
[formatter setDateFormat:@"dd.MM.YYYY"];
result = [formatter stringFromDate:date];
return result;
}
return result;
}
更新2:在每次迭代结束时添加[NSThread sleepForTimeInterval:0.001];
似乎摆脱了问题。我仍然不知道为什么。
我还注意到\320
不时出现,它让我想到它可能与字符编码有关。将每个字符串更改为英文字符也只能解决问题。我也发现了this帖子,但是我不太明白它是否与我的问题有关。顺序跳过对我来说仍然是最大的谜团。
我一直在调查并添加了两行。这个在for-in循环之前的那个
NSMutableArray *array = [NSMutableArray new];
并且这个在循环中
[array addObject:formattedDateString];
和测试结束时的断点。数组中的字符串不会出现在日志中的任何错误。