Conversion de NSString en NSDate (et vice-versa)

229

Comment pourrais-je convertir un NSString" 01/02/10 " (c'est-à-dire le 1er février 2010) en un NSDate? Et comment pourrais-je transformer le NSDatedos en chaîne?

cannyboy
la source
utilisez 2010. puis jetez un oeil à mon message. J'ai fourni une conversion pour les deux processus.
Pavan,

Réponses:

450

Swift 4 et versions ultérieures

Mise à jour: 2018

Chaîne à ce jour

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 à chaîne

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

Mis à jour: 20 juillet 2017

Chaîne en 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)

Rapide

Mis à jour: 22 octobre 2015

Chaîne en 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)

Objectif c

NSString à NSDate

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

NSDate convertit en NSString:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"dd-MM-yyyy"];
NSString *stringDate = [dateFormatter stringFromDate:[NSDate date]];
NSLog(@"%@", stringDate);
Pavan
la source
cela devrait-il être deux ys dans le setDateFormat?
cannyboy
Je ne sais pas si le travail de 2 ans. mais la règle générale est le format que vous allez donner à keeo le même format pour le setDateFormat. donc premier trty 2010 et écrivez 4 y comme so 'yyyy'. comme je suis sûr que cela fonctionnera sans aucun doute
Pavan
1
vaut vraiment la peine de vérifier ce post.
iOmi
7
Quelle est la raison de NSDate *dateFromString = [[NSDate alloc] init];si attribuez une nouvelle valeur au pointeur sur la ligne suivante ???
Valeriy Van
4
Un autre élément à surveiller - Si la valeur de votre chaîne (date) est répertoriée comme 29/05/2013, votre appel à setDateFormat devra correspondre à la même chose - c'est-à-dire [dateFormatter setDateFormat: @ "MM / dd / yyyy"] - Le la personne que j'aidais continuait d'essayer d'utiliser des tirets lorsque leurs données de chaîne avaient des barres obliques. - Excellente réponse Pavan.
noobzilla
54

MISE À JOUR 2019 (Swift 4):

J'ai fait une Dateextension pour ça. Il utilise NSDataDetectorau lieu deNSDateFormatter .

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

Assez agréable, il reconnaît même des choses comme "Demain à 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 comme:

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

MISE À JOUR 2014:

A fait une extension NSString pour cela.

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

Grâce à NSDataDetector , il reconnaît de nombreux formats.

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

Faisant partie du kit eppz!, Saisissez la catégorie NSString + EPPZKit.h de GitHub.


RÉPONSE ORIGINALE 2013:

Si vous n'êtes pas sûr (ou ne vous souciez pas) du format de date contenu dans la chaîne, utilisez NSDataDetector pour analyser la 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; }];
Geri Borbás
la source
Il ne semble pas prendre en charge le format 24 heures. Par exemple NSString-> 2013-09-11 01:31:22 +0000convertit en NSDate->2013-09-11 13:31:22 +0000
sooper
J'aime le plus cette réponse car la chaîne de date d'origine peut être très arbitraire. C'est formidable dans les cas où l'utilisateur entre la date dans un champ de texte plutôt que via un sélecteur.
Kyle
2
comment cette méthode déciderait-elle si la date est en JJ / MM / aaaa ou MM / JJ / aaaa? par exemple si l'entrée est 01/03/2014 quel serait le résultat?
ahmad
@ahmad Je suis entièrement d'accord - cette approche ne fonctionnera probablement pas si vous devez prendre en charge différents paramètres de langue.
Frank Schmitt
@sooper XCTAssertEqual(Date.FromString("2013-09-11 01:31:22 +0000"), Date.FromCalendar(2013, 9, 11, 1, 31, 22))semble très bien.
Geri Borbás
33

Lorsque vous utilisez des dates au format fixe, vous devez définir les paramètres régionaux du formateur de date sur "en_US_POSIX".

Extrait du Guide de formatage des données

Si vous travaillez avec des dates au format fixe, vous devez d'abord définir les paramètres régionaux du formateur de date sur quelque chose de approprié pour votre format fixe. Dans la plupart des cas, le meilleur environnement local à choisir est en_US_POSIX, un environnement local spécialement conçu pour produire des résultats en anglais américain, quelles que soient les préférences de l'utilisateur et du système . en_US_POSIX est également invariant dans le temps (si les États-Unis, à un moment donné dans le futur, modifient la façon dont ils formatent les dates, en_US changera pour refléter le nouveau comportement, mais en_US_POSIX ne changera pas), et entre les plates-formes (en_US_POSIX fonctionne de la même manière sur iPhone OS comme il le fait sur OS X, et comme il le fait sur d'autres plates-formes).

Swift 3 ou version ultérieure

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"

Analyser la date personnalisée et reconvertir la date au même format de chaîne:

let dateString = "01/02/10"

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

Voici tous les éléments que vous pouvez utiliser pour le personnaliser selon vos besoins:

entrez la description de l'image ici

Leo Dabus
la source
Que faire si plusieurs threads accèdent à ces méthodes? Cela ne pourrait-il pas conduire à des erreurs en raison de la réaffectation du format de date du formateur? Est-ce que l'utilisation de variables (date / heure / jour de semaine) n'est qu'une préférence de la vôtre ou est-ce peut-être un avantage de le faire de cette façon ou est-ce une meilleure pratique?
lahmar
19

Pourquoi ne pas ajouter une catégorie à 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];
Sveinung Kval Bakken
la source
J'ai trouvé cela vraiment utile. Merci!
Thomas Johannesmeyer
6

utiliser "10" pour représenter une année n'est pas bon, car cela peut être 1910, 1810, etc. Vous devriez probablement utiliser 4 chiffres pour cela.

Si vous pouvez changer la date en quelque chose comme

yyyymmdd

Ensuite, vous pouvez utiliser:

// 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];
canard
la source
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];
Mohit
la source
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];
Rushabh
la source
1
NSString *mystr=@"Your string date";

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

Nslog(@"%@",now);

Si vous souhaitez définir le format, utilisez le code ci-dessous:

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]);
chowdary mahesh
la source
1

Utilisez cette méthode pour convertir de NSStringà NSdate:

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

Si quelqu'un est intéressé à faire quelque chose comme ça dans Swift ces jours-ci, j'ai un début sur quelque chose, même si ce n'est pas parfait.

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()
}
Kyle
la source
1

Date à NSString

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

NSString à 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
MaxEcho
la source
0

Vous pouvez utiliser des extensions pour cela.

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

Ainsi, alors que le code réel d'exécution ressemblera à ce qui suit

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

Il existe également des méthodes par défaut, mais je suppose que cela pourrait ne pas fonctionner pour le format que vous avez donné dans la documentation

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

La meilleure pratique est de vous construire une classe générale où vous mettez toutes vos méthodes d'utilisation générale, des méthodes utiles dans presque tous les projets et y ajoutez le code suggéré par @Pavan comme:

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

}

.. et ainsi de suite pour toutes les autres méthodes utiles

Ce faisant, vous commencez à créer un code réutilisable propre pour votre application. À votre santé!

Laur Stefan
la source
0

Selon Swift 2.2

Vous pouvez obtenir facilement NSDate à partir de String et String à partir de NSDate. par exemple

Premier formateur de date

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

Maintenant, obtenez la date de la chaîne et vice versa.

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

Maintenant, profitez-en.

Gautam Sareriya
la source
0

NSString à NSDate ou NSDate à 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;
}
Khurshid
la source
0

Les exemples ci-dessus ne sont pas simplement écrits pour Swift 3.0+

Mise à jour - Swift 3.0+ - Convertir la date en chaîne

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)
Elon R.
la source
0

Chaîne à ce jour

var dateFormatter = DateFormatter()
dateFormatter.format = "dd/MM/yyyy"

var dateFromString: Date? = dateFormatter.date(from: dateString) //pass string here

Date à chaîne

 var dateFormatter = DateFormatter()
 dateFormatter.dateFormat = "dd-MM-yyyy"
 let newDate = dateFormatter.string(from: date) //pass Date here
Parth Barot
la source