Konvertieren von NSString in NSDate (und wieder zurück)


229

Wie würde ich ein NSString" 01/02/10 " (dh 1. Februar 2010) in ein " konvertieren " NSDate? Und wie könnte ich den NSDateRücken in eine Schnur verwandeln ?


benutze 2010. und schau dir dann meinen Beitrag an. Ich habe für beide Prozesse eine Konvertierung bereitgestellt.
Pavan

Antworten:


450

Swift 4 und höher

Aktualisiert: 2018

Zeichenfolge bis Datum

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)

Datum zu 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

Aktualisiert: 20. Juli 2017

Zeichenfolge zu 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)

Schnell

Aktualisiert: 22. Oktober 2015

Zeichenfolge zu 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)

Ziel c

NSString zu NSDate

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

NSDate in NSString konvertieren:

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

sollte das zwei ys im setDateFormat sein?
Cannyboy

Ich bin mir nicht sicher, ob 2 Jahre Arbeit sind. Als Faustregel gilt jedoch, welches Format Sie keeo für das setDateFormat das gleiche Format geben werden. Also erstmal 2010 und schreibe 4 Jahre wie 'JJJJ'. Ich bin mir sicher, dass das definitiv funktionieren wird
Pavan

1
Es lohnt sich, diesen Beitrag zu lesen.
iOmi

7
Was ist der Grund, NSDate *dateFromString = [[NSDate alloc] init];wenn dem Zeiger in der nächsten Zeile ein neuer Wert zugewiesen wird?
Valeriy Van

4
Ein weiterer Punkt, auf den Sie achten sollten - Wenn Ihr Wert für Zeichenfolge (Datum) als 29.05.2013 aufgeführt ist, muss Ihr Aufruf von setDateFormat mit demselben übereinstimmen - dh [dateFormatter setDateFormat: @ "MM / tt / jjjj"] - Der Ich habe immer wieder versucht, Bindestriche zu verwenden, wenn ihre Zeichenfolgendaten Schrägstriche hatten. - Großartige Antwort Pavan.
Noobzilla

54

UPDATE 2019 (Swift 4):

Machte eine Date Erweiterung gemacht. Es verwendet NSDataDetectoranstelle von NSDateFormatter.

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

Ziemlich angenehm, es erkennt sogar Dinge wie "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))

Geht wie:

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:

Machte ein Habe dafür NSString-Erweiterung gemacht.

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

Dank an NSDataDetector erkennt es eine ganze Menge 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>

Teil von Holen Sie sich als eppz! Kits die Kategorie NSString + EPPZKit.h von GitHub.


URSPRÜNGLICHE ANTWORT 2013:

Verwenden Sie NSDataDetector zum Parsen des Datums , unabhängig davon, ob Sie sich über das in der Zeichenfolge enthaltene Datumsformat nicht sicher sind (oder sich nicht darum kümmern) .

//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; }];

Das 24-Stunden-Format scheint nicht unterstützt zu werden. ZB NSString-> 2013-09-11 01:31:22 +0000konvertiert zu NSDate->2013-09-11 13:31:22 +0000
Sooper

Diese Antwort gefällt mir am besten, da die ursprüngliche Datumszeichenfolge sehr willkürlich sein kann. Dies ist ideal in Fällen, in denen der Benutzer das Datum nicht über eine Auswahl, sondern in ein Textfeld eingibt.
Kyle

2
Wie würde diese Methode entscheiden, ob das Datum in TT / MM / JJJJ oder MM / TT / JJJJ angegeben ist? Wenn die Eingabe beispielsweise 01/03/2014 lautet, wie würde das Ergebnis aussehen?
Ahmad

@ahmad Ich stimme voll und ganz zu - dieser Ansatz wird wahrscheinlich nicht funktionieren, wenn Sie verschiedene Spracheinstellungen unterstützen müssen.
Frank Schmitt

@ Sooper XCTAssertEqual(Date.FromString("2013-09-11 01:31:22 +0000"), Date.FromCalendar(2013, 9, 11, 1, 31, 22))scheint in Ordnung.
Geri Borbás

33

Wenn Sie Datumsangaben mit festem Format verwenden, müssen Sie das Gebietsschema für den Datumsformatierer auf festlegen "en_US_POSIX".

Entnommen aus dem Datenformatierungshandbuch

Wenn Sie mit Datumsangaben mit festem Format arbeiten, sollten Sie zuerst das Gebietsschema des Datumsformatierers auf einen Wert festlegen, der für Ihr festes Format geeignet ist. In den meisten Fällen ist en_US_POSIX das beste Gebietsschema zur Auswahl. Dieses Gebietsschema wurde speziell entwickelt, um unabhängig von Benutzer- und Systemeinstellungen Ergebnisse in US-Englisch zu erzielen . en_US_POSIX ist auch zeitlich unveränderlich (wenn die USA zu einem späteren Zeitpunkt die Formatierung von Datumsangaben ändern, ändert sich en_US, um das neue Verhalten widerzuspiegeln, en_US_POSIX jedoch nicht) und zwischen Plattformen (en_US_POSIX funktioniert auf dem iPhone genauso Betriebssystem wie unter OS X und wie auf anderen Plattformen).

Swift 3 oder höher

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)
    }
}

Verwendung:

// 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"

Analysieren des benutzerdefinierten Datums und Zurückkonvertieren des Datums in dasselbe Zeichenfolgenformat:

let dateString = "01/02/10"

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

Hier finden Sie alle Elemente, mit denen Sie es nach Bedarf anpassen können:

Geben Sie hier die Bildbeschreibung ein


Was ist, wenn mehrere Threads auf diese Methoden zugreifen? Könnte dies nicht zu Fehlern führen, wenn das Datumsformat des Formatierers neu zugewiesen wird? Ist die Verwendung von Variablen (Datum / Uhrzeit / Wochentag) nur eine Ihrer Präferenzen oder ist dies möglicherweise ein Vorteil, wenn Sie dies so tun, oder ist es eine bewährte Methode?
Lahmar

19

Warum nicht eine Kategorie zu NSString hinzufügen?

// NSString+Date.h
@interface NSString (Date)
+ (NSDate*)stringDateFromString:(NSString*)string;
+ (NSString*)stringDateFromDate:(NSDate*)date;
@end


// NSString+Date.m
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:@"EEE, dd MMM yyyy HH:mm:ss ZZZ"];

NSDate *date = [dateFormatter dateFromString:stringDate ];
[dateFormatter release];
+ (NSDateFormatter*)stringDateFormatter
{
    static NSDateFormatter* formatter = nil;
    if (formatter == nil)
    {
        formatter = [[NSDateFormatter alloc] init];
        [formatter setDateFormat:@"EEE, dd MMM yyyy HH:mm:ss ZZZ"];
    }   
    return formatter;
}

+ (NSDate*)stringDateFromString:(NSString*)string
{
    return [[NSString stringDateFormatter] dateFromString:string];
}

+ (NSString*)stringDateFromDate:(NSDate*)date
{
    return [[NSString stringDateFormatter] stringFromDate:date];
}


// Usage (#import "NSString+Date.h") or add in "YOUR PROJECT".pch file
NSString* string = [NSString stringDateFromDate:[NSDate date]];
NSDate* date = [NSString stringDateFromString:string];

Fand das wirklich nützlich. Vielen Dank!
Thomas Johannesmeyer

6

Die Verwendung von "10" für die Darstellung eines Jahres ist nicht gut, da dies 1910, 1810 usw. sein kann. Sie sollten dafür wahrscheinlich 4 Ziffern verwenden.

Wenn Sie das Datum auf so etwas wie ändern können

yyyymmdd

Dann können Sie verwenden:

// Convert string to date object
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"yyyyMMdd"];
NSDate *date = [dateFormat dateFromString:dateStr];  

// Convert date object to desired output format
[dateFormat setDateFormat:@"EEEE MMMM d, YYYY"];
dateStr = [dateFormat stringFromDate:date];  
[dateFormat release];

4
NSString *dateStr = @"Tue, 25 May 2010 12:53:58 +0000";

// Convert string to date object
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"EE, d LLLL yyyy HH:mm:ss Z"];
NSDate *date = [dateFormat dateFromString:dateStr]; 
[dateFormat release];

2
// Convert string to date 

NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"yyyyMMdd"];
NSDate *date = [dateFormat dateFromString:dateStr];  

// Convert Date to string

[dateFormat setDateFormat:@"EEEE MMMM d, YYYY"];
dateStr = [dateFormat stringFromDate:date];  
[dateFormat release];

1
NSString *mystr=@"Your string date";

NSCalendar *cal = [NSCalendar currentCalendar];
NSDate *now = [dateFormatter dateFromString:mystr];

Nslog(@"%@",now);

Wenn Sie das Format einstellen möchten, verwenden Sie den folgenden Code:

NSString *dateString = @"01-02-2010";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

// this is important - we set our input date format to match our input string
// if format doesn't match you'll get nil from your string, so be careful
[dateFormatter setDateFormat:@"dd-MM-yyyy"];
NSDate *dateFromString = [[NSDate alloc] init];

// voila!
dateFromString = [dateFormatter dateFromString:dateString];
Nslog(@"%@",[dateFormatter dateFromString:dateString]);

1

Verwenden Sie diese Methode, um von NSStringzu konvertieren NSdate:

-(NSDate *)getDateFromString:(NSString *)pstrDate
{
    NSDateFormatter* myFormatter = [[NSDateFormatter alloc] init];
    [myFormatter setDateFormat:@"dd/MM/yyyy"];
    NSDate* myDate = [myFormatter dateFromString:pstrDate];
    return myDate;
}

1

Wenn jemand heutzutage daran interessiert ist, so etwas in Swift zu machen, habe ich einen Anfang mit etwas, obwohl es nicht perfekt ist.

func detectDate(dateString: NSString) -> NSDate {

    var error: NSError?
    let detector: NSDataDetector = NSDataDetector.dataDetectorWithTypes(NSTextCheckingType.Date.toRaw(), error: &error)!

    if error == nil {
        var matches = detector.matchesInString(dateString, options: nil, range: NSMakeRange(0, dateString.length))

        let currentLocale = NSLocale.currentLocale()
        for match in matches {
            match.resultType == NSTextCheckingType.Date
            NSLog("Date: \(match.date.description)")
            return match.date
        }
    }
    return NSDate()
}

1

Datum zu NSString

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

NSString zu 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

Hierfür können Sie Erweiterungen verwenden.

extension NSDate {
    //NSString to NSDate
    convenience
    init(dateString:String) {
        let nsDateFormatter = NSDateFormatter()
        nsDateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss"
        // Add the locale if required here
        let dateObj = nsDateFormatter.dateFromString(dateString)
        self.init(timeInterval:0, sinceDate:dateObj!)
    }

    //NSDate to time string
    func getTime() -> String {
        let timeFormatter = NSDateFormatter()
        timeFormatter.dateFormat = "hh:mm"
        //Can also set the default styles for date or time using .timeStyle or .dateStyle
        return timeFormatter.stringFromDate(self)
    }

    //NSDate to date string
    func getDate() -> String {
        let dateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = "dd, MMM"
        return dateFormatter.stringFromDate(self)
    }

    //NSDate to String
    func getString() -> String {
        let dateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss"
        return dateFormatter.stringFromDate(self)
    }
}

Während der Ausführung sieht der tatsächliche Code also wie folgt aus

    var dateObjFromString = NSDate(dateString: cutDateTime)
    var dateString = dateObjFromString.getDate()
    var timeString = dateObjFromString.getTime()
    var stringFromDate = dateObjFromString.getString()

Es gibt auch einige Standardmethoden, aber ich denke, es funktioniert möglicherweise nicht für das Format, das Sie aus der Dokumentation angegeben haben

    -dateFromString(_:)
    -stringFromDate(_:)
    -localizedStringFromDate(_ date: NSDate,
                     dateStyle dateStyle: NSDateFormatterStyle,
                     timeStyle timeStyle: NSDateFormatterStyle) -> String

0

Die beste Vorgehensweise besteht darin, sich eine allgemeine Klasse zu erstellen, in der Sie alle allgemeinen Verwendungsmethoden, die in fast allen Projekten nützlich sind, einfügen und dort den von @Pavan vorgeschlagenen Code wie folgt hinzufügen:

+ (NSDate *)getDateOutOfString:(NSString *)passedString andDateFormat:(NSString *)dateFormat{

    NSString *dateString = passedString;
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:dateFormat];
    NSDate *dateFromString = [[NSDate alloc] init];
    dateFromString = [dateFormatter dateFromString:dateString];
    return dateFromString;

}

.. und so weiter für alle anderen nützlichen Methoden

Auf diese Weise erstellen Sie einen sauberen wiederverwendbaren Code für Ihre App. Prost!


0

Gemäß Swift 2.2

Sie können NSDate leicht von String und String von NSDate erhalten. z.B

Erster Datumsformatierer einstellen

let formatter = NSDateFormatter();
formatter.dateStyle = NSDateFormatterStyle.MediumStyle
formatter.timeStyle = .NoStyle
formatter.dateFormat = "MM/dd/yyyy"

Holen Sie sich jetzt das Datum von der Zeichenfolge und umgekehrt.

let strDate = formatter.stringFromDate(NSDate())
print(strDate)
let dateFromStr = formatter.dateFromString(strDate)
print(dateFromStr)

Jetzt viel Spaß.


0

NSString zu NSDate oder NSDate zu NSString

//This method is used to get NSDate from string 
//Pass the date formate ex-"dd-MM-yyyy hh:mm a"
+ (NSDate*)getDateFromString:(NSString *)dateString withFormate:(NSString *)formate  {

    // Converted date from date string
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]];
    [dateFormatter setDateFormat:formate];
    NSDate *convertedDate         = [dateFormatter dateFromString:dateString];
    return convertedDate;
}

//This method is used to get the NSString for NSDate
//Pass the date formate ex-"dd-MM-yyyy hh:mm a"
+ (NSString *)getDateStringFromDate:(NSDate *)date withFormate:(NSString *)formate {

    // Converted date from date string
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    //[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]];
    [dateFormatter setDateFormat:formate];
    NSString *convertedDate         = [dateFormatter stringFromDate:date];
    return convertedDate;
}

0

Die obigen Beispiele sind nicht nur für Swift 3.0+ geschrieben

Update - Swift 3.0+ - Datum in String konvertieren

let date = Date() // insert your date data here
var dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd" // add custom format if you'd like 
var dateString = dateFormatter.string(from: date)

0

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.