-->

NSString to NSDate

2019-01-01 07:06发布

问题:

I got a string that contains the current date by using this :

NSString *date = [[NSDate date] description];

At a different point I want to retrieve the date from this string and I used the following code:

[NSDateFormatter setDefaultFormatterBehavior:NSDateFormatterBehavior10_4];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
//[NSDateFormatter setDefaultFormatterBehavior:NSDateFormatterBehaviorDefault];
[dateFormatter setDateFormat:@\"YYYY-MM-DD HH:MM:SS ±HHMM\"];

NSDate *dateFromString = [[NSDate alloc] init];
dateFromString = [dateFormatter dateFromString:<NSString containing date>];

I am getting dateFromString as nil 0x0. What am I doing wrong?

回答1:

You can\'t invent format string syntax and expect it to work; you need to actually use a documented format. (Seriously, \"MM\" meaning \"month\", \"minute\" and \"GMT offset minutes\" all at the same time?)

As the documentation points out, the 10.4 formatters use Unicode format strings.

Try \"yyyy-MM-dd HH:mm:ss ZZZ\" instead.

Also, Objective-C source is ASCII. Don\'t put characters like ± in there and expect it to work in any context; instead, use strings files.



回答2:

Also, dateFromString: returns an autoreleased NSDate, so:

NSDate *dateFromString = [[NSDate alloc] init]; // <- non freed instance
dateFromString = [dateFormatter dateFromString:<NSString containing date>]; // <- new autoreleased instance
....
[dateFromString release]; // <- wrong

You may want to:

//NSDate *dateFromString = [[NSDate alloc] init];
NSDate *dateFromString = [dateFormatter dateFromString:<NSString containing date>];
....
//[dateFromString release]; // dateFromString is autoreleased

Hope this could save someone :)



回答3:

You might check out TouchTime.

https://github.com/jheising/TouchTime.

It\'s a direct port of the awesome strtotime function in PHP in 5.4 for Cocoa and iOS. It will take in pretty much any arbitrary format of date or time string and convert it to an NSDate.

Hope it works, and enjoy!



回答4:

Made an NSString extension for that.

// Simple as this.   
date = dateString.dateValue;

Thanks to NSDataDetector, it recognizes a whole lot of format.

// Tested in GMT+1 (Hungary).
@\"2014-01-16\" dateValue is <2014-01-16 11:00:00 +0000>
@\"2014.01.16\" dateValue is <2014-01-16 11:00:00 +0000>
@\"2014/01/16\" dateValue is <2014-01-16 11:00:00 +0000>
@\"2014 Jan 16\" dateValue is <2014-01-16 11:00:00 +0000>
@\"2014 Jan 16th\" dateValue is <2014-01-16 11:00:00 +0000>
@\"20140116\" dateValue is <2014-01-16 11:00:00 +0000>
@\"01-16-2014\" dateValue is <2014-01-16 11:00:00 +0000>
@\"01.16.2014\" dateValue is <2014-01-16 11:00:00 +0000>
@\"01/16/2014\" dateValue is <2014-01-16 11:00:00 +0000>
@\"16 January 2014\" dateValue is <2014-01-16 11:00:00 +0000>
@\"01-16-2014 17:05:05\" dateValue is <2014-01-16 16:05:05 +0000>
@\"01-16-2014 T 17:05:05 UTC\" dateValue is <2014-01-16 17:05:05 +0000>
@\"17:05, 1 January 2014 (UTC)\" dateValue is <2014-01-01 16:05:00 +0000>

Part of eppz!kit, grab the category NSString+EPPZKit.h from GitHub.


ORIGINAL ANSWER: Whether you\'re not sure (or just don\'t care) about the date format contained in the string, use NSDataDetector for parsing date.

//Role players.
NSString *dateString = @\"Wed, 03 Jul 2013 02:16:02 -0700\";
__block NSDate *detectedDate;

//Detect.
NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingAllTypes error:nil];
[detector enumerateMatchesInString:dateString
                           options:kNilOptions
                             range:NSMakeRange(0, [dateString length])
                        usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop)
{ detectedDate = result.date; }];


回答5:

As previously answered, that is what happens when you invent a new sytax.

Based on Apple NSDateFormatter Class Reference documentation

There are many attributes you can get and set on a style date formatter, ... You are encouraged, however, not to change individual settings. Instead you should accept the default settings established on initialization and specify the format using setDateStyle:, setTimeStyle:

This is specially important for the output, which is different for every locale. By default NSDateFormatter observes the current user’s locale settings. So the same NSDate could be 22.11.2011 18:33:19, or Nov 22, 2011 6:33:19 PM, or 2011-11-22 下午6:33:19 or even २२-११-२०११ ६:३३:१९ अपराह्, all for the same input and with the same code.

Consider for example this code

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

[dateFormatter setDateStyle:NSDateFormatterShortStyle];
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];

// ShortStyle used: 11/23/37 3:30pm
NSString *dateString = [dateFormatter stringFromDate:date];

Check Apple docs for the different styles of NSDateFormatterStyle or this excellent tutorial