Don't use clj-time, use clojure.java-time instead
Tags: clojure, java
Published: 2024-01-10 03:41:00

---
title: Don't use clj-time, use clojure.java-time instead
published: false
tags: clojure, java
cover_image: https://pics.craiyon.com/2023-08-03/69f5d433df1c4a7e9e5a7113ee6f7bd0.webp
published: true
---

## clj-time

> A date and time library for Clojure, wrapping the Joda Time library. DEPRECATED 

A big warning sign on a project's README should have deterred anyone from using the library but my goldfish memory can't remember why

I have used `clj-time` in my previous project before. I did not recall anything bad about it. Time, just like a logger, in Java has a long history. For the most part, when you have to deal with time, you google around, find which method to call, and move on. 

Until this one fine afternoon, I saw lots of new error logs. The stacktrace looks like this:
```
#error {
 :cause "The datetime zone id 'America/Ciudad_Juarez' is not recognised"
 :via
 [{:type java.lang.IllegalArgumentException
   :message "The datetime zone id 'America/Ciudad_Juarez' is not recognised"
   :at [org.joda.time.DateTimeZone forID "DateTimeZone.java" 234]}]
 :trace
 [[org.joda.time.DateTimeZone forID "DateTimeZone.java" 234]
  [clj_time.core$time_zone_for_id invokeStatic "core.clj" 411]
  [clj_time.core$time_zone_for_id invoke "core.clj" 406]
  [app.domain.hotel$time_zone invokeStatic "hotel.clj" 129]
   ...
  [clojure.core$reduce1 invokeStatic "core.clj" 944]
  [clojure.core$set invokeStatic "core.clj" 4101]
  [org.eclipse.jetty.util.thread.QueuedThreadPool$Runner run "QueuedThreadPool.java" 1034]
  [java.lang.Thread run nil -1]]}

```

It turns out a partner system sends an update with timezone record like 'America/Ciudad_Juarez'

Wait, what is wrong with that time zone? Let's fire up a REPL and check that:

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

(time/time-zone-for-id "America/Ciudad_Juarez')
Execution error (IllegalArgumentException) at org.joda.time.DateTimeZone/forID (DateTimeZone.java:234).
The datetime zone id 'America/Ciudad_Juarez' is not recognised
```
Uh oh, wait that can't be right. How about:
```
(time/time-zone-for-id "America/Chicago")
;; => #<org.joda.time.tz.CachedDateTimeZone@23749549 America/Chicago>
```

That one is fine. Quick Google-ing tells me Ciudad Juarez was only [recently added to a list of timezones back in 2022](https://mm.icann.org/pipermail/tz-announce/2022-November/000076.html)

Okay, how do we upgrade our Clojure / Java system with that latest timezone? Does Java reads the timezone database somewhere? That leads me to [Oracle TZUpdater](https://www.oracle.com/java/technologies/javase/tzupdater-readme.html) app

Fair enough. Let's update our Dockerfile:
```
FROM debian:bullseye-slim as final
RUN apt-get update && apt-get install -y curl wget unzip

ENV JAVA_HOME=/usr/local/openjdk-17

RUN wget --header "Cookie: oraclelicense=accept-securebackup-cookie" https://download.oracle.com/otn-pub/java/tzupdater/2.3.2/tzupdater-2.3.2.zip && \
    unzip tzupdater-2.3.2.zip && \
    $JAVA_HOME/bin/java -jar tzupdater-2.3.2/tzupdater.jar -f -l https://www.iana.org/time-zones/repository/tzdata-latest.tar.gz

ENTRYPOINT ["java", "-jar", "app-standalone.jar"]
```

Not a big deal. That should be it, right? Not too soon! Turns out [clj-time](https://github.com/clj-time/clj-time/) is a wrapper of [Joda Time](https://www.joda.org/joda-time/) and the project's README says:

> If you are using Java 8 or later, please use the built-in Java Time instead of Joda Time -- or look at clojure.java-time if you want a Clojure wrapper for that, or cljc.java-time for a thin Clojure(Script) wrapper, or juxt/tick for another cross-platform option. See Converting from Joda Time to java.time for more details about the similarities and differences between the two libraries. 

Okay so clj-time is deprecated, latest version is 0.15.2. Let's try [dm3/clojure.java-time](https://github.com/dm3/clojure.java-time). Sure enough: 

```
(jt/local-date (jt/instant) "America/Ciudad_Juarez")
;; => #<java.time.LocalDate@5bfc8967 2024-01-09>
```
It picks up the new timezone. Now why wouldn't Joda pick up the latest timezone? To be fair, Joda time does. Here is the [release report](https://www.joda.org/joda-time/changes-report.html). It bundles new [Global Tz](https://github.com/JodaOrg/global-tz) which is derived from [IANA Time Zone database](https://data.iana.org/time-zones/)

But `clj-time` wouldn't. It is marked as deprecated. Now my only option is to wholesale adopt java-time, change hundreds of lines of code, or fork clj-time and upgrade to the latest Joda time. Note to myself, pick the newer library for new project guys.