@@ -1611,30 +1611,42 @@ defmodule DateTime do
1611
1611
@ doc """
1612
1612
Adds a specified amount of time to a `DateTime`.
1613
1613
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
+
1614
1623
Accepts an `amount_to_add` in any `unit`. `unit` can be `:day`,
1615
1624
`:hour`, `:minute`, `:second` or any subsecond precision from
1616
1625
`t:System.time_unit/0`. It defaults to `:second`. Negative values
1617
1626
will move backwards in time.
1618
1627
1619
- This function always considers the unit to be computed according
1620
- to the `Calendar.ISO`.
1621
-
1622
1628
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.
1629
1634
1630
1635
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
1632
1637
user requests a meeting to happen every day at 15:00 and you use this
1633
1638
function to compute all future meetings by adding day after day, this
1634
1639
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.
1638
1650
1639
1651
## Examples
1640
1652
@@ -1664,8 +1676,6 @@ defmodule DateTime do
1664
1676
iex> result.microsecond
1665
1677
{21000, 3}
1666
1678
1667
- To shift a datetime by a `Duration` and according to its underlying calendar, use `DateTime.shift/3`.
1668
-
1669
1679
"""
1670
1680
@ doc since: "1.8.0"
1671
1681
@ spec add (
@@ -1739,7 +1749,7 @@ defmodule DateTime do
1739
1749
to UTC, and finally computing the new timezone in case of shifts.
1740
1750
This ensures `shift/3` always returns a valid datetime.
1741
1751
1742
- On the other hand , time zones that observe "Daylight Saving Time"
1752
+ Consequently , time zones that observe "Daylight Saving Time"
1743
1753
or other changes, across summer/winter time will add/remove hours
1744
1754
from the resulting datetime:
1745
1755
@@ -1751,12 +1761,22 @@ defmodule DateTime do
1751
1761
DateTime.shift(dt, hour: 2)
1752
1762
#=> #DateTime<2018-11-04 01:00:00-08:00 PST America/Los_Angeles>
1753
1763
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
+
1754
1769
In case you don't want these changes to happen automatically or you
1755
1770
want to surface time zone conflicts to the user, you can shift
1756
1771
the datetime as a naive datetime and then use `from_naive/2`:
1757
1772
1758
1773
dt |> NaiveDateTime.shift(duration) |> DateTime.from_naive(dt.time_zone)
1759
1774
1775
+ The above will surface time jumps and ambiguous datetimes, allowing you
1776
+ to deal with them accordingly.
1777
+
1778
+ ## ISO calendar considerations
1779
+
1760
1780
When using the default ISO calendar, durations are collapsed and
1761
1781
applied in the order of months, then seconds and microseconds:
1762
1782
0 commit comments