Skip to content

Instantly share code, notes, and snippets.

@betawaffle
Created December 15, 2011 19:48
Show Gist options
  • Save betawaffle/1482550 to your computer and use it in GitHub Desktop.
Save betawaffle/1482550 to your computer and use it in GitHub Desktop.
-spec timestamp(atom(), binary(), object()) -> object().
%% Facebook Timestamp (eg. <<"2011-11-21T22:37:44+0000">>)
timestamp(Field, <<Year:4/binary, $-, Month:2/binary, $-, Day:2/binary, $T,
Hour:2/binary, $:, Minute:2/binary, $:, Second:2/binary, Offset:5/binary>>, Acc = #fb_object{}) ->
Date = {?BIN_TO_INT(Year), ?BIN_TO_INT(Month), ?BIN_TO_INT(Day)},
Time = {?BIN_TO_INT(Hour), ?BIN_TO_INT(Minute), ?BIN_TO_INT(Second)},
DateTime = case Offset of
<<"+0000">> -> % UTC
{Date, Time};
_ ->
to_utc(Date, Time, Offset)
end,
append_field(Field, DateTime, Acc);
%% ===================================================================
%% Time Conversion (probably not necessary, but w/e)
%% ===================================================================
-define(DAYS_IN_MONTH(M), element(M, {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31})).
-spec to_utc(date(), time(), binary()) -> datetime().
to_utc(Date, {Hour, Minute, Second}, <<$+, OffH:2/binary, OffM:2/binary>>) ->
NewHour = Hour - ?BIN_TO_INT(OffH),
NewMinute = Minute - ?BIN_TO_INT(OffM),
validate_datetime(Date, {NewHour, NewMinute, Second});
to_utc(Date, {Hour, Minute, Second}, <<$-, OffH:2/binary, OffM:2/binary>>) ->
NewHour = Hour + ?BIN_TO_INT(OffH),
NewMinute = Minute + ?BIN_TO_INT(OffM),
validate_datetime(Date, {NewHour, NewMinute, Second}).
% -spec validate_datetime(datetime()) -> datetime().
% validate_datetime({Date, Time}) ->
% validate_datetime(Date, Time).
-spec validate_datetime(date(), time()) -> datetime().
%% Shift Minutes to Hours
validate_datetime(Date, {H, M, S}) when M < 0 ->
validate_datetime(Date, {H - 1, M + 60, S});
validate_datetime(Date, {H, M, S}) when M > 59 ->
validate_datetime(Date, {H + 1, M - 60, S});
%% Shift Hours to Days
validate_datetime({Y, Mo, D}, {H, M, S}) when H < 0 ->
validate_datetime({Y, Mo, D - 1}, {H + 24, M, S});
validate_datetime({Y, Mo, D}, {H, M, S}) when H > 23 ->
validate_datetime({Y, Mo, D + 1}, {H - 24, M, S});
%% Shift Days to Months
validate_datetime({Y, Mo, D}, Time) when D < 1 ->
{OffY, NewM} = validate_month(Mo - 1),
{{Y + OffY, NewM, D + ?DAYS_IN_MONTH(NewM)}, Time};
validate_datetime({Y, Mo, D}, Time) when D > ?DAYS_IN_MONTH(Mo) ->
{OffY, NewM} = validate_month(Mo + 1),
{{Y + OffY, NewM, D - ?DAYS_IN_MONTH(Mo)}, Time};
%% Done
validate_datetime(Date, Time) -> {Date, Time}.
-spec validate_month(integer()) -> {integer(), 1..12}.
validate_month(M) when M < 1 -> X = M - 12, {-X div -12, X rem 12 + 12};
validate_month(M) when M > 12 -> X = M - 1, { X div 12, X rem 12 + 1};
validate_month(M) -> {0, M}.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment