Hope will help someone.
We will be grateful if someone indicates what can be improved. Thank you in advance!
port_helper.erl
-module(port_helper). -export([get_stdout/1]). get_stdout(Port) -> loop(Port, []). loop(Port, DataAcc) -> receive {Port, {data, Data}} -> loop(Port, DataAcc ++ Data); {Port, eof} -> DataAcc end.
timestamp_with_time_zone.erl
-module(timestamp_with_time_zone). -export([to_time_zone/2, to_universal_time/1, modify/2]). to_time_zone({{{Year, Month, Day}, {Hour, Minute, Second}}, TimeZone}, OutputTimeZone) -> InputPattern = "~4.10.0B-~2.10.0B-~2.10.0B ~2.10.0B:~2.10.0B:~2.10.0B", InputDeep = io_lib:format(InputPattern, [Year, Month, Day, Hour, Minute, Second]), Input = lists:flatten(InputDeep), {external_date(Input, TimeZone, OutputTimeZone), OutputTimeZone}. to_universal_time({{{Year, Month, Day}, {Hour, Minute, Second}}, TimeZone}) -> {Timestamp, "UTC"} = to_time_zone({{{Year, Month, Day}, {Hour, Minute, Second}}, TimeZone}, "UTC"), Timestamp. modify({{{Year, Month, Day}, {Hour, Minute, Second}}, TimeZone}, {Times, Unit}) -> if Times > 0 -> TimesModifier = ""; Times < 0 -> TimesModifier = " ago" end, InputPattern = "~4.10.0B-~2.10.0B-~2.10.0B ~2.10.0B:~2.10.0B:~2.10.0B ~.10B ~s~s", InputDeep = io_lib:format(InputPattern, [Year, Month, Day, Hour, Minute, Second, abs(Times), Unit, TimesModifier]), Input = lists:flatten(InputDeep), external_date(Input, TimeZone, TimeZone). external_date(Input, InputTimeZone, OutputTimeZone) -> CmdPattern = "date --date 'TZ=\"~s\" ~s' +%Y%m%d%H%M%S", CmdDeep = io_lib:format(CmdPattern, [InputTimeZone, Input]), Cmd = lists:flatten(CmdDeep), Port = open_port({spawn, Cmd}, [{env, [{"TZ", OutputTimeZone}]}, eof, stderr_to_stdout]), ResultString = port_helper:get_stdout(Port), case io_lib:fread("~4d~2d~2d~2d~2d~2d", ResultString) of {ok, [YearNew, MonthNew, DayNew, HourNew, MinuteNew, SecondNew], _LeftOverChars} -> {{YearNew, MonthNew, DayNew}, {HourNew, MinuteNew, SecondNew}} end.