{"id":19714857,"url":"https://github.com/dm3/clojure.joda-time","last_synced_at":"2025-10-13T08:16:26.384Z","repository":{"id":12748817,"uuid":"15421983","full_name":"dm3/clojure.joda-time","owner":"dm3","description":"An idiomatic Clojure wrapper for Joda-Time","archived":false,"fork":false,"pushed_at":"2017-05-18T09:47:06.000Z","size":186,"stargazers_count":27,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-13T08:16:24.752Z","etag":null,"topics":["clojure","interop","java","joda-time","library"],"latest_commit_sha":null,"homepage":null,"language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dm3.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-12-24T16:47:45.000Z","updated_at":"2023-09-08T16:44:18.000Z","dependencies_parsed_at":"2022-09-05T20:10:25.410Z","dependency_job_id":null,"html_url":"https://github.com/dm3/clojure.joda-time","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/dm3/clojure.joda-time","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dm3%2Fclojure.joda-time","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dm3%2Fclojure.joda-time/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dm3%2Fclojure.joda-time/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dm3%2Fclojure.joda-time/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dm3","download_url":"https://codeload.github.com/dm3/clojure.joda-time/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dm3%2Fclojure.joda-time/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279014289,"owners_count":26085488,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clojure","interop","java","joda-time","library"],"created_at":"2024-11-11T22:36:20.803Z","updated_at":"2025-10-13T08:16:26.368Z","avatar_url":"https://github.com/dm3.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Clojure.Joda-Time\n\n## For Java 8 Users\n\nIf you are on Java 8 and don't need to support earlier Java versions, consider\nusing [Clojure.Java-Time](https://github.com/dm3/clojure.java-time)!\n\n## For Java 7-and-below Users\n\n[![Build Status](https://travis-ci.org/dm3/clojure.joda-time.png?branch=master)](https://travis-ci.org/dm3/clojure.joda-time)\n\nAn idiomatic Clojure wrapper for Joda-Time.\n\nMain goals:\n\n* Provide a consistent API for common operations with\n  instants, date-times, periods, partials and intervals.\n* Provide an escape hatch from Joda types to clojure datastructures\n  and back where possible.\n* Avoid reflective calls (this is a problem, because many types in Joda-Time\n  have similar functionality hidden under similarly named and overloaded\n  methods with no common interfaces).\n* Provide an entry point into Joda-Time by freeing the user from importing most\n  of the Joda-Time classes.\n\nWhy use Clojure.Joda-Time over [clj-time](https://github.com/clj-time/clj-time)?\n\n* You don't want to treat `DateTime` differently from other dates\n* You need to operate on arbitrary `Periods` and `Partials`\n* You want to have everything handy under a single namespace (two, if you want some sugar)\n* You know the Joda-Time library and want to stay close to the original API\n* You need to perform complicated operations on dates/periods/intervals/durations\n\nThis library employs a structured and comprehensive approach to exposing the\nJoda-Time API to the Clojure world. It can help in the 10% of cases when\nfunctionality provided by *clj-time* isn't enough. Try it out and see if it\nsticks!\n\n## Usage\n\nAdd the following dependency to your `project.clj`:\n\n```clj\n[clojure.joda-time \"0.7.0\"]\n```\n\n[API](http://dm3.github.io/clojure.joda-time/) of the Clojure.Joda-Time\nconsists of one namespace, namely: `joda-time`.  For the purposes of this\nguide, we will `use` the main namespace:\n\n```clj\n(refer-clojure :exclude [merge partial iterate format print contains? max min])\n(use 'joda-time)\n```\n\n### An appetizer\n\nFirst, a quick run through common use cases.\n\nWhat is the current date and time in our time zone?\n\n```clj\n(def now (date-time))\n=\u003e #\u003cDateTime 2013-12-10T13:07:16.000+02:00\u003e\n```\n\nIn UTC?\n\n```clj\n(with-zone now (timezone :UTC))\n=\u003e #\u003cDateTime 2013-12-10T11:07:16.000Z\u003e\n```\n\nIn UTC but with the current timezone's time?\n\n```clj\n(in-zone now (timezone :UTC))\n=\u003e #\u003cDateTime 2013-12-10T13:07:16.000Z\u003e\n```\n\nWithout the time zone?\n\n```clj\n(def now-local (local-date-time))\n=\u003e #\u003cLocalDateTime 2013-12-10T13:07:16.000\u003e\n```\n\nNow, how would we go about a date five years and six months from now?  First,\nwe would need to represent this period:\n\n```clj\n(period {:years 5, :months 6})\n=\u003e #\u003cPeriod P5Y6M\u003e\n```\n\nor as a sum:\n\n```clj\n(def five-years-and-some (plus (years 5) (months 6)))\n=\u003e #\u003cPeriod P5Y6M\u003e\n```\n\nNow for the date:\n\n```clj\n(def in-five-years (plus now five-years-and-some))\n=\u003e #\u003cDateTime 2019-06-10T13:07:16.000+03:00\u003e\n\n(def in-five-years-local (plus now-local five-years-and-some))\n=\u003e #\u003cLocalDateTime 2019-06-10T13:07:16.000\u003e\n```\n\nHow many hours to the point five years and six months from now?\n\n```clj\n(hours-in now in-five-years)\n=\u003e 48191\n\n(hours-in now-local in-five-years-local)\n=\u003e 48191\n```\n\nWhat if we want a specific date?\n\n```clj\n(def in-two-years (date-time \"2015-12-10\"))\n=\u003e #\u003cDateTime 2015-12-10T00:00:00.000+02:00\u003e\n\n(def in-two-years-local (local-date-time \"2015-12-10\"))\n=\u003e #\u003cLocalDateTime 2015-12-10T00:00:00.000\u003e\n```\n\nSame with positional arguments:\n\n```clj\n(def in-two-years-positional (date-time 2015 12 10))\n=\u003e #\u003cDateTime 2015-12-10T00:00:00.000+02:00\u003e\n\n(def in-two-years-local-positional (local-date-time 2015 12 10))\n=\u003e #\u003cLocalDateTime 2015-12-10T00:00:00.000\u003e\n```\n\nDoes the interval from `now` to `in-five-years` contain this date?\n\n```clj\n(after? in-five-years in-two-years now)\n=\u003e true\n\n(after? in-five-years-local in-two-years-local now-local)\n=\u003e true\n```\n\nAnother way, actually using the interval type:\n\n```clj\n(contains? (interval now in-five-years) in-two-years)\n=\u003e true\n\n(contains? (partial-interval now-local in-five-years-local) in-two-years-local)\n=\u003e true\n```\n\nWhat's the largest/smallest date in the list?\n\n```clj\n(max now in-five-years in-two-years)\n=\u003e #\u003cDateTime 2019-06-10T13:07:16.000+03:00\u003e\n\n(min now in-five-years in-two-years)\n=\u003e #\u003cDateTime 2013-12-10T13:07:16.000+02:00\u003e\n```\n\nWhat about the current day of month?\n\n```clj\n(-\u003e now (property :dayOfMonth) value)\n=\u003e 10\n\n(-\u003e now-local (property :dayOfMonth) value)\n=\u003e 10\n```\n\nThe date at the last day of month?\n\n```clj\n(-\u003e now (property :dayOfMonth) with-max-value)\n=\u003e #\u003cDateTime 2013-12-31T13:07:16.000+02:00\u003e\n\n(def new-years-eve (-\u003e now-local (property :dayOfMonth) with-max-value)\n=\u003e #\u003cLocalDateTime 2013-12-31T13:07:16.000\u003e\n```\n\nWe can also do this using the `accessors` namespace:\n\n```clj\n(require '[joda-time.accessors :as ja])\n\n(value (ja/day-of-month-prop now))\n=\u003e #\u003cProperty Property[dayOfMonth]\u003e\n\n(ja/day-of-month now)\n=\u003e 10\n\n(ja/min-day-of-month now)\n=\u003e 1\n\n(ja/max-day-of-month now)\n=\u003e 31\n\n(ja/with-max-day-of-month now)\n=\u003e #\u003cDateTime 2013-12-31T13:07:16.000+02:00\u003e\n\n(ja/with-day-of-month now 20)\n=\u003e #\u003cDateTime 2013-12-20T13:07:16.000+02:00\u003e\n```\n\nEvery date at the last day of month from now?\n\n```clj\n(iterate plus new-years-eve (months 1))\n=\u003e (#\u003cLocalDateTime 2013-12-31T13:07:16.000\u003e\n    #\u003cLocalDateTime 2014-01-31T13:07:16.000\u003e ...)\n```\n\nIn case we want to print the dates, we'll need a formatter:\n\n```clj\n(def our-formatter (formatter \"yyyy/MM/dd\"))\n=\u003e #\u003cDateTimeFormatter ...\u003e\n\n(print our-formatter now)\n=\u003e \"2013/12/10\"\n\n(print our-formatter now-local)\n=\u003e \"2013/12/10\"\n```\n\nAnd what about parsing?\n\n```clj\n(parse-date-time our-formatter \"2013/12/10\")\n=\u003e #\u003cDateTime 2013-12-10T00:00:00.000+02:00\u003e\n\n(parse-local-date our-formatter \"2013/12/10\")\n=\u003e #\u003cLocalDate 2013-12-10\u003e\n```\n\nHow should we convert between Joda dates and java.util/sql Dates?\n\n```clj\n(local-date now)\n=\u003e #\u003cLocalDate 2013-12-10\u003e\n\n(date-time now-local)\n=\u003e #\u003cDateTime 2013-12-10T13:07:16.000+02:00\u003e\n\n(local-time now)\n=\u003e #\u003cLocalTime 13:07:16.000\u003e\n\n(date-time (local-time now))\n=\u003e #\u003cDateTime 1970-01-01T13:07:16.000+03:00\u003e\n\n(to-java-date now)\n=\u003e #inst \"2013-12-10T11:07:16.000-00:00\"\n\n(to-java-date local-now)\n=\u003e #inst \"2013-12-10T11:07:16.000-00:00\"\n\n(to-millis-from-epoch now)\n=\u003e 1386673636000\n```\n\nI hope you're interested. However, we've barely scratched the surface of the\nAPI. Please, continue reading for a deeper look.\n\n### Joda-Time entities\n\nClojure.Joda-Time provides a way to construct most of the time entities\nprovided by the Joda-Time. For example, given a `LocalDate` type in Joda-Time,\nthe corresponding construction function (I'll hijack the name \"constructor\" to\ndefine construction functions) in Clojure.Joda-Time will be called\n`local-date`.\n\nA call to a constructor with a single argument goes through the following\npattern:\n\n* given a `nil`, return a `nil` (**important**: this is different from the\n  default Joda-Time behaviour which usually has a default value for `nil`)\n* given a number, convert it to `Long` and invoke the next rule,\n* given a map, try to reconstruct a time entity from its map representation\n  (see **Properties** section) or invoke one of the constructors on the\n  corresponding Java class.\n* given any object, pass it to the Joda-Time `ConverterManager`,\n\nMostly single-argument constructors are supported (except for a several cases\nwhich we will look at later on) to avoid confusion with overloading.\n\nBy convention, a call to a constructor without arguments will return a time\nentity constructed at the current date and time.\n\n#### Instants\n\nIn Joda-Time [instants](http://www.joda.org/joda-time/key_instant.html) are\nrepresented by `DateTime` and `Instant` types.\n\n```clj\n(date-time)\n=\u003e #\u003cDateTime 2013-12-10T10:20:13.133+02:00\u003e\n\n(instant)\n=\u003e #\u003cInstant 2013-12-10T10:20:16.233+02:00\u003e\n```\n\nYou might have noticed that `DateMidnight` is not supported. This is because\nthe type is deprecated in the recent versions of Joda-Time. If you need a\nmidnight date, you should be use:\n\n```clj\n(.withTimeAtStartOfDay (date-time))\n=\u003e #\u003cDateTime 2013-12-10T00:00:00.000+02:00\u003e\n```\n\n#### Partials\n\n[Partials](http://www.joda.org/joda-time/key_partial.html) are represented by\n`Partial`, `LocalDate`, `LocalDateTime`, `LocalTime`, `YearMonth` and `MonthDay`.\n\n```clj\n(partial)\n=\u003e #\u003cPartial []\u003e\n\n(partial {:year 2013, :monthOfYear 12})\n=\u003e #\u003cPartial 2013-12\u003e\n\n(local-date)\n=\u003e #\u003cLocalDate 2013-12-10\u003e\n\n(local-date-time)\n=\u003e #\u003cLocalDateTime 2013-12-10T10:15:13.553\u003e\n\n(local-time)\n=\u003e #\u003cLocalTime 10:15:15.234\u003e\n\n(year-month)\n=\u003e #\u003cYearMonth 2013-12\u003e\n\n(month-day)\n=\u003e #\u003cMonthDay --12-10\u003e\n```\n\nMulti-arity versions of the constructors are also supported. The fields not\nprovided will default to minimum values (0 for hours, minutes, seconds, millis;\n1 for days).\n\n#### Periods\n\nJoda types for [periods](http://www.joda.org/joda-time/key_period.html) are\n`Period`, `MutablePeriod`, `Years`, `Months`, `Weeks`, `Days`, `Hours`,\n`Minutes` and `Seconds`.\n\nMulti-field period accepts a map of several possible shapes. The first shape is\na map representation of a period, e.g.:\n\n```clj\n(period {:years 10, :months 10})\n=\u003e #\u003cPeriod P10Y10M\u003e\n```\n\nthe second shape delegates to an appropriate Joda `Period` constructor, such\nas:\n\n```clj\n(period {:start 0, :end 1000})\n=\u003e #\u003cPeriod PT1S\u003e\n```\n\nPeriod constructor can be called with two arguments, where the second argument\nis the type of the period - either a `PeriodType` or a vector of duration field\nname keywords:\n\n```clj\n(period 1000 [:millis])\n=\u003e #\u003cPeriod PT1S\u003e\n\n(period {:start 0, :end 1000} (period-type :millis))\n=\u003e #\u003cPeriod PT1S\u003e\n```\n\nAll of the single-field periods are constructed the same way:\n\n```clj\n(years 10)\n=\u003e #\u003cYears P10Y\u003e\n\n(months 5)\n=\u003e #\u003cMonths P5M\u003e\n```\n\nSingle-field period constructors can also be used to extract duration component\nout of the multi-field period:\n\n```clj\n(years (period {:years 20, :months 10}))\n=\u003e #\u003cYears P20Y\u003e\n```\n\nWhen called on an interval, single-field period constructor will calculate the\nduration (same as `Years.yearsIn`, `Months.monthsIn`, etc. in Joda-Time):\n\n```clj\n(minutes (interval (date-time \"2008\") (date-time \"2010\")))\n=\u003e #\u003cMinutes PT1052640M\u003e\n```\n\nYou can get the value of the single-field period using the helper functions in\n`joda-time.accessors`:\n\n```clj\n(ja/minutes (period {:hours 20, :minutes 10}))\n=\u003e 10\n```\n\nTo get the standard duration of the period, use one of the `-in` functions:\n\n```clj\n(minutes-in (period {:hours 20, :minutes 10}))\n=\u003e 1210\n```\n\nBe aware that standard duration doesn't work for periods containing months or\nyears as they are variable length.\n\nYou can also query the type of the period:\n\n```clj\n(period-type (period))\n=\u003e #\u003cPeriodType PeriodType[Standard]\u003e\n\n(period-type (years 5))\n=\u003e #\u003cPeriodType PeriodType[Years]\u003e\n```\n\n`period-type` can also construct a `PeriodType` out of the duration field type\nnames:\n\n```clj\n(period-type :years)\n=\u003e #\u003cPeriodType PeriodType[Years]\u003e\n\n(period-type :years :months :weeks :days)\n=\u003e #\u003cPeriodType PeriodType[StandardNoHoursNoMinutesNoSecondsNoMillis]\u003e\n```\n\nYou can also convert the `PeriodType` back to a seq of keywords:\n\n```clj\n(period-type-\u003eseq (period-type (years 10)))\n=\u003e [:years]\n```\n\n#### Durations\n\n[Duration](http://www.joda.org/joda-time/key_duration.html) is the most\nboring time entity. It can be constructed in the following way:\n\n```clj\n(duration 1000)\n=\u003e #\u003cDuration PT1S\u003e\n```\n\nDuration constructor also accepts a map (you can find the whole set of options\nin the docstring):\n\n```clj\n(duration {:start (date-time), :period (years 5)})\n=\u003e #\u003cDuration PT157766400S\u003e\n```\n\n#### Intervals\n\n[Intervals](http://www.joda.org/joda-time/key_interval.html) consist of a\nsingle type inherited from Joda Time:\n\n```clj\n(interval 0 1000)\n=\u003e #\u003cInterval 1970-01-01T00:00:00.000Z/1970-01-01T00:00:01.000Z\u003e\n```\n\nand one additional type defined in this library:\n\n```clj\n(partial-interval (partial {:year 0}) (partial {:year 2010}))\n=\u003e #joda_time.interval.PartialInterval{:start #\u003cPartial 0000\u003e, :end #\u003cPartial 2010\u003e}\n\n(partial-interval (local-date \"2010\") (local-date \"2013\"))\n=\u003e #joda_time.interval.PartialInterval{:start #\u003cLocalDate 2010-01-01\u003e,\n                                       :end #\u003cLocalDate 2013-01-01\u003e}\n```\n\nrecord representation of the partial interval is an implementation detail and\nshould not be relied upon.\n\nAs you can see, the interval constructor accepts start and end arguments -\neither milliseconds from epoch, instants or date-times. Constructor also\naccepts a map with different combinations of `start`, `end`, `duration` and\n`period` parameters, same as Joda-Time `Interval` constructors:\n\n```clj\n(interval {:start 0, :end 1000})\n=\u003e #\u003cInterval 1970-01-01T00:00:00.000Z/1970-01-01T00:00:01.000Z\u003e\n\n(interval {:start 0, :duration 1000})\n=\u003e #\u003cInterval 1970-01-01T00:00:00.000Z/1970-01-01T00:00:01.000Z\u003e\n\n(interval {:start 0, :period (seconds 1)})\n=\u003e #\u003cInterval 1970-01-01T00:00:00.000Z/1970-01-01T00:00:01.000Z\u003e\n```\n\nBoth instant and partial intervals support a common set of operations on their\nstart/end (string representation of the interval is shortened for readability):\n\n```clj\n(def i (interval 0 10000))\n=\u003e #\u003cInterval 00.000/10.000\u003e\n\n(move-start-to i (instant 5000))\n=\u003e #\u003cInterval 05.000/10.000\u003e\n\n(move-end-to i (instant 5000))\n=\u003e #\u003cInterval 00.000/05.000\u003e\n\n(move-start-by i (seconds 5))\n=\u003e #\u003cInterval 05.000/10.000\u003e\n\n(move-end-by i (seconds 5))\n=\u003e #\u003cInterval 05.000/15.000\u003e\n\n(move-end-by i (seconds 5))\n=\u003e #\u003cInterval 05.000/15.000\u003e\n```\n\nintervals can also be queried for several properties:\n\n```clj\n(start i)\n=\u003e #\u003cDateTime 1970-01-01T00:00:00.000Z\u003e\n\n(end i)\n=\u003e #\u003cDateTime 1970-01-01T00:00:10.000Z\u003e\n\n(contains? i (interval 2000 5000))\n=\u003e true\n\n(contains? i (interval 0 15000))\n=\u003e false\n\n(contains? (interval (date-time \"2010\") (date-time \"2012\"))\n           (date-time \"2011\"))\n=\u003e true\n\n(overlaps? (interval (date-time \"2010\") (date-time \"2012\"))\n           (interval (date-time \"2011\") (date-time \"2013\")))\n=\u003e true\n\n(abuts? (interval (date-time \"2010\") (date-time \"2012\"))\n        (interval (date-time \"2012\") (date-time \"2013\")))\n=\u003e true\n```\n\nwe can also calculate interval operations present in the Joda-Time:\n\n```clj\n(overlap (interval (date-time \"2010\") (date-time \"2012\"))\n         (interval (date-time \"2011\") (date-time \"2013\")))\n=\u003e #\u003cInterval 2011/2012\u003e\n\n(gap (interval (date-time \"2010\") (date-time \"2012\"))\n     (interval (date-time \"2013\") (date-time \"2015\")))\n=\u003e #\u003cInterval 2012/2013\u003e\n```\n\nAll of the above functions work with partial intervals the same way.\n\n#### Timezones and Chronologies\n\nTimezones can be constructed through the `timezone` function given the\n(case-sensitive) timezone ID:\n\n```clj\n(timezone)\n=\u003e #\u003cCachedDateTimeZone Europe/Vilnius\u003e\n\n(timezone \"Europe/Vilnius\")\n=\u003e #\u003cCachedDateTimeZone Europe/Vilnius\u003e\n\n(timezone :UTC)\n=\u003e #\u003cFixedDateTimeZone UTC\u003e\n```\n\nChronologies are constructed using `chronology` with a lower-case chronology\ntype and an optional timezone argument:\n\n```clj\n(chronology :coptic)\n=\u003e #\u003cCopticChronology CopticChronology [Europe/Vilnius]\u003e\n\n(chronology :coptic :UTC)\n=\u003e #\u003cCopticChronology CopticChronology [UTC]\u003e\n\n(chronology :iso (timezone :UTC))\n=\u003e #\u003cISOChronology ISOChronology [UTC]\u003e\n```\n\n#### Formatters\n\nFormatters (printers and parsers) are defined through the `formatter` function:\n\n```clj\n(formatter \"yyyy-MM-dd\")\n=\u003e #\u003cDateTimeFormatter ...\u003e\n```\n\nAll of the ISO formatter defined by Joda-Time in the `ISODateTimeFormat` class\ncan be referenced by the appropriate keywords:\n\n```clj\n(formatter :date-time)\n=\u003e #\u003cDateTimeFormatter ...\u003e\n```\n\nFormatters may also be composed out of multiple patterns and other formatters:\n\n```clj\n(def fmt (formatter \"yyyy/MM/dd\" :date-time (formatter :date)))\n=\u003e #\u003cDateTimeFormatter ...\u003e\n```\n\nthe resulting formatter will print according to the first pattern:\n\n```clj\n(print fmt (date-time \"2010\"))\n=\u003e \"2010/01/01\"\n```\n\nand parse all of the provided formats. Dates can be parsed from strings using\na family of `parse` functions:\n\n```clj\n(parse-date-time fmt \"2010/01/01\")\n=\u003e #\u003cDateTime 2010-01-01T00:00:00.000+02:00\u003e\n\n(parse-mutable-date-time fmt \"2010/01/01\")\n=\u003e #\u003cMutableDateTime 2010-01-01T00:00:00.000+02:00\u003e\n\n(parse-local-date fmt \"2010/01/01\")\n=\u003e #\u003cLocalDate 2010-01-01\u003e\n\n(parse-local-date-time fmt \"2010/01/01\")\n=\u003e #\u003cLocalDateTime 2010-01-01T00:00:00.000\u003e\n\n(parse-local-time fmt \"2010/01/01\")\n=\u003e #\u003cLocalTime 00:00:00.000\u003e\n```\n\n### Conversions\n\nJoda-Time partials, instants and date-times can be converted back and forth\nusing the corresponding constructors:\n\n```clj\n(def now (date-time))\n=\u003e #\u003cDateTime 2013-12-10T13:07:16.000+02:00\u003e\n\n(local-date now)\n=\u003e #\u003cLocalDate 2013-12-10\u003e\n\n(local-date-time now)\n=\u003e #\u003cLocalDateTime 2013-12-10T13:07:16.000\u003e\n\n(date-time (local-date now))\n=\u003e #\u003cDateTime 2013-12-10T00:00:00.000+02:00\u003e\n\n(instant (local-date now))\n=\u003e #\u003cInstant 2013-12-10T00:00:00.000Z\u003e\n\n(date-time (partial {:hourOfDay 12}))\n=\u003e #\u003cDateTime 1970-01-01T12:00:00.000+03:00\u003e\n```\n\nAs you can see, conversions to date-time do not force the UTC timezone and set\nthe missing fields to the unix epoch. If we want to construct a date-time out\nof a partial and fill the missing fields in another way, we could use the map\nconstructor:\n\n```clj\n(date-time {:partial (partial {:millisOfDay 1000}), :base now})\n=\u003e #\u003cDateTime 2013-12-10T00:00:01.000+02:00\u003e\n```\n\nYou can customize date-time construction from partials by registering a custom\n`InstantConverter` in the Joda `ConverterManager`.\n\nWe can also convert Joda date entities to native Java types:\n\n```clj\n(to-java-date now)\n=\u003e #inst \"2013-12-10T11:07:16.000-00:00\"\n\n(type (to-sql-date now))\n=\u003e java.sql.Date\n\n(to-sql-timestamp now)\n=\u003e #inst \"2013-12-10T11:07:16.000000000-00:00\"\n\n(to-millis-from-epoch now)\n=\u003e 1386673636000\n```\n\nOf course, native Java types can be converted between themselves:\n\n```clj\n(to-java-date 1386673636000)\n=\u003e #inst \"2013-12-10T11:07:16.000-00:00\"\n\n(to-java-date \"2013-12-10\")\n=\u003e #inst \"2013-12-09T22:00:00.000-00:00\"\n```\n\nDon't worry about the seemingly incorrect java date in the last example. We get\nan `2013-12-09` *inst* out of a `2013-12-10` string because *inst* is printed\nin the UTC timezone. We can check that everything is OK by converting back to\nthe Joda date-time:\n\n```clj\n(= (date-time 2013 12 10) (date-time (to-java-date \"2013-12-10\")))\n=\u003e true\n```\n\nSame with local dates:\n\n```clj\n(= (local-date-time 2013 12 10) (local-date-time (to-java-date \"2013-12-10\")))\n=\u003e true\n```\n\nEven more conversions:\n\n```clj\n(= now (date-time (local-date-time (to-java-date now))))\n=\u003e true\n```\n\n### Properties\n\nProperties allow us to query and act on separate fields of date-times,\ninstants, partials and periods.\n\nWe can query single properties by using the `property` function:\n\n```clj\n(value (property (date-time \"2010\") :monthOfYear))\n=\u003e 1\n\n(max-value (property (instant \"2010\") :monthOfYear))\n=\u003e 12\n\n(min-value (property (partial {:monthOfYear 10}) :monthOfYear))\n=\u003e 1\n\n(with-value (property (period {:years 10, :months 5}) :years) 15)\n=\u003e #\u003cPeriod P15Y5M\u003e\n```\n\nProperty expressions read better when chained with threading macros:\n\n```clj\n(-\u003e (date-time \"2010\") (property :monthOfYear) value)\n=\u003e 1\n```\n\nClojure loves maps, so I've tried to produce a map interface to the most\ncommonly used Joda-time entities. Date-times, instants, partials and periods\ncan be converted into maps using the `properties` function which uses\n`property` under the hood.  For example, a `DateTime` contains a whole bunch of\nproperties - one for every `DateTimeFieldType`:\n\n```clj\n(def props (properties (date-time)))\n=\u003e {:centuryOfEra #\u003cProperty Property[centuryOfEra]\u003e, ...}\n\n(keys props)\n=\u003e (:centuryOfEra :clockhourOfDay :clockhourOfHalfday\n    :dayOfMonth :dayOfWeek :dayOfYear\n    :era :halfdayOfDay :hourOfDay :hourOfHalfday\n    :millisOfDay :millisOfSecond :minuteOfDay\n    :minuteOfHour :monthOfYear :secondOfDay :secondOfMinute\n    :weekOfWeekyear :weekyear :weekyearOfCentury\n    :year :yearOfCentury :yearOfEra)\n```\n\nNow we can get the values for all of the fields (we'll cheat and use\n`flatland.useful.map/map-vals`):\n\n```clj\n(useful/map-vals props value)\n=\u003e {:year 2013, :monthOfYear 12, :dayOfMonth 8,\n    :yearOfCentury 13, :hourOfHalfday 9, :minuteOfDay 1305, ...}\n```\n\nalthough this is better achieved by calling `as-map` convenience function.\n\nAs you can see, map representations allow us to plug into the rich set of\noperations on maps provided by Clojure and free us from using\n`DateTimeFieldType` or `DurationFieldType` classes directly.\n\nPartials contain a smaller set of properties, for example:\n\n```clj\n(-\u003e (partial {:year 2013, :monthOfYear 12})\n    properties\n    (useful/map-vals value))\n=\u003e {:year 2013, :monthOfYear 12}\n```\n\nProperties allow us to perform a bunch of useful calculations, such as getting\nthe date for the last day of the current month:\n\n```clj\n(-\u003e (date-time) (property :dayOfMonth) with-max-value)\n```\n\nor get the date for the first day:\n\n```clj\n(-\u003e (date-time) (properties :dayOfMonth) with-min-value)\n```\n\nThe above can also be done using the `joda-time.accessors` namespace which\ndefines a function for every possible date-time field supported by Joda-Time.\n\n```clj\n(ja/with-max-day-of-month (date-time))\n(ja/with-min-day-of-month (date-time))\n```\n\nWe can also solve a common problem of getting a sequence of dates for the last\nday of month:\n\n```clj\n(iterate #(ja/with-max-day-of-month (plus %1 %2)) (local-date) (months 1))\n=\u003e (#\u003cLocalDate 2013-12-31\u003e #\u003cLocalDate 2014-01-31\u003e ...)\n```\n\nNote that `iterate` is defined in the `joda-time` namespace.\n\n### Operations\n\nOne of the most useful parts of the Joda-Time library is it's rich set of\narithmetic operations allowed on the various time entities. You can sum periods\nand durations together or add them to date-times, instants or partials.  You\ncan compute the difference of durations and periods or subtract them from\ndates. You can also negate and compute absolute values of durations and\nperiods.\n\nHere's an example of using a `plus` operation on a date-time:\n\n```clj\n(def now (date-time \"2010-01-01\"))\n=\u003e #\u003cDateTime 2010-01-01T00:00:00.000+02:00\u003e\n\n(plus now (years 11))\n=\u003e #\u003cDateTime 2021-01-01T00:00:00.000+02:00\u003e\n\n(def millis-10sec (* 10 1000))\n=\u003e 10000\n\n(def duration-10sec (duration millis-10sec)\n=\u003e #\u003cDuration PT10S\u003e\n\n(plus now (years 11) (months 10) (days 20) duration-10sec millis-10sec)\n=\u003e #\u003cDateTime 2021-11-21T00:00:20.000+02:00\u003e\n```\n\nsame with instants:\n\n```clj\n(plus (instant \"2010-01-01\") (years 11))\n=\u003e #\u003cInstant 2021-01-01T00:00:00.000Z\u003e\n```\n\nwith partials:\n\n```clj\n(def now (local-date 2010 1 1))\n=\u003e #\u003cLocalDate 2010-01-01\u003e\n\n(plus now (years 11) (months 10) (days 20))\n=\u003e #\u003cLocalDate 2021-11-21\u003e\n```\n\nor with periods:\n\n```clj\n(def p (plus (years 10) (years 10) (months 10)))\n=\u003e #\u003cPeriod P20Y10M\u003e\n\n(period-type p)\n=\u003e #\u003cPeriodType PeriodType[StandardNoWeeksNoDaysNoHoursNoMinutesNoSecondsNoMillis]\u003e\n```\n\nor with durations:\n\n```clj\n(plus (duration 1000) (duration 1000) 1000)\n=\u003e #\u003cDuration PT3S\u003e\n```\n\nObviously, you can `minus` all the same things you can `plus`:\n\n```clj\n(minus now (years 11) (months 10))\n=\u003e #\u003cLocalDate 1998-03-01\u003e\n\n(minus (duration 1000) (duration 1000) 1000)\n=\u003e #\u003cDuration PT-1S\u003e\n\n(minus (years 10) (years 10) (months 10))\n=\u003e #\u003cPeriod P-10M\u003e\n```\n\nAs you can see, durations and periods can become negative. Actually, we can\nturn a positive period into a negative one by using `negate`:\n\n```clj\n(negate (years 10))\n=\u003e #\u003cYears P-10Y\u003e\n\n(negate (duration 1000))\n=\u003e #\u003cDuration PT-1S\u003e\n```\n\nand we can take an absolute value of a period or a duration:\n\n```clj\n(abs (days -20))\n=\u003e #\u003cDays P20D\u003e\n\n(abs (days 20))\n=\u003e #\u003cDays P20D\u003e\n\n(abs (duration -1000))\n=\u003e #\u003cDuration PT1S\u003e\n```\n\nThere is also a `merge` operation which is supported by periods and partials.\nIn case of a period, `merge` works like `plus`, only the values get overwritten\nlike when merging maps with `clojure.core/merge`:\n\n```clj\n(merge (period {:years 10, :months 6}) (years 20) (days 10))\n=\u003e #\u003cPeriod P20Y6M10D\u003e\n\n(merge (local-date) (local-time))\n=\u003e #\u003cPartial 2013-12-09T11:10:00.350\u003e\n\n(merge (local-date) (local-time) (partial {:era 0})\n=\u003e #\u003cPartial [era=0, year=2013, monthOfYear=12, dayOfMonth=9,\n              hourOfDay=11, minuteOfHour=10, secondOfMinute=5,\n              millisOfSecond=429]\u003e\n```\n\nEssentially, merging several partials or periods together is the same as\nconverting them to their map representations with `as-map`, merging maps and\nconverting the result back into a period/partial, only in a more efficient way.\n\nIt's important to note that operations on mutable Joda-Time entities aren't\nsupported. You are expected to chain methods through java interop.\n\n## License\n\nCopyright © 2013 Vadim Platonov\n\nDistributed under the MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdm3%2Fclojure.joda-time","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdm3%2Fclojure.joda-time","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdm3%2Fclojure.joda-time/lists"}