NSNumber from NSDate

Thromordyn picture Thromordyn · Apr 14, 2011 · Viewed 10.5k times · Source

I'm attempting to get around a date validation that refuses to take anything earlier than tomorrow.
So far I have this:

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)

That's great, but dateY is not an NSNumber. I need an NSNumber for the comparison, but I can't find anything that works. (I don't even know how an NSNumber can be 2011-04-14 13:22:29 +0000, anyway...)

I can use NSDateFormatter to convert an NSDate into an NSString, so if it would be possible to take that string and convert it to the required NSNumber (as opposed to directly converting the NSDate to an NSNumber, which I can't seem to find help with either), that would be fine.


- (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;
    }
}

Right now, the user is not allowed to choose a date before tomorrow. errorStr lies. Before today makes more sense than before tomorrow as a rule for refusing to save the date, so I've been fighting with this thing to let me use yesterday in place of today, rather than looking any deeper.

Edit: Using NSOrderedSame allows any date to be selected without an error. That won't do.

Answer

odrm picture odrm · Apr 14, 2011

You can convert an NSDate to an NSNumber like this:

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

and convert back like:

aDate = [NSDate dateWithTimeIntervalSinceReferenceDate:[NSNumber doubleValue]];