now() and arithmetic
Matthias Lang
matthias@REDACTED
Mon May 6 10:58:25 CEST 2002
> Does TZ actually affect now() on some platforms?
I think the manpage is wrong:
now()
Returns the tuple {MegaSecs, Secs, Microsecs}
which is the elapsed time since 00:00 GMT, January
1, 1970 (zero hour) on the assumption that the
underlying OS supports this. Otherwise, some other
point in time is chosen. It is also guaranteed that
subsequent calls to this BIF returns continuously
increasing values. Hence, the return value from
now() can be used to generate unique time-stamps.
It can only be used to check the local time of day
if the time-zone info of the underlying operating
system is properly configured.
now() is defined as being the elapsed time since 00:00 GMT, Jan 1,
1970, so it should be independent of the timezone in any case. Maybe
the last sentence should be moved to the calendar module, under
now_to_local_time/1.
Digging deeper: the value now() returns is based on
sys_gettimeofday(), which, for all unix implementations, is a call to
gettimeofday with a NULL second argument. Under linux that means TZ
does not affect it. I'd be surprised if that wasn't so for other
unices. No idea what VxWorks and Windows do. As far as I can see
(quick look only!), the highres timer stuff in solaris is only used to
fine-tune the value from gettimeofday.
> Is this the "rapidly changing system time" or have you had some
> crazy users playing with the time?
<war story>
Whenever one of Corelatus' magic boxes was newly installed and
configured in the customer's test lab, the internal hardware watchdog
would reboot it once. Embarassing when you're selling a 'carrier
class' system.
Turned out that all the systems had been sitting in storage for a
month and had thus forgotten what the time was (we use a high MTBF
'supercap' instead of a battery, so the realtime clock can keep going
for a week without power, but not a month). So, on first boot, they'd
get a hardcoded time and, as soon as NTP was configured, the system
time would adjust itself by about a year. Because of a bug in Erlang
R7B-3 (fixed in R8B-1), Erlang's timers would go insane and trigger
events nonstop. The VM's CPU use would be sky high, which the watchdog
correctly diagnosed as a sign of insanity and rebooted.
Now that the problem is fixed, the same series of events causes no
greater damage than now() running 1% faster than it really should, so
all of our internal timers are 1% shorter than nominal. Truly
timing-critical events are managed by hardware, so this is OK for us.
</war story>
> PS Here are my amazingly simple routines.
>
> now_to_timeval() ->
> now_to_timeval(now()).
>
> now_to_timeval({MegaSecs, Secs, MicroSecs}) ->
> {MegaSecs*1000000+Secs, MicroSecs}.
>
> timeval_to_now({Secs, MicroSecs}) ->
> {trunc(Secs / 1000000), Secs rem 1000000, MicroSecs}.
If you use {Secs div 1000000, ... } it'll make systems without
floating point happier.
Matthias
More information about the erlang-questions
mailing list