2015-02-06 4 views
4

Я рассмотрел следующий вопрос: How to add days to current date in clojure.Как добавить дни к дате в Clojure

Однако я очень новичок в Clojure, и я застрял в следующем сценарии. Я получаю временную метку в строчном формате. Поэтому я разборе его с помощью следующих действий:

(.parse (java.text.SimpleDateFormat. "yyyy-MM-dd") date) 

Который дает мне результат, который выглядит следующим образом:

#inst "2015-02-13T00:20:00.000-00:00" 

Как добавить сказать 90 дней до этого, а затем преобразовать его обратно в формат строки ? Я попробовал это на основе приведенной выше ссылке:

(java.util.Date. (+ (* 7 86400 1000) 
        (.parse (java.text.SimpleDateFormat. "yyyy-MM-dd") date))) 

Который дал мне следующую ошибку:

ClassCastException java.util.Date cannot be cast to java.lang.Number clojure.lang.Numbers.add 
+0

Лучше использовать [Joda Time] (http://www.joda.org/ joda-time /) вместо стандартных библиотек даты и времени Java. Существует также оболочка Clojure, [clj-time] (https://github.com/clj-time/clj-time). См. Эту статью [IBM Developer Works article] (http://www.ibm.com/developerworks/java/library/j-jodatime/index.html#N100BA) для получения более подробной информации о том, почему Joda Time является лучшим вариантом. –

ответ

3

parse возвращающую java.util.Date, ошибка вы видите говорит вам, что вы не можете бросить Date до Number. Вы можете использовать getTime, чтобы получить миллисекунды в Date:

(java.util.Date. (+ (* 7 86400 1000) 
       (.getTime (.parse (java.text.SimpleDateFormat. "yyyy-MM-dd") date)))) 

Это потенциально добавляет 7 дней до даты. Если вы хотите потенциально добавьте 90 дней, вам нужно заменить 7 на 90, вот так: (* 90 86400 1000).

Вы можете также использовать java.util.Calendar:

(let [cal (Calendar/getInstance) 
     d (.parse (java.text.SimpleDateFormat. "yyyy-MM-dd") date)] 
    (doto cal 
    (.setTime d) 
    (.add Calendar/DATE 90) 
    (.getTime))) 

Или еще лучше, clj-time:

(require '[clj-time.core :as t]) 
(require '[clj-time.format :as f]) 

(t/plus (f/parse (f/formatters :year-month-day) date) 
     (t/days 90)) 
+0

О, извините за 7 и 90 дней. Это была опечатка. – newbie

+3

«Это добавляет 7 дней к дате» --- если только каждый из них точно равен «86400» секунд, что не всегда так – zerkms

+0

@zerkms, вы правы, я отредактировал ответ. Благодаря! –

1

Я бы не рекомендовал использовать дату и время унаследованного API в новом коде, если вы можете избежать его ,

Java 8 принес новый API для даты, с которой вы можете выразить эту проблему элегантно:

(let [date-format java.time.format.DateTimeFormatter/ISO_LOCAL_DATE] 
    (.. (java.time.LocalDate/parse "2015-02-13" date-format) 
     (plusDays 90) 
     (format date-format))) 

или даже, принимая все ярлыки:

(-> (java.time.LocalDate/parse "2015-02-13") (.plusDays 90) str) 
1

clj-time имеет from-now и ago:

(require '[clj-time.core :refer [days from-now]]) 

(-> 90 days from-now) 

=> #object[org.joda.time.DateTime 0x4d8bcee3 "2017-01-11T16:03:40.067Z"]

(require '[clj-time.core :refer [hours ago]]) 

(-> 7 hours ago) 

=> #object[org.joda.time.DateTime 0x3eef2142 "2016-10-13T09:19:01.246Z"]

Доступные PeriodType определения: years, months, weeks, days, hours, minutes, seconds.


Полученные в результате Joda DateTime объектов можно легко манипулировать, например, до эпохи UNIX в миллисекундах:

(require '[clj-time.coerce :as coerce]) 

(coerce/to-long (-> 90 days from-now)) 

=> 1484150620067

0

Это решение возвращает java.util.Date:

(defn add-days-to-instant [num-days ^java.util.Date d] 
    (.getTime (let [cal (Calendar/getInstance)] 
       (doto cal 
       (.setTime d) 
       (.add Calendar/DATE num-days)))))