Current section

Files

Jump to
birl src birl_ffi.erl
Raw

src/birl_ffi.erl

-module(birl_ffi).
-export([now/0, to_parts/1, to_iso/1, from_iso/1, monotonic_now/0]).
-define(DaysInMonths, [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]).
now() -> os:system_time(millisecond).
to_parts(Timestmap) ->
calendar:system_time_to_universal_time(Timestmap, millisecond).
to_iso(Timestmap) ->
{{Year, Month, Day}, {Hour, Minute, Second}} = to_parts(Timestmap),
MilliSecond = Timestmap rem 1000,
iolist_to_binary(
io_lib:format(
"~4.10.0B-~2.10.0B-~2.10.0BT~2.10.0B:~2.10.0B:~2.10.0B.~3.10.0BZ",
[Year, Month, Day, Hour, Minute, Second, MilliSecond]
)
).
from_iso(ISODate) ->
[Date, Time] = string:split(ISODate, "T"),
[YearStr, MonthStr, DayStr] = string:split(Date, "-", all),
[HoursStr, MinutesStr, Rest] = string:split(Time, ":", all),
[SecondsStr, MilliSecondsStr] = string:split(Rest, "."),
Year = binary_to_integer(YearStr),
Month = binary_to_integer(MonthStr),
Day = binary_to_integer(DayStr),
Hours = binary_to_integer(HoursStr),
Minutes = binary_to_integer(MinutesStr),
Seconds = binary_to_integer(SecondsStr),
MilliSeconds = binary_to_integer(string:slice(MilliSecondsStr, 0, 3)),
DaysInYears = calculate_days_from_year(Year - 1, 0),
DaysInMonths = calculate_days_from_month(Year, Month - 1, 0),
Days = DaysInYears + DaysInMonths + Day - 1,
(((Days * 3600 * 24) + (Hours * 3600) + (Minutes * 60) + Seconds) * 1000) + MilliSeconds.
calculate_days_from_year(1969, Days) ->
Days;
calculate_days_from_year(Year, Days) ->
case calendar:is_leap_year(Year) of
true ->
calculate_days_from_year(Year - 1, Days + 366);
false ->
calculate_days_from_year(Year - 1, Days + 365)
end.
calculate_days_from_month(_, 0, Days) ->
Days;
calculate_days_from_month(Year, Month, Days) ->
case calendar:is_leap_year(Year) and (Month == 2) of
true ->
calculate_days_from_month(Year, 1, Days + 29);
false ->
calculate_days_from_month(Year, Month - 1, Days + lists:nth(Month, ?DaysInMonths))
end.
monotonic_now() -> os:perf_counter(millisecond).