Skip to content

Instantly share code, notes, and snippets.

@sinkovsky
Created October 19, 2009 13:05
Show Gist options
  • Save sinkovsky/213343 to your computer and use it in GitHub Desktop.
Save sinkovsky/213343 to your computer and use it in GitHub Desktop.
-record(timestamp, {year, month, day, hour, minute, second, fraction, timezone}).
-record(timezone, {hour, minute}).
parse_iso8601(Time) when is_list(Time) ->
parse_iso8601( list_to_binary(Time) );
parse_iso8601(Time) when is_binary(Time) ->
try
{ok, iso_to_rec(
year,
Time,
#timestamp{
year = 0,
day = 0,
month = 0,
hour = 0,
minute = 0,
second = 0,
fraction = 0,
timezone = #timezone{ hour = 0, minute = 0}
}
)
}
catch
error:Err -> {error, not_iso8601, Err}
end.
iso_to_rec( _State, <<>>, R ) -> R;
iso_to_rec(second, <<"-", Rest/bitstring>>, R) ->
iso_to_rec(tz_hour, Rest, R );
iso_to_rec(fraction, <<"-", Rest/bitstring>>, R) ->
iso_to_rec(tz_hour, Rest, R );
iso_to_rec(_State, <<"+", Rest/bitstring>>, R) ->
iso_to_rec(tz_hour, Rest, R );
iso_to_rec( State, <<"-", Rest/bitstring>>, R ) ->
iso_to_rec( State, Rest, R );
iso_to_rec( State, <<" ", Rest/bitstring>>, R ) ->
iso_to_rec( State, Rest, R );
iso_to_rec( State, <<"T", Rest/bitstring>>, R ) ->
iso_to_rec( State, Rest, R );
iso_to_rec( State, <<":", Rest/bitstring>>, R ) ->
iso_to_rec( State, Rest, R );
iso_to_rec( fraction, <<".", Rest/bitstring>>, R ) ->
iso_to_rec( fraction, Rest, R );
iso_to_rec( year, <<Year:32/bitstring, Rest/bitstring>>, R ) ->
iso_to_rec( month, Rest, R#timestamp{ year = Year } );
iso_to_rec( month, <<Month:16/bitstring, Rest/bitstring>>, R ) ->
iso_to_rec( day, Rest, R#timestamp{ month = Month } );
iso_to_rec( day, <<Day:16/bitstring, Rest/bitstring>>, R ) ->
iso_to_rec( hour, Rest, R#timestamp{ day = Day } );
iso_to_rec( hour, <<Hour:16/bitstring, Rest/bitstring>>, R ) ->
iso_to_rec( minute, Rest, R#timestamp{ hour = Hour } );
iso_to_rec( minute, <<Minute:16/bitstring, Rest/bitstring>>, R ) ->
iso_to_rec( second, Rest, R#timestamp{ minute = Minute } );
iso_to_rec( second, <<Second:16/bitstring, Rest/bitstring>>, R ) ->
iso_to_rec( fraction, Rest, R#timestamp{ second = Second } );
%% parsing fraction by character, cause we don't know its length
iso_to_rec( fraction, <<C:8/bitstring, Rest/bitstring>>, R) ->
iso_to_rec( fraction, Rest, R#timestamp{ fraction = R#timestamp.fraction * 10 + list_to_integer(binary_to_list(C))});
iso_to_rec( tz_hour, <<Tz_hour:16/bitstring, Rest/bitstring>>, R) ->
iso_to_rec(minute, Rest, R#timestamp{ timezone = (R#timestamp.timezone)#timezone{ hour = Tz_hour }} );
iso_to_rec( tz_minute, <<Tz_min:16/bitstring, Rest/bitstring>>, R) ->
iso_to_rec(minute, Rest, R#timestamp{ timezone = (R#timestamp.timezone)#timezone{ minute = Tz_min }} ).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment