7

How do I parse "2010-04-30T00:45:48.711127" into an NSDate? (and maintain all precision)

bradley.ayers
  • 37,165
  • 14
  • 93
  • 99
  • 1
    possible duplicate of [Parsing unsupported date formats in via Cocoa’s NSDate](http://stackoverflow.com/questions/399527/parsing-unsupported-date-formats-in-via-cocoas-nsdate) – Nicholas Riley May 09 '10 at 02:35
  • 1
    hint FWIW: your question is ambiguous-- it's not 100% clear whether you're asking a "beginner" question about Cocoa ("how do I parse dates in a given format") or an advanced one. In your case based on your comments on answers, you were asking the advanced version. That being so, you might get less noise in the answers if you include a note saying e.g. "I know that NSDateFormatter can be used for this format, but it runs out of precision three places too early.". – Ben Zotto May 09 '10 at 16:41

3 Answers3

4

You have your work cut out for you.

NSDate will throw out any values past 3 decimal places for seconds. You can create a subclass of NSDate to hold on to that precision but you'll also need to implement your own parsing and custom formatters to input and display it since NSDateFormatter and CFDateFormatter, which it is built on, will also truncate precision after 3 decimal places. Depending on what you're doing though that shouldn't be all that hard.

This is a simple subclass (not implementing NSCoding or NSCopying) that will hold on to all the precision you give it.

@interface RMPreciseDate : NSDate {
    double secondsFromAbsoluteTime;
}

@end

@implementation RMPreciseDate

- (NSTimeInterval)timeIntervalSinceReferenceDate {
    return secondsFromAbsoluteTime;
}

- (id)initWithTimeIntervalSinceReferenceDate:(NSTimeInterval)secsToBeAdded {
    if (!(self = [super init]))
        return nil;

    secondsFromAbsoluteTime = secsToBeAdded;

    return self;
}

@end

You can then ask for the -timeIntervalSince1970 to get UNIX epoch time.

There is an ISO8601 date/time parser class already out there, but since it's using NSDateComponents to generate its date it's limited to full-second precision currently, but you could use it as a starting point perhaps to create more precise representations.

Ashley Clark
  • 8,813
  • 3
  • 35
  • 35
0

I'm going to try this ISO 8601 parser and unparser for a similar situation: http://boredzo.org/iso8601parser/

Peter DeWeese
  • 18,141
  • 8
  • 79
  • 101
-1

It seems the NSDate only has millisecond precision.

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd'T'hh:mm:ss.SSSSSS"];

    NSDate *date = [dateFormatter dateFromString:@"2010-04-30T00:45:48.711127"];

    NSLog(@"%@", date);

    NSString *string = [dateFormatter stringFromDate:date];

    NSLog(@"%@", string);

    [pool drain];
    return 0;
}

That code yields the following console output:

Program loaded.
run
[Switching to process 27202]
Running…
2010-05-08 20:02:46.342 TestNSDate[27202:a0f] 2010-04-30 00:45:48 -0700
2010-05-08 20:02:46.344 TestNSDate[27202:a0f] 2010-04-30T12:45:48.711000

Debugger stopped.
Program exited with status value:0.

So "2010-04-30T00:45:48.711127" turning into "2010-04-30T00:45:48.711000" is probably not what you have in mind.

WineSoaked
  • 1,455
  • 1
  • 14
  • 14
  • It seems we are both stuck at the same point. I think the problem is with NSDateFormatter though, since in many places it is documented that NSDate supports microsecond precision. – bradley.ayers May 09 '10 at 04:16
  • There's NSTimeInterval that possesses that ability. Perhaps a composite pattern is in order... – WineSoaked May 10 '10 at 14:29
  • Perhaps I should be more specific: How important is it that you're storing these sub-millisecond resolution timestamps (for want of a better description) in NSDate itself? Couldn't a subclass that handles the microsecond resolution make up the difference for maintaining the additional precision you're needing? – WineSoaked May 10 '10 at 16:53
  • 1
    Your code has a small bug. You should change the format to yyyy-MM-dd'T'HH:mm:ss.SSSSSS (note the HH instead of hh) as the time in iso fromat uses uses 24h clock instead of 12h. – Piotr Czapla Aug 27 '10 at 22:36