The main argument for having it in core is:

  * It integrates directly with the Calendar behaviour
  * We could provide built-in sigils in the future to create readable
durations, such as ~P[3 hours and 10 minutes]
  * Postgrex, Explorer, CLDR, etc all implement their own version of
durations

Arguments for not having it in core: it happens that all of the arguments
above can also be solved without adding Duration to Elixir and, instead, by
creating a custom library:

  * A separate library could extend the calendar behaviour with shift_*
functions
  * Third-party sigils can also be provided by libraries
  * Postgrex, Explorer, and CLDR could create or use a package with a
duratio type shared across them all

I would love to hear the community thoughts.

On Wed, Mar 6, 2024 at 7:16 PM 'Theo Fiedler' via elixir-lang-core <
elixir-lang-core@googlegroups.com> wrote:

> *Preface*
>
> We currently have `add/2-3` to manipulate calendar types in the standard
> library. These functions allow adding a specified amount of time of given
> unit to a date/time. The standard library currently misses means to apply
> more complex, or logical *durations *to calendar types. e.g. adding a
> month, a week, or one month and 10 days to a date.
>
> *Reasons for it*
>
> While similar functionality exists in libraries, such as CLDR, Timex, Tox,
> adding this functionality to the standard library has already been
> requested and discussed at multiple occasions over the past years. To list
> a few examples:
>
> - https://github.com/elixir-lang/elixir/pull/10199
> - https://elixirforum.com/t/get-date-n-months-years-in-the-past/48346/3
> -
> https://elixir-lang.slack.com/archives/C0HEX82NR/p1709581478427009?thread_ts=1709368588.334759&cid=C0HEX82NR
>
> Furthermore the shift behaviour in the extremely popular library Timex
> changed <https://github.com/bitwalker/timex/issues/731> in Elixir >=
> 1.14.3 which may have complicated the mostly lean and non-breaking language
> upgrade Elixir has to offer.
>
> Elixir has a great set of modules and functions that deal with date and
> time, the APIs are consistent and `shift/2-3` should fit right in, solving
> many standard needs of various industries, be it for reporting,
> appointments, events, finance... the list goes on, engineers probably face
> the need to shift time logically more often than not in their careers.
>
> *Technical details*
>
> Duration
> A date or time must be shifted by a *duration*. There is an ISO8601 for
> durations <https://en.wikipedia.org/wiki/ISO_8601#Durations>, which the
> initial implementation is loosely following. The structure of a Duration
> lives in its own module with its own set of functions to create and
> manipulate durations. One example of where it diverts from the ISO
> standard, is that it implements microseconds. Microseconds in a *duration*
> are stored in the same format as in the time calendar types, meaning they
> integrate well and provide consistency.
>
> Shift
> The shift behaviour is implemented as a callback on Calendar and supported
> by all calendar types: Date, DateTime, NaiveDateTime and Time. Date, Time
> and NaiveDateTime each have their own implementation of a "shift", while
> DateTime gets converted to a NaiveDateTime before applying the shift, and
> is then rebuilt to a DateTime in its original timezone. `shift/2-3` also
> has guaranteed output types (which isn't a given in many libraries) and
> follows the consistent API which is established in the calendar modules.
>
> Find the current state of the implementation here:
> https://github.com/elixir-lang/elixir/pull/13385
>
> *Benchmarks*
>
> There are some benchmarks + StreamData tests in the PR description.
>
> *Outlook*
>
> *After  *adding the Duration type and shift behaviour to the standard
> library, the following things could be explored and derived from the
> initial work:
>
>
>    - Implementing a protocol that allows Duration to be applied to any
>    data type, not just dates and times.
>    - A range-like data type that allows us to do recurring constructs on
>    any data type. For example, Duration.interval(~D[2000-01-01], month: 1),
>    when iterated, would emit {:ok, date} | {:error, start, duration,
>    reason} entries
>    - A sigil for easy creation of durations: ~P[3 hours and 10 minutes]
>    - Making it so add/2-3 reuses the shift_* functions
>
> *Reasons against it*
>
> While I am convinced that adding `shift/2-3` to the standard library would
> be very beneficial, nothing really speaks against the points mentioned
> above to be implemented in a library instead. However, something as crucial
> and central as date/time manipulation should still be part of the standard
> library, negating the risk of breaking changes, inconsistent behaviour and
> outdated or too unique ergonomics which aren't widely applicable, unlike
> what should be part of the standard library.
>
> Many thanks to @jose & @kip for the initial reviews and everyone in
> advance taking the time to read the proposal!
>
> Looking forward to hear other peoples ideas and opinions on the subject!
>
> --
> You received this message because you are subscribed to the Google Groups
> "elixir-lang-core" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to elixir-lang-core+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/elixir-lang-core/cb0ed628-3848-4de0-aa13-c0f4761e4d99n%40googlegroups.com
> <https://groups.google.com/d/msgid/elixir-lang-core/cb0ed628-3848-4de0-aa13-c0f4761e4d99n%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elixir-lang-core+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4%2BNmFsMhbkRubMjnmM8c_Amq8DgmKCJtzJ1GEuM4-sVgw%40mail.gmail.com.

Reply via email to