Conversione di NSString in NSDate (e viceversa)


229

Come trasformerei un NSStringsimile " 01/02/10 " (che significa 1 febbraio 2010) in un NSDate? E come potrei trasformare la NSDateschiena in una corda?


usa il 2010. e poi dai un'occhiata al mio post. Ho fornito una conversione per entrambi i processi.
Pavan,

Risposte:


450

Swift 4 e versioni successive

Aggiornato: 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

Aggiornato: 20 luglio 2017

Stringa a 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 a String

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

veloce

Aggiornato: 22 ottobre 2015

Stringa a 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 a String

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

Objective-C

NSString a NSDate

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

NSDate converti in NSString:

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

dovrebbero essere due anni nel setDateFormat?
cannyboy,

non sono sicuro che il lavoro di 2 anni. ma la regola empirica è qualsiasi formato tu abbia mai dato a Keeo lo stesso formato per setDateFormat. quindi prima del trenta 2010 e scrivere 4 anni come "yyyy". come sono sicuro che funzionerà sicuramente
Pavan,

1
vale la pena controllare questo post.
iOmi,

7
Qual è il motivo per cui NSDate *dateFromString = [[NSDate alloc] init];assegnare un nuovo valore al puntatore nella riga successiva ???
Valeriy Van,

4
Un altro elemento a cui prestare attenzione: se il valore della stringa (data) è elencato come 29/05/2013, la chiamata a setDateFormat dovrà corrispondere allo stesso, ovvero [dateFormatter setDateFormat: @ "MM / dd / yyyy"] - Il la persona che stavo aiutando continuava a provare a usare i trattini quando i loro dati sulle stringhe presentavano barre. - Ottima risposta Pavan.
Noobzilla,

54

AGGIORNAMENTO 2019 (Swift 4):

Ho fatto Dateun'estensione per quello. Usa NSDataDetectorinvece di NSDateFormatter.

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

Abbastanza divertente, riconosce persino cose come "Domani alle 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))

Va come:

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

AGGIORNAMENTO 2014:

Realizzato un'estensione NSString per questo.

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

Grazie a NSDataDetector , riconosce un sacco di formati.

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

Parte del kit eppz ! , prendi la categoria NSString + EPPZKit.h da GitHub.


RISPOSTA ORIGINALE 2013:

Se non sei sicuro (o non ti interessa) del formato della data contenuto nella stringa, usa NSDataDetector per l'analisi della data .

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

Non sembra supportare il formato 24 ore. Ad esempio NSString-> 2013-09-11 01:31:22 +0000converte in NSDate->2013-09-11 13:31:22 +0000
sooper l'

Mi piace di più questa risposta poiché la stringa della data originale può essere molto arbitraria. Questo è ottimo nei casi in cui l'utente sta inserendo la data in un campo di testo anziché tramite un selettore.
Kyle,

2
come deciderebbe questo metodo se la data è in GG / MM / aaaa o MM / GG / aaaa? ad esempio se l'input è 01/03/2014 quale sarebbe il risultato?
ahmad,

@ahmad Sono d'accordo con tutto il cuore - questo approccio probabilmente non funzionerà se devi supportare impostazioni di lingua diverse.
Frank Schmitt,

@sooper XCTAssertEqual(Date.FromString("2013-09-11 01:31:22 +0000"), Date.FromCalendar(2013, 9, 11, 1, 31, 22))sembra a posto.
Geri Borbás,

33

Quando si utilizzano date in formato fisso, è necessario impostare le impostazioni internazionali del formatter data su "en_US_POSIX".

Tratto dalla guida alla formattazione dei dati

Se lavori con date in formato fisso, devi prima impostare le impostazioni internazionali del formatter data su qualcosa di appropriato per il tuo formato fisso. Nella maggior parte dei casi, la migliore locale da scegliere è en_US_POSIX, una locale appositamente progettata per produrre risultati in inglese americano, indipendentemente dalle preferenze dell'utente e del sistema . en_US_POSIX è anche invariante nel tempo (se gli Stati Uniti, ad un certo punto in futuro, cambiano il modo in cui formatta le date, en_US cambierà per riflettere il nuovo comportamento, ma en_US_POSIX non lo farà) e tra piattaforme (en_US_POSIX funziona allo stesso modo su iPhone OS come su OS X e su altre piattaforme).

Swift 3 o successivo

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

utilizzo:

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

Analisi della data personalizzata e conversione della data nello stesso formato di stringa:

let dateString = "01/02/10"

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

Ecco tutti gli elementi che puoi utilizzare per personalizzarlo secondo necessità:

inserisci qui la descrizione dell'immagine


Cosa succede se più thread accedono a questi metodi? Ciò non potrebbe comportare errori dovuti alla riassegnazione della data del formattatore? L'uso delle variabili (data / ora / giorno della settimana) è solo una delle tue preferenze o è forse un vantaggio nel farlo in quel modo o è una buona pratica?
Lahmar,

19

Perché non aggiungere una categoria a NSString?

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

Ho trovato questo davvero utile. Grazie!
Thomas Johannesmeyer,

6

usare "10" per rappresentare un anno non va bene, perché può essere 1910, 1810, ecc. Probabilmente dovresti usare 4 cifre per quello.

Se puoi cambiare la data in qualcosa del genere

yyyymmdd

Quindi puoi usare:

// 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);

Se vuoi impostare il formato usa il codice qui sotto:

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

Utilizzare questo metodo per convertire da NSStringa NSdate:

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

1

Se qualcuno è interessato a fare qualcosa del genere in Swift in questi giorni, ho un inizio su qualcosa, anche se non è perfetto.

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

Data a NSString

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

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

È possibile utilizzare le estensioni per questo.

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

Quindi, mentre l'esecuzione del codice effettivo apparirà come segue

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

Esistono anche alcuni metodi predefiniti, ma suppongo che potrebbe non funzionare per il formato fornito dalla documentazione

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

0

La migliore pratica è di costruirti una classe generale in cui metti tutti i tuoi metodi di uso generale, metodi utili in quasi tutti i progetti e aggiungi il codice suggerito da @Pavan come:

+ (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;

}

.. e così via per tutti gli altri metodi utili

In questo modo inizi a creare un codice riutilizzabile pulito per la tua app. Saluti!


0

Secondo Swift 2.2

È possibile ottenere facilmente NSDate da String e String da NSDate. per esempio

Primo programma di formattazione della data

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

Ora ottieni la data dalla stringa e viceversa.

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

Adesso divertiti.


0

Da NSString a NSDate o da NSDate a 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

Gli esempi sopra non sono semplicemente scritti per Swift 3.0+

Aggiornamento - Swift 3.0+ - Converti la data in stringa

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

Data a stringa

 var dateFormatter = DateFormatter()
 dateFormatter.dateFormat = "dd-MM-yyyy"
 let newDate = dateFormatter.string(from: date) //pass Date here
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.