2013-12-17 1 views
0

У меня есть модель с некоторыми полями. Я хочу получить строковое поле из mongodb и получить подстроку. Я пытаюсь: Мой код get_items. Здесь важна только одна строка с фильтром.string: str для строки из базы данных

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. Мой datetime использует мою собственную функцию.

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. 

Моя функция преобразования даты и времени в строку.

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]). 

Моя функция преобразования строки в дату и время.

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}}. 

Мой фильтр способ.

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. 

И у меня есть ошибка:

{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, 

Пожалуйста, помогите мне.

ответ

1

Во-первых, вы можете попробовать использовать tempo lib (https://github.com/selectel/tempo) для дат синтаксического анализа и форматирования.

Как насчет вашей проблемы: строка: substr работает с строки - списки целых чисел. < < «2013-12-17 18:36:42» >> - двоичный код, и перед его обработкой необходимо преобразовать его в строку, используя функцию binary_to_list.

0

Хорошо, так что ошибка происходит из вашей функции

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}}. 

Но учитывая ваши функции кодирования

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]). 

можно реализовать декодер, используя шаблон соответствия (адаптируя его для двоичных файлов проста в то время как синтаксически неудобно) :

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])} }. 

(код остается непроверенным)