/
utils.ex
166 lines (135 loc) · 4.51 KB
/
utils.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
defmodule Sanbase.DateTimeUtils do
def after_interval(interval, datetime \\ DateTime.utc_now()) when is_binary(interval) do
compound_duration_to_seconds(interval) |> seconds_after(datetime)
end
def seconds_after(seconds, datetime \\ DateTime.utc_now()) do
datetime
|> Timex.shift(seconds: seconds)
end
def days_after(days, datetime \\ DateTime.utc_now()) do
seconds_after(days * 60 * 60 * 24, datetime)
end
def seconds_ago(seconds, datetime \\ DateTime.utc_now()) do
datetime
|> Timex.shift(seconds: -seconds)
end
def minutes_ago(minutes) do
seconds_ago(minutes * 60)
end
def hours_ago(hours) do
seconds_ago(hours * 60 * 60)
end
def days_ago(days) do
seconds_ago(days * 60 * 60 * 24)
end
def start_of_day(datetime \\ DateTime.utc_now()) do
%DateTime{datetime | hour: 0, minute: 0, second: 0, microsecond: {0, 0}}
end
# Interval should be an integer followed by one of: s, m, h, d or w
def str_to_sec(interval) do
interval_type = String.last(interval)
String.slice(interval, 0..-2)
|> String.to_integer()
|> str_to_sec(interval_type)
end
def str_to_hours(interval) do
str_to_sec(interval) |> Integer.floor_div(3600)
end
defp str_to_sec(seconds, "s"), do: seconds
defp str_to_sec(minutes, "m"), do: minutes * 60
defp str_to_sec(hours, "h"), do: hours * 60 * 60
defp str_to_sec(days, "d"), do: days * 60 * 60 * 24
defp str_to_sec(weeks, "w"), do: weeks * 60 * 60 * 24 * 7
def ecto_date_to_datetime(ecto_date) do
{:ok, datetime, _} =
(Ecto.Date.to_iso8601(ecto_date) <> "T00:00:00Z") |> DateTime.from_iso8601()
datetime
end
def compund_duration_to_tuple(interval) do
{int_interval, duration_index} = Integer.parse(interval)
duration_type =
case duration_index do
"ns" -> :nanoseconds
"ms" -> :milliseconds
"s" -> :seconds
"m" -> :minutes
"h" -> :hours
"d" -> :days
"w" -> :weeks
_ -> nil
end
{int_interval, duration_type}
end
def compound_duration_to_seconds(interval) do
{int_interval, duration_index} = Integer.parse(interval)
case duration_index do
"ns" -> div(int_interval, 1_000_000_000)
"ms" -> div(int_interval, 1_000_000)
"s" -> int_interval
"m" -> int_interval * 60
"h" -> int_interval * 60 * 60
"d" -> int_interval * 24 * 60 * 60
"w" -> int_interval * 7 * 24 * 60 * 60
_ -> int_interval
end
end
def compound_duration_to_days(interval) do
interval_in_seconds = compound_duration_to_seconds(interval)
one_day_in_seconds = 3600 * 24
div(interval_in_seconds, one_day_in_seconds)
end
def compound_duration_to_hours(interval) do
interval_in_seconds = compound_duration_to_seconds(interval)
one_hour_in_seconds = 3600
div(interval_in_seconds, one_hour_in_seconds)
end
def compound_duration_to_text(interval) do
{int_interval, duration_index} = Integer.parse(interval)
case duration_index do
"ns" -> "#{int_interval} nanosecond(s)"
"ms" -> "#{int_interval} millisecond(s)"
"s" -> "#{int_interval} second(s)"
"m" -> "#{int_interval} minute(s)"
"h" -> "#{int_interval} hour(s)"
"d" -> "#{int_interval} day(s)"
"w" -> "#{int_interval} week(s)"
end
end
def valid_compound_duration?(value) do
case Integer.parse(value) do
{int, string} when is_integer(int) and string in ["ns", "s", "m", "h", "d", "w"] -> true
_ -> false
end
end
def from_erl(erl_datetime) do
with {:ok, naive_dt} <- NaiveDateTime.from_erl(erl_datetime),
{:ok, datetime} <- DateTime.from_naive(naive_dt, "Etc/UTC") do
{:ok, datetime}
end
end
def from_erl!(erl_datetime) do
case from_erl(erl_datetime) do
{:ok, datetime} -> datetime
{:error, error} -> raise(error)
end
end
def from_iso8601!(datetime_str) when is_binary(datetime_str) do
{:ok, datetime, _} = DateTime.from_iso8601(datetime_str)
datetime
end
def from_iso8601_to_unix!(datetime_str) do
datetime_str
|> from_iso8601!()
|> DateTime.to_unix()
end
def valid_interval_string?(interval_string) when not is_binary(interval_string) do
{:error, "The provided string #{interval_string} is not a valid string interval"}
end
def valid_interval_string?(interval_string) when is_binary(interval_string) do
if Regex.match?(~r/^\d+[smhdw]{1}$/, interval_string) do
true
else
{:error, "The provided string #{interval_string} is not a valid string interval"}
end
end
end