Jak przekonwertować datę ciągu na NSDate?

195

Chcę przekonwertować „2014-07-15 06: 55: 14.198000 + 00: 00” tę datę ciągu na NSDate w Swift.

Shardul
źródło
Wygląda na to, że Twój ciąg „2014-07-15 06: 55: 14.198000 + 00: 00” jest nieosiągalny, jeśli używasz NSDateFormatter
Alex Peda
Jako zasób towarzyszący dla wszystkich poniższych odpowiedzi, zdecydowanie polecam sprawdzenie nsdateformatter.com
user3344977
Stare odpowiedzi tutaj są naprawdę ŹLE . Dokument Apple mówi krystalicznie czyste, że musisz buforować formatyzator. stackoverflow.com/a/42370648/294884
Fattie
Jeśli potrzebujesz pomocnika z tym formatem, nsdateformatter.com
Pedro Luz

Odpowiedzi:

341

Spróbuj tego:

let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = /* find out and place date format from 
                            * http://userguide.icu-project.org/formatparse/datetime
                            */
let date = dateFormatter.dateFromString(/* your_date_string */)

Aby uzyskać dalsze zapytanie, sprawdź klasy NSDateFormatter i DateFormatter w Framework Foundation odpowiednio dla Objective-C i Swift.

Swift 3 i nowszy (w tym Swift 4)

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = /* date_format_you_want_in_string from
                            * http://userguide.icu-project.org/formatparse/datetime
                            */
guard let date = dateFormatter.date(from: /* your_date_string */) else {
   fatalError("ERROR: Date conversion failed due to mismatched format.")
}

// use date constant here
x4h1d
źródło
11
Znalazłem rozwiązanie wystarczy ustawić „rrrr-MM-dd gg: mm: ss.SSSSxxx” ten format daty
Shardul
1
Mam ciąg daty taki jak ten „2014-07-15 06: 55: 14-0400” i próbowałem użyć yyyy-MM-dd hh:mm:ssZZZ. Ale nie mogę pobrać obiektu daty z ciągu.
iamprem,
2
@Prem, jeśli zobaczysz, że wynik jest "2014-07-15 10:55:14 +0000"prawidłowy. Począwszy od NSDateopisu, wynik daty byłby obliczany z różnicą (tutaj GMT -4 godziny). Jeśli chcesz uzyskać różnicę między GMT a UTC, -0400sprawdź to odniesienie
x4h1d
@ x4h1d, Hej, mam to! Popełniłem błąd, w hhktórym powinno być HH. Dzięki!
iamprem,
3
@ lmiguelvargasf, myślę, że tak będzie yyyy-MM-dd'T'HH:mm:ss.SSS'Z'. Zakładam, że Zjest tu tylko postacią. Pamiętaj, że Zma również specjalne znaczenie. Jeśli chcesz Zokreślić jako, basic hmsformat będzie yyyy-MM-dd'T'HH:mm:ss.SSSZ.
x4h1d
71

Szybki 4

import Foundation

let dateString = "2014-07-15" // change to your date format

var dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"

let date = dateFormatter.date(from: dateString)
println(date)

Szybki 3

import Foundation

var dateString = "2014-07-15" // change to your date format

var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"

var date = dateFormatter.dateFromString(dateString)
println(date)

Mogę to zrobić za pomocą tego kodu.

Kiattisak Anoochitarom
źródło
5
Kod jest nieprawidłowy. Wydaje „15 stycznia 2014, 12:00”
Jake Lin
5
użycie ddzamiast DDpowinno pomóc rozwiązać problem „zawsze w styczniu”.
Pascal Belloncle,
1
Prawidłowa wersja jest, yyyy-MM-ddw przeciwnym razie przeanalizowana data utknęła w styczniu - zaktualizowałem odpowiedź, aby odzwierciedlić zmianę.
Zorayr
Co jeśli chcę przekazać bieżącą datę jako ciąg. Czy to zadziała?
Arjun Kalidas
@Zorayr, Kittisak: Dostaję out out, opcjonalne (2014-07-14 18:30:00 +0000), co oznacza, że ​​jeden dzień jest pomniejszony. Jak mogę to naprawić?
Vineesh TP,
54
 func convertDateFormatter(date: String) -> String
 {

    let dateFormatter = NSDateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"//this your string date format
    dateFormatter.timeZone = NSTimeZone(name: "UTC")
    let date = dateFormatter.dateFromString(date)


    dateFormatter.dateFormat = "yyyy MMM EEEE HH:mm"///this is what you want to convert format
    dateFormatter.timeZone = NSTimeZone(name: "UTC")
    let timeStamp = dateFormatter.stringFromDate(date!)


    return timeStamp
}

Zaktualizowano dla Swift 3.

func convertDateFormatter(date: String) -> String
{

    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"//this your string date format
    dateFormatter.timeZone = NSTimeZone(name: "UTC") as TimeZone!
    let date = dateFormatter.date(from: date)


    dateFormatter.dateFormat = "yyyy MMM EEEE HH:mm"///this is what you want to convert format
    dateFormatter.timeZone = NSTimeZone(name: "UTC") as TimeZone!
    let timeStamp = dateFormatter.string(from: date!)


    return timeStamp
}
idris yıldız
źródło
17

Detale

  • Swift 4, Xcode 9.2
  • Swift 5, Xcode 10.2 (10E125)

Rozwiązanie

import Foundation

extension DateFormatter {

    convenience init (format: String) {
        self.init()
        dateFormat = format
        locale = Locale.current
    }
}

extension String {

    func toDate (dateFormatter: DateFormatter) -> Date? {
        return dateFormatter.date(from: self)
    }

    func toDateString (dateFormatter: DateFormatter, outputFormat: String) -> String? {
        guard let date = toDate(dateFormatter: dateFormatter) else { return nil }
        return DateFormatter(format: outputFormat).string(from: date)
    }
}

extension Date {

    func toString (dateFormatter: DateFormatter) -> String? {
        return dateFormatter.string(from: self)
    }
}

Stosowanie

var dateString = "14.01.2017T14:54:00"
let dateFormatter = DateFormatter(format: "dd.MM.yyyy'T'HH:mm:ss")
let date = Date()

print("original String with date:               \(dateString)")
print("date String() to Date():                 \(dateString.toDate(dateFormatter: dateFormatter)!)")
print("date String() to formated date String(): \(dateString.toDateString(dateFormatter: dateFormatter, outputFormat: "dd MMMM")!)")
let dateFormatter2 = DateFormatter(format: "dd MMM HH:mm")
print("format Date():                           \(date.toString(dateFormatter: dateFormatter2)!)")

Wynik

wprowadź opis zdjęcia tutaj

Więcej informacji

Informacje o formacie daty

Wasilij Bodnarchuk
źródło
15

Jeśli będziesz musiał często parsować ciąg znaków w dacie, możesz przenieść funkcjonalność do rozszerzenia. Utworzyłem plik sharedCode.swift i umieściłem tam moje rozszerzenia:

extension String
{   
    func toDateTime() -> NSDate
    {
        //Create Date Formatter
        let dateFormatter = NSDateFormatter()

        //Specify Format of String to Parse
        dateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss.SSSSxxx"

        //Parse into NSDate
        let dateFromString : NSDate = dateFormatter.dateFromString(self)!

        //Return Parsed Date
        return dateFromString
    }
}

Następnie, jeśli chcesz przekonwertować swój ciąg na NSDate, możesz po prostu napisać coś takiego:

var myDate = myDateString.toDateTime()
użytkownik2266987
źródło
1
Dzięki. Możliwe jest również, choć mniej przydatne, pisanie: var myDate = "04-05-2015" .toDateTime () Znalazłem to przydatne podczas konfigurowania danych testowych.
Stephen Watson,
1
Jestem prawie pewien, że tak hhpowinno być HH.
Alex
Nie daje mi to w podanym przeze mnie formacie: var date = NSDate (); let dateFormatter = NSDateFormatter (); dateFormatter.dateFormat = "MMMM d, RRRR"; let myDate = dateFormatter.stringFromDate (date); I na dodatek, jeśli użyję twojego rozszerzenia w ten sposób -> var myDate2 = myDate.toDateTime (); Daje mi zupełnie inną datę, a nie aktualną.
Arjun Kalidas
9

Dla Swift 3

func stringToDate(_ str: String)->Date{
    let formatter = DateFormatter()
    formatter.dateFormat="yyyy-MM-dd hh:mm:ss Z"
    return formatter.date(from: str)!
}
func dateToString(_ str: Date)->String{
    var dateFormatter = DateFormatter()
    dateFormatter.timeStyle=DateFormatter.Style.short
    return dateFormatter.string(from: str)
}
Rishabh Dugar
źródło
5

Fragmenty kodu na tej stronie kontroli jakości są „do góry nogami” ...

Pierwszą rzeczą, o której wspomina Apple, jest buforowanie formatera w pamięci podręcznej ...

Link do Apple doco określający dokładnie, jak to zrobić:

Formatowanie pamięci podręcznej w celu zwiększenia wydajności Tworzenie formatera daty nie jest tanią operacją. ... buforuj pojedyncze wystąpienie ...

Użyj globalnego ...

let df : DateFormatter = {
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd"
    return formatter 
}()

Następnie użyj tego formatyzatora w dowolnym miejscu ...

let s = df.string(from: someDate)

lub

let d = df.date(from: someString)

Lub użyj dowolnej z wielu innych, wielu wygodnych metod w DateFormatter.

To takie proste.

(Jeśli napiszesz rozszerzenie w String, twój kod jest całkowicie „do góry nogami” - nie możesz używać żadnych wywołań dateFormatter!)

Zauważ, że zwykle będziesz mieć kilka takich globali .. takich jak „formatForClient” „formatForPubNub” „formatForDisplayOnInvoiceScreen” .. itp.

Fattie
źródło
Nie trzeba pozostawiać ich w zasięgu globalnym. Możesz rozszerzyć Formatter po prostu zadeklarować swoje właściwości jako statyczne. sprawdź ten stackoverflow.com/a/43658213/2303865
Leo Dabus
4

Rozszerzenia wsparcia Swift, z rozszerzeniem można dodać nowe funkcje do istniejącej class, structure, enumerationlub protocoltypu.

Możesz dodać nową initfunkcję do NSDateobiektu, rozszerzając obiekt za pomocą extensionsłowa kluczowego.

extension NSDate
{
    convenience
    init(dateString:String) {
        let dateStringFormatter = NSDateFormatter()
        dateStringFormatter.dateFormat = "yyyyMMdd"
        dateStringFormatter.locale = NSLocale(localeIdentifier: "fr_CH_POSIX")
        let d = dateStringFormatter.dateFromString(dateString)!
        self.init(timeInterval:0, sinceDate:d)
    }
} 

Teraz możesz zainicjować obiekt NSDate za pomocą:

let myDateObject = NSDate(dateString:"2010-12-15 06:00:00")
Hugo Pereira
źródło
Lubię sposób inicjacji. Czy nie ma innego sposobu na utworzenie daty bez użycia timeInterval? co jeśli nsdate przestanie mieć inicjalizator z parametrem daty? jak byś to rozwiązał? Osobiście wolę sposób inicjacji, ale nie wiem, jak rozwiązać ten problem
Mijail
Mam problem: moja data jako ciąg znaków jest taka: „2017-03-10 22:16:00 +0000” i użyłem tego formatu: „rrrr-MM-dd gg: mm: ss Z” i ten: „rrrr-MM-dd'T'HH: mm: ss”. Ale dla obu, gdy to zrobię: let beginDate = df.date(from: beginDateString), dostaję zero! czemu? ( df = DateFormatter())
Paul Bénéteau,
4

Od Swift 3 wiele prefiksów NS zostało usuniętych.

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ" 
/* date format string rules
 * http://userguide.icu-project.org/formatparse/datetime
 */

let date = dateFormatter.date(from: dateString)
Toddg
źródło
Mam problem: moja data jako ciąg znaków jest taka: „2017-03-10 22:16:00 +0000” i użyłem tego formatu: „rrrr-MM-dd gg: mm: ss Z” i ten: „rrrr-MM-dd'T'HH: mm: ss”. Ale dla obu, gdy to zrobię: let beginDate = df.date(from: beginDateString), dostaję zero! czemu? ( df = DateFormatter())
Paul Bénéteau,
4

Swift 3,4:

2 przydatne konwersje:

string(from: Date) // to convert from Date to a String
date(from: String) // to convert from String to Date

Zastosowanie: 1.

let date = Date() //gives today's date
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd.MM.yyyy"
let todaysDateInUKFormat = dateFormatter.string(from: date)

2)

 let someDateInString = "23.06.2017"
 var getDateFromString = dateFormatter.date(from: someDateInString)
Naishta
źródło
3

DLA SWIFT 3.1

func convertDateStringToDate(longDate: String) -> String{

    /* INPUT: longDate = "2017-01-27T05:00:00.000Z"
     * OUTPUT: "1/26/17"
     * date_format_you_want_in_string from
     * http://userguide.icu-project.org/formatparse/datetime
     */

    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
    let date = dateFormatter.date(from: longDate)

    if date != nil {

        let formatter = DateFormatter()
        formatter.dateStyle = .short
        let dateShort = formatter.string(from: date!)

        return dateShort

    } else {

        return longDate

    }
}

UWAGA: TO BĘDZIE ZWRÓCIĆ ORYGINALNY STRING JEŚLI BŁĄD

Brian
źródło
2

Aby dodać ciąg znaków w formacie daty w Swift, zrobiłem to

 var dataFormatter:NSDateFormatter = NSDateFormatter()
                dataFormatter.dateFormat = "dd-MMMM 'at' HH:mm a"

cell.timeStamplbl.text = dataFormatter.stringFromDate(object.createdAt)
ioopl
źródło
2

Ta praca dla mnie ..

    import Foundation
    import UIKit

    //dateString = "01/07/2017"
    private func parseDate(_ dateStr: String) -> String {
            let simpleDateFormat = DateFormatter()
            simpleDateFormat.dateFormat = "dd/MM/yyyy" //format our date String
            let dateFormat = DateFormatter()
            dateFormat.dateFormat = "dd 'de' MMMM 'de' yyyy" //format return

            let date = simpleDateFormat.date(from: dateStr)
            return dateFormat.string(from: date!)
    }
marlonpya
źródło
1

Poniżej znajduje się kilka opcji konwersji formatu ciągów na datę w szybkim iOS.

  1. Thursday, Dec 27, 2018 format = EEEE, MMM d, yyyy
  2. 12/27/2018 format = MM/dd/yyyy
  3. 12-27-2018 09:59 format = MM-dd-yyyy HH:mm
  4. Dec 27, 9:59 AM format = MMM d, h:mm a
  5. December 2018 format = MMMM yyyy
  6. Dec 27, 2018 format = MMM d, yyyy
  7. Thu, 27 Dec 2018 09:59:19 +0000 format = E, d MMM yyyy HH:mm:ss Z
  8. 2018-12-27T09:59:19+0000 format = yyyy-MM-dd'T'HH:mm:ssZ
  9. 27.12.18 format = dd.MM.yy
  10. 09:59:19.815 format = HH:mm:ss.SSS
Devesh
źródło
0
Swift: iOS
if we have string, convert it to NSDate,

var dataString = profileValue["dob"] as String
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MM-dd-yyyy"

// convert string into date
let dateValue:NSDate? = dateFormatter.dateFromString(dataString)

if you have and date picker parse date like this

// to avoid any nil value
if let isDate = dateValue {
self.datePicker.date = isDate
}
Vinod Joshi
źródło
0

Możesz wypróbować ten szybki kod

    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "dd/MM/yyyy"//same as strDate date formator
    dateFormatter.timeZone = TimeZone(abbreviation: "GMT+0:00")//Must used if you get one day less in conversion
    let convertedDateObject = dateFormatter.date(from: strDate)
Rahul Panzade
źródło
0

SWIFT 5 , Xcode 11.0

Przekaż swój (data w ciągu) w „dateString” i w „dateFormat” formacie, który chcesz. Aby wybrać format, użyj strony NDateFormatter .

func getDateFrom(dateString: String, dateFormat: String) -> Date? {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = dateFormat
    dateFormatter.locale = Locale(identifier: "en_US")
    guard let date = dateFormatter.date(from: dateString) else {return nil}
    return date
}
Abdul Karim Khan
źródło
-3
import Foundation

let now : String = "2014-07-16 03:03:34 PDT"
var date : NSDate
var dateFormatter : NSDateFormatter

date = dateFormatter.dateFromString(now)

date // $R6: __NSDate = 2014-07-16 03:03:34 PDT

https://developer.apple.com/library/prerelease/mac/documentation/Cocoa/Reference/Foundation/Classes/NSDateFormatter_Class/index.html#//apple_ref/doc/uid/20000447-SW32

Ch0c0late
źródło
2
Jak to ma działać? Formatyzator daty nie został zainicjowany, nie ma też powodu, aby dzielić deklarację i inicjalizację daty.
Ixx,