Привет,
Раньше эта библиотека использовалась для простого преобразования дат без необходимости указывать функцию преобразования даты (по крайней мере, это поведение, которое я видел).
Так например
public private(set) var myDate:Date?
public fund mapping(map: Map) {
myDate <- map["my_date"]
}
Учитывая, что дата имеет формат «2016-12-09T13: 37: 27.262Z», она преобразует эту дату должным образом без необходимости указывать, что это действительно дата.
Моя текущая модель по какой-то причине не может правильно проанализировать дату. Я пробовал оба примера, приведенные в read-me, я рассмотрел "закрытые" проблемы, касающиеся форматирования даты, и я также попытался использовать их примеры ... все равно не повезло.
Я пробовал эти преобразования даты
Мой модульный тест ...
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())
}
}
который производит ...
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\"}")
Ясно, что дата, которую я даю, не 1970 ... и дата, указанная выше, действительно является датой в формате ISO. Я использую сервер Express / Mongo, и я просто использую javascript-вызов Date.now для генерации даты. Кроме того, схема в модели Mongo имеет тип Date.
Вот моя модель поездки
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())
}
}
Опять же, как указано выше, я пробовал использовать как DateTransform (), так и ISO8601DateTransform ().
Если я использую функцию DateTransform, мой модульный тест «пройдет», потому что свойство date больше не будет равным нулю, но это будет дата 1970 года, что неверно.
Если я использую ISO8601DateTransform, свойство равно нулю, и модульный тест завершится неудачно, потому что ожидалось, что дата не будет нулем.
Раньше я просто указывал, что это свойство было «датой», и оно все преобразует правильно, без необходимости специально устанавливать кортеж DateTransform для сопоставления. Я точно не знаю, что делаю здесь неправильно.
==== Обновлен, чтобы он выглядел красивее =====
Так что я считаю, что, возможно, решил свою проблему ...
Я до сих пор не знаю, почему встроенный форматировщик даты ISO не работает, но я создал свой
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!)
}}
похоже, это работает нормально, теперь модульные тесты проходят с действительными датами.
Просто чтобы добавить к этому. Я не мог заставить вышеперечисленное решение работать, но оно действительно направило меня в правильное русло, и я так ценю его. Я внес некоторые изменения, и это работает для меня.
//
// 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
}
}
Другое исправление:
https://forums.swift.org/t/iso8601dateformatter-fails-to-parse-a-valid-iso-8601-date/22999/12
открытый класс ISODateTransform: TransformType {
public typealias Object = Date
общедоступный typealias 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
}
}
Самый полезный комментарий
Так что я считаю, что, возможно, решил свою проблему ...
Я до сих пор не знаю, почему встроенный форматировщик даты ISO не работает, но я создал свой
похоже, это работает нормально, теперь модульные тесты проходят с действительными датами.