在Vapor 3应用程序中,我有一个Event
模型,该模型具有属性startDate: Date
和endDate: Date
。
现在,我想知道如何在POST请求中传递这些日期值。在邮递员中,我在x-www-form-urlencoded
中尝试了以下操作:
startDate -> 2019-03-14
这将返回以下错误:
无法转换为
Double
:str(\“ 2019-03-14 \”)
显然,Date
变成了Double
。
因此,我需要传递什么值?
我知道,我可以在Postman中插入{{$timestamp}}
,但是1)在Postman之外使用API时,这不能回答我的问题; 2)这不允许我输入其他日期比现在。
答案 0 :(得分:1)
我不确定x-www-form-urlencoded
是因为我测试了它,并且如果我以0
的形式发送日期,它会将其解码为2001-01-01 00:00:00 +0000
,以为肯定是1970-01-01 00:00:00 +0000
。
但是使用JSON有效负载,您可以灵活地进行操作,因为您可以根据需要提供JSONDecoder
配置。
struct Payload: Content {
var date: Date
}
router.post("check") { req throws -> Future<String> in
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .secondsSince1970 // choose it for unix-timestamp
return try req.content.decode(json: Payload.self, using: decoder).map { p in
return String(describing: p.date)
}
}
router.post("check") { req throws -> Future<String> in
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
formatter.timeZone = TimeZone(secondsFromGMT: 0)
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(formatter) // custom date formatter
return try req.content.decode(json: Payload.self, using: decoder).map { p in
return String(describing: p.date)
}
}
因此,对于unix时间戳,您应该发送从1970年开始的秒,例如0
将被解码为1970-01-01 00:00:00 +0000
。
对于上述自定义格式,您应该发送2018-01-01 00:00:00
之类的日期以将其解码为2018-01-01 00:00:00 +0000
extension ContentContainer where M: Request {
func decodeJson<D>(_ payload: D.Type) throws -> Future<D> where D: Decodable {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
formatter.timeZone = TimeZone(secondsFromGMT: 0)
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(formatter)
return try decode(json: payload, using: decoder)
}
}
这样您就可以像这样解码有效载荷
router.post("check") { (req) throws -> Future<String> in
return try req.content.decodeJson(Payload.self).map { p in
return String(describing: p.date)
}
}
答案 1 :(得分:1)
因此,这里的问题在于,默认情况下,Date
实例使用自2001年1月1日以来的时间间隔进行解码。Vapor使用的URL form decoder不支持不同的日期策略,例如{ {1}}目前正在执行,因此您必须以其他方式进行解码。这里有一些我可以提出的想法:
手动实现JSONDecoder
和Event.init(from:)
方法。只是为了确保您不破坏Fluent编码,您可能必须添加一些额外的逻辑,但这应该可以工作。这是一个示例:
.encode(to:)