【问题标题】:Clojure change date after add to postgresql添加到 postgresql 后的 Clojure 更改日期
【发布时间】:2017-06-30 02:18:02
【问题描述】:

我在使用 clojure 和 postgresql 时遇到问题。

例如,当我将“2017-06-27”插入 DB(日期格式列)时,它会保存“2017-06-26”,当我选择此结果时,返回的对象是#inst“2017-06 -28T03:00:00.000-00:00"

最奇怪的是,当我在本地机器上运行测试时会发生这种情况,因为我创建了一个 docker 设置,并且相同的代码可以完美运行。

代码如下:

(ns balances.db
  (:require [clj-time.coerce :as c]
            [clj-time.format :as f]))

; Function to convert data objects from queries to string
(defn db-to-str [date]
  (f/unparse (f/formatters :date) (c/from-sql-date date))
)

; Function to convert string to data objetcs that can be inserted in db
(defn str-to-db [date]
  (c/to-sql-date date)
)

(ns balances.operation
  (:require [clojure.java.jdbc :as jdbc]
            [balances.db :refer [db-spec]]))

(defn create-operation [accountid amount description operationdate]
  (jdbc/insert! db-spec :operations {
    :accountid accountid 
    :amount amount 
    :description description 
    :operationdate operationdate
  })
)

(ns balances.operation-test
  (:use clojure.test
        ring.mock.request
        balances.core-test)
  (:require [balances.operation :as operation]
            [balances.db :as db]))

(use-fixtures :each db/clear-db-fixture)

(deftest operation
    (testing "create operation"
      (let [op (first (operation/create-operation 1 100 "Test operation" (db/str-to-db "2017-06-27")))]
        (is (= "2017-06-27" (db/db-to-str (op :operationdate))))
      )
    )
)

在本地环境下,创建操作测试失败,返回:

expected: (= "2017-06-27" (db/db-to-str (op :operationdate)))
  actual: (not (= "2017-06-27" "2017-06-26"))

在 docker 环境中测试通过。

【问题讨论】:

    标签: postgresql clojure clj-time


    【解决方案1】:

    听起来您的本地环境与您的数据库和 docker 环境具有不同的区域设置和/或时区。

    在每个环境中打开一个 Clojure REPL 并检查 JVM 语言环境设置为:

    (str (java.util.Locale/getDefault))
    

    同时在每个环境(bash?)上打开一个终端 shell 并输入 date 以查看操作系统时区设置为什么。

    如果其中任何一个不同,那么您将知道您需要同步它们并更正至少一个 JVM 或 OS 环境以使用相同的时区和语言环境。

    【讨论】:

    • 谢谢!是它!虽然 docker date 是“...UTC...”,但 local 是“...-3...”,因此它会将 3 添加到保存日期。但是现在,我怎样才能避免这种情况呢?我想准确保存输入的日期...
    • 您需要阅读 Postgres 日期/时间规范:postgresql.org/docs/9.1/static/datatype-datetime.html。一般来说,最简单的方法是始终、始终使用 UTC 进行输入和输出,否则您将反复出现时区冲突。请注意,Postgres always 使用 UTC 存储时间戳。所有其他时区仅用于输入/输出。
    • 只是为了给其他来这里的人留下信息,通过使用“SET TIME ZONE 'UTC';”将 postgresql 时区更改为 UTC 解决了这个问题,正如 here 解释的那样,我还更改了日期列类型为“时间戳[无时区]”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-15
    • 2015-07-14
    • 1970-01-01
    • 2017-01-08
    • 1970-01-01
    • 1970-01-01
    • 2021-10-17
    相关资源
    最近更新 更多