(month [this] (clj-time/month (as-date this)))
(day [this] (clj-time/day (as-date this)))
(day-of-week [this] (clj-time/day-of-week (as-date this)))
(hour [this] (clj-time/hour (as-date this)))
(minute [this] (clj-time/minute (as-date this)))
(sec [this] (clj-time/sec (as-date this)))
(second [this] (clj-time/second (as-date this)))
(milli [this] (clj-time/milli (as-date this)))
(clj-time/after? [this that] (clj-time/after? (as-date this) that))
(before? [this that] (clj-time/before? (as-date this) that)))
And I want to be able to use some functions in both directions:
(def x (WeirdDate. 1986 5 2))
(def y (clj-time/date-time 2014 5 2))
(prn (clj-time/before? x y))
(prn (clj-time/after? y x))
The first one works, the second one fails with `ClassCastException: WeirdDate cannot be cast to org.joda.time.ReadableInstant`. I think this is because of a type hint which is present on the on the org.joda.time.DateTime implementation[0] of the DateTimeProtocol but not on the protocol:
(after? [this ^ReadableInstant that] (.isAfter this that))
So I add the ReadableInstant methods to the WeirdDate record:
ReadableInstant
(.equals [this readableInstant] (.equals (as-date this) readableInstant))
(.get [this type] (get (as-date this) type))
(.getChronology [this] (.getChronology (as-date this)))
(.getMillis [this] (.getMillis (as-date this)))
(.getZone [this] (.getZone (as-date this)))
(.hashCode [this] (.hashCode (as-date this)))
(.isAfter [this instant] (.isAfter (as-date this) instant))
(.isBefore [this instant] (.isBefore (as-date this) instant))
(.isEqual [this instant] (.isEqual (as-date this) instant))
(.isSupported [this field] (.isSupported (as-date this) field))
(.toInstant [this] (.toInstant (as-date this)))
(.toString [this] (.toString (as-date this)))
Now I get `IllegalArgumentException: Must hint overloaded method: get`. So I annotate according to the Java interface[1]:
ReadableInstant
(.equals ^boolean [this ^Object readableInstant] (.equals (as-date this) readableInstant))
(.get ^int [this ^DateTimeFieldType type] (get (as-date this) type))
(.getChronology ^Chronology [this] (.getChronology (as-date this)))
(.getMillis ^long [this] (.getMillis (as-date this)))
(.getZone ^DateTimeZone [this] (.getZone (as-date this)))
(.hashCode ^int [this] (.hashCode (as-date this)))
(.isAfter ^boolean [this ^ReadableInstant instant] (.isAfter (as-date this) instant))
(.isBefore ^boolean [this ^ReadableInstant instant] (.isBefore (as-date this) instant))
(.isEqual ^boolean [this ^ReadableInstant instant] (.isEqual (as-date this) instant))
(.isSupported ^boolean [this ^DateTimeFieldType field] (.isSupported (as-date this) field))
(.toInstant ^Instant [this] (.toInstant (as-date this)))
(.toString ^String [this] (.toString (as-date this)))
Again, `IllegalArgumentException: Must hint overloaded method: get`.
As far as I know this is all correctly annotated, although I'm not sure about the return types, as records aren't mentioned in the documentation[2] but it does say "For function return values, the type hint can be placed before the arguments vector".
Any ideas?