Retrieving the time() as a HH:MM:SS string
I'm learning Erlang and I was asking myself what is the best way to turn the time() output into a formatted time string (HH:MM:SS). The code I came up with is:
my_time() ->
{H, M, S} = time(),
integer_to_list(H) ++ ":" ++ integer_to_list(M) ++ ":" ++ integer_to_list(S).
This code won't do the trick exactly as it won't pad with zeros t开发者_运维技巧he minutes or seconds. It also uses the ++ operator to concatenate lists which isn't recommended.
What is the correct way of implementing this trivial task in Erlang?
A correct, easy-to-understand implementation uses format
(which is like printf
):
my_time() ->
{H, M, S} = time(),
io_lib:format('~2..0b:~2..0b:~2..0b', [H, M, S]).
~2..0b
is a placeholder for an integer to be printed in base 10, taking up at least 2 characters, and padded on the left with the character 0
.
References:
- http://www.erlang.org/doc/man/io_lib.html#format-2 (the function that you're calling)
- http://www.erlang.org/doc/man/io.html#fwrite-1 (the place where the format is documented)
You should only worry about performance if you're calling your function in a tight loop, and if profiling benchmarks show that your function is actually a bottleneck.
I don't know why you think concatenating list with length 8 can be any problem but if you want be really fast you can do:
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].
There are not correct ways, there are faster or slower, more or less memory consuming and more or less concise solutions.
Edit: If you like more concise but same performance:
-define(DEC(X), $0 + X div 10, $0 + X rem 10).
my_time() ->
{H, M, S} = time(),
[?DEC(H), $:, ?DEC(M), $:, ?DEC(S)].
I like Dave Harveys dh_date module. The only "fix" required is that format/2 only take now() or datetime(). Easily fixed as in the example below.
4> dh_date:format("H:i:s",{{0,0,0},time()}).
"07:23:58"
精彩评论