12

有一个更好的方法吗?

-(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:...] 电话)

4

6 回答 6

25

文档中:

强烈建议不要使用 NSCalendarDate。它还没有被弃用,但它可能会在 Mac OS X v10.5 之后的下一个主要操作系统版本中出现。对于日历计算,您应该使用 NSCalendar、NSDate 和 NSDateComponents 的合适组合,如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: 可以容忍超出范围的值,但不能保证。强烈建议您不要依赖它。

于 2008-10-08T05:56:35.640 回答
7

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

于 2008-10-08T06:06:31.970 回答
4
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];
于 2009-08-06T07:25:55.660 回答
1
[NSDate dateWithNaturalLanguageString:@"midnight tomorrow"];
于 2009-05-13T20:55:38.647 回答
0

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

于 2008-10-08T06:01:24.400 回答
0

你可以这样尝试:

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;
于 2016-02-21T11:16:26.773 回答