2015-01-12 16 views
6

Ho un JSON di ritorno nella mia applicazione in Swift, e ho un campo che mi restituisce una data. Quando faccio riferimento a questi dati, il codice mi dà qualcosa come "/ Date (1420420409680) /". Come posso convertirlo in NSDate? In Swift, per favore, ho testato gli esempi con Objective-C, senza successo.Parsing JSON (data) a Swift

+1

Vedi http://stackoverflow.com/questions/26844132/how-to-convert-unix-timestamp-into-swift-nsdate-object – rmaddy

+0

È un semplice timestamp UNIX vecchio. –

+0

@HotLicks: ... solo in millisecondi (o sarebbe nell'anno 46981 :) –

risposta

9

che sembra molto simile alla codifica JSON data usati per Microsoft ASP.NET AJAX, che descritto in An Introduction to JavaScript Object Notation (JSON) in JavaScript and .NET:

ad esempio, ASP.NET AJAX di Microsoft utilizza nessuno dei desc costolette convenzioni. Piuttosto, codifica i valori .NET DateTime come una stringa JSON, dove il contenuto della stringa è/Date (ticks)/e dove ticks rappresenta millisecondi da epoca (UTC). Quindi 29 novembre 1989, 4:55:30 AM, in UTC è codificato come "\/Date (628318530718) \ /".

L'unica differenza è che si ha il formato /Date(ticks)/ e non \/Date(ticks)\/.

È necessario estrarre il numero tra parentesi. Dividendo che per 1000 si ottiene il numero in secondi dal 1 ° gennaio 1970.

Il codice seguente mostra come ciò potrebbe essere fatto. Si è implementato come un "inizializzatore convenienza failable" per NSDate:

extension NSDate { 
    convenience init?(jsonDate: String) { 

     let prefix = "/Date(" 
     let suffix = ")/" 
     // Check for correct format: 
     if jsonDate.hasPrefix(prefix) && jsonDate.hasSuffix(suffix) { 
      // Extract the number as a string: 
      let from = jsonDate.startIndex.advancedBy(prefix.characters.count) 
      let to = jsonDate.endIndex.advancedBy(-suffix.characters.count) 
      // Convert milliseconds to double 
      guard let milliSeconds = Double(jsonDate[from ..< to]) else { 
       return nil 
      } 
      // Create NSDate with this UNIX timestamp 
      self.init(timeIntervalSince1970: milliSeconds/1000.0) 
     } else { 
      return nil 
     } 
    } 
} 

Esempio di utilizzo (con la stringa data):

if let theDate = NSDate(jsonDate: "/Date(1420420409680)/") { 
    print(theDate) 
} else { 
    print("wrong format") 
} 

Questo dà l'uscita

 
2015-01-05 01:13:29 +0000 

Aggiornamento per Swift 3 (Xcode 8):

extension Date { 
    init?(jsonDate: String) { 

     let prefix = "/Date(" 
     let suffix = ")/" 

     // Check for correct format: 
     guard jsonDate.hasPrefix(prefix) && jsonDate.hasSuffix(suffix) else { return nil } 

     // Extract the number as a string: 
     let from = jsonDate.index(jsonDate.startIndex, offsetBy: prefix.characters.count) 
     let to = jsonDate.index(jsonDate.endIndex, offsetBy: -suffix.characters.count) 

     // Convert milliseconds to double 
     guard let milliSeconds = Double(jsonDate[from ..< to]) else { return nil } 

     // Create NSDate with this UNIX timestamp 
     self.init(timeIntervalSince1970: milliSeconds/1000.0) 
    } 
} 

Esempio:

if let theDate = Date(jsonDate: "/Date(1420420409680)/") { 
    print(theDate) 
} else { 
    print("wrong format") 
} 
+0

@Martin questa estensione non riesce per un valore come: "/ Date (1479119050805 + 0300) /" perché il metodo Double init di millisecondi non può restituire un double per il valore di 1479119050805 + 0300 a causa del segno più, se si riesce a gestire questo caso per favore condividi il tuo codice qui – JAHelia

+1

@ JAHelia: dai un'occhiata a http://stackoverflow.com/a/33166980/1187415 per una versione più recente che legge le date JSON con o senza offset fuso orario. –

+1

@Martin è fantastico, grazie per l'interessante estensione – JAHelia

1

Sembra un timestamp Unix: 2015/01/12 @ 06:14 (UTC) [Secondo http://www.unixtimestamp.com/index.php]

È possibile convertirlo in un oggetto NSDate utilizzando il costruttore NSDate (timeIntervalSince1970: unixTimestamp)

+0

E come ottengo il tempo di questa variabile? –

2

Aggiungendo su quello che gli altri hanno fornito, è sufficiente creare metodo di utilità nella classe di seguito:

func dateFromStringConverter(date: String)-> NSDate? { 
    //Create Date Formatter 
    let dateFormatter = NSDateFormatter() 
    //Specify Format of String to Parse 
    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" //or you can use "yyyy-MM-dd'T'HH:mm:ssX" 
    //Parse into NSDate 
    let dateFromString : NSDate = dateFormatter.dateFromString(date)! 

    return dateFromString 
} 

Poi si può chiamare questo metodo nel vostro successo restituito, analizzato oggetto JSON, come di seguito:

//Parse the date 
guard let datePhotoWasTaken = itemDictionary["date_taken"] as? String else {return} 
    YourClassModel.dateTakenProperty = self.dateFromStringConverter(datePhotoWasTaken) 

Oppure si può ignorare il metodo di utilità e al codice chiamante sopra tutto e semplicemente fare questo:

//Parse the date 
guard let datePhotoWasTaken = itemDictionary["date_taken"] as? NSString else {return} 
    YourClassModel.dateTakenProperty = NSDate(timeIntervalSince1970: datePhotoWasTaken.doubleValue) 

E che dovrebbe funzionare!

+0

La domanda riguarda l'analisi di una stringa come '"/Date (1420420409680)/"' –

1

per la conversione JSON String per Data & Tempo in Swift 3.0 utilizzare al di sotto Codice: -

let timeinterval : TimeInterval = (checkInTime as! NSString).doubleValue 
let dateFromServer = NSDate(timeIntervalSince1970:timeinterval) 
print(dateFromServer) 
let dateFormater : DateFormatter = DateFormatter() 
//dateFormater.dateFormat = "dd-MMM-yyyy HH:mm a" // 22-Sep-2017 14:53 PM 
dateFormater.dateFormat = "dd-MMM-yyyy hh:mm a" // 22-Sep-2017 02:53 PM 
print(dateFormater.string(from: dateFromServer as Date)) 

dove checkInTimewill essere il vostro String.Hope Aiuterà qualcuno

+0

La domanda riguarda l'analisi di una stringa come '"/Date (1420420409680)/"' –