Converting NSString to NSDate (and back again) Converting NSString to NSDate (and back again) objective-c objective-c

Converting NSString to NSDate (and back again)


Swift 4 and later

Updated: 2018

String to Date

var dateString = "02-03-2017"var dateFormatter = DateFormatter()// This is important - we set our input date format to match our input string// if the format doesn't match you'll get nil from your string, so be carefuldateFormatter.dateFormat = "dd-MM-yyyy"//`date(from:)` returns an optional so make sure you unwrap when using. var dateFromString: Date? = dateFormatter.date(from: dateString)

Date to String

var formatter = DateFormatter()formatter.dateFormat = "dd-MM-yyyy"guard let unwrappedDate = dateFromString else { return }//Using the dateFromString variable from before. let stringDate: String = formatter.string(from: dateFromString)

Swift 3

Updated: 20th July 2017

String to NSDate

var dateString = "02-03-2017"var dateFormatter = DateFormatter()// This is important - we set our input date format to match our input string// if the format doesn't match you'll get nil from your string, so be carefuldateFormatter.dateFormat = "dd-MM-yyyy"var dateFromString = dateFormatter.date(from: dateString)

NSDate to String

var formatter = DateFormatter()formatter.dateFormat = "dd-MM-yyyy"let stringDate: String = formatter.string(from: dateFromString)

Swift

Updated: 22nd October 2015

String to NSDate

var dateString = "01-02-2010"var dateFormatter = NSDateFormatter()// this is imporant - we set our input date format to match our input stringdateFormatter.dateFormat = "dd-MM-yyyy"// voila!var dateFromString = dateFormatter.dateFromString(dateString)

NSDate to String

var formatter = NSDateFormatter()formatter.dateFormat = "dd-MM-yyyy"let stringDate: String = formatter.stringFromDate(NSDate())println(stringDate)

Objective-C

NSString to NSDate

NSString *dateString = @"01-02-2010";NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];[dateFormatter setDateFormat:@"dd-MM-yyyy"];NSDate *dateFromString = [dateFormatter dateFromString:dateString];

NSDate convert to NSString:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];[dateFormatter setDateFormat:@"dd-MM-yyyy"];NSString *stringDate = [dateFormatter stringFromDate:[NSDate date]];NSLog(@"%@", stringDate);


UPDATE 2019 (Swift 4):

Made a Date extension for that. It uses NSDataDetector instead of NSDateFormatter.

// Just throw at it without any format.var date: Date? = Date.FromString("02-14-2019 17:05:05")

Pretty enjoyable, it even recognizes things like "Tomorrow at 5".

XCTAssertEqual(Date.FromString("2019-02-14"),                    Date.FromCalendar(2019, 2, 14))XCTAssertEqual(Date.FromString("2019.02.14"),                    Date.FromCalendar(2019, 2, 14))XCTAssertEqual(Date.FromString("2019/02/14"),                    Date.FromCalendar(2019, 2, 14))XCTAssertEqual(Date.FromString("2019 Feb 14"),                   Date.FromCalendar(2019, 2, 14))XCTAssertEqual(Date.FromString("2019 Feb 14th"),                 Date.FromCalendar(2019, 2, 14))XCTAssertEqual(Date.FromString("20190214"),                      Date.FromCalendar(2019, 2, 14))XCTAssertEqual(Date.FromString("02-14-2019"),                    Date.FromCalendar(2019, 2, 14))XCTAssertEqual(Date.FromString("02.14.2019 5:00 PM"),            Date.FromCalendar(2019, 2, 14, 17))XCTAssertEqual(Date.FromString("02/14/2019 17:00"),              Date.FromCalendar(2019, 2, 14, 17))XCTAssertEqual(Date.FromString("14 February 2019 at 5 hour"),    Date.FromCalendar(2019, 2, 14, 17))XCTAssertEqual(Date.FromString("02-14-2019 17:05:05"),           Date.FromCalendar(2019, 2, 14, 17, 05, 05))XCTAssertEqual(Date.FromString("17:05, 14 February 2019 (UTC)"), Date.FromCalendar(2019, 2, 14, 17, 05))XCTAssertEqual(Date.FromString("02-14-2019 17:05:05 GMT"),       Date.FromCalendar(2019, 2, 14, 17, 05, 05))XCTAssertEqual(Date.FromString("02-13-2019 Tomorrow"),           Date.FromCalendar(2019, 2, 14))XCTAssertEqual(Date.FromString("2019 Feb 14th Tomorrow at 5"),   Date.FromCalendar(2019, 2, 14, 17))

Goes like:

extension Date{    public static func FromString(_ dateString: String) -> Date?    {        // Date detector.        let detector = try! NSDataDetector(types: NSTextCheckingResult.CheckingType.date.rawValue)        // Enumerate matches.        var matchedDate: Date?        var matchedTimeZone: TimeZone?        detector.enumerateMatches(            in: dateString,            options: [],            range: NSRange(location: 0, length: dateString.utf16.count),            using:            {                (eachResult, _, _) in                // Lookup matches.                matchedDate = eachResult?.date                matchedTimeZone = eachResult?.timeZone                // Convert to GMT (!) if no timezone detected.                if matchedTimeZone == nil, let detectedDate = matchedDate                { matchedDate = Calendar.current.date(byAdding: .second, value: TimeZone.current.secondsFromGMT(), to: detectedDate)! }        })        // Result.        return matchedDate    }}

UPDATE 2014:

Made an NSString extension for that.

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

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

'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 2013:

Whether you're not sure (or 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; }];


When using fixed-format dates you need to set the date formatter locale to "en_US_POSIX".

Taken from the Data Formatting Guide

If you're working with fixed-format dates, you should first set the locale of the date formatter to something appropriate for your fixed format. In most cases the best locale to choose is en_US_POSIX, a locale that's specifically designed to yield US English results regardless of both user and system preferences. en_US_POSIX is also invariant in time (if the US, at some point in the future, changes the way it formats dates, en_US will change to reflect the new behavior, but en_US_POSIX will not), and between platforms (en_US_POSIX works the same on iPhone OS as it does on OS X, and as it does on other platforms).

Swift 3 or later

extension Formatter {    static let customDate: DateFormatter = {        let formatter = DateFormatter()        formatter.locale = Locale(identifier: "en_US_POSIX")        formatter.dateFormat = "dd/MM/yy"        return formatter    }()    static let time: DateFormatter = {        let formatter = DateFormatter()        formatter.locale = Locale(identifier: "en_US_POSIX")        formatter.dateFormat = "HH:mm"        return formatter    }()    static let weekdayName: DateFormatter = {        let formatter = DateFormatter()        formatter.dateFormat = "cccc"        return formatter    }()    static let month: DateFormatter = {        let formatter = DateFormatter()        formatter.dateFormat = "LLLL"        return formatter    }()}

extension Date {    var customDate: String {        return Formatter.customDate.string(from: self)    }    var customTime: String {        return Formatter.time.string(from: self)    }    var weekdayName: String {        return Formatter.weekdayName.string(from: self)    }    var monthName: String {        return Formatter.month.string(from: self)    }}extension String {    var customDate: Date? {        return Formatter.customDate.date(from: self)    }}

usage:

// this will be displayed like this regardless of the user and system preferencesDate().customTime          //  "16:50"Date().customDate          //  "06/05/17"// this will be displayed according to user and system preferencesDate().weekdayName         //  "Saturday"Date().monthName           //  "May"

Parsing the custom date and converting the date back to the same string format:

let dateString = "01/02/10"if let date = dateString.customDate {    print(date.customDate)   // "01/02/10\n"    print(date.monthName)    // customDate}

Here it is all elements you can use to customize it as necessary:

enter image description here