@@ -31,21 +31,21 @@ defmodule Tzdata do
31
31
zone_list provides a list of all the zone names that can be used with
32
32
DateTime. This includes aliases.
33
33
"""
34
- @ spec zone_list ( ) :: [ Calendar . time_zone ]
35
- def zone_list , do: Tzdata.ReleaseReader . zone_and_link_list
34
+ @ spec zone_list ( ) :: [ Calendar . time_zone ( ) ]
35
+ def zone_list , do: Tzdata.ReleaseReader . zone_and_link_list ( )
36
36
37
37
@ doc """
38
38
Like zone_list, but excludes aliases for zones.
39
39
"""
40
- @ spec canonical_zone_list ( ) :: [ Calendar . time_zone ]
41
- def canonical_zone_list , do: Tzdata.ReleaseReader . zone_list
40
+ @ spec canonical_zone_list ( ) :: [ Calendar . time_zone ( ) ]
41
+ def canonical_zone_list , do: Tzdata.ReleaseReader . zone_list ( )
42
42
43
43
@ doc """
44
44
A list of aliases for zone names. For instance Europe/Jersey
45
45
is an alias for Europe/London. Aliases are also known as linked zones.
46
46
"""
47
- @ spec zone_alias_list ( ) :: [ Calendar . time_zone ]
48
- def zone_alias_list , do: Tzdata.ReleaseReader . link_list
47
+ @ spec zone_alias_list ( ) :: [ Calendar . time_zone ( ) ]
48
+ def zone_alias_list , do: Tzdata.ReleaseReader . link_list ( )
49
49
50
50
@ doc """
51
51
Takes the name of a zone. Returns true if zone exists. Otherwise false.
@@ -57,7 +57,7 @@ defmodule Tzdata do
57
57
iex> Tzdata.zone_exists? "Europe/Jersey"
58
58
true
59
59
"""
60
- @ spec zone_exists? ( String . t ) :: boolean ( )
60
+ @ spec zone_exists? ( String . t ( ) ) :: boolean ( )
61
61
def zone_exists? ( name ) , do: Enum . member? ( zone_list ( ) , name )
62
62
63
63
@ doc """
@@ -69,7 +69,7 @@ defmodule Tzdata do
69
69
iex> Tzdata.canonical_zone? "Europe/Jersey"
70
70
false
71
71
"""
72
- @ spec canonical_zone? ( Calendar . time_zone ) :: boolean ( )
72
+ @ spec canonical_zone? ( Calendar . time_zone ( ) ) :: boolean ( )
73
73
def canonical_zone? ( name ) , do: Enum . member? ( canonical_zone_list ( ) , name )
74
74
75
75
@ doc """
@@ -81,7 +81,7 @@ defmodule Tzdata do
81
81
iex> Tzdata.zone_alias? "Europe/London"
82
82
false
83
83
"""
84
- @ spec zone_alias? ( Calendar . time_zone ) :: boolean ( )
84
+ @ spec zone_alias? ( Calendar . time_zone ( ) ) :: boolean ( )
85
85
def zone_alias? ( name ) , do: Enum . member? ( zone_alias_list ( ) , name )
86
86
87
87
@ doc """
@@ -90,16 +90,16 @@ defmodule Tzdata do
90
90
iex> Tzdata.links["Europe/Jersey"]
91
91
"Europe/London"
92
92
"""
93
- @ spec links ( ) :: % { Calendar . time_zone => Calendar . time_zone }
94
- def links , do: Tzdata.ReleaseReader . links
93
+ @ spec links ( ) :: % { Calendar . time_zone ( ) => Calendar . time_zone ( ) }
94
+ def links , do: Tzdata.ReleaseReader . links ( )
95
95
96
96
@ doc """
97
97
Returns a map with keys being group names and the values lists of
98
98
time zone names. The group names mirror the file names used by the tzinfo
99
99
database.
100
100
"""
101
- @ spec zone_lists_grouped ( ) :: % { atom ( ) => [ Calendar . time_zone ] }
102
- def zone_lists_grouped , do: Tzdata.ReleaseReader . by_group
101
+ @ spec zone_lists_grouped ( ) :: % { atom ( ) => [ Calendar . time_zone ( ) ] }
102
+ def zone_lists_grouped , do: Tzdata.ReleaseReader . by_group ( )
103
103
104
104
@ doc """
105
105
Returns tzdata release version as a string.
@@ -109,8 +109,8 @@ defmodule Tzdata do
109
109
Tzdata.tzdata_version
110
110
"2014i"
111
111
"""
112
- @ spec tzdata_version ( ) :: String . t
113
- def tzdata_version , do: Tzdata.ReleaseReader . release_version
112
+ @ spec tzdata_version ( ) :: String . t ( )
113
+ def tzdata_version , do: Tzdata.ReleaseReader . release_version ( )
114
114
115
115
@ doc """
116
116
Returns a list of periods for the `zone_name` provided as an argument.
@@ -138,12 +138,14 @@ defmodule Tzdata do
138
138
iex> Tzdata.periods("Not existing")
139
139
{:error, :not_found}
140
140
"""
141
- @ spec periods ( Calendar . time_zone ) :: { :ok , [ time_zone_period ] } | { :error , atom ( ) }
141
+ @ spec periods ( Calendar . time_zone ( ) ) :: { :ok , [ time_zone_period ] } | { :error , atom ( ) }
142
142
def periods ( zone_name ) do
143
143
{ tag , p } = Tzdata.ReleaseReader . periods_for_zone_or_link ( zone_name )
144
+
144
145
case tag do
145
146
:ok ->
146
- mapped_p = for { _ , f_utc , f_wall , f_std , u_utc , u_wall , u_std , utc_off , std_off , zone_abbr } <- p do
147
+ mapped_p =
148
+ for { _ , f_utc , f_wall , f_std , u_utc , u_wall , u_std , utc_off , std_off , zone_abbr } <- p do
147
149
% {
148
150
std_off: std_off ,
149
151
utc_off: utc_off ,
@@ -152,8 +154,11 @@ defmodule Tzdata do
152
154
zone_abbr: zone_abbr
153
155
}
154
156
end
157
+
155
158
{ :ok , mapped_p }
156
- _ -> { :error , p }
159
+
160
+ _ ->
161
+ { :error , p }
157
162
end
158
163
end
159
164
@@ -191,15 +196,18 @@ defmodule Tzdata do
191
196
iex> Tzdata.periods_for_time("Europe/Copenhagen", 63594816000, :wall)
192
197
[]
193
198
"""
194
- @ spec periods_for_time ( Calendar . time_zone , gregorian_seconds , :standard | :wall | :utc ) :: [ time_zone_period ] | { :error , term }
199
+ @ spec periods_for_time ( Calendar . time_zone ( ) , gregorian_seconds , :standard | :wall | :utc ) ::
200
+ [ time_zone_period ] | { :error , term }
195
201
def periods_for_time ( zone_name , time_point , time_type ) do
196
202
case possible_periods_for_zone_and_time ( zone_name , time_point , time_type ) do
197
203
{ :ok , periods } ->
198
204
match_fn = fn % { from: from , until: until } ->
199
205
smaller_than_or_equals ( Map . get ( from , time_type ) , time_point ) &&
200
206
bigger_than ( Map . get ( until , time_type ) , time_point )
201
207
end
208
+
202
209
do_consecutive_matching ( periods , match_fn , [ ] , false )
210
+
203
211
{ :error , _ } = error ->
204
212
error
205
213
end
@@ -210,49 +218,62 @@ defmodule Tzdata do
210
218
# remaining list.
211
219
defp do_consecutive_matching ( [ ] , _fun , [ ] , _did_last_match ) , do: [ ]
212
220
defp do_consecutive_matching ( [ ] , _fun , matched , _did_last_match ) , do: matched
221
+
213
222
defp do_consecutive_matching ( _list , _fun , matched , false ) when matched != [ ] do
214
223
# If there are matches and previous did not match then the matches are no
215
224
# long consecutive. So we return the result.
216
- matched |> Enum . reverse
225
+ matched |> Enum . reverse ( )
217
226
end
218
- defp do_consecutive_matching ( [ h | t ] , fun , matched , _did_last_match ) do
227
+
228
+ defp do_consecutive_matching ( [ h | t ] , fun , matched , _did_last_match ) do
219
229
if fun . ( h ) == true do
220
- do_consecutive_matching ( t , fun , [ h | matched ] , true )
230
+ do_consecutive_matching ( t , fun , [ h | matched ] , true )
221
231
else
222
232
do_consecutive_matching ( t , fun , matched , false )
223
233
end
224
234
end
225
235
226
236
# Use dynamic periods for points in time that are about 40 years into the future
227
237
@ years_in_the_future_where_precompiled_periods_are_used 40
228
- @ point_from_which_to_use_dynamic_periods :calendar . datetime_to_gregorian_seconds { { ( :calendar . universal_time |> elem ( 0 ) |> elem ( 0 ) ) + @ years_in_the_future_where_precompiled_periods_are_used , 1 , 1 } , { 0 , 0 , 0 } }
229
- defp possible_periods_for_zone_and_time ( zone_name , time_point , time_type ) when time_point >= @ point_from_which_to_use_dynamic_periods do
238
+ @ point_from_which_to_use_dynamic_periods :calendar . datetime_to_gregorian_seconds (
239
+ { { ( :calendar . universal_time ( ) |> elem ( 0 ) |> elem ( 0 ) ) +
240
+ @ years_in_the_future_where_precompiled_periods_are_used ,
241
+ 1 , 1 } , { 0 , 0 , 0 } }
242
+ )
243
+ defp possible_periods_for_zone_and_time ( zone_name , time_point , time_type )
244
+ when time_point >= @ point_from_which_to_use_dynamic_periods do
230
245
if Tzdata.FarFutureDynamicPeriods . zone_in_30_years_in_eternal_period? ( zone_name ) do
231
246
periods ( zone_name )
232
247
else
233
- link_status = Tzdata.ReleaseReader . links |> Map . get ( zone_name )
248
+ link_status = Tzdata.ReleaseReader . links ( ) |> Map . get ( zone_name )
249
+
234
250
if link_status == nil do
235
251
Tzdata.FarFutureDynamicPeriods . periods_for_point_in_time ( time_point , zone_name )
236
252
else
237
253
possible_periods_for_zone_and_time ( link_status , time_point , time_type )
238
254
end
239
255
end
240
256
end
257
+
241
258
defp possible_periods_for_zone_and_time ( zone_name , time_point , time_type ) do
242
- { :ok , periods } = Tzdata.ReleaseReader . periods_for_zone_time_and_type ( zone_name , time_point , time_type )
243
- mapped_periods = periods
244
- |> Enum . sort_by ( fn { _ , from_utc , _ , _ , _ , _ , _ , _ , _ , _ } -> - ( from_utc |> Tzdata.ReleaseReader . delimiter_to_number ) end )
245
- |> Enum . map (
246
- fn { _ , f_utc , f_wall , f_std , u_utc , u_wall , u_std , utc_off , std_off , zone_abbr } ->
247
- % {
248
- std_off: std_off ,
249
- utc_off: utc_off ,
250
- from: % { utc: f_utc , wall: f_wall , standard: f_std } ,
251
- until: % { utc: u_utc , standard: u_std , wall: u_wall } ,
252
- zone_abbr: zone_abbr
253
- }
254
- end
255
- )
259
+ { :ok , periods } =
260
+ Tzdata.ReleaseReader . periods_for_zone_time_and_type ( zone_name , time_point , time_type )
261
+
262
+ mapped_periods =
263
+ periods
264
+ |> Enum . sort_by ( fn { _ , from_utc , _ , _ , _ , _ , _ , _ , _ , _ } ->
265
+ - ( from_utc |> Tzdata.ReleaseReader . delimiter_to_number ( ) )
266
+ end )
267
+ |> Enum . map ( fn { _ , f_utc , f_wall , f_std , u_utc , u_wall , u_std , utc_off , std_off , zone_abbr } ->
268
+ % {
269
+ std_off: std_off ,
270
+ utc_off: utc_off ,
271
+ from: % { utc: f_utc , wall: f_wall , standard: f_std } ,
272
+ until: % { utc: u_utc , standard: u_std , wall: u_wall } ,
273
+ zone_abbr: zone_abbr
274
+ }
275
+ end )
276
+
256
277
{ :ok , mapped_periods }
257
278
end
258
279
@@ -270,7 +291,7 @@ defmodule Tzdata do
270
291
"""
271
292
@ spec leap_seconds_with_tai_diff ( ) :: [ % { date_time: :calendar . datetime ( ) , tai_diff: integer } ]
272
293
def leap_seconds_with_tai_diff do
273
- leap_seconds_data = Tzdata.ReleaseReader . leap_sec_data
294
+ leap_seconds_data = Tzdata.ReleaseReader . leap_sec_data ( )
274
295
leap_seconds_data . leap_seconds
275
296
end
276
297
@@ -305,7 +326,7 @@ defmodule Tzdata do
305
326
"""
306
327
@ spec leap_second_data_valid_until ( ) :: :calendar . datetime ( )
307
328
def leap_second_data_valid_until do
308
- leap_seconds_data = Tzdata.ReleaseReader . leap_sec_data
329
+ leap_seconds_data = Tzdata.ReleaseReader . leap_sec_data ( )
309
330
leap_seconds_data . valid_until
310
331
end
311
332
0 commit comments