Objectmapper: Seltsames Verhalten der Datumstransformation

Erstellt am 14. Dez. 2016  ·  3Kommentare  ·  Quelle: tristanhimmelman/ObjectMapper

Hallo,

Vorher hat diese Bibliothek nur Daten transformiert, ohne eine Datumstransformationsfunktion angeben zu müssen (zumindest ist dies das Verhalten, das ich gesehen habe).

Also zum Beispiel

public private(set) var myDate:Date?

public fund mapping(map: Map) {
  myDate <- map["my_date"]
}

Da das Datum das Format "2016-12-09T13:37:27.262Z" hat, würde es dieses Datum richtig umwandeln, ohne dass ich angeben müsste, dass es sich tatsächlich um ein Datum handelt.

Mein aktuelles Modell kann das Datum aus irgendeinem Grund nicht richtig analysieren. Ich habe beide Beispiele in der Readme-Datei ausprobiert, ich habe mir die "geschlossenen" Probleme bezüglich der Datumsformatierung angesehen und ich habe auch versucht, ihre Beispiele zu verwenden ... immer noch kein Glück.

Ich habe diese Datumstransformationen ausprobiert

  1. DateTransform()
  2. ISO-Datumstransformationsfunktion

Mein Unit-Test...

class TripTests: XCTestCase {
    func testInflateTestObjectFromJSON() {
        var tripObj = [String:AnyObject]()
        tripObj["_id"] = "123" as AnyObject?
        tripObj["dropoff_time"] = "2016-12-09T13:37:27.262Z" as AnyObject?
        let trip = Trip(JSON: tripObj)
        XCTAssertNotNil(trip?.id)
        XCTAssertNotNil(trip?.dropoffTime)
        print(trip?.pickupTime)
        print(trip?.dropoffTime)
        dump(trip?.toJSONString())
    }
}

was produziert...

Optional(1970-01-01 00:33:36 +0000)
Optional(1970-01-01 00:33:36 +0000)
▿ Optional("{\"dropoff_time\":2016,\"pickup_time\":2016,\"_id\":\"123\"}")

Offensichtlich ist das Datum, das ich angebe, nicht 1970 ... und das obige Datum ist tatsächlich ein ISO-formatiertes Datum. Der Server, den ich betreibe, ist Express/Mongo und ich verwende einfach den JavaScript-Aufruf Date.now, um ein Datum zu generieren. Außerdem ist das Schema im Mongo-Modell vom Typ 'Datum'.

Hier ist mein Trip-Modell

import Foundation
import ObjectMapper

public class Trip : Mappable {
    public private(set) var id: String?
    public var pickupTime:Date?
    public var dropoffTime:Date?
    public var completed:Bool?
    public private(set) var createdAt:Date?
    public private(set) var updatedAt:Date?


    public init(captain: User?, passenger: User?) {
        self.captain = captain
        self.passenger = passenger
    }

    public required init?(map: Map) {

    }

    public func mapping(map: Map) {
        id <- map["_id"]
        pickupTime <- (map["pickup_time"], DateTransform())
        dropoffTime <- (map["dropoff_time"], DateTransform())
        completed <- map["completed"]
        updatedAt <- (map["updated_at"], DateTransform())
        createdAt <- (map["created_at"], DateTransform())
    }
}

Auch hier habe ich, wie oben erwähnt, versucht, sowohl DateTransform() als auch ISO8601DateTransform() zu verwenden.

Wenn ich die DateTransform-Funktion verwende, wird mein Komponententest "bestanden", da die Datumseigenschaft nicht mehr Null ist, jedoch das Datum von 1970 ist, das nicht korrekt ist.

Wenn ich ISO8601DateTransform verwende, ist die Eigenschaft nil und der Komponententest schlägt fehl, da erwartet wurde, dass das Datum nicht nil ist.

Vorher würde ich nur angeben, dass die Eigenschaft ein "Datum" ist und alles korrekt transformiert wird, ohne dass ich speziell ein DateTransform-Tupel für die Zuordnung festlegen muss. Ich weiß nicht genau was ich hier falsch mache.

==== Aktualisiert, damit es schöner aussieht =====

Hilfreichster Kommentar

Also ich glaube, ich habe mein Problem vielleicht selbst gelöst...

Ich weiß immer noch nicht, warum der eingebaute ISO-Datumsformatierer nicht funktioniert, aber ich habe meinen eigenen erstellt

import Foundation
import ObjectMapper
open class ISODateTransform: TransformType {
    public typealias Object = Date
    public typealias JSON = String

    public init() {}

    public func transformFromJSON(_ value: Any?) -> Date? {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"

        guard let strValue = value as? String else { return nil }
        return formatter.date(from: strValue)
    }

    public func transformToJSON(_ value: Date?) -> String? {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
        guard value != nil else { return nil }
        return formatter.string(from: value!)
    }}

dies scheint gut zu funktionieren, Unit-Tests werden jetzt mit gültigen Daten durchgeführt.

Alle 3 Kommentare

Also ich glaube, ich habe mein Problem vielleicht selbst gelöst...

Ich weiß immer noch nicht, warum der eingebaute ISO-Datumsformatierer nicht funktioniert, aber ich habe meinen eigenen erstellt

import Foundation
import ObjectMapper
open class ISODateTransform: TransformType {
    public typealias Object = Date
    public typealias JSON = String

    public init() {}

    public func transformFromJSON(_ value: Any?) -> Date? {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"

        guard let strValue = value as? String else { return nil }
        return formatter.date(from: strValue)
    }

    public func transformToJSON(_ value: Date?) -> String? {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
        guard value != nil else { return nil }
        return formatter.string(from: value!)
    }}

dies scheint gut zu funktionieren, Unit-Tests werden jetzt mit gültigen Daten durchgeführt.

Nur um dies zu ergänzen. Ich konnte die obige Lösung nicht zum Laufen bringen, aber sie hat mich in die richtigen Richtungen gelenkt, die so sehr geschätzt werden. Ich habe einige Optimierungen vorgenommen und das funktioniert für mich.

//
//  ISODateTransform.swift
//

import Foundation
import ObjectMapper

open class ISODateTransform: TransformType {
    public typealias Object = Date
    public typealias JSON = String

    public init() {}

    public func transformFromJSON (_ value: Any?) -> Date? {
        guard let datestring = value as? String else { return nil }
        let isoFormatter = ISO8601DateFormatter()
        let date = isoFormatter.date(from: datestring)!

        return date
    }

    public func transformToJSON(_ value: Date?) -> String? {
        let isoFormatter = ISO8601DateFormatter()
        let string = isoFormatter.string(from: value!)

        return string
    }
}

Ein weiterer Fix:
https://forums.swift.org/t/iso8601dateformatter-fails-to-parse-a-valid-iso-8601-date/22999/12

offene Klasse ISODateTransform: TransformType {
public typealias Object = Date
öffentlicher Typalias JSON = String

public init() {}

public func transformFromJSON (_ value: Any?) -> Date? {
    guard let datestring = value as? String else { return nil }
    let isoFormatter = ISO8601DateFormatter()
    //Critical Fix
    isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
    let date = isoFormatter.date(from: datestring)!

    return date
}

public func transformToJSON(_ value: Date?) -> String? {
    let isoFormatter = ISO8601DateFormatter()
    //Critical Fix
    isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
    let string = isoFormatter.string(from: value!)
    return string
}

}

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

pcompassion picture pcompassion  ·  3Kommentare

Dbigshooter picture Dbigshooter  ·  4Kommentare

VictorAlbertos picture VictorAlbertos  ·  3Kommentare

Sajjon picture Sajjon  ·  4Kommentare

maksTheAwesome picture maksTheAwesome  ·  4Kommentare