Packages
livebook
0.8.0
0.19.8
0.19.7
0.19.6
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.6
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.3
0.17.2
0.17.1
0.17.0
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.14.0-rc.1
0.14.0-rc.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.2
0.1.1
0.1.0
Automate code & data workflows with interactive notebooks
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/livebook/utils/time.ex
defmodule Livebook.Utils.Time do
@moduledoc false
# A simplified version of https://gist.github.com/tlemens/88e9b08f62150ba6082f478a4a03ac52
@doc """
Formats the given point in time relatively to present.
"""
@spec time_ago_in_words(NaiveDateTime.t()) :: String.t()
def time_ago_in_words(naive_date_time) when is_struct(naive_date_time, NaiveDateTime) do
now = NaiveDateTime.utc_now()
if NaiveDateTime.compare(naive_date_time, now) == :gt do
raise ArgumentError, "expected a datetime in the past, got: #{inspect(naive_date_time)}"
end
distance_of_time_in_words(naive_date_time, now)
end
@doc """
Formats time distance between `from_ndt` and `to_ndt`
as a human-readable string.
## Examples
iex> Livebook.Utils.Time.distance_of_time_in_words(~N[2020-06-20 18:15:00], ~N[2020-06-20 18:15:04])
"less than 5 seconds"
iex> Livebook.Utils.Time.distance_of_time_in_words(~N[2020-06-20 18:15:00], ~N[2020-06-20 18:15:09])
"less than 10 seconds"
iex> Livebook.Utils.Time.distance_of_time_in_words(~N[2020-06-20 18:15:00], ~N[2020-06-20 18:15:19])
"less than 20 seconds"
iex> Livebook.Utils.Time.distance_of_time_in_words(~N[2020-06-20 18:15:00], ~N[2020-06-20 18:15:20])
"half a minute"
iex> Livebook.Utils.Time.distance_of_time_in_words(~N[2020-06-20 18:15:00], ~N[2020-06-20 18:15:39])
"half a minute"
iex> Livebook.Utils.Time.distance_of_time_in_words(~N[2020-06-20 18:15:00], ~N[2020-06-20 18:15:40])
"less than a minute"
iex> Livebook.Utils.Time.distance_of_time_in_words(~N[2020-06-20 18:15:00], ~N[2020-06-20 18:15:59])
"less than a minute"
iex> Livebook.Utils.Time.distance_of_time_in_words(~N[2020-06-20 18:15:00], ~N[2020-06-20 18:16:00])
"1 minute"
iex> Livebook.Utils.Time.distance_of_time_in_words(~N[2020-06-20 18:15:00], ~N[2020-06-20 18:16:29])
"1 minute"
iex> Livebook.Utils.Time.distance_of_time_in_words(~N[2020-06-20 18:15:00], ~N[2020-06-20 18:16:30])
"2 minutes"
iex> Livebook.Utils.Time.distance_of_time_in_words(~N[2020-06-20 18:15:00], ~N[2020-06-20 18:58:30])
"44 minutes"
iex> Livebook.Utils.Time.distance_of_time_in_words(~N[2020-06-20 18:15:00], ~N[2020-06-20 18:59:30])
"about 1 hour"
iex> Livebook.Utils.Time.distance_of_time_in_words(~N[2020-06-20 18:15:00], ~N[2020-06-20 19:59:30])
"about 2 hours"
iex> Livebook.Utils.Time.distance_of_time_in_words(~N[2020-06-20 18:15:00], ~N[2020-06-21 18:14:00])
"about 24 hours"
iex> Livebook.Utils.Time.distance_of_time_in_words(~N[2020-06-20 18:15:00], ~N[2020-06-21 18:15:00])
"1 day"
iex> Livebook.Utils.Time.distance_of_time_in_words(~N[2020-06-20 18:15:00], ~N[2020-06-22 18:15:00])
"2 days"
iex> Livebook.Utils.Time.distance_of_time_in_words(~N[2020-06-20 18:15:00], ~N[2020-07-22 18:15:00])
"about 1 month"
iex> Livebook.Utils.Time.distance_of_time_in_words(~N[2020-06-20 18:15:00], ~N[2021-08-22 18:15:00])
"about 14 months"
"""
@spec distance_of_time_in_words(NaiveDateTime.t(), NaiveDateTime.t()) :: String.t()
def distance_of_time_in_words(from_ndt, to_ndt)
when is_struct(from_ndt, NaiveDateTime) and is_struct(to_ndt, NaiveDateTime) do
duration_seconds = NaiveDateTime.diff(to_ndt, from_ndt)
{:seconds, duration_seconds}
|> maybe_convert_to_minutes()
|> duration_in_words()
end
defp maybe_convert_to_minutes({:seconds, seconds}) when seconds > 59 do
{:minutes, round(seconds / 60)}
end
defp maybe_convert_to_minutes(duration), do: duration
defp duration_in_words({:seconds, seconds}) when seconds in 0..4 do
"less than 5 seconds"
end
defp duration_in_words({:seconds, seconds}) when seconds in 5..9 do
"less than 10 seconds"
end
defp duration_in_words({:seconds, seconds}) when seconds in 10..19 do
"less than 20 seconds"
end
defp duration_in_words({:seconds, seconds}) when seconds in 20..39 do
"half a minute"
end
defp duration_in_words({:seconds, seconds}) when seconds in 40..59 do
"less than a minute"
end
defp duration_in_words({:minutes, minutes}) when minutes == 1 do
"1 minute"
end
defp duration_in_words({:minutes, minutes}) when minutes in 2..44 do
"#{minutes} minutes"
end
defp duration_in_words({:minutes, minutes}) when minutes in 45..89 do
"about 1 hour"
end
# 90 mins up to 24 hours
defp duration_in_words({:minutes, minutes}) when minutes in 90..1439 do
"about #{round(minutes / 60)} hours"
end
# 24 hours up to 42 hours
defp duration_in_words({:minutes, minutes}) when minutes in 1440..2519 do
"1 day"
end
# 42 hours up to 30 days
defp duration_in_words({:minutes, minutes}) when minutes in 2520..43_199 do
"#{round(minutes / 1440)} days"
end
# 30 days up to 45 days
defp duration_in_words({:minutes, minutes}) when minutes in 43_200..64_799 do
"about 1 month"
end
# 45 days up to 60 days
defp duration_in_words({:minutes, minutes}) when minutes in 64_800..86_399 do
"about 2 months"
end
defp duration_in_words({:minutes, minutes}) do
"about #{round(minutes / 43_200)} months"
end
end