NSDate 时间比较中的时区问题.

判断两个时间是不是同一天,是没法用时间戳对比的,两个时间戳间隔在24小时以内不能表明是同一天。ios

用时间戳对比,也是要计算是否同一年,同一月,同一日,才能判断出是否同一天。macos

因此一般对比两个时间是用 NSDate 来对比,可是要注意:NSDate 的时间实际上有某个时区的时间的含义,经过 [NSDate date] 建立出来的时间默认是零时区时间,可是这并不意味着两个 NSDate 比较(判断是否同一天)就必定会有正确的结果。网络

NSDate 比较是不是同一天,本质是比较 NSDateComponents 的 day month year 是否都相等。spa

好比:code

- (BOOL)isSameDayWithDate:(NSDate *)date
{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    unsigned unitFlag = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
    NSDateComponents *comp1 = [calendar components:unitFlag fromDate:self];
    NSDateComponents *comp2 = [calendar components:unitFlag fromDate:date];
    return (([comp1 day] == [comp2 day]) && ([comp1 month] == [comp2 month]) && ([comp1 year] == [comp2 year]));
}
复制代码

网络上不少文章都介绍对 NSDate 或者 NSCalendar 作了扩展,来判断某个日期是不是今天、昨天、明天。实际上 NSCalendar 在 ios(8.0) 开始提供了几个官方方法。component

- (BOOL)isDateInToday:(NSDate *)date;

- (BOOL)isDateInYesterday:(NSDate *)date;

- (BOOL)isDateInTomorrow:(NSDate *)date;
复制代码

可是考虑到用户是能够修改手机时间的,一般咱们会使用 ntp 时间做为标准时间,而不直接使用手机时间。it

NSCalendar 也有提供了一个方法能够直接对比两个时间。io

/*
	This API compares the Days of the given dates, reporting them equal if they are in the same Day.
*/
- (BOOL)isDate:(NSDate *)date1 inSameDayAsDate:(NSDate *)date2 API_AVAILABLE(macos(10.9), ios(8.0), watchos(2.0), tvos(9.0));
复制代码

可是,在实际场景中,比较两个 NSDate 是不是同一天的时候,一般须要两个 NSDate 同时处于当地时区才有意义。class

一样的两个时间,在一个时区是同一天,在另外一个时区极可能不是同一天!!!扩展

若是你在东八区,用两个零时区的时间来对比,是会出很大的问题的。

举个例子:

today 1553741981 零时区 2019-03-28 02:59:41 +0000 (东八区 2019-03-28 10:59:41)
day   1553788800 零时区 2019-03-28 15:59:59 +0000 (东八区 2019-03-29 00:00:00)
复制代码
相关文章
相关标签/搜索