I have a Vapor 3 API up on Heroku. Unfortunately, it's not handling dates correctly. Originally, I thought I could just treat dates like strings for simplicity in Vapor, like so:
struct MyModel {
var time: String?
}
But whenever I fetch MyModel
s from the db and return it, the time
key doesn't appear at all (while other keys and values have no problems). I thought I might be able to just change time
's type to Date
, but that resulted in the same thing, and I've already used ContentConfig
to set the JsonEncoder.dateEncodingStrategy
to .iso8601
(again, no luck – perhaps because dateEncodingStrategy
only supports millis on Linux, which is what Heroku uses?).
How do I convert Postgres dates to ISO8601 in json with Vapor 3 running on Heroku?
Got it working! Just changed the properties to Date
s, and manually converted request query parameters to Date
s as well (for use in filter
calls). So, a little more by hand than most things in Vapor 3, but not terrible.
Eg my model looks like this now:
struct MyModel {
var time: Date?
}
And then when I try to filter by date I do something like this:
var builder = MyModel.query(on: req)
if let afterString: String = try? self.query.get(String.self, at: "after") {
let afterDate: Date? = DateFormatter.iso8601Full.date(from: afterString)
builder = builder.filter(\.time > afterDate)
}
where after
is a url parameter, and DateFormatter.iso8601Full
is my iso8601 date formatter. Then when I'm returning an array of MyModel
s in a response, I map the array to an array of MyModelResponseObject
s which look like this:
struct MyModelResponseObject {
var time: String?
}
by doing something like this:
myModelsFuture.all().map(to: [MyModelResponseObject].self, { (myModels) -> [MyModelResponseObject] in
return myModels.map { it in
return MyModelResponseObject(time: DateFormatter.iso8601Full.string(from: it.time ?? Date.init(timeIntervalSince1970: 0)))
}
}
So basically I'm manually converting the dates into the format that I want when returning them in JSON.