如何创建表示下一个指定日期的完整NSDate对象?

时间:2010-08-11 04:22:25

标签: iphone ipad nsdate ios

我可能没有清楚地说明这个标题,但如果用户指定的时间是下午2:30,而且当前是下午2:00,那么我需要一个NSDate对象代表当天的时间,下午2:30 。如果用户指定的时间是下午2:30并且当前是下午3:00,那么我需要一个NSDate对象,该对象明天表示时间为下午2:30。与闹钟的工作方式类似。

我已经编写了这段代码,但它很尴尬很长,感觉真的很笨,我觉得它应该更简单,但我是iOS开发和这个特定API的新手。

非常感谢您的帮助!

4 个答案:

答案 0 :(得分:1)

您是否已经有一个NSDate代表用户选择的日期/时间?如果是这样,将它与现在(通过earlierDate:laterDate:)进行比较是非常简单的事情,并在一天后创建一个新的(通过dateWithTimeInterval:sinceDate:initWithTimeInterval:sinceDate:

这样的事情:

// Assume dateTarget is an NSDate representing the date/time the user picked.
// Is it earlier than now?
if( [dateTarget earlierDate:[NSDate date]] == dateTarget ) {
    // dateTarget is earlier than now.
    // Add 1 day to it.
    NSDate* newDate = [[NSDate alloc]initWithTimeInterval:60*60*24 sinceDate:dateTarget];
    [dateTarget release];
    dateTarget = newDate;
}

// dateTarget is now either the original time, or if that time passed, the same time tomorrow.
NSLog( @"dateTarget = %@", dateTarget );

答案 1 :(得分:1)

如果你添加一个在夏令时期间混乱的时间间隔,我相信。一天之后添加秒数将在一天之后但一小时之前或之后结束。我很确定我之前碰到过这个问题,但我猜你可以轻松测试一下。

另一种方法是使用NSDateComponents:

// using while will be inefficient when the targetDate is more than a few days in the past
while ([targetDate compare:[NSDate date]] == NSOrderedAscending) {
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSInteger units = NSYearCalendarUnit |
                      NSMonthCalendarUnit |
                      NSDayCalendarUnit |
                      NSHourCalendarUnit |
                      NSMinuteCalendarUnit |
                      NSSecondCalendarUnit;
    NSDateComponents *comps = [calendar components:units fromDate:targetDate];
    [comps setDay:[comps day] + 1]; // if day is 32 for instance, it'll automatically roll over to the next month
    NSDate *targetDate = [calendar dateFromComponents:comps];
}

上述内容绝不是一个理想的解决方案(例如,如果您保留它,它会泄漏targetDate),但主要是为了向您展示如何使用NSDateComponents向NSDate添加1天。

答案 2 :(得分:1)

假设用户正在使用UIDatePicker来选择日期,这就是我要做的事情:

NSDate * selectedDate = ...; //2:30pm
NSDate * selectedComponents = [[NSCalendar currentCalendar] components:(NSHourCalendarUnit | NSMinuteCalendarUnit) fromDate:selectedDate];

NSDate * now = [NSDate date];
NSDate * nowComponents = [[NSCalendar currentCalendar] components:NSUIntegerMax fromDate:now];

[nowComponents setHour:[selectedComponents hour]];
[nowComponents setMinute:[selectedComponents minute]];

NSDate * targetDate = [[NSCalendar currentCalendar] dateFromComponents:nowComponents];
if ([[now laterDate:targetDate] isEqual:now]) {
  //in a comparison between now and the target date, the target date has already passed
  [nowComponents setDay:[nowComponents day]+1];
  targetDate = [[NSCalendar currentCalendar] dateFromComponents:nowComponents];
}

//target date is now at the appropriate 2:30pm

旁注:由于NSCalendarUnitNSUInteger的位域类型,我传入NSUIntegerMax以检索所有可能的日历单位。这样我就不必有大量的按位OR语句。

答案 3 :(得分:0)

如果您从用户那里获得userDate,并nowDate = [NSDate date],那么

NSComparisonResult diff = [userDate compare: nowDate];

如果diff为NSOrderedDescending,则userDate晚于nowDate,并为今天设置闹钟。如果是NSOrderedAscending,则为明天设置闹钟。您可以测试NSOrderedSame,但它永远不会。

你想避免确定它是哪一天,所以在我看来,添加NSTimeInterval的差异加上24 * 60 * 60(如果是明天的警报)或只是区别(如果今天发出警报)就足够了。

我不知道为什么每个人都想制作闹钟。我无法理解,这是无法做到的。