| Paste number 49404: | SMPP time decoding |
| Pasted by: | archaelus |
| When: | 1 year, 8 months ago |
| Share: | Tweet this! | http://paste.lisp.org/+124C |
| Channel: | #erlang |
| Paste contents: |
pdu_timing(Pdu) -> RawDelivery = extract_delivery(Pdu), RawExpiry = extract_expiry(Pdu), smpp_timing(RawDelivery, RawExpiry). smpp_timing(undefined, undefined) -> {undefined, undefined}; smpp_timing(undefined, RawExpiry) -> {undefined, smpptime_to_universal(RawExpiry)}; smpp_timing(RawDelivery, undefined) -> {smpptime_to_universal(RawDelivery), undefined}; smpp_timing(RawDelivery, RawExpiry) -> DeliveryDT = smpptime_to_universal(RawDelivery), {DeliveryDT, adjust_expiry(DeliveryDT, smpptime_to_universal(RawExpiry))}. adjust_expiry(BaseDT, ExpiryDT) -> adjust_expiry(BaseDT, ExpiryDT, erlang:universaltime()). adjust_expiry(BaseDT, ExpiryDT, NowDT) -> datetime_add(BaseDT, datetime_diff(NowDT, ExpiryDT)). extract_expiry(Pdu) -> case dict:find(validity_period, Pdu) of {ok, Time} when Time /= [] -> Time; _ -> undefined end. extract_delivery(Pdu) -> case dict:find(schedule_delivery_time, Pdu) of {ok, Time} when Time /= [] -> Time; _ -> undefined end. smpptime_to_universal(Raw) -> smpptime_to_universal(Raw, erlang:universaltime()). smpptime_to_universal([Yh,Yl, Mh,Ml, Dh, Dl, Hh, Hl, Mih, Mil, Sh, Sl, _St, _Nh, _Nl, $R], NowDT) -> [_Year, _Month, Day, Hour, Min, Sec] = smpptime_parse([Yh,Yl],[Mh,Ml],[Dh,Dl], [Hh, Hl],[Mih, Mil], [Sh,Sl]), % How many days are there in a month? or a year? Secs = (Day * 24 * 60 * 60) + (Hour * 60 * 60) + (Min * 60) + Sec, datetime_add(NowDT, Secs); smpptime_to_universal([Yh,Yl, Mh,Ml, Dh, Dl, Hh, Hl, Mih, Mil, Sh, Sl, St, Nh, Nl, P], _NowDT) -> Time = smpptime_parse([Yh,Yl],[Mh,Ml],[Dh,Dl], [Hh, Hl],[Mih, Mil], [Sh,Sl], St), DT = list_to_datetime(Time), smpptime_adjust(DT, [P,Nh,Nl]). smpptime_parse(Year, Month, Day, Hour, Min, Sec) -> [list_to_integer(Year), list_to_integer(Month), list_to_integer(Day), list_to_integer(Hour), list_to_integer(Min), list_to_integer(Sec)]. smpptime_parse(Year, Month, Day, Hour, Min, Sec, Tenths) -> [list_to_integer(Year), list_to_integer(Month), list_to_integer(Day), list_to_integer(Hour), list_to_integer(Min), round(list_to_float(Sec ++ [$.,Tenths]))]. list_to_datetime([Year, Month, Day, Hour, Min, Sec]) -> {{smpptime_year_normalise(Year), Month, Day}, {Hour, Min, Sec}}. smpptime_adjust(DT, [_,$0,$0]) -> DT; smpptime_adjust(DT, TZoffset) -> TZo = list_to_integer(TZoffset), TZoSecs = 60 * 15 * TZo, AdjSecs = calendar:datetime_to_gregorian_seconds(DT) - TZoSecs, calendar:gregorian_seconds_to_datetime(AdjSecs). datetime_add(T, Interval) -> S = calendar:datetime_to_gregorian_seconds(T), calendar:gregorian_seconds_to_datetime(S + Interval). datetime_diff(T1, T2) -> calendar:datetime_to_gregorian_seconds(T2) - calendar:datetime_to_gregorian_seconds(T1). universal_to_smpptime({{Year,Month,Day},{Hour,Min,Sec}}) -> Fmt = "~2.10.0B~2.10.0B~2.10.0B~2.10.0B~2.10.0B~2.10.0B000+", lists:flatten(io_lib:format(Fmt, [Year, Month, Day, Hour, Min, Sec])). smpptime_year_normalise_test() -> ?assert(smpptime_year_normalise(0) == 2000), ?assert(smpptime_year_normalise(70) == 1970), ?assert(smpptime_year_normalise(1970) == 1970), ?assert(smpptime_year_normalise(2000) == 2000), ?assert(lists:all(fun (N) -> smpptime_year_normalise(N) >= 1970 end, lists:seq(0,170))). smpptime_relative_test() -> Now = {{2007,05,17},{15,58,00}}, ?assert(smpptime_to_universal("000000000000000R", Now) == {{2007,05,17},{15,58,00}}), ?assert(smpptime_to_universal("000000000200000R", Now) == {{2007,05,17},{16,00,00}}), ?assert(smpptime_to_universal("000000010301000R", Now) == {{2007,05,17},{17,01,01}}), ?assert(smpptime_to_universal("000019010301000R", Now) == {{2007,06,05},{17,01,01}}), ?assert(smpptime_to_universal("000000000001000R", Now) == {{2007,05,17},{15,58,01}}). smpptime_absolute_test() -> ?assertMatch({{2007,05,17},{15,58,00}}, smpptime_to_universal("070517155800000+")), ?assertMatch({{2007,05,17},{15,58,00}}, smpptime_to_universal("070517155800000-")), ?assertMatch({{2007,5,17},{3,58,0}}, smpptime_to_universal("070517155800048+")).
This paste has no annotations.