mirror of
https://github.com/valitydev/rfc3339.git
synced 2024-11-06 08:35:17 +00:00
Added function parse_to_local_datetime/1
To utilize parse/1 but to give you {date(), time()} in the local timezone
This commit is contained in:
parent
6bbdfe6c41
commit
a539c15aaa
18
.gitignore
vendored
Normal file
18
.gitignore
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
.rebar3
|
||||||
|
_*
|
||||||
|
.eunit
|
||||||
|
*.o
|
||||||
|
*.beam
|
||||||
|
*.plt
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
.erlang.cookie
|
||||||
|
ebin
|
||||||
|
*.log
|
||||||
|
erl_crash.dump
|
||||||
|
.rebar
|
||||||
|
_build
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
rebar3.crashdump
|
||||||
|
rebar.lock
|
44
README.md
Normal file → Executable file
44
README.md
Normal file → Executable file
@ -2,7 +2,49 @@
|
|||||||
|
|
||||||
parse and format rfc3339 strings in elixir and erlang
|
parse and format rfc3339 strings in elixir and erlang
|
||||||
|
|
||||||
|
## Installing as a rebar depedancy (erlang)
|
||||||
|
|
||||||
|
You install it as a rebar dependency by adding the following in the deps section of rebar.config
|
||||||
|
|
||||||
|
```erlang
|
||||||
|
{rfc3339, {git, "git://github.com/talentdeficit/rfc3339.git", {branch, master}}}
|
||||||
|
```
|
||||||
|
## building
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rebar3 compile
|
||||||
|
```
|
||||||
|
|
||||||
|
## running
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rebar3 shell
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## erlang usage
|
||||||
|
|
||||||
|
###### parse_to_local_datetime
|
||||||
|
|
||||||
|
```erlang
|
||||||
|
> rfc3339:parse_to_local_datetime(<<"1996-12-19T16:39:57-08:00">>).
|
||||||
|
{{1996,12,19},{10,39,57}}
|
||||||
|
```
|
||||||
|
|
||||||
|
###### parse
|
||||||
|
```erlang
|
||||||
|
> rfc3339:parse(<<"1937-01-01T12:00:27.87+00:20">>).
|
||||||
|
{ok,{{1937,1,1},{12,0,27},870000,20}}
|
||||||
|
```
|
||||||
|
|
||||||
|
###### format
|
||||||
|
```erlang
|
||||||
|
> rfc3339:format({date(), time()}).
|
||||||
|
{ok,<<"2016-07-02T14:04:39Z">>}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## todo
|
## todo
|
||||||
|
|
||||||
* everything
|
-[ ] everything
|
||||||
|
300
src/rfc3339.erl
300
src/rfc3339.erl
@ -1,6 +1,7 @@
|
|||||||
|
% vim: sw=4 ts=4 et ft=erlang
|
||||||
-module(rfc3339).
|
-module(rfc3339).
|
||||||
|
|
||||||
-export([parse/1]).
|
-export([parse/1,parse_to_local_datetime/1]).
|
||||||
-export([format/1, format/2]).
|
-export([format/1, format/2]).
|
||||||
-export([to_map/1]).
|
-export([to_map/1]).
|
||||||
-export([to_time/1, to_time/2]).
|
-export([to_time/1, to_time/2]).
|
||||||
@ -25,6 +26,17 @@
|
|||||||
|
|
||||||
-type error() :: badarg | baddate | badtime | badyear | badday | badhour | badminute | badsecond | badusec | badtimezone.
|
-type error() :: badarg | baddate | badtime | badyear | badday | badhour | badminute | badsecond | badusec | badtimezone.
|
||||||
|
|
||||||
|
%% -spec parse_to_local_datetime(binary()) -> {date(), time()}
|
||||||
|
parse_to_local_datetime(Bin) ->
|
||||||
|
{ok, {Date, Time, _, TZ}} = parse(Bin),
|
||||||
|
TZSecs = calendar:datetime_to_gregorian_seconds({Date, Time}),
|
||||||
|
UTCDateTime = calendar:gregorian_seconds_to_datetime(case TZ of
|
||||||
|
_ when is_integer(TZ) ->
|
||||||
|
TZSecs + (60*TZ);
|
||||||
|
_ ->
|
||||||
|
TZSecs
|
||||||
|
end),
|
||||||
|
calendar:universal_time_to_local_time(UTCDateTime).
|
||||||
|
|
||||||
-spec parse(binary()) -> {ok, {date(), time(), usec(), tz()}} | {error, error()}.
|
-spec parse(binary()) -> {ok, {date(), time(), usec(), tz()}} | {error, error()}.
|
||||||
parse(Bin) when is_binary(Bin) -> date(Bin, {undefined, undefined, undefined, undefined});
|
parse(Bin) when is_binary(Bin) -> date(Bin, {undefined, undefined, undefined, undefined});
|
||||||
@ -32,10 +44,10 @@ parse(_) -> {error, badarg}.
|
|||||||
|
|
||||||
-spec to_map(binary()) -> {ok, map()} | {error, error()}.
|
-spec to_map(binary()) -> {ok, map()} | {error, error()}.
|
||||||
to_map(Bin) when is_binary(Bin) ->
|
to_map(Bin) when is_binary(Bin) ->
|
||||||
case parse(Bin) of
|
case parse(Bin) of
|
||||||
{ok, {Date, Time, USec, Tz}} -> mapify(Date, Time, USec, Tz, #{});
|
{ok, {Date, Time, USec, Tz}} -> mapify(Date, Time, USec, Tz, #{});
|
||||||
{error, Error} -> {error, Error}
|
{error, Error} -> {error, Error}
|
||||||
end;
|
end;
|
||||||
to_map(_) -> {error, badarg}.
|
to_map(_) -> {error, badarg}.
|
||||||
|
|
||||||
-spec to_time(binary()) -> {ok, integer()} | {error, error()}.
|
-spec to_time(binary()) -> {ok, integer()} | {error, error()}.
|
||||||
@ -43,30 +55,30 @@ to_time(Bin) when is_binary(Bin) -> to_time(Bin, native).
|
|||||||
|
|
||||||
-spec to_time(binary(), erlang:time_unit()) -> {ok, integer()} | {error, error()}.
|
-spec to_time(binary(), erlang:time_unit()) -> {ok, integer()} | {error, error()}.
|
||||||
to_time(Bin, Unit) when is_binary(Bin) ->
|
to_time(Bin, Unit) when is_binary(Bin) ->
|
||||||
case parse(Bin) of
|
case parse(Bin) of
|
||||||
{ok, {Date, {Hour, Min, Sec}, USec, Tz}} ->
|
{ok, {Date, {Hour, Min, Sec}, USec, Tz}} ->
|
||||||
Epoch = calendar:datetime_to_gregorian_seconds({{1970, 1, 1}, {0, 0, 0}}),
|
Epoch = calendar:datetime_to_gregorian_seconds({{1970, 1, 1}, {0, 0, 0}}),
|
||||||
Time = {Hour, Min + or_zero(Tz), Sec},
|
Time = {Hour, Min + or_zero(Tz), Sec},
|
||||||
GregorianSeconds = calendar:datetime_to_gregorian_seconds({Date, Time}),
|
GregorianSeconds = calendar:datetime_to_gregorian_seconds({Date, Time}),
|
||||||
U = erlang:convert_time_unit(or_zero(USec), micro_seconds, Unit),
|
U = erlang:convert_time_unit(or_zero(USec), micro_seconds, Unit),
|
||||||
{ok, erlang:convert_time_unit(GregorianSeconds - Epoch, seconds, Unit) + U};
|
{ok, erlang:convert_time_unit(GregorianSeconds - Epoch, seconds, Unit) + U};
|
||||||
{error, Error} -> {error, Error}
|
{error, Error} -> {error, Error}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
mapify({Year, Month, Day}, Time, USec, Tz, Result)
|
mapify({Year, Month, Day}, Time, USec, Tz, Result)
|
||||||
when is_integer(Year), is_integer(Month), is_integer(Day) ->
|
when is_integer(Year), is_integer(Month), is_integer(Day) ->
|
||||||
mapify(Time, USec, Tz, maps:merge(Result, #{year => Year, month => Month, day => Day}));
|
mapify(Time, USec, Tz, maps:merge(Result, #{year => Year, month => Month, day => Day}));
|
||||||
mapify(_, _, _, _, _) -> {error, badarg}.
|
mapify(_, _, _, _, _) -> {error, badarg}.
|
||||||
|
|
||||||
mapify({Hour, Min, Sec}, USec, Tz, Result)
|
mapify({Hour, Min, Sec}, USec, Tz, Result)
|
||||||
when is_integer(Hour), is_integer(Min), is_integer(Sec) ->
|
when is_integer(Hour), is_integer(Min), is_integer(Sec) ->
|
||||||
mapify(USec, Tz, maps:merge(Result, #{hour => Hour, min => Min, sec => Sec}));
|
mapify(USec, Tz, maps:merge(Result, #{hour => Hour, min => Min, sec => Sec}));
|
||||||
mapify(_, _, _, _) -> {error, badarg}.
|
mapify(_, _, _, _) -> {error, badarg}.
|
||||||
|
|
||||||
mapify(undefined, Tz, Result) -> mapify(Tz, Result);
|
mapify(undefined, Tz, Result) -> mapify(Tz, Result);
|
||||||
mapify(USec, Tz, Result) when is_integer(USec) ->
|
mapify(USec, Tz, Result) when is_integer(USec) ->
|
||||||
mapify(Tz, maps:merge(Result, #{usec => USec}));
|
mapify(Tz, maps:merge(Result, #{usec => USec}));
|
||||||
mapify(_, _, _) -> {error, badarg}.
|
mapify(_, _, _) -> {error, badarg}.
|
||||||
|
|
||||||
mapify(undefined, Result) -> Result;
|
mapify(undefined, Result) -> Result;
|
||||||
@ -74,95 +86,95 @@ mapify(Tz, Result) when is_integer(Tz) -> maps:merge(Result, #{tz_offset => Tz})
|
|||||||
mapify(_, _) -> {error, badarg}.
|
mapify(_, _) -> {error, badarg}.
|
||||||
|
|
||||||
mapify(Time) when is_integer(Time) ->
|
mapify(Time) when is_integer(Time) ->
|
||||||
Epoch = calendar:datetime_to_gregorian_seconds({{1970, 1, 1}, {0, 0, 0}}),
|
Epoch = calendar:datetime_to_gregorian_seconds({{1970, 1, 1}, {0, 0, 0}}),
|
||||||
GregorianSeconds = Time div 1000000 + Epoch,
|
GregorianSeconds = Time div 1000000 + Epoch,
|
||||||
{{Year, Month, Day}, {Hour, Min, Sec}} = calendar:gregorian_seconds_to_datetime(GregorianSeconds),
|
{{Year, Month, Day}, {Hour, Min, Sec}} = calendar:gregorian_seconds_to_datetime(GregorianSeconds),
|
||||||
USec = Time rem 1000000,
|
USec = Time rem 1000000,
|
||||||
#{year => Year, month => Month, day => Day, hour => Hour, min => Min, sec => Sec, usec => USec};
|
#{year => Year, month => Month, day => Day, hour => Hour, min => Min, sec => Sec, usec => USec};
|
||||||
mapify(_) -> {error, badarg}.
|
mapify(_) -> {error, badarg}.
|
||||||
|
|
||||||
-spec format(map() | {date(), time(), usec(), tz()} | datetime() | integer()) -> {ok, binary()} | {error, error()}.
|
-spec format(map() | {date(), time(), usec(), tz()} | datetime() | integer()) -> {ok, binary()} | {error, error()}.
|
||||||
format({Date, Time, USec, Tz})
|
format({Date, Time, USec, Tz})
|
||||||
when is_tuple(Date), is_tuple(Time) ->
|
when is_tuple(Date), is_tuple(Time) ->
|
||||||
format(mapify(Date, Time, USec, Tz, #{}));
|
format(mapify(Date, Time, USec, Tz, #{}));
|
||||||
format({Date, Time})
|
format({Date, Time})
|
||||||
when is_tuple(Date), is_tuple(Time) ->
|
when is_tuple(Date), is_tuple(Time) ->
|
||||||
format(mapify(Date, Time, undefined, undefined, #{}));
|
format(mapify(Date, Time, undefined, undefined, #{}));
|
||||||
format(Time) when is_integer(Time) ->
|
format(Time) when is_integer(Time) ->
|
||||||
%% USec is the greatest fidelity supported. nano seconds are converted lossily
|
%% USec is the greatest fidelity supported. nano seconds are converted lossily
|
||||||
USec = erlang:convert_time_unit(Time, native, micro_seconds),
|
USec = erlang:convert_time_unit(Time, native, micro_seconds),
|
||||||
format(mapify(USec));
|
format(mapify(USec));
|
||||||
format(Dt) when is_map(Dt) ->
|
format(Dt) when is_map(Dt) ->
|
||||||
Date = format_date(Dt),
|
Date = format_date(Dt),
|
||||||
Time = format_time(Dt),
|
Time = format_time(Dt),
|
||||||
{ok, format_(Date, Time)}.
|
{ok, format_(Date, Time)}.
|
||||||
|
|
||||||
-spec format(integer(), erlang:time_unit()) -> {ok, binary()} | {error, error()}.
|
-spec format(integer(), erlang:time_unit()) -> {ok, binary()} | {error, error()}.
|
||||||
format(Time, Unit) when is_integer(Time) ->
|
format(Time, Unit) when is_integer(Time) ->
|
||||||
USec = erlang:convert_time_unit(Time, Unit, micro_seconds),
|
USec = erlang:convert_time_unit(Time, Unit, micro_seconds),
|
||||||
format(mapify(USec)).
|
format(mapify(USec)).
|
||||||
|
|
||||||
|
|
||||||
date(<<Y1, Y2, Y3, Y4, $-, M1, M2, $-, D1, D2, Rest/binary>>, {undefined, undefined, undefined, undefined}) ->
|
date(<<Y1, Y2, Y3, Y4, $-, M1, M2, $-, D1, D2, Rest/binary>>, {undefined, undefined, undefined, undefined}) ->
|
||||||
Year = to_year(Y1, Y2, Y3, Y4),
|
Year = to_year(Y1, Y2, Y3, Y4),
|
||||||
Month = to_month(M1, M2),
|
Month = to_month(M1, M2),
|
||||||
Day = to_day(D1, D2, Year, Month),
|
Day = to_day(D1, D2, Year, Month),
|
||||||
Date = coalesce(Year, Month, Day),
|
Date = coalesce(Year, Month, Day),
|
||||||
time(Rest, {Date, undefined, undefined, undefined});
|
time(Rest, {Date, undefined, undefined, undefined});
|
||||||
date(_, _Result) ->
|
date(_, _Result) ->
|
||||||
{error, baddate}.
|
{error, baddate}.
|
||||||
|
|
||||||
%% space
|
%% space
|
||||||
time(_, {{error, Error}, _, _, _}) -> {error, Error};
|
time(_, {{error, Error}, _, _, _}) -> {error, Error};
|
||||||
time(<<Sep, H1, H2, $:, M1, M2, $:, S1, S2, Rest/binary>>, {Date, undefined, undefined, undefined})
|
time(<<Sep, H1, H2, $:, M1, M2, $:, S1, S2, Rest/binary>>, {Date, undefined, undefined, undefined})
|
||||||
when Sep == 16#20 orelse Sep == $t orelse Sep == $T ->
|
when Sep == 16#20 orelse Sep == $t orelse Sep == $T ->
|
||||||
Hour = to_hour(H1, H2),
|
Hour = to_hour(H1, H2),
|
||||||
Min = to_minute(M1, M2),
|
Min = to_minute(M1, M2),
|
||||||
Sec = to_second(S1, S2),
|
Sec = to_second(S1, S2),
|
||||||
Time = coalesce(Hour, Min, Sec),
|
Time = coalesce(Hour, Min, Sec),
|
||||||
usec_or_tz(Rest, {Date, Time, undefined, undefined});
|
usec_or_tz(Rest, {Date, Time, undefined, undefined});
|
||||||
time(_, _) -> {error, badtime}.
|
time(_, _) -> {error, badtime}.
|
||||||
|
|
||||||
usec_or_tz(_, {_, {error, Error}, _, _}) -> {error, Error};
|
usec_or_tz(_, {_, {error, Error}, _, _}) -> {error, Error};
|
||||||
usec_or_tz(<<$., Rest/binary>>, Result) ->
|
usec_or_tz(<<$., Rest/binary>>, Result) ->
|
||||||
usec(Rest, Result, 0, 100000);
|
usec(Rest, Result, 0, 100000);
|
||||||
usec_or_tz(Rest, Result) -> tz(Rest, Result).
|
usec_or_tz(Rest, Result) -> tz(Rest, Result).
|
||||||
|
|
||||||
%% next two clauses burn off fractional seconds beyond microsecond precision
|
%% next two clauses burn off fractional seconds beyond microsecond precision
|
||||||
usec(<<X, Rest/binary>>, Result, USec, 0)
|
usec(<<X, Rest/binary>>, Result, USec, 0)
|
||||||
when X >= $0 andalso X =< $9 ->
|
when X >= $0 andalso X =< $9 ->
|
||||||
usec(Rest, Result, USec, 0);
|
usec(Rest, Result, USec, 0);
|
||||||
%% keep a running acc of usecs
|
%% keep a running acc of usecs
|
||||||
usec(<<X, Rest/binary>>, Result, USec, Multiplier)
|
usec(<<X, Rest/binary>>, Result, USec, Multiplier)
|
||||||
when X >= $0 andalso X =< $9 ->
|
when X >= $0 andalso X =< $9 ->
|
||||||
try list_to_integer([X]) of
|
try list_to_integer([X]) of
|
||||||
N -> usec(Rest, Result, USec + (N * Multiplier), Multiplier div 10)
|
N -> usec(Rest, Result, USec + (N * Multiplier), Multiplier div 10)
|
||||||
catch
|
catch
|
||||||
error:badarg -> {error, badusec}
|
error:badarg -> {error, badusec}
|
||||||
end;
|
end;
|
||||||
%% not a digit, insert usecs into time and proceed to tz
|
%% not a digit, insert usecs into time and proceed to tz
|
||||||
usec(Bin, {Date, Time, undefined, undefined}, USec, _) ->
|
usec(Bin, {Date, Time, undefined, undefined}, USec, _) ->
|
||||||
tz(Bin, {Date, Time, USec, undefined});
|
tz(Bin, {Date, Time, USec, undefined});
|
||||||
usec(_, _, _, _) -> {error, badusec}.
|
usec(_, _, _, _) -> {error, badusec}.
|
||||||
|
|
||||||
tz(<<$+, H1, H2, $:, M1, M2>>, {Date, Time, USec, undefined}) ->
|
tz(<<$+, H1, H2, $:, M1, M2>>, {Date, Time, USec, undefined}) ->
|
||||||
Hour = to_hour(H1, H2),
|
Hour = to_hour(H1, H2),
|
||||||
Min = to_minute(M1, M2),
|
Min = to_minute(M1, M2),
|
||||||
case calc_tz(positive, Hour, Min) of
|
case calc_tz(positive, Hour, Min) of
|
||||||
TZ when is_integer(TZ) -> {ok, {Date, Time, USec, TZ}};
|
TZ when is_integer(TZ) -> {ok, {Date, Time, USec, TZ}};
|
||||||
{error, Error} -> {error, Error}
|
{error, Error} -> {error, Error}
|
||||||
end;
|
end;
|
||||||
tz(<<$-, H1, H2, $:, M1, M2>>, {Date, Time, USec, undefined}) ->
|
tz(<<$-, H1, H2, $:, M1, M2>>, {Date, Time, USec, undefined}) ->
|
||||||
Hour = to_hour(H1, H2),
|
Hour = to_hour(H1, H2),
|
||||||
Min = to_minute(M1, M2),
|
Min = to_minute(M1, M2),
|
||||||
case calc_tz(negative, Hour, Min) of
|
case calc_tz(negative, Hour, Min) of
|
||||||
TZ when is_integer(TZ) -> {ok, {Date, Time, USec, TZ}};
|
TZ when is_integer(TZ) -> {ok, {Date, Time, USec, TZ}};
|
||||||
{error, Error} -> {error, Error}
|
{error, Error} -> {error, Error}
|
||||||
end;
|
end;
|
||||||
tz(<<$Z>>, Result) ->
|
tz(<<$Z>>, Result) ->
|
||||||
{ok, Result};
|
{ok, Result};
|
||||||
tz(<<$z>>, Result) ->
|
tz(<<$z>>, Result) ->
|
||||||
{ok, Result};
|
{ok, Result};
|
||||||
tz(_, _) -> {error, badtimezone}.
|
tz(_, _) -> {error, badtimezone}.
|
||||||
|
|
||||||
calc_tz(_, {error, Error}, _) -> {error, Error};
|
calc_tz(_, {error, Error}, _) -> {error, Error};
|
||||||
@ -176,103 +188,103 @@ coalesce(_, _, {error, Error}) -> {error, Error};
|
|||||||
coalesce(X, Y, Z) -> {X, Y, Z}.
|
coalesce(X, Y, Z) -> {X, Y, Z}.
|
||||||
|
|
||||||
to_year(Y1, Y2, Y3, Y4) ->
|
to_year(Y1, Y2, Y3, Y4) ->
|
||||||
try list_to_integer([Y1, Y2, Y3, Y4]) of
|
try list_to_integer([Y1, Y2, Y3, Y4]) of
|
||||||
Year when Year >= 0 andalso Year =< 9999 -> Year;
|
Year when Year >= 0 andalso Year =< 9999 -> Year;
|
||||||
_ -> {error, badyear}
|
_ -> {error, badyear}
|
||||||
catch
|
catch
|
||||||
error:badarg -> {error, badyear}
|
error:badarg -> {error, badyear}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
to_month(M1, M2) ->
|
to_month(M1, M2) ->
|
||||||
try list_to_integer([M1, M2]) of
|
try list_to_integer([M1, M2]) of
|
||||||
Month when Month >= 1 andalso Month =< 12 -> Month;
|
Month when Month >= 1 andalso Month =< 12 -> Month;
|
||||||
_ -> {error, badmonth}
|
_ -> {error, badmonth}
|
||||||
catch
|
catch
|
||||||
error:badarg -> {error, badmonth}
|
error:badarg -> {error, badmonth}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
to_day(D1, D2, Year, Month) ->
|
to_day(D1, D2, Year, Month) ->
|
||||||
try list_to_integer([D1, D2]) of
|
try list_to_integer([D1, D2]) of
|
||||||
Day when Day >= 0 andalso Day =< 28 -> Day;
|
Day when Day >= 0 andalso Day =< 28 -> Day;
|
||||||
Day when Day >= 29 andalso Day =< 31 ->
|
Day when Day >= 29 andalso Day =< 31 ->
|
||||||
case day_in_month(Year, Month, Day) of
|
case day_in_month(Year, Month, Day) of
|
||||||
true -> Day;
|
true -> Day;
|
||||||
false -> {error, badday}
|
false -> {error, badday}
|
||||||
end;
|
end;
|
||||||
_ -> {error, badday}
|
_ -> {error, badday}
|
||||||
catch
|
catch
|
||||||
error:badarg -> {error, badday}
|
error:badarg -> {error, badday}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
day_in_month({error, badyear}, _, _) -> {error, badyear};
|
day_in_month({error, badyear}, _, _) -> {error, badyear};
|
||||||
day_in_month(_, {error, badmonth}, _) -> {error, badmonth};
|
day_in_month(_, {error, badmonth}, _) -> {error, badmonth};
|
||||||
day_in_month(Year, Month, Day) ->
|
day_in_month(Year, Month, Day) ->
|
||||||
case Day of
|
case Day of
|
||||||
29 when Month == 2 -> ((Year rem 4 == 0) andalso not (Year rem 100 == 0)) orelse (Year rem 400 == 0);
|
29 when Month == 2 -> ((Year rem 4 == 0) andalso not (Year rem 100 == 0)) orelse (Year rem 400 == 0);
|
||||||
30 when Month == 2 -> false;
|
30 when Month == 2 -> false;
|
||||||
31 when Month == 2; Month == 4; Month == 6; Month == 9; Month == 11 -> false;
|
31 when Month == 2; Month == 4; Month == 6; Month == 9; Month == 11 -> false;
|
||||||
_ -> true
|
_ -> true
|
||||||
end.
|
end.
|
||||||
|
|
||||||
to_hour(H1, H2) ->
|
to_hour(H1, H2) ->
|
||||||
try list_to_integer([H1, H2]) of
|
try list_to_integer([H1, H2]) of
|
||||||
Hour when Hour >= 0 andalso Hour =< 23 -> Hour;
|
Hour when Hour >= 0 andalso Hour =< 23 -> Hour;
|
||||||
_ -> {error, badhour}
|
_ -> {error, badhour}
|
||||||
catch
|
catch
|
||||||
error:badarg -> {error, badhour}
|
error:badarg -> {error, badhour}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
to_minute(M1, M2) ->
|
to_minute(M1, M2) ->
|
||||||
try list_to_integer([M1, M2]) of
|
try list_to_integer([M1, M2]) of
|
||||||
Min when Min >= 0 andalso Min =< 59 -> Min;
|
Min when Min >= 0 andalso Min =< 59 -> Min;
|
||||||
_ -> {error, badminute}
|
_ -> {error, badminute}
|
||||||
catch
|
catch
|
||||||
error:badarg -> {error, badminute}
|
error:badarg -> {error, badminute}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
to_second(S1, S2) ->
|
to_second(S1, S2) ->
|
||||||
try list_to_integer([S1, S2]) of
|
try list_to_integer([S1, S2]) of
|
||||||
Sec when Sec >= 0 andalso Sec =< 60 -> Sec;
|
Sec when Sec >= 0 andalso Sec =< 60 -> Sec;
|
||||||
_ -> {error, badsecond}
|
_ -> {error, badsecond}
|
||||||
catch
|
catch
|
||||||
error:badarg -> {error, badsecond}
|
error:badarg -> {error, badsecond}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
format_date(Dt) ->
|
format_date(Dt) ->
|
||||||
Year = g(year, Dt),
|
Year = g(year, Dt),
|
||||||
Month = g(month, Dt),
|
Month = g(month, Dt),
|
||||||
Day = g(day, Dt),
|
Day = g(day, Dt),
|
||||||
format_date(Year, Month, Day).
|
format_date(Year, Month, Day).
|
||||||
|
|
||||||
format_date(Y, M, D) when is_integer(Y), is_integer(M), is_integer(D) ->
|
format_date(Y, M, D) when is_integer(Y), is_integer(M), is_integer(D) ->
|
||||||
io_lib:format("~4.10.0B-~2.10.0B-~2.10.0B", [Y, M, D]);
|
io_lib:format("~4.10.0B-~2.10.0B-~2.10.0B", [Y, M, D]);
|
||||||
format_date(_, _, _) -> {error, baddate}.
|
format_date(_, _, _) -> {error, baddate}.
|
||||||
|
|
||||||
format_time(Dt) ->
|
format_time(Dt) ->
|
||||||
Hour = g(hour, Dt),
|
Hour = g(hour, Dt),
|
||||||
Min = g(min, Dt),
|
Min = g(min, Dt),
|
||||||
Sec = g(sec, Dt),
|
Sec = g(sec, Dt),
|
||||||
USec = g(usec, Dt),
|
USec = g(usec, Dt),
|
||||||
Time = format_time(Hour, Min, Sec, USec),
|
Time = format_time(Hour, Min, Sec, USec),
|
||||||
Offset = g(tz_offset, Dt),
|
Offset = g(tz_offset, Dt),
|
||||||
TZ = format_offset(Offset),
|
TZ = format_offset(Offset),
|
||||||
format_time(Time, TZ).
|
format_time(Time, TZ).
|
||||||
|
|
||||||
format_time(H, M, S, 0) when is_integer(H), is_integer(M), is_integer(S) ->
|
format_time(H, M, S, 0) when is_integer(H), is_integer(M), is_integer(S) ->
|
||||||
io_lib:format("~2.10.0B:~2.10.0B:~2.10.0B", [H, M, S]);
|
io_lib:format("~2.10.0B:~2.10.0B:~2.10.0B", [H, M, S]);
|
||||||
format_time(H, M, S, U) when is_integer(H), is_integer(M), is_integer(S), is_integer(U) ->
|
format_time(H, M, S, U) when is_integer(H), is_integer(M), is_integer(S), is_integer(U) ->
|
||||||
SU = (S / 1) + (U / 1000000),
|
SU = (S / 1) + (U / 1000000),
|
||||||
io_lib:format("~2.10.0B:~2.10.0B:~9.6.0f", [H, M, SU]);
|
io_lib:format("~2.10.0B:~2.10.0B:~9.6.0f", [H, M, SU]);
|
||||||
format_time(_, _, _, _) -> {error, badtime}.
|
format_time(_, _, _, _) -> {error, badtime}.
|
||||||
|
|
||||||
format_offset(undefined) -> "Z";
|
format_offset(undefined) -> "Z";
|
||||||
format_offset(nil) -> "Z";
|
format_offset(nil) -> "Z";
|
||||||
format_offset(0) -> "Z";
|
format_offset(0) -> "Z";
|
||||||
format_offset(M) when is_integer(M) ->
|
format_offset(M) when is_integer(M) ->
|
||||||
Sign = case M >= 0 of true -> "+"; false -> "-" end,
|
Sign = case M >= 0 of true -> "+"; false -> "-" end,
|
||||||
Hour = abs(M) div 60,
|
Hour = abs(M) div 60,
|
||||||
Min = abs(M) rem 60,
|
Min = abs(M) rem 60,
|
||||||
Sign ++ io_lib:format("~2.10.0B:~2.10.0B", [Hour, Min]).
|
Sign ++ io_lib:format("~2.10.0B:~2.10.0B", [Hour, Min]).
|
||||||
|
|
||||||
format_time({error, Error}, _) -> {error, Error};
|
format_time({error, Error}, _) -> {error, Error};
|
||||||
format_time(Time, TZ) -> [Time, TZ].
|
format_time(Time, TZ) -> [Time, TZ].
|
||||||
@ -282,11 +294,11 @@ format_(_, {error, badtime}) -> {error, badtime};
|
|||||||
format_(Date, Time) -> unicode:characters_to_binary([Date, "T", Time]).
|
format_(Date, Time) -> unicode:characters_to_binary([Date, "T", Time]).
|
||||||
|
|
||||||
g(Key, Map) ->
|
g(Key, Map) ->
|
||||||
case maps:get(Key, Map, undefined) of
|
case maps:get(Key, Map, undefined) of
|
||||||
nil -> 0;
|
nil -> 0;
|
||||||
undefined -> 0;
|
undefined -> 0;
|
||||||
Val -> Val
|
Val -> Val
|
||||||
end.
|
end.
|
||||||
|
|
||||||
or_zero(undefined) -> 0;
|
or_zero(undefined) -> 0;
|
||||||
or_zero(N) when is_integer(N) -> N.
|
or_zero(N) when is_integer(N) -> N.
|
Loading…
Reference in New Issue
Block a user