Получение time() в виде строки HH:MM:SS

Я изучаю Erlang и спрашиваю себя, как лучше всего превратить вывод time() в форматированную строку времени (ЧЧ: ММ: СС). Код, который я придумал:

my_time() ->
    {H, M, S} = time(),
    integer_to_list(H) ++ ":" ++ integer_to_list(M) ++ ":" ++ integer_to_list(S).

Этот код не будет работать точно так же, как он не будет заполнен нулями минут или секунд. Он также использует оператор ++ для объединения списков, что не рекомендуется.

Как правильно реализовать эту тривиальную задачу в Erlang?

3 ответа

Решение

Правильная, простая для понимания реализация использует format (который как printf):

my_time() ->
    {H, M, S} = time(),
    io_lib:format('~2..0b:~2..0b:~2..0b', [H, M, S]).

~2..0b является заполнителем для целого числа, которое должно быть напечатано в основании 10, занимая не менее 2 символов, и дополнено слева символом 0,

Рекомендации:

Вы должны беспокоиться о производительности, только если вы вызываете свою функцию в узком цикле, и если тесты профилирования показывают, что ваша функция на самом деле является узким местом.

Я не знаю, почему вы думаете, что объединение списка с длиной 8 может быть любой проблемой, но если вы хотите быть очень быстрым, вы можете сделать:

my_time() ->
    {H, M, S} = time(),
    [$0 + H div 10, $0 + H rem 10, $:, $0 + M div 10, $0 + M rem 10, $:, $0 + S div 10, $0 + S rem 10].

Не существует правильных способов, есть более быстрые или медленные, более или менее потребляющие память и более или менее краткие решения.

Редактировать: если вам нравится более лаконичный, но одинаковый результат:

-define(DEC(X), $0 + X div 10, $0 + X rem 10).
my_time() ->
    {H, M, S} = time(),
    [?DEC(H), $:, ?DEC(M), $:, ?DEC(S)].

Мне нравится модуль Dave Harveys dh_date. Единственное "исправление" - это то, что format/2 принимает только now() или datetime(). Легко исправить, как в примере ниже.

4> dh_date:format("H:i:s",{{0,0,0},time()}).
"07:23:58"
Другие вопросы по тегам