now() -> now_to_tz

Per Hedeland per@REDACTED
Thu Feb 27 14:54:42 CET 2003


Anastasia Gornostaeva <ermine@REDACTED> wrote:
>
>How can I convert time now() to time using appropriate TZ?
>I found only calendar:now_to_local(), but I want convert to other time zones.

This is actually not entirely trivial to do inside or outside Erlang,
since there are no "explicit" ANSI/POSIX/Unix interfaces to get that
info: The existing interfaces deal only with local time and GMT/UTC,
obtaining the mapping between them by means of some system-specific
config file such as /etc/localtime and/or the TZ environment variable.

Below is a convoluted "solution" that works on two (2) Unix dialects
(and actually 'linux' isn't even a guarantee for that), and whose only
excuse is that you don't have to write any non-Erlang code.:-)
Realistically you'd replace 'date' and its arguments with a few lines of
C that did just what you wanted (basically call localtime() - it will
"work" when TZ is appropriately set on program startup).

--Per Hedeland


%% 2> N=erlang:now().                                
%% {1046,347773,325485}
%% 3> calendar:now_to_local_time(N).                 
%% {{2003,2,27},{13,9,33}}
%% 4> foo:now_to_zone_time(N, "Europe/Stockholm").
%% {{2003,2,27},{13,9,33}}
%% 5> foo:now_to_zone_time(N, "").                
%% {{2003,2,27},{12,9,33}}
%% 6> foo:now_to_zone_time(N, "America/Los_Angeles").
%% {{2003,2,27},{4,9,33}}

now_to_zone_time(Now, Zone) ->
    Args = case os:type() of
	       {unix, freebsd} ->
		   {MegaSecs, Secs, _} = Now,
		   io_lib:format(" -j -f %s ~w ", [1000000 * MegaSecs + Secs]);
	       {unix, linux} ->
		   {{UY, UMon, UD}, {UH, UMin, US}} =
		       calendar:now_to_universal_time(Now),
		   io_lib:format(" --date='~w-~w-~w ~w:~w:~w UTC' ",
				 [UY, UMon, UD, UH, UMin, US])
	   end,
    Cmd = "TZ=" ++ Zone ++ " date" ++ Args ++ " '+%Y %m %d %H %M %S'",
    ZoneTimeStr = string:tokens(os:cmd(Cmd), " \n"),
    [ZY, ZMon, ZD, ZH, ZMin, ZS] = lists:map(fun(T) -> list_to_integer(T) end,
					     ZoneTimeStr),
    {list_to_tuple([ZY, ZMon, ZD]), list_to_tuple([ZH, ZMin, ZS])}.




More information about the erlang-questions mailing list