[erlang-questions] microseconds since midnight

Henning Diedrich <>
Sat Jan 9 11:47:30 CET 2010


Hi Ulf,

As it is now, I don't poll time twice. But I depend on state,using a 
constant MidNightOffset.

I should stick with now() if I got you right and that's what the code 
below should allow for. The features you explained about now() are 
exactly what I need. 1% deviation from wall clock is fine, no jumps are 
important, being in sync with Erlang timers even opens up a host of 
extra possibilities I am now looking at. Thanks for pointing that out.

The functions below create the offset once (nightsynctime_offset), as 
rough total seconds between 1.1.70 and last midnight and and then every 
time I need the 4 byte sync timestamp, a call of nightsynctime(Offset) 
is made, which simply substracts the Offset from now.

Eventually it's not important that the Offset is exact but only that it 
stays the same. Where Jayson's suggestion comes in, to shave off the 
entire overhead.

Thanks,
Henning

% Notes
% http://ftp.sunet.se/pub//lang/erlang/doc/man/erl.html
%
% Erl option +c
% Disable compensation for sudden changes of system time.
%
% Normally, erlang:now/0 will not immediately reflect sudden changes in 
the system
% time, in order to keep timers (including receive-after) working. 
Instead, the time
% maintained by erlang:now/0 is slowly adjusted towards the new system 
time. (Slowly
% means in one percent adjustments; if the time is off by one minute, 
the time % will be
% adjusted in 100 minutes.)
%
% When the +c option is given, this slow adjustment will not take place. 
Instead
% erlang:now/0 will always reflect the current system time. Note that 
timers are based on
% erlang:now/0. If the system time jumps, timers then time out at the 
wrong time.

Ulf Wiger wrote:
> Since os:timespamp() and universaltime() are derived from the same
> system clock, it would be better to call TS=os:timestamp() and then
> calendar:now_to_datetime(TS). This will eliminate the race condition
> of having to sample the time twice.
>
> BR,
> Ulf W
>
> 2010/1/9, Henning Diedrich <>:
>   
>> Thanks for the education.
>>
>> I was actually looking for something as reliable as now(), i.e. deriving
>> the milliseconds since midnight (subj line of post was simplifying) to
>> get a relative, reliable four byte sync value to be sent across systems.
>>
>> I came up with the following. Bearing my original question in mind,
>> maybe you can see at a glance if this is safe. Or, since it needs to be
>> done often, could be done cheaper. Thanks a lot!
>>
>> Henning
>>
>>
>> %% Milliseconds since midnight. ------------------
>>
>> nightsynctime_offset() ->
>>
>>     {_, Time_1} = erlang:universaltime(),
>>     SSMN_1 = calendar:time_to_seconds(Time_1),
>>     {MegaSec_2, Seconds_2, _} = now(),
>>     % MidNightOffset =
>>     (MegaSec_2 * 1000000) + Seconds_2 - SSMN_1.
>>
>> nightsynctime(MidNightOffset) ->
>>
>>     {MegaSec_3, Seconds_3, MicroSec_3} = now(),
>>     % NightSyncTime =
>>     (MegaSec_3 * 1000000 + Seconds_3 - MidNightOffset) * 1000
>>      + trunc(MicroSec_3 / 1000).
>>
>> %% Test ------------------------------------------------
>>
>> start() ->
>>
>>     secondtimes(),
>>     MidNightOffset = nightsynctime_offset(),
>>     loop(MidNightOffset, 0).
>>
>> loop(MidNightOffset, LastSync) ->
>>
>>     SyncTime = nightsynctime(MidNightOffset),
>>     io:format("~p~n", [SyncTime]),
>>
>>     % test (do in the day, obviously)
>>     if SyncTime < LastSync -> exit("counting backwards") ; true -> ok end,
>>
>>     timer:sleep(166),
>>     loop(MidNightOffset, SyncTime).
>>
>>
>> Output:
>>
>> 328986
>> 329153
>> 329320
>> 329487
>> 329654
>> 329821
>> ...
>>
>>
>>
>> Ulf Wiger wrote:
>>     
>>> -----BEGIN PGP SIGNED MESSAGE-----
>>> Hash: SHA1
>>>
>>> Henning Diedrich wrote:
>>>
>>>       
>>>> Hi,
>>>>
>>>> are now() and universaltime() incrementing their seconds count at the
>>>> exact same time?
>>>>
>>>> So that the seconds from calendar:time_to_seconds(universaltime()) and
>>>> the microseconds from now() could simply be added up S*1000000+Ms?
>>>>
>>>> Or would that risk having the microseconds going back to zero at
>>>> different times then when the seconds counter is counted up?
>>>>
>>>>         
>>> now() is not guaranteed to show accurate wall-clock time. It is
>>> guaranteed to always increment at least by one microsecond for each
>>> call. It also normally adjusts its speed by up to 1% if it detects
>>> a deviation from the system clock. This is to ensure that the
>>> "real-time clock" of Erlang doesn't suddenly make a big leap in
>>> time just because some clueless operator changed the system time
>>> (or the system clock is in a time zone that obeys DST). As
>>> Erlang timers rely on now(), big leaps can either cause all timers
>>> to fire at once, or all of them going into deep sleep for a looong
>>> time, both of which can be equally disastrous.
>>>
>>> os:timestamp() looks like a now() object, but reads the system clock,
>>> and should behave the way you want. This function is a recent
>>> addition - R13, I think.
>>>
>>> BR,
>>> Ulf W
>>> -----BEGIN PGP SIGNATURE-----
>>> Version: GnuPG v1.4.9 (GNU/Linux)
>>> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
>>>
>>> iEYEARECAAYFAktHwNcACgkQtqqFieqzed1W7ACg92GMvW6WaN6vFRjyc3qzcaQM
>>> +ZoAn3Obne7EZk2gF2029IEgVgWUFeXv
>>> =XIOf
>>> -----END PGP SIGNATURE-----
>>> ---------------------------------------------------
>>>
>>> ---------------------------------------------------
>>>
>>> WE'VE CHANGED NAMES!
>>>
>>> Since January 1st 2010 Erlang Training and Consulting Ltd. has become
>>> ERLANG SOLUTIONS LTD.
>>>
>>> www.erlang-solutions.com
>>>
>>>
>>> ________________________________________________________________
>>> erlang-questions mailing list. See http://www.erlang.org/faq.html
>>> erlang-questions (at) erlang.org
>>>
>>>
>>>
>>>       
>>     
>
>   



More information about the erlang-questions mailing list