NSNumber от NSDate - PullRequest
       9

NSNumber от NSDate

12 голосов
/ 14 апреля 2011

Я пытаюсь обойти проверку даты, которая отказывается принимать что-либо раньше, чем завтра.
Пока у меня есть это:

NSDate *dateY = [NSDate dateWithTimeIntervalSinceNow:-86400];
                // Negative one day, in seconds (-60*60*24)
NSLog(@"%@", [NSDate date]);
    // "yyyy-MM-dd HH:mm:ss Z", accurate assuming Z = +0000
NSLog(@"%@", dateY);
    // "yyyy-MM-dd HH:mm:ss Z", same accuracy (minus one day)

Это прекрасно, но dateY неNSNumber.Мне нужно NSNumber для сравнения, но я не могу найти ничего, что работает.(Я даже не знаю, как NSNumber может быть 2011-04-14 13:22:29 +0000, во всяком случае ...)

Я могу использовать NSDateFormatter для преобразования NSDate в NSString, так что если этобыло бы возможно взять эту строку и преобразовать ее в требуемый NSNumber (в отличие от прямого преобразования NSDate в NSNumber, что я не могу найти помощь с любой из них), это было бы хорошо.


- (BOOL)validateDueDate:(id *)ioValue error:(NSError **)outError {
    NSDate *dateY = [NSDate dateWithTimeIntervalSinceNow:-86400];
    NSNumber *tis1970 = [NSNumber numberWithDouble:[dateY timeIntervalSince1970]];
    NSLog(@"NSNumber From Date : %@", tis1970);
    NSLog(@"Date From NSNumber : %@", [NSDate dateWithTimeIntervalSince1970:[tis1970 doubleValue]]);

    // Due dates in the past are not valid
    // Enforced that a due date has to be >= today's date
    if ([*ioValue compare:[NSDate date]] == NSOrderedAscending) {
        if (outError != NULL) {
            NSString *errorStr = [[[NSString alloc] initWithString:@"Due date must be today or later."] autorelease];
            NSDictionary *userInfoDictionary = [NSDictionary dictionaryWithObject:errorStr forKey:@"ErrorString"];
            NSError *error = [[[NSError alloc]
                                initWithDomain:TASKS_ERROR_DOMAIN
                                code:DUEDATE_VALIDATION_ERROR_CODE
                                userInfo:userInfoDictionary] autorelease];
            *outError = error;
            }
        return NO;
    } else {
        return YES;
    }
}

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

Править: Использование NSOrderedSame позволяет выбрать любую дату без ошибок.Это не сработает.

Ответы [ 3 ]

26 голосов
/ 14 апреля 2011

Вы можете преобразовать NSDate в NSNumber следующим образом:

NSDate *aDate = [NSDate date];
NSNumber *secondsSinceRefDate = [NSNumber numberWithDouble:[aDate timeIntervalSinceReferenceDate]];

и конвертировать обратно как:

aDate = [NSDate dateWithTimeIntervalSinceReferenceDate:[NSNumber doubleValue]];
1 голос
/ 14 апреля 2011

Никогда не следует использовать 86400 для расчета разницы дат, поскольку не во всех днях по 86 400 секунд.Вместо этого используйте NSDateComponents:

- (BOOL)validateDueDate:(NSDate *)dueDate error:(NSError *)error {
  NSDate *today = [NSDate date];
  NSCalendar *calendar = [NSCalendar currentCalendar];
  NSDateComponents *components = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:today];
  //adjust the components to tomorrow at the first instant of the day
  [components setDay:[components day] + 1];
  [components setHour:0];
  [components setMinute:0];
  [components setSecond:0];
  NSDate *tomorrow = [calendar dateFromComponents:components];

  NSDate *earlierDate = [dueDate earlierDate:tomorrow];
  if ([earlierDate isEqualToDate:dueDate]) {
    //the dueDate is before tomorrow
    if (error != nil) {
      NSString *errorStr = [[[NSString alloc] initWithString:@"Due date must be today or later."] autorelease];
      NSDictionary *userInfoDictionary = [NSDictionary dictionaryWithObject:errorStr forKey:NSLocalizedDescriptionKey];
      *error = [[[NSError alloc] initWithDomain:TASKS_ERROR_DOMAIN code:DUEDATE_VALIDATION_ERROR_CODE userInfo:userInfoDictionary] autorelease];
    }
    return NO;
  }
  return YES;
}

ПРЕДУПРЕЖДЕНИЕ: код, введенный в браузере. Caveat Implementor

1 голос
/ 14 апреля 2011

Все, что нужно для получения NSNumber, это

NSDate *dateY = [NSDate dateWithTimeIntervalSinceNow:-86400];
NSNumber *tis1970 = [NSNumber numberWithDouble:[dateY timeIntervalSince1970]];
NSLog(@"NSNumber From Date : %@", tis1970);
NSLog(@"Date From NSNumber : %@", [NSDate dateWithTimeIntervalSince1970:[tis1970 doubleValue]]);
...