主页 iOS中NSDate是否是今天Today
Post
Cancel

iOS中NSDate是否是今天Today

前言

本文具有强烈的个人感情色彩,如有观看不适,请尽快关闭. 本文仅作为个人学习记录使用,也欢迎在许可协议范围内转载或分享,请尊重版权并且保留原文链接,谢谢您的理解合作. 如果您觉得本站对您能有帮助,您可以使用RSS方式订阅本站,感谢支持!.

背景

每天的iOS开发过程中经常会出现Check一些逻辑是否每天仅发生一次,一般我们的通用是用NSDate判断是否是今天,然后对NSDate做持久化存储 eg: MMKV、或者NSUserDefault,但随着工程的日渐庞大,我们逐渐关注一些细节和代码 的耗时.

首先来看一下几种不同的逻辑判断NSDateisToday的代码实现

  • 1.系统NSCalendar日历
1
2
NSDate *date = [NSDate date]; //这里取当前日期,正常应该做为参数传入NSDate
BOOL inToday = [[NSCalendar currentCalendar] isDateInToday:date]
  • 2.增加更多参数调用NSCalendar
1
2
3
4
5
6
7
8
- (BOOL)isToday {
    NSCalendar *cal = [NSCalendar currentCalendar];
    NSDateComponents *components = [cal components:(NSCalendarUnitEra|NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay) fromDate:[NSDate date]];
    NSDate *today = [cal dateFromComponents:components];
    components = [cal components:(NSCalendarUnitEra|NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay) fromDate:self];
    NSDate *otherDate = [cal dateFromComponents:components];
    return [today isEqualToDate:otherDate];
}
  • 3.通过比较时间
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- (BOOL)isTodayWithDate:(NSDate *)date {
    NSDate *selfBegin = [self dateByBeginDay];
    NSDate *dateBegin = [date dateByBeginDay];
    if (fabs([selfBegin timeIntervalSinceDate:dateBegin]) < 1.0e-6) {
        return YES;
    }
    return NO;
}

- (NSDate *)dateByBeginDay {
    //前一天的结束  16:00为结束  8小时时区  今天开始 也就是说 前一天的00:00:00
    unsigned int flags      = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
    NSDateComponents *parts = [[NSCalendar currentCalendar] components:flags fromDate:self];
    [parts setHour:0];
    [parts setMinute:0];
    [parts setSecond:0];
    return [[NSCalendar currentCalendar] dateFromComponents:parts];
}

这几种都是检测是否是当天的代码

故事的开始

今天工作中Review代码 对NSDate的检查判断是否是today的耗时问题产生了分歧,工程师解决问题的方式很简单,实践代码证明是否耗时.

我选中了 第一种和第三种做测试.代码如下:

1
2
2023-02-13 19:59:08.855078+0800 NSDateSpeedDemo[1837:197213] NSCalendar耗时:0.011064
2023-02-13 19:59:11.108141+0800 NSDateSpeedDemo[1837:197213] NSDate (YZUtils)耗时:0.030793

完整的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
- (IBAction)didSysDateClick:(id)sender {
    NSDate *date = [NSDate date];
    CFTimeInterval startTime = CACurrentMediaTime();
    for (int i = 0; i < 1000; i++) {
        __unused BOOL inToday = [[NSCalendar currentCalendar] isDateInToday:date];
    }
    CFTimeInterval endTime = CACurrentMediaTime();
    NSString *log = [NSString stringWithFormat:@"NSCalendar耗时:%f",endTime - startTime];
    NSLog(@"%@", log);
    self.l1.text = log;
    
}

- (IBAction)didOnCusDateClick:(id)sender {
    NSDate *date = [NSDate date];
    CFTimeInterval startTime = CACurrentMediaTime();
    for (int i = 0; i < 1000; i++) {
        __unused BOOL inToday = [date isTodayWithDate:date];
        self.l2.text = [NSString stringWithFormat:@"SysDate:%d",i];
    }
    CFTimeInterval endTime = CACurrentMediaTime();
    NSString *log = [NSString stringWithFormat:@"NSDate (YZUtils)耗时:%f",endTime - startTime];
    NSLog(@"%@", log);
    self.l2.text = log;
}

总结

这时间上还是差至少1x左右,如果频繁的操作确实会影响一些性能.

demo

该博客文章由作者通过 CC BY 4.0 进行授权。

博客的图片资源优化

objc中的类型安全转换