Fork me on GitHub

Did I just discover a bug in the java standard library?

(ns scratchpad
  (:import java.text.SimpleDateFormat
           (java.time Instant Locale ZoneOffset)

(def pattern-1 "EEE, dd MMM yyyy HH:mm:ss ZZZZ")
(def pattern-2 "EEE, dd MMM yyyy HH:mm:ss ZZ")

(defn format-time [t pat]
  (when t
      (instance? Date t)
      (.format (new SimpleDateFormat
                    Locale/ENGLISH) t)
      (instance? Instant t)
      (.format (DateTimeFormatter/ofPattern pat Locale/ENGLISH)
               (.atOffset t ZoneOffset/UTC)))))

(let [inst (Instant/now)
      date (Date/from inst)]
  [[(format-time inst pattern-1) (format-time date pattern-1)]
   [(format-time inst pattern-2) (format-time date pattern-2)]])
=> [["Tue, 02 Nov 2021 05:52:02 +0000" "Tue, 02 Nov 2021 05:52:02 +0000"]
    ["Tue, 02 Nov 2021 05:52:02 +0000" "Tue, 02 Nov 2021 05:52:02 +0000"]]
=> [["Tue, 02 Nov 2021 05:52:02 GMT"   "Tue, 02 Nov 2021 05:52:02 +0000"]
    ["Tue, 02 Nov 2021 05:52:02 +0000" "Tue, 02 Nov 2021 05:52:02 +0000"]]
According to the, "Z" in a pattern should not yield a localized zone offset.

Colin P. Hill12:11:47

Looks right to me (emphasis mine) > Offset Z: This formats the offset based on the number of pattern letters. One, two or three letters outputs the hour and minute, without a colon, such as '+0130'. The output will be '+0000' when the offset is zero. Four letters outputs the form of localized offset, equivalent to four letters of Offset-O. The output will be the corresponding localized offset text if the offset is zero. Five letters outputs the hour, minute, with optional second if non-zero, with colon. It outputs 'Z' if the offset is zero. Six or more letters throws IllegalArgumentException.


Damn, that makes me look dumb. Yet again I’m defeated by just skimming and not reading.

Daniel Craig15:11:43

java.util.Date is cursed

Daniel Craig15:11:25

easily my least favorite class 🙂


I discovered this while switching to the new java.time API.

Daniel Craig15:11:25

oh yeah I see what you mean


Nice name by the way @danielmartincraig