• Stars
    star
    131
  • Rank 275,867 (Top 6 %)
  • Language
    Clojure
  • License
    MIT License
  • Created over 5 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

java.time clojure clojurescript

Clojars Project Tests build bb compatible

cljc.java-time

A Clojure(Script) library which mirrors the java.time api through kebab-case-named vars.

The java.time api is augmented with:

  • predicate functions for each entity type: (cljc.java-time.extn.predicates/instant? x)
  • more helpful error messages for unsupported operations on Instants

This library uses a pure-JS implementation of java.time, see here for discussion on whether that affects application performance or build size

See my talk at Clojure/North 2019 for more background.

Temporal, the new JS platform Date-Time lib has been considered for use as an alternative basis of this library instead of js-joda, but although it has some overlap with java.time, Temporal is different enough that implementing cljc.java-time would be very difficult. For a dependency-free Clojure(Script) date-time API, see Tempo

Related Libraries

tick is a higher level date-time library that uses this one. Even if you're using cljc.java-time directly, ie not through tick, it has very relevant docs on extra setup for use with ClojureScript

time-literals is a Clojure(Script) library which provides tagged literals for objects from jsr-310 domain

Rationale

This library sits atop java.time on the jvm and cljs.java-time on Javascript platforms. Writing cross-platform code that uses those libraries directly is harder than interop normally is because:

  • To call the java.time 'static' methods in a cljc file you need to use the dot-special-form which is not idiomatic
  • The underlying js library has changed the name of the getter methods in java.time (in almost all cases) to remove the 'get' part of the name. There are ways to get around that on a case by case basis, but this library handles it for you.

.. but I just develop on the JVM Only

Reasons to use this:

  • All type hinting is done for you
  • comp, apply, juxt and all other clojure.core fns that apply to fns can now be used without anon fns: #(.foo %)
  • In fact, instead of seeing #(.foo %) in someone's code and not knowing what foo is, you'll have a properly namespaced clojure function foo - much better!
  • predicates, for example (local-date? x)

How it works

For every class in java.time, there is a clojure namespace.

For example, corresponding to java.time.LocalDate, there is a namespace

cljc.java-time.local-date

In that and every other namespace, there is one var per public method/field in the corresponding class.

For example, for the method java.time.LocalDate/parse, there is a corresponding function cljc.java-time.local-date/parse

Instance methods take the instance as the extra first arg

Usage

Clojars badge is at the top of this README

Version 0.1.9 and up require minimum Clojurescript version of 1.10.741

If using cljsjs, add js-joda and js-joda-locale-en-us to your dependencies as well

In .cljc file

(ns my.cljc
  (:require  [cljc.java-time.local-date :as ld])
   
;create a date
(def a-date (ld/parse "2019-01-01"))
   
;add some days
(ld/plus-days a-date 99)

Roundtripping with legacy Date

(require '[cljc.java-time.instant :as i])

;cljs
(-> (js/Date.) (.getTime) (i/of-epoch-milli) (i/to-epoch-milli) (js/Date.))

;clj 
(-> (Date.) (.getTime) (i/of-epoch-milli) (i/to-epoch-milli) (Date.))

Here is how to get to a babashka (v 1.2.174+) repl with cljc.java-time:

export BABASHKA_CLASSPATH=$(clojure -Spath -Sdeps '{:deps {com.widdindustries/cljc.java-time {:mvn/version "RELEASE"}}}')

bb

Problems & Irregularities

java.time.Year#isLeap exists as an instance method and a static method. Only the static version has been wrapped.

Inheritance/Polymorphism

The code of this project consists of mechanically generated functions for the java.time methods, even if those methods are inherited via superclasses or interfaces. In this project, functions are generated in every class they can be applied to. For example there is cljc.java-time.temporal.temporal/is-supported and also cljc.java-time.local-date/is-supported, with the latter being essentially unnecessary but included anyway.

Note

Java 9

A couple of new methods were added to java.time in Java 9 - these are not included in this library because according to the Clojure Survey about half of Clojure users are still on Java 8 :(

ClojureScript

Be aware that the underlying js implementation is probably only 99% complete. Anything you find missing can be added via pull request to js-joda

Development

The code of the project is generated by the generate-library-code! function in the dev/gen.clj namespace.

Clojure and Clojurescript

To run all tests:

make test 

Start a repl:

 clj -Adev:test:test-cljs

For Clojurescript dev, see the dev/cljs.clj file for functions to start test build in shadow and run tests.

babashka

Start babashka as follows

deps -A:test -Scommand "bb -cp {{classpath}}" --socket-repl 1666'

and run tests from the repl

one cmd to do this would be preferable

License

Copyright © 2021 Widd Industries

Distributed under the MIT License

More Repositories

1

time-literals

Clojure(Script) tagged literals for jsr-310 ( java.time) entities
Clojure
65
star
2

tempo

dependency-free clojure(script) time library
Clojure
39
star
3

tools.jvm

clojure tools for getting information about the jvm runtime
Clojure
38
star
4

firebase-clojurescript-todo-list

tutorial on setting up a simple todo list app with clojurescript and firebase
Clojure
17
star
5

clojure.log4j2

clojure log4j2
Clojure
15
star
6

cljs.java-time

jsr-310 (java.time) api in Clojurescript
JavaScript
14
star
7

tiado-cljs2

clojurescript build setup
Clojure
12
star
8

js-literal

like inbuilt cljs #js literal, but recursive
Clojure
10
star
9

defoclock

For when it's time to start def'ing stuff in the REPL
Clojure
6
star
10

slf4clj

Macros for structured logging to slf4j 2.0
Clojure
6
star
11

time-specs

Clojure(Script) library providing clojure.spec specs and generators for java.time
Clojure
5
star
12

clojurescript-library-consumers-test

test that different clojurescript build types can consume an npm-depending library
Makefile
3
star
13

Cljs-Async-Timeout-Tests

Clojurescript Cljs Async Timeout Tests
Clojure
3
star
14

tick-on-shadow-cljs-demo

example showing juxt tick ( jsr-310, java.time ) on shadow cljs
Clojure
3
star
15

blog

my blog
HTML
2
star
16

cljs-date-lib-comparison

Clojure
2
star
17

henryw374.github.io

HTML
2
star
18

sudoku

sudoku solver in clojure
Clojure
1
star
19

threeplay

Playing about with Three.js from Clojurescript
Clojure
1
star
20

Temporal.jvm

java implementation of https://github.com/tc39/proposal-temporal
Clojure
1
star
21

demo-lib-using-dependency-free-cljc.java-time

showing that dead code elimination works on the bundled jsjoda library
Clojure
1
star
22

cljs-enzyme-demo

example of using airbnb enzyme test with clojurescript re-frame and a router
Clojure
1
star
23

cljs-synchronous-promise

behaves like js promise but synchronous. useful for testing
Clojure
1
star
24

ginandtomic

playing about with datomic, seeing how it might be used idiomatically from Java
Clojure
1
star
25

jsr310-tagged-literals

Clojure(Script) tagged literals for jsr-310 (java-time) entities
Clojure
1
star
26

cljs-using-non-foreign-es6

trying to work out how it is possible for clojurescript code to require non-library es6 modules
JavaScript
1
star
27

cljs-importmap-demo

app demonstrates clojurescript app using 3rd party npm libraries coming via importmap
Clojure
1
star
28

temporal-test-clocks

drop-in alternatives to the Temporal.Now clock for testing purposes
TypeScript
1
star
29

influx-log4j2-appender

Clojure
1
star