Converting NSString to NSDate (and back again)

后端 未结 17 2493
-上瘾入骨i
-上瘾入骨i 2020-11-21 23:26

How would I convert an NSString like \"01/02/10\" (meaning 1st February 2010) into an NSDate? And how could I turn the NSDat

相关标签:
17条回答
  • 2020-11-22 00:04

    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; }];
    
    0 讨论(0)
  • 2020-11-22 00:06

    String To Date

    var dateFormatter = DateFormatter()
    dateFormatter.format = "dd/MM/yyyy"
    
    var dateFromString: Date? = dateFormatter.date(from: dateString) //pass string here
    

    Date To String

     var dateFormatter = DateFormatter()
     dateFormatter.dateFormat = "dd-MM-yyyy"
     let newDate = dateFormatter.string(from: date) //pass Date here
    
    0 讨论(0)
  • 2020-11-22 00:10

    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 preferences
    Date().customTime          //  "16:50"
    Date().customDate          //  "06/05/17"
    // this will be displayed according to user and system preferences
    Date().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

    0 讨论(0)
  • 2020-11-22 00:11

    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 careful
    dateFormatter.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 careful
    dateFormatter.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 string
    dateFormatter.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);
    
    0 讨论(0)
  • 2020-11-22 00:11

    Use this method to convert from NSString to NSdate:

    -(NSDate *)getDateFromString:(NSString *)pstrDate
    {
        NSDateFormatter* myFormatter = [[NSDateFormatter alloc] init];
        [myFormatter setDateFormat:@"dd/MM/yyyy"];
        NSDate* myDate = [myFormatter dateFromString:pstrDate];
        return myDate;
    }
    
    0 讨论(0)
  • 2020-11-22 00:11

    Date to NSString

    NSString *dateString = [NSString stringWithFormat:@"%@",[NSDate date]];
    NSLog(@"string: %@",dateString ); //2015-03-24 12:28:49 +0000
    

    NSString to NSDate

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"];
    NSDate *date = [formatter dateFromString:dateString];
    NSLog(@"date: %@", date); //015-03-24 12:28:49 +0000
    
    0 讨论(0)
提交回复
热议问题