mirror of
https://github.com/dlang/phobos.git
synced 2025-04-29 22:50:38 +03:00
733 lines
20 KiB
D
733 lines
20 KiB
D
// Written in the D programming language
|
|
|
|
/++
|
|
Module containing Date/Time functionality.
|
|
|
|
This module provides:
|
|
$(UL
|
|
$(LI Types to represent points in time:
|
|
$(REF SysTime,std,_datetime,systime),
|
|
$(REF Date,std,_datetime,date),
|
|
$(REF TimeOfDay,std,_datetime,date),
|
|
$(REF DateTime,std,_datetime,date).)
|
|
$(LI Types to represent intervals of time.)
|
|
$(LI Types to represent ranges over intervals of time.)
|
|
$(LI Types to represent time zones (used by
|
|
$(REF SysTime,std,_datetime,systime)).)
|
|
$(LI A platform-independent, high precision stopwatch type:
|
|
$(LREF StopWatch))
|
|
$(LI Benchmarking functions.)
|
|
$(LI Various helper functions.)
|
|
)
|
|
|
|
Closely related to std.datetime is <a href="core_time.html">$(D core.time)</a>,
|
|
and some of the time types used in std.datetime come from there - such as
|
|
$(REF Duration, core,time), $(REF TickDuration, core,time), and
|
|
$(REF FracSec, core,time).
|
|
core.time is publically imported into std.datetime, it isn't necessary
|
|
to import it separately.
|
|
|
|
Three of the main concepts used in this module are time points, time
|
|
durations, and time intervals.
|
|
|
|
A time point is a specific point in time. e.g. January 5th, 2010
|
|
or 5:00.
|
|
|
|
A time duration is a length of time with units. e.g. 5 days or 231 seconds.
|
|
|
|
A time interval indicates a period of time associated with a fixed point in
|
|
time. It is either two time points associated with each other,
|
|
indicating the time starting at the first point up to, but not including,
|
|
the second point - e.g. [January 5th, 2010 - March 10th, 2010$(RPAREN) - or
|
|
it is a time point and a time duration associated with one another. e.g.
|
|
January 5th, 2010 and 5 days, indicating [January 5th, 2010 -
|
|
January 10th, 2010$(RPAREN).
|
|
|
|
Various arithmetic operations are supported between time points and
|
|
durations (e.g. the difference between two time points is a time duration),
|
|
and ranges can be gotten from time intervals, so range-based operations may
|
|
be done on a series of time points.
|
|
|
|
The types that the typical user is most likely to be interested in are
|
|
$(REF Date,std,_datetime,date) (if they want dates but don't care about
|
|
time), $(REF DateTime,std,_datetime,date) (if they want dates and times
|
|
but don't care about time zones), $(REF SysTime,std,_datetime,systime) (if
|
|
they want the date and time from the OS and/or do care about time zones),
|
|
and StopWatch (a platform-independent, high precision stop watch).
|
|
$(REF Date,std,_datetime,date) and $(REF DateTime,std,_datetime,date) are
|
|
optimized for calendar-based operations, while
|
|
$(REF SysTime,std,_datetime,systime) is designed for dealing with time from
|
|
the OS. Check out their specific documentation for more details.
|
|
|
|
To get the current time, use $(REF Clock.currTime,std,_datetime,systime).
|
|
It will return the current time as a $(REF SysTime,std,_datetime,systime). To
|
|
print it, $(D toString) is sufficient, but if using $(D toISOString),
|
|
$(D toISOExtString), or $(D toSimpleString), use the corresponding
|
|
$(D fromISOString), $(D fromISOExtString), or $(D fromSimpleString) to
|
|
create a $(REF SysTime,std,_datetime,systime) from the string.
|
|
|
|
--------------------
|
|
auto currentTime = Clock.currTime();
|
|
auto timeString = currentTime.toISOExtString();
|
|
auto restoredTime = SysTime.fromISOExtString(timeString);
|
|
--------------------
|
|
|
|
Various functions take a string (or strings) to represent a unit of time
|
|
(e.g. $(D convert!("days", "hours")(numDays))). The valid strings to use
|
|
with such functions are $(D "years"), $(D "months"), $(D "weeks"),
|
|
$(D "days"), $(D "hours"), $(D "minutes"), $(D "seconds"),
|
|
$(D "msecs") (milliseconds), $(D "usecs") (microseconds),
|
|
$(D "hnsecs") (hecto-nanoseconds - i.e. 100 ns), or some subset thereof.
|
|
There are a few functions in core.time which take $(D "nsecs"), but because
|
|
nothing in std.datetime has precision greater than hnsecs, and very little
|
|
in core.time does, no functions in std.datetime accept $(D "nsecs").
|
|
To remember which units are abbreviated and which aren't,
|
|
all units seconds and greater use their full names, and all
|
|
sub-second units are abbreviated (since they'd be rather long if they
|
|
weren't).
|
|
|
|
Note:
|
|
$(REF DateTimeException,std,_datetime,date) is an alias for
|
|
$(REF TimeException, core,time), so you don't need to worry about
|
|
core.time functions and std.datetime functions throwing different
|
|
exception types (except in the rare case that they throw something other
|
|
than $(REF TimeException, core,time) or
|
|
$(REF DateTimeException,std,_datetime,date)).
|
|
|
|
See_Also:
|
|
$(DDLINK intro-to-_datetime, Introduction to std.datetime,
|
|
Introduction to std._datetime)<br>
|
|
$(HTTP en.wikipedia.org/wiki/ISO_8601, ISO 8601)<br>
|
|
$(HTTP en.wikipedia.org/wiki/Tz_database,
|
|
Wikipedia entry on TZ Database)<br>
|
|
$(HTTP en.wikipedia.org/wiki/List_of_tz_database_time_zones,
|
|
List of Time Zones)<br>
|
|
|
|
License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
|
|
Authors: Jonathan M Davis and Kato Shoichi
|
|
Source: $(PHOBOSSRC std/_datetime/package.d)
|
|
+/
|
|
module std.datetime;
|
|
|
|
public import core.time;
|
|
public import std.datetime.date;
|
|
public import std.datetime.interval;
|
|
public import std.datetime.systime;
|
|
public import std.datetime.timezone;
|
|
|
|
import core.exception : AssertError;
|
|
import std.typecons : Flag, Yes, No;
|
|
import std.functional : unaryFun;
|
|
import std.traits;
|
|
|
|
|
|
// Verify module example.
|
|
@safe unittest
|
|
{
|
|
auto currentTime = Clock.currTime();
|
|
auto timeString = currentTime.toISOExtString();
|
|
auto restoredTime = SysTime.fromISOExtString(timeString);
|
|
}
|
|
|
|
// Verify Examples for core.time.Duration which couldn't be in core.time.
|
|
@safe unittest
|
|
{
|
|
assert(std.datetime.Date(2010, 9, 7) + dur!"days"(5) ==
|
|
std.datetime.Date(2010, 9, 12));
|
|
|
|
assert(std.datetime.Date(2010, 9, 7) - std.datetime.Date(2010, 10, 3) ==
|
|
dur!"days"(-26));
|
|
}
|
|
|
|
@safe unittest
|
|
{
|
|
import std.traits : hasUnsharedAliasing;
|
|
/* Issue 6642 */
|
|
static assert(!hasUnsharedAliasing!Date);
|
|
static assert(!hasUnsharedAliasing!TimeOfDay);
|
|
static assert(!hasUnsharedAliasing!DateTime);
|
|
static assert(!hasUnsharedAliasing!SysTime);
|
|
}
|
|
|
|
|
|
//==============================================================================
|
|
// Everything after here will be deprecated after we have replacements which
|
|
// use MonoTime and Duration.
|
|
//==============================================================================
|
|
|
|
|
|
/++
|
|
Used by StopWatch to indicate whether it should start immediately upon
|
|
construction.
|
|
|
|
If set to $(D AutoStart.no), then the stopwatch is not started when it is
|
|
constructed.
|
|
|
|
Otherwise, if set to $(D AutoStart.yes), then the stopwatch is started when
|
|
it is constructed.
|
|
+/
|
|
alias AutoStart = Flag!"autoStart";
|
|
|
|
|
|
/++
|
|
$(RED This will be deprecated in 2.076. Please use
|
|
$(REF StopWatch,std,datetime,stopwatch) instead. It uses
|
|
$(REF Monotime,core,time) and $(REF Duration,core,time) rather
|
|
than $(REF TickDuration,core,time), which will also be deprecated in
|
|
2.076.)
|
|
|
|
$(D StopWatch) measures time as precisely as possible.
|
|
|
|
This class uses a high-performance counter. On Windows systems, it uses
|
|
$(D QueryPerformanceCounter), and on Posix systems, it uses
|
|
$(D clock_gettime) if available, and $(D gettimeofday) otherwise.
|
|
|
|
But the precision of $(D StopWatch) differs from system to system. It is
|
|
impossible to for it to be the same from system to system since the precision
|
|
of the system clock varies from system to system, and other system-dependent
|
|
and situation-dependent stuff (such as the overhead of a context switch
|
|
between threads) can also affect $(D StopWatch)'s accuracy.
|
|
+/
|
|
@safe struct StopWatch
|
|
{
|
|
public:
|
|
|
|
/++
|
|
Auto start with constructor.
|
|
+/
|
|
this(AutoStart autostart) @nogc
|
|
{
|
|
if (autostart)
|
|
start();
|
|
}
|
|
|
|
@nogc @safe unittest
|
|
{
|
|
auto sw = StopWatch(Yes.autoStart);
|
|
sw.stop();
|
|
}
|
|
|
|
|
|
///
|
|
bool opEquals(const StopWatch rhs) const pure nothrow @nogc
|
|
{
|
|
return opEquals(rhs);
|
|
}
|
|
|
|
/// ditto
|
|
bool opEquals(const ref StopWatch rhs) const pure nothrow @nogc
|
|
{
|
|
return _timeStart == rhs._timeStart &&
|
|
_timeMeasured == rhs._timeMeasured;
|
|
}
|
|
|
|
|
|
/++
|
|
Resets the stop watch.
|
|
+/
|
|
void reset() @nogc
|
|
{
|
|
if (_flagStarted)
|
|
{
|
|
// Set current system time if StopWatch is measuring.
|
|
_timeStart = TickDuration.currSystemTick;
|
|
}
|
|
else
|
|
{
|
|
// Set zero if StopWatch is not measuring.
|
|
_timeStart.length = 0;
|
|
}
|
|
|
|
_timeMeasured.length = 0;
|
|
}
|
|
|
|
///
|
|
@nogc @safe unittest
|
|
{
|
|
StopWatch sw;
|
|
sw.start();
|
|
sw.stop();
|
|
sw.reset();
|
|
assert(sw.peek().to!("seconds", real)() == 0);
|
|
}
|
|
|
|
|
|
/++
|
|
Starts the stop watch.
|
|
+/
|
|
void start() @nogc
|
|
{
|
|
assert(!_flagStarted);
|
|
_flagStarted = true;
|
|
_timeStart = TickDuration.currSystemTick;
|
|
}
|
|
|
|
@nogc @system unittest
|
|
{
|
|
StopWatch sw;
|
|
sw.start();
|
|
auto t1 = sw.peek();
|
|
bool doublestart = true;
|
|
try
|
|
sw.start();
|
|
catch (AssertError e)
|
|
doublestart = false;
|
|
assert(!doublestart);
|
|
sw.stop();
|
|
assert((t1 - sw.peek()).to!("seconds", real)() <= 0);
|
|
}
|
|
|
|
|
|
/++
|
|
Stops the stop watch.
|
|
+/
|
|
void stop() @nogc
|
|
{
|
|
assert(_flagStarted);
|
|
_flagStarted = false;
|
|
_timeMeasured += TickDuration.currSystemTick - _timeStart;
|
|
}
|
|
|
|
@nogc @system unittest
|
|
{
|
|
StopWatch sw;
|
|
sw.start();
|
|
sw.stop();
|
|
auto t1 = sw.peek();
|
|
bool doublestop = true;
|
|
try
|
|
sw.stop();
|
|
catch (AssertError e)
|
|
doublestop = false;
|
|
assert(!doublestop);
|
|
assert((t1 - sw.peek()).to!("seconds", real)() == 0);
|
|
}
|
|
|
|
|
|
/++
|
|
Peek at the amount of time which has passed since the stop watch was
|
|
started.
|
|
+/
|
|
TickDuration peek() const @nogc
|
|
{
|
|
if (_flagStarted)
|
|
return TickDuration.currSystemTick - _timeStart + _timeMeasured;
|
|
|
|
return _timeMeasured;
|
|
}
|
|
|
|
@nogc @safe unittest
|
|
{
|
|
StopWatch sw;
|
|
sw.start();
|
|
auto t1 = sw.peek();
|
|
sw.stop();
|
|
auto t2 = sw.peek();
|
|
auto t3 = sw.peek();
|
|
assert(t1 <= t2);
|
|
assert(t2 == t3);
|
|
}
|
|
|
|
|
|
/++
|
|
Set the amount of time which has been measured since the stop watch was
|
|
started.
|
|
+/
|
|
void setMeasured(TickDuration d) @nogc
|
|
{
|
|
reset();
|
|
_timeMeasured = d;
|
|
}
|
|
|
|
@nogc @safe unittest
|
|
{
|
|
StopWatch sw;
|
|
TickDuration t0;
|
|
t0.length = 100;
|
|
sw.setMeasured(t0);
|
|
auto t1 = sw.peek();
|
|
assert(t0 == t1);
|
|
}
|
|
|
|
|
|
/++
|
|
Confirm whether this stopwatch is measuring time.
|
|
+/
|
|
bool running() @property const pure nothrow @nogc
|
|
{
|
|
return _flagStarted;
|
|
}
|
|
|
|
@nogc @safe unittest
|
|
{
|
|
StopWatch sw1;
|
|
assert(!sw1.running);
|
|
sw1.start();
|
|
assert(sw1.running);
|
|
sw1.stop();
|
|
assert(!sw1.running);
|
|
StopWatch sw2 = Yes.autoStart;
|
|
assert(sw2.running);
|
|
sw2.stop();
|
|
assert(!sw2.running);
|
|
sw2.start();
|
|
assert(sw2.running);
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
// true if observing.
|
|
bool _flagStarted = false;
|
|
|
|
// TickDuration at the time of StopWatch starting measurement.
|
|
TickDuration _timeStart;
|
|
|
|
// Total time that StopWatch ran.
|
|
TickDuration _timeMeasured;
|
|
}
|
|
|
|
///
|
|
@safe unittest
|
|
{
|
|
void writeln(S...)(S args){}
|
|
static void bar() {}
|
|
|
|
StopWatch sw;
|
|
enum n = 100;
|
|
TickDuration[n] times;
|
|
TickDuration last = TickDuration.from!"seconds"(0);
|
|
foreach (i; 0 .. n)
|
|
{
|
|
sw.start(); //start/resume mesuring.
|
|
foreach (unused; 0 .. 1_000_000)
|
|
bar();
|
|
sw.stop(); //stop/pause measuring.
|
|
//Return value of peek() after having stopped are the always same.
|
|
writeln((i + 1) * 1_000_000, " times done, lap time: ",
|
|
sw.peek().msecs, "[ms]");
|
|
times[i] = sw.peek() - last;
|
|
last = sw.peek();
|
|
}
|
|
real sum = 0;
|
|
// To get the number of seconds,
|
|
// use properties of TickDuration.
|
|
// (seconds, msecs, usecs, hnsecs)
|
|
foreach (t; times)
|
|
sum += t.hnsecs;
|
|
writeln("Average time: ", sum/n, " hnsecs");
|
|
}
|
|
|
|
|
|
/++
|
|
$(RED This will be deprecated in 2.076. Please use
|
|
$(REF benchmark,std,datetime,stopwatch) instead. It uses
|
|
$(REF Monotime,core,time) and $(REF Duration,core,time) rather
|
|
than $(REF TickDuration,core,time), which will also be deprecated in
|
|
2.076.)
|
|
|
|
Benchmarks code for speed assessment and comparison.
|
|
|
|
Params:
|
|
fun = aliases of callable objects (e.g. function names). Each should
|
|
take no arguments.
|
|
n = The number of times each function is to be executed.
|
|
|
|
Returns:
|
|
The amount of time (as a $(REF TickDuration, core,time)) that it took to
|
|
call each function $(D n) times. The first value is the length of time
|
|
that it took to call $(D fun[0]) $(D n) times. The second value is the
|
|
length of time it took to call $(D fun[1]) $(D n) times. Etc.
|
|
|
|
Note that casting the TickDurations to $(REF Duration, core,time)s will make
|
|
the results easier to deal with (and it may change in the future that
|
|
benchmark will return an array of Durations rather than TickDurations).
|
|
|
|
See_Also:
|
|
$(LREF measureTime)
|
|
+/
|
|
TickDuration[fun.length] benchmark(fun...)(uint n)
|
|
{
|
|
TickDuration[fun.length] result;
|
|
StopWatch sw;
|
|
sw.start();
|
|
|
|
foreach (i, unused; fun)
|
|
{
|
|
sw.reset();
|
|
foreach (j; 0 .. n)
|
|
fun[i]();
|
|
result[i] = sw.peek();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
///
|
|
@safe unittest
|
|
{
|
|
import std.conv : to;
|
|
int a;
|
|
void f0() {}
|
|
void f1() {auto b = a;}
|
|
void f2() {auto b = to!string(a);}
|
|
auto r = benchmark!(f0, f1, f2)(10_000);
|
|
auto f0Result = to!Duration(r[0]); // time f0 took to run 10,000 times
|
|
auto f1Result = to!Duration(r[1]); // time f1 took to run 10,000 times
|
|
auto f2Result = to!Duration(r[2]); // time f2 took to run 10,000 times
|
|
}
|
|
|
|
@safe unittest
|
|
{
|
|
int a;
|
|
void f0() {}
|
|
//void f1() {auto b = to!(string)(a);}
|
|
void f2() {auto b = (a);}
|
|
auto r = benchmark!(f0, f2)(100);
|
|
}
|
|
|
|
|
|
/++
|
|
Return value of benchmark with two functions comparing.
|
|
+/
|
|
@safe struct ComparingBenchmarkResult
|
|
{
|
|
/++
|
|
Evaluation value
|
|
|
|
This returns the evaluation value of performance as the ratio of
|
|
baseFunc's time over targetFunc's time. If performance is high, this
|
|
returns a high value.
|
|
+/
|
|
@property real point() const pure nothrow
|
|
{
|
|
return _baseTime.length / cast(const real)_targetTime.length;
|
|
}
|
|
|
|
|
|
/++
|
|
The time required of the base function
|
|
+/
|
|
@property public TickDuration baseTime() const pure nothrow
|
|
{
|
|
return _baseTime;
|
|
}
|
|
|
|
|
|
/++
|
|
The time required of the target function
|
|
+/
|
|
@property public TickDuration targetTime() const pure nothrow
|
|
{
|
|
return _targetTime;
|
|
}
|
|
|
|
private:
|
|
|
|
this(TickDuration baseTime, TickDuration targetTime) pure nothrow
|
|
{
|
|
_baseTime = baseTime;
|
|
_targetTime = targetTime;
|
|
}
|
|
|
|
TickDuration _baseTime;
|
|
TickDuration _targetTime;
|
|
}
|
|
|
|
|
|
/++
|
|
$(RED This will be deprecated in 2.076. Please use
|
|
$(REF benchmark,std,datetime,stopwatch) instead. This function has
|
|
not been ported to $(REF Monotime,core,time) and
|
|
$(REF Duration,core,time), because it is a trivial wrapper around
|
|
benchmark.)
|
|
|
|
Benchmark with two functions comparing.
|
|
|
|
Params:
|
|
baseFunc = The function to become the base of the speed.
|
|
targetFunc = The function that wants to measure speed.
|
|
times = The number of times each function is to be executed.
|
|
+/
|
|
ComparingBenchmarkResult comparingBenchmark(alias baseFunc,
|
|
alias targetFunc,
|
|
int times = 0xfff)()
|
|
{
|
|
auto t = benchmark!(baseFunc, targetFunc)(times);
|
|
return ComparingBenchmarkResult(t[0], t[1]);
|
|
}
|
|
|
|
///
|
|
@safe unittest
|
|
{
|
|
void f1x() {}
|
|
void f2x() {}
|
|
@safe void f1o() {}
|
|
@safe void f2o() {}
|
|
auto b1 = comparingBenchmark!(f1o, f2o, 1)(); // OK
|
|
//writeln(b1.point);
|
|
}
|
|
|
|
//Bug# 8450
|
|
@system unittest
|
|
{
|
|
@safe void safeFunc() {}
|
|
@trusted void trustFunc() {}
|
|
@system void sysFunc() {}
|
|
auto safeResult = comparingBenchmark!((){safeFunc();}, (){safeFunc();})();
|
|
auto trustResult = comparingBenchmark!((){trustFunc();}, (){trustFunc();})();
|
|
auto sysResult = comparingBenchmark!((){sysFunc();}, (){sysFunc();})();
|
|
auto mixedResult1 = comparingBenchmark!((){safeFunc();}, (){trustFunc();})();
|
|
auto mixedResult2 = comparingBenchmark!((){trustFunc();}, (){sysFunc();})();
|
|
auto mixedResult3 = comparingBenchmark!((){safeFunc();}, (){sysFunc();})();
|
|
}
|
|
|
|
|
|
/++
|
|
$(RED This will be deprecated in 2.076. Please use
|
|
$(REF StopWatch,std,datetime,stopwatch) instead. This function has
|
|
not been ported to $(REF Monotime,core,time) and
|
|
$(REF Duration,core,time), because it is a trivial wrapper around
|
|
StopWatch.)
|
|
|
|
Function for starting to a stop watch time when the function is called
|
|
and stopping it when its return value goes out of scope and is destroyed.
|
|
|
|
When the value that is returned by this function is destroyed,
|
|
$(D func) will run. $(D func) is a unary function that takes a
|
|
$(REF TickDuration, core,time).
|
|
|
|
Example:
|
|
--------------------
|
|
{
|
|
auto mt = measureTime!((TickDuration a)
|
|
{ /+ do something when the scope is exited +/ });
|
|
// do something that needs to be timed
|
|
}
|
|
--------------------
|
|
|
|
which is functionally equivalent to
|
|
|
|
--------------------
|
|
{
|
|
auto sw = StopWatch(Yes.autoStart);
|
|
scope(exit)
|
|
{
|
|
TickDuration a = sw.peek();
|
|
/+ do something when the scope is exited +/
|
|
}
|
|
// do something that needs to be timed
|
|
}
|
|
--------------------
|
|
|
|
See_Also:
|
|
$(LREF benchmark)
|
|
+/
|
|
@safe auto measureTime(alias func)()
|
|
if (isSafe!((){StopWatch sw; unaryFun!func(sw.peek());}))
|
|
{
|
|
struct Result
|
|
{
|
|
private StopWatch _sw = void;
|
|
this(AutoStart as)
|
|
{
|
|
_sw = StopWatch(as);
|
|
}
|
|
~this()
|
|
{
|
|
unaryFun!(func)(_sw.peek());
|
|
}
|
|
}
|
|
return Result(Yes.autoStart);
|
|
}
|
|
|
|
auto measureTime(alias func)()
|
|
if (!isSafe!((){StopWatch sw; unaryFun!func(sw.peek());}))
|
|
{
|
|
struct Result
|
|
{
|
|
private StopWatch _sw = void;
|
|
this(AutoStart as)
|
|
{
|
|
_sw = StopWatch(as);
|
|
}
|
|
~this()
|
|
{
|
|
unaryFun!(func)(_sw.peek());
|
|
}
|
|
}
|
|
return Result(Yes.autoStart);
|
|
}
|
|
|
|
// Verify Example.
|
|
@safe unittest
|
|
{
|
|
{
|
|
auto mt = measureTime!((TickDuration a)
|
|
{ /+ do something when the scope is exited +/ });
|
|
// do something that needs to be timed
|
|
}
|
|
|
|
{
|
|
auto sw = StopWatch(Yes.autoStart);
|
|
scope(exit)
|
|
{
|
|
TickDuration a = sw.peek();
|
|
/+ do something when the scope is exited +/
|
|
}
|
|
// do something that needs to be timed
|
|
}
|
|
}
|
|
|
|
@safe unittest
|
|
{
|
|
import std.math : isNaN;
|
|
|
|
@safe static void func(TickDuration td)
|
|
{
|
|
assert(!td.to!("seconds", real)().isNaN());
|
|
}
|
|
|
|
auto mt = measureTime!(func)();
|
|
|
|
/+
|
|
with (measureTime!((a){assert(a.seconds);}))
|
|
{
|
|
// doSomething();
|
|
// @@@BUG@@@ doesn't work yet.
|
|
}
|
|
+/
|
|
}
|
|
|
|
@safe unittest
|
|
{
|
|
import std.math : isNaN;
|
|
|
|
static void func(TickDuration td)
|
|
{
|
|
assert(!td.to!("seconds", real)().isNaN());
|
|
}
|
|
|
|
auto mt = measureTime!(func)();
|
|
|
|
/+
|
|
with (measureTime!((a){assert(a.seconds);}))
|
|
{
|
|
// doSomething();
|
|
// @@@BUG@@@ doesn't work yet.
|
|
}
|
|
+/
|
|
}
|
|
|
|
//Bug# 8450
|
|
@system unittest
|
|
{
|
|
@safe void safeFunc() {}
|
|
@trusted void trustFunc() {}
|
|
@system void sysFunc() {}
|
|
auto safeResult = measureTime!((a){safeFunc();})();
|
|
auto trustResult = measureTime!((a){trustFunc();})();
|
|
auto sysResult = measureTime!((a){sysFunc();})();
|
|
}
|