Skip to content

Commit 0864738

Browse files
Support precision in NaiveDateTime/DateTime.utc_now (#12558)
1 parent 151caab commit 0864738

File tree

2 files changed

+80
-5
lines changed

2 files changed

+80
-5
lines changed

lib/elixir/lib/calendar/datetime.ex

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,16 +147,55 @@ defmodule DateTime do
147147
If you want the current time in Unix seconds,
148148
use `System.os_time/1` instead.
149149
150+
You can also pass a time unit to automatically
151+
truncate the resulting datetime. This is available
152+
since v1.15.0.
153+
150154
## Examples
151155
152156
iex> datetime = DateTime.utc_now()
153157
iex> datetime.time_zone
154158
"Etc/UTC"
155159
160+
iex> datetime = DateTime.utc_now(:second)
161+
iex> datetime.microsecond
162+
{0, 0}
163+
164+
"""
165+
@spec utc_now(Calendar.calendar() | :native | :microsecond | :millisecond | :second) :: t
166+
def utc_now(calendar_or_time_unit \\ Calendar.ISO) do
167+
case calendar_or_time_unit do
168+
unit when unit in [:microsecond, :millisecond, :second, :native] ->
169+
utc_now(unit, Calendar.ISO)
170+
171+
calendar ->
172+
utc_now(:native, calendar)
173+
end
174+
end
175+
176+
@doc """
177+
Returns the current datetime in UTC, supporting
178+
a specific calendar and precision.
179+
180+
If you want the current time in Unix seconds,
181+
use `System.os_time/1` instead.
182+
183+
## Examples
184+
185+
iex> datetime = DateTime.utc_now(:microsecond, Calendar.ISO)
186+
iex> datetime.time_zone
187+
"Etc/UTC"
188+
189+
iex> datetime = DateTime.utc_now(:second, Calendar.ISO)
190+
iex> datetime.microsecond
191+
{0, 0}
192+
156193
"""
157-
@spec utc_now(Calendar.calendar()) :: t
158-
def utc_now(calendar \\ Calendar.ISO) do
159-
System.os_time() |> from_unix!(:native, calendar)
194+
@doc since: "1.15.0"
195+
@spec utc_now(:native | :microsecond | :millisecond | :second, Calendar.calendar()) :: t
196+
def utc_now(time_unit, calendar)
197+
when time_unit in [:native, :microsecond, :millisecond, :second] do
198+
System.os_time(time_unit) |> from_unix!(time_unit, calendar)
160199
end
161200

162201
@doc """

lib/elixir/lib/calendar/naive_datetime.ex

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,16 +92,23 @@ defmodule NaiveDateTime do
9292
Prefer using `DateTime.utc_now/0` when possible as, opposite
9393
to `NaiveDateTime`, it will keep the time zone information.
9494
95+
You can also provide a time unit to automatically truncate
96+
the naive datetime. This is available since v1.15.0.
97+
9598
## Examples
9699
97100
iex> naive_datetime = NaiveDateTime.utc_now()
98101
iex> naive_datetime.year >= 2016
99102
true
100103
104+
iex> naive_datetime = NaiveDateTime.utc_now(:second)
105+
iex> naive_datetime.microsecond
106+
{0, 0}
107+
101108
"""
102109
@doc since: "1.4.0"
103-
@spec utc_now(Calendar.calendar()) :: t
104-
def utc_now(calendar \\ Calendar.ISO)
110+
@spec utc_now(Calendar.calendar() | :native | :microsecond | :millisecond | :second) :: t
111+
def utc_now(calendar_or_time_unit \\ Calendar.ISO)
105112

106113
def utc_now(Calendar.ISO) do
107114
{:ok, {year, month, day}, {hour, minute, second}, microsecond} =
@@ -119,12 +126,41 @@ defmodule NaiveDateTime do
119126
}
120127
end
121128

129+
def utc_now(time_unit) when time_unit in [:microsecond, :millisecond, :second, :native] do
130+
utc_now(time_unit, Calendar.ISO)
131+
end
132+
122133
def utc_now(calendar) do
123134
calendar
124135
|> DateTime.utc_now()
125136
|> DateTime.to_naive()
126137
end
127138

139+
@doc """
140+
Returns the current naive datetime in UTC, supporting a specific
141+
calendar and precision.
142+
143+
Prefer using `DateTime.utc_now/2` when possible as, opposite
144+
to `NaiveDateTime`, it will keep the time zone information.
145+
146+
## Examples
147+
148+
iex> naive_datetime = NaiveDateTime.utc_now(:second, Calendar.ISO)
149+
iex> naive_datetime.year >= 2016
150+
true
151+
152+
iex> naive_datetime = NaiveDateTime.utc_now(:second, Calendar.ISO)
153+
iex> naive_datetime.microsecond
154+
{0, 0}
155+
156+
"""
157+
@doc since: "1.15.0"
158+
@spec utc_now(:native | :microsecond | :millisecond | :second, Calendar.calendar()) :: t
159+
def utc_now(time_unit, calendar)
160+
when time_unit in [:native, :microsecond, :millisecond, :second] do
161+
DateTime.utc_now(time_unit, calendar) |> DateTime.to_naive()
162+
end
163+
128164
@doc """
129165
Returns the "local time" for the machine the Elixir program is running on.
130166

0 commit comments

Comments
 (0)