2014-08-04 2 views
3

У меня есть таблица в MySQL.Проблемы с часовым поясом с MySQL и clj-time

create table demo (theDate datetime);

вставить две даты, один в летнее время, один нет.

(require '[clj-time.core :as t]) 
(require '[clj-time.coerce :as coerce]) 
(require '[korma.core :as k]) 

(k/insert :demo (values {:theDate (coerce/to-sql-date (t/date-time 2014 01 01))})) 
(k/insert :demo (values {:theDate (coerce/to-sql-date (t/date-time 2014 06 01))})) 

От моего клиента MySQL это выглядит как правильные значения уместились:

mysql> select * from demo; 
+---------------------+ 
| theDate    | 
+---------------------+ 
| 2014-01-01 00:00:00 | 
| 2014-06-01 00:00:00 | 
+---------------------+ 

Когда я выбираю с Кормой (я не представляю Корма делает что-либо отношение сверху JDBC), Я получаю разницу в часовом поясе в дате отсутствия летнего времени.

=> (k/select :demo) 
[{:theDate #inst "2014-01-01T00:00:00.000000000-00:00"} 
{:theDate #inst "2014-05-31T23:00:00.000000000-00:00"}] 

И когда я выбираю даты:

(map #(-> % :theDate coerce/from-sql-date t/month) (k/select :demo)) 
(1 5) 

В то время как я ожидал бы получить (1 6) (я сознательно поставить даты на месяц границы для иллюстрации). То же самое происходит, когда я использую date, а не datetime Тип MySQL.

Что мне не хватает? Как вставить [(t/date-time 2014 01 01) (t/date-time 2014 06 01)] и вернуться (1 6)?

+0

Вы должны быть хранящей временные метки, UTC, и преобразование их в локальный, когда вам нужно, чтобы отобразить их. –

+0

или хранить unix timestamp как долго – edbond

ответ

10

Результат, полученный вами, зависит от часовой пояс по умолчанию для JVM. Вы можете исправить это с помощью любого механизма, который дает вам операционная система хоста. Но по моему опыту, как правило, лучше принудительно использовать JVM для известного значения.

Это достижение со свойством в командной строке или в Leiningen project.clj

:jvm-opts ["-Duser.timezone=UTC"] 
+1

Спасибо вам большое! – Joe

+0

_to добавить некоторые ключевые слова google/back link_: моя проблема заключалась в том, что я буду хранить UTC в MySQL db, и я бы запросил его в clojure, это было бы внезапно локальным временем, и никакое принуждение не получило бы его интерпретируется как UTC. Я попросил сопровождающих 'clj-time' оставить примечание об этом в своих документах где-нибудь: https://github.com/clj-time/clj-time/issues/233 –

0

Мы столкнулись с этим, а также и в конечном итоге с помощью Корме-х exec-raw и указания:

at time zone 'utc' as theData 

на самом деле получить обратно правильный часовой пояс.

+0

Спасибо! Ответ sw1nn решил, но я думал, что 'exec-raw' не работает с выборами? Я получаю 'SQLException Не могу выполнить executeUpdate() для SELECTs com.mysql.jdbc.SQLError.createSQLException (SQLError.java:1074)' когда I '(k/exec-raw" select * from demo ")'. – Joe

Смежные вопросы