-
Notifications
You must be signed in to change notification settings - Fork 405
Expand file tree
/
Copy pathprotocol.ex
More file actions
300 lines (236 loc) · 11.4 KB
/
protocol.ex
File metadata and controls
300 lines (236 loc) · 11.4 KB
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
defprotocol Timex.Protocol do
@moduledoc """
This protocol defines the API for functions which take a `Date`,
`NaiveDateTime`, or `DateTime` as input.
"""
@fallback_to_any true
alias Timex.Types
@doc """
Convert a date/time value to a Julian calendar date number
"""
@spec to_julian(Types.valid_datetime) :: float | {:error, term}
def to_julian(datetime)
@doc """
Convert a date/time value to gregorian seconds (seconds since start of year zero)
"""
@spec to_gregorian_seconds(Types.valid_datetime) :: non_neg_integer | {:error, term}
def to_gregorian_seconds(datetime)
@doc """
Convert a date/time value to gregorian microseconds (microseconds since the start of year zero)
"""
@spec to_gregorian_microseconds(Types.valid_datetime) :: non_neg_integer | {:error, term}
def to_gregorian_microseconds(datetime)
@doc """
Convert a date/time value to seconds since the UNIX Epoch
"""
@spec to_unix(Types.valid_datetime) :: non_neg_integer | {:error, term}
def to_unix(datetime)
@doc """
Convert a date/time value to a Date
"""
@spec to_date(Types.valid_datetime) :: Date.t | {:error, term}
def to_date(datetime)
@doc """
Convert a date/time value to a DateTime.
An optional timezone can be provided, UTC will be assumed if one is not provided.
"""
@spec to_datetime(Types.valid_datetime) :: DateTime.t | {:error, term}
@spec to_datetime(Types.valid_datetime, Types.valid_timezone) ::
DateTime.t | Timex.AmbiguousDateTime.t | {:error, term}
def to_datetime(datetime, timezone \\ :utc)
@doc """
Convert a date/time value to a NaiveDateTime
"""
@spec to_naive_datetime(Types.valid_datetime) :: NaiveDateTime.t | {:error, term}
def to_naive_datetime(datetime)
@doc """
Convert a date/time value to it's Erlang tuple variant
i.e. Date becomes `{y,m,d}`, DateTime/NaiveDateTime become
`{{y,m,d},{h,mm,s}}`
"""
@spec to_erl(Types.valid_datetime) :: Types.date | Types.datetime | {:error, term}
def to_erl(datetime)
@doc """
Get the century a date/time value is in
"""
@spec century(Types.year | Types.valid_datetime) :: non_neg_integer | {:error, term}
def century(datetime)
@doc """
Return a boolean indicating whether the date/time value is in a leap year
"""
@spec is_leap?(Types.valid_datetime | Types.year) :: boolean | {:error, term}
def is_leap?(datetime)
@doc """
Shift a date/time value using a list of shift unit/value pairs
"""
@spec shift(Types.valid_datetime, Timex.shift_options) ::
Types.valid_datetime | Timex.AmbiguousDateTime.t | {:error, term}
def shift(datetime, options)
@doc """
Set fields on a date/time value using a list of unit/value pairs
"""
@spec set(Types.valid_datetime, Timex.set_options) :: Types.valid_datetime | {:error, term}
def set(datetime, options)
@doc """
Get a new version of the date/time value representing the beginning of the day
"""
@spec beginning_of_day(Types.valid_datetime) :: Types.valid_datetime | {:error, term}
def beginning_of_day(datetime)
@doc """
Get a new version of the date/time value representing the end of the day
"""
@spec end_of_day(Types.valid_datetime) :: Types.valid_datetime | {:error, term}
def end_of_day(datetime)
@doc """
Get a new version of the date/time value representing the beginning of it's week,
providing a weekday name (as an atom) for the day which starts the week, i.e. `:mon`.
"""
@spec beginning_of_week(Types.valid_datetime, Types.weekstart) :: Types.valid_datetime | {:error, term}
def beginning_of_week(datetime, weekstart)
@doc """
Get a new version of the date/time value representing the ending of it's week,
providing a weekday name (as an atom) for the day which starts the week, i.e. `:mon`.
"""
@spec end_of_week(Types.valid_datetime, Types.weekstart) :: Types.valid_datetime | {:error, term}
def end_of_week(datetime, weekstart)
@doc """
Get a new version of the date/time value representing the beginning of it's year
"""
@spec beginning_of_year(Types.year | Types.valid_datetime) :: Types.valid_datetime | {:error, term}
def beginning_of_year(datetime)
@doc """
Get a new version of the date/time value representing the ending of it's year
"""
@spec end_of_year(Types.year | Types.valid_datetime) :: Types.valid_datetime | {:error, term}
def end_of_year(datetime)
@doc """
Get a new version of the date/time value representing the beginning of it's quarter
"""
@spec beginning_of_quarter(Types.valid_datetime) :: Types.valid_datetime | {:error, term}
def beginning_of_quarter(datetime)
@doc """
Get a new version of the date/time value representing the ending of it's quarter
"""
@spec end_of_quarter(Types.valid_datetime) :: Types.valid_datetime | {:error, term}
def end_of_quarter(datetime)
@doc """
Get a new version of the date/time value representing the beginning of it's month
"""
@spec beginning_of_month(Types.valid_datetime) :: Types.valid_datetime | {:error, term}
def beginning_of_month(datetime)
@doc """
Get a new version of the date/time value representing the ending of it's month
"""
@spec end_of_month(Types.valid_datetime) :: Types.valid_datetime | {:error, term}
def end_of_month(datetime)
@doc """
Get the quarter for the given date/time value
"""
@spec quarter(Types.month | Types.valid_datetime) :: 1..4 | {:error, term}
def quarter(datetime)
@doc """
Get the number of days in the month for the given date/time value
"""
@spec days_in_month(Types.valid_datetime) :: Types.num_of_days | {:error, term}
def days_in_month(datetime)
@doc """
Get the week number of the given date/time value, starting at 1
"""
@spec week_of_month(Types.valid_datetime) :: Types.week_of_month | {:error, term}
def week_of_month(datetime)
@doc """
Get the ordinal weekday number of the given date/time value
"""
@spec weekday(Types.valid_datetime) :: Types.weekday | {:error, term}
def weekday(datetime)
@doc """
Get the ordinal day number of the given date/time value
"""
@spec day(Types.valid_datetime) :: Types.daynum | {:error, term}
def day(datetime)
@doc """
Get the English ordinal suffix (st, nd, rd, th) of the given date/time value
"""
@spec ordinal_suffix(Types.valid_datetime) :: Types.daynum | {:error, term}
def ordinal_suffix(datetime)
@doc """
Determine if the provided date/time value is valid.
"""
@spec is_valid?(Types.valid_datetime) :: boolean | {:error, term}
def is_valid?(datetime)
@doc """
Return a pair {year, week number} (as defined by ISO 8601) that the given date/time value falls on.
"""
@spec iso_week(Types.valid_datetime) :: {Types.year, Types.weeknum} | {:error, term}
def iso_week(datetime)
@doc """
Shifts the given date/time value to the ISO day given
"""
@spec from_iso_day(Types.valid_datetime, non_neg_integer) ::
Types.valid_datetime | {:error, term}
def from_iso_day(datetime, day)
end
defimpl Timex.Protocol, for: Any do
def to_julian(%{__struct__: _} = d), do: Timex.to_julian(Map.from_struct(d))
def to_julian(_datetime), do: {:error, :invalid_date}
def to_gregorian_seconds(%{__struct__: _} = d), do: Timex.to_gregorian_seconds(Map.from_struct(d))
def to_gregorian_seconds(_datetime), do: {:error, :invalid_date}
def to_gregorian_microseconds(%{__struct__: _} = d), do: Timex.to_gregorian_microseconds(Map.from_struct(d))
def to_gregorian_microseconds(_datetime), do: {:error, :invalid_date}
def to_unix(%{__struct__: _} = d), do: Timex.to_unix(Map.from_struct(d))
def to_unix(_datetime), do: {:error, :invalid_date}
def to_date(%{__struct__: _} = d), do: Timex.to_date(Map.from_struct(d))
def to_date(_datetime), do: {:error, :invalid_date}
def to_datetime(%{__struct__: _} = d, timezone), do: Timex.to_datetime(Map.from_struct(d), timezone)
def to_datetime(_datetime, _timezone), do: {:error, :invalid_date}
def to_naive_datetime(%{__struct__: _} = d), do: Timex.to_naive_datetime(Map.from_struct(d))
def to_naive_datetime(_datetime), do: {:error, :invalid_date}
def to_erl(%{__struct__: _} = d), do: Timex.to_erl(Map.from_struct(d))
def to_erl(_datetime), do: {:error, :invalid_date}
def century(%{__struct__: _} = d), do: Timex.century(Map.from_struct(d))
def century(_datetime), do: {:error, :invalid_date}
def is_leap?(%{__struct__: _} = d), do: Timex.is_leap?(Map.from_struct(d))
def is_leap?(_datetime), do: {:error, :invalid_date}
def shift(%{__struct__: _} = d, options), do: Timex.shift(Map.from_struct(d), options)
def shift(_datetime, _options), do: {:error, :invalid_date}
def set(%{__struct__: _} = d, options), do: Timex.set(Map.from_struct(d), options)
def set(_datetime, _options), do: {:error, :invalid_date}
def beginning_of_day(%{__struct__: _} = d), do: Timex.beginning_of_day(Map.from_struct(d))
def beginning_of_day(_datetime), do: {:error, :invalid_date}
def end_of_day(%{__struct__: _} = d), do: Timex.end_of_day(Map.from_struct(d))
def end_of_day(_datetime), do: {:error, :invalid_date}
def beginning_of_week(%{__struct__: _} = d, weekstart), do: Timex.beginning_of_week(Map.from_struct(d), weekstart)
def beginning_of_week(_datetime, _weekstart), do: {:error, :invalid_date}
def end_of_week(%{__struct__: _} = d, weekstart), do: Timex.end_of_week(Map.from_struct(d), weekstart)
def end_of_week(_datetime, _weekstart), do: {:error, :invalid_date}
def beginning_of_year(%{__struct__: _} = d), do: Timex.beginning_of_year(Map.from_struct(d))
def beginning_of_year(_datetime), do: {:error, :invalid_date}
def end_of_year(%{__struct__: _} = d), do: Timex.end_of_year(Map.from_struct(d))
def end_of_year(_datetime), do: {:error, :invalid_date}
def beginning_of_quarter(%{__struct__: _} = d), do: Timex.beginning_of_quarter(Map.from_struct(d))
def beginning_of_quarter(_datetime), do: {:error, :invalid_date}
def end_of_quarter(%{__struct__: _} = d), do: Timex.end_of_quarter(Map.from_struct(d))
def end_of_quarter(_datetime), do: {:error, :invalid_date}
def beginning_of_month(%{__struct__: _} = d), do: Timex.beginning_of_month(Map.from_struct(d))
def beginning_of_month(_datetime), do: {:error, :invalid_date}
def end_of_month(%{__struct__: _} = d), do: Timex.end_of_month(Map.from_struct(d))
def end_of_month(_datetime), do: {:error, :invalid_date}
def quarter(%{__struct__: _} = d), do: Timex.quarter(Map.from_struct(d))
def quarter(_datetime), do: {:error, :invalid_date}
def days_in_month(%{__struct__: _} = d), do: Timex.days_in_month(Map.from_struct(d))
def days_in_month(_datetime), do: {:error, :invalid_date}
def week_of_month(%{__struct__: _} = d), do: Timex.week_of_month(Map.from_struct(d))
def week_of_month(_datetime), do: {:error, :invalid_date}
def weekday(%{__struct__: _} = d), do: Timex.weekday(Map.from_struct(d))
def weekday(_datetime), do: {:error, :invalid_date}
def day(%{__struct__: _} = d), do: Timex.day(Map.from_struct(d))
def day(_datetime), do: {:error, :invalid_date}
def ordinal_suffix(%{__struct__: _} = d), do: Timex.ordinal_suffix(Map.from_struct(d))
def ordinal_suffix(_datetime), do: {:error, :invalid_date}
def is_valid?(%{__struct__: _} = d), do: Timex.is_valid?(Map.from_struct(d))
def is_valid?(_datetime), do: false
def iso_week(%{__struct__: _} = d), do: Timex.iso_week(Map.from_struct(d))
def iso_week(_datetime), do: {:error, :invalid_date}
def from_iso_day(%{__struct__: _} = d, _day), do: Timex.from_iso_day(Map.from_struct(d))
def from_iso_day(_datetime, _day), do: {:error, :invalid_date}
end