Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何转换clojure';s#将文字量设置为等效的java.time类型?_Clojure_Java Time_Clojure Next.jdbc - Fatal编程技术网

如何转换clojure';s#将文字量设置为等效的java.time类型?

如何转换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

我使用库将记录持久化到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 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的页面