Clojure / JDBC / Postgresql:我试图从字符串更新postgresql中的时间戳值,得到一个错误

时间:2012-02-16 04:27:00

标签: postgresql jdbc clojure timestamp

将clojure jdbc库与postgresql一起使用。我在postgresql中有一个带有时间戳列“created_at”的表“xxx”,我有一个包含正确格式的日期的字符串。插入失败:

(require '[clojure.java.jdbc :as sql])

(sql/with-connection *db*
  (sql/insert-record :xxx {:created_at "Thu Feb 09 10:38:01 +0000 2012"}))

这是错误:

org.postgresql.util.PSQLException: ERROR: column "created_at" 
is of type timestamp with time zone but expression is of type character varying

所以我理解postgres需要一个时间戳值,但是如何将日期的字符串表示转换为postgres会接受的内容? java.util.Date也失败了,我在clojure postgres库上找不到任何文档。

谢谢!

1 个答案:

答案 0 :(得分:16)

您需要传入java.sql.Timestamp个实例。要使用clj-time,一个用于Clojure的Joda-Time包装库将您的字符串解析为一个字符串,您可以执行以下操作:

(require '(clj-time [format :as timef] [coerce :as timec])

(->> "Thu Feb 09 10:38:01 +0000 2012"
     (timef/parse (timef/formatter "EEE MMM dd HH:mm:ss Z yyyy"))
     timec/to-timestamp)

然后可以通过JDBC将返回的值传递给PostgreSQL。

如果您以其他字符串格式获取日期并将其转换为此日期,则可以跳过转换并为原始表示提供适当的格式化程序。默认情况下,clj-time.format/formatters地图中有相当多的可用内容,比如REPL中的(clj-time.format/show-formatters),以查看带有示例的列表。此外,clj-time.coerce/from-string按顺序尝试所有默认格式化程序,返回第一个后续解析的值(如果没有则返回nil)。如果您要将日期作为java.util.Datelong获取,请在同一名称空间中查看from-datefrom-long

如果您决定使用[clj-time "0.3.6"],请在project.clj中使用clj-time作为依赖关系说明符。

或者,您可以使用其他方式将时间戳字符串解析为java.sql.Timestamp; Timestamp本身可以解析不同的字符串表示形式:

(java.sql.Timestamp/valueOf "2004-10-19 10:23:54")

clj-time是在Clojure中处理日期和时间的最明智的方式,所以它可能值得你花时间。