Convertir NSString a NSDate (y viceversa)

229

¿Cómo convertiría un NSString" 01/02/10 " similar (es decir, el 1 de febrero de 2010) en un NSDate? ¿Y cómo podría convertir la NSDateespalda en una cuerda?

cannyboy
fuente
uso 2010. y luego echa un vistazo a mi publicación. He proporcionado una conversión para ambos procesos.
Pavan

Respuestas:

450

Swift 4 y posterior

Actualizado: 2018

Cadena hasta la fecha

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

Actualizado: 20 de julio de 2017

Cadena 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 to String

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

Rápido

Actualizado: 22 de octubre de 2015

Cadena 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 to String

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

C objetivo

NSString a NSDate

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

NSDate convertir a NSString:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"dd-MM-yyyy"];
NSString *stringDate = [dateFormatter stringFromDate:[NSDate date]];
NSLog(@"%@", stringDate);
Pavana
fuente
¿Deberían ser dos ys en setDateFormat?
cannyboy
No estoy seguro si 2 años de trabajo. pero la regla de oro es cualquier formato que le dé a keeo el mismo formato para setDateFormat. así que primero trty 2010 y escriba 4 años como 'aaaa'. como estoy seguro de que definitivamente funcionará
Pavan
1
Vale la pena revisar esta publicación.
iOmi
77
¿Cuál es la razón de NSDate *dateFromString = [[NSDate alloc] init];si asignar un nuevo valor al puntero en la siguiente línea?
Valeriy Van
44
Otro elemento a tener en cuenta: si el valor de su cadena (fecha) aparece como 29/05/2013, su llamada a setDateFormat deberá coincidir con la misma, es decir, [dateFormatter setDateFormat: @ "MM / dd / aaaa"] - El El individuo que estaba ayudando seguía intentando utilizar guiones cuando sus datos de cadena tenían barras. - Gran respuesta Pavan.
noobzilla
54

ACTUALIZACIÓN 2019 (Swift 4):

Hizo una Dateextensión para eso. Utiliza en NSDataDetectorlugar de NSDateFormatter.

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

Bastante agradable, incluso reconoce cosas como "Mañana a las 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 como:

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

ACTUALIZACIÓN 2014:

Hizo una extensión NSString para eso.

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

Gracias a NSDataDetector , reconoce una gran cantidad de formatos.

'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!, Tome la categoría NSString + EPPZKit.h de GitHub.


RESPUESTA ORIGINAL 2013:

Si no está seguro (o no le importa) sobre el formato de fecha contenido en la cadena, use NSDataDetector para analizar la fecha .

//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
fuente
No parece admitir el formato de 24 horas. Por ejemplo, NSString-> se 2013-09-11 01:31:22 +0000convierte a NSDate->2013-09-11 13:31:22 +0000
sooper el
Esta respuesta me gusta más, ya que la cadena de fecha original puede ser muy arbitraria. Esto es excelente en los casos en que el usuario ingresa la fecha en un campo de texto en lugar de hacerlo a través de un selector.
Kyle
2
¿Cómo decidiría este método si la fecha está en DD / MM / aaaa o MM / DD / aaaa? por ejemplo, si la entrada es 01/03/2014, ¿cuál sería el resultado?
ahmad
@ahmad Estoy totalmente de acuerdo: este enfoque probablemente no funcionará si tiene que admitir diferentes configuraciones de idioma.
Frank Schmitt
@sooper XCTAssertEqual(Date.FromString("2013-09-11 01:31:22 +0000"), Date.FromCalendar(2013, 9, 11, 1, 31, 22))parece estar bien.
Geri Borbás
33

Cuando utilice fechas de formato fijo, debe establecer la configuración regional de formateador de fecha en "en_US_POSIX".

Tomado de la Guía de formato de datos

Si está trabajando con fechas de formato fijo, primero debe establecer la configuración regional del formateador de fecha en algo apropiado para su formato fijo. En la mayoría de los casos, la mejor configuración regional para elegir es en_US_POSIX, una configuración regional específicamente diseñada para producir resultados en inglés de EE. UU. Independientemente de las preferencias del usuario y del sistema . en_US_POSIX también es invariable en el tiempo (si EE. UU., en algún momento en el futuro, cambia la forma en que formatea las fechas, en_US cambiará para reflejar el nuevo comportamiento, pero en_US_POSIX no lo hará), y entre plataformas (en_US_POSIX funciona igual en iPhone SO como lo hace en OS X, y como lo hace en otras plataformas).

Swift 3 o posterior

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

uso:

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

Análisis de la fecha personalizada y conversión de la fecha al mismo formato de cadena:

let dateString = "01/02/10"

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

Aquí están todos los elementos que puede usar para personalizarlo según sea necesario:

ingrese la descripción de la imagen aquí

Leo Dabus
fuente
¿Qué pasa si varios hilos acceden a estos métodos? ¿No podría eso conducir a errores debido a la reasignación del dateFormat del formateador? ¿Es el uso de variables (fecha / hora / día de la semana) solo una preferencia suya o es su ventaja tal vez hacerlo o es una mejor práctica?
lahmar
19

¿Por qué no agregar una categoría 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];
Sveinung Kval Bakken
fuente
Encontré esto realmente útil. ¡Gracias!
Thomas Johannesmeyer
6

usar "10" para representar un año no es bueno, porque puede ser 1910, 1810, etc. Probablemente deberías usar 4 dígitos para eso.

Si puedes cambiar la fecha a algo como

yyyymmdd

Entonces puedes usar:

// 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];
Pato
fuente
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
fuente
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
fuente
1
NSString *mystr=@"Your string date";

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

Nslog(@"%@",now);

Si desea establecer el formato, use el siguiente código:

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

Use este método para convertir de NSStringa NSdate:

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

Si alguien está interesado en hacer algo como esto en Swift en estos días, tengo un comienzo en algo, aunque no es perfecto.

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
fuente
1

Fecha para 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
MaxEcho
fuente
0

Puedes usar extensiones para esto.

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

Entonces, mientras que la ejecución del código real se verá como sigue

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

También hay algunos métodos predeterminados, pero supongo que podría no funcionar para el formato que ha proporcionado de la documentación

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

La mejor práctica es crear una clase general donde coloque todos sus métodos de uso general, métodos útiles en casi todos los proyectos y agregue el código sugerido por @Pavan como:

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

}

.. y así sucesivamente para todos los demás métodos útiles

Al hacerlo, comienza a construir un código limpio reutilizable para su aplicación. ¡Salud!

Laur Stefan
fuente
0

Según Swift 2.2

Puede obtener fácilmente NSDate de String y String de NSDate. p.ej

Formateador de la primera fecha establecida

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

Ahora obtenga la fecha de la cadena y viceversa.

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

Ahora disfruta.

Gautam Sareriya
fuente
0

NSString a NSDate o 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;
}
Khurshid
fuente
0

Los ejemplos anteriores no están escritos simplemente para Swift 3.0+

Actualización - Swift 3.0+ - Convertir fecha a cadena

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.
fuente
0

Cadena hasta la fecha

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

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

Fecha a cadena

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