Search code examples
clojureclj-time

clj-time always returns today's date.


I have a strange problem here. I am calling dates from a database and I am attempting to show the PostgreSQL dates, formatted as "2013-01-01", to display on my site as "January 1, 2013"

I have the following code:

(ns mr.layouts
  (:require 
            [clj-time.format :as ctf]))


(def to-mdy (ctf/formatter "MMMM d, yyyy"))

(defn coerce-mdy [sd]
  (ctf/unparse to-mdy (ctf/parse sd)))

The call to the database looks like:

(layouts/coerce-mdy startdate)

The above code does what I want if I test it from the REPL:

mr.handler=> (use 'mr.layouts)
nil
mr.handler=> (require '[clj-time.format :as ctf])
nil
mr.handler=> (coerce-mdy "2012-01-01")
"January 1, 2012"
mr.handler=> (coerce-mdy "2014-10-04")
"October 4, 2014"
mr.handler=> 

But what I am getting on the webpage is "September 1, 2013" (today as of this writing) and no other dates. I don't have "2013-09-01" in the database.

I've returned the raw date-value from the data base from (coerse-mdy) and it returns the correct date, so the closest I've been able to isolate this issue is in either (to-mdy) or (coerce-mdy).

So far, I've tried moving the function to the local namespace and using localized let values.


Solution

  • When using clj-time with a database, I've found that I need to use the functions to-sql-date and from-sql-date in the coerce namespace (source here: https://github.com/clj-time/clj-time/blob/master/src/clj_time/coerce.clj)

    This is because, as @noisesmith mentioned in his comment, most clojure sql libraries will give a date object (specifically, a java.sql.Date) for a date field in the db. This needs to be treated slightly differently from a string in order to get something that plays nice with clj-time.

    Assuming your date is indeed a java.sql.Date, the following should do the trick...

    (ns mr.layouts
      (:require [clj-time.format :as ctf]
                [clj-time.coerce :as coerce]))
    
    (def to-mdy (ctf/formatter "MMMM d, yyyy"))
    
    (defn coerce-mdy [sd]
      (ctf/unparse to-mdy (coerce/from-sql-date sd)))