如何转换clojure';s#将文字量设置为等效的java.time类型?
我使用库将记录持久化到PostgreSQL表中。如下所示,这些值是LocalDate实例和Instant实例。SQL列的类型分别为DATE和TIMESTAMPTZ 需要从Java->SQL映射如何转换clojure';s#将文字量设置为等效的java.time类型?,clojure,java-time,clojure-next.jdbc,Clojure,Java Time,Clojure Next.jdbc,我使用库将记录持久化到PostgreSQL表中。如下所示,这些值是LocalDate实例和Instant实例。SQL列的类型分别为DATE和TIMESTAMPTZ 需要从Java->SQL映射next.jdbc.date-time命名空间,如文档中所述 {:id 7, :trade_date #object[java.time.LocalDate 0x6b751cb1 2020-12-22], :created_at #object[java.time.Instant 0x3add5e17 20
next.jdbc.date-time
命名空间,如文档中所述
{:id 7, :trade_date #object[java.time.LocalDate 0x6b751cb1 2020-12-22], :created_at #object[java.time.Instant 0x3add5e17 2020-12-22T11:41:07.557790Z]}
当我读回记录时(SQL->Clojure),表示如下
{:id 7, :trade_date #inst "2020-12-21T18:30:00.000-00:00", :created_at #inst "2020-12-22T11:41:07.557790000-00:00"}
那么它们被读回为#inst literals?
我希望它们作为java.time类型返回。还请注意,LocalDate似乎转换为UTC时间戳。这是我到目前为止发现的
; inst -> Instant
=> (.toInstant #inst "2020-12-22T11:41:07.557790000-00:00")
#object[java.time.Instant 0x312cc79e "2020-12-22T11:41:07.557Z"]
; inst -> LocalDate
=> (-> #inst "2020-12-21T18:30:00.000-00:00"
#_=> .toInstant
#_=> (ZonedDateTime/ofInstant (ZoneId/of "UTC"))
#_=> (.withZoneSameInstant (ZoneId/systemDefault))
#_=> (.toLocalDate))
#object[java.time.LocalDate 0x44048462 "2020-12-22"]
这似乎并不简单。有更好的办法吗
参考资料:
在和1小时后根据答案拼凑而成。那没用 结果是next.jdbc使用java.sql.*类型重新构造记录,这些类型恰好在REPL中作为#inst文本打印出来 调用
(.toInstant sql date实例)
时出现异常(这是按设计的)。然而,有了这一点信息,就很容易实现最终的结果。通过此映射器运行返回的映射向量
(defn mapSqlToTimeTypes [map-with-sql-types]
(reduce (fn [return-map [k, v]]
(cond
(instance? java.sql.Timestamp v) (assoc return-map k (.toInstant v))
(instance? java.sql.Date v) (assoc return-map k (.toLocalDate v))
:else (assoc return-map k v)))
{}
map-with-sql-types))
因此#inst只是一个带标记的文本,默认情况下,它的底层类型是java.util.Date
(定义我的指令“2018-03-28810:48:00.000”)
(=java.util.Date(类my inst))
;=> 真的
但是您或任何库都可以更改#inst的默认读取器,因为数据读取器是一个动态变量。因此,在任何时间点,根据您使用的库的不同#inst可能会生成不同的底层类型
我自己还没有使用过nex.jdbc,但我认为您需要调用读取为即时或读取为本地函数。看见
同时签出clj时间Clojure库。还可以查看java.time的clojure.java-time包装器作为@Gishu答案的一个小简化,使用
postwark
进行这种类型的数据转换通常非常方便。要将所有关键字转换为普通字符串,例如:
(defn walk-keywords->strings
"Recursively walks form, converting all keywords to strings. "
[form]
(walk/postwalk (fn [item]
(if (keyword? item)
(t/kw->str item)
item))
form))
这在处理web请求和响应时特别有用,这些请求和响应通常是深度嵌套的映射和向量。这些选项都完成了一半的工作-我的表有UTC时间戳和本地日期。因此,我将通过这些方法调用获取Instant或LocalDate。你能给我一些链接让我更好地理解这个词吗。。我读过几本Clojure的书,但不记得有介绍过这一点。你不应该使用
clj time
库,因为它已经过时了!而是使用java.time
interop。这里还有帮助函数:@AlanThompson,噢,谢谢。我还是个老学生。Gishu,读一下clojure reader的页面