Skip to content

Commit

Permalink
Implement issue 13433.
Browse files Browse the repository at this point in the history
This adds an option for getting the time using the coarser, faster
realtime clock on systems that support it for those who need to get the
time frequently (and thus quickly) but don't need it to be particularly
precise.
  • Loading branch information
jmdavis committed Oct 4, 2014
1 parent 95222b8 commit 2e60521
Showing 1 changed file with 82 additions and 17 deletions.
99 changes: 82 additions & 17 deletions std/datetime.d
Original file line number Diff line number Diff line change
Expand Up @@ -331,13 +331,33 @@ public:
/++
Returns the current time in the given time zone.

The overload with one parameter uses $(LREF LocalTime) for the time zone
It's provided so that those needing to make $(D coarse) be $(D true)
don't have to pass the time zone when they want $(LREF LocalTime).

Params:
tz = The time zone for the SysTime that's returned.
coarse = Whether a coarse time source should be used instead of the
normal one. So, it's faster, but less precise (e.g. 1 ms
instead of 1 usec). Not all systems support a coarse option
(in which case, the same clock is used regardless), and it
will vary from system to system how precise or fast it is.
But it does provide an option where getting the time as
quickly as possible is necessary, but high precision is
not.

Throws:
$(XREF exception, ErrnoException) (on Posix) or $(XREF exception, Exception) (on Windows)
if it fails to get the time of day.
$(LREF DateTimeException) if it fails to get the time.
+/
static SysTime currTime(immutable TimeZone tz = LocalTime()) @safe
static SysTime currTime(immutable TimeZone tz = LocalTime(), bool coarse = false) @safe
{
return SysTime(currStdTime(coarse), tz);
}

/++ Ditto +/
static SysTime currTime(bool coarse) @safe
{
return SysTime(currStdTime, tz);
return SysTime(currStdTime(coarse), LocalTime());
}

unittest
Expand All @@ -362,16 +382,37 @@ public:
assert(diff >= -2);
assert(diff <= 2);
}

auto prec1 = Clock.currTime();
auto prec2 = Clock.currTime(UTC());
auto prec3 = Clock.currTime(UTC(), false);
assert(prec1 <= prec2, format("%s %s", prec1, prec2));
assert(prec2 <= prec3, format("%s %s", prec2, prec3));

auto coarse1 = Clock.currTime(UTC(), true);
auto coarse2 = Clock.currTime(true);
assert(coarse1 <= coarse2, format("%s %s", coarse1, coarse2));
}


/++
Returns the number of hnsecs since midnight, January 1st, 1 A.D. for the
current time.

Params:
coarse = Whether a coarse time source should be used instead of the
normal one. So, it's faster, but less precise (e.g. 1 ms
instead of 1 usec). Not all systems support a coarse option
(in which case, the same clock is used regardless), and it
will vary from system to system how precise or fast it is.
But it does provide an option where getting the time as
quickly as possible is necessary, but high precision is
not.

Throws:
$(LREF DateTimeException) if it fails to get the time.
+/
static @property long currStdTime() @trusted
static long currStdTime(bool coarse = false) @trusted
{
version(Windows)
{
Expand All @@ -384,18 +425,7 @@ public:
{
enum hnsecsToUnixEpoch = 621_355_968_000_000_000L;

static if(is(typeof(clock_gettime)))
{
timespec ts;

if(clock_gettime(CLOCK_REALTIME, &ts) != 0)
throw new TimeException("Failed in clock_gettime().");

return convert!("seconds", "hnsecs")(ts.tv_sec) +
ts.tv_nsec / 100 +
hnsecsToUnixEpoch;
}
else
version(OSX)
{
timeval tv;

Expand All @@ -406,9 +436,44 @@ public:
convert!("usecs", "hnsecs")(tv.tv_usec) +
hnsecsToUnixEpoch;
}
else version(Posix)
{
timespec ts;

version(linux)
enum coarseClock = CLOCK_REALTIME_COARSE;
else version(FreeBSD)
enum coarseClock = CLOCK_REALTIME_FAST;
else
static assert(0, "What is the constant for the COARSE realtime clock on this system?");

if(clock_gettime(coarse ? coarseClock : CLOCK_REALTIME, &ts) != 0)
throw new TimeException("Failed in clock_gettime().");

return convert!("seconds", "hnsecs")(ts.tv_sec) +
ts.tv_nsec / 100 +
hnsecsToUnixEpoch;
}
}
}

unittest
{
auto prec1 = Clock.currStdTime;
auto prec2 = Clock.currStdTime(false);
assert(prec1 <= prec2, format("%s %s", prec1, prec2));

// Note that coarse1 might actually be before prec2, because if a coarse
// clock exists on this system, then prec2 and coarse1 are using
// different clocks (though the difference will probably be around the
// resolution of the coarse clock rather than being drastically
// different).
auto coarse1 = Clock.currStdTime(true);
auto coarse2 = Clock.currStdTime(true);
assert(coarse1 <= coarse2, format("%s %s", coarse1, coarse2));
}


/++
The current system tick. The number of ticks per second varies from
system to system. currSystemTick uses a monotonic clock, so it's
Expand Down

0 comments on commit 2e60521

Please sign in to comment.