【问题标题】:Is there a better way to find midnight tomorrow?有没有更好的方法来找到明天的午夜?
【发布时间】:2008-10-08 05:26:10
【问题描述】:

有没有更好的方法来做到这一点?

-(NSDate *)getMidnightTommorow {
    NSCalendarDate *now = [NSCalendarDate date];
    NSCalendarDate *tomorrow = [now dateByAddingYears:0 months:0 days:1 hours:0 minutes:0 seconds:0];
    return [NSCalendarDate dateWithYear:[tomorrow yearOfCommonEra]
                                  month:[tomorrow monthOfYear]
                                    day:[tomorrow dayOfMonth]
                                   hour:0
                                 minute:0
                                 second:0
                               timeZone:[tomorrow timeZone]];
}

请注意,我总是希望下一个午夜,即使我拨打电话时恰好是午夜,但是如果恰好是 23:59:59,我当然希望午夜即将到来。

自然语言函数看起来很不稳定,如果我在“day”字段中超过 32,我不确定 Cocoa 会做什么。 (如果可行,我可以放弃 [now dateByAddingYears:...] 调用)

【问题讨论】:

    标签: cocoa date performance


    【解决方案1】:

    来自documentation

    强烈使用 NSCalendarDate 灰心。它还没有被弃用, 但是它可能会出现在下一个主要操作系统中 Mac OS X v10.5 之后发布。为了 历法计算,你应该 使用合适的组合 NSCalendar、NSDate 和 NSDateComponents,如中所述 Dates and Times Programming Topics for Cocoa 中的日历。

    遵循该建议:

    NSDate *today = [NSDate date];
    
    NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    
    NSDateComponents *components = [[NSDateComponents alloc] init];
    components.day = 1;
    NSDate *tomorrow = [gregorian dateByAddingComponents:components toDate:today options:0];
    [components release];
    
    NSUInteger unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit;
    components = [gregorian components:unitFlags fromDate:tomorrow];
    components.hour = 0;
    components.minute = 0;
    
    NSDate *tomorrowMidnight = [gregorian dateFromComponents:components];
    
    [gregorian release];
    [components release];
    

    (我不确定这是否是最有效的实现,但它应该作为正确方向的指针。)

    注意:理论上,您可以通过允许值大于组件正常值范围的日期组件对象来减少此处的代码量(例如,只需将 1 添加到日期组​​件,这可能会导致其具有值 32)。然而,尽管dateFromComponents:可能容忍越界值,但不能保证。强烈建议您不要依赖它。

    【讨论】:

    • 从那个指针开始,看起来我可以删掉大部分内容,因为 dateFromComponents 确实似乎可以容忍月底之后的几天。
    • dateFromComponents 可以容忍越界值,但不能保证。强烈建议您不要依赖它。
    • 我在东海岸,今天一整天,当我进行上述转换时,我得到凌晨 1 点(我的时间间隔是 -5 小时,但似乎 NSCalendar 确信它是 -4小时。(即使我明确设置了时区)
    • 你不重复发布components吗?
    【解决方案2】:

    不,这将与您今天找到午夜的方式相同。

    【讨论】:

    • 恐怕这里的人们的讽刺/幽默检测器非常有缺陷。如果你不这样标记你有趣的 cmets,你会被否决。 BTDT。
    • 我不会拒绝你的答案,但即使假设它很有趣,开什么玩笑?忽略问题细节的轻率简短回答?对于 SO 上的每一个技术问题,您都可以使用您的“笑话”。这就是为什么它不好笑。
    • 这并不是说公式和今天一样加一。这是故意误解问题的句子结构,好像我相信 Dre 是在问,如果他等一天,是否会出现一个目前没有的更好的公式。 “有没有更好的方法来找到明天的午夜?”看?对此你可以很正确地回答:“如果非要解释,那就不好笑了。”
    • 这很有趣,但您应该在有趣的评论下方给出更可靠的答案。
    【解决方案3】:
    NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
    
    NSDate *tomorrow = [NSDate dateWithTimeIntervalSinceNow:(24 * 60 * 60)];
    
    NSDateComponents *components = [gregorian components:(NSYearCalendarUnit |
                                                          NSMonthCalendarUnit |
                                                          NSDayCalendarUnit)
                                                fromDate:tomorrow];
    
    NSDate *midnight = [gregorian dateFromComponents:components];
    

    【讨论】:

    • 每当程序员将一天定义为 60 * 60 * 24 时,闰秒就会消失。不要这样做。
    【解决方案4】:
    [NSDate dateWithNaturalLanguageString:@"midnight tomorrow"];
    

    【讨论】:

    • 有趣的方法(我对此表示赞同),但请注意文档中的警告:“它可能会产生意想不到的结果,强烈建议不要使用它。”
    • 谢谢,我也在寻找更好的解决方案,因为 iPhone sdk 不喜欢我使用它,但它现在仍然可以工作:)
    【解决方案5】:

    将您当前的日期和时间转换为 Unix 日期(自 1970 年以来的秒数)或 DOS 风格(自 1980 年以来),然后加上 24 小时并将其转换回来。然后将小时、分钟和秒重置为零以到达午夜。

    【讨论】:

      【解决方案6】:

      你可以试试这个方法:

      NSCalendar *calendar = [NSCalendar currentCalendar];
      NSDateComponents *comps = [[NSDateComponents alloc] init];
      [comps setDay:1];
      NSDate *tomorrow = [calendar dateByAddingComponents:comps toDate:[NSDate date] options:0]; //it gives us tomorrow with current time
      NSDate *midnight = [calendar startOfDayForDate:tomorrow]; //here we get next midnight
      

      如果需要设置 NSTimer,也可以轻松检索秒间隔:

      double intervalToMidnight = midnight.timeIntervalSinceNow;
      

      【讨论】:

        猜你喜欢
        • 2011-10-14
        • 2020-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-23
        • 2016-08-08
        • 1970-01-01
        相关资源
        最近更新 更多