string:str for string from database

87 views Asked by At

I have model with some fields. I want to get string field from mongodb and get substring. I'm trying: My get_items code. Here is important just one line with filter.

get_items('GET', []) ->
Items = boss_db:find(item, []),
S = Req:query_param("start"),
F = Req:query_param("finish"),
Start = string_to_datetime(S),
Finish = string_to_datetime(F),
Fitems = filter(Items, Start, Finish, []),
{json, [{items, Fitems}]}.

create_item code. My datetime using my own function.

create_item('POST', []) ->
Lastname = Req:post_param("lastname"),
User = hd(boss_db:find(consumer, [{lastname, Lastname}])),
DateTime = datetime_to_string(calendar:now_to_local_time(erlang:now())),
Type = Req:post_param("type"),
IdType = Req:post_param("idtype"),
Item = item:new(id, User:id(), DateTime, Type, IdType),
case Item:save() of
    {ok, SavedItem} -> {json, [{status, "ok"}]};
    {error, Reason} -> {json, [{error, Reason}]}
end.

My function to converting datetime to string.

datetime_to_string({{YY, MM, DD}, {Hour, Min, Sec}}) -> 
io_lib:format("~4..0w-~2..0w-~2..0w ~2..0w:~2..0w:~2..0w",
    [YY, MM, DD, Hour, Min, Sec]).

My function to converting string to datetime.

string_to_datetime(S) ->
{YY, _} = string:to_integer(string:substr(S, 1, 4)),
{MM, _} = string:to_integer(string:substr(S, 6, 2)),
{DD, _} = string:to_integer(string:substr(S, 9, 2)),
{Hour, _} = string:to_integer(string:substr(S, 12, 2)),
{Min, _} = string:to_integer(string:substr(S, 15, 2)),
{Sec, _} = string:to_integer(string:substr(S, 18, 2)),
{{YY, MM, DD}, {Hour, Min, Sec}}.

My filter method.

filter([], Start, Finish, Acc) -> Acc;
filter([Model|Models], Start, Finish, Acc) ->
DateTime = string_to_datetime(Model:datetime()),
{D1, _} = calendar:time_difference(Start, DateTime),
{D2, _} = calendar:time_difference(DateTime, Finish),
if
    D1 >= 0, D2 >= 0 -> filter(Models, Start, Finish, [Model | Acc]);
    true -> filter(Models, Start, Finish, Acc)
end.

And I have the error:

{function_clause,
    [{string,substr2,
         [<<"2013-12-17 18:36:42">>,1],
         [{file,"string.erl"},{line,213}]},
     {string,substr,3,[{file,"string.erl"},{line,208}]},
     {cb_tracker_main_controller,string_to_datetime,2,

Please, help me.

2

There are 2 answers

0
fenollp On

Okay so the error comes from your function

string_to_datetime(S) ->
    {YY, _} = string:to_integer(string:substr(S, 1, 4)),
    {MM, _} = string:to_integer(string:substr(S, 6, 2)),
    {DD, _} = string:to_integer(string:substr(S, 9, 2)),
    {Hour, _} = string:to_integer(string:substr(S, 12, 2)),
    {Min, _} = string:to_integer(string:substr(S, 15, 2)),
    {Sec, _} = string:to_integer(string:substr(S, 18, 2)),
    {{YY, MM, DD}, {Hour, Min, Sec}}.

But given your encoding function

datetime_to_string({{YY, MM, DD}, {Hour, Min, Sec}}) -> 
    io_lib:format("~4..0w-~2..0w-~2..0w ~2..0w:~2..0w:~2..0w",
        [YY, MM, DD, Hour, Min, Sec]).

One can implement a decoder using pattern matching (adapting it for binaries is straightforward while syntactically awkward):

string_to_datetime (S) ->
    [Y1,Y2,Y3,Y4, $-, M1,M2, $-, D1,D2, $ , H1,H2, $:, N1,N2, $:, S1,S2] = S,
    { {list_to_integer([Y1,Y2,Y3,Y4]),list_to_integer([M1,M2]),list_to_integer([D1,D2])}
    , {list_to_integer([H1,H2]),      list_to_integer([N1,N2]),list_to_integer([S1,S2])} }.

(code remains untested)

0
P_A On

Firstly you can try to use tempo lib (https://github.com/selectel/tempo) for parsing and formatting dates.

What about your problem: string:substr works with strings - lists of integers. <<"2013-12-17 18:36:42">> - binary and you need to convert it into string using binary_to_list function before processing.