summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVinícius Müller <vinigm.nho@gmail.com>2023-05-11 11:33:42 -0300
committerGitHub <noreply@github.com>2023-05-11 16:33:42 +0200
commit08647385a6e4da572cbe508df9d73cc48704a382 (patch)
tree281f920786c14186033220a95cb92cb4a8dc4376
parent151caab673fae5091a06e820456a2f0f065f5e57 (diff)
downloadelixir-08647385a6e4da572cbe508df9d73cc48704a382.tar.gz
Support precision in NaiveDateTime/DateTime.utc_now (#12558)
-rw-r--r--lib/elixir/lib/calendar/datetime.ex45
-rw-r--r--lib/elixir/lib/calendar/naive_datetime.ex40
2 files changed, 80 insertions, 5 deletions
diff --git a/lib/elixir/lib/calendar/datetime.ex b/lib/elixir/lib/calendar/datetime.ex
index 4c1d6ef6b..44d74dee3 100644
--- a/lib/elixir/lib/calendar/datetime.ex
+++ b/lib/elixir/lib/calendar/datetime.ex
@@ -147,16 +147,55 @@ defmodule DateTime do
If you want the current time in Unix seconds,
use `System.os_time/1` instead.
+ You can also pass a time unit to automatically
+ truncate the resulting datetime. This is available
+ since v1.15.0.
+
## Examples
iex> datetime = DateTime.utc_now()
iex> datetime.time_zone
"Etc/UTC"
+ iex> datetime = DateTime.utc_now(:second)
+ iex> datetime.microsecond
+ {0, 0}
+
+ """
+ @spec utc_now(Calendar.calendar() | :native | :microsecond | :millisecond | :second) :: t
+ def utc_now(calendar_or_time_unit \\ Calendar.ISO) do
+ case calendar_or_time_unit do
+ unit when unit in [:microsecond, :millisecond, :second, :native] ->
+ utc_now(unit, Calendar.ISO)
+
+ calendar ->
+ utc_now(:native, calendar)
+ end
+ end
+
+ @doc """
+ Returns the current datetime in UTC, supporting
+ a specific calendar and precision.
+
+ If you want the current time in Unix seconds,
+ use `System.os_time/1` instead.
+
+ ## Examples
+
+ iex> datetime = DateTime.utc_now(:microsecond, Calendar.ISO)
+ iex> datetime.time_zone
+ "Etc/UTC"
+
+ iex> datetime = DateTime.utc_now(:second, Calendar.ISO)
+ iex> datetime.microsecond
+ {0, 0}
+
"""
- @spec utc_now(Calendar.calendar()) :: t
- def utc_now(calendar \\ Calendar.ISO) do
- System.os_time() |> from_unix!(:native, calendar)
+ @doc since: "1.15.0"
+ @spec utc_now(:native | :microsecond | :millisecond | :second, Calendar.calendar()) :: t
+ def utc_now(time_unit, calendar)
+ when time_unit in [:native, :microsecond, :millisecond, :second] do
+ System.os_time(time_unit) |> from_unix!(time_unit, calendar)
end
@doc """
diff --git a/lib/elixir/lib/calendar/naive_datetime.ex b/lib/elixir/lib/calendar/naive_datetime.ex
index 611905824..9c53ab4c5 100644
--- a/lib/elixir/lib/calendar/naive_datetime.ex
+++ b/lib/elixir/lib/calendar/naive_datetime.ex
@@ -92,16 +92,23 @@ defmodule NaiveDateTime do
Prefer using `DateTime.utc_now/0` when possible as, opposite
to `NaiveDateTime`, it will keep the time zone information.
+ You can also provide a time unit to automatically truncate
+ the naive datetime. This is available since v1.15.0.
+
## Examples
iex> naive_datetime = NaiveDateTime.utc_now()
iex> naive_datetime.year >= 2016
true
+ iex> naive_datetime = NaiveDateTime.utc_now(:second)
+ iex> naive_datetime.microsecond
+ {0, 0}
+
"""
@doc since: "1.4.0"
- @spec utc_now(Calendar.calendar()) :: t
- def utc_now(calendar \\ Calendar.ISO)
+ @spec utc_now(Calendar.calendar() | :native | :microsecond | :millisecond | :second) :: t
+ def utc_now(calendar_or_time_unit \\ Calendar.ISO)
def utc_now(Calendar.ISO) do
{:ok, {year, month, day}, {hour, minute, second}, microsecond} =
@@ -119,6 +126,10 @@ defmodule NaiveDateTime do
}
end
+ def utc_now(time_unit) when time_unit in [:microsecond, :millisecond, :second, :native] do
+ utc_now(time_unit, Calendar.ISO)
+ end
+
def utc_now(calendar) do
calendar
|> DateTime.utc_now()
@@ -126,6 +137,31 @@ defmodule NaiveDateTime do
end
@doc """
+ Returns the current naive datetime in UTC, supporting a specific
+ calendar and precision.
+
+ Prefer using `DateTime.utc_now/2` when possible as, opposite
+ to `NaiveDateTime`, it will keep the time zone information.
+
+ ## Examples
+
+ iex> naive_datetime = NaiveDateTime.utc_now(:second, Calendar.ISO)
+ iex> naive_datetime.year >= 2016
+ true
+
+ iex> naive_datetime = NaiveDateTime.utc_now(:second, Calendar.ISO)
+ iex> naive_datetime.microsecond
+ {0, 0}
+
+ """
+ @doc since: "1.15.0"
+ @spec utc_now(:native | :microsecond | :millisecond | :second, Calendar.calendar()) :: t
+ def utc_now(time_unit, calendar)
+ when time_unit in [:native, :microsecond, :millisecond, :second] do
+ DateTime.utc_now(time_unit, calendar) |> DateTime.to_naive()
+ end
+
+ @doc """
Returns the "local time" for the machine the Elixir program is running on.
WARNING: This function can cause insidious bugs. It depends on the time zone