Fork me on GitHub
#java
<
2021-11-02
>
West15:11:40

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

(ns scratchpad
  (:import java.text.SimpleDateFormat
           (java.time Instant Locale ZoneOffset)
           java.time.format.DateTimeFormatter
           java.util.Date))

(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
    (cond
      (instance? Date t)
      (.format (new SimpleDateFormat
                    pat
                    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)]])
Expected:
=> [["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"]]
Actual:
=> [["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 https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/format/DateTimeFormatter.html, "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 https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/format/TextStyle.html#FULL 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.

West13:11:08

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 🙂

West15:11:54

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

Daniel Craig15:11:25

oh yeah I see what you mean

West15:11:26

Nice name by the way @danielmartincraig