2015-01-12 17 views
6

Mam zwrot JSON w mojej aplikacji w Swift i pole, które zwraca mi datę. Kiedy odwołuję się do tych danych, kod daje mi coś w stylu "/ Date (1420420409680) /". Jak przekonwertować to na NSDate? W Swift, proszę, przetestowałem przykłady z Objective-C, bez powodzenia.Parsowanie JSON (data) do Swift

+1

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

+0

Jest to zwykły stary znacznik czasu UNIX. –

+0

@HotLicks: ... tylko w milisekundach (lub byłoby to w roku 46981 :) –

Odpowiedz

9

który wygląda bardzo podobnie do kodowania JSON na randkę jak używany przez Microsoft ASP.NET AJAX, który jest opisany w An Introduction to JavaScript Object Notation (JSON) in JavaScript and .NET:

na przykład, ASP.NET AJAX Microsoftu korzysta ani z desc żebrowane konwencje . Zamiast tego koduje wartości .NET DateTime jako ciąg JSON, , gdzie treść ciągu to/Date (ticks)/i gdzie ticks reprezentuje milisekundy od epoki (UTC). 29 listopada 1989, 4:55:30, w UTC jest zakodowany jako "\/Date (628318530718) \ /".

Jedyną różnicą jest to, że mają format /Date(ticks)/ i nie \/Date(ticks)\/.

Musisz wyodrębnić liczbę z nawiasów. Podzielenie tego przez 1000 podaje liczbę w sekundach od 1 stycznia 1970.

Poniższy kod pokazuje, jak można to zrobić. Jest on realizowany jako na "failable wygody inicjatora" dla 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 
     } 
    } 
} 

Przykład użycia (z datą ciąg):

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

Daje wyjście

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

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

Przykład:

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

@Martin to rozszerzenie kończy się niepowodzeniem dla wartości typu: "/ Date (1479119050805 + 0300) /" ponieważ metoda Double init o milisekundach nie może zwrócić podwójnego dla wartości 1479119050805 + 0300 ze względu na znak plusa, jeśli uda ci się obsłużyć w tym przypadku prosimy o udostępnienie kodu tutaj – JAHelia

+1

@JAHelia: Zajrzyj na http://stackoverflow.com/a/33166980/1187415 dla nowszej wersji, która czyta daty JSON z lub bez przesunięcia strefy czasowej. –

+1

@Martin, który jest niesamowity, dzięki za fajne rozszerzenie – JAHelia

1

To wygląda jak uniksowy znacznik czasu: 12.01.2015 @ 6:14 pm (UTC) [Zgodnie http://www.unixtimestamp.com/index.php]

można przekonwertować go do obiektu NSDate pomocą konstruktora NSDate (timeIntervalSince1970: unixTimestamp)

+0

A jak dostaję czas na tę zmienną? –

2

Dodanie na co inni pod warunkiem, wystarczy utworzyć metodę użytkowej w klasie poniżej:

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 
} 

Następnie można wywołać tej metody w swojej powodzeniem wrócił, parsował obiekt JSON, jak poniżej:

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

Albo można zignorować metodę użytkową oraz kod rozmówcy powyżej całkowicie i po prostu to zrobić:

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

I to powinno działać!

+0

Pytanie dotyczy parsowania łańcucha takiego jak '"/Date (1420420409680)/"' –

1

do konwersji JSON String na bieżąco & Czas Swift 3.0 Korzystanie poniższy kod: -

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

gdzie checkInTimewill być Twój String.Hope pomoże ktoś

+0

Pytanie dotyczy parsowania ciągu typu '"/Date (1420420409680)/"' –