jamesmintram
I have been reading the docs for Elixir’s Date/DateTime libraries but I cannot find a way to calculate a date which is either N months or N years before/after a particular date.
Date.add/2 appears to only accept days.
DateTime.add/3 will only accept “up to” :seconds
Can someone point me in the right direction?
Trending in Questions
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
Hello,
I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
So my question is quite simple and i have found no conclusive answer on forum, google or AI.
Should we use :erlang.float for Integer to ...
New
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New
apply_graft/2 doesn’t rewrite an add_many sub-workflow’s deps on an add step. Grafted jobs cancel with “upstream job was deleted”
Version...
New
Other Trending Topics
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hi there! We created Gust: A task orchestrator inspired by Airflow.
For those who have never heard about Aiflow, it’s a Python-based wor...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve.
They are GUI (Emerge) and State management (S...
New
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #ai
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming











Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
hubertlepicki
I generally use third party library for this, although maybe it’s possible withing standard library these days, but I default to
Timex.shiftfromtimexlibrary:kip
ex_cldr_calendars also provides the ability to add date parts to dates: Cldr.Calendar — Cldr Calendars v2.4.4
josevalim
I would love to have this feature in Elixir. To me it is really the last pending feature in the Calendar module. It seems it is a simple contract on a function called “plus”, which I would call “shift” instead.
@kip, how are the rules generated in your case? Automatically from CLDR? Is there a way we could see the rules converted to Elixir code for the ISO calendar?
Thank you!
kip
@josevalim, there’s no CLDR dependency on this part - its all straight
Calendarcallbacks.The only part that is tricky is what to do with something like
Calendar.shift ~[2016-02-29], :year, 1. It is an invalid result?In my implementation I have an option
:coerceto force a valid date at the end of the target month. I’ve never liked it. Suggestions very welcome on how to handle this.Happy to draft a PR for this, its not very complicated other than that issue.
cmo
Timex has the concept of ambiguous datetimes, which force you to decide whether you want to take the earlier or later time.
LostKobrakai
Same on DateTime.shift_zone.
josevalim
The ambiguous DateTime is about daylight summer time, which is a separate issue from invalid dates. That’s because shift should be considered a shift on the wall clock instead of shifting the data in a contiguous line. This implies two things:
For the second one, which was the one @kip mentioned, I suggest handling it with as a rounding operation, so we can either round :up or :down. I would pick :down as the default so you always land within the same month. Note this applies for quarter/month/year shifting.
For example, adding one day to Feb 28th is always March 1st. No invalid date is built in the process. Adding one month to Jan 31st should be Feb 28th (unless you have a leap year).
This further introduces complication related to commutative property of those operators. For example:
That’s why shifting operations are often done with durations, because you need to express the whole operation in one tackle. For example, consider the difference between:
However, things get a bit trickier once you consider 1 year and -1 day. Do you remove the day from the resolved date or from the invalid date? E.g. which one is the desired result?
I think it should be the first. So my proposal would be to start with:
shift_options is a keyword list with year, quarter, month, week, day, and round. shift_options will be applied on the order of highest to lower (i.e. the order defined above). Once you apply any of year/quarter/month, you need to round to a valid date. Then add week/day as wall clock shifts too.
We could support hour/minute/second too, but because we are strictly talking about wall-clock shifts, they have to be implemented as wall-clock shifts instead of operations on iso days, which is slightly annoying.
Besides the contiguous time interpretation existing in
addtoday, another difference between this and theaddfunction is that we will consider the definition of duration/interval specific to your calendar whileaddalways adds a unit of value specific to the gregorian calendar.I would also suggest starting with the implementation for NaiveDateTime, and then move to DateTime and Date next. If you agree @kip, a pull request is welcome!
LostKobrakai
All those complications are why I’m excited about alternative approaches explored by calendar_interval [1] or being explored with tempo.
Adding “1 month” to a date can mean many things like for example:
I’d love an API, which can express the difference in meaning without feeling overly imperative. The last two of my examples in my mind are much more a variant of:
This however becomes more complicated once not just a single “unit of time” is added, but multiple ones and the precisions need to be taken at multiple levels of the addition.
1: https://www.youtube.com/watch?v=Zm95cYAtAa8
josevalim
Unfortunately I don’t think those libraries solve the problems I described above (@wojtekmach and @kip, pls correct me if I am wrong).
They do help expressing more complex constructs and how to compose and interpret them. However, all of the challenges in my previous comment already picked a unique answer for the question of what adding “1 month” means, which is:
After that, we still need to answer the following questions:
what are the order of operations in a single interval? The order you add the units and round them matter. Maybe those libraries propose a semantic order already, which we could copy.
What is your interpretation of time when it comes to days/seconds and timezones? Time may mean two things: wall-clock and a contiguous line. Working on the contiguous line is much easier but surprising, because it means adding 1 day during daylight saving time is actually adding 23 hours or 25 hours. A wall-clock operation would literally shift the day and return ambiguity errors if it falls exactly during dst.
And the second question in paticular is not answered in the libraries above (afaik).
LostKobrakai
I don’t think so as well – hence the “exploring” verb – but they feel closer to allowing users to express the different interpretations instead of the specific implementation picking one.