Как я могу создать полный объект NSDate, который представляет следующий указанный день? - PullRequest
3 голосов
/ 11 августа 2010

Я, вероятно, недостаточно четко обозначил этот заголовок, но если пользователь указывает время 14:30, а сейчас это 14:00, тогда мне нужен объект NSDate, который представляет текущий день со временем 14:30.,Если пользователь указывает время 14:30 и в настоящее время 15:00, тогда мне нужен объект NSDate, который представляет завтра со временем 14:30.Похоже на то, как будет работать будильник.

Я уже написал этот код, но он смущает долго, и он кажется очень грязным, и я чувствую, что он должен быть более простым, но я новичок в разработке для iOS, и этоконкретный API.

Большое спасибо заранее за вашу помощь!

Ответы [ 4 ]

1 голос
/ 11 августа 2010

Я полагаю, что если вы добавите интервал времени, который испортит время перехода на летнее время.Добавление секунд за один день будет в итоге днем ​​позже, но на час раньше или позже.Я почти уверен, что сталкивался с этим раньше, но вы можете проверить это легко, я думаю.

Другим способом было бы использование 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, если вы его сохранили), но в основном предназначено, чтобы показать вам, как добавить 1 день к NSDate, используя NSDateComponents.

1 голос
/ 11 августа 2010

Предполагая, что пользователь использует 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

Примечание: поскольку NSCalendarUnit является типом битового поля для NSUInteger, я передаю NSUIntegerMax, чтобы получить все возможные календарные единицы. Таким образом, мне не нужно иметь массивное побитовое выражение ИЛИ.

1 голос
/ 11 августа 2010

У вас уже есть 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 );
0 голосов
/ 11 августа 2010

Если вы получаете userDate от пользователя и nowDate = [NSDate date], то

NSComparisonResult diff = [userDate compare: nowDate];

Если разница равна NSOrderedDescending, тогда userDate будет позже, чем nowDate, и вы установили будильник на сегодня. Если это NSOrderedAscending, то вы устанавливаете будильник на завтра. Вы можете проверить на NSOrderedSame, но это никогда не будет.

Вы бы не хотели определять, какой сегодня день, поэтому мне кажется, что нужно добавить NSTimeInterval разности плюс 24 * 60 * 60 (если будильник будет завтра) или просто разницу (если будильник сегодня) хватило бы.

Я не знаю, почему все пытаются делать будильники. Это не может быть сделано, насколько я могу судить.

...