Packages

Erlang library for conversion from one local time to another based on google cctz

Current section

Files

Jump to
elocaltime src elocaltime.erl
Raw

src/elocaltime.erl

-module(elocaltime).
-include("elocaltime.hrl").
-export([
start/0,
start/1,
stop/0,
civil_lookup/2,
absolute_lookup/2,
utc2local_datetime/2,
utc2local_ts/2,
local2utc_ts/3,
local2utc_datetime/3,
is_timezone_valid/1,
format/2,
format/3
]).
-type reason() :: any().
-type datetime() :: calendar:datetime() | timestamp().
-type timezone() :: binary() | ?TIMEZONE_UTC | ?TIMEZONE_LOCAL | ?TIMEZONE_FIXED(integer()).
-type disambiguation() :: ?DS_STANDARD | ?DS_DAYLIGHT | ?DS_BOTH.
-type absolute_lookup() :: #absolute_lookup{}.
-type civil_lookup() :: #civil_lookup{}.
-spec start() ->
ok | {error, reason()}.
start() ->
start(temporary).
-spec start(permanent | transient | temporary) ->
ok | {error, reason()}.
start(Type) ->
case application:ensure_all_started(elocaltime, Type) of
{ok, _} ->
ok;
Other ->
Other
end.
-spec stop() ->
ok.
stop() ->
application:stop(elocaltime).
-spec civil_lookup(datetime(), timezone()) ->
{ok, civil_lookup()} | {error, reason()}.
civil_lookup(Date, Timezone) ->
case elocaltime_timezone:get_tz(Timezone) of
{ok, TzRef} ->
elocaltime_nif:civil_lookup(to_datetime(Date), TzRef);
Error ->
Error
end.
-spec absolute_lookup(datetime(), timezone()) ->
{ok, absolute_lookup()} | {error, reason()}.
absolute_lookup(Date, Timezone) ->
case elocaltime_timezone:get_tz(Timezone) of
{ok, TzRef} ->
elocaltime_nif:absolute_lookup(to_seconds(Date), TzRef);
Error ->
Error
end.
-spec utc2local_datetime(datetime(), timezone()) ->
{ok, calendar:datetime()} | {error, reason()}.
utc2local_datetime(Date, Timezone) ->
case absolute_lookup(Date, Timezone) of
{ok, #absolute_lookup{date = LocalDate}} ->
{ok, LocalDate};
Error ->
Error
end.
-spec utc2local_ts(datetime(), timezone()) ->
{ok, timestamp()} | {error, reason()}.
utc2local_ts(Date, Timezone) ->
case utc2local_datetime(Date, Timezone) of
{ok, DateTime} ->
{ok, elocaltime_utils:datetime2ts(DateTime)};
Error ->
Error
end.
-spec local2utc_ts(datetime(), timezone(), disambiguation()) ->
{ok, timestamp()} | {ok, timestamp(), timestamp()} | {error, reason()}.
local2utc_ts(Date, Timezone, Disambiguation) ->
case civil_lookup(Date, Timezone) of
{ok, CivilLookup} ->
disambiguation(CivilLookup, Disambiguation);
Error ->
Error
end.
-spec local2utc_datetime(datetime(), timezone(), disambiguation()) ->
{ok, calendar:datetime()} | {ok, calendar:datetime(), calendar:datetime()} | {error, reason()}.
local2utc_datetime(Date, Timezone, Disambiguation) ->
case local2utc_ts(Date, Timezone, Disambiguation) of
{ok, Dt} ->
{ok, elocaltime_utils:ts2datetime(Dt)};
{ok, DtPre, DtPost} ->
{ok, elocaltime_utils:ts2datetime(DtPre), elocaltime_utils:ts2datetime(DtPost)};
Error ->
Error
end.
-spec is_timezone_valid(timezone()) ->
boolean().
is_timezone_valid(Timezone) ->
elocaltime_timezone:is_valid(Timezone).
-spec format(binary(), datetime()) ->
{ok, binary()}.
format(Format, DateTime) ->
elocaltime_nif:format(Format, to_seconds(DateTime)).
-spec format(binary(), datetime(), timezone()) ->
{ok, binary()}.
format(Format, DateTime, Timezone) ->
case elocaltime_timezone:get_tz(Timezone) of
{ok, TzRef} ->
elocaltime_nif:format(Format, to_seconds(DateTime), TzRef);
Error ->
Error
end.
%private
-spec disambiguation(civil_lookup(), disambiguation()) ->
{ok, timestamp()} | {ok, timestamp(), timestamp()}.
disambiguation(#civil_lookup{civil_kind = Kind, pre = Pre, trans = _Trans, post = Post}, Disambiguation) ->
case Kind of
?CIVIL_KIND_UNIQUE ->
{ok, Pre};
_ ->
case Disambiguation of
?DS_STANDARD ->
{ok, Pre};
?DS_DAYLIGHT ->
{ok, Post};
?DS_BOTH ->
{ok, Pre, Post}
end
end.
-spec to_seconds(datetime()) ->
timestamp().
to_seconds(V) when is_integer(V) ->
V;
to_seconds(V) ->
elocaltime_utils:datetime2ts(V).
-spec to_datetime(datetime()) ->
calendar:datetime().
to_datetime(V) when is_integer(V) ->
elocaltime_utils:ts2datetime(V);
to_datetime(V) ->
V.