[erlang-questions] timestamp conversion

143 views
Skip to first unread message

Peter W. Morreale

unread,
Apr 15, 2011, 6:13:31 PM4/15/11
to erlang-questions

This may be embarrassingly simple, but I am struggling with it...

I need compare string timestamps for dealing with expiration. In some
cases it may another string timestamp, in others it will be against the
current time.

The string timestamps will always have the format:

Year-Month-DayTHour:Min:SecZ"

I think I want to convert to integer seconds, however even then its not
clear to me how to perform the comparison, although I think this is a
case for using the "if" expression.

Please be gentle, I'm still new to Erlang.

Thanks much
-PWM


_______________________________________________
erlang-questions mailing list
erlang-q...@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions

Juan Jose Comellas

unread,
Apr 15, 2011, 6:47:56 PM4/15/11
to pmor...@novell.com, erlang-questions
This function should help you convert a string timestamp into the
elapsed seconds since January 1, year 0:

timestamp_to_gregorian_seconds(Timestamp) ->
%% Divide the string into its different datetime components
Tokens = string:tokens(Timestamp, "-T:Z"),
%% Convert each string into an integer
[Year, Month, Day, Hour, Min, Sec] = [list_to_integer(N) || N <- Tokens],
%% Convert the datetime to seconds
calendar:datetime_to_gregorian_seconds({{Year, Month, Day}, {Hour,
Min, Sec}}).

I haven't even compiled it, but it should give you and idea of how to
convert the timestamps.

Juanjo

Jachym Holecek

unread,
Apr 15, 2011, 6:53:49 PM4/15/11
to Peter W. Morreale, erlang-questions
# Peter W. Morreale 2011-04-15:

> This may be embarrassingly simple, but I am struggling with it...
>
> I need compare string timestamps for dealing with expiration. In some
> cases it may another string timestamp, in others it will be against the
> current time.
>
> The string timestamps will always have the format:
>
> Year-Month-DayTHour:Min:SecZ"
>
> I think I want to convert to integer seconds, however even then its not
> clear to me how to perform the comparison, although I think this is a
> case for using the "if" expression.
>
> Please be gentle, I'm still new to Erlang.

Well, if all the fields are fixed width and taking final 'Z' to mean UTC [1],
you can just compare the strings, it will happen to work just the way you
want. :-) Try it in the shell to convince yourself.

More generally, you can easily [2] parse the string into datetime, which has
the form {{Year, Month, Day}, {Hour, Min, Sec}}, and then use functions in
calendar module (erl -man calendar) to convert that to gregorian seconds;
that's a simple (and large) integer suitable for comparisons and distance
calculations. For obtaining current timestamp you can use erlang:universaltime()
or now(), depends if on the resolution you need.

As to performing the comparison itself, you can do:

case T2 >= T1 of
true ->
expire(Thing);
_ ->
keep(Thing)
end

or

if T2 >= T1 ->
expire(Thing);
true ->
keep(Thing)
end

or

maybe_expire(T2, T1, Thing)

where

maybe_expire(T2, T1, Thing) when T2 >= T1 ->
expire(Thing);
maybe_expire(_, _, Thing) ->
keep(Thing).

In all of these, T1 and T2 are timestamps and their representation depends
on the conditions above. 'Thing', expire/1 and keep/1 have just intuitive
meaning.

HTH,
-- Jachym

[1] For nitpicks: and assuming characters codes for 0-9 sort in natural order.

[2] Assuming fixed fields widths, this goes like (completely untested):

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

If field widths aren't fixed, it's still simple but a bit tedious -- ask if you
need it (and don't forget to subject the person feeding you dodgy timestamps to
great pain in that case!).

Steve Davis

unread,
Apr 15, 2011, 7:15:30 PM4/15/11
to erlang-q...@erlang.org
I've not exhaustively tested this but a direct comparison of the list
(though I prefer binary text representations for a whole raft of
reasons)... should work for you.

e.g. given the string format (esp. length) is known to be exactly the
same:
L1 = "2011-04-15T23:00:48Z"
L2 = "2011-04-15T23:00:53Z"

4> L1 < L2.
true
5> L1 > L2.
false

etc.

> erlang-questi...@erlang.orghttp://erlang.org/mailman/listinfo/erlang-questions

Peter W. Morreale

unread,
Apr 15, 2011, 7:35:03 PM4/15/11
to Steve Davis, erlang-q...@erlang.org
On Fri, 2011-04-15 at 16:15 -0700, Steve Davis wrote:
> I've not exhaustively tested this but a direct comparison of the list
> (though I prefer binary text representations for a whole raft of
> reasons)... should work for you.
>
> e.g. given the string format (esp. length) is known to be exactly the
> same:
> L1 = "2011-04-15T23:00:48Z"
> L2 = "2011-04-15T23:00:53Z"
>
> 4> L1 < L2.
> true
> 5> L1 > L2.
> false
>
> etc.
>

Oh my.

I get it.

Thank you to all who responded.

Best
-PWM

Reply all
Reply to author
Forward
0 new messages