@@ -1611,30 +1611,42 @@ defmodule DateTime do
16111611 @ doc """
16121612 Adds a specified amount of time to a `DateTime`.
16131613
1614+ > #### Prefer `shift/2` {: .info}
1615+ >
1616+ > Prefer `shift/2` over `add/3`, as it offers a more ergonomic API.
1617+ >
1618+ > `add/3` provides a lower-level API which only supports fixed units
1619+ > such as `:hour` and `:second`, but not `:month` (as the exact length
1620+ > of a month depends on the current month). `add/3` always considers
1621+ > the unit to be computed according to the `Calendar.ISO`.
1622+
16141623 Accepts an `amount_to_add` in any `unit`. `unit` can be `:day`,
16151624 `:hour`, `:minute`, `:second` or any subsecond precision from
16161625 `t:System.time_unit/0`. It defaults to `:second`. Negative values
16171626 will move backwards in time.
16181627
1619- This function always considers the unit to be computed according
1620- to the `Calendar.ISO`.
1621-
16221628 This function relies on a contiguous representation of time,
1623- ignoring the wall time and timezone changes. For example, if you add
1624- one day when there are summer time/daylight saving time changes,
1625- it will also change the time forward or backward by one hour,
1626- so the elapsed time is precisely 24 hours. Similarly, adding just
1627- a few seconds to a datetime just before "spring forward" can cause
1628- wall time to increase by more than an hour.
1629+ ignoring timezone changes. For example, if you add one day when there
1630+ are summer time/daylight saving time changes, it will also change the
1631+ time forward or backward by one hour, so the elapsed time is precisely
1632+ 24 hours. Similarly, adding just a few seconds to a datetime just before
1633+ "spring forward" can cause wall time to increase by more than an hour.
16291634
16301635 While this means this function is precise in terms of elapsed time,
1631- its result may be misleading in certain use cases. For example, if a
1636+ its result may be confusing in certain use cases. For example, if a
16321637 user requests a meeting to happen every day at 15:00 and you use this
16331638 function to compute all future meetings by adding day after day, this
16341639 function may change the meeting time to 14:00 or 16:00 if there are
1635- changes to the current timezone. Computing of recurring datetimes is
1636- not currently supported in Elixir's standard library but it is available
1637- by third-party libraries.
1640+ changes to the current timezone.
1641+
1642+ In case you don't want these changes to happen automatically or you
1643+ want to surface time zone conflicts to the user, you can add to
1644+ the datetime as a naive datetime and then use `from_naive/2`:
1645+
1646+ dt |> NaiveDateTime.add(1, :day) |> DateTime.from_naive(dt.time_zone)
1647+
1648+ The above will surface time jumps and ambiguous datetimes, allowing you
1649+ to deal with them accordingly.
16381650
16391651 ## Examples
16401652
@@ -1664,8 +1676,6 @@ defmodule DateTime do
16641676 iex> result.microsecond
16651677 {21000, 3}
16661678
1667- To shift a datetime by a `Duration` and according to its underlying calendar, use `DateTime.shift/3`.
1668-
16691679 """
16701680 @ doc since: "1.8.0"
16711681 @ spec add (
@@ -1739,7 +1749,7 @@ defmodule DateTime do
17391749 to UTC, and finally computing the new timezone in case of shifts.
17401750 This ensures `shift/3` always returns a valid datetime.
17411751
1742- On the other hand , time zones that observe "Daylight Saving Time"
1752+ Consequently , time zones that observe "Daylight Saving Time"
17431753 or other changes, across summer/winter time will add/remove hours
17441754 from the resulting datetime:
17451755
@@ -1751,12 +1761,22 @@ defmodule DateTime do
17511761 DateTime.shift(dt, hour: 2)
17521762 #=> #DateTime<2018-11-04 01:00:00-08:00 PST America/Los_Angeles>
17531763
1764+ Although the first example shows a difference of 2 hours when
1765+ comparing the wall clocks of the given datetime with the returned one,
1766+ due to the "spring forward" time jump, the actual ellapsed time is
1767+ still exactly of 1 hour.
1768+
17541769 In case you don't want these changes to happen automatically or you
17551770 want to surface time zone conflicts to the user, you can shift
17561771 the datetime as a naive datetime and then use `from_naive/2`:
17571772
17581773 dt |> NaiveDateTime.shift(duration) |> DateTime.from_naive(dt.time_zone)
17591774
1775+ The above will surface time jumps and ambiguous datetimes, allowing you
1776+ to deal with them accordingly.
1777+
1778+ ## ISO calendar considerations
1779+
17601780 When using the default ISO calendar, durations are collapsed and
17611781 applied in the order of months, then seconds and microseconds:
17621782
0 commit comments