mirror of
https://github.com/dlang/phobos.git
synced 2025-04-28 22:21:09 +03:00
34104 lines
1.5 MiB
34104 lines
1.5 MiB
//Written in the D programming language
|
|
|
|
/++
|
|
Module containing Date/Time functionality.
|
|
|
|
This module provides:
|
|
$(UL
|
|
$(LI Types to represent points in time: $(D SysTime), $(D Date),
|
|
$(D TimeOfDay), and $(D DateTime).)
|
|
$(LI Types to represent intervals of time.)
|
|
$(LI Types to represent ranges over intervals of time.)
|
|
$(LI Types to represent time zones (used by $(D SysTime)).)
|
|
$(LI A platform-independent, high precision stopwatch type:
|
|
$(D 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
|
|
$(CXREF time, Duration), $(CXREF time, TickDuration), and
|
|
$(CXREF time, FracSec). So, you may want to look at its documentation as
|
|
well. However, core.time is publically imported into std.datetime, so you
|
|
don't have 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. So, 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
|
|
$(D Date) (if they want dates but don't care about time), $(D DateTime)
|
|
(if they want dates and times but don't care about time zones), $(D 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).
|
|
$(D Date) and $(D DateTime) are optimized for calendar-based operations,
|
|
while $(D SysTime) is designed for dealing with time from the OS. Check out
|
|
their specific documentation for more details.
|
|
|
|
To get the current time, use $(D Clock.currTime). It will return the current
|
|
time as a $(D SysTime). If you want to print it, $(D toString) is
|
|
sufficient, but if you use $(D toISOString), $(D toISOExtString), or
|
|
$(D toSimpleString), you can use the corresponding $(D fromISOString),
|
|
$(D fromISOExtString), or $(D fromISOExtString) to create a
|
|
$(D 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"). If
|
|
you need help remembering which units are abbreviated and which aren't,
|
|
notice that 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).
|
|
|
|
If you're looking for the definitions of $(D Duration), $(D TickDuration),
|
|
or $(D FracSec), they're in core.time.
|
|
|
|
Note:
|
|
$(D DateTimeException) is an alias for core.time's $(D TimeException),
|
|
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 $(D TimeException) or
|
|
$(D DateTimeException)).
|
|
|
|
See_Also:
|
|
$(WEB en.wikipedia.org/wiki/ISO_8601, ISO 8601)
|
|
$(WEB en.wikipedia.org/wiki/Tz_database, Wikipedia entry on TZ Database)
|
|
$(WEB en.wikipedia.org/wiki/List_of_tz_database_time_zones,
|
|
List of Time Zones)
|
|
|
|
Copyright: Copyright 2010 - 2011
|
|
License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
|
|
Authors: Jonathan M Davis and Kato Shoichi
|
|
Source: $(PHOBOSSRC std/_datetime.d)
|
|
+/
|
|
module std.datetime;
|
|
|
|
public import core.time;
|
|
|
|
import core.exception;
|
|
import core.stdc.time;
|
|
|
|
import std.array;
|
|
import std.algorithm;
|
|
import std.ascii;
|
|
import std.conv;
|
|
import std.exception;
|
|
import std.file;
|
|
import std.functional;
|
|
import std.math;
|
|
import std.metastrings;
|
|
import std.path;
|
|
import std.range;
|
|
import std.stdio;
|
|
import std.string;
|
|
import std.system;
|
|
import std.traits;
|
|
|
|
version(Windows)
|
|
{
|
|
import core.sys.windows.windows;
|
|
import std.c.windows.winsock;
|
|
|
|
//For system call to access the registry.
|
|
pragma(lib, "advapi32.lib");
|
|
}
|
|
else version(Posix)
|
|
{
|
|
import core.sys.posix.arpa.inet;
|
|
import core.sys.posix.stdlib;
|
|
import core.sys.posix.time;
|
|
import core.sys.posix.sys.time;
|
|
|
|
//We need to disable many tests because building all of Phobos
|
|
//with all of std.datetime's unit tests enables currently causes
|
|
//dmd to run out of memory.
|
|
//Regardless of that, however, it's also useful to be able to
|
|
//easily turn the tests on and off.
|
|
version = testStdDateTime;
|
|
}
|
|
|
|
version(unittest)
|
|
{
|
|
import std.c.string;
|
|
import std.stdio;
|
|
}
|
|
|
|
//I'd just alias it to indexOf, but
|
|
//http://d.puremagic.com/issues/show_bug.cgi?id=6013 would mean that that would
|
|
//pollute the global namespace. So, for now, I've created an alias which is
|
|
//highly unlikely to conflict with anything that anyone else is doing.
|
|
private alias std.string.indexOf stds_indexOf;
|
|
|
|
//Verify module example.
|
|
version(testStdDateTime) 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.
|
|
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));
|
|
}
|
|
|
|
//Note: There various functions which void as their return type and ref of the
|
|
// struct type which they're in as a commented out return type. Ideally,
|
|
// they would return the ref, but there are several dmd bugs which prevent
|
|
// that, relating to both ref and invariants. So, I've left the ref return
|
|
// types commented out with the idea that those functions can be made to
|
|
// return a ref to this once those bugs have been fixed.
|
|
|
|
//==============================================================================
|
|
// Section with public enums and constants.
|
|
//==============================================================================
|
|
|
|
/++
|
|
Represents the 12 months of the Gregorian year (January is 1).
|
|
+/
|
|
enum Month : ubyte { jan = 1, ///
|
|
feb, ///
|
|
mar, ///
|
|
apr, ///
|
|
may, ///
|
|
jun, ///
|
|
jul, ///
|
|
aug, ///
|
|
sep, ///
|
|
oct, ///
|
|
nov, ///
|
|
dec ///
|
|
}
|
|
|
|
/++
|
|
Represents the 7 days of the Gregorian week (Sunday is 0).
|
|
+/
|
|
enum DayOfWeek : ubyte { sun = 0, ///
|
|
mon, ///
|
|
tue, ///
|
|
wed, ///
|
|
thu, ///
|
|
fri, ///
|
|
sat ///
|
|
}
|
|
|
|
/++
|
|
In some date calculations, adding months or years can cause the date to fall
|
|
on a day of the month which is not valid (e.g. February 29th 2001 or
|
|
June 31st 2000). If overflow is allowed (as is the default), then the month
|
|
will be incremented accordingly (so, February 29th 2001 would become
|
|
March 1st 2001, and June 31st 2000 would become July 1st 2000). If overflow
|
|
is not allowed, then the day will be adjusted to the last valid day in that
|
|
month (so, February 29th 2001 would become February 28th 2001 and
|
|
June 31st 2000 would become June 30th 2000).
|
|
|
|
AllowDayOverflow only applies to calculations involving months or years.
|
|
+/
|
|
enum AllowDayOverflow
|
|
{
|
|
/// No, don't allow day overflow.
|
|
no,
|
|
|
|
/// Yes, allow day overflow.
|
|
yes
|
|
}
|
|
|
|
/++
|
|
Indicates a direction in time. One example of its use is $(D Interval)'s
|
|
$(D expand) function which uses it to indicate whether the interval should
|
|
be expanded backwards (into the past), forwards (into the future), or both.
|
|
+/
|
|
enum Direction
|
|
{
|
|
/// Backward.
|
|
bwd,
|
|
|
|
/// Forward.
|
|
fwd,
|
|
|
|
/// Both backward and forward.
|
|
both
|
|
}
|
|
|
|
/++
|
|
Used to indicate whether $(D popFront) should be called immediately upon
|
|
creating a range. The idea is that for some functions used to generate a
|
|
range for an interval, $(D front) is not necessarily a time point which
|
|
would ever be generated by the range, and if you want the first time point
|
|
in the range to match what the function generates, then you use
|
|
$(D PopFirst.yes) to indicate that the range should have $(D popFront)
|
|
called on it before the range is returned so that $(D front) is a time point
|
|
which the function would generate.
|
|
|
|
For instance, if the function used to generate a range of time points
|
|
generated successive Easters (i.e. you're iterating over all of the Easters
|
|
within the interval), the initial date probably isn't an Easter. By using
|
|
$(D PopFirst.yes), you would be telling the function which returned the
|
|
range that you wanted $(D popFront) to be called so that front would then be
|
|
an Easter - the next one generated by the function (which if you were
|
|
iterating forward, would be the Easter following the original $(D front),
|
|
while if you were iterating backward, it would be the Easter prior to the
|
|
original $(D front)). If $(D PopFirst.no) were used, then $(D front) would
|
|
remain the original time point and it would not necessarily be a time point
|
|
which would be generated by the range-generating function (which in many
|
|
cases is exactly what you
|
|
want - e.g. if you were iterating over every day starting at the beginning
|
|
of the interval).
|
|
+/
|
|
enum PopFirst
|
|
{
|
|
/// No, don't call popFront() before returning the range.
|
|
no,
|
|
|
|
/// Yes, call popFront() before returning the range.
|
|
yes
|
|
}
|
|
|
|
/++
|
|
Used by StopWatch to indicate whether it should start immediately upon
|
|
construction.
|
|
+/
|
|
enum AutoStart
|
|
{
|
|
/// No, don't start the StopWatch when it is constructed.
|
|
no,
|
|
|
|
/// Yes, do start the StopWatch when it is constructed.
|
|
yes
|
|
}
|
|
|
|
/++
|
|
Array of the strings representing time units, starting with the smallest
|
|
unit and going to the largest. It does not include $(D "nsecs").
|
|
|
|
Includes $(D "hnsecs") (hecto-nanoseconds (100 ns)),
|
|
$(D "usecs") (microseconds), $(D "msecs") (milliseconds), $(D "seconds"),
|
|
$(D "minutes"), $(D "hours"), $(D "days"), $(D "weeks"), $(D "months"), and
|
|
$(D "years")
|
|
+/
|
|
immutable string[] timeStrings = ["hnsecs", "usecs", "msecs", "seconds", "minutes",
|
|
"hours", "days", "weeks", "months", "years"];
|
|
|
|
//==============================================================================
|
|
// Section with other types.
|
|
//==============================================================================
|
|
|
|
/++
|
|
Exception type used by std.datetime. It's an alias to TimeException, which
|
|
is what core.time uses. So, you can catch either and not worry about which
|
|
module it came from.
|
|
+/
|
|
alias TimeException DateTimeException;
|
|
|
|
/++
|
|
Effectively a namespace to make it clear that the methods it contains are
|
|
getting the time from the system clock. It cannot be instantiated.
|
|
+/
|
|
final class Clock
|
|
{
|
|
public:
|
|
|
|
/++
|
|
Returns the current time in the given time zone.
|
|
|
|
Throws:
|
|
$(D ErrnoException) (on Posix) or $(D Exception) (on Windows)
|
|
if it fails to get the time of day.
|
|
+/
|
|
static SysTime currTime(immutable TimeZone tz = LocalTime())
|
|
{
|
|
return SysTime(currStdTime, tz);
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
assert(currTime(UTC()).timezone is UTC());
|
|
|
|
//I have no idea why, but for some reason, Windows/Wine likes to get
|
|
//time_t wrong when getting it with core.stdc.time.time. On one box
|
|
//I have (which has its local time set to UTC), it always gives time_t
|
|
//in the real local time (America/Los_Angeles), and after the most recent
|
|
//DST switch, every Windows box that I've tried it in is reporting
|
|
//time_t as being 1 hour off of where it's supposed to be. So, I really
|
|
//don't know what the deal is, but given what I'm seeing, I don't trust
|
|
//core.stdc.time.time on Windows, so I'm just going to disable this test
|
|
//on Windows.
|
|
version(Posix)
|
|
{
|
|
immutable unixTimeD = currTime().toUnixTime();
|
|
immutable unixTimeC = core.stdc.time.time(null);
|
|
immutable diff = unixTimeC - unixTimeD;
|
|
|
|
_assertPred!">="(diff, -2);
|
|
_assertPred!"<="(diff, 2);
|
|
}
|
|
}
|
|
|
|
/++
|
|
Returns the number of hnsecs since midnight, January 1st, 1 A.D. for the
|
|
current time.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if it fails to get the time.
|
|
+/
|
|
@trusted
|
|
static @property long currStdTime()
|
|
{
|
|
version(Windows)
|
|
{
|
|
//FILETIME represents hnsecs from midnight, January 1st, 1601.
|
|
enum hnsecsFrom1601 = 504_911_232_000_000_000L;
|
|
|
|
FILETIME fileTime;
|
|
|
|
GetSystemTimeAsFileTime(&fileTime);
|
|
|
|
ulong tempHNSecs = fileTime.dwHighDateTime;
|
|
tempHNSecs <<= 32;
|
|
tempHNSecs |= fileTime.dwLowDateTime;
|
|
|
|
return cast(long)tempHNSecs + hnsecsFrom1601;
|
|
}
|
|
else version(Posix)
|
|
{
|
|
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
|
|
{
|
|
timeval tv;
|
|
|
|
if(gettimeofday(&tv, null) != 0)
|
|
throw new TimeException("Failed in gettimeofday().");
|
|
|
|
return convert!("seconds", "hnsecs")(tv.tv_sec) +
|
|
convert!("usecs", "hnsecs")(tv.tv_usec) +
|
|
hnsecsToUnixEpoch;
|
|
}
|
|
}
|
|
}
|
|
|
|
/++
|
|
The current system tick. The number of ticks per second varies from
|
|
system to system. currSystemTick uses a monotonic clock, so it's
|
|
intended for precision timing by comparing relative time values, not
|
|
for getting the current system time.
|
|
|
|
Warning:
|
|
On some systems, the monotonic clock may stop counting when
|
|
the computer goes to sleep or hibernates. So, the monotonic
|
|
clock could be off if that occurs. This is known to happen
|
|
on Mac OS X. It has not been tested whether it occurs on
|
|
either Windows or Linux.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if it fails to get the time.
|
|
+/
|
|
@safe
|
|
static @property TickDuration currSystemTick()
|
|
{
|
|
return TickDuration.currSystemTick();
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
assert(Clock.currSystemTick.length > 0);
|
|
}
|
|
|
|
/++
|
|
The current number of system ticks since the application started.
|
|
The number of ticks per second varies from system to system.
|
|
This uses a monotonic clock.
|
|
|
|
Warning:
|
|
On some systems, the monotonic clock may stop counting when
|
|
the computer goes to sleep or hibernates. So, the monotonic
|
|
clock could be off if that occurs. This is known to happen
|
|
on Mac OS X. It has not been tested whether it occurs on
|
|
either Windows or on Linux.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if it fails to get the time.
|
|
+/
|
|
@safe
|
|
static @property TickDuration currAppTick()
|
|
{
|
|
return currSystemTick - TickDuration.appOrigin;
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
auto a = Clock.currSystemTick;
|
|
auto b = Clock.currAppTick;
|
|
assert(a.length);
|
|
assert(b.length);
|
|
assert(a > b);
|
|
}
|
|
|
|
private:
|
|
|
|
@disable this() {}
|
|
}
|
|
|
|
//==============================================================================
|
|
// Section with time points.
|
|
//==============================================================================
|
|
|
|
/++
|
|
$(D SysTime) is the type used when you want to get the current time from the
|
|
system or if you're doing anything that involves time zones. Unlike
|
|
$(D DateTime), the time zone is an integral part of $(D SysTime) (though if
|
|
all you care about is local time, you can pretty much ignore time zones, and
|
|
it will work, since it defaults to using the local time zone). It holds its
|
|
internal time in std time (hnsecs since midnight, January 1st, 1 A.D. UTC),
|
|
so it interfaces well with the system time. However, that means that, unlike
|
|
$(D DateTime), it is not optimized for calendar-based operations, and
|
|
getting individual units from it such as years or days is going to involve
|
|
conversions and be less efficient.
|
|
|
|
Basically, if you care about calendar-based operations and don't
|
|
necessarily care about time zones, then $(D DateTime) would be the type to
|
|
use. However, if what you care about is the system time, then $(D SysTime)
|
|
would be the type to use.
|
|
|
|
$(D Clock.currTime) will return the current time as a $(D SysTime). If you
|
|
want to convert a $(D SysTime) to a $(D Date) or $(D DateTime), simply cast
|
|
it. And if you ever want to convert a $(D Date) or $(D DateTime) to a
|
|
$(D SysTime), use $(D SysTime)'s constructor, and you can pass in the
|
|
intended time zone with it (or don't pass in a $(D TimeZone), and the local
|
|
time zone will be used). Be aware, however, that converting from a
|
|
$(D DateTime) to a $(D SysTime) will not necessarily be 100% accurate due to
|
|
DST (one hour of the year doesn't exist and another occurs twice). So, if
|
|
you don't want to risk any conversion errors, keep your times as
|
|
$(D SysTime)s. Aside from DST though, there shouldn't be any conversion
|
|
problems.
|
|
|
|
If you care about using time zones other than local time or UTC, you can use
|
|
$(D PosixTimeZone) on Posix systems (or on Windows, if you provide the TZ
|
|
Database files), and you can use $(D WindowsTimeZone) on Windows systems.
|
|
The time in $(D SysTime) is kept internally in hnsecs from midnight,
|
|
January 1st, 1 A.D. UTC. So, you never get conversion errors when changing
|
|
the time zone of a $(D SysTime). $(D LocalTime) is the $(D TimeZone) class
|
|
which represents the local time, and $(D UTC) is the $(D TimeZone) class
|
|
which represents UTC. $(D SysTime) uses $(D LocalTime) if no $(D TimeZone)
|
|
is provided. For more details on time zones, look at the documentation for
|
|
$(D TimeZone), $(D PosixTimeZone), and $(D WindowsTimeZone).
|
|
|
|
$(D SysTime)'s range is from approximately 29,000 B.C. to approximately
|
|
29,000 A.D.
|
|
+/
|
|
struct SysTime
|
|
{
|
|
public:
|
|
|
|
/++
|
|
Params:
|
|
dateTime = The $(D DateTime) to use to set this $(D SysTime)'s
|
|
internal std time. As $(D DateTime) has no concept of
|
|
time zone, tz is used as its time zone.
|
|
tz = The $(D TimeZone) to use for this $(D SysTime). If null,
|
|
$(D LocalTime) will be used. The given $(D DateTime) is
|
|
assumed to be in the given time zone.
|
|
+/
|
|
this(in DateTime dateTime, immutable TimeZone tz = null) nothrow
|
|
{
|
|
try
|
|
this(dateTime, FracSec.from!"hnsecs"(0), tz);
|
|
catch(Exception e)
|
|
assert(0, "FracSec's constructor threw when it shouldn't have.");
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
static void test(DateTime dt, immutable TimeZone tz, long expected)
|
|
{
|
|
auto sysTime = SysTime(dt, tz);
|
|
_assertPred!"=="(sysTime._stdTime, expected);
|
|
assert(sysTime._timezone is (tz is null ? LocalTime() : tz),
|
|
format("Given DateTime: %s", dt));
|
|
}
|
|
|
|
test(DateTime.init, UTC(), 0);
|
|
test(DateTime(1, 1, 1, 12, 30, 33), UTC(), 450_330_000_000L);
|
|
test(DateTime(0, 12, 31, 12, 30, 33), UTC(), -413_670_000_000L);
|
|
test(DateTime(1, 1, 1, 0, 0, 0), UTC(), 0);
|
|
test(DateTime(1, 1, 1, 0, 0, 1), UTC(), 10_000_000L);
|
|
test(DateTime(0, 12, 31, 23, 59, 59), UTC(), -10_000_000L);
|
|
|
|
test(DateTime(1, 1, 1, 0, 0, 0), new SimpleTimeZone(-60),
|
|
36_000_000_000L);
|
|
test(DateTime(1, 1, 1, 0, 0, 0), new SimpleTimeZone(0), 0);
|
|
test(DateTime(1, 1, 1, 0, 0, 0), new SimpleTimeZone(60),
|
|
-36_000_000_000L);
|
|
}
|
|
|
|
/++
|
|
Params:
|
|
dateTime = The $(D DateTime) to use to set this $(D SysTime)'s
|
|
internal std time. As $(D DateTime) has no concept of
|
|
time zone, tz is used as its time zone.
|
|
fracSec = The fractional seconds portion of the time.
|
|
tz = The $(D TimeZone) to use for this $(D SysTime). If null,
|
|
$(D LocalTime) will be used. The given $(D DateTime) is
|
|
assumed to be in the given time zone.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if $(D fracSec) is negative.
|
|
+/
|
|
this(in DateTime dateTime, in FracSec fracSec, immutable TimeZone tz = null)
|
|
{
|
|
immutable fracHNSecs = fracSec.hnsecs;
|
|
enforce(fracHNSecs >= 0, new DateTimeException("A SysTime cannot have negative fractional seconds."));
|
|
_timezone = tz is null ? LocalTime() : tz;
|
|
|
|
try
|
|
{
|
|
immutable dateDiff = (dateTime.date - Date(1, 1, 1)).total!"hnsecs";
|
|
immutable todDiff = (dateTime.timeOfDay - TimeOfDay(0, 0, 0)).total!"hnsecs";
|
|
|
|
immutable adjustedTime = dateDiff + todDiff + fracHNSecs;
|
|
immutable standardTime = _timezone.tzToUTC(adjustedTime);
|
|
|
|
this(standardTime, _timezone.get);
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
assert(0, "Date, TimeOfDay, or DateTime's constructor threw when " ~
|
|
"it shouldn't have.");
|
|
}
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
static void test(DateTime dt,
|
|
FracSec fracSec,
|
|
immutable TimeZone tz,
|
|
long expected)
|
|
{
|
|
auto sysTime = SysTime(dt, fracSec, tz);
|
|
_assertPred!"=="(sysTime._stdTime, expected);
|
|
assert(sysTime._timezone is (tz is null ? LocalTime() : tz),
|
|
format("Given DateTime: %s, Given FracSec: %s", dt, fracSec));
|
|
}
|
|
|
|
test(DateTime.init, FracSec.init, UTC(), 0);
|
|
test(DateTime(1, 1, 1, 12, 30, 33), FracSec.init, UTC(), 450_330_000_000L);
|
|
test(DateTime(0, 12, 31, 12, 30, 33), FracSec.init, UTC(), -413_670_000_000L);
|
|
test(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"msecs"(1), UTC(), 10_000L);
|
|
test(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"msecs"(999), UTC(), -10_000L);
|
|
|
|
test(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999), UTC(), -1);
|
|
test(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(1), UTC(), -9_999_999);
|
|
test(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(0), UTC(), -10_000_000);
|
|
|
|
assertThrown!DateTimeException(SysTime(DateTime.init, FracSec.from!"hnsecs"(-1), UTC()));
|
|
}
|
|
|
|
/++
|
|
Params:
|
|
date = The $(D Date) to use to set this $(D SysTime)'s internal std
|
|
time. As $(D Date) has no concept of time zone, tz is used as
|
|
its time zone.
|
|
tz = The $(D TimeZone) to use for this $(D SysTime). If null,
|
|
$(D LocalTime) will be used. The given $(D Date) is assumed
|
|
to be in the given time zone.
|
|
+/
|
|
this(in Date date, immutable TimeZone tz = null) nothrow
|
|
{
|
|
_timezone = tz is null ? LocalTime() : tz;
|
|
|
|
try
|
|
{
|
|
immutable adjustedTime = (date - Date(1, 1, 1)).total!"hnsecs";
|
|
immutable standardTime = _timezone.tzToUTC(adjustedTime);
|
|
|
|
this(standardTime, _timezone.get);
|
|
}
|
|
catch(Exception e)
|
|
assert(0, "Date's constructor through when it shouldn't have.");
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
static void test(Date d, immutable TimeZone tz, long expected)
|
|
{
|
|
auto sysTime = SysTime(d, tz);
|
|
_assertPred!"=="(sysTime._stdTime, expected);
|
|
assert(sysTime._timezone is (tz is null ? LocalTime() : tz),
|
|
format("Given Date: %s", d));
|
|
}
|
|
|
|
test(Date.init, UTC(), 0);
|
|
test(Date(1, 1, 1), UTC(), 0);
|
|
test(Date(1, 1, 2), UTC(), 864000000000);
|
|
test(Date(0, 12, 31), UTC(), -864000000000);
|
|
}
|
|
|
|
/++
|
|
Note:
|
|
Whereas the other constructors take in the given date/time, assume
|
|
that it's in the given time zone, and convert it to hnsecs in UTC
|
|
since midnight, January 1st, 1 A.D. UTC - i.e. std time - this
|
|
constructor takes a std time, which is specifically already in UTC,
|
|
so no conversion takes place. Of course, the various getter
|
|
properties and functions will use the given time zone's conversion
|
|
function to convert the results to that time zone, but no conversion
|
|
of the arguments to this constructor takes place.
|
|
|
|
Params:
|
|
stdTime = The number of hnsecs since midnight, January 1st, 1 A.D. UTC.
|
|
tz = The $(D TimeZone) to use for this $(D SysTime). If null,
|
|
$(D LocalTime) will be used.
|
|
+/
|
|
this(long stdTime, immutable TimeZone tz = null) pure nothrow
|
|
{
|
|
_stdTime = stdTime;
|
|
_timezone = tz is null ? LocalTime() : tz;
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
static void test(long stdTime, immutable TimeZone tz)
|
|
{
|
|
auto sysTime = SysTime(stdTime, tz);
|
|
_assertPred!"=="(sysTime._stdTime, stdTime);
|
|
assert(sysTime._timezone is (tz is null ? LocalTime() : tz),
|
|
format("Given stdTime: %s", stdTime));
|
|
}
|
|
|
|
foreach(stdTime; [-1234567890L, -250, 0, 250, 1235657390L])
|
|
{
|
|
foreach(tz; testTZs)
|
|
test(stdTime, tz);
|
|
}
|
|
}
|
|
|
|
/++
|
|
Params:
|
|
rhs = The $(D SysTime) to assign to this one.
|
|
+/
|
|
ref SysTime opAssign(const ref SysTime rhs) pure nothrow
|
|
{
|
|
_stdTime = rhs._stdTime;
|
|
_timezone = rhs._timezone.get;
|
|
|
|
return this;
|
|
}
|
|
|
|
/++
|
|
Params:
|
|
rhs = The $(D SysTime) to assign to this one.
|
|
+/
|
|
ref SysTime opAssign(SysTime rhs) pure nothrow
|
|
{
|
|
_stdTime = rhs._stdTime;
|
|
_timezone = rhs._timezone.get;
|
|
|
|
return this;
|
|
}
|
|
|
|
/++
|
|
Checks for equality between this $(D SysTime) and the given
|
|
$(D SysTime).
|
|
|
|
Note that the time zone is ignored. Only the internal
|
|
std times (which are in UTC) are compared.
|
|
+/
|
|
bool opEquals(const ref SysTime rhs) const pure nothrow
|
|
{
|
|
return _stdTime == rhs._stdTime;
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
_assertPred!"=="(SysTime(DateTime.init, UTC()), SysTime(0, UTC()));
|
|
_assertPred!"=="(SysTime(DateTime.init, UTC()), SysTime(0));
|
|
_assertPred!"=="(SysTime(Date.init, UTC()), SysTime(0));
|
|
_assertPred!"=="(SysTime(0), SysTime(0));
|
|
|
|
static void test(DateTime dt,
|
|
immutable TimeZone tz1,
|
|
immutable TimeZone tz2)
|
|
{
|
|
auto st1 = SysTime(dt);
|
|
st1.timezone = tz1;
|
|
|
|
auto st2 = SysTime(dt);
|
|
st2.timezone = tz2;
|
|
|
|
_assertPred!"=="(st1, st2);
|
|
}
|
|
|
|
foreach(tz1; testTZs)
|
|
{
|
|
foreach(tz2; testTZs)
|
|
{
|
|
foreach(dt; chain(testDateTimesBC, testDateTimesAD))
|
|
test(dt, tz1, tz2);
|
|
}
|
|
}
|
|
|
|
auto st = SysTime(DateTime(1999, 7, 6, 12, 33, 30));
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 33, 30));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 33, 30));
|
|
static assert(__traits(compiles, st == st));
|
|
static assert(__traits(compiles, st == cst));
|
|
//static assert(__traits(compiles, st == ist));
|
|
static assert(__traits(compiles, cst == st));
|
|
static assert(__traits(compiles, cst == cst));
|
|
//static assert(__traits(compiles, cst == ist));
|
|
//static assert(__traits(compiles, ist == st));
|
|
//static assert(__traits(compiles, ist == cst));
|
|
//static assert(__traits(compiles, ist == ist));
|
|
}
|
|
|
|
/++
|
|
Compares this $(D SysTime) with the given $(D SysTime).
|
|
|
|
Time zone is irrelevant when comparing $(D SysTime)s.
|
|
|
|
Returns:
|
|
$(BOOKTABLE,
|
|
$(TR $(TD this < rhs) $(TD < 0))
|
|
$(TR $(TD this == rhs) $(TD 0))
|
|
$(TR $(TD this > rhs) $(TD > 0))
|
|
)
|
|
+/
|
|
int opCmp(in SysTime rhs) const pure nothrow
|
|
{
|
|
if(_stdTime < rhs._stdTime)
|
|
return -1;
|
|
if(_stdTime > rhs._stdTime)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
_assertPred!("opCmp", "==")(SysTime(DateTime.init, UTC()),
|
|
SysTime(0, UTC()));
|
|
_assertPred!("opCmp", "==")(SysTime(DateTime.init, UTC()), SysTime(0));
|
|
_assertPred!("opCmp", "==")(SysTime(Date.init, UTC()), SysTime(0));
|
|
_assertPred!("opCmp", "==")(SysTime(0), SysTime(0));
|
|
|
|
static void testEqual(DateTime dt,
|
|
immutable TimeZone tz1,
|
|
immutable TimeZone tz2)
|
|
{
|
|
auto st1 = SysTime(dt);
|
|
st1.timezone = tz1;
|
|
|
|
auto st2 = SysTime(dt);
|
|
st2.timezone = tz2;
|
|
|
|
_assertPred!("opCmp", "==")(st1, st2);
|
|
}
|
|
|
|
foreach(dt; chain(testDateTimesBC, testDateTimesAD))
|
|
{
|
|
foreach(tz1; testTZs)
|
|
{
|
|
foreach(tz2; testTZs)
|
|
testEqual(dt, tz1, tz2);
|
|
}
|
|
}
|
|
|
|
static void testCmp(DateTime dt1,
|
|
immutable TimeZone tz1,
|
|
DateTime dt2,
|
|
immutable TimeZone tz2)
|
|
{
|
|
auto st1 = SysTime(dt1);
|
|
st1.timezone = tz1;
|
|
|
|
auto st2 = SysTime(dt2);
|
|
st2.timezone = tz2;
|
|
|
|
_assertPred!("opCmp", "<")(st1, st2);
|
|
_assertPred!("opCmp", ">")(st2, st1);
|
|
}
|
|
|
|
auto dts = testDateTimesBC ~ testDateTimesAD;
|
|
foreach(tz1; testTZs)
|
|
{
|
|
foreach(tz2; testTZs)
|
|
{
|
|
for(size_t i = 0; i < dts.length; ++i)
|
|
{
|
|
for(size_t j = i + 1; j < dts.length; ++j)
|
|
testCmp(dts[i], tz1, dts[j], tz2);
|
|
}
|
|
}
|
|
}
|
|
|
|
auto st = SysTime(DateTime(1999, 7, 6, 12, 33, 30));
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 33, 30));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 33, 30));
|
|
static assert(__traits(compiles, st.opCmp(st)));
|
|
static assert(__traits(compiles, st.opCmp(cst)));
|
|
//static assert(__traits(compiles, st.opCmp(ist)));
|
|
static assert(__traits(compiles, cst.opCmp(st)));
|
|
static assert(__traits(compiles, cst.opCmp(cst)));
|
|
//static assert(__traits(compiles, cst.opCmp(ist)));
|
|
//static assert(__traits(compiles, ist.opCmp(st)));
|
|
//static assert(__traits(compiles, ist.opCmp(cst)));
|
|
//static assert(__traits(compiles, ist.opCmp(ist)));
|
|
}
|
|
|
|
/++
|
|
Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive
|
|
are B.C.
|
|
+/
|
|
@property short year() const nothrow
|
|
{
|
|
return (cast(Date)this).year;
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
static void test(SysTime sysTime, long expected, size_t line = __LINE__)
|
|
{
|
|
_assertPred!"=="(sysTime.year, expected,
|
|
format("Value given: %s", sysTime), __FILE__, line);
|
|
}
|
|
|
|
test(SysTime(0, UTC()), 1);
|
|
test(SysTime(1, UTC()), 1);
|
|
test(SysTime(-1, UTC()), 0);
|
|
|
|
foreach(year; chain(testYearsBC, testYearsAD))
|
|
{
|
|
foreach(md; testMonthDays)
|
|
{
|
|
foreach(tod; testTODs)
|
|
{
|
|
auto dt = DateTime(Date(year, md.month, md.day), tod);
|
|
|
|
foreach(tz; testTZs)
|
|
{
|
|
foreach(fs; testFracSecs)
|
|
test(SysTime(dt, fs, tz), year);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, cst.year));
|
|
//static assert(__traits(compiles, ist.year));
|
|
}
|
|
|
|
/++
|
|
Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive
|
|
are B.C.
|
|
|
|
Params:
|
|
year = The year to set this $(D SysTime)'s year to.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the new year is not a leap year and the
|
|
resulting date would be on February 29th.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(SysTime(DateTime(1999, 7, 6, 9, 7, 5)).year == 1999);
|
|
assert(SysTime(DateTime(2010, 10, 4, 0, 0, 30)).year == 2010);
|
|
assert(SysTime(DateTime(-7, 4, 5, 7, 45, 2)).year == -7);
|
|
--------------------
|
|
+/
|
|
@property void year(int year)
|
|
{
|
|
auto hnsecs = adjTime;
|
|
auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
|
|
|
|
if(hnsecs < 0)
|
|
{
|
|
hnsecs += convert!("hours", "hnsecs")(24);
|
|
--days;
|
|
}
|
|
|
|
auto date = Date(cast(int)days);
|
|
date.year = year;
|
|
|
|
immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1);
|
|
|
|
adjTime = newDaysHNSecs + hnsecs;
|
|
}
|
|
|
|
//Verify Examples.
|
|
version(testStdDateTime) unittest
|
|
{
|
|
assert(SysTime(DateTime(1999, 7, 6, 9, 7, 5)).year == 1999);
|
|
assert(SysTime(DateTime(2010, 10, 4, 0, 0, 30)).year == 2010);
|
|
assert(SysTime(DateTime(-7, 4, 5, 7, 45, 2)).year == -7);
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
static void test(SysTime st, int year, in SysTime expected, size_t line = __LINE__)
|
|
{
|
|
st.year = year;
|
|
_assertPred!"=="(st, expected, "", __FILE__, line);
|
|
}
|
|
|
|
foreach(st; chain(testSysTimesBC, testSysTimesAD))
|
|
{
|
|
auto dt = cast(DateTime)st;
|
|
|
|
foreach(year; chain(testYearsBC, testYearsAD))
|
|
{
|
|
auto e = SysTime(DateTime(year, dt.month, dt.day, dt.hour, dt.minute, dt.second),
|
|
st.fracSec,
|
|
st.timezone);
|
|
test(st, year, e);
|
|
}
|
|
}
|
|
|
|
foreach(fs; testFracSecs)
|
|
{
|
|
foreach(tz; testTZs)
|
|
{
|
|
foreach(tod; testTODs)
|
|
{
|
|
test(SysTime(DateTime(Date(1999, 2, 28), tod), fs, tz), 2000,
|
|
SysTime(DateTime(Date(2000, 2, 28), tod), fs, tz));
|
|
test(SysTime(DateTime(Date(2000, 2, 28), tod), fs, tz), 1999,
|
|
SysTime(DateTime(Date(1999, 2, 28), tod), fs, tz));
|
|
}
|
|
|
|
foreach(tod; testTODsThrown)
|
|
{
|
|
auto st = SysTime(DateTime(Date(2000, 2, 29), tod), fs, tz);
|
|
assertThrown!DateTimeException(st.year = 1999);
|
|
}
|
|
}
|
|
}
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(!__traits(compiles, cst.year = 7));
|
|
//static assert(!__traits(compiles, ist.year = 7));
|
|
}
|
|
|
|
/++
|
|
Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if $(D isAD) is true.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(SysTime(DateTime(0, 1, 1, 12, 30, 33)).yearBC == 1);
|
|
assert(SysTime(DateTime(-1, 1, 1, 10, 7, 2)).yearBC == 2);
|
|
assert(SysTime(DateTime(-100, 1, 1, 4, 59, 0)).yearBC == 101);
|
|
--------------------
|
|
+/
|
|
@property ushort yearBC() const
|
|
{
|
|
return (cast(Date)this).yearBC;
|
|
}
|
|
|
|
//Verify Examples.
|
|
version(testStdDateTime) unittest
|
|
{
|
|
assert(SysTime(DateTime(0, 1, 1, 12, 30, 33)).yearBC == 1);
|
|
assert(SysTime(DateTime(-1, 1, 1, 10, 7, 2)).yearBC == 2);
|
|
assert(SysTime(DateTime(-100, 1, 1, 4, 59, 0)).yearBC == 101);
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
foreach(st; testSysTimesBC)
|
|
{
|
|
auto msg = format("SysTime: %s", st);
|
|
assertNotThrown!DateTimeException(st.yearBC, msg);
|
|
_assertPred!"=="(st.yearBC, (st.year * -1) + 1, msg);
|
|
}
|
|
|
|
foreach(st; [testSysTimesAD[0], testSysTimesAD[$/2], testSysTimesAD[$-1]])
|
|
assertThrown!DateTimeException(st.yearBC, format("SysTime: %s", st));
|
|
|
|
auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, st.year = 12));
|
|
static assert(!__traits(compiles, cst.year = 12));
|
|
//static assert(!__traits(compiles, ist.year = 12));
|
|
}
|
|
|
|
|
|
/++
|
|
Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C.
|
|
|
|
Params:
|
|
year = The year B.C. to set this $(D SysTime)'s year to.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if a non-positive value is given.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto st = SysTime(DateTime(2010, 1, 1, 7, 30, 0));
|
|
st.yearBC = 1;
|
|
assert(st == SysTime(DateTime(0, 1, 1, 7, 30, 0)));
|
|
|
|
st.yearBC = 10;
|
|
assert(st == SysTime(DateTime(-9, 1, 1, 7, 30, 0)));
|
|
--------------------
|
|
+/
|
|
@property void yearBC(int year)
|
|
{
|
|
auto hnsecs = adjTime;
|
|
auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
|
|
|
|
if(hnsecs < 0)
|
|
{
|
|
hnsecs += convert!("hours", "hnsecs")(24);
|
|
--days;
|
|
}
|
|
|
|
auto date = Date(cast(int)days);
|
|
date.yearBC = year;
|
|
|
|
immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1);
|
|
|
|
adjTime = newDaysHNSecs + hnsecs;
|
|
}
|
|
|
|
//Verify Examples
|
|
version(testStdDateTime) unittest
|
|
{
|
|
auto st = SysTime(DateTime(2010, 1, 1, 7, 30, 0));
|
|
st.yearBC = 1;
|
|
assert(st == SysTime(DateTime(0, 1, 1, 7, 30, 0)));
|
|
|
|
st.yearBC = 10;
|
|
assert(st == SysTime(DateTime(-9, 1, 1, 7, 30, 0)));
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
static void test(SysTime st, int year, in SysTime expected, size_t line = __LINE__)
|
|
{
|
|
st.yearBC = year;
|
|
_assertPred!"=="(st, expected, format("SysTime: %s", st), __FILE__, line);
|
|
}
|
|
|
|
foreach(st; chain(testSysTimesBC, testSysTimesAD))
|
|
{
|
|
auto dt = cast(DateTime)st;
|
|
|
|
foreach(year; testYearsBC)
|
|
{
|
|
auto e = SysTime(DateTime(year, dt.month, dt.day, dt.hour, dt.minute, dt.second),
|
|
st.fracSec,
|
|
st.timezone);
|
|
|
|
test(st, (year * -1) + 1, e);
|
|
}
|
|
}
|
|
|
|
foreach(st; [testSysTimesBC[0], testSysTimesBC[$ - 1],
|
|
testSysTimesAD[0], testSysTimesAD[$ - 1]])
|
|
{
|
|
foreach(year; testYearsBC)
|
|
assertThrown!DateTimeException(st.yearBC = year);
|
|
}
|
|
|
|
foreach(fs; testFracSecs)
|
|
{
|
|
foreach(tz; testTZs)
|
|
{
|
|
foreach(tod; testTODs)
|
|
{
|
|
test(SysTime(DateTime(Date(-1999, 2, 28), tod), fs, tz), 2001,
|
|
SysTime(DateTime(Date(-2000, 2, 28), tod), fs, tz));
|
|
test(SysTime(DateTime(Date(-2000, 2, 28), tod), fs, tz), 2000,
|
|
SysTime(DateTime(Date(-1999, 2, 28), tod), fs, tz));
|
|
}
|
|
|
|
foreach(tod; testTODsThrown)
|
|
{
|
|
auto st = SysTime(DateTime(Date(-2000, 2, 29), tod), fs, tz);
|
|
assertThrown!DateTimeException(st.year = -1999);
|
|
}
|
|
}
|
|
}
|
|
|
|
auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, st.yearBC = 12));
|
|
static assert(!__traits(compiles, cst.yearBC = 12));
|
|
//static assert(!__traits(compiles, ist.yearBC = 12));
|
|
}
|
|
|
|
/++
|
|
Month of a Gregorian Year.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(SysTime(DateTime(1999, 7, 6, 9, 7, 5)).month == 7);
|
|
assert(SysTime(DateTime(2010, 10, 4, 0, 0, 30)).month == 10);
|
|
assert(SysTime(DateTime(-7, 4, 5, 7, 45, 2)).month == 4);
|
|
--------------------
|
|
+/
|
|
@property Month month() const nothrow
|
|
{
|
|
return (cast(Date)this).month;
|
|
}
|
|
|
|
//Verify Examples.
|
|
version(testStdDateTime) unittest
|
|
{
|
|
assert(SysTime(DateTime(1999, 7, 6, 9, 7, 5)).month == 7);
|
|
assert(SysTime(DateTime(2010, 10, 4, 0, 0, 30)).month == 10);
|
|
assert(SysTime(DateTime(-7, 4, 5, 7, 45, 2)).month == 4);
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
static void test(SysTime sysTime, Month expected, size_t line = __LINE__)
|
|
{
|
|
_assertPred!"=="(sysTime.month, expected,
|
|
format("Value given: %s", sysTime), __FILE__, line);
|
|
}
|
|
|
|
test(SysTime(0, UTC()), Month.jan);
|
|
test(SysTime(1, UTC()), Month.jan);
|
|
test(SysTime(-1, UTC()), Month.dec);
|
|
|
|
foreach(year; chain(testYearsBC, testYearsAD))
|
|
{
|
|
foreach(md; testMonthDays)
|
|
{
|
|
foreach(tod; testTODs)
|
|
{
|
|
auto dt = DateTime(Date(year, md.month, md.day), tod);
|
|
|
|
foreach(fs; testFracSecs)
|
|
{
|
|
foreach(tz; testTZs)
|
|
test(SysTime(dt, fs, tz), md.month);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, cst.month));
|
|
//static assert(__traits(compiles, ist.month));
|
|
}
|
|
|
|
|
|
/++
|
|
Month of a Gregorian Year.
|
|
|
|
Params:
|
|
month = The month to set this $(D SysTime)'s month to.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given month is not a valid month.
|
|
+/
|
|
@property void month(Month month)
|
|
{
|
|
auto hnsecs = adjTime;
|
|
auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
|
|
|
|
if(hnsecs < 0)
|
|
{
|
|
hnsecs += convert!("hours", "hnsecs")(24);
|
|
--days;
|
|
}
|
|
|
|
auto date = Date(cast(int)days);
|
|
date.month = month;
|
|
|
|
immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1);
|
|
|
|
adjTime = newDaysHNSecs + hnsecs;
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
static void test(SysTime st, Month month, in SysTime expected, size_t line = __LINE__)
|
|
{
|
|
st.month = cast(Month)month;
|
|
_assertPred!"=="(st, expected, "", __FILE__, line);
|
|
}
|
|
|
|
foreach(st; chain(testSysTimesBC, testSysTimesAD))
|
|
{
|
|
auto dt = cast(DateTime)st;
|
|
|
|
foreach(md; testMonthDays)
|
|
{
|
|
if(st.day > maxDay(dt.year, md.month))
|
|
continue;
|
|
|
|
auto e = SysTime(DateTime(dt.year, md.month, dt.day, dt.hour, dt.minute, dt.second),
|
|
st.fracSec,
|
|
st.timezone);
|
|
|
|
test(st, md.month, e);
|
|
}
|
|
}
|
|
|
|
foreach(fs; testFracSecs)
|
|
{
|
|
foreach(tz; testTZs)
|
|
{
|
|
foreach(tod; testTODs)
|
|
{
|
|
foreach(year; filter!((a){return yearIsLeapYear(a);})
|
|
(chain(testYearsBC, testYearsAD)))
|
|
{
|
|
test(SysTime(DateTime(Date(year, 1, 29), tod), fs, tz),
|
|
Month.feb,
|
|
SysTime(DateTime(Date(year, 2, 29), tod), fs, tz));
|
|
}
|
|
|
|
foreach(year; chain(testYearsBC, testYearsAD))
|
|
{
|
|
test(SysTime(DateTime(Date(year, 1, 28), tod), fs, tz),
|
|
Month.feb,
|
|
SysTime(DateTime(Date(year, 2, 28), tod), fs, tz));
|
|
test(SysTime(DateTime(Date(year, 7, 30), tod), fs, tz),
|
|
Month.jun,
|
|
SysTime(DateTime(Date(year, 6, 30), tod), fs, tz));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach(fs; [testFracSecs[0], testFracSecs[$-1]])
|
|
{
|
|
foreach(tz; testTZs)
|
|
{
|
|
foreach(tod; testTODsThrown)
|
|
{
|
|
foreach(year; [testYearsBC[$-3], testYearsBC[$-2],
|
|
testYearsBC[$-2], testYearsAD[0],
|
|
testYearsAD[$-2], testYearsAD[$-1]])
|
|
{
|
|
auto day = yearIsLeapYear(year) ? 30 : 29;
|
|
auto st1 = SysTime(DateTime(Date(year, 1, day), tod), fs, tz);
|
|
assertThrown!DateTimeException(st1.month = Month.feb);
|
|
|
|
auto st2 = SysTime(DateTime(Date(year, 7, 31), tod), fs, tz);
|
|
assertThrown!DateTimeException(st2.month = Month.jun);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(!__traits(compiles, cst.month = 12));
|
|
//static assert(!__traits(compiles, ist.month = 12));
|
|
}
|
|
|
|
/++
|
|
Day of a Gregorian Month.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(SysTime(DateTime(1999, 7, 6, 9, 7, 5)).day == 6);
|
|
assert(SysTime(DateTime(2010, 10, 4, 0, 0, 30)).day == 4);
|
|
assert(SysTime(DateTime(-7, 4, 5, 7, 45, 2)).day == 5);
|
|
--------------------
|
|
+/
|
|
@property ubyte day() const nothrow
|
|
{
|
|
return (cast(Date)this).day;
|
|
}
|
|
|
|
//Verify Examples.
|
|
version(testStdDateTime) unittest
|
|
{
|
|
assert(SysTime(DateTime(1999, 7, 6, 9, 7, 5)).day == 6);
|
|
assert(SysTime(DateTime(2010, 10, 4, 0, 0, 30)).day == 4);
|
|
assert(SysTime(DateTime(-7, 4, 5, 7, 45, 2)).day == 5);
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
static void test(SysTime sysTime, int expected, size_t line = __LINE__)
|
|
{
|
|
_assertPred!"=="(sysTime.day, expected,
|
|
format("Value given: %s", sysTime), __FILE__, line);
|
|
}
|
|
|
|
test(SysTime(0, UTC()), 1);
|
|
test(SysTime(1, UTC()), 1);
|
|
test(SysTime(-1, UTC()), 31);
|
|
|
|
foreach(year; chain(testYearsBC, testYearsAD))
|
|
{
|
|
foreach(md; testMonthDays)
|
|
{
|
|
foreach(tod; testTODs)
|
|
{
|
|
auto dt = DateTime(Date(year, md.month, md.day), tod);
|
|
|
|
foreach(tz; testTZs)
|
|
{
|
|
foreach(fs; testFracSecs)
|
|
test(SysTime(dt, fs, tz), md.day);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, cst.day));
|
|
//static assert(__traits(compiles, ist.day));
|
|
}
|
|
|
|
|
|
/++
|
|
Day of a Gregorian Month.
|
|
|
|
Params:
|
|
day = The day of the month to set this $(D SysTime)'s day to.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given day is not a valid day of the
|
|
current month.
|
|
+/
|
|
@property void day(int day)
|
|
{
|
|
auto hnsecs = adjTime;
|
|
auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
|
|
|
|
if(hnsecs < 0)
|
|
{
|
|
hnsecs += convert!("hours", "hnsecs")(24);
|
|
--days;
|
|
}
|
|
|
|
auto date = Date(cast(int)days);
|
|
date.day = day;
|
|
|
|
immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1);
|
|
|
|
adjTime = newDaysHNSecs + hnsecs;
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
static void test(SysTime st, int day, in SysTime expected, size_t line = __LINE__)
|
|
{
|
|
st.day = day;
|
|
_assertPred!"=="(st, expected, "", __FILE__, line);
|
|
}
|
|
|
|
foreach(day; chain(testDays))
|
|
{
|
|
foreach(st; chain(testSysTimesBC, testSysTimesAD))
|
|
{
|
|
auto dt = cast(DateTime)st;
|
|
|
|
if(day > maxDay(dt.year, dt.month))
|
|
continue;
|
|
|
|
auto e = SysTime(DateTime(dt.year, dt.month, day, dt.hour, dt.minute, dt.second),
|
|
st.fracSec,
|
|
st.timezone);
|
|
|
|
test(st, day, e);
|
|
}
|
|
}
|
|
|
|
foreach(tz; testTZs)
|
|
{
|
|
foreach(tod; testTODs)
|
|
{
|
|
foreach(fs; testFracSecs)
|
|
{
|
|
foreach(year; chain(testYearsBC, testYearsAD))
|
|
{
|
|
foreach(month; EnumMembers!Month)
|
|
{
|
|
auto st = SysTime(DateTime(Date(year, month, 1), tod), fs, tz);
|
|
immutable max = maxDay(year, month);
|
|
|
|
test(st, max, SysTime(DateTime(Date(year, month, max), tod), fs, tz));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach(tz; testTZs)
|
|
{
|
|
foreach(tod; testTODsThrown)
|
|
{
|
|
foreach(fs; [testFracSecs[0], testFracSecs[$-1]])
|
|
{
|
|
foreach(year; [testYearsBC[$-3], testYearsBC[$-2],
|
|
testYearsBC[$-2], testYearsAD[0],
|
|
testYearsAD[$-2], testYearsAD[$-1]])
|
|
{
|
|
foreach(month; EnumMembers!Month)
|
|
{
|
|
auto st = SysTime(DateTime(Date(year, month, 1), tod), fs, tz);
|
|
immutable max = maxDay(year, month);
|
|
|
|
assertThrown!DateTimeException(st.day = max + 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(!__traits(compiles, cst.day = 27));
|
|
//static assert(!__traits(compiles, ist.day = 27));
|
|
}
|
|
|
|
|
|
/++
|
|
Hours past midnight.
|
|
+/
|
|
@property ubyte hour() const nothrow
|
|
{
|
|
auto hnsecs = adjTime;
|
|
auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
|
|
|
|
if(hnsecs < 0)
|
|
{
|
|
hnsecs += convert!("hours", "hnsecs")(24);
|
|
--days;
|
|
}
|
|
|
|
return cast(ubyte)getUnitsFromHNSecs!"hours"(hnsecs);
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
static void test(SysTime sysTime, int expected, size_t line = __LINE__)
|
|
{
|
|
_assertPred!"=="(sysTime.hour, expected,
|
|
format("Value given: %s", sysTime), __FILE__, line);
|
|
}
|
|
|
|
test(SysTime(0, UTC()), 0);
|
|
test(SysTime(1, UTC()), 0);
|
|
test(SysTime(-1, UTC()), 23);
|
|
|
|
foreach(tz; testTZs)
|
|
{
|
|
foreach(year; chain(testYearsBC, testYearsAD))
|
|
{
|
|
foreach(md; testMonthDays)
|
|
{
|
|
foreach(hour; testHours)
|
|
{
|
|
foreach(minute; testMinSecs)
|
|
{
|
|
foreach(second; testMinSecs)
|
|
{
|
|
auto dt = DateTime(Date(year, md.month, md.day),
|
|
TimeOfDay(hour, minute, second));
|
|
|
|
foreach(fs; testFracSecs)
|
|
test(SysTime(dt, fs, tz), hour);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, cst.hour));
|
|
//static assert(__traits(compiles, ist.hour));
|
|
}
|
|
|
|
|
|
/++
|
|
Hours past midnight.
|
|
|
|
Params:
|
|
hour = The hours to set this $(D SysTime)'s hour to.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given hour are not a valid hour of
|
|
the day.
|
|
+/
|
|
@property void hour(int hour)
|
|
{
|
|
enforceValid!"hours"(hour);
|
|
|
|
auto hnsecs = adjTime;
|
|
auto days = splitUnitsFromHNSecs!"days"(hnsecs);
|
|
immutable daysHNSecs = convert!("days", "hnsecs")(days);
|
|
immutable negative = hnsecs < 0;
|
|
|
|
if(negative)
|
|
hnsecs += convert!("hours", "hnsecs")(24);
|
|
|
|
hnsecs = removeUnitsFromHNSecs!"hours"(hnsecs);
|
|
hnsecs += convert!("hours", "hnsecs")(hour);
|
|
|
|
if(negative)
|
|
hnsecs -= convert!("hours", "hnsecs")(24);
|
|
|
|
adjTime = daysHNSecs + hnsecs;
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
static void test(SysTime st, int hour, in SysTime expected,
|
|
size_t line = __LINE__)
|
|
{
|
|
st.hour = hour;
|
|
_assertPred!"=="(st, expected, "", __FILE__, line);
|
|
}
|
|
|
|
foreach(hour; chain(testHours))
|
|
{
|
|
foreach(st; chain(testSysTimesBC, testSysTimesAD))
|
|
{
|
|
auto dt = cast(DateTime)st;
|
|
auto e = SysTime(DateTime(dt.year, dt.month, dt.day, hour, dt.minute, dt.second),
|
|
st.fracSec,
|
|
st.timezone);
|
|
|
|
test(st, hour, e);
|
|
}
|
|
}
|
|
|
|
auto st = testSysTimesAD[0];
|
|
assertThrown!DateTimeException(st.hour = -1);
|
|
assertThrown!DateTimeException(st.hour = 60);
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(!__traits(compiles, cst.hour = 27));
|
|
//static assert(!__traits(compiles, ist.hour = 27));
|
|
}
|
|
|
|
|
|
/++
|
|
Minutes past the current hour.
|
|
+/
|
|
@property ubyte minute() const nothrow
|
|
{
|
|
auto hnsecs = adjTime;
|
|
auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
|
|
|
|
if(hnsecs < 0)
|
|
{
|
|
hnsecs += convert!("hours", "hnsecs")(24);
|
|
--days;
|
|
}
|
|
|
|
hnsecs = removeUnitsFromHNSecs!"hours"(hnsecs);
|
|
|
|
return cast(ubyte)getUnitsFromHNSecs!"minutes"(hnsecs);
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
static void test(SysTime sysTime, int expected, size_t line = __LINE__)
|
|
{
|
|
_assertPred!"=="(sysTime.minute, expected,
|
|
format("Value given: %s", sysTime), __FILE__, line);
|
|
}
|
|
|
|
test(SysTime(0, UTC()), 0);
|
|
test(SysTime(1, UTC()), 0);
|
|
test(SysTime(-1, UTC()), 59);
|
|
|
|
foreach(tz; testTZs)
|
|
{
|
|
foreach(year; chain(testYearsBC, testYearsAD))
|
|
{
|
|
foreach(md; testMonthDays)
|
|
{
|
|
foreach(hour; testHours)
|
|
{
|
|
foreach(minute; testMinSecs)
|
|
{
|
|
foreach(second; testMinSecs)
|
|
{
|
|
auto dt = DateTime(Date(year, md.month, md.day),
|
|
TimeOfDay(hour, minute, second));
|
|
|
|
foreach(fs; testFracSecs)
|
|
test(SysTime(dt, fs, tz), minute);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, cst.minute));
|
|
//static assert(__traits(compiles, ist.minute));
|
|
}
|
|
|
|
|
|
/++
|
|
Minutes past the current hour.
|
|
|
|
Params:
|
|
minutes = The minute to set this $(D SysTime)'s minute to.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given minute are not a valid minute
|
|
of an hour.
|
|
+/
|
|
@property void minute(int minute)
|
|
{
|
|
enforceValid!"minutes"(minute);
|
|
|
|
auto hnsecs = adjTime;
|
|
auto days = splitUnitsFromHNSecs!"days"(hnsecs);
|
|
immutable daysHNSecs = convert!("days", "hnsecs")(days);
|
|
immutable negative = hnsecs < 0;
|
|
|
|
if(negative)
|
|
hnsecs += convert!("hours", "hnsecs")(24);
|
|
|
|
immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs);
|
|
hnsecs = removeUnitsFromHNSecs!"minutes"(hnsecs);
|
|
|
|
hnsecs += convert!("hours", "hnsecs")(hour);
|
|
hnsecs += convert!("minutes", "hnsecs")(minute);
|
|
|
|
if(negative)
|
|
hnsecs -= convert!("hours", "hnsecs")(24);
|
|
|
|
adjTime = daysHNSecs + hnsecs;
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
static void test(SysTime st, int minute, in SysTime expected, size_t line = __LINE__)
|
|
{
|
|
st.minute = minute;
|
|
_assertPred!"=="(st, expected, "", __FILE__, line);
|
|
}
|
|
|
|
foreach(minute; testMinSecs)
|
|
{
|
|
foreach(st; chain(testSysTimesBC, testSysTimesAD))
|
|
{
|
|
auto dt = cast(DateTime)st;
|
|
auto e = SysTime(DateTime(dt.year, dt.month, dt.day, dt.hour, minute, dt.second),
|
|
st.fracSec,
|
|
st.timezone);
|
|
|
|
test(st, minute, e);
|
|
}
|
|
}
|
|
|
|
auto st = testSysTimesAD[0];
|
|
assertThrown!DateTimeException(st.minute = -1);
|
|
assertThrown!DateTimeException(st.minute = 60);
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(!__traits(compiles, cst.minute = 27));
|
|
//static assert(!__traits(compiles, ist.minute = 27));
|
|
}
|
|
|
|
|
|
/++
|
|
Seconds past the current minute.
|
|
+/
|
|
@property ubyte second() const nothrow
|
|
{
|
|
auto hnsecs = adjTime;
|
|
auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
|
|
|
|
if(hnsecs < 0)
|
|
{
|
|
hnsecs += convert!("hours", "hnsecs")(24);
|
|
--days;
|
|
}
|
|
|
|
hnsecs = removeUnitsFromHNSecs!"hours"(hnsecs);
|
|
hnsecs = removeUnitsFromHNSecs!"minutes"(hnsecs);
|
|
|
|
return cast(ubyte)getUnitsFromHNSecs!"seconds"(hnsecs);
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
static void test(SysTime sysTime, int expected, size_t line = __LINE__)
|
|
{
|
|
_assertPred!"=="(sysTime.second, expected,
|
|
format("Value given: %s", sysTime), __FILE__, line);
|
|
}
|
|
|
|
test(SysTime(0, UTC()), 0);
|
|
test(SysTime(1, UTC()), 0);
|
|
test(SysTime(-1, UTC()), 59);
|
|
|
|
foreach(tz; testTZs)
|
|
{
|
|
foreach(year; chain(testYearsBC, testYearsAD))
|
|
{
|
|
foreach(md; testMonthDays)
|
|
{
|
|
foreach(hour; testHours)
|
|
{
|
|
foreach(minute; testMinSecs)
|
|
{
|
|
foreach(second; testMinSecs)
|
|
{
|
|
auto dt = DateTime(Date(year, md.month, md.day),
|
|
TimeOfDay(hour, minute, second));
|
|
|
|
foreach(fs; testFracSecs)
|
|
test(SysTime(dt, fs, tz), second);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, cst.second));
|
|
//static assert(__traits(compiles, ist.second));
|
|
}
|
|
|
|
|
|
/++
|
|
Seconds past the current minute.
|
|
|
|
Params:
|
|
second = The second to set this $(D SysTime)'s second to.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given second are not a valid second
|
|
of a minute.
|
|
+/
|
|
@property void second(int second)
|
|
{
|
|
enforceValid!"seconds"(second);
|
|
|
|
auto hnsecs = adjTime;
|
|
auto days = splitUnitsFromHNSecs!"days"(hnsecs);
|
|
immutable daysHNSecs = convert!("days", "hnsecs")(days);
|
|
immutable negative = hnsecs < 0;
|
|
|
|
if(negative)
|
|
hnsecs += convert!("hours", "hnsecs")(24);
|
|
|
|
immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs);
|
|
immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs);
|
|
hnsecs = removeUnitsFromHNSecs!"seconds"(hnsecs);
|
|
|
|
hnsecs += convert!("hours", "hnsecs")(hour);
|
|
hnsecs += convert!("minutes", "hnsecs")(minute);
|
|
hnsecs += convert!("seconds", "hnsecs")(second);
|
|
|
|
if(negative)
|
|
hnsecs -= convert!("hours", "hnsecs")(24);
|
|
|
|
adjTime = daysHNSecs + hnsecs;
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
static void test(SysTime st, int second, in SysTime expected,
|
|
size_t line = __LINE__)
|
|
{
|
|
st.second = second;
|
|
_assertPred!"=="(st, expected, "", __FILE__, line);
|
|
}
|
|
|
|
foreach(second; testMinSecs)
|
|
{
|
|
foreach(st; chain(testSysTimesBC, testSysTimesAD))
|
|
{
|
|
auto dt = cast(DateTime)st;
|
|
auto e = SysTime(DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, second),
|
|
st.fracSec,
|
|
st.timezone);
|
|
|
|
test(st, second, e);
|
|
}
|
|
}
|
|
|
|
auto st = testSysTimesAD[0];
|
|
assertThrown!DateTimeException(st.second = -1);
|
|
assertThrown!DateTimeException(st.second = 60);
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(!__traits(compiles, cst.seconds = 27));
|
|
//static assert(!__traits(compiles, ist.seconds = 27));
|
|
}
|
|
|
|
|
|
/++
|
|
Fractional seconds passed the second.
|
|
+/
|
|
@property FracSec fracSec() const nothrow
|
|
{
|
|
try
|
|
{
|
|
auto hnsecs = removeUnitsFromHNSecs!"days"(adjTime);
|
|
|
|
if(hnsecs < 0)
|
|
hnsecs += convert!("hours", "hnsecs")(24);
|
|
|
|
hnsecs = removeUnitsFromHNSecs!"seconds"(hnsecs);
|
|
|
|
return FracSec.from!"hnsecs"(cast(int)hnsecs);
|
|
}
|
|
catch(Exception e)
|
|
assert(0, "FracSec.from!\"hnsecs\"() threw.");
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
static void test(SysTime sysTime, FracSec expected, size_t line = __LINE__)
|
|
{
|
|
_assertPred!"=="(sysTime.fracSec, expected,
|
|
format("Value given: %s", sysTime), __FILE__, line);
|
|
}
|
|
|
|
test(SysTime(0, UTC()), FracSec.from!"hnsecs"(0));
|
|
test(SysTime(1, UTC()), FracSec.from!"hnsecs"(1));
|
|
test(SysTime(-1, UTC()), FracSec.from!"hnsecs"(9_999_999));
|
|
|
|
foreach(tz; testTZs)
|
|
{
|
|
foreach(year; chain(testYearsBC, testYearsAD))
|
|
{
|
|
foreach(md; testMonthDays)
|
|
{
|
|
foreach(hour; testHours)
|
|
{
|
|
foreach(minute; testMinSecs)
|
|
{
|
|
foreach(second; testMinSecs)
|
|
{
|
|
auto dt = DateTime(Date(year, md.month, md.day),
|
|
TimeOfDay(hour, minute, second));
|
|
|
|
foreach(fs; testFracSecs)
|
|
test(SysTime(dt, fs, tz), fs);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, cst.fracSec));
|
|
//static assert(__traits(compiles, ist.fracSec));
|
|
}
|
|
|
|
|
|
/++
|
|
Fractional seconds passed the second.
|
|
|
|
Params:
|
|
fracSec = The fractional seconds to set this $(D SysTimes)'s
|
|
fractional seconds to.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if $(D fracSec) is negative.
|
|
+/
|
|
@property void fracSec(FracSec fracSec)
|
|
{
|
|
immutable fracHNSecs = fracSec.hnsecs;
|
|
enforce(fracHNSecs >= 0, new DateTimeException("A SysTime cannot have negative fractional seconds."));
|
|
|
|
auto hnsecs = adjTime;
|
|
auto days = splitUnitsFromHNSecs!"days"(hnsecs);
|
|
immutable daysHNSecs = convert!("days", "hnsecs")(days);
|
|
immutable negative = hnsecs < 0;
|
|
|
|
if(negative)
|
|
hnsecs += convert!("hours", "hnsecs")(24);
|
|
|
|
immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs);
|
|
immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs);
|
|
immutable second = getUnitsFromHNSecs!"seconds"(hnsecs);
|
|
|
|
hnsecs = fracHNSecs;
|
|
hnsecs += convert!("hours", "hnsecs")(hour);
|
|
hnsecs += convert!("minutes", "hnsecs")(minute);
|
|
hnsecs += convert!("seconds", "hnsecs")(second);
|
|
|
|
if(negative)
|
|
hnsecs -= convert!("hours", "hnsecs")(24);
|
|
|
|
adjTime = daysHNSecs + hnsecs;
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
static void test(SysTime st, FracSec fracSec, in SysTime expected, size_t line = __LINE__)
|
|
{
|
|
st.fracSec = fracSec;
|
|
_assertPred!"=="(st, expected, "", __FILE__, line);
|
|
}
|
|
|
|
foreach(fracSec; testFracSecs)
|
|
{
|
|
foreach(st; chain(testSysTimesBC, testSysTimesAD))
|
|
{
|
|
auto dt = cast(DateTime)st;
|
|
auto e = SysTime(DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second),
|
|
fracSec,
|
|
st.timezone);
|
|
|
|
test(st, fracSec, e);
|
|
}
|
|
}
|
|
|
|
SysTime st = SysTime(DateTime(2011, 7, 11, 2, 51, 27));
|
|
assertThrown!DateTimeException(st.fracSec = FracSec.from!"hnsecs"(-1));
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(!__traits(compiles, cst.fracSec = FracSec.from!"msecs"(7)));
|
|
//static assert(!__traits(compiles, ist.fracSec = FracSec.from!"msecs"(7)));
|
|
}
|
|
|
|
|
|
/++
|
|
The total hnsecs from midnight, January 1st, 1 A.D. UTC. This is the
|
|
internal representation of $(D SysTime).
|
|
+/
|
|
@property long stdTime() const pure nothrow
|
|
{
|
|
return _stdTime;
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
_assertPred!"=="(SysTime(0).stdTime, 0);
|
|
_assertPred!"=="(SysTime(1).stdTime, 1);
|
|
_assertPred!"=="(SysTime(-1).stdTime, -1);
|
|
_assertPred!"=="(SysTime(DateTime(1, 1, 1, 0, 0, 33), FracSec.from!"hnsecs"(502), UTC()).stdTime,
|
|
330000502L);
|
|
_assertPred!"=="(SysTime(DateTime(1970, 1, 1, 0, 0, 0), UTC()).stdTime,
|
|
621355968000000000L);
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, cst.stdTime));
|
|
//static assert(__traits(compiles, ist.stdTime));
|
|
}
|
|
|
|
|
|
/++
|
|
The total hnsecs from midnight, January 1st, 1 A.D. UTC. This is the
|
|
internal representation of $(D SysTime).
|
|
|
|
Params:
|
|
stdTime = The number of hnsecs since January 1st, 1 A.D. UTC.
|
|
+/
|
|
@property void stdTime(long stdTime) pure nothrow
|
|
{
|
|
_stdTime = stdTime;
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
static void test(long stdTime, in SysTime expected, size_t line = __LINE__)
|
|
{
|
|
auto st = SysTime(0, UTC());
|
|
st.stdTime = stdTime;
|
|
_assertPred!"=="(st, expected);
|
|
}
|
|
|
|
test(0, SysTime(Date(1, 1, 1), UTC()));
|
|
test(1, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(1), UTC()));
|
|
test(-1, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999), UTC()));
|
|
test(330_000_502L, SysTime(DateTime(1, 1, 1, 0, 0, 33), FracSec.from!"hnsecs"(502), UTC()));
|
|
test(621_355_968_000_000_000L, SysTime(DateTime(1970, 1, 1, 0, 0, 0), UTC()));
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(!__traits(compiles, cst.stdTime = 27));
|
|
//static assert(!__traits(compiles, ist.stdTime = 27));
|
|
}
|
|
|
|
|
|
/++
|
|
The current time zone of this $(D SysTime). Its internal time is always
|
|
kept in UTC, so there are no conversion issues between time zones due to
|
|
DST. Functions which return all or part of the time - such as hours -
|
|
adjust the time to this $(D SysTime)'s time zone before returning.
|
|
+/
|
|
@property immutable(TimeZone) timezone() const pure nothrow
|
|
{
|
|
return _timezone.get;
|
|
}
|
|
|
|
|
|
/++
|
|
The current time zone of this $(D SysTime). It's internal time is always
|
|
kept in UTC, so there are no conversion issues between time zones due to
|
|
DST. Functions which return all or part of the time - such as hours -
|
|
adjust the time to this $(D SysTime)'s time zone before returning.
|
|
|
|
Params:
|
|
tz = The $(D TimeZone) to set this $(D SysTime)'s time zone to.
|
|
+/
|
|
@property void timezone(immutable TimeZone timezone) pure nothrow
|
|
{
|
|
if(timezone is null)
|
|
_timezone = LocalTime();
|
|
else
|
|
_timezone = timezone;
|
|
}
|
|
|
|
|
|
/++
|
|
Returns whether DST is in effect for this $(D SysTime).
|
|
+/
|
|
@property bool dstInEffect() const nothrow
|
|
{
|
|
return _timezone.dstInEffect(_stdTime);
|
|
//This function's unit testing is done in the time zone classes.
|
|
}
|
|
|
|
|
|
/++
|
|
Returns a $(D SysTime) with the same std time as this one, but with
|
|
$(D LocalTime) as its time zone.
|
|
+/
|
|
SysTime toLocalTime() const nothrow
|
|
{
|
|
return SysTime(_stdTime, LocalTime());
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
{
|
|
auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), FracSec.from!"hnsecs"(27));
|
|
_assertPred!"=="(sysTime, sysTime.toLocalTime());
|
|
_assertPred!"=="(sysTime._stdTime, sysTime.toLocalTime()._stdTime);
|
|
assert(sysTime.toLocalTime().timezone is LocalTime());
|
|
assert(sysTime.toLocalTime().timezone is sysTime.timezone);
|
|
assert(sysTime.toLocalTime().timezone !is UTC());
|
|
}
|
|
|
|
{
|
|
immutable stz = new SimpleTimeZone(-3 * 60);
|
|
auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), FracSec.from!"hnsecs"(27), stz);
|
|
_assertPred!"=="(sysTime, sysTime.toLocalTime());
|
|
_assertPred!"=="(sysTime._stdTime, sysTime.toLocalTime()._stdTime);
|
|
assert(sysTime.toLocalTime().timezone is LocalTime());
|
|
assert(sysTime.toLocalTime().timezone !is UTC());
|
|
assert(sysTime.toLocalTime().timezone !is stz);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns a $(D SysTime) with the same std time as this one, but with
|
|
$(D UTC) as its time zone.
|
|
+/
|
|
SysTime toUTC() const pure nothrow
|
|
{
|
|
return SysTime(_stdTime, UTC());
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), FracSec.from!"hnsecs"(27));
|
|
_assertPred!"=="(sysTime, sysTime.toUTC());
|
|
_assertPred!"=="(sysTime._stdTime, sysTime.toUTC()._stdTime);
|
|
assert(sysTime.toUTC().timezone is UTC());
|
|
assert(sysTime.toUTC().timezone !is LocalTime());
|
|
assert(sysTime.toUTC().timezone !is sysTime.timezone);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns a $(D SysTime) with the same std time as this one, but with
|
|
given time zone as its time zone.
|
|
+/
|
|
SysTime toOtherTZ(immutable TimeZone tz) const pure nothrow
|
|
{
|
|
if(tz is null)
|
|
return SysTime(_stdTime, LocalTime());
|
|
else
|
|
return SysTime(_stdTime, tz);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
immutable stz = new SimpleTimeZone(11 * 60);
|
|
auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), FracSec.from!"hnsecs"(27));
|
|
_assertPred!"=="(sysTime, sysTime.toOtherTZ(stz));
|
|
_assertPred!"=="(sysTime._stdTime, sysTime.toOtherTZ(stz)._stdTime);
|
|
assert(sysTime.toOtherTZ(stz).timezone is stz);
|
|
assert(sysTime.toOtherTZ(stz).timezone !is LocalTime());
|
|
assert(sysTime.toOtherTZ(stz).timezone !is UTC());
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns a $(D time_t) which represents the same time as this
|
|
$(D SysTime).
|
|
|
|
Note that like all conversions in std.datetime, this is a truncating
|
|
conversion.
|
|
|
|
If $(D time_t) is 32 bits, rather than 64, and the result can't fit in a
|
|
32-bit value, then the closest value that can be held in 32 bits will be
|
|
used (so $(D time_t.max) if it goes over and $(D time_t.min) if it goes
|
|
under).
|
|
+/
|
|
time_t toUnixTime() const pure nothrow
|
|
{
|
|
return stdTimeToUnixTime(_stdTime);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(SysTime(DateTime(1970, 1, 1), UTC()).toUnixTime, 0);
|
|
_assertPred!"=="(SysTime(DateTime(1970, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(1), UTC()).toUnixTime, 0);
|
|
_assertPred!"=="(SysTime(DateTime(1970, 1, 1, 0, 0, 0), FracSec.from!"usecs"(1), UTC()).toUnixTime, 0);
|
|
_assertPred!"=="(SysTime(DateTime(1970, 1, 1, 0, 0, 0), FracSec.from!"msecs"(1), UTC()).toUnixTime, 0);
|
|
_assertPred!"=="(SysTime(DateTime(1970, 1, 1, 0, 0, 1), UTC()).toUnixTime, 1);
|
|
_assertPred!"=="(SysTime(DateTime(1969, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999), UTC()).toUnixTime, 0);
|
|
_assertPred!"=="(SysTime(DateTime(1969, 12, 31, 23, 59, 59), FracSec.from!"usecs"(999_999), UTC()).toUnixTime, 0);
|
|
_assertPred!"=="(SysTime(DateTime(1969, 12, 31, 23, 59, 59), FracSec.from!"msecs"(999), UTC()).toUnixTime, 0);
|
|
_assertPred!"=="(SysTime(DateTime(1969, 12, 31, 23, 59, 59), UTC()).toUnixTime, -1);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns a $(D timeval) which represents this $(D SysTime).
|
|
|
|
Note that like all conversions in std.datetime, this is a truncating
|
|
conversion.
|
|
|
|
If $(D time_t) is 32 bits, rather than 64, and the result can't fit in a
|
|
32-bit value, then the closest value that can be held in 32 bits will be
|
|
used for $(D tv_sec). (so $(D time_t.max) if it goes over and
|
|
$(D time_t.min) if it goes under).
|
|
+/
|
|
timeval toTimeVal() const pure nothrow
|
|
{
|
|
immutable tv_sec = toUnixTime();
|
|
|
|
immutable fracHNSecs = removeUnitsFromHNSecs!"seconds"(_stdTime - 621355968000000000L);
|
|
immutable tv_usec = cast(int)convert!("hnsecs", "usecs")(fracHNSecs);
|
|
|
|
return timeval(tv_sec, tv_usec);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assert(SysTime(DateTime(1970, 1, 1), UTC()).toTimeVal() == timeval(0, 0));
|
|
assert(SysTime(DateTime(1970, 1, 1), FracSec.from!"hnsecs"(9), UTC()).toTimeVal() == timeval(0, 0));
|
|
assert(SysTime(DateTime(1970, 1, 1), FracSec.from!"hnsecs"(10), UTC()).toTimeVal() == timeval(0, 1));
|
|
assert(SysTime(DateTime(1970, 1, 1), FracSec.from!"usecs"(7), UTC()).toTimeVal() == timeval(0, 7));
|
|
|
|
assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), UTC()).toTimeVal() == timeval(1, 0));
|
|
assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), FracSec.from!"hnsecs"(9), UTC()).toTimeVal() == timeval(1, 0));
|
|
assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), FracSec.from!"hnsecs"(10), UTC()).toTimeVal() == timeval(1, 1));
|
|
assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), FracSec.from!"usecs"(7), UTC()).toTimeVal() == timeval(1, 7));
|
|
|
|
assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999), UTC()).toTimeVal() ==
|
|
timeval(0, 0));
|
|
assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_990), UTC()).toTimeVal() ==
|
|
timeval(0, -1));
|
|
|
|
assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), FracSec.from!"usecs"(999_999), UTC()).toTimeVal() ==
|
|
timeval(0, -1));
|
|
assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), FracSec.from!"usecs"(999), UTC()).toTimeVal() ==
|
|
timeval(0, -999_001));
|
|
assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), FracSec.from!"msecs"(999), UTC()).toTimeVal() ==
|
|
timeval(0, -1000));
|
|
assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), UTC()).toTimeVal() == timeval(-1, 0));
|
|
assert(SysTime(DateTime(1969, 12, 31, 23, 59, 58), FracSec.from!"usecs"(17), UTC()).toTimeVal() ==
|
|
timeval(-1, -999_983));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns a $(D tm) which represents this $(D SysTime).
|
|
+/
|
|
tm toTM() const nothrow
|
|
{
|
|
try
|
|
{
|
|
auto dateTime = cast(DateTime)this;
|
|
tm timeInfo;
|
|
|
|
timeInfo.tm_sec = dateTime.second;
|
|
timeInfo.tm_min = dateTime.minute;
|
|
timeInfo.tm_hour = dateTime.hour;
|
|
timeInfo.tm_mday = dateTime.day;
|
|
timeInfo.tm_mon = dateTime.month - 1;
|
|
timeInfo.tm_year = dateTime.year - 1900;
|
|
timeInfo.tm_wday = dateTime.dayOfWeek;
|
|
timeInfo.tm_yday = dateTime.dayOfYear - 1;
|
|
timeInfo.tm_isdst = _timezone.dstInEffect(_stdTime);
|
|
|
|
version(Posix)
|
|
{
|
|
char[] zone = (timeInfo.tm_isdst ? _timezone.dstName : _timezone.stdName).dup;
|
|
zone ~= "\0";
|
|
|
|
timeInfo.tm_gmtoff = cast(int)convert!("hnsecs", "seconds")(adjTime - _stdTime);
|
|
timeInfo.tm_zone = zone.ptr;
|
|
}
|
|
|
|
return timeInfo;
|
|
}
|
|
catch(Exception e)
|
|
assert(0, "Either DateTime's constructor threw.");
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
version(Posix)
|
|
{
|
|
scope(exit) clearTZEnvVar();
|
|
setTZEnvVar("America/Los_Angeles");
|
|
}
|
|
|
|
{
|
|
auto timeInfo = SysTime(DateTime(1970, 1, 1)).toTM();
|
|
|
|
_assertPred!"=="(timeInfo.tm_sec, 0);
|
|
_assertPred!"=="(timeInfo.tm_min, 0);
|
|
_assertPred!"=="(timeInfo.tm_hour, 0);
|
|
_assertPred!"=="(timeInfo.tm_mday, 1);
|
|
_assertPred!"=="(timeInfo.tm_mon, 0);
|
|
_assertPred!"=="(timeInfo.tm_year, 70);
|
|
_assertPred!"=="(timeInfo.tm_wday, 4);
|
|
_assertPred!"=="(timeInfo.tm_yday, 0);
|
|
|
|
version(Posix)
|
|
_assertPred!"=="(timeInfo.tm_isdst, 0);
|
|
else version(Windows)
|
|
assert(timeInfo.tm_isdst == 0 || timeInfo.tm_isdst == 1);
|
|
|
|
version(Posix)
|
|
{
|
|
_assertPred!"=="(timeInfo.tm_gmtoff, -8 * 60 * 60);
|
|
_assertPred!"=="(to!string(timeInfo.tm_zone), "PST");
|
|
}
|
|
}
|
|
|
|
{
|
|
auto timeInfo = SysTime(DateTime(2010, 7, 4, 12, 15, 7), FracSec.from!"hnsecs"(15)).toTM();
|
|
|
|
_assertPred!"=="(timeInfo.tm_sec, 7);
|
|
_assertPred!"=="(timeInfo.tm_min, 15);
|
|
_assertPred!"=="(timeInfo.tm_hour, 12);
|
|
_assertPred!"=="(timeInfo.tm_mday, 4);
|
|
_assertPred!"=="(timeInfo.tm_mon, 6);
|
|
_assertPred!"=="(timeInfo.tm_year, 110);
|
|
_assertPred!"=="(timeInfo.tm_wday, 0);
|
|
_assertPred!"=="(timeInfo.tm_yday, 184);
|
|
|
|
version(Posix)
|
|
_assertPred!"=="(timeInfo.tm_isdst, 1);
|
|
else version(Windows)
|
|
assert(timeInfo.tm_isdst == 0 || timeInfo.tm_isdst == 1);
|
|
|
|
version(Posix)
|
|
{
|
|
_assertPred!"=="(timeInfo.tm_gmtoff, -7 * 60 * 60);
|
|
_assertPred!"=="(to!string(timeInfo.tm_zone), "PDT");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Adds the given number of years or months to this $(D SysTime). A
|
|
negative number will subtract.
|
|
|
|
Note that if day overflow is allowed, and the date with the adjusted
|
|
year/month overflows the number of days in the new month, then the month
|
|
will be incremented by one, and the day set to the number of days
|
|
overflowed. (e.g. if the day were 31 and the new month were June, then
|
|
the month would be incremented to July, and the new day would be 1). If
|
|
day overflow is not allowed, then the day will be set to the last valid
|
|
day in the month (e.g. June 31st would become June 30th).
|
|
|
|
Params:
|
|
units = The type of units to add ("years" or "months").
|
|
value = The number of months or years to add to this
|
|
$(D SysTime).
|
|
allowOverflow = Whether the days should be allowed to overflow,
|
|
causing the month to increment.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto st1 = SysTime(DateTime(2010, 1, 1, 12, 30, 33));
|
|
st1.add!"months"(11);
|
|
assert(st1 == SysTime(DateTime(2010, 12, 1, 12, 30, 33)));
|
|
|
|
auto st2 = SysTime(DateTime(2010, 1, 1, 12, 30, 33));
|
|
st2.add!"months"(-11);
|
|
assert(st2 == SysTime(DateTime(2009, 2, 1, 12, 30, 33)));
|
|
|
|
auto st3 = SysTime(DateTime(2000, 2, 29, 12, 30, 33));
|
|
st3.add!"years"(1);
|
|
assert(st3 == SysTime(DateTime(2001, 3, 1, 12, 30, 33)));
|
|
|
|
auto st4 = SysTime(DateTime(2000, 2, 29, 12, 30, 33));
|
|
st4.add!"years"(1, AllowDayOverflow.no);
|
|
assert(st4 == SysTime(DateTime(2001, 2, 28, 12, 30, 33)));
|
|
--------------------
|
|
+/
|
|
ref SysTime add(string units)(long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) nothrow
|
|
if(units == "years" ||
|
|
units == "months")
|
|
{
|
|
auto hnsecs = adjTime;
|
|
auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
|
|
|
|
if(hnsecs < 0)
|
|
{
|
|
hnsecs += convert!("hours", "hnsecs")(24);
|
|
--days;
|
|
}
|
|
|
|
auto date = Date(cast(int)days);
|
|
date.add!units(value, allowOverflow);
|
|
days = date.dayOfGregorianCal - 1;
|
|
|
|
if(days < 0)
|
|
{
|
|
hnsecs -= convert!("hours", "hnsecs")(24);
|
|
++days;
|
|
}
|
|
|
|
immutable newDaysHNSecs = convert!("days", "hnsecs")(days);
|
|
|
|
adjTime = newDaysHNSecs + hnsecs;
|
|
|
|
return this;
|
|
}
|
|
|
|
//Verify Examples.
|
|
unittest
|
|
{
|
|
version (testStdDateTime)
|
|
{
|
|
auto st1 = SysTime(DateTime(2010, 1, 1, 12, 30, 33));
|
|
st1.add!"months"(11);
|
|
assert(st1 == SysTime(DateTime(2010, 12, 1, 12, 30, 33)));
|
|
|
|
auto st2 = SysTime(DateTime(2010, 1, 1, 12, 30, 33));
|
|
st2.add!"months"(-11);
|
|
assert(st2 == SysTime(DateTime(2009, 2, 1, 12, 30, 33)));
|
|
|
|
auto st3 = SysTime(DateTime(2000, 2, 29, 12, 30, 33));
|
|
st3.add!"years"(1);
|
|
assert(st3 == SysTime(DateTime(2001, 3, 1, 12, 30, 33)));
|
|
|
|
auto st4 = SysTime(DateTime(2000, 2, 29, 12, 30, 33));
|
|
st4.add!"years"(1, AllowDayOverflow.no);
|
|
assert(st4 == SysTime(DateTime(2001, 2, 28, 12, 30, 33)));
|
|
}
|
|
}
|
|
|
|
//Test add!"years"() with AllowDayOverlow.yes
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 7, 6));
|
|
sysTime.add!"years"(7);
|
|
_assertPred!"=="(sysTime, SysTime(Date(2006, 7, 6)));
|
|
sysTime.add!"years"(-9);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1997, 7, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 2, 28));
|
|
sysTime.add!"years"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(2000, 2, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(2000, 2, 29));
|
|
sysTime.add!"years"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 3, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 7, 3), FracSec.from!"msecs"(234));
|
|
sysTime.add!"years"(7);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(2006, 7, 6, 12, 7, 3), FracSec.from!"msecs"(234)));
|
|
sysTime.add!"years"(-9);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1997, 7, 6, 12, 7, 3), FracSec.from!"msecs"(234)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1999, 2, 28, 0, 7, 2), FracSec.from!"usecs"(1207));
|
|
sysTime.add!"years"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(2000, 2, 28, 0, 7, 2), FracSec.from!"usecs"(1207)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(2000, 2, 29, 0, 7, 2), FracSec.from!"usecs"(1207));
|
|
sysTime.add!"years"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1999, 3, 1, 0, 7, 2), FracSec.from!"usecs"(1207)));
|
|
}
|
|
|
|
//Test B.C.
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 7, 6));
|
|
sysTime.add!"years"(-7);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2006, 7, 6)));
|
|
sysTime.add!"years"(9);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1997, 7, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 2, 28));
|
|
sysTime.add!"years"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2000, 2, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-2000, 2, 29));
|
|
sysTime.add!"years"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 3, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 7, 3), FracSec.from!"msecs"(234));
|
|
sysTime.add!"years"(-7);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-2006, 7, 6, 12, 7, 3), FracSec.from!"msecs"(234)));
|
|
sysTime.add!"years"(9);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-1997, 7, 6, 12, 7, 3), FracSec.from!"msecs"(234)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-1999, 2, 28, 3, 3, 3), FracSec.from!"hnsecs"(3));
|
|
sysTime.add!"years"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-2000, 2, 28, 3, 3, 3), FracSec.from!"hnsecs"(3)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-2000, 2, 29, 3, 3, 3), FracSec.from!"hnsecs"(3));
|
|
sysTime.add!"years"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-1999, 3, 1, 3, 3, 3), FracSec.from!"hnsecs"(3)));
|
|
}
|
|
|
|
//Test Both
|
|
{
|
|
auto sysTime = SysTime(Date(4, 7, 6));
|
|
sysTime.add!"years"(-5);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1, 7, 6)));
|
|
sysTime.add!"years"(5);
|
|
_assertPred!"=="(sysTime, SysTime(Date(4, 7, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-4, 7, 6));
|
|
sysTime.add!"years"(5);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1, 7, 6)));
|
|
sysTime.add!"years"(-5);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-4, 7, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(4, 7, 6));
|
|
sysTime.add!"years"(-8);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-4, 7, 6)));
|
|
sysTime.add!"years"(8);
|
|
_assertPred!"=="(sysTime, SysTime(Date(4, 7, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-4, 7, 6));
|
|
sysTime.add!"years"(8);
|
|
_assertPred!"=="(sysTime, SysTime(Date(4, 7, 6)));
|
|
sysTime.add!"years"(-8);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-4, 7, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-4, 2, 29));
|
|
sysTime.add!"years"(5);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1, 3, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(4, 2, 29));
|
|
sysTime.add!"years"(-5);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1, 3, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0));
|
|
sysTime.add!"years"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
sysTime.add!"years"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999));
|
|
sysTime.add!"years"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
sysTime.add!"years"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(0, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0));
|
|
sysTime.add!"years"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
sysTime.add!"years"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(0, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999));
|
|
sysTime.add!"years"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
sysTime.add!"years"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(4, 7, 6, 14, 7, 1), FracSec.from!"usecs"(54329));
|
|
sysTime.add!"years"(-5);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-1, 7, 6, 14, 7, 1), FracSec.from!"usecs"(54329)));
|
|
sysTime.add!"years"(5);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(4, 7, 6, 14, 7, 1), FracSec.from!"usecs"(54329)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-4, 7, 6, 14, 7, 1), FracSec.from!"usecs"(54329));
|
|
sysTime.add!"years"(5);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 7, 6, 14, 7, 1), FracSec.from!"usecs"(54329)));
|
|
sysTime.add!"years"(-5);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-4, 7, 6, 14, 7, 1), FracSec.from!"usecs"(54329)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-4, 2, 29, 5, 5, 5), FracSec.from!"msecs"(555));
|
|
sysTime.add!"years"(5);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 3, 1, 5, 5, 5), FracSec.from!"msecs"(555)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(4, 2, 29, 5, 5, 5), FracSec.from!"msecs"(555));
|
|
sysTime.add!"years"(-5);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-1, 3, 1, 5, 5, 5), FracSec.from!"msecs"(555)));
|
|
}
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(!__traits(compiles, cst.add!"years"(4)));
|
|
//static assert(!__traits(compiles, ist.add!"years"(4)));
|
|
}
|
|
}
|
|
|
|
//Test add!"years"() with AllowDayOverlow.no
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 7, 6));
|
|
sysTime.add!"years"(7, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(2006, 7, 6)));
|
|
sysTime.add!"years"(-9, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1997, 7, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 2, 28));
|
|
sysTime.add!"years"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(2000, 2, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(2000, 2, 29));
|
|
sysTime.add!"years"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 2, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 7, 3), FracSec.from!"msecs"(234));
|
|
sysTime.add!"years"(7, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(2006, 7, 6, 12, 7, 3), FracSec.from!"msecs"(234)));
|
|
sysTime.add!"years"(-9, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1997, 7, 6, 12, 7, 3), FracSec.from!"msecs"(234)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1999, 2, 28, 0, 7, 2), FracSec.from!"usecs"(1207));
|
|
sysTime.add!"years"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(2000, 2, 28, 0, 7, 2), FracSec.from!"usecs"(1207)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(2000, 2, 29, 0, 7, 2), FracSec.from!"usecs"(1207));
|
|
sysTime.add!"years"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1999, 2, 28, 0, 7, 2), FracSec.from!"usecs"(1207)));
|
|
}
|
|
|
|
//Test B.C.
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 7, 6));
|
|
sysTime.add!"years"(-7, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2006, 7, 6)));
|
|
sysTime.add!"years"(9, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1997, 7, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 2, 28));
|
|
sysTime.add!"years"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2000, 2, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-2000, 2, 29));
|
|
sysTime.add!"years"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 2, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 7, 3), FracSec.from!"msecs"(234));
|
|
sysTime.add!"years"(-7, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-2006, 7, 6, 12, 7, 3), FracSec.from!"msecs"(234)));
|
|
sysTime.add!"years"(9, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-1997, 7, 6, 12, 7, 3), FracSec.from!"msecs"(234)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-1999, 2, 28, 3, 3, 3), FracSec.from!"hnsecs"(3));
|
|
sysTime.add!"years"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-2000, 2, 28, 3, 3, 3), FracSec.from!"hnsecs"(3)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-2000, 2, 29, 3, 3, 3), FracSec.from!"hnsecs"(3));
|
|
sysTime.add!"years"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-1999, 2, 28, 3, 3, 3), FracSec.from!"hnsecs"(3)));
|
|
}
|
|
|
|
//Test Both
|
|
{
|
|
auto sysTime = SysTime(Date(4, 7, 6));
|
|
sysTime.add!"years"(-5, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1, 7, 6)));
|
|
sysTime.add!"years"(5, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(4, 7, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-4, 7, 6));
|
|
sysTime.add!"years"(5, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1, 7, 6)));
|
|
sysTime.add!"years"(-5, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-4, 7, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(4, 7, 6));
|
|
sysTime.add!"years"(-8, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-4, 7, 6)));
|
|
sysTime.add!"years"(8, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(4, 7, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-4, 7, 6));
|
|
sysTime.add!"years"(8, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(4, 7, 6)));
|
|
sysTime.add!"years"(-8, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-4, 7, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-4, 2, 29));
|
|
sysTime.add!"years"(5, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1, 2, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(4, 2, 29));
|
|
sysTime.add!"years"(-5, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1, 2, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0));
|
|
sysTime.add!"years"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
sysTime.add!"years"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999));
|
|
sysTime.add!"years"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
sysTime.add!"years"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(0, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0));
|
|
sysTime.add!"years"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
sysTime.add!"years"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(0, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999));
|
|
sysTime.add!"years"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
sysTime.add!"years"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(4, 7, 6, 14, 7, 1), FracSec.from!"usecs"(54329));
|
|
sysTime.add!"years"(-5);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-1, 7, 6, 14, 7, 1), FracSec.from!"usecs"(54329)));
|
|
sysTime.add!"years"(5);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(4, 7, 6, 14, 7, 1), FracSec.from!"usecs"(54329)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(4, 7, 6, 14, 7, 1), FracSec.from!"usecs"(54329));
|
|
sysTime.add!"years"(-5, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-1, 7, 6, 14, 7, 1), FracSec.from!"usecs"(54329)));
|
|
sysTime.add!"years"(5, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(4, 7, 6, 14, 7, 1), FracSec.from!"usecs"(54329)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-4, 7, 6, 14, 7, 1), FracSec.from!"usecs"(54329));
|
|
sysTime.add!"years"(5, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 7, 6, 14, 7, 1), FracSec.from!"usecs"(54329)));
|
|
sysTime.add!"years"(-5, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-4, 7, 6, 14, 7, 1), FracSec.from!"usecs"(54329)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-4, 2, 29, 5, 5, 5), FracSec.from!"msecs"(555));
|
|
sysTime.add!"years"(5, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 2, 28, 5, 5, 5), FracSec.from!"msecs"(555)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(4, 2, 29, 5, 5, 5), FracSec.from!"msecs"(555));
|
|
sysTime.add!"years"(-5, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-1, 2, 28, 5, 5, 5), FracSec.from!"msecs"(555)));
|
|
}
|
|
}
|
|
}
|
|
|
|
//Test add!"months"() with AllowDayOverlow.yes
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 7, 6));
|
|
sysTime.add!"months"(3);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 10, 6)));
|
|
sysTime.add!"months"(-4);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 6, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 7, 6));
|
|
sysTime.add!"months"(6);
|
|
_assertPred!"=="(sysTime, SysTime(Date(2000, 1, 6)));
|
|
sysTime.add!"months"(-6);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 7, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 7, 6));
|
|
sysTime.add!"months"(27);
|
|
_assertPred!"=="(sysTime, SysTime(Date(2001, 10, 6)));
|
|
sysTime.add!"months"(-28);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 6, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 5, 31));
|
|
sysTime.add!"months"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 7, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 5, 31));
|
|
sysTime.add!"months"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 5, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 2, 28));
|
|
sysTime.add!"months"(12);
|
|
_assertPred!"=="(sysTime, SysTime(Date(2000, 2, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(2000, 2, 29));
|
|
sysTime.add!"months"(12);
|
|
_assertPred!"=="(sysTime, SysTime(Date(2001, 3, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 7, 31));
|
|
sysTime.add!"months"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 8, 31)));
|
|
sysTime.add!"months"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 10, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1998, 8, 31));
|
|
sysTime.add!"months"(13);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 10, 1)));
|
|
sysTime.add!"months"(-13);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1998, 9, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1997, 12, 31));
|
|
sysTime.add!"months"(13);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 1, 31)));
|
|
sysTime.add!"months"(-13);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1997, 12, 31)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1997, 12, 31));
|
|
sysTime.add!"months"(14);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 3, 3)));
|
|
sysTime.add!"months"(-14);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1998, 1, 3)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1998, 12, 31));
|
|
sysTime.add!"months"(14);
|
|
_assertPred!"=="(sysTime, SysTime(Date(2000, 3, 2)));
|
|
sysTime.add!"months"(-14);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 1, 2)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 12, 31));
|
|
sysTime.add!"months"(14);
|
|
_assertPred!"=="(sysTime, SysTime(Date(2001, 3, 3)));
|
|
sysTime.add!"months"(-14);
|
|
_assertPred!"=="(sysTime, SysTime(Date(2000, 1, 3)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), FracSec.from!"usecs"(5007));
|
|
sysTime.add!"months"(3);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1999, 10, 6, 12, 2, 7), FracSec.from!"usecs"(5007)));
|
|
sysTime.add!"months"(-4);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1999, 6, 6, 12, 2, 7), FracSec.from!"usecs"(5007)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), FracSec.from!"hnsecs"(422202));
|
|
sysTime.add!"months"(14);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(2000, 3, 2, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
sysTime.add!"months"(-14);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1999, 1, 2, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), FracSec.from!"hnsecs"(422202));
|
|
sysTime.add!"months"(14);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(2001, 3, 3, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
sysTime.add!"months"(-14);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(2000, 1, 3, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
}
|
|
|
|
//Test B.C.
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 7, 6));
|
|
sysTime.add!"months"(3);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 10, 6)));
|
|
sysTime.add!"months"(-4);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 6, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 7, 6));
|
|
sysTime.add!"months"(6);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1998, 1, 6)));
|
|
sysTime.add!"months"(-6);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 7, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 7, 6));
|
|
sysTime.add!"months"(-27);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2001, 4, 6)));
|
|
sysTime.add!"months"(28);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 8, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 5, 31));
|
|
sysTime.add!"months"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 7, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 5, 31));
|
|
sysTime.add!"months"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 5, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 2, 28));
|
|
sysTime.add!"months"(-12);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2000, 2, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-2000, 2, 29));
|
|
sysTime.add!"months"(-12);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2001, 3, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 7, 31));
|
|
sysTime.add!"months"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 8, 31)));
|
|
sysTime.add!"months"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 10, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1998, 8, 31));
|
|
sysTime.add!"months"(13);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1997, 10, 1)));
|
|
sysTime.add!"months"(-13);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1998, 9, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1997, 12, 31));
|
|
sysTime.add!"months"(13);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1995, 1, 31)));
|
|
sysTime.add!"months"(-13);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1997, 12, 31)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1997, 12, 31));
|
|
sysTime.add!"months"(14);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1995, 3, 3)));
|
|
sysTime.add!"months"(-14);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1996, 1, 3)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-2002, 12, 31));
|
|
sysTime.add!"months"(14);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2000, 3, 2)));
|
|
sysTime.add!"months"(-14);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2001, 1, 2)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-2001, 12, 31));
|
|
sysTime.add!"months"(14);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 3, 3)));
|
|
sysTime.add!"months"(-14);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2000, 1, 3)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), FracSec.from!"usecs"(5007));
|
|
sysTime.add!"months"(3);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-1999, 10, 6, 12, 2, 7), FracSec.from!"usecs"(5007)));
|
|
sysTime.add!"months"(-4);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-1999, 6, 6, 12, 2, 7), FracSec.from!"usecs"(5007)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), FracSec.from!"hnsecs"(422202));
|
|
sysTime.add!"months"(14);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-2000, 3, 2, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
sysTime.add!"months"(-14);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-2001, 1, 2, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), FracSec.from!"hnsecs"(422202));
|
|
sysTime.add!"months"(14);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-1999, 3, 3, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
sysTime.add!"months"(-14);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-2000, 1, 3, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
}
|
|
|
|
//Test Both
|
|
{
|
|
auto sysTime = SysTime(Date(1, 1, 1));
|
|
sysTime.add!"months"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(0, 12, 1)));
|
|
sysTime.add!"months"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1, 1, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(4, 1, 1));
|
|
sysTime.add!"months"(-48);
|
|
_assertPred!"=="(sysTime, SysTime(Date(0, 1, 1)));
|
|
sysTime.add!"months"(48);
|
|
_assertPred!"=="(sysTime, SysTime(Date(4, 1, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(4, 3, 31));
|
|
sysTime.add!"months"(-49);
|
|
_assertPred!"=="(sysTime, SysTime(Date(0, 3, 2)));
|
|
sysTime.add!"months"(49);
|
|
_assertPred!"=="(sysTime, SysTime(Date(4, 4, 2)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(4, 3, 31));
|
|
sysTime.add!"months"(-85);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-3, 3, 3)));
|
|
sysTime.add!"months"(85);
|
|
_assertPred!"=="(sysTime, SysTime(Date(4, 4, 3)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0));
|
|
sysTime.add!"months"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
sysTime.add!"months"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999));
|
|
sysTime.add!"months"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
sysTime.add!"months"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0), FracSec.from!"hnsecs"(0));
|
|
sysTime.add!"months"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
sysTime.add!"months"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999));
|
|
sysTime.add!"months"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
sysTime.add!"months"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), FracSec.from!"hnsecs"(17));
|
|
sysTime.add!"months"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 1, 0, 7, 9), FracSec.from!"hnsecs"(17)));
|
|
sysTime.add!"months"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 0, 7, 9), FracSec.from!"hnsecs"(17)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), FracSec.from!"msecs"(9));
|
|
sysTime.add!"months"(-85);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-3, 3, 3, 12, 11, 10), FracSec.from!"msecs"(9)));
|
|
sysTime.add!"months"(85);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(4, 4, 3, 12, 11, 10), FracSec.from!"msecs"(9)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), FracSec.from!"msecs"(9));
|
|
sysTime.add!"months"(85);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(4, 5, 1, 12, 11, 10), FracSec.from!"msecs"(9)));
|
|
sysTime.add!"months"(-85);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-3, 4, 1, 12, 11, 10), FracSec.from!"msecs"(9)));
|
|
}
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(!__traits(compiles, cst.add!"months"(4)));
|
|
//static assert(!__traits(compiles, ist.add!"months"(4)));
|
|
}
|
|
}
|
|
|
|
//Test add!"months"() with AllowDayOverlow.no
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 7, 6));
|
|
sysTime.add!"months"(3, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 10, 6)));
|
|
sysTime.add!"months"(-4, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 6, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 7, 6));
|
|
sysTime.add!"months"(6, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(2000, 1, 6)));
|
|
sysTime.add!"months"(-6, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 7, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 7, 6));
|
|
sysTime.add!"months"(27, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(2001, 10, 6)));
|
|
sysTime.add!"months"(-28, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 6, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 5, 31));
|
|
sysTime.add!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 6, 30)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 5, 31));
|
|
sysTime.add!"months"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 4, 30)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 2, 28));
|
|
sysTime.add!"months"(12, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(2000, 2, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(2000, 2, 29));
|
|
sysTime.add!"months"(12, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(2001, 2, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 7, 31));
|
|
sysTime.add!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 8, 31)));
|
|
sysTime.add!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 9, 30)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1998, 8, 31));
|
|
sysTime.add!"months"(13, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 9, 30)));
|
|
sysTime.add!"months"(-13, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1998, 8, 30)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1997, 12, 31));
|
|
sysTime.add!"months"(13, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 1, 31)));
|
|
sysTime.add!"months"(-13, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1997, 12, 31)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1997, 12, 31));
|
|
sysTime.add!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 2, 28)));
|
|
sysTime.add!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1997, 12, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1998, 12, 31));
|
|
sysTime.add!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(2000, 2, 29)));
|
|
sysTime.add!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1998, 12, 29)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 12, 31));
|
|
sysTime.add!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(2001, 2, 28)));
|
|
sysTime.add!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 12, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), FracSec.from!"usecs"(5007));
|
|
sysTime.add!"months"(3, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1999, 10, 6, 12, 2, 7), FracSec.from!"usecs"(5007)));
|
|
sysTime.add!"months"(-4, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1999, 6, 6, 12, 2, 7), FracSec.from!"usecs"(5007)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), FracSec.from!"hnsecs"(422202));
|
|
sysTime.add!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(2000, 2, 29, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
sysTime.add!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1998, 12, 29, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), FracSec.from!"hnsecs"(422202));
|
|
sysTime.add!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(2001, 2, 28, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
sysTime.add!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1999, 12, 28, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
}
|
|
|
|
//Test B.C.
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 7, 6));
|
|
sysTime.add!"months"(3, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 10, 6)));
|
|
sysTime.add!"months"(-4, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 6, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 7, 6));
|
|
sysTime.add!"months"(6, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1998, 1, 6)));
|
|
sysTime.add!"months"(-6, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 7, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 7, 6));
|
|
sysTime.add!"months"(-27, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2001, 4, 6)));
|
|
sysTime.add!"months"(28, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 8, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 5, 31));
|
|
sysTime.add!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 6, 30)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 5, 31));
|
|
sysTime.add!"months"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 4, 30)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 2, 28));
|
|
sysTime.add!"months"(-12, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2000, 2, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-2000, 2, 29));
|
|
sysTime.add!"months"(-12, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2001, 2, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 7, 31));
|
|
sysTime.add!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 8, 31)));
|
|
sysTime.add!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 9, 30)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1998, 8, 31));
|
|
sysTime.add!"months"(13, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1997, 9, 30)));
|
|
sysTime.add!"months"(-13, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1998, 8, 30)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1997, 12, 31));
|
|
sysTime.add!"months"(13, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1995, 1, 31)));
|
|
sysTime.add!"months"(-13, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1997, 12, 31)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1997, 12, 31));
|
|
sysTime.add!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1995, 2, 28)));
|
|
sysTime.add!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1997, 12, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-2002, 12, 31));
|
|
sysTime.add!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2000, 2, 29)));
|
|
sysTime.add!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2002, 12, 29)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-2001, 12, 31));
|
|
sysTime.add!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 2, 28)));
|
|
sysTime.add!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2001, 12, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), FracSec.from!"usecs"(5007));
|
|
sysTime.add!"months"(3, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-1999, 10, 6, 12, 2, 7), FracSec.from!"usecs"(5007)));
|
|
sysTime.add!"months"(-4, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-1999, 6, 6, 12, 2, 7), FracSec.from!"usecs"(5007)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), FracSec.from!"hnsecs"(422202));
|
|
sysTime.add!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-2000, 2, 29, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
sysTime.add!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-2002, 12, 29, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), FracSec.from!"hnsecs"(422202));
|
|
sysTime.add!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-1999, 2, 28, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
sysTime.add!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-2001, 12, 28, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
}
|
|
|
|
//Test Both
|
|
{
|
|
auto sysTime = SysTime(Date(1, 1, 1));
|
|
sysTime.add!"months"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(0, 12, 1)));
|
|
sysTime.add!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1, 1, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(4, 1, 1));
|
|
sysTime.add!"months"(-48, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(0, 1, 1)));
|
|
sysTime.add!"months"(48, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(4, 1, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(4, 3, 31));
|
|
sysTime.add!"months"(-49, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(0, 2, 29)));
|
|
sysTime.add!"months"(49, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(4, 3, 29)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(4, 3, 31));
|
|
sysTime.add!"months"(-85, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-3, 2, 28)));
|
|
sysTime.add!"months"(85, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(4, 3, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0));
|
|
sysTime.add!"months"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
sysTime.add!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999));
|
|
sysTime.add!"months"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
sysTime.add!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0), FracSec.from!"hnsecs"(0));
|
|
sysTime.add!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
sysTime.add!"months"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999));
|
|
sysTime.add!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
sysTime.add!"months"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), FracSec.from!"hnsecs"(17));
|
|
sysTime.add!"months"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 1, 0, 7, 9), FracSec.from!"hnsecs"(17)));
|
|
sysTime.add!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 0, 7, 9), FracSec.from!"hnsecs"(17)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), FracSec.from!"msecs"(9));
|
|
sysTime.add!"months"(-85, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-3, 2, 28, 12, 11, 10), FracSec.from!"msecs"(9)));
|
|
sysTime.add!"months"(85, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(4, 3, 28, 12, 11, 10), FracSec.from!"msecs"(9)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), FracSec.from!"msecs"(9));
|
|
sysTime.add!"months"(85, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(4, 4, 30, 12, 11, 10), FracSec.from!"msecs"(9)));
|
|
sysTime.add!"months"(-85, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-3, 3, 30, 12, 11, 10), FracSec.from!"msecs"(9)));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Adds the given number of years or months to this $(D SysTime). A
|
|
negative number will subtract.
|
|
|
|
The difference between rolling and adding is that rolling does not
|
|
affect larger units. So, if you roll a $(D SysTime) 12 months, you
|
|
get the exact same $(D SysTime). However, the days can still be affected
|
|
due to the differing number of days in each month.
|
|
|
|
Because there are no units larger than years, there is no difference
|
|
between adding and rolling years.
|
|
|
|
Params:
|
|
units = The type of units to add ("years" or "months").
|
|
value = The number of months or years to add to this
|
|
$(D SysTime).
|
|
allowOverflow = Whether the days should be allowed to overflow,
|
|
causing the month to increment.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto st1 = SysTime(DateTime(2010, 1, 1, 12, 33, 33));
|
|
st1.roll!"months"(1);
|
|
assert(st1 == SysTime(DateTime(2010, 2, 1, 12, 33, 33)));
|
|
|
|
auto st2 = SysTime(DateTime(2010, 1, 1, 12, 33, 33));
|
|
st2.roll!"months"(-1);
|
|
assert(st2 == SysTime(DateTime(2010, 12, 1, 12, 33, 33)));
|
|
|
|
auto st3 = SysTime(DateTime(1999, 1, 29, 12, 33, 33));
|
|
st3.roll!"months"(1);
|
|
assert(st3 == SysTime(DateTime(1999, 3, 1, 12, 33, 33)));
|
|
|
|
auto st4 = SysTime(DateTime(1999, 1, 29, 12, 33, 33));
|
|
st4.roll!"months"(1, AllowDayOverflow.no);
|
|
assert(st4 == SysTime(DateTime(1999, 2, 28, 12, 33, 33)));
|
|
|
|
auto st5 = SysTime(DateTime(2000, 2, 29, 12, 30, 33));
|
|
st5.roll!"years"(1);
|
|
assert(st5 == SysTime(DateTime(2001, 3, 1, 12, 30, 33)));
|
|
|
|
auto st6 = SysTime(DateTime(2000, 2, 29, 12, 30, 33));
|
|
st6.roll!"years"(1, AllowDayOverflow.no);
|
|
assert(st6 == SysTime(DateTime(2001, 2, 28, 12, 30, 33)));
|
|
--------------------
|
|
+/
|
|
/+ref SysTime+/ void roll(string units)(long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) nothrow
|
|
if(units == "years")
|
|
{
|
|
add!"years"(value, allowOverflow);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Verify Examples.
|
|
auto st1 = SysTime(DateTime(2010, 1, 1, 12, 33, 33));
|
|
st1.roll!"months"(1);
|
|
assert(st1 == SysTime(DateTime(2010, 2, 1, 12, 33, 33)));
|
|
|
|
auto st2 = SysTime(DateTime(2010, 1, 1, 12, 33, 33));
|
|
st2.roll!"months"(-1);
|
|
assert(st2 == SysTime(DateTime(2010, 12, 1, 12, 33, 33)));
|
|
|
|
auto st3 = SysTime(DateTime(1999, 1, 29, 12, 33, 33));
|
|
st3.roll!"months"(1);
|
|
assert(st3 == SysTime(DateTime(1999, 3, 1, 12, 33, 33)));
|
|
|
|
auto st4 = SysTime(DateTime(1999, 1, 29, 12, 33, 33));
|
|
st4.roll!"months"(1, AllowDayOverflow.no);
|
|
assert(st4 == SysTime(DateTime(1999, 2, 28, 12, 33, 33)));
|
|
|
|
auto st5 = SysTime(DateTime(2000, 2, 29, 12, 30, 33));
|
|
st5.roll!"years"(1);
|
|
assert(st5 == SysTime(DateTime(2001, 3, 1, 12, 30, 33)));
|
|
|
|
auto st6 = SysTime(DateTime(2000, 2, 29, 12, 30, 33));
|
|
st6.roll!"years"(1, AllowDayOverflow.no);
|
|
assert(st6 == SysTime(DateTime(2001, 2, 28, 12, 30, 33)));
|
|
}
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, st.roll!"years"(4)));
|
|
static assert(!__traits(compiles, cst.roll!"years"(4)));
|
|
//static assert(!__traits(compiles, ist.roll!"years"(4)));
|
|
}
|
|
}
|
|
|
|
|
|
//Shares documentation with "years" version.
|
|
/+ref SysTime+/ void roll(string units)(long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) nothrow
|
|
if(units == "months")
|
|
{
|
|
auto hnsecs = adjTime;
|
|
auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
|
|
|
|
if(hnsecs < 0)
|
|
{
|
|
hnsecs += convert!("hours", "hnsecs")(24);
|
|
--days;
|
|
}
|
|
|
|
auto date = Date(cast(int)days);
|
|
date.roll!"months"(value, allowOverflow);
|
|
days = date.dayOfGregorianCal - 1;
|
|
|
|
if(days < 0)
|
|
{
|
|
hnsecs -= convert!("hours", "hnsecs")(24);
|
|
++days;
|
|
}
|
|
|
|
immutable newDaysHNSecs = convert!("days", "hnsecs")(days);
|
|
|
|
adjTime = newDaysHNSecs + hnsecs;
|
|
}
|
|
|
|
//Test roll!"months"() with AllowDayOverlow.yes
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 7, 6));
|
|
sysTime.roll!"months"(3);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 10, 6)));
|
|
sysTime.roll!"months"(-4);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 6, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 7, 6));
|
|
sysTime.roll!"months"(6);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 1, 6)));
|
|
sysTime.roll!"months"(-6);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 7, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 7, 6));
|
|
sysTime.roll!"months"(27);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 10, 6)));
|
|
sysTime.roll!"months"(-28);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 6, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 5, 31));
|
|
sysTime.roll!"months"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 7, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 5, 31));
|
|
sysTime.roll!"months"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 5, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 2, 28));
|
|
sysTime.roll!"months"(12);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 2, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(2000, 2, 29));
|
|
sysTime.roll!"months"(12);
|
|
_assertPred!"=="(sysTime, SysTime(Date(2000, 2, 29)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 7, 31));
|
|
sysTime.roll!"months"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 8, 31)));
|
|
sysTime.roll!"months"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 10, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1998, 8, 31));
|
|
sysTime.roll!"months"(13);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1998, 10, 1)));
|
|
sysTime.roll!"months"(-13);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1998, 9, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1997, 12, 31));
|
|
sysTime.roll!"months"(13);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1997, 1, 31)));
|
|
sysTime.roll!"months"(-13);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1997, 12, 31)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1997, 12, 31));
|
|
sysTime.roll!"months"(14);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1997, 3, 3)));
|
|
sysTime.roll!"months"(-14);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1997, 1, 3)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1998, 12, 31));
|
|
sysTime.roll!"months"(14);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1998, 3, 3)));
|
|
sysTime.roll!"months"(-14);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1998, 1, 3)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 12, 31));
|
|
sysTime.roll!"months"(14);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 3, 3)));
|
|
sysTime.roll!"months"(-14);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 1, 3)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), FracSec.from!"usecs"(5007));
|
|
sysTime.roll!"months"(3);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1999, 10, 6, 12, 2, 7), FracSec.from!"usecs"(5007)));
|
|
sysTime.roll!"months"(-4);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1999, 6, 6, 12, 2, 7), FracSec.from!"usecs"(5007)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), FracSec.from!"hnsecs"(422202));
|
|
sysTime.roll!"months"(14);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1998, 3, 3, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
sysTime.roll!"months"(-14);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1998, 1, 3, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), FracSec.from!"hnsecs"(422202));
|
|
sysTime.roll!"months"(14);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1999, 3, 3, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
sysTime.roll!"months"(-14);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1999, 1, 3, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
}
|
|
|
|
//Test B.C.
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 7, 6));
|
|
sysTime.roll!"months"(3);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 10, 6)));
|
|
sysTime.roll!"months"(-4);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 6, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 7, 6));
|
|
sysTime.roll!"months"(6);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 1, 6)));
|
|
sysTime.roll!"months"(-6);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 7, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 7, 6));
|
|
sysTime.roll!"months"(-27);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 4, 6)));
|
|
sysTime.roll!"months"(28);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 8, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 5, 31));
|
|
sysTime.roll!"months"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 7, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 5, 31));
|
|
sysTime.roll!"months"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 5, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 2, 28));
|
|
sysTime.roll!"months"(-12);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 2, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-2000, 2, 29));
|
|
sysTime.roll!"months"(-12);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2000, 2, 29)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 7, 31));
|
|
sysTime.roll!"months"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 8, 31)));
|
|
sysTime.roll!"months"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 10, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1998, 8, 31));
|
|
sysTime.roll!"months"(13);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1998, 10, 1)));
|
|
sysTime.roll!"months"(-13);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1998, 9, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1997, 12, 31));
|
|
sysTime.roll!"months"(13);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1997, 1, 31)));
|
|
sysTime.roll!"months"(-13);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1997, 12, 31)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1997, 12, 31));
|
|
sysTime.roll!"months"(14);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1997, 3, 3)));
|
|
sysTime.roll!"months"(-14);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1997, 1, 3)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-2002, 12, 31));
|
|
sysTime.roll!"months"(14);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2002, 3, 3)));
|
|
sysTime.roll!"months"(-14);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2002, 1, 3)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-2001, 12, 31));
|
|
sysTime.roll!"months"(14);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2001, 3, 3)));
|
|
sysTime.roll!"months"(-14);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2001, 1, 3)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0));
|
|
sysTime.roll!"months"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 12, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
sysTime.roll!"months"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999));
|
|
sysTime.roll!"months"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 12, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
sysTime.roll!"months"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0), FracSec.from!"hnsecs"(0));
|
|
sysTime.roll!"months"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
sysTime.roll!"months"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999));
|
|
sysTime.roll!"months"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
sysTime.roll!"months"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), FracSec.from!"hnsecs"(5007));
|
|
sysTime.roll!"months"(3);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-1999, 10, 6, 12, 2, 7), FracSec.from!"hnsecs"(5007)));
|
|
sysTime.roll!"months"(-4);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-1999, 6, 6, 12, 2, 7), FracSec.from!"hnsecs"(5007)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), FracSec.from!"hnsecs"(422202));
|
|
sysTime.roll!"months"(14);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-2002, 3, 3, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
sysTime.roll!"months"(-14);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-2002, 1, 3, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), FracSec.from!"hnsecs"(422202));
|
|
sysTime.roll!"months"(14);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-2001, 3, 3, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
sysTime.roll!"months"(-14);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-2001, 1, 3, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
}
|
|
|
|
//Test Both
|
|
{
|
|
auto sysTime = SysTime(Date(1, 1, 1));
|
|
sysTime.roll!"months"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1, 12, 1)));
|
|
sysTime.roll!"months"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1, 1, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(4, 1, 1));
|
|
sysTime.roll!"months"(-48);
|
|
_assertPred!"=="(sysTime, SysTime(Date(4, 1, 1)));
|
|
sysTime.roll!"months"(48);
|
|
_assertPred!"=="(sysTime, SysTime(Date(4, 1, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(4, 3, 31));
|
|
sysTime.roll!"months"(-49);
|
|
_assertPred!"=="(sysTime, SysTime(Date(4, 3, 2)));
|
|
sysTime.roll!"months"(49);
|
|
_assertPred!"=="(sysTime, SysTime(Date(4, 4, 2)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(4, 3, 31));
|
|
sysTime.roll!"months"(-85);
|
|
_assertPred!"=="(sysTime, SysTime(Date(4, 3, 2)));
|
|
sysTime.roll!"months"(85);
|
|
_assertPred!"=="(sysTime, SysTime(Date(4, 4, 2)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1, 1, 1));
|
|
sysTime.roll!"months"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1, 12, 1)));
|
|
sysTime.roll!"months"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1, 1, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-4, 1, 1));
|
|
sysTime.roll!"months"(-48);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-4, 1, 1)));
|
|
sysTime.roll!"months"(48);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-4, 1, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-4, 3, 31));
|
|
sysTime.roll!"months"(-49);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-4, 3, 2)));
|
|
sysTime.roll!"months"(49);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-4, 4, 2)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-4, 3, 31));
|
|
sysTime.roll!"months"(-85);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-4, 3, 2)));
|
|
sysTime.roll!"months"(85);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-4, 4, 2)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), FracSec.from!"hnsecs"(17));
|
|
sysTime.roll!"months"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 12, 1, 0, 7, 9), FracSec.from!"hnsecs"(17)));
|
|
sysTime.roll!"months"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 0, 7, 9), FracSec.from!"hnsecs"(17)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), FracSec.from!"msecs"(9));
|
|
sysTime.roll!"months"(-85);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(4, 3, 2, 12, 11, 10), FracSec.from!"msecs"(9)));
|
|
sysTime.roll!"months"(85);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(4, 4, 2, 12, 11, 10), FracSec.from!"msecs"(9)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), FracSec.from!"msecs"(9));
|
|
sysTime.roll!"months"(85);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-3, 5, 1, 12, 11, 10), FracSec.from!"msecs"(9)));
|
|
sysTime.roll!"months"(-85);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-3, 4, 1, 12, 11, 10), FracSec.from!"msecs"(9)));
|
|
}
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(!__traits(compiles, cst.roll!"months"(4)));
|
|
//static assert(!__traits(compiles, ist.roll!"months"(4)));
|
|
|
|
//Verify Examples.
|
|
auto st1 = SysTime(DateTime(2010, 1, 1, 12, 33, 33));
|
|
st1.roll!"months"(1);
|
|
assert(st1 == SysTime(DateTime(2010, 2, 1, 12, 33, 33)));
|
|
|
|
auto st2 = SysTime(DateTime(2010, 1, 1, 12, 33, 33));
|
|
st2.roll!"months"(-1);
|
|
assert(st2 == SysTime(DateTime(2010, 12, 1, 12, 33, 33)));
|
|
|
|
auto st3 = SysTime(DateTime(1999, 1, 29, 12, 33, 33));
|
|
st3.roll!"months"(1);
|
|
assert(st3 == SysTime(DateTime(1999, 3, 1, 12, 33, 33)));
|
|
|
|
auto st4 = SysTime(DateTime(1999, 1, 29, 12, 33, 33));
|
|
st4.roll!"months"(1, AllowDayOverflow.no);
|
|
assert(st4 == SysTime(DateTime(1999, 2, 28, 12, 33, 33)));
|
|
}
|
|
}
|
|
|
|
//Test roll!"months"() with AllowDayOverlow.no
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 7, 6));
|
|
sysTime.roll!"months"(3, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 10, 6)));
|
|
sysTime.roll!"months"(-4, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 6, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 7, 6));
|
|
sysTime.roll!"months"(6, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 1, 6)));
|
|
sysTime.roll!"months"(-6, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 7, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 7, 6));
|
|
sysTime.roll!"months"(27, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 10, 6)));
|
|
sysTime.roll!"months"(-28, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 6, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 5, 31));
|
|
sysTime.roll!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 6, 30)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 5, 31));
|
|
sysTime.roll!"months"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 4, 30)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 2, 28));
|
|
sysTime.roll!"months"(12, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 2, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(2000, 2, 29));
|
|
sysTime.roll!"months"(12, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(2000, 2, 29)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 7, 31));
|
|
sysTime.roll!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 8, 31)));
|
|
sysTime.roll!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 9, 30)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1998, 8, 31));
|
|
sysTime.roll!"months"(13, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1998, 9, 30)));
|
|
sysTime.roll!"months"(-13, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1998, 8, 30)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1997, 12, 31));
|
|
sysTime.roll!"months"(13, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1997, 1, 31)));
|
|
sysTime.roll!"months"(-13, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1997, 12, 31)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1997, 12, 31));
|
|
sysTime.roll!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1997, 2, 28)));
|
|
sysTime.roll!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1997, 12, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1998, 12, 31));
|
|
sysTime.roll!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1998, 2, 28)));
|
|
sysTime.roll!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1998, 12, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 12, 31));
|
|
sysTime.roll!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 2, 28)));
|
|
sysTime.roll!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 12, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), FracSec.from!"usecs"(5007));
|
|
sysTime.roll!"months"(3, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1999, 10, 6, 12, 2, 7), FracSec.from!"usecs"(5007)));
|
|
sysTime.roll!"months"(-4, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1999, 6, 6, 12, 2, 7), FracSec.from!"usecs"(5007)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), FracSec.from!"hnsecs"(422202));
|
|
sysTime.roll!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1998, 2, 28, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
sysTime.roll!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1998, 12, 28, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), FracSec.from!"hnsecs"(422202));
|
|
sysTime.roll!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1999, 2, 28, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
sysTime.roll!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1999, 12, 28, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
}
|
|
|
|
//Test B.C.
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 7, 6));
|
|
sysTime.roll!"months"(3, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 10, 6)));
|
|
sysTime.roll!"months"(-4, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 6, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 7, 6));
|
|
sysTime.roll!"months"(6, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 1, 6)));
|
|
sysTime.roll!"months"(-6, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 7, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 7, 6));
|
|
sysTime.roll!"months"(-27, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 4, 6)));
|
|
sysTime.roll!"months"(28, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 8, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 5, 31));
|
|
sysTime.roll!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 6, 30)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 5, 31));
|
|
sysTime.roll!"months"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 4, 30)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 2, 28));
|
|
sysTime.roll!"months"(-12, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 2, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-2000, 2, 29));
|
|
sysTime.roll!"months"(-12, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2000, 2, 29)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 7, 31));
|
|
sysTime.roll!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 8, 31)));
|
|
sysTime.roll!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 9, 30)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1998, 8, 31));
|
|
sysTime.roll!"months"(13, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1998, 9, 30)));
|
|
sysTime.roll!"months"(-13, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1998, 8, 30)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1997, 12, 31));
|
|
sysTime.roll!"months"(13, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1997, 1, 31)));
|
|
sysTime.roll!"months"(-13, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1997, 12, 31)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1997, 12, 31));
|
|
sysTime.roll!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1997, 2, 28)));
|
|
sysTime.roll!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1997, 12, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-2002, 12, 31));
|
|
sysTime.roll!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2002, 2, 28)));
|
|
sysTime.roll!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2002, 12, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-2001, 12, 31));
|
|
sysTime.roll!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2001, 2, 28)));
|
|
sysTime.roll!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2001, 12, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), FracSec.from!"usecs"(5007));
|
|
sysTime.roll!"months"(3, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-1999, 10, 6, 12, 2, 7), FracSec.from!"usecs"(5007)));
|
|
sysTime.roll!"months"(-4, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-1999, 6, 6, 12, 2, 7), FracSec.from!"usecs"(5007)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), FracSec.from!"hnsecs"(422202));
|
|
sysTime.roll!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-2002, 2, 28, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
sysTime.roll!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-2002, 12, 28, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), FracSec.from!"hnsecs"(422202));
|
|
sysTime.roll!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-2001, 2, 28, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
sysTime.roll!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-2001, 12, 28, 7, 7, 7), FracSec.from!"hnsecs"(422202)));
|
|
}
|
|
|
|
//Test Both
|
|
{
|
|
auto sysTime = SysTime(Date(1, 1, 1));
|
|
sysTime.roll!"months"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1, 12, 1)));
|
|
sysTime.roll!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1, 1, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(4, 1, 1));
|
|
sysTime.roll!"months"(-48, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(4, 1, 1)));
|
|
sysTime.roll!"months"(48, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(4, 1, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(4, 3, 31));
|
|
sysTime.roll!"months"(-49, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(4, 2, 29)));
|
|
sysTime.roll!"months"(49, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(4, 3, 29)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(4, 3, 31));
|
|
sysTime.roll!"months"(-85, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(4, 2, 29)));
|
|
sysTime.roll!"months"(85, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(4, 3, 29)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1, 1, 1));
|
|
sysTime.roll!"months"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1, 12, 1)));
|
|
sysTime.roll!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1, 1, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-4, 1, 1));
|
|
sysTime.roll!"months"(-48, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-4, 1, 1)));
|
|
sysTime.roll!"months"(48, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-4, 1, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-4, 3, 31));
|
|
sysTime.roll!"months"(-49, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-4, 2, 29)));
|
|
sysTime.roll!"months"(49, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-4, 3, 29)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-4, 3, 31));
|
|
sysTime.roll!"months"(-85, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-4, 2, 29)));
|
|
sysTime.roll!"months"(85, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-4, 3, 29)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0));
|
|
sysTime.roll!"months"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 12, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
sysTime.roll!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999));
|
|
sysTime.roll!"months"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 12, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
sysTime.roll!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0), FracSec.from!"hnsecs"(0));
|
|
sysTime.roll!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
sysTime.roll!"months"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999));
|
|
sysTime.roll!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
sysTime.roll!"months"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), FracSec.from!"hnsecs"(17));
|
|
sysTime.roll!"months"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 12, 1, 0, 7, 9), FracSec.from!"hnsecs"(17)));
|
|
sysTime.roll!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 0, 7, 9), FracSec.from!"hnsecs"(17)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), FracSec.from!"msecs"(9));
|
|
sysTime.roll!"months"(-85, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(4, 2, 29, 12, 11, 10), FracSec.from!"msecs"(9)));
|
|
sysTime.roll!"months"(85, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(4, 3, 29, 12, 11, 10), FracSec.from!"msecs"(9)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), FracSec.from!"msecs"(9));
|
|
sysTime.roll!"months"(85, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-3, 4, 30, 12, 11, 10), FracSec.from!"msecs"(9)));
|
|
sysTime.roll!"months"(-85, AllowDayOverflow.no);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-3, 3, 30, 12, 11, 10), FracSec.from!"msecs"(9)));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Adds the given number of units to this $(D SysTime). A negative number
|
|
will subtract.
|
|
|
|
The difference between rolling and adding is that rolling does not
|
|
affect larger units. So, for instance, if you roll a $(D SysTime) one
|
|
year's worth of days, then you get the exact same $(D SysTime).
|
|
|
|
Accepted units are $(D "days"), $(D "minutes"), $(D "hours"),
|
|
$(D "minutes"), $(D "seconds"), $(D "msecs"), $(D "usecs"), and
|
|
$(D "hnsecs").
|
|
|
|
Note that when rolling msecs, usecs or hnsecs, they all add up to a
|
|
second. So, for example, rolling 1000 msecs is exactly the same as
|
|
rolling 100,000 usecs.
|
|
|
|
Params:
|
|
units = The units to add.
|
|
value = The number of $(D_PARAM units) to add to this $(D SysTime).
|
|
|
|
Examples:
|
|
--------------------
|
|
auto st1 = SysTime(DateTime(2010, 1, 1, 11, 23, 12));
|
|
st1.roll!"days"(1);
|
|
assert(st1 == SysTime(DateTime(2010, 1, 2, 11, 23, 12)));
|
|
st1.roll!"days"(365);
|
|
assert(st1 == SysTime(DateTime(2010, 1, 26, 11, 23, 12)));
|
|
st1.roll!"days"(-32);
|
|
assert(st1 == SysTime(DateTime(2010, 1, 25, 11, 23, 12)));
|
|
|
|
auto st2 = SysTime(DateTime(2010, 7, 4, 12, 0, 0));
|
|
st2.roll!"hours"(1);
|
|
assert(st2 == SysTime(DateTime(2010, 7, 4, 13, 0, 0)));
|
|
|
|
auto st3 = SysTime(DateTime(2010, 1, 1, 0, 0, 0));
|
|
st3.roll!"seconds"(-1);
|
|
assert(st3 == SysTime(DateTime(2010, 1, 1, 0, 0, 59)));
|
|
|
|
auto st4 = SysTime(DateTime(2010, 1, 1, 0, 0, 0),
|
|
FracSec.from!"usecs"(2_400));
|
|
st4.roll!"usecs"(-1_200_000);
|
|
assert(st4 == SysTime(DateTime(2010, 1, 1, 0, 0, 0),
|
|
FracSec.from!"usecs"(802_400)));
|
|
--------------------
|
|
+/
|
|
/+ref SysTime+/ void roll(string units)(long value) nothrow
|
|
if(units == "days")
|
|
{
|
|
auto hnsecs = adjTime;
|
|
auto gdays = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
|
|
|
|
if(hnsecs < 0)
|
|
{
|
|
hnsecs += convert!("hours", "hnsecs")(24);
|
|
--gdays;
|
|
}
|
|
|
|
auto date = Date(cast(int)gdays);
|
|
date.roll!"days"(value);
|
|
gdays = date.dayOfGregorianCal - 1;
|
|
|
|
if(gdays < 0)
|
|
{
|
|
hnsecs -= convert!("hours", "hnsecs")(24);
|
|
++gdays;
|
|
}
|
|
|
|
immutable newDaysHNSecs = convert!("days", "hnsecs")(gdays);
|
|
|
|
adjTime = newDaysHNSecs + hnsecs;
|
|
}
|
|
|
|
//Verify Examples.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto st1 = SysTime(DateTime(2010, 1, 1, 11, 23, 12));
|
|
st1.roll!"days"(1);
|
|
assert(st1 == SysTime(DateTime(2010, 1, 2, 11, 23, 12)));
|
|
st1.roll!"days"(365);
|
|
assert(st1 == SysTime(DateTime(2010, 1, 26, 11, 23, 12)));
|
|
st1.roll!"days"(-32);
|
|
assert(st1 == SysTime(DateTime(2010, 1, 25, 11, 23, 12)));
|
|
|
|
auto st2 = SysTime(DateTime(2010, 7, 4, 12, 0, 0));
|
|
st2.roll!"hours"(1);
|
|
assert(st2 == SysTime(DateTime(2010, 7, 4, 13, 0, 0)));
|
|
|
|
auto st3 = SysTime(DateTime(2010, 1, 1, 0, 0, 0));
|
|
st3.roll!"seconds"(-1);
|
|
assert(st3 == SysTime(DateTime(2010, 1, 1, 0, 0, 59)));
|
|
|
|
auto st4 = SysTime(DateTime(2010, 1, 1, 0, 0, 0),
|
|
FracSec.from!"usecs"(2_400));
|
|
st4.roll!"usecs"(-1_200_000);
|
|
assert(st4 == SysTime(DateTime(2010, 1, 1, 0, 0, 0),
|
|
FracSec.from!"usecs"(802_400)));
|
|
}
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 2, 28));
|
|
sysTime.roll!"days"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 2, 1)));
|
|
sysTime.roll!"days"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 2, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(2000, 2, 28));
|
|
sysTime.roll!"days"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(2000, 2, 29)));
|
|
sysTime.roll!"days"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(2000, 2, 1)));
|
|
sysTime.roll!"days"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(2000, 2, 29)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 6, 30));
|
|
sysTime.roll!"days"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 6, 1)));
|
|
sysTime.roll!"days"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 6, 30)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 7, 31));
|
|
sysTime.roll!"days"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 7, 1)));
|
|
sysTime.roll!"days"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 7, 31)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 1, 1));
|
|
sysTime.roll!"days"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 1, 31)));
|
|
sysTime.roll!"days"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 1, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 7, 6));
|
|
sysTime.roll!"days"(9);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 7, 15)));
|
|
sysTime.roll!"days"(-11);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 7, 4)));
|
|
sysTime.roll!"days"(30);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 7, 3)));
|
|
sysTime.roll!"days"(-3);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 7, 31)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 7, 6));
|
|
sysTime.roll!"days"(365);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 7, 30)));
|
|
sysTime.roll!"days"(-365);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 7, 6)));
|
|
sysTime.roll!"days"(366);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 7, 31)));
|
|
sysTime.roll!"days"(730);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 7, 17)));
|
|
sysTime.roll!"days"(-1096);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 7, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(1999, 2, 6));
|
|
sysTime.roll!"days"(365);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 2, 7)));
|
|
sysTime.roll!"days"(-365);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 2, 6)));
|
|
sysTime.roll!"days"(366);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 2, 8)));
|
|
sysTime.roll!"days"(730);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 2, 10)));
|
|
sysTime.roll!"days"(-1096);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1999, 2, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1999, 2, 28, 7, 9, 2), FracSec.from!"usecs"(234578));
|
|
sysTime.roll!"days"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1999, 2, 1, 7, 9, 2), FracSec.from!"usecs"(234578)));
|
|
sysTime.roll!"days"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1999, 2, 28, 7, 9, 2), FracSec.from!"usecs"(234578)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1999, 7, 6, 7, 9, 2), FracSec.from!"usecs"(234578));
|
|
sysTime.roll!"days"(9);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1999, 7, 15, 7, 9, 2), FracSec.from!"usecs"(234578)));
|
|
sysTime.roll!"days"(-11);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1999, 7, 4, 7, 9, 2), FracSec.from!"usecs"(234578)));
|
|
sysTime.roll!"days"(30);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1999, 7, 3, 7, 9, 2), FracSec.from!"usecs"(234578)));
|
|
sysTime.roll!"days"(-3);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1999, 7, 31, 7, 9, 2), FracSec.from!"usecs"(234578)));
|
|
}
|
|
|
|
//Test B.C.
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 2, 28));
|
|
sysTime.roll!"days"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 2, 1)));
|
|
sysTime.roll!"days"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 2, 28)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-2000, 2, 28));
|
|
sysTime.roll!"days"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2000, 2, 29)));
|
|
sysTime.roll!"days"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2000, 2, 1)));
|
|
sysTime.roll!"days"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-2000, 2, 29)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 6, 30));
|
|
sysTime.roll!"days"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 6, 1)));
|
|
sysTime.roll!"days"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 6, 30)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 7, 31));
|
|
sysTime.roll!"days"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 7, 1)));
|
|
sysTime.roll!"days"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 7, 31)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 1, 1));
|
|
sysTime.roll!"days"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 1, 31)));
|
|
sysTime.roll!"days"(1);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 1, 1)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 7, 6));
|
|
sysTime.roll!"days"(9);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 7, 15)));
|
|
sysTime.roll!"days"(-11);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 7, 4)));
|
|
sysTime.roll!"days"(30);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 7, 3)));
|
|
sysTime.roll!"days"(-3);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 7, 31)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(Date(-1999, 7, 6));
|
|
sysTime.roll!"days"(365);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 7, 30)));
|
|
sysTime.roll!"days"(-365);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 7, 6)));
|
|
sysTime.roll!"days"(366);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 7, 31)));
|
|
sysTime.roll!"days"(730);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 7, 17)));
|
|
sysTime.roll!"days"(-1096);
|
|
_assertPred!"=="(sysTime, SysTime(Date(-1999, 7, 6)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-1999, 2, 28, 7, 9, 2), FracSec.from!"usecs"(234578));
|
|
sysTime.roll!"days"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-1999, 2, 1, 7, 9, 2), FracSec.from!"usecs"(234578)));
|
|
sysTime.roll!"days"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-1999, 2, 28, 7, 9, 2), FracSec.from!"usecs"(234578)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(-1999, 7, 6, 7, 9, 2), FracSec.from!"usecs"(234578));
|
|
sysTime.roll!"days"(9);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-1999, 7, 15, 7, 9, 2), FracSec.from!"usecs"(234578)));
|
|
sysTime.roll!"days"(-11);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-1999, 7, 4, 7, 9, 2), FracSec.from!"usecs"(234578)));
|
|
sysTime.roll!"days"(30);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(-1999, 7, 3, 7, 9, 2), FracSec.from!"usecs"(234578)));
|
|
sysTime.roll!"days"(-3);
|
|
}
|
|
|
|
//Test Both
|
|
{
|
|
auto sysTime = SysTime(Date(1, 7, 6));
|
|
sysTime.roll!"days"(-365);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1, 7, 13)));
|
|
sysTime.roll!"days"(365);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1, 7, 6)));
|
|
sysTime.roll!"days"(-731);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1, 7, 19)));
|
|
sysTime.roll!"days"(730);
|
|
_assertPred!"=="(sysTime, SysTime(Date(1, 7, 5)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0));
|
|
sysTime.roll!"days"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 31, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
sysTime.roll!"days"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999));
|
|
sysTime.roll!"days"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
sysTime.roll!"days"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(0, 12, 31, 0, 0, 0), FracSec.from!"hnsecs"(0));
|
|
sysTime.roll!"days"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
sysTime.roll!"days"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 31, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999));
|
|
sysTime.roll!"days"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
sysTime.roll!"days"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1, 7, 6, 13, 13, 9), FracSec.from!"msecs"(22));
|
|
sysTime.roll!"days"(-365);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 7, 13, 13, 13, 9), FracSec.from!"msecs"(22)));
|
|
sysTime.roll!"days"(365);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 7, 6, 13, 13, 9), FracSec.from!"msecs"(22)));
|
|
sysTime.roll!"days"(-731);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 7, 19, 13, 13, 9), FracSec.from!"msecs"(22)));
|
|
sysTime.roll!"days"(730);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 7, 5, 13, 13, 9), FracSec.from!"msecs"(22)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(0, 7, 6, 13, 13, 9), FracSec.from!"msecs"(22));
|
|
sysTime.roll!"days"(-365);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 7, 13, 13, 13, 9), FracSec.from!"msecs"(22)));
|
|
sysTime.roll!"days"(365);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 7, 6, 13, 13, 9), FracSec.from!"msecs"(22)));
|
|
sysTime.roll!"days"(-731);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 7, 19, 13, 13, 9), FracSec.from!"msecs"(22)));
|
|
sysTime.roll!"days"(730);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 7, 5, 13, 13, 9), FracSec.from!"msecs"(22)));
|
|
}
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(!__traits(compiles, cst.roll!"days"(4)));
|
|
//static assert(!__traits(compiles, ist.roll!"days"(4)));
|
|
|
|
//Verify Examples.
|
|
auto st = SysTime(DateTime(2010, 1, 1, 11, 23, 12));
|
|
st.roll!"days"(1);
|
|
assert(st == SysTime(DateTime(2010, 1, 2, 11, 23, 12)));
|
|
st.roll!"days"(365);
|
|
assert(st == SysTime(DateTime(2010, 1, 26, 11, 23, 12)));
|
|
st.roll!"days"(-32);
|
|
assert(st == SysTime(DateTime(2010, 1, 25, 11, 23, 12)));
|
|
}
|
|
}
|
|
|
|
|
|
//Shares documentation with "days" version.
|
|
/+ref SysTime+/ void roll(string units)(long value) nothrow
|
|
if(units == "hours" ||
|
|
units == "minutes" ||
|
|
units == "seconds")
|
|
{
|
|
try
|
|
{
|
|
auto hnsecs = adjTime;
|
|
auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
|
|
|
|
if(hnsecs < 0)
|
|
{
|
|
hnsecs += convert!("hours", "hnsecs")(24);
|
|
--days;
|
|
}
|
|
|
|
immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs);
|
|
immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs);
|
|
immutable second = splitUnitsFromHNSecs!"seconds"(hnsecs);
|
|
|
|
auto dateTime = DateTime(Date(cast(int)days), TimeOfDay(cast(int)hour, cast(int)minute, cast(int)second));
|
|
dateTime.roll!units(value);
|
|
--days;
|
|
|
|
hnsecs += convert!("hours", "hnsecs")(dateTime.hour);
|
|
hnsecs += convert!("minutes", "hnsecs")(dateTime.minute);
|
|
hnsecs += convert!("seconds", "hnsecs")(dateTime.second);
|
|
|
|
if(days < 0)
|
|
{
|
|
hnsecs -= convert!("hours", "hnsecs")(24);
|
|
++days;
|
|
}
|
|
|
|
immutable newDaysHNSecs = convert!("days", "hnsecs")(days);
|
|
|
|
adjTime = newDaysHNSecs + hnsecs;
|
|
}
|
|
catch(Exception e)
|
|
assert(0, "Either DateTime's constructor or TimeOfDay's constructor threw.");
|
|
}
|
|
|
|
//Test roll!"hours"().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static void TestST(SysTime orig, int hours, in SysTime expected, size_t line = __LINE__)
|
|
{
|
|
orig.roll!"hours"(hours);
|
|
_assertPred!"=="(orig, expected, "", __FILE__, line);
|
|
}
|
|
|
|
//Test A.D.
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 1, SysTime(DateTime(1999, 7, 6, 13, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 2, SysTime(DateTime(1999, 7, 6, 14, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 3, SysTime(DateTime(1999, 7, 6, 15, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 4, SysTime(DateTime(1999, 7, 6, 16, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 5, SysTime(DateTime(1999, 7, 6, 17, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 6, SysTime(DateTime(1999, 7, 6, 18, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 7, SysTime(DateTime(1999, 7, 6, 19, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 8, SysTime(DateTime(1999, 7, 6, 20, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 9, SysTime(DateTime(1999, 7, 6, 21, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 10, SysTime(DateTime(1999, 7, 6, 22, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 11, SysTime(DateTime(1999, 7, 6, 23, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 12, SysTime(DateTime(1999, 7, 6, 0, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 13, SysTime(DateTime(1999, 7, 6, 1, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 14, SysTime(DateTime(1999, 7, 6, 2, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 15, SysTime(DateTime(1999, 7, 6, 3, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 16, SysTime(DateTime(1999, 7, 6, 4, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 17, SysTime(DateTime(1999, 7, 6, 5, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 18, SysTime(DateTime(1999, 7, 6, 6, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 19, SysTime(DateTime(1999, 7, 6, 7, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 20, SysTime(DateTime(1999, 7, 6, 8, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 21, SysTime(DateTime(1999, 7, 6, 9, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 22, SysTime(DateTime(1999, 7, 6, 10, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 23, SysTime(DateTime(1999, 7, 6, 11, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 24, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 25, SysTime(DateTime(1999, 7, 6, 13, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 50, SysTime(DateTime(1999, 7, 6, 14, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 10_000, SysTime(DateTime(1999, 7, 6, 4, 30, 33), FracSec.from!"msecs"(45)));
|
|
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -1, SysTime(DateTime(1999, 7, 6, 11, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -2, SysTime(DateTime(1999, 7, 6, 10, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -3, SysTime(DateTime(1999, 7, 6, 9, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -4, SysTime(DateTime(1999, 7, 6, 8, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -5, SysTime(DateTime(1999, 7, 6, 7, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -6, SysTime(DateTime(1999, 7, 6, 6, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -7, SysTime(DateTime(1999, 7, 6, 5, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -8, SysTime(DateTime(1999, 7, 6, 4, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -9, SysTime(DateTime(1999, 7, 6, 3, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -10, SysTime(DateTime(1999, 7, 6, 2, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -11, SysTime(DateTime(1999, 7, 6, 1, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -12, SysTime(DateTime(1999, 7, 6, 0, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -13, SysTime(DateTime(1999, 7, 6, 23, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -14, SysTime(DateTime(1999, 7, 6, 22, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -15, SysTime(DateTime(1999, 7, 6, 21, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -16, SysTime(DateTime(1999, 7, 6, 20, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -17, SysTime(DateTime(1999, 7, 6, 19, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -18, SysTime(DateTime(1999, 7, 6, 18, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -19, SysTime(DateTime(1999, 7, 6, 17, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -20, SysTime(DateTime(1999, 7, 6, 16, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -21, SysTime(DateTime(1999, 7, 6, 15, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -22, SysTime(DateTime(1999, 7, 6, 14, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -23, SysTime(DateTime(1999, 7, 6, 13, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -24, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -25, SysTime(DateTime(1999, 7, 6, 11, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -50, SysTime(DateTime(1999, 7, 6, 10, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -10_000, SysTime(DateTime(1999, 7, 6, 20, 30, 33), FracSec.from!"msecs"(45)));
|
|
|
|
TestST(SysTime(DateTime(1999, 7, 6, 0, 30, 33), FracSec.from!"msecs"(45)), 1, SysTime(DateTime(1999, 7, 6, 1, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 0, 30, 33), FracSec.from!"msecs"(45)), 0, SysTime(DateTime(1999, 7, 6, 0, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 0, 30, 33), FracSec.from!"msecs"(45)), -1, SysTime(DateTime(1999, 7, 6, 23, 30, 33), FracSec.from!"msecs"(45)));
|
|
|
|
TestST(SysTime(DateTime(1999, 7, 6, 23, 30, 33), FracSec.from!"msecs"(45)), 1, SysTime(DateTime(1999, 7, 6, 0, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 23, 30, 33), FracSec.from!"msecs"(45)), 0, SysTime(DateTime(1999, 7, 6, 23, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 23, 30, 33), FracSec.from!"msecs"(45)), -1, SysTime(DateTime(1999, 7, 6, 22, 30, 33), FracSec.from!"msecs"(45)));
|
|
|
|
TestST(SysTime(DateTime(1999, 7, 31, 23, 30, 33), FracSec.from!"msecs"(45)), 1, SysTime(DateTime(1999, 7, 31, 0, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 8, 1, 0, 30, 33), FracSec.from!"msecs"(45)), -1, SysTime(DateTime(1999, 8, 1, 23, 30, 33), FracSec.from!"msecs"(45)));
|
|
|
|
TestST(SysTime(DateTime(1999, 12, 31, 23, 30, 33), FracSec.from!"msecs"(45)), 1, SysTime(DateTime(1999, 12, 31, 0, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(2000, 1, 1, 0, 30, 33), FracSec.from!"msecs"(45)), -1, SysTime(DateTime(2000, 1, 1, 23, 30, 33), FracSec.from!"msecs"(45)));
|
|
|
|
TestST(SysTime(DateTime(1999, 2, 28, 23, 30, 33), FracSec.from!"msecs"(45)), 25, SysTime(DateTime(1999, 2, 28, 0, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1999, 3, 2, 0, 30, 33), FracSec.from!"msecs"(45)), -25, SysTime(DateTime(1999, 3, 2, 23, 30, 33), FracSec.from!"msecs"(45)));
|
|
|
|
TestST(SysTime(DateTime(2000, 2, 28, 23, 30, 33), FracSec.from!"msecs"(45)), 25, SysTime(DateTime(2000, 2, 28, 0, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(2000, 3, 1, 0, 30, 33), FracSec.from!"msecs"(45)), -25, SysTime(DateTime(2000, 3, 1, 23, 30, 33), FracSec.from!"msecs"(45)));
|
|
|
|
//Test B.C.
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 1, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 2, SysTime(DateTime(-1999, 7, 6, 14, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 3, SysTime(DateTime(-1999, 7, 6, 15, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 4, SysTime(DateTime(-1999, 7, 6, 16, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 5, SysTime(DateTime(-1999, 7, 6, 17, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 6, SysTime(DateTime(-1999, 7, 6, 18, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 7, SysTime(DateTime(-1999, 7, 6, 19, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 8, SysTime(DateTime(-1999, 7, 6, 20, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 9, SysTime(DateTime(-1999, 7, 6, 21, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 10, SysTime(DateTime(-1999, 7, 6, 22, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 11, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 12, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 13, SysTime(DateTime(-1999, 7, 6, 1, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 14, SysTime(DateTime(-1999, 7, 6, 2, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 15, SysTime(DateTime(-1999, 7, 6, 3, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 16, SysTime(DateTime(-1999, 7, 6, 4, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 17, SysTime(DateTime(-1999, 7, 6, 5, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 18, SysTime(DateTime(-1999, 7, 6, 6, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 19, SysTime(DateTime(-1999, 7, 6, 7, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 20, SysTime(DateTime(-1999, 7, 6, 8, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 21, SysTime(DateTime(-1999, 7, 6, 9, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 22, SysTime(DateTime(-1999, 7, 6, 10, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 23, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 24, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 25, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 50, SysTime(DateTime(-1999, 7, 6, 14, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), 10_000, SysTime(DateTime(-1999, 7, 6, 4, 30, 33), FracSec.from!"msecs"(45)));
|
|
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -1, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -2, SysTime(DateTime(-1999, 7, 6, 10, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -3, SysTime(DateTime(-1999, 7, 6, 9, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -4, SysTime(DateTime(-1999, 7, 6, 8, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -5, SysTime(DateTime(-1999, 7, 6, 7, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -6, SysTime(DateTime(-1999, 7, 6, 6, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -7, SysTime(DateTime(-1999, 7, 6, 5, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -8, SysTime(DateTime(-1999, 7, 6, 4, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -9, SysTime(DateTime(-1999, 7, 6, 3, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -10, SysTime(DateTime(-1999, 7, 6, 2, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -11, SysTime(DateTime(-1999, 7, 6, 1, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -12, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -13, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -14, SysTime(DateTime(-1999, 7, 6, 22, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -15, SysTime(DateTime(-1999, 7, 6, 21, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -16, SysTime(DateTime(-1999, 7, 6, 20, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -17, SysTime(DateTime(-1999, 7, 6, 19, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -18, SysTime(DateTime(-1999, 7, 6, 18, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -19, SysTime(DateTime(-1999, 7, 6, 17, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -20, SysTime(DateTime(-1999, 7, 6, 16, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -21, SysTime(DateTime(-1999, 7, 6, 15, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -22, SysTime(DateTime(-1999, 7, 6, 14, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -23, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -24, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -25, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -50, SysTime(DateTime(-1999, 7, 6, 10, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(45)), -10_000, SysTime(DateTime(-1999, 7, 6, 20, 30, 33), FracSec.from!"msecs"(45)));
|
|
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 0, 30, 33), FracSec.from!"msecs"(45)), 1, SysTime(DateTime(-1999, 7, 6, 1, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 0, 30, 33), FracSec.from!"msecs"(45)), 0, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 0, 30, 33), FracSec.from!"msecs"(45)), -1, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), FracSec.from!"msecs"(45)));
|
|
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 23, 30, 33), FracSec.from!"msecs"(45)), 1, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 23, 30, 33), FracSec.from!"msecs"(45)), 0, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 23, 30, 33), FracSec.from!"msecs"(45)), -1, SysTime(DateTime(-1999, 7, 6, 22, 30, 33), FracSec.from!"msecs"(45)));
|
|
|
|
TestST(SysTime(DateTime(-1999, 7, 31, 23, 30, 33), FracSec.from!"msecs"(45)), 1, SysTime(DateTime(-1999, 7, 31, 0, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-1999, 8, 1, 0, 30, 33), FracSec.from!"msecs"(45)), -1, SysTime(DateTime(-1999, 8, 1, 23, 30, 33), FracSec.from!"msecs"(45)));
|
|
|
|
TestST(SysTime(DateTime(-2001, 12, 31, 23, 30, 33), FracSec.from!"msecs"(45)), 1, SysTime(DateTime(-2001, 12, 31, 0, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-2000, 1, 1, 0, 30, 33), FracSec.from!"msecs"(45)), -1, SysTime(DateTime(-2000, 1, 1, 23, 30, 33), FracSec.from!"msecs"(45)));
|
|
|
|
TestST(SysTime(DateTime(-2001, 2, 28, 23, 30, 33), FracSec.from!"msecs"(45)), 25, SysTime(DateTime(-2001, 2, 28, 0, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-2001, 3, 2, 0, 30, 33), FracSec.from!"msecs"(45)), -25, SysTime(DateTime(-2001, 3, 2, 23, 30, 33), FracSec.from!"msecs"(45)));
|
|
|
|
TestST(SysTime(DateTime(-2000, 2, 28, 23, 30, 33), FracSec.from!"msecs"(45)), 25, SysTime(DateTime(-2000, 2, 28, 0, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(-2000, 3, 1, 0, 30, 33), FracSec.from!"msecs"(45)), -25, SysTime(DateTime(-2000, 3, 1, 23, 30, 33), FracSec.from!"msecs"(45)));
|
|
|
|
//Test Both
|
|
TestST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), FracSec.from!"msecs"(45)), 17_546, SysTime(DateTime(-1, 1, 1, 13, 30, 33), FracSec.from!"msecs"(45)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 13, 30, 33), FracSec.from!"msecs"(45)), -17_546, SysTime(DateTime(1, 1, 1, 11, 30, 33), FracSec.from!"msecs"(45)));
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0));
|
|
sysTime.roll!"hours"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 23, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
sysTime.roll!"hours"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1, 1, 1, 0, 59, 59), FracSec.from!"hnsecs"(9_999_999));
|
|
sysTime.roll!"hours"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
sysTime.roll!"hours"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 0, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(0, 12, 31, 23, 0, 0), FracSec.from!"hnsecs"(0));
|
|
sysTime.roll!"hours"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 31, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
sysTime.roll!"hours"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 31, 23, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999));
|
|
sysTime.roll!"hours"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 31, 0, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
sysTime.roll!"hours"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
}
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(!__traits(compiles, cst.roll!"hours"(4)));
|
|
//static assert(!__traits(compiles, ist.roll!"hours"(4)));
|
|
|
|
//Verify Examples.
|
|
auto st1 = SysTime(DateTime(2010, 7, 4, 12, 0, 0));
|
|
st1.roll!"hours"(1);
|
|
assert(st1 == SysTime(DateTime(2010, 7, 4, 13, 0, 0)));
|
|
|
|
auto st2 = SysTime(DateTime(2010, 2, 12, 12, 0, 0));
|
|
st2.roll!"hours"(-1);
|
|
assert(st2 == SysTime(DateTime(2010, 2, 12, 11, 0, 0)));
|
|
|
|
auto st3 = SysTime(DateTime(2009, 12, 31, 0, 0, 0));
|
|
st3.roll!"minutes"(1);
|
|
assert(st3 == SysTime(DateTime(2009, 12, 31, 0, 1, 0)));
|
|
|
|
auto st4 = SysTime(DateTime(2010, 1, 1, 0, 0, 0));
|
|
st4.roll!"minutes"(-1);
|
|
assert(st4 == SysTime(DateTime(2010, 1, 1, 0, 59, 0)));
|
|
|
|
auto st5 = SysTime(DateTime(2009, 12, 31, 0, 0, 0));
|
|
st5.roll!"seconds"(1);
|
|
assert(st5 == SysTime(DateTime(2009, 12, 31, 0, 0, 1)));
|
|
|
|
auto st6 = SysTime(DateTime(2010, 1, 1, 0, 0, 0));
|
|
st6.roll!"seconds"(-1);
|
|
assert(st6 == SysTime(DateTime(2010, 1, 1, 0, 0, 59)));
|
|
}
|
|
}
|
|
|
|
//Test roll!"minutes"().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static void TestST(SysTime orig, int minutes, in SysTime expected, size_t line = __LINE__)
|
|
{
|
|
orig.roll!"minutes"(minutes);
|
|
_assertPred!"=="(orig, expected, "", __FILE__, line);
|
|
}
|
|
|
|
//Test A.D.
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 1, SysTime(DateTime(1999, 7, 6, 12, 31, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 2, SysTime(DateTime(1999, 7, 6, 12, 32, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 3, SysTime(DateTime(1999, 7, 6, 12, 33, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 4, SysTime(DateTime(1999, 7, 6, 12, 34, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 5, SysTime(DateTime(1999, 7, 6, 12, 35, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 10, SysTime(DateTime(1999, 7, 6, 12, 40, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 15, SysTime(DateTime(1999, 7, 6, 12, 45, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 29, SysTime(DateTime(1999, 7, 6, 12, 59, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 30, SysTime(DateTime(1999, 7, 6, 12, 0, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 45, SysTime(DateTime(1999, 7, 6, 12, 15, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 75, SysTime(DateTime(1999, 7, 6, 12, 45, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 90, SysTime(DateTime(1999, 7, 6, 12, 0, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 100, SysTime(DateTime(1999, 7, 6, 12, 10, 33), FracSec.from!"usecs"(7203)));
|
|
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 689, SysTime(DateTime(1999, 7, 6, 12, 59, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 690, SysTime(DateTime(1999, 7, 6, 12, 0, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 691, SysTime(DateTime(1999, 7, 6, 12, 1, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 960, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 1439, SysTime(DateTime(1999, 7, 6, 12, 29, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 1440, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 1441, SysTime(DateTime(1999, 7, 6, 12, 31, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 2880, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)));
|
|
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -1, SysTime(DateTime(1999, 7, 6, 12, 29, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -2, SysTime(DateTime(1999, 7, 6, 12, 28, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -3, SysTime(DateTime(1999, 7, 6, 12, 27, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -4, SysTime(DateTime(1999, 7, 6, 12, 26, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -5, SysTime(DateTime(1999, 7, 6, 12, 25, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -10, SysTime(DateTime(1999, 7, 6, 12, 20, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -15, SysTime(DateTime(1999, 7, 6, 12, 15, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -29, SysTime(DateTime(1999, 7, 6, 12, 1, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -30, SysTime(DateTime(1999, 7, 6, 12, 0, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -45, SysTime(DateTime(1999, 7, 6, 12, 45, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -75, SysTime(DateTime(1999, 7, 6, 12, 15, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -90, SysTime(DateTime(1999, 7, 6, 12, 0, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -100, SysTime(DateTime(1999, 7, 6, 12, 50, 33), FracSec.from!"usecs"(7203)));
|
|
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -749, SysTime(DateTime(1999, 7, 6, 12, 1, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -750, SysTime(DateTime(1999, 7, 6, 12, 0, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -751, SysTime(DateTime(1999, 7, 6, 12, 59, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -960, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -1439, SysTime(DateTime(1999, 7, 6, 12, 31, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -1440, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -1441, SysTime(DateTime(1999, 7, 6, 12, 29, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -2880, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)));
|
|
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 0, 33), FracSec.from!"usecs"(7203)), 1, SysTime(DateTime(1999, 7, 6, 12, 1, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 0, 33), FracSec.from!"usecs"(7203)), 0, SysTime(DateTime(1999, 7, 6, 12, 0, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 0, 33), FracSec.from!"usecs"(7203)), -1, SysTime(DateTime(1999, 7, 6, 12, 59, 33), FracSec.from!"usecs"(7203)));
|
|
|
|
TestST(SysTime(DateTime(1999, 7, 6, 11, 59, 33), FracSec.from!"usecs"(7203)), 1, SysTime(DateTime(1999, 7, 6, 11, 0, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 11, 59, 33), FracSec.from!"usecs"(7203)), 0, SysTime(DateTime(1999, 7, 6, 11, 59, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 11, 59, 33), FracSec.from!"usecs"(7203)), -1, SysTime(DateTime(1999, 7, 6, 11, 58, 33), FracSec.from!"usecs"(7203)));
|
|
|
|
TestST(SysTime(DateTime(1999, 7, 6, 0, 0, 33), FracSec.from!"usecs"(7203)), 1, SysTime(DateTime(1999, 7, 6, 0, 1, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 0, 0, 33), FracSec.from!"usecs"(7203)), 0, SysTime(DateTime(1999, 7, 6, 0, 0, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 0, 0, 33), FracSec.from!"usecs"(7203)), -1, SysTime(DateTime(1999, 7, 6, 0, 59, 33), FracSec.from!"usecs"(7203)));
|
|
|
|
TestST(SysTime(DateTime(1999, 7, 5, 23, 59, 33), FracSec.from!"usecs"(7203)), 1, SysTime(DateTime(1999, 7, 5, 23, 0, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 5, 23, 59, 33), FracSec.from!"usecs"(7203)), 0, SysTime(DateTime(1999, 7, 5, 23, 59, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1999, 7, 5, 23, 59, 33), FracSec.from!"usecs"(7203)), -1, SysTime(DateTime(1999, 7, 5, 23, 58, 33), FracSec.from!"usecs"(7203)));
|
|
|
|
TestST(SysTime(DateTime(1998, 12, 31, 23, 59, 33), FracSec.from!"usecs"(7203)), 1, SysTime(DateTime(1998, 12, 31, 23, 0, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1998, 12, 31, 23, 59, 33), FracSec.from!"usecs"(7203)), 0, SysTime(DateTime(1998, 12, 31, 23, 59, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1998, 12, 31, 23, 59, 33), FracSec.from!"usecs"(7203)), -1, SysTime(DateTime(1998, 12, 31, 23, 58, 33), FracSec.from!"usecs"(7203)));
|
|
|
|
//Test B.C.
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 1, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 2, SysTime(DateTime(-1999, 7, 6, 12, 32, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 3, SysTime(DateTime(-1999, 7, 6, 12, 33, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 4, SysTime(DateTime(-1999, 7, 6, 12, 34, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 5, SysTime(DateTime(-1999, 7, 6, 12, 35, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 10, SysTime(DateTime(-1999, 7, 6, 12, 40, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 15, SysTime(DateTime(-1999, 7, 6, 12, 45, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 29, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 30, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 45, SysTime(DateTime(-1999, 7, 6, 12, 15, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 75, SysTime(DateTime(-1999, 7, 6, 12, 45, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 90, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 100, SysTime(DateTime(-1999, 7, 6, 12, 10, 33), FracSec.from!"usecs"(7203)));
|
|
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 689, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 690, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 691, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 960, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 1439, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 1440, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 1441, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), 2880, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)));
|
|
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -1, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -2, SysTime(DateTime(-1999, 7, 6, 12, 28, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -3, SysTime(DateTime(-1999, 7, 6, 12, 27, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -4, SysTime(DateTime(-1999, 7, 6, 12, 26, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -5, SysTime(DateTime(-1999, 7, 6, 12, 25, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -10, SysTime(DateTime(-1999, 7, 6, 12, 20, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -15, SysTime(DateTime(-1999, 7, 6, 12, 15, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -29, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -30, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -45, SysTime(DateTime(-1999, 7, 6, 12, 45, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -75, SysTime(DateTime(-1999, 7, 6, 12, 15, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -90, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -100, SysTime(DateTime(-1999, 7, 6, 12, 50, 33), FracSec.from!"usecs"(7203)));
|
|
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -749, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -750, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -751, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -960, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -1439, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -1440, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -1441, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)), -2880, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7203)));
|
|
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 0, 33), FracSec.from!"usecs"(7203)), 1, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 0, 33), FracSec.from!"usecs"(7203)), 0, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 0, 33), FracSec.from!"usecs"(7203)), -1, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), FracSec.from!"usecs"(7203)));
|
|
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 11, 59, 33), FracSec.from!"usecs"(7203)), 1, SysTime(DateTime(-1999, 7, 6, 11, 0, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 11, 59, 33), FracSec.from!"usecs"(7203)), 0, SysTime(DateTime(-1999, 7, 6, 11, 59, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 11, 59, 33), FracSec.from!"usecs"(7203)), -1, SysTime(DateTime(-1999, 7, 6, 11, 58, 33), FracSec.from!"usecs"(7203)));
|
|
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 0, 0, 33), FracSec.from!"usecs"(7203)), 1, SysTime(DateTime(-1999, 7, 6, 0, 1, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 0, 0, 33), FracSec.from!"usecs"(7203)), 0, SysTime(DateTime(-1999, 7, 6, 0, 0, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 0, 0, 33), FracSec.from!"usecs"(7203)), -1, SysTime(DateTime(-1999, 7, 6, 0, 59, 33), FracSec.from!"usecs"(7203)));
|
|
|
|
TestST(SysTime(DateTime(-1999, 7, 5, 23, 59, 33), FracSec.from!"usecs"(7203)), 1, SysTime(DateTime(-1999, 7, 5, 23, 0, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 5, 23, 59, 33), FracSec.from!"usecs"(7203)), 0, SysTime(DateTime(-1999, 7, 5, 23, 59, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-1999, 7, 5, 23, 59, 33), FracSec.from!"usecs"(7203)), -1, SysTime(DateTime(-1999, 7, 5, 23, 58, 33), FracSec.from!"usecs"(7203)));
|
|
|
|
TestST(SysTime(DateTime(-2000, 12, 31, 23, 59, 33), FracSec.from!"usecs"(7203)), 1, SysTime(DateTime(-2000, 12, 31, 23, 0, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-2000, 12, 31, 23, 59, 33), FracSec.from!"usecs"(7203)), 0, SysTime(DateTime(-2000, 12, 31, 23, 59, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(-2000, 12, 31, 23, 59, 33), FracSec.from!"usecs"(7203)), -1, SysTime(DateTime(-2000, 12, 31, 23, 58, 33), FracSec.from!"usecs"(7203)));
|
|
|
|
//Test Both
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0)), -1, SysTime(DateTime(1, 1, 1, 0, 59, 0)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 0)), 1, SysTime(DateTime(0, 12, 31, 23, 0, 0)));
|
|
|
|
TestST(SysTime(DateTime(0, 1, 1, 0, 0, 0)), -1, SysTime(DateTime(0, 1, 1, 0, 59, 0)));
|
|
TestST(SysTime(DateTime(-1, 12, 31, 23, 59, 0)), 1, SysTime(DateTime(-1, 12, 31, 23, 0, 0)));
|
|
|
|
TestST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), FracSec.from!"usecs"(7203)), 1_052_760, SysTime(DateTime(-1, 1, 1, 11, 30, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 13, 30, 33), FracSec.from!"usecs"(7203)), -1_052_760, SysTime(DateTime(1, 1, 1, 13, 30, 33), FracSec.from!"usecs"(7203)));
|
|
|
|
TestST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), FracSec.from!"usecs"(7203)), 1_052_782, SysTime(DateTime(-1, 1, 1, 11, 52, 33), FracSec.from!"usecs"(7203)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 13, 52, 33), FracSec.from!"usecs"(7203)), -1_052_782, SysTime(DateTime(1, 1, 1, 13, 30, 33), FracSec.from!"usecs"(7203)));
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0));
|
|
sysTime.roll!"minutes"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 0, 59, 0), FracSec.from!"hnsecs"(0)));
|
|
sysTime.roll!"minutes"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 59), FracSec.from!"hnsecs"(9_999_999));
|
|
sysTime.roll!"minutes"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 0, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
sysTime.roll!"minutes"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 0, 0, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 0), FracSec.from!"hnsecs"(0));
|
|
sysTime.roll!"minutes"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 31, 23, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
sysTime.roll!"minutes"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 31, 23, 59, 0), FracSec.from!"hnsecs"(0)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999));
|
|
sysTime.roll!"minutes"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 31, 23, 0, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
sysTime.roll!"minutes"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
}
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(!__traits(compiles, cst.roll!"minutes"(4)));
|
|
//static assert(!__traits(compiles, ist.roll!"minutes"(4)));
|
|
}
|
|
}
|
|
|
|
//Test roll!"seconds"().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static void TestST(SysTime orig, int seconds, in SysTime expected, size_t line = __LINE__)
|
|
{
|
|
orig.roll!"seconds"(seconds);
|
|
_assertPred!"=="(orig, expected, "", __FILE__, line);
|
|
}
|
|
|
|
//Test A.D.
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 1, SysTime(DateTime(1999, 7, 6, 12, 30, 34), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 2, SysTime(DateTime(1999, 7, 6, 12, 30, 35), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 3, SysTime(DateTime(1999, 7, 6, 12, 30, 36), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 4, SysTime(DateTime(1999, 7, 6, 12, 30, 37), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 5, SysTime(DateTime(1999, 7, 6, 12, 30, 38), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 10, SysTime(DateTime(1999, 7, 6, 12, 30, 43), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 15, SysTime(DateTime(1999, 7, 6, 12, 30, 48), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 26, SysTime(DateTime(1999, 7, 6, 12, 30, 59), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 27, SysTime(DateTime(1999, 7, 6, 12, 30, 0), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 30, SysTime(DateTime(1999, 7, 6, 12, 30, 3), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 59, SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 61, SysTime(DateTime(1999, 7, 6, 12, 30, 34), FracSec.from!"msecs"(274)));
|
|
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 1766, SysTime(DateTime(1999, 7, 6, 12, 30, 59), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 1767, SysTime(DateTime(1999, 7, 6, 12, 30, 0), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 1768, SysTime(DateTime(1999, 7, 6, 12, 30, 1), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 2007, SysTime(DateTime(1999, 7, 6, 12, 30, 0), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 3599, SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 3600, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 3601, SysTime(DateTime(1999, 7, 6, 12, 30, 34), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 7200, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)));
|
|
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -1, SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -2, SysTime(DateTime(1999, 7, 6, 12, 30, 31), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -3, SysTime(DateTime(1999, 7, 6, 12, 30, 30), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -4, SysTime(DateTime(1999, 7, 6, 12, 30, 29), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -5, SysTime(DateTime(1999, 7, 6, 12, 30, 28), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -10, SysTime(DateTime(1999, 7, 6, 12, 30, 23), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -15, SysTime(DateTime(1999, 7, 6, 12, 30, 18), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -33, SysTime(DateTime(1999, 7, 6, 12, 30, 0), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -34, SysTime(DateTime(1999, 7, 6, 12, 30, 59), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -35, SysTime(DateTime(1999, 7, 6, 12, 30, 58), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -59, SysTime(DateTime(1999, 7, 6, 12, 30, 34), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -61, SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"msecs"(274)));
|
|
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 0), FracSec.from!"msecs"(274)), 1, SysTime(DateTime(1999, 7, 6, 12, 30, 1), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 0), FracSec.from!"msecs"(274)), 0, SysTime(DateTime(1999, 7, 6, 12, 30, 0), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 0), FracSec.from!"msecs"(274)), -1, SysTime(DateTime(1999, 7, 6, 12, 30, 59), FracSec.from!"msecs"(274)));
|
|
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 0, 0), FracSec.from!"msecs"(274)), 1, SysTime(DateTime(1999, 7, 6, 12, 0, 1), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 0, 0), FracSec.from!"msecs"(274)), 0, SysTime(DateTime(1999, 7, 6, 12, 0, 0), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 0, 0), FracSec.from!"msecs"(274)), -1, SysTime(DateTime(1999, 7, 6, 12, 0, 59), FracSec.from!"msecs"(274)));
|
|
|
|
TestST(SysTime(DateTime(1999, 7, 6, 0, 0, 0), FracSec.from!"msecs"(274)), 1, SysTime(DateTime(1999, 7, 6, 0, 0, 1), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 0, 0, 0), FracSec.from!"msecs"(274)), 0, SysTime(DateTime(1999, 7, 6, 0, 0, 0), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 0, 0, 0), FracSec.from!"msecs"(274)), -1, SysTime(DateTime(1999, 7, 6, 0, 0, 59), FracSec.from!"msecs"(274)));
|
|
|
|
TestST(SysTime(DateTime(1999, 7, 5, 23, 59, 59), FracSec.from!"msecs"(274)), 1, SysTime(DateTime(1999, 7, 5, 23, 59, 0), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 5, 23, 59, 59), FracSec.from!"msecs"(274)), 0, SysTime(DateTime(1999, 7, 5, 23, 59, 59), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 5, 23, 59, 59), FracSec.from!"msecs"(274)), -1, SysTime(DateTime(1999, 7, 5, 23, 59, 58), FracSec.from!"msecs"(274)));
|
|
|
|
TestST(SysTime(DateTime(1998, 12, 31, 23, 59, 59), FracSec.from!"msecs"(274)), 1, SysTime(DateTime(1998, 12, 31, 23, 59, 0), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1998, 12, 31, 23, 59, 59), FracSec.from!"msecs"(274)), 0, SysTime(DateTime(1998, 12, 31, 23, 59, 59), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1998, 12, 31, 23, 59, 59), FracSec.from!"msecs"(274)), -1, SysTime(DateTime(1998, 12, 31, 23, 59, 58), FracSec.from!"msecs"(274)));
|
|
|
|
//Test B.C.
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 35), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 3, SysTime(DateTime(-1999, 7, 6, 12, 30, 36), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 4, SysTime(DateTime(-1999, 7, 6, 12, 30, 37), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 5, SysTime(DateTime(-1999, 7, 6, 12, 30, 38), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 43), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 15, SysTime(DateTime(-1999, 7, 6, 12, 30, 48), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 26, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 27, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 30, SysTime(DateTime(-1999, 7, 6, 12, 30, 3), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 59, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 61, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), FracSec.from!"msecs"(274)));
|
|
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 1766, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 1767, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 1768, SysTime(DateTime(-1999, 7, 6, 12, 30, 1), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 2007, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 3599, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 3600, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 3601, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 7200, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)));
|
|
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 31), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -3, SysTime(DateTime(-1999, 7, 6, 12, 30, 30), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -4, SysTime(DateTime(-1999, 7, 6, 12, 30, 29), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -5, SysTime(DateTime(-1999, 7, 6, 12, 30, 28), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 23), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -15, SysTime(DateTime(-1999, 7, 6, 12, 30, 18), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -33, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -34, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -35, SysTime(DateTime(-1999, 7, 6, 12, 30, 58), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -59, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -61, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), FracSec.from!"msecs"(274)));
|
|
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 0), FracSec.from!"msecs"(274)), 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 1), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 0), FracSec.from!"msecs"(274)), 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 0), FracSec.from!"msecs"(274)), -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), FracSec.from!"msecs"(274)));
|
|
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 0, 0), FracSec.from!"msecs"(274)), 1, SysTime(DateTime(-1999, 7, 6, 12, 0, 1), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 0, 0), FracSec.from!"msecs"(274)), 0, SysTime(DateTime(-1999, 7, 6, 12, 0, 0), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 0, 0), FracSec.from!"msecs"(274)), -1, SysTime(DateTime(-1999, 7, 6, 12, 0, 59), FracSec.from!"msecs"(274)));
|
|
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 0, 0, 0), FracSec.from!"msecs"(274)), 1, SysTime(DateTime(-1999, 7, 6, 0, 0, 1), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 0, 0, 0), FracSec.from!"msecs"(274)), 0, SysTime(DateTime(-1999, 7, 6, 0, 0, 0), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 0, 0, 0), FracSec.from!"msecs"(274)), -1, SysTime(DateTime(-1999, 7, 6, 0, 0, 59), FracSec.from!"msecs"(274)));
|
|
|
|
TestST(SysTime(DateTime(-1999, 7, 5, 23, 59, 59), FracSec.from!"msecs"(274)), 1, SysTime(DateTime(-1999, 7, 5, 23, 59, 0), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 5, 23, 59, 59), FracSec.from!"msecs"(274)), 0, SysTime(DateTime(-1999, 7, 5, 23, 59, 59), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 5, 23, 59, 59), FracSec.from!"msecs"(274)), -1, SysTime(DateTime(-1999, 7, 5, 23, 59, 58), FracSec.from!"msecs"(274)));
|
|
|
|
TestST(SysTime(DateTime(-2000, 12, 31, 23, 59, 59), FracSec.from!"msecs"(274)), 1, SysTime(DateTime(-2000, 12, 31, 23, 59, 0), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-2000, 12, 31, 23, 59, 59), FracSec.from!"msecs"(274)), 0, SysTime(DateTime(-2000, 12, 31, 23, 59, 59), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-2000, 12, 31, 23, 59, 59), FracSec.from!"msecs"(274)), -1, SysTime(DateTime(-2000, 12, 31, 23, 59, 58), FracSec.from!"msecs"(274)));
|
|
|
|
//Test Both
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"msecs"(274)), -1, SysTime(DateTime(1, 1, 1, 0, 0, 59), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"msecs"(274)), 1, SysTime(DateTime(0, 12, 31, 23, 59, 0), FracSec.from!"msecs"(274)));
|
|
|
|
TestST(SysTime(DateTime(0, 1, 1, 0, 0, 0), FracSec.from!"msecs"(274)), -1, SysTime(DateTime(0, 1, 1, 0, 0, 59), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1, 12, 31, 23, 59, 59), FracSec.from!"msecs"(274)), 1, SysTime(DateTime(-1, 12, 31, 23, 59, 0), FracSec.from!"msecs"(274)));
|
|
|
|
TestST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), FracSec.from!"msecs"(274)), 63_165_600L, SysTime(DateTime(-1, 1, 1, 11, 30, 33), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 13, 30, 33), FracSec.from!"msecs"(274)), -63_165_600L, SysTime(DateTime(1, 1, 1, 13, 30, 33), FracSec.from!"msecs"(274)));
|
|
|
|
TestST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), FracSec.from!"msecs"(274)), 63_165_617L, SysTime(DateTime(-1, 1, 1, 11, 30, 50), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 13, 30, 50), FracSec.from!"msecs"(274)), -63_165_617L, SysTime(DateTime(1, 1, 1, 13, 30, 33), FracSec.from!"msecs"(274)));
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0));
|
|
sysTime.roll!"seconds"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 0, 0, 59), FracSec.from!"hnsecs"(0)));
|
|
sysTime.roll!"seconds"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(9_999_999));
|
|
sysTime.roll!"seconds"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 0, 0, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
sysTime.roll!"seconds"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(9_999_999)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(0));
|
|
sysTime.roll!"seconds"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 31, 23, 59, 0), FracSec.from!"hnsecs"(0)));
|
|
sysTime.roll!"seconds"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(0)));
|
|
}
|
|
|
|
{
|
|
auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999));
|
|
sysTime.roll!"seconds"(1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 31, 23, 59, 0), FracSec.from!"hnsecs"(9_999_999)));
|
|
sysTime.roll!"seconds"(-1);
|
|
_assertPred!"=="(sysTime, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
}
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(!__traits(compiles, cst.roll!"seconds"(4)));
|
|
//static assert(!__traits(compiles, ist.roll!"seconds"(4)));
|
|
}
|
|
}
|
|
|
|
|
|
//Shares documentation with "days" version.
|
|
/+ref SysTime+/ void roll(string units)(long value) nothrow
|
|
if(units == "msecs" ||
|
|
units == "usecs" ||
|
|
units == "hnsecs")
|
|
{
|
|
auto hnsecs = adjTime;
|
|
immutable days = splitUnitsFromHNSecs!"days"(hnsecs);
|
|
immutable negative = hnsecs < 0;
|
|
|
|
if(negative)
|
|
hnsecs += convert!("hours", "hnsecs")(24);
|
|
|
|
immutable seconds = splitUnitsFromHNSecs!"seconds"(hnsecs);
|
|
|
|
hnsecs += convert!(units, "hnsecs")(value);
|
|
hnsecs %= convert!("seconds", "hnsecs")(1);
|
|
|
|
if(hnsecs < 0)
|
|
hnsecs += convert!("seconds", "hnsecs")(1);
|
|
|
|
hnsecs += convert!("seconds", "hnsecs")(seconds);
|
|
|
|
if(negative)
|
|
hnsecs -= convert!("hours", "hnsecs")(24);
|
|
|
|
immutable newDaysHNSecs = convert!("days", "hnsecs")(days);
|
|
|
|
adjTime = newDaysHNSecs + hnsecs;
|
|
}
|
|
|
|
|
|
//Test roll!"msecs"().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static void TestST(SysTime orig, int milliseconds, in SysTime expected, size_t line = __LINE__)
|
|
{
|
|
orig.roll!"msecs"(milliseconds);
|
|
_assertPred!"=="(orig, expected, "", __FILE__, line);
|
|
}
|
|
|
|
//Test A.D.
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(275)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(276)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(284)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(374)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(0)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(275)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(0)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(1)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(0)));
|
|
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(273)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(272)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(264)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(174)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(0)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(273)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(0)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(0)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(999)));
|
|
|
|
//Test B.C.
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(275)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(276)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(284)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(374)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(0)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(275)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(0)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(1)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(0)));
|
|
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(273)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(272)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(264)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(174)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(0)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(273)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(0)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(0)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(274)), -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(999)));
|
|
|
|
//Test Both
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"msecs"(0)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"msecs"(1)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"msecs"(0)), 0, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"msecs"(0)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"msecs"(0)), -1, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"msecs"(999)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"msecs"(0)), -2, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"msecs"(998)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"msecs"(0)), -1000, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"msecs"(0)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"msecs"(0)), -2000, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"msecs"(0)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"msecs"(0)), -2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"msecs"(445)));
|
|
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_989_999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 1, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 2, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(19_999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(5_549_999)));
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(!__traits(compiles, cst.addMSecs(4)));
|
|
//static assert(!__traits(compiles, ist.addMSecs(4)));
|
|
}
|
|
}
|
|
|
|
//Test roll!"usecs"().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static void TestST(SysTime orig, long microseconds, in SysTime expected, size_t line = __LINE__)
|
|
{
|
|
orig.roll!"usecs"(microseconds);
|
|
_assertPred!"=="(orig, expected, "", __FILE__, line);
|
|
}
|
|
|
|
//Test A.D.
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(275)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(276)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(284)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(374)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(1000)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(1274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(1275)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(2274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(26_999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(27_000)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(27_001)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(766_999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(767_000)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)));
|
|
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(273)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(272)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(264)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(174)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(0)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(999_999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(999_274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(999_273)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(998_274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(967_000)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(966_999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(167_000)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(166_999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)));
|
|
|
|
//Test B.C.
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(275)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(276)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(284)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(374)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(1000)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(1274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(1275)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(2274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(26_999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(27_000)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(27_001)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(766_999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(767_000)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), 3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)));
|
|
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(273)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(272)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(264)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(174)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(0)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(999_999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(999_274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(999_273)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(998_274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(967_000)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(966_999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(167_000)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(166_999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)), -3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(274)));
|
|
|
|
//Test Both
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"usecs"(0)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"usecs"(1)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"usecs"(0)), 0, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"usecs"(0)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"usecs"(0)), -1, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"usecs"(999_999)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"usecs"(0)), -2, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"usecs"(999_998)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"usecs"(0)), -1000, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"usecs"(999_000)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"usecs"(0)), -2000, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"usecs"(998_000)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"usecs"(0)), -2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"usecs"(997_445)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"usecs"(0)), -1_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"usecs"(0)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"usecs"(0)), -2_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"usecs"(0)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"usecs"(0)), -2_333_333, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"usecs"(666_667)));
|
|
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_989)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 1, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 2, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(19)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(19_999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(25_549)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 1_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 2_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 2_333_333, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(3_333_329)));
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(!__traits(compiles, cst.roll!"usecs"(4)));
|
|
//static assert(!__traits(compiles, ist.roll!"usecs"(4)));
|
|
}
|
|
}
|
|
|
|
//Test roll!"hnsecs"().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static void TestST(SysTime orig, long hnsecs, in SysTime expected, size_t line = __LINE__)
|
|
{
|
|
orig.roll!"hnsecs"(hnsecs);
|
|
_assertPred!"=="(orig, expected, "", __FILE__, line);
|
|
}
|
|
|
|
//Test A.D.
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(275)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(276)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(284)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(374)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1000)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1275)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(2274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(26_999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(27_000)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(27_001)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1_766_999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1_767_000)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1_000_274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 36_000_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(273)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(272)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(264)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(174)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(0)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(9_999_999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(9_999_274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(9_999_273)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(9_998_274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(9_967_000)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(9_966_999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(8_167_000)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(8_166_999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(9_000_274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -36_000_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
|
|
//Test B.C.
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(275)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(276)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(284)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(374)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1000)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1275)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(2274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(26_999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(27_000)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(27_001)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1_766_999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1_767_000)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1_000_274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(273)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(272)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(264)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(174)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(0)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(9_999_999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(9_999_274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(9_999_273)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(9_998_274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(9_967_000)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(9_966_999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(8_167_000)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(8_166_999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(9_000_274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
|
|
//Test Both
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(1)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), 0, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -1, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(9_999_999)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -2, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(9_999_998)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -1000, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(9_999_000)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -2000, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(9_998_000)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(9_997_445)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -1_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(9_000_000)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -2_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(8_000_000)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -2_333_333, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(7_666_667)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -10_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -20_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -20_888_888, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(9_111_112)));
|
|
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_998)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 1, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(0)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 2, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(1)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(1999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(2554)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 1_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(999_999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 2_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(1_999_999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 2_333_333, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(2_333_332)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 10_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 20_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 20_888_888, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(888_887)));
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(!__traits(compiles, cst.roll!"hnsecs"(4)));
|
|
//static assert(!__traits(compiles, ist.roll!"hnsecs"(4)));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Gives the result of adding or subtracting a duration from this
|
|
$(D SysTime).
|
|
|
|
The legal types of arithmetic for $(D SysTime) using this operator are
|
|
|
|
$(BOOKTABLE,
|
|
$(TR $(TD SysTime) $(TD +) $(TD duration) $(TD -->) $(TD SysTime))
|
|
$(TR $(TD SysTime) $(TD -) $(TD duration) $(TD -->) $(TD SysTime))
|
|
)
|
|
|
|
Params:
|
|
duration = The duration to add to or subtract from this
|
|
$(D SysTime).
|
|
+/
|
|
SysTime opBinary(string op, D)(in D duration) const pure nothrow
|
|
if((op == "+" || op == "-") &&
|
|
(is(Unqual!D == Duration) ||
|
|
is(Unqual!D == TickDuration)))
|
|
{
|
|
SysTime retval = SysTime(this._stdTime, this._timezone.get);
|
|
|
|
static if(is(Unqual!D == Duration))
|
|
immutable hnsecs = duration.total!"hnsecs";
|
|
else static if(is(Unqual!D == TickDuration))
|
|
immutable hnsecs = duration.hnsecs;
|
|
|
|
//Ideally, this would just be
|
|
//retval._stdTime += unaryFun!(op ~ "a")(hnsecs);
|
|
//But there isn't currently a pure version of unaryFun!().
|
|
|
|
static if(op == "+")
|
|
immutable signedHNSecs = hnsecs;
|
|
else static if(op == "-")
|
|
immutable signedHNSecs = -hnsecs;
|
|
else
|
|
static assert(0);
|
|
|
|
retval._stdTime += signedHNSecs;
|
|
|
|
return retval;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(2_345_678));
|
|
|
|
_assertPred!"=="(st + dur!"weeks"(7), SysTime(DateTime(1999, 8, 24, 12, 30, 33), FracSec.from!"hnsecs"(2_345_678)));
|
|
_assertPred!"=="(st + dur!"weeks"(-7), SysTime(DateTime(1999, 5, 18, 12, 30, 33), FracSec.from!"hnsecs"(2_345_678)));
|
|
_assertPred!"=="(st + dur!"days"(7), SysTime(DateTime(1999, 7, 13, 12, 30, 33), FracSec.from!"hnsecs"(2_345_678)));
|
|
_assertPred!"=="(st + dur!"days"(-7), SysTime(DateTime(1999, 6, 29, 12, 30, 33), FracSec.from!"hnsecs"(2_345_678)));
|
|
_assertPred!"=="(st + dur!"hours"(7), SysTime(DateTime(1999, 7, 6, 19, 30, 33), FracSec.from!"hnsecs"(2_345_678)));
|
|
_assertPred!"=="(st + dur!"hours"(-7), SysTime(DateTime(1999, 7, 6, 5, 30, 33), FracSec.from!"hnsecs"(2_345_678)));
|
|
_assertPred!"=="(st + dur!"minutes"(7), SysTime(DateTime(1999, 7, 6, 12, 37, 33), FracSec.from!"hnsecs"(2_345_678)));
|
|
_assertPred!"=="(st + dur!"minutes"(-7), SysTime(DateTime(1999, 7, 6, 12, 23, 33), FracSec.from!"hnsecs"(2_345_678)));
|
|
_assertPred!"=="(st + dur!"seconds"(7), SysTime(DateTime(1999, 7, 6, 12, 30, 40), FracSec.from!"hnsecs"(2_345_678)));
|
|
_assertPred!"=="(st + dur!"seconds"(-7), SysTime(DateTime(1999, 7, 6, 12, 30, 26), FracSec.from!"hnsecs"(2_345_678)));
|
|
_assertPred!"=="(st + dur!"msecs"(7), SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(2_415_678)));
|
|
_assertPred!"=="(st + dur!"msecs"(-7), SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(2_275_678)));
|
|
_assertPred!"=="(st + dur!"usecs"(7), SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(2_345_748)));
|
|
_assertPred!"=="(st + dur!"usecs"(-7), SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(2_345_608)));
|
|
_assertPred!"=="(st + dur!"hnsecs"(7), SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(2_345_685)));
|
|
_assertPred!"=="(st + dur!"hnsecs"(-7), SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(2_345_671)));
|
|
|
|
//This probably only runs in cases where gettimeofday() is used, but it's
|
|
//hard to do this test correctly with variable ticksPerSec.
|
|
if(TickDuration.ticksPerSec == 1_000_000)
|
|
{
|
|
_assertPred!"=="(st + TickDuration.from!"usecs"(7), SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(2_345_748)));
|
|
_assertPred!"=="(st + TickDuration.from!"usecs"(-7), SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(2_345_608)));
|
|
}
|
|
|
|
_assertPred!"=="(st - dur!"weeks"(-7), SysTime(DateTime(1999, 8, 24, 12, 30, 33), FracSec.from!"hnsecs"(2_345_678)));
|
|
_assertPred!"=="(st - dur!"weeks"(7), SysTime(DateTime(1999, 5, 18, 12, 30, 33), FracSec.from!"hnsecs"(2_345_678)));
|
|
_assertPred!"=="(st - dur!"days"(-7), SysTime(DateTime(1999, 7, 13, 12, 30, 33), FracSec.from!"hnsecs"(2_345_678)));
|
|
_assertPred!"=="(st - dur!"days"(7), SysTime(DateTime(1999, 6, 29, 12, 30, 33), FracSec.from!"hnsecs"(2_345_678)));
|
|
_assertPred!"=="(st - dur!"hours"(-7), SysTime(DateTime(1999, 7, 6, 19, 30, 33), FracSec.from!"hnsecs"(2_345_678)));
|
|
_assertPred!"=="(st - dur!"hours"(7), SysTime(DateTime(1999, 7, 6, 5, 30, 33), FracSec.from!"hnsecs"(2_345_678)));
|
|
_assertPred!"=="(st - dur!"minutes"(-7), SysTime(DateTime(1999, 7, 6, 12, 37, 33), FracSec.from!"hnsecs"(2_345_678)));
|
|
_assertPred!"=="(st - dur!"minutes"(7), SysTime(DateTime(1999, 7, 6, 12, 23, 33), FracSec.from!"hnsecs"(2_345_678)));
|
|
_assertPred!"=="(st - dur!"seconds"(-7), SysTime(DateTime(1999, 7, 6, 12, 30, 40), FracSec.from!"hnsecs"(2_345_678)));
|
|
_assertPred!"=="(st - dur!"seconds"(7), SysTime(DateTime(1999, 7, 6, 12, 30, 26), FracSec.from!"hnsecs"(2_345_678)));
|
|
_assertPred!"=="(st - dur!"msecs"(-7), SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(2_415_678)));
|
|
_assertPred!"=="(st - dur!"msecs"(7), SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(2_275_678)));
|
|
_assertPred!"=="(st - dur!"usecs"(-7), SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(2_345_748)));
|
|
_assertPred!"=="(st - dur!"usecs"(7), SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(2_345_608)));
|
|
_assertPred!"=="(st - dur!"hnsecs"(-7), SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(2_345_685)));
|
|
_assertPred!"=="(st - dur!"hnsecs"(7), SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(2_345_671)));
|
|
|
|
//This probably only runs in cases where gettimeofday() is used, but it's
|
|
//hard to do this test correctly with variable ticksPerSec.
|
|
if(TickDuration.ticksPerSec == 1_000_000)
|
|
{
|
|
_assertPred!"=="(st - TickDuration.from!"usecs"(-7), SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(2_345_748)));
|
|
_assertPred!"=="(st - TickDuration.from!"usecs"(7), SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(2_345_608)));
|
|
}
|
|
|
|
static void TestST(in SysTime orig, long hnsecs, in SysTime expected, size_t line = __LINE__)
|
|
{
|
|
_assertPred!"=="(orig + dur!"hnsecs"(hnsecs), expected, "", __FILE__, line);
|
|
}
|
|
|
|
//Test A.D.
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(275)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(276)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(284)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(374)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1000)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1275)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(2274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(26_999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(27_000)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(27_001)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1_766_999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1_767_000)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1_000_274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 39), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 36, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 31, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 36_000_000_000L, SysTime(DateTime(1999, 7, 6, 13, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(273)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(272)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(264)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(174)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(0)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_999_999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_999_274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_999_273)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_998_274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_967_000)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_966_999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(8_167_000)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(8_166_999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_000_274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 27), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 24, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 29, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -36_000_000_000L, SysTime(DateTime(1999, 7, 6, 11, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
|
|
//Test B.C.
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(275)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(276)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(284)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(374)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1000)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1275)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(2274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(26_999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(27_000)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(27_001)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1_766_999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1_767_000)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1_000_274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 39), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 36, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(273)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(272)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(264)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(174)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(0)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_999_999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_999_274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_999_273)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_998_274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_967_000)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_966_999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(8_167_000)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(8_166_999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_000_274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 27), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 24, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
|
|
//Test Both
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(1)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), 0, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -2, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_998)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_000)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_998_000)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_997_445)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -1_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_000_000)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -2_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(8_000_000)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -2_333_333, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(7_666_667)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -10_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(0)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -20_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 58), FracSec.from!"hnsecs"(0)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -20_888_888, SysTime(DateTime(0, 12, 31, 23, 59, 57), FracSec.from!"hnsecs"(9_111_112)));
|
|
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_998)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 2, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(1)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 1000, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 2000, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(1999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(2554)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 1_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(999_999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 2_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(1_999_999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 2_333_333, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(2_333_332)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 10_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(9_999_999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 20_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 1), FracSec.from!"hnsecs"(9_999_999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 20_888_888, SysTime(DateTime(1, 1, 1, 0, 0, 2), FracSec.from!"hnsecs"(888_887)));
|
|
|
|
auto duration = dur!"seconds"(12);
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, cst + duration));
|
|
//static assert(__traits(compiles, ist + duration));
|
|
static assert(__traits(compiles, cst - duration));
|
|
//static assert(__traits(compiles, ist - duration));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Gives the result of adding or subtracting a duration from this
|
|
$(D SysTime), as well as assigning the result to this $(D SysTime).
|
|
|
|
The legal types of arithmetic for $(D SysTime) using this operator are
|
|
|
|
$(BOOKTABLE,
|
|
$(TR $(TD SysTime) $(TD +) $(TD duration) $(TD -->) $(TD SysTime))
|
|
$(TR $(TD SysTime) $(TD -) $(TD duration) $(TD -->) $(TD SysTime))
|
|
)
|
|
|
|
Params:
|
|
duration = The duration to add to or subtract from this
|
|
$(D SysTime).
|
|
+/
|
|
/+ref+/ SysTime opOpAssign(string op, D)(in D duration) pure nothrow
|
|
if((op == "+" || op == "-") &&
|
|
(is(Unqual!D == Duration) ||
|
|
is(Unqual!D == TickDuration)))
|
|
{
|
|
static if(is(Unqual!D == Duration))
|
|
auto hnsecs = duration.total!"hnsecs";
|
|
else static if(is(Unqual!D == TickDuration))
|
|
auto hnsecs = duration.hnsecs;
|
|
|
|
//Ideally, this would just be
|
|
//_stdTime += unaryFun!(op ~ "a")(hnsecs);
|
|
//But there isn't currently a pure version of unaryFun!().
|
|
|
|
static if(op == "+")
|
|
immutable signedHNSecs = hnsecs;
|
|
else static if(op == "-")
|
|
immutable signedHNSecs = -hnsecs;
|
|
else
|
|
static assert(0);
|
|
|
|
_stdTime += signedHNSecs;
|
|
|
|
return this;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"+="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"weeks"(7), SysTime(DateTime(1999, 8, 24, 12, 30, 33)));
|
|
_assertPred!"+="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"weeks"(-7), SysTime(DateTime(1999, 5, 18, 12, 30, 33)));
|
|
_assertPred!"+="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"days"(7), SysTime(DateTime(1999, 7, 13, 12, 30, 33)));
|
|
_assertPred!"+="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"days"(-7), SysTime(DateTime(1999, 6, 29, 12, 30, 33)));
|
|
|
|
_assertPred!"+="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"hours"(7), SysTime(DateTime(1999, 7, 6, 19, 30, 33)));
|
|
_assertPred!"+="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"hours"(-7), SysTime(DateTime(1999, 7, 6, 5, 30, 33)));
|
|
_assertPred!"+="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"minutes"(7), SysTime(DateTime(1999, 7, 6, 12, 37, 33)));
|
|
_assertPred!"+="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"minutes"(-7), SysTime(DateTime(1999, 7, 6, 12, 23, 33)));
|
|
_assertPred!"+="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"seconds"(7), SysTime(DateTime(1999, 7, 6, 12, 30, 40)));
|
|
_assertPred!"+="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"seconds"(-7), SysTime(DateTime(1999, 7, 6, 12, 30, 26)));
|
|
_assertPred!"+="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"msecs"(7), SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(7)));
|
|
_assertPred!"+="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"msecs"(-7), SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"msecs"(993)));
|
|
_assertPred!"+="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"usecs"(7), SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7)));
|
|
_assertPred!"+="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"usecs"(-7), SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"usecs"(999_993)));
|
|
_assertPred!"+="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"hnsecs"(7), SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(7)));
|
|
_assertPred!"+="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"hnsecs"(-7), SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_999_993)));
|
|
|
|
_assertPred!"-="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"weeks"(-7), SysTime(DateTime(1999, 8, 24, 12, 30, 33)));
|
|
_assertPred!"-="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"weeks"(7), SysTime(DateTime(1999, 5, 18, 12, 30, 33)));
|
|
_assertPred!"-="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"days"(-7), SysTime(DateTime(1999, 7, 13, 12, 30, 33)));
|
|
_assertPred!"-="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"days"(7), SysTime(DateTime(1999, 6, 29, 12, 30, 33)));
|
|
|
|
_assertPred!"-="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"hours"(-7), SysTime(DateTime(1999, 7, 6, 19, 30, 33)));
|
|
_assertPred!"-="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"hours"(7), SysTime(DateTime(1999, 7, 6, 5, 30, 33)));
|
|
_assertPred!"-="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"minutes"(-7), SysTime(DateTime(1999, 7, 6, 12, 37, 33)));
|
|
_assertPred!"-="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"minutes"(7), SysTime(DateTime(1999, 7, 6, 12, 23, 33)));
|
|
_assertPred!"-="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"seconds"(-7), SysTime(DateTime(1999, 7, 6, 12, 30, 40)));
|
|
_assertPred!"-="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"seconds"(7), SysTime(DateTime(1999, 7, 6, 12, 30, 26)));
|
|
_assertPred!"-="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"msecs"(-7), SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(7)));
|
|
_assertPred!"-="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"msecs"(7), SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"msecs"(993)));
|
|
_assertPred!"-="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"usecs"(-7), SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(7)));
|
|
_assertPred!"-="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"usecs"(7), SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"usecs"(999_993)));
|
|
_assertPred!"-="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"hnsecs"(-7), SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(7)));
|
|
_assertPred!"-="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)), dur!"hnsecs"(7), SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_999_993)));
|
|
|
|
static void TestST(SysTime orig, long hnsecs, in SysTime expected, size_t line = __LINE__)
|
|
{
|
|
orig += dur!"hnsecs"(hnsecs);
|
|
_assertPred!"=="(orig, expected, "", __FILE__, line);
|
|
}
|
|
|
|
//Test A.D.
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(275)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(276)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(284)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(374)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1000)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1275)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(2274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(26_999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(27_000)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(27_001)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1_766_999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1_767_000)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1_000_274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 39), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 36, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 31, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 36_000_000_000L, SysTime(DateTime(1999, 7, 6, 13, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(273)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(272)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(264)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(174)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(0)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_999_999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_999_274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_999_273)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_998_274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_967_000)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_966_999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(8_167_000)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(8_166_999)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_000_274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 27), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 24, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 29, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -36_000_000_000L, SysTime(DateTime(1999, 7, 6, 11, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
|
|
//Test B.C.
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(275)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(276)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(284)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(374)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1000)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1275)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(2274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(26_999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(27_000)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(27_001)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1_766_999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1_767_000)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1_000_274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 39), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 36, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), 36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(273)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(272)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(264)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(174)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(0)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_999_999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_999_274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_999_273)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_998_274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_967_000)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_966_999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(8_167_000)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(8_166_999)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), FracSec.from!"hnsecs"(9_000_274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 27), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 24, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), FracSec.from!"hnsecs"(274)));
|
|
TestST(SysTime(DateTime(-1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(274)), -36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), FracSec.from!"hnsecs"(274)));
|
|
|
|
//Test Both
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(1)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), 0, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -2, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_998)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_000)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_998_000)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_997_445)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -1_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_000_000)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -2_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(8_000_000)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -2_333_333, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(7_666_667)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -10_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(0)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -20_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 58), FracSec.from!"hnsecs"(0)));
|
|
TestST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), -20_888_888, SysTime(DateTime(0, 12, 31, 23, 59, 57), FracSec.from!"hnsecs"(9_111_112)));
|
|
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_998)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 2, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(1)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 1000, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 2000, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(1999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(2554)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 1_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(999_999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 2_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(1_999_999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 2_333_333, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(2_333_332)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 10_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(9_999_999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 20_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 1), FracSec.from!"hnsecs"(9_999_999)));
|
|
TestST(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 20_888_888, SysTime(DateTime(1, 1, 1, 0, 0, 2), FracSec.from!"hnsecs"(888_887)));
|
|
|
|
auto duration = dur!"seconds"(12);
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(!__traits(compiles, cst += duration));
|
|
//static assert(!__traits(compiles, ist += duration));
|
|
static assert(!__traits(compiles, cst -= duration));
|
|
//static assert(!__traits(compiles, ist -= duration));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Gives the difference between two $(D SysTime)s.
|
|
|
|
The legal types of arithmetic for $(D SysTime) using this operator are
|
|
|
|
$(BOOKTABLE,
|
|
$(TR $(TD SysTime) $(TD -) $(TD SysTime) $(TD -->) $(TD duration))
|
|
)
|
|
+/
|
|
Duration opBinary(string op)(in SysTime rhs) const pure nothrow
|
|
if(op == "-")
|
|
{
|
|
return dur!"hnsecs"(_stdTime - rhs._stdTime);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1998, 7, 6, 12, 30, 33)),
|
|
dur!"seconds"(31_536_000));
|
|
_assertPred!"=="(SysTime(DateTime(1998, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)),
|
|
dur!"seconds"(-31_536_000));
|
|
|
|
_assertPred!"=="(SysTime(DateTime(1999, 8, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)),
|
|
dur!"seconds"(26_78_400));
|
|
_assertPred!"=="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 8, 6, 12, 30, 33)),
|
|
dur!"seconds"(-26_78_400));
|
|
|
|
_assertPred!"=="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 5, 12, 30, 33)),
|
|
dur!"seconds"(86_400));
|
|
_assertPred!"=="(SysTime(DateTime(1999, 7, 5, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)),
|
|
dur!"seconds"(-86_400));
|
|
|
|
_assertPred!"=="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 11, 30, 33)),
|
|
dur!"seconds"(3600));
|
|
_assertPred!"=="(SysTime(DateTime(1999, 7, 6, 11, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)),
|
|
dur!"seconds"(-3600));
|
|
|
|
_assertPred!"=="(SysTime(DateTime(1999, 7, 6, 12, 31, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)),
|
|
dur!"seconds"(60));
|
|
_assertPred!"=="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 31, 33)),
|
|
dur!"seconds"(-60));
|
|
|
|
_assertPred!"=="(SysTime(DateTime(1999, 7, 6, 12, 30, 34)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)),
|
|
dur!"seconds"(1));
|
|
_assertPred!"=="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 34)),
|
|
dur!"seconds"(-1));
|
|
|
|
_assertPred!"=="(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(532)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)),
|
|
dur!"msecs"(532));
|
|
_assertPred!"=="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"msecs"(532)),
|
|
dur!"msecs"(-532));
|
|
|
|
_assertPred!"=="(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(333_347)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)),
|
|
dur!"usecs"(333_347));
|
|
_assertPred!"=="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"usecs"(333_347)),
|
|
dur!"usecs"(-333_347));
|
|
|
|
_assertPred!"=="(SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1_234_567)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)),
|
|
dur!"hnsecs"(1_234_567));
|
|
_assertPred!"=="(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33), FracSec.from!"hnsecs"(1_234_567)),
|
|
dur!"hnsecs"(-1_234_567));
|
|
|
|
_assertPred!"=="(SysTime(DateTime(1, 1, 1, 12, 30, 33)) - SysTime(DateTime(1, 1, 1, 0, 0, 0)), dur!"seconds"(45033));
|
|
_assertPred!"=="(SysTime(DateTime(1, 1, 1, 0, 0, 0)) - SysTime(DateTime(1, 1, 1, 12, 30, 33)), dur!"seconds"(-45033));
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 31, 12, 30, 33)) - SysTime(DateTime(1, 1, 1, 0, 0, 0)), dur!"seconds"(-41367));
|
|
_assertPred!"=="(SysTime(DateTime(1, 1, 1, 0, 0, 0)) - SysTime(DateTime(0, 12, 31, 12, 30, 33)), dur!"seconds"(41367));
|
|
|
|
_assertPred!"=="(SysTime(DateTime(1, 1, 1, 0, 0, 0)) - SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)),
|
|
dur!"hnsecs"(1));
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)) - SysTime(DateTime(1, 1, 1, 0, 0, 0)),
|
|
dur!"hnsecs"(-1));
|
|
|
|
auto tz = TimeZone.getTimeZone("America/Los_Angeles");
|
|
|
|
_assertPred!"=="(SysTime(DateTime(2011, 1, 13, 8, 17, 2), FracSec.from!"msecs"(296), tz) -
|
|
SysTime(DateTime(2011, 1, 13, 8, 17, 2), FracSec.from!"msecs"(296), tz),
|
|
dur!"hnsecs"(0));
|
|
|
|
_assertPred!"=="(SysTime(DateTime(2011, 1, 13, 8, 17, 2), FracSec.from!"msecs"(296), tz) -
|
|
SysTime(DateTime(2011, 1, 13, 8, 17, 2), FracSec.from!"msecs"(296), UTC()),
|
|
dur!"hours"(8));
|
|
|
|
_assertPred!"=="(SysTime(DateTime(2011, 1, 13, 8, 17, 2), FracSec.from!"msecs"(296), UTC()) -
|
|
SysTime(DateTime(2011, 1, 13, 8, 17, 2), FracSec.from!"msecs"(296), tz),
|
|
dur!"hours"(-8));
|
|
|
|
auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, st - st));
|
|
static assert(__traits(compiles, cst - st));
|
|
//static assert(__traits(compiles, ist - st));
|
|
|
|
static assert(__traits(compiles, st - cst));
|
|
static assert(__traits(compiles, cst - cst));
|
|
//static assert(__traits(compiles, ist - cst));
|
|
|
|
//static assert(__traits(compiles, st - ist));
|
|
//static assert(__traits(compiles, cst - ist));
|
|
//static assert(__traits(compiles, ist - ist));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the difference between the two $(D SysTime)s in months.
|
|
|
|
You can get the difference in years by subtracting the year property
|
|
of two $(D SysTime)s, and you can get the difference in days or weeks by
|
|
subtracting the $(D SysTime)s themselves and using the $(D Duration)
|
|
that results, but because you cannot convert between months and smaller
|
|
units without a specific date (which $(D Duration)s don't have), you
|
|
cannot get the difference in months without doing some math using both
|
|
the year and month properties, so this is a convenience function for
|
|
getting the difference in months.
|
|
|
|
Note that the number of days in the months or how far into the month
|
|
either date is is irrelevant. It is the difference in the month property
|
|
combined with the difference in years * 12. So, for instance,
|
|
December 31st and January 1st are one month apart just as December 1st
|
|
and January 31st are one month apart.
|
|
|
|
Params:
|
|
rhs = The $(D SysTime) to subtract from this one.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(SysTime(Date(1999, 2, 1)).diffMonths(SysTime(Date(1999, 1, 31))) == 1);
|
|
assert(SysTime(Date(1999, 1, 31)).diffMonths(SysTime(Date(1999, 2, 1))) == -1);
|
|
assert(SysTime(Date(1999, 3, 1)).diffMonths(SysTime(Date(1999, 1, 1))) == 2);
|
|
assert(SysTime(Date(1999, 1, 1)).diffMonths(SysTime(Date(1999, 3, 31))) == -2);
|
|
--------------------
|
|
+/
|
|
int diffMonths(in SysTime rhs) const nothrow
|
|
{
|
|
return (cast(Date)this).diffMonths(cast(Date)rhs);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, st.diffMonths(st)));
|
|
static assert(__traits(compiles, cst.diffMonths(st)));
|
|
//static assert(__traits(compiles, ist.diffMonths(st)));
|
|
|
|
static assert(__traits(compiles, st.diffMonths(cst)));
|
|
static assert(__traits(compiles, cst.diffMonths(cst)));
|
|
//static assert(__traits(compiles, ist.diffMonths(cst)));
|
|
|
|
//static assert(__traits(compiles, st.diffMonths(ist)));
|
|
//static assert(__traits(compiles, cst.diffMonths(ist)));
|
|
//static assert(__traits(compiles, ist.diffMonths(ist)));
|
|
|
|
//Verify Examples.
|
|
assert(SysTime(Date(1999, 2, 1)).diffMonths(SysTime(Date(1999, 1, 31))) == 1);
|
|
assert(SysTime(Date(1999, 1, 31)).diffMonths(SysTime(Date(1999, 2, 1))) == -1);
|
|
assert(SysTime(Date(1999, 3, 1)).diffMonths(SysTime(Date(1999, 1, 1))) == 2);
|
|
assert(SysTime(Date(1999, 1, 1)).diffMonths(SysTime(Date(1999, 3, 31))) == -2);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this $(D SysTime) is in a leap year.
|
|
+/
|
|
@property bool isLeapYear() const nothrow
|
|
{
|
|
return (cast(Date)this).isLeapYear;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, st.isLeapYear));
|
|
static assert(__traits(compiles, cst.isLeapYear));
|
|
//static assert(__traits(compiles, ist.isLeapYear));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Day of the week this $(D SysTime) is on.
|
|
+/
|
|
@property DayOfWeek dayOfWeek() const nothrow
|
|
{
|
|
return getDayOfWeek(dayOfGregorianCal);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, st.dayOfWeek));
|
|
static assert(__traits(compiles, cst.dayOfWeek));
|
|
//static assert(__traits(compiles, ist.dayOfWeek));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Day of the year this $(D SysTime) is on.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(SysTime(DateTime(1999, 1, 1, 12, 22, 7)).dayOfYear == 1);
|
|
assert(SysTime(DateTime(1999, 12, 31, 7, 2, 59)).dayOfYear == 365);
|
|
assert(SysTime(DateTime(2000, 12, 31, 21, 20, 0)).dayOfYear == 366);
|
|
--------------------
|
|
+/
|
|
@property ushort dayOfYear() const nothrow
|
|
{
|
|
return (cast(Date)this).dayOfYear;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, st.dayOfYear));
|
|
static assert(__traits(compiles, cst.dayOfYear));
|
|
//static assert(__traits(compiles, ist.dayOfYear));
|
|
|
|
//Verify Examples.
|
|
assert(SysTime(DateTime(1999, 1, 1, 12, 22, 7)).dayOfYear == 1);
|
|
assert(SysTime(DateTime(1999, 12, 31, 7, 2, 59)).dayOfYear == 365);
|
|
assert(SysTime(DateTime(2000, 12, 31, 21, 20, 0)).dayOfYear == 366);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Day of the year.
|
|
|
|
Params:
|
|
day = The day of the year to set which day of the year this
|
|
$(D SysTime) is on.
|
|
+/
|
|
@property void dayOfYear(int day)
|
|
{
|
|
immutable hnsecs = adjTime;
|
|
immutable days = convert!("hnsecs", "days")(hnsecs);
|
|
immutable theRest = hnsecs - convert!("days", "hnsecs")(days);
|
|
|
|
auto date = Date(cast(int)days);
|
|
date.dayOfYear = day;
|
|
|
|
immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1);
|
|
|
|
adjTime = newDaysHNSecs + theRest;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, st.dayOfYear = 12));
|
|
static assert(!__traits(compiles, cst.dayOfYear = 12));
|
|
//static assert(!__traits(compiles, ist.dayOfYear = 12));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
The Xth day of the Gregorian Calendar that this $(D SysTime) is on.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).dayOfGregorianCal == 1);
|
|
assert(SysTime(DateTime(1, 12, 31, 23, 59, 59)).dayOfGregorianCal == 365);
|
|
assert(SysTime(DateTime(2, 1, 1, 2, 2, 2)).dayOfGregorianCal == 366);
|
|
|
|
assert(SysTime(DateTime(0, 12, 31, 7, 7, 7)).dayOfGregorianCal == 0);
|
|
assert(SysTime(DateTime(0, 1, 1, 19, 30, 0)).dayOfGregorianCal == -365);
|
|
assert(SysTime(DateTime(-1, 12, 31, 4, 7, 0)).dayOfGregorianCal == -366);
|
|
|
|
assert(SysTime(DateTime(2000, 1, 1, 9, 30, 20)).dayOfGregorianCal == 730_120);
|
|
assert(SysTime(DateTime(2010, 12, 31, 15, 45, 50)).dayOfGregorianCal == 734_137);
|
|
--------------------
|
|
+/
|
|
@property int dayOfGregorianCal() const nothrow
|
|
{
|
|
immutable adjustedTime = adjTime;
|
|
|
|
//We have to add one because 0 would be midnight, January 1st, 1 A.D.,
|
|
//which would be the 1st day of the Gregorian Calendar, not the 0th. So,
|
|
//simply casting to days is one day off.
|
|
if(adjustedTime > 0)
|
|
return cast(int)getUnitsFromHNSecs!"days"(adjustedTime) + 1;
|
|
|
|
auto hnsecs = adjustedTime;
|
|
immutable days = cast(int)splitUnitsFromHNSecs!"days"(hnsecs);
|
|
|
|
return hnsecs == 0 ? days + 1 : days;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
_assertPred!"=="(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)).dayOfGregorianCal, 1);
|
|
_assertPred!"=="(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(1)).dayOfGregorianCal, 1);
|
|
_assertPred!"=="(SysTime(DateTime(1, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal, 1);
|
|
|
|
_assertPred!"=="(SysTime(DateTime(1, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 1);
|
|
_assertPred!"=="(SysTime(DateTime(1, 1, 2, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 2);
|
|
_assertPred!"=="(SysTime(DateTime(1, 2, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 32);
|
|
_assertPred!"=="(SysTime(DateTime(2, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 366);
|
|
_assertPred!"=="(SysTime(DateTime(3, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 731);
|
|
_assertPred!"=="(SysTime(DateTime(4, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 1096);
|
|
_assertPred!"=="(SysTime(DateTime(5, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 1462);
|
|
_assertPred!"=="(SysTime(DateTime(50, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 17_898);
|
|
_assertPred!"=="(SysTime(DateTime(97, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 35_065);
|
|
_assertPred!"=="(SysTime(DateTime(100, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 36_160);
|
|
_assertPred!"=="(SysTime(DateTime(101, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 36_525);
|
|
_assertPred!"=="(SysTime(DateTime(105, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 37_986);
|
|
_assertPred!"=="(SysTime(DateTime(200, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 72_684);
|
|
_assertPred!"=="(SysTime(DateTime(201, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 73_049);
|
|
_assertPred!"=="(SysTime(DateTime(300, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 109_208);
|
|
_assertPred!"=="(SysTime(DateTime(301, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 109_573);
|
|
_assertPred!"=="(SysTime(DateTime(400, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 145_732);
|
|
_assertPred!"=="(SysTime(DateTime(401, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 146_098);
|
|
_assertPred!"=="(SysTime(DateTime(500, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 182_257);
|
|
_assertPred!"=="(SysTime(DateTime(501, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 182_622);
|
|
_assertPred!"=="(SysTime(DateTime(1000, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 364_878);
|
|
_assertPred!"=="(SysTime(DateTime(1001, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 365_243);
|
|
_assertPred!"=="(SysTime(DateTime(1600, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 584_023);
|
|
_assertPred!"=="(SysTime(DateTime(1601, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 584_389);
|
|
_assertPred!"=="(SysTime(DateTime(1900, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 693_596);
|
|
_assertPred!"=="(SysTime(DateTime(1901, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 693_961);
|
|
_assertPred!"=="(SysTime(DateTime(1945, 11, 12, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 710_347);
|
|
_assertPred!"=="(SysTime(DateTime(1999, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 729_755);
|
|
_assertPred!"=="(SysTime(DateTime(2000, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 730_120);
|
|
_assertPred!"=="(SysTime(DateTime(2001, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 730_486);
|
|
|
|
_assertPred!"=="(SysTime(DateTime(2010, 1, 1, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, 733_773);
|
|
_assertPred!"=="(SysTime(DateTime(2010, 1, 31, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, 733_803);
|
|
_assertPred!"=="(SysTime(DateTime(2010, 2, 1, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, 733_804);
|
|
_assertPred!"=="(SysTime(DateTime(2010, 2, 28, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, 733_831);
|
|
_assertPred!"=="(SysTime(DateTime(2010, 3, 1, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, 733_832);
|
|
_assertPred!"=="(SysTime(DateTime(2010, 3, 31, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, 733_862);
|
|
_assertPred!"=="(SysTime(DateTime(2010, 4, 1, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, 733_863);
|
|
_assertPred!"=="(SysTime(DateTime(2010, 4, 30, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, 733_892);
|
|
_assertPred!"=="(SysTime(DateTime(2010, 5, 1, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, 733_893);
|
|
_assertPred!"=="(SysTime(DateTime(2010, 5, 31, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, 733_923);
|
|
_assertPred!"=="(SysTime(DateTime(2010, 6, 1, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, 733_924);
|
|
_assertPred!"=="(SysTime(DateTime(2010, 6, 30, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, 733_953);
|
|
_assertPred!"=="(SysTime(DateTime(2010, 7, 1, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, 733_954);
|
|
_assertPred!"=="(SysTime(DateTime(2010, 7, 31, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, 733_984);
|
|
_assertPred!"=="(SysTime(DateTime(2010, 8, 1, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, 733_985);
|
|
_assertPred!"=="(SysTime(DateTime(2010, 8, 31, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, 734_015);
|
|
_assertPred!"=="(SysTime(DateTime(2010, 9, 1, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, 734_016);
|
|
_assertPred!"=="(SysTime(DateTime(2010, 9, 30, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, 734_045);
|
|
_assertPred!"=="(SysTime(DateTime(2010, 10, 1, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, 734_046);
|
|
_assertPred!"=="(SysTime(DateTime(2010, 10, 31, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, 734_076);
|
|
_assertPred!"=="(SysTime(DateTime(2010, 11, 1, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, 734_077);
|
|
_assertPred!"=="(SysTime(DateTime(2010, 11, 30, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, 734_106);
|
|
_assertPred!"=="(SysTime(DateTime(2010, 12, 1, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, 734_107);
|
|
_assertPred!"=="(SysTime(DateTime(2010, 12, 31, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, 734_137);
|
|
|
|
_assertPred!"=="(SysTime(DateTime(2012, 2, 1, 0, 0, 0), FracSec.from!"msecs"(0)).dayOfGregorianCal, 734_534);
|
|
_assertPred!"=="(SysTime(DateTime(2012, 2, 28, 0, 0, 0), FracSec.from!"msecs"(0)).dayOfGregorianCal, 734_561);
|
|
_assertPred!"=="(SysTime(DateTime(2012, 2, 29, 0, 0, 0), FracSec.from!"msecs"(0)).dayOfGregorianCal, 734_562);
|
|
_assertPred!"=="(SysTime(DateTime(2012, 3, 1, 0, 0, 0), FracSec.from!"msecs"(0)).dayOfGregorianCal, 734_563);
|
|
|
|
//Test B.C.
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal, 0);
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_998)).dayOfGregorianCal, 0);
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(0)).dayOfGregorianCal, 0);
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 31, 0, 0, 0), FracSec.from!"hnsecs"(1)).dayOfGregorianCal, 0);
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 31, 0, 0, 0), FracSec.from!"hnsecs"(0)).dayOfGregorianCal, 0);
|
|
|
|
_assertPred!"=="(SysTime(DateTime(-1, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal, -366);
|
|
_assertPred!"=="(SysTime(DateTime(-1, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_998)).dayOfGregorianCal, -366);
|
|
_assertPred!"=="(SysTime(DateTime(-1, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(0)).dayOfGregorianCal, -366);
|
|
_assertPred!"=="(SysTime(DateTime(-1, 12, 31, 0, 0, 0), FracSec.from!"hnsecs"(0)).dayOfGregorianCal, -366);
|
|
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 31, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, 0);
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 30, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -1);
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -30);
|
|
_assertPred!"=="(SysTime(DateTime(0, 11, 30, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -31);
|
|
|
|
_assertPred!"=="(SysTime(DateTime(-1, 12, 31, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -366);
|
|
_assertPred!"=="(SysTime(DateTime(-1, 12, 30, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -367);
|
|
_assertPred!"=="(SysTime(DateTime(-1, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -730);
|
|
_assertPred!"=="(SysTime(DateTime(-2, 12, 31, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -731);
|
|
_assertPred!"=="(SysTime(DateTime(-2, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -1095);
|
|
_assertPred!"=="(SysTime(DateTime(-3, 12, 31, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -1096);
|
|
_assertPred!"=="(SysTime(DateTime(-3, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -1460);
|
|
_assertPred!"=="(SysTime(DateTime(-4, 12, 31, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -1461);
|
|
_assertPred!"=="(SysTime(DateTime(-4, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -1826);
|
|
_assertPred!"=="(SysTime(DateTime(-5, 12, 31, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -1827);
|
|
_assertPred!"=="(SysTime(DateTime(-5, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -2191);
|
|
_assertPred!"=="(SysTime(DateTime(-9, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -3652);
|
|
|
|
_assertPred!"=="(SysTime(DateTime(-49, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -18_262);
|
|
_assertPred!"=="(SysTime(DateTime(-50, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -18_627);
|
|
_assertPred!"=="(SysTime(DateTime(-97, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -35_794);
|
|
_assertPred!"=="(SysTime(DateTime(-99, 12, 31, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -36_160);
|
|
_assertPred!"=="(SysTime(DateTime(-99, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -36_524);
|
|
_assertPred!"=="(SysTime(DateTime(-100, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -36_889);
|
|
_assertPred!"=="(SysTime(DateTime(-101, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -37_254);
|
|
_assertPred!"=="(SysTime(DateTime(-105, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -38_715);
|
|
_assertPred!"=="(SysTime(DateTime(-200, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -73_413);
|
|
_assertPred!"=="(SysTime(DateTime(-201, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -73_778);
|
|
_assertPred!"=="(SysTime(DateTime(-300, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -109_937);
|
|
_assertPred!"=="(SysTime(DateTime(-301, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -110_302);
|
|
_assertPred!"=="(SysTime(DateTime(-400, 12, 31, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -146_097);
|
|
_assertPred!"=="(SysTime(DateTime(-400, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -146_462);
|
|
_assertPred!"=="(SysTime(DateTime(-401, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -146_827);
|
|
_assertPred!"=="(SysTime(DateTime(-499, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -182_621);
|
|
_assertPred!"=="(SysTime(DateTime(-500, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -182_986);
|
|
_assertPred!"=="(SysTime(DateTime(-501, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -183_351);
|
|
_assertPred!"=="(SysTime(DateTime(-1000, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -365_607);
|
|
_assertPred!"=="(SysTime(DateTime(-1001, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -365_972);
|
|
_assertPred!"=="(SysTime(DateTime(-1599, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -584_387);
|
|
_assertPred!"=="(SysTime(DateTime(-1600, 12, 31, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -584_388);
|
|
_assertPred!"=="(SysTime(DateTime(-1600, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -584_753);
|
|
_assertPred!"=="(SysTime(DateTime(-1601, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -585_118);
|
|
_assertPred!"=="(SysTime(DateTime(-1900, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -694_325);
|
|
_assertPred!"=="(SysTime(DateTime(-1901, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -694_690);
|
|
_assertPred!"=="(SysTime(DateTime(-1999, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -730_484);
|
|
_assertPred!"=="(SysTime(DateTime(-2000, 12, 31, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -730_485);
|
|
_assertPred!"=="(SysTime(DateTime(-2000, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -730_850);
|
|
_assertPred!"=="(SysTime(DateTime(-2001, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)).dayOfGregorianCal, -731_215);
|
|
|
|
_assertPred!"=="(SysTime(DateTime(-2010, 1, 1, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, -734_502);
|
|
_assertPred!"=="(SysTime(DateTime(-2010, 1, 31, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, -734_472);
|
|
_assertPred!"=="(SysTime(DateTime(-2010, 2, 1, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, -734_471);
|
|
_assertPred!"=="(SysTime(DateTime(-2010, 2, 28, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, -734_444);
|
|
_assertPred!"=="(SysTime(DateTime(-2010, 3, 1, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, -734_443);
|
|
_assertPred!"=="(SysTime(DateTime(-2010, 3, 31, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, -734_413);
|
|
_assertPred!"=="(SysTime(DateTime(-2010, 4, 1, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, -734_412);
|
|
_assertPred!"=="(SysTime(DateTime(-2010, 4, 30, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, -734_383);
|
|
_assertPred!"=="(SysTime(DateTime(-2010, 5, 1, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, -734_382);
|
|
_assertPred!"=="(SysTime(DateTime(-2010, 5, 31, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, -734_352);
|
|
_assertPred!"=="(SysTime(DateTime(-2010, 6, 1, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, -734_351);
|
|
_assertPred!"=="(SysTime(DateTime(-2010, 6, 30, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, -734_322);
|
|
_assertPred!"=="(SysTime(DateTime(-2010, 7, 1, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, -734_321);
|
|
_assertPred!"=="(SysTime(DateTime(-2010, 7, 31, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, -734_291);
|
|
_assertPred!"=="(SysTime(DateTime(-2010, 8, 1, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, -734_290);
|
|
_assertPred!"=="(SysTime(DateTime(-2010, 8, 31, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, -734_260);
|
|
_assertPred!"=="(SysTime(DateTime(-2010, 9, 1, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, -734_259);
|
|
_assertPred!"=="(SysTime(DateTime(-2010, 9, 30, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, -734_230);
|
|
_assertPred!"=="(SysTime(DateTime(-2010, 10, 1, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, -734_229);
|
|
_assertPred!"=="(SysTime(DateTime(-2010, 10, 31, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, -734_199);
|
|
_assertPred!"=="(SysTime(DateTime(-2010, 11, 1, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, -734_198);
|
|
_assertPred!"=="(SysTime(DateTime(-2010, 11, 30, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, -734_169);
|
|
_assertPred!"=="(SysTime(DateTime(-2010, 12, 1, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, -734_168);
|
|
_assertPred!"=="(SysTime(DateTime(-2010, 12, 31, 23, 59, 59), FracSec.from!"msecs"(999)).dayOfGregorianCal, -734_138);
|
|
|
|
_assertPred!"=="(SysTime(DateTime(-2012, 2, 1, 0, 0, 0), FracSec.from!"msecs"(0)).dayOfGregorianCal, -735_202);
|
|
_assertPred!"=="(SysTime(DateTime(-2012, 2, 28, 0, 0, 0), FracSec.from!"msecs"(0)).dayOfGregorianCal, -735_175);
|
|
_assertPred!"=="(SysTime(DateTime(-2012, 2, 29, 0, 0, 0), FracSec.from!"msecs"(0)).dayOfGregorianCal, -735_174);
|
|
_assertPred!"=="(SysTime(DateTime(-2012, 3, 1, 0, 0, 0), FracSec.from!"msecs"(0)).dayOfGregorianCal, -735_173);
|
|
|
|
_assertPred!"=="(SysTime(DateTime(-3760, 9, 7, 0, 0, 0), FracSec.from!"msecs"(0)).dayOfGregorianCal, -1_373_427); //Start of Hebrew Calendar
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, cst.dayOfGregorianCal));
|
|
//static assert(__traits(compiles, ist.dayOfGregorianCal));
|
|
|
|
//Verify Examples.
|
|
assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).dayOfGregorianCal == 1);
|
|
assert(SysTime(DateTime(1, 12, 31, 23, 59, 59)).dayOfGregorianCal == 365);
|
|
assert(SysTime(DateTime(2, 1, 1, 2, 2, 2)).dayOfGregorianCal == 366);
|
|
|
|
assert(SysTime(DateTime(0, 12, 31, 7, 7, 7)).dayOfGregorianCal == 0);
|
|
assert(SysTime(DateTime(0, 1, 1, 19, 30, 0)).dayOfGregorianCal == -365);
|
|
assert(SysTime(DateTime(-1, 12, 31, 4, 7, 0)).dayOfGregorianCal == -366);
|
|
|
|
assert(SysTime(DateTime(2000, 1, 1, 9, 30, 20)).dayOfGregorianCal == 730_120);
|
|
assert(SysTime(DateTime(2010, 12, 31, 15, 45, 50)).dayOfGregorianCal == 734_137);
|
|
}
|
|
}
|
|
|
|
|
|
//Test that the logic for the day of the Gregorian Calendar is consistent
|
|
//between Date and SysTime.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
_assertPred!"=="(Date(1, 1, 1).dayOfGregorianCal, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(1, 1, 2).dayOfGregorianCal, SysTime(DateTime(1, 1, 2, 0, 0, 0), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(1, 2, 1).dayOfGregorianCal, SysTime(DateTime(1, 2, 1, 0, 0, 0), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2, 1, 1).dayOfGregorianCal, SysTime(DateTime(2, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(3, 1, 1).dayOfGregorianCal, SysTime(DateTime(3, 1, 1, 12, 13, 14), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(4, 1, 1).dayOfGregorianCal, SysTime(DateTime(4, 1, 1, 12, 13, 14), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(5, 1, 1).dayOfGregorianCal, SysTime(DateTime(5, 1, 1, 12, 13, 14), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(50, 1, 1).dayOfGregorianCal, SysTime(DateTime(50, 1, 1, 12, 13, 14), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(97, 1, 1).dayOfGregorianCal, SysTime(DateTime(97, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(100, 1, 1).dayOfGregorianCal, SysTime(DateTime(100, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(101, 1, 1).dayOfGregorianCal, SysTime(DateTime(101, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(105, 1, 1).dayOfGregorianCal, SysTime(DateTime(105, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(200, 1, 1).dayOfGregorianCal, SysTime(DateTime(200, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(201, 1, 1).dayOfGregorianCal, SysTime(DateTime(201, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(300, 1, 1).dayOfGregorianCal, SysTime(DateTime(300, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(301, 1, 1).dayOfGregorianCal, SysTime(DateTime(301, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(400, 1, 1).dayOfGregorianCal, SysTime(DateTime(400, 1, 1, 12, 13, 14), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(401, 1, 1).dayOfGregorianCal, SysTime(DateTime(401, 1, 1, 12, 13, 14), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(500, 1, 1).dayOfGregorianCal, SysTime(DateTime(500, 1, 1, 12, 13, 14), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(501, 1, 1).dayOfGregorianCal, SysTime(DateTime(501, 1, 1, 12, 13, 14), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(1000, 1, 1).dayOfGregorianCal, SysTime(DateTime(1000, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(1001, 1, 1).dayOfGregorianCal, SysTime(DateTime(1001, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(1600, 1, 1).dayOfGregorianCal, SysTime(DateTime(1600, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(1601, 1, 1).dayOfGregorianCal, SysTime(DateTime(1601, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(1900, 1, 1).dayOfGregorianCal, SysTime(DateTime(1900, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(1901, 1, 1).dayOfGregorianCal, SysTime(DateTime(1901, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(1945, 11, 12).dayOfGregorianCal, SysTime(DateTime(1945, 11, 12, 0, 0, 0), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(1999, 1, 1).dayOfGregorianCal, SysTime(DateTime(1999, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(1999, 7, 6).dayOfGregorianCal, SysTime(DateTime(1999, 7, 6, 12, 13, 14), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2000, 1, 1).dayOfGregorianCal, SysTime(DateTime(2000, 1, 1, 12, 13, 14), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2001, 1, 1).dayOfGregorianCal, SysTime(DateTime(2001, 1, 1, 12, 13, 14), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
|
|
_assertPred!"=="(Date(2010, 1, 1).dayOfGregorianCal, SysTime(DateTime(2010, 1, 1, 12, 13, 14), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2010, 1, 31).dayOfGregorianCal, SysTime(DateTime(2010, 1, 31, 23, 0, 0), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2010, 2, 1).dayOfGregorianCal, SysTime(DateTime(2010, 2, 1, 23, 59, 59), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2010, 2, 28).dayOfGregorianCal, SysTime(DateTime(2010, 2, 28, 23, 59, 59), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2010, 3, 1).dayOfGregorianCal, SysTime(DateTime(2010, 3, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2010, 3, 31).dayOfGregorianCal, SysTime(DateTime(2010, 3, 31, 0, 0, 0), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2010, 4, 1).dayOfGregorianCal, SysTime(DateTime(2010, 4, 1, 0, 0, 0), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2010, 4, 30).dayOfGregorianCal, SysTime(DateTime(2010, 4, 30, 0, 0, 0), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2010, 5, 1).dayOfGregorianCal, SysTime(DateTime(2010, 5, 1, 0, 0, 0), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2010, 5, 31).dayOfGregorianCal, SysTime(DateTime(2010, 5, 31, 12, 13, 14), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2010, 6, 1).dayOfGregorianCal, SysTime(DateTime(2010, 6, 1, 12, 13, 14), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2010, 6, 30).dayOfGregorianCal, SysTime(DateTime(2010, 6, 30, 12, 13, 14), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2010, 7, 1).dayOfGregorianCal, SysTime(DateTime(2010, 7, 1, 12, 13, 14), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2010, 7, 31).dayOfGregorianCal, SysTime(DateTime(2010, 7, 31, 23, 59, 59), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2010, 8, 1).dayOfGregorianCal, SysTime(DateTime(2010, 8, 1, 23, 59, 59), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2010, 8, 31).dayOfGregorianCal, SysTime(DateTime(2010, 8, 31, 23, 59, 59), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2010, 9, 1).dayOfGregorianCal, SysTime(DateTime(2010, 9, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2010, 9, 30).dayOfGregorianCal, SysTime(DateTime(2010, 9, 30, 12, 0, 0), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2010, 10, 1).dayOfGregorianCal, SysTime(DateTime(2010, 10, 1, 0, 12, 0), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2010, 10, 31).dayOfGregorianCal, SysTime(DateTime(2010, 10, 31, 0, 0, 12), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2010, 11, 1).dayOfGregorianCal, SysTime(DateTime(2010, 11, 1, 23, 0, 0), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2010, 11, 30).dayOfGregorianCal, SysTime(DateTime(2010, 11, 30, 0, 59, 0), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2010, 12, 1).dayOfGregorianCal, SysTime(DateTime(2010, 12, 1, 0, 0, 59), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2010, 12, 31).dayOfGregorianCal, SysTime(DateTime(2010, 12, 31, 0, 59, 59), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
|
|
_assertPred!"=="(Date(2012, 2, 1).dayOfGregorianCal, SysTime(DateTime(2012, 2, 1, 23, 0, 59), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2012, 2, 28).dayOfGregorianCal, SysTime(DateTime(2012, 2, 28, 23, 59, 0), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2012, 2, 29).dayOfGregorianCal, SysTime(DateTime(2012, 2, 29, 7, 7, 7), FracSec.from!"hnsecs"(7)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(2012, 3, 1).dayOfGregorianCal, SysTime(DateTime(2012, 3, 1, 7, 7, 7), FracSec.from!"hnsecs"(7)).dayOfGregorianCal);
|
|
|
|
//Test B.C.
|
|
_assertPred!"=="(Date(0, 12, 31).dayOfGregorianCal, SysTime(DateTime(0, 12, 31, 0, 0, 0), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(0, 12, 30).dayOfGregorianCal, SysTime(DateTime(0, 12, 30, 0, 0, 0), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(0, 12, 1).dayOfGregorianCal, SysTime(DateTime(0, 12, 1, 0, 0, 0), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(0, 11, 30).dayOfGregorianCal, SysTime(DateTime(0, 11, 30, 0, 0, 0), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
|
|
_assertPred!"=="(Date(-1, 12, 31).dayOfGregorianCal, SysTime(DateTime(-1, 12, 31, 12, 13, 14), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-1, 12, 30).dayOfGregorianCal, SysTime(DateTime(-1, 12, 30, 12, 13, 14), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-1, 1, 1).dayOfGregorianCal, SysTime(DateTime(-1, 1, 1, 12, 13, 14), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2, 12, 31).dayOfGregorianCal, SysTime(DateTime(-2, 12, 31, 12, 13, 14), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2, 1, 1).dayOfGregorianCal, SysTime(DateTime(-2, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-3, 12, 31).dayOfGregorianCal, SysTime(DateTime(-3, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-3, 1, 1).dayOfGregorianCal, SysTime(DateTime(-3, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-4, 12, 31).dayOfGregorianCal, SysTime(DateTime(-4, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-4, 1, 1).dayOfGregorianCal, SysTime(DateTime(-4, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-5, 12, 31).dayOfGregorianCal, SysTime(DateTime(-5, 12, 31, 0, 0, 0), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-5, 1, 1).dayOfGregorianCal, SysTime(DateTime(-5, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-9, 1, 1).dayOfGregorianCal, SysTime(DateTime(-9, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
|
|
_assertPred!"=="(Date(-49, 1, 1).dayOfGregorianCal, SysTime(DateTime(-49, 1, 1, 12, 13, 14), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-50, 1, 1).dayOfGregorianCal, SysTime(DateTime(-50, 1, 1, 12, 13, 14), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-97, 1, 1).dayOfGregorianCal, SysTime(DateTime(-97, 1, 1, 12, 13, 14), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-99, 12, 31).dayOfGregorianCal, SysTime(DateTime(-99, 12, 31, 12, 13, 14), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-99, 1, 1).dayOfGregorianCal, SysTime(DateTime(-99, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-100, 1, 1).dayOfGregorianCal, SysTime(DateTime(-100, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-101, 1, 1).dayOfGregorianCal, SysTime(DateTime(-101, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-105, 1, 1).dayOfGregorianCal, SysTime(DateTime(-105, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-200, 1, 1).dayOfGregorianCal, SysTime(DateTime(-200, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-201, 1, 1).dayOfGregorianCal, SysTime(DateTime(-201, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-300, 1, 1).dayOfGregorianCal, SysTime(DateTime(-300, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-301, 1, 1).dayOfGregorianCal, SysTime(DateTime(-301, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-400, 12, 31).dayOfGregorianCal, SysTime(DateTime(-400, 12, 31, 12, 13, 14), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-400, 1, 1).dayOfGregorianCal, SysTime(DateTime(-400, 1, 1, 12, 13, 14), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-401, 1, 1).dayOfGregorianCal, SysTime(DateTime(-401, 1, 1, 12, 13, 14), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-499, 1, 1).dayOfGregorianCal, SysTime(DateTime(-499, 1, 1, 12, 13, 14), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-500, 1, 1).dayOfGregorianCal, SysTime(DateTime(-500, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-501, 1, 1).dayOfGregorianCal, SysTime(DateTime(-501, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-1000, 1, 1).dayOfGregorianCal, SysTime(DateTime(-1000, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-1001, 1, 1).dayOfGregorianCal, SysTime(DateTime(-1001, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-1599, 1, 1).dayOfGregorianCal, SysTime(DateTime(-1599, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-1600, 12, 31).dayOfGregorianCal, SysTime(DateTime(-1600, 12, 31, 0, 0, 0), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-1600, 1, 1).dayOfGregorianCal, SysTime(DateTime(-1600, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-1601, 1, 1).dayOfGregorianCal, SysTime(DateTime(-1601, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-1900, 1, 1).dayOfGregorianCal, SysTime(DateTime(-1900, 1, 1, 12, 13, 14), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-1901, 1, 1).dayOfGregorianCal, SysTime(DateTime(-1901, 1, 1, 12, 13, 14), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-1999, 1, 1).dayOfGregorianCal, SysTime(DateTime(-1999, 1, 1, 12, 13, 14), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-1999, 7, 6).dayOfGregorianCal, SysTime(DateTime(-1999, 7, 6, 12, 13, 14), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2000, 12, 31).dayOfGregorianCal, SysTime(DateTime(-2000, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2000, 1, 1).dayOfGregorianCal, SysTime(DateTime(-2000, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2001, 1, 1).dayOfGregorianCal, SysTime(DateTime(-2001, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
|
|
_assertPred!"=="(Date(-2010, 1, 1).dayOfGregorianCal, SysTime(DateTime(-2010, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2010, 1, 31).dayOfGregorianCal, SysTime(DateTime(-2010, 1, 31, 0, 0, 0), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2010, 2, 1).dayOfGregorianCal, SysTime(DateTime(-2010, 2, 1, 0, 0, 0), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2010, 2, 28).dayOfGregorianCal, SysTime(DateTime(-2010, 2, 28, 0, 0, 0), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2010, 3, 1).dayOfGregorianCal, SysTime(DateTime(-2010, 3, 1, 0, 0, 0), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2010, 3, 31).dayOfGregorianCal, SysTime(DateTime(-2010, 3, 31, 12, 13, 14), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2010, 4, 1).dayOfGregorianCal, SysTime(DateTime(-2010, 4, 1, 12, 13, 14), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2010, 4, 30).dayOfGregorianCal, SysTime(DateTime(-2010, 4, 30, 12, 13, 14), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2010, 5, 1).dayOfGregorianCal, SysTime(DateTime(-2010, 5, 1, 12, 13, 14), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2010, 5, 31).dayOfGregorianCal, SysTime(DateTime(-2010, 5, 31, 23, 59, 59), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2010, 6, 1).dayOfGregorianCal, SysTime(DateTime(-2010, 6, 1, 23, 59, 59), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2010, 6, 30).dayOfGregorianCal, SysTime(DateTime(-2010, 6, 30, 23, 59, 59), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2010, 7, 1).dayOfGregorianCal, SysTime(DateTime(-2010, 7, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2010, 7, 31).dayOfGregorianCal, SysTime(DateTime(-2010, 7, 31, 0, 0, 0), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2010, 8, 1).dayOfGregorianCal, SysTime(DateTime(-2010, 8, 1, 0, 0, 0), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2010, 8, 31).dayOfGregorianCal, SysTime(DateTime(-2010, 8, 31, 0, 0, 0), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2010, 9, 1).dayOfGregorianCal, SysTime(DateTime(-2010, 9, 1, 0, 0, 0), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2010, 9, 30).dayOfGregorianCal, SysTime(DateTime(-2010, 9, 30, 12, 0, 0), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2010, 10, 1).dayOfGregorianCal, SysTime(DateTime(-2010, 10, 1, 0, 12, 0), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2010, 10, 31).dayOfGregorianCal, SysTime(DateTime(-2010, 10, 31, 0, 0, 12), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2010, 11, 1).dayOfGregorianCal, SysTime(DateTime(-2010, 11, 1, 23, 0, 0), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2010, 11, 30).dayOfGregorianCal, SysTime(DateTime(-2010, 11, 30, 0, 59, 0), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2010, 12, 1).dayOfGregorianCal, SysTime(DateTime(-2010, 12, 1, 0, 0, 59), FracSec.from!"hnsecs"(500)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2010, 12, 31).dayOfGregorianCal, SysTime(DateTime(-2010, 12, 31, 0, 59, 59), FracSec.from!"hnsecs"(50_000)).dayOfGregorianCal);
|
|
|
|
_assertPred!"=="(Date(-2012, 2, 1).dayOfGregorianCal, SysTime(DateTime(-2012, 2, 1, 23, 0, 59), FracSec.from!"hnsecs"(9_999_999)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2012, 2, 28).dayOfGregorianCal, SysTime(DateTime(-2012, 2, 28, 23, 59, 0), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2012, 2, 29).dayOfGregorianCal, SysTime(DateTime(-2012, 2, 29, 7, 7, 7), FracSec.from!"hnsecs"(7)).dayOfGregorianCal);
|
|
_assertPred!"=="(Date(-2012, 3, 1).dayOfGregorianCal, SysTime(DateTime(-2012, 3, 1, 7, 7, 7), FracSec.from!"hnsecs"(7)).dayOfGregorianCal);
|
|
|
|
_assertPred!"=="(Date(-3760, 9, 7).dayOfGregorianCal, SysTime(DateTime(-3760, 9, 7, 0, 0, 0), FracSec.from!"hnsecs"(0)).dayOfGregorianCal);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
The Xth day of the Gregorian Calendar that this $(D SysTime) is on.
|
|
Setting this property does not affect the time portion of $(D SysTime).
|
|
|
|
Params:
|
|
days = The day of the Gregorian Calendar to set this $(D SysTime)
|
|
to.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto st = SysTime(DateTime(0, 0, 0, 12, 0, 0));
|
|
st.dayOfGregorianCal = 1;
|
|
assert(st == SysTime(DateTime(1, 1, 1, 12, 0, 0)));
|
|
|
|
st.dayOfGregorianCal = 365;
|
|
assert(st == SysTime(DateTime(1, 12, 31, 12, 0, 0)));
|
|
|
|
st.dayOfGregorianCal = 366;
|
|
assert(st == SysTime(DateTime(2, 1, 1, 12, 0, 0)));
|
|
|
|
st.dayOfGregorianCal = 0;
|
|
assert(st == SysTime(DateTime(0, 12, 31, 12, 0, 0)));
|
|
|
|
st.dayOfGregorianCal = -365;
|
|
assert(st == SysTime(DateTime(-0, 1, 1, 12, 0, 0)));
|
|
|
|
st.dayOfGregorianCal = -366;
|
|
assert(st == SysTime(DateTime(-1, 12, 31, 12, 0, 0)));
|
|
|
|
st.dayOfGregorianCal = 730_120;
|
|
assert(st == SysTime(DateTime(2000, 1, 1, 12, 0, 0)));
|
|
|
|
st.dayOfGregorianCal = 734_137;
|
|
assert(st == SysTime(DateTime(2010, 12, 31, 12, 0, 0)));
|
|
--------------------
|
|
+/
|
|
@property void dayOfGregorianCal(int days) nothrow
|
|
{
|
|
auto hnsecs = adjTime;
|
|
hnsecs = removeUnitsFromHNSecs!"days"(hnsecs);
|
|
|
|
if(hnsecs < 0)
|
|
hnsecs += convert!("hours", "hnsecs")(24);
|
|
|
|
if(--days < 0)
|
|
{
|
|
hnsecs -= convert!("hours", "hnsecs")(24);
|
|
++days;
|
|
}
|
|
|
|
immutable newDaysHNSecs = convert!("days", "hnsecs")(days);
|
|
|
|
adjTime = newDaysHNSecs + hnsecs;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
void testST(SysTime orig, int day, in SysTime expected, size_t line = __LINE__)
|
|
{
|
|
orig.dayOfGregorianCal = day;
|
|
_assertPred!"=="(orig, expected, "", __FILE__, line);
|
|
}
|
|
|
|
//Test A.D.
|
|
testST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
testST(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(1)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(1)));
|
|
testST(SysTime(DateTime(1, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 1, SysTime(DateTime(1, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
|
|
//Test B.C.
|
|
testST(SysTime(DateTime(0, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)), 0, SysTime(DateTime(0, 12, 31, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
testST(SysTime(DateTime(0, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
testST(SysTime(DateTime(0, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(1)), 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(1)));
|
|
testST(SysTime(DateTime(0, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(0)), 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(0)));
|
|
|
|
//Test Both.
|
|
testST(SysTime(DateTime(-512, 7, 20, 0, 0, 0), FracSec.from!"hnsecs"(0)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
testST(SysTime(DateTime(-513, 6, 6, 0, 0, 0), FracSec.from!"hnsecs"(1)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(1)));
|
|
testST(SysTime(DateTime(-511, 5, 7, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 1, SysTime(DateTime(1, 1, 1, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
|
|
testST(SysTime(DateTime(1607, 4, 8, 0, 0, 0), FracSec.from!"hnsecs"(0)), 0, SysTime(DateTime(0, 12, 31, 0, 0, 0), FracSec.from!"hnsecs"(0)));
|
|
testST(SysTime(DateTime(1500, 3, 9, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)), 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
testST(SysTime(DateTime(999, 2, 10, 23, 59, 59), FracSec.from!"hnsecs"(1)), 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(1)));
|
|
testST(SysTime(DateTime(2007, 12, 11, 23, 59, 59), FracSec.from!"hnsecs"(0)), 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(0)));
|
|
|
|
|
|
auto sysTime = SysTime(DateTime(1, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212));
|
|
|
|
void testST2(int day, in SysTime expected, size_t line = __LINE__)
|
|
{
|
|
sysTime.dayOfGregorianCal = day;
|
|
_assertPred!"=="(sysTime, expected, "", __FILE__, line);
|
|
}
|
|
|
|
//Test A.D.
|
|
testST2(1, SysTime(DateTime(1, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(2, SysTime(DateTime(1, 1, 2, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(32, SysTime(DateTime(1, 2, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(366, SysTime(DateTime(2, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(731, SysTime(DateTime(3, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(1096, SysTime(DateTime(4, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(1462, SysTime(DateTime(5, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(17_898, SysTime(DateTime(50, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(35_065, SysTime(DateTime(97, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(36_160, SysTime(DateTime(100, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(36_525, SysTime(DateTime(101, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(37_986, SysTime(DateTime(105, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(72_684, SysTime(DateTime(200, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(73_049, SysTime(DateTime(201, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(109_208, SysTime(DateTime(300, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(109_573, SysTime(DateTime(301, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(145_732, SysTime(DateTime(400, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(146_098, SysTime(DateTime(401, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(182_257, SysTime(DateTime(500, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(182_622, SysTime(DateTime(501, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(364_878, SysTime(DateTime(1000, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(365_243, SysTime(DateTime(1001, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(584_023, SysTime(DateTime(1600, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(584_389, SysTime(DateTime(1601, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(693_596, SysTime(DateTime(1900, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(693_961, SysTime(DateTime(1901, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(729_755, SysTime(DateTime(1999, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(730_120, SysTime(DateTime(2000, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(730_486, SysTime(DateTime(2001, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
|
|
testST2(733_773, SysTime(DateTime(2010, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(733_803, SysTime(DateTime(2010, 1, 31, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(733_804, SysTime(DateTime(2010, 2, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(733_831, SysTime(DateTime(2010, 2, 28, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(733_832, SysTime(DateTime(2010, 3, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(733_862, SysTime(DateTime(2010, 3, 31, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(733_863, SysTime(DateTime(2010, 4, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(733_892, SysTime(DateTime(2010, 4, 30, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(733_893, SysTime(DateTime(2010, 5, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(733_923, SysTime(DateTime(2010, 5, 31, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(733_924, SysTime(DateTime(2010, 6, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(733_953, SysTime(DateTime(2010, 6, 30, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(733_954, SysTime(DateTime(2010, 7, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(733_984, SysTime(DateTime(2010, 7, 31, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(733_985, SysTime(DateTime(2010, 8, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(734_015, SysTime(DateTime(2010, 8, 31, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(734_016, SysTime(DateTime(2010, 9, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(734_045, SysTime(DateTime(2010, 9, 30, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(734_046, SysTime(DateTime(2010, 10, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(734_076, SysTime(DateTime(2010, 10, 31, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(734_077, SysTime(DateTime(2010, 11, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(734_106, SysTime(DateTime(2010, 11, 30, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(734_107, SysTime(DateTime(2010, 12, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(734_137, SysTime(DateTime(2010, 12, 31, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
|
|
testST2(734_534, SysTime(DateTime(2012, 2, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(734_561, SysTime(DateTime(2012, 2, 28, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(734_562, SysTime(DateTime(2012, 2, 29, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(734_563, SysTime(DateTime(2012, 3, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
|
|
testST2(734_534, SysTime(DateTime(2012, 2, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
|
|
testST2(734_561, SysTime(DateTime(2012, 2, 28, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(734_562, SysTime(DateTime(2012, 2, 29, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(734_563, SysTime(DateTime(2012, 3, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
|
|
//Test B.C.
|
|
testST2(0, SysTime(DateTime(0, 12, 31, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-1, SysTime(DateTime(0, 12, 30, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-30, SysTime(DateTime(0, 12, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-31, SysTime(DateTime(0, 11, 30, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
|
|
testST2(-366, SysTime(DateTime(-1, 12, 31, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-367, SysTime(DateTime(-1, 12, 30, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-730, SysTime(DateTime(-1, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-731, SysTime(DateTime(-2, 12, 31, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-1095, SysTime(DateTime(-2, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-1096, SysTime(DateTime(-3, 12, 31, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-1460, SysTime(DateTime(-3, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-1461, SysTime(DateTime(-4, 12, 31, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-1826, SysTime(DateTime(-4, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-1827, SysTime(DateTime(-5, 12, 31, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-2191, SysTime(DateTime(-5, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-3652, SysTime(DateTime(-9, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
|
|
testST2(-18_262, SysTime(DateTime(-49, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-18_627, SysTime(DateTime(-50, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-35_794, SysTime(DateTime(-97, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-36_160, SysTime(DateTime(-99, 12, 31, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-36_524, SysTime(DateTime(-99, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-36_889, SysTime(DateTime(-100, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-37_254, SysTime(DateTime(-101, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-38_715, SysTime(DateTime(-105, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-73_413, SysTime(DateTime(-200, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-73_778, SysTime(DateTime(-201, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-109_937, SysTime(DateTime(-300, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-110_302, SysTime(DateTime(-301, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-146_097, SysTime(DateTime(-400, 12, 31, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-146_462, SysTime(DateTime(-400, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-146_827, SysTime(DateTime(-401, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-182_621, SysTime(DateTime(-499, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-182_986, SysTime(DateTime(-500, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-183_351, SysTime(DateTime(-501, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-365_607, SysTime(DateTime(-1000, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-365_972, SysTime(DateTime(-1001, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-584_387, SysTime(DateTime(-1599, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-584_388, SysTime(DateTime(-1600, 12, 31, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-584_753, SysTime(DateTime(-1600, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-585_118, SysTime(DateTime(-1601, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-694_325, SysTime(DateTime(-1900, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-694_690, SysTime(DateTime(-1901, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-730_484, SysTime(DateTime(-1999, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-730_485, SysTime(DateTime(-2000, 12, 31, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-730_850, SysTime(DateTime(-2000, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-731_215, SysTime(DateTime(-2001, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
|
|
testST2(-734_502, SysTime(DateTime(-2010, 1, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-734_472, SysTime(DateTime(-2010, 1, 31, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-734_471, SysTime(DateTime(-2010, 2, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-734_444, SysTime(DateTime(-2010, 2, 28, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-734_443, SysTime(DateTime(-2010, 3, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-734_413, SysTime(DateTime(-2010, 3, 31, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-734_412, SysTime(DateTime(-2010, 4, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-734_383, SysTime(DateTime(-2010, 4, 30, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-734_382, SysTime(DateTime(-2010, 5, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-734_352, SysTime(DateTime(-2010, 5, 31, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-734_351, SysTime(DateTime(-2010, 6, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-734_322, SysTime(DateTime(-2010, 6, 30, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-734_321, SysTime(DateTime(-2010, 7, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-734_291, SysTime(DateTime(-2010, 7, 31, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-734_290, SysTime(DateTime(-2010, 8, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-734_260, SysTime(DateTime(-2010, 8, 31, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-734_259, SysTime(DateTime(-2010, 9, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-734_230, SysTime(DateTime(-2010, 9, 30, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-734_229, SysTime(DateTime(-2010, 10, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-734_199, SysTime(DateTime(-2010, 10, 31, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-734_198, SysTime(DateTime(-2010, 11, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-734_169, SysTime(DateTime(-2010, 11, 30, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-734_168, SysTime(DateTime(-2010, 12, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-734_138, SysTime(DateTime(-2010, 12, 31, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
|
|
testST2(-735_202, SysTime(DateTime(-2012, 2, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-735_175, SysTime(DateTime(-2012, 2, 28, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-735_174, SysTime(DateTime(-2012, 2, 29, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
testST2(-735_173, SysTime(DateTime(-2012, 3, 1, 12, 2, 9), FracSec.from!"msecs"(212)));
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(!__traits(compiles, cst.dayOfGregorianCal = 7));
|
|
//static assert(!__traits(compiles, ist.dayOfGregorianCal = 7));
|
|
|
|
//Verify Examples.
|
|
auto st = SysTime(DateTime(0, 1, 1, 12, 0, 0));
|
|
st.dayOfGregorianCal = 1;
|
|
assert(st == SysTime(DateTime(1, 1, 1, 12, 0, 0)));
|
|
|
|
st.dayOfGregorianCal = 365;
|
|
assert(st == SysTime(DateTime(1, 12, 31, 12, 0, 0)));
|
|
|
|
st.dayOfGregorianCal = 366;
|
|
assert(st == SysTime(DateTime(2, 1, 1, 12, 0, 0)));
|
|
|
|
st.dayOfGregorianCal = 0;
|
|
assert(st == SysTime(DateTime(0, 12, 31, 12, 0, 0)));
|
|
|
|
st.dayOfGregorianCal = -365;
|
|
assert(st == SysTime(DateTime(-0, 1, 1, 12, 0, 0)));
|
|
|
|
st.dayOfGregorianCal = -366;
|
|
assert(st == SysTime(DateTime(-1, 12, 31, 12, 0, 0)));
|
|
|
|
st.dayOfGregorianCal = 730_120;
|
|
assert(st == SysTime(DateTime(2000, 1, 1, 12, 0, 0)));
|
|
|
|
st.dayOfGregorianCal = 734_137;
|
|
assert(st == SysTime(DateTime(2010, 12, 31, 12, 0, 0)));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
The ISO 8601 week of the year that this $(D SysTime) is in.
|
|
|
|
See_Also:
|
|
$(WEB en.wikipedia.org/wiki/ISO_week_date, ISO Week Date).
|
|
+/
|
|
@property ubyte isoWeek() const nothrow
|
|
{
|
|
return (cast(Date)this).isoWeek;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, st.isoWeek));
|
|
static assert(__traits(compiles, cst.isoWeek));
|
|
//static assert(__traits(compiles, ist.isoWeek));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
$(D SysTime) for the last day in the month that this Date is in.
|
|
The time portion of endOfMonth is always 23:59:59.9999999.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(SysTime(DateTime(1999, 1, 6, 0, 0, 0)).endOfMonth ==
|
|
SysTime(DateTime(1999, 1, 31, 23, 59, 59),
|
|
FracSec.from!"hnsecs"(9_999_999)));
|
|
|
|
assert(SysTime(DateTime(1999, 2, 7, 19, 30, 0),
|
|
FracSec.from!"msecs"(24)).endOfMonth ==
|
|
SysTime(DateTime(1999, 2, 28, 23, 59, 59),
|
|
FracSec.from!"hnsecs"(9_999_999)));
|
|
|
|
assert(SysTime(DateTime(2000, 2, 7, 5, 12, 27),
|
|
FracSec.from!"usecs"(5203)).endOfMonth ==
|
|
SysTime(DateTime(2000, 2, 29, 23, 59, 59),
|
|
FracSec.from!"hnsecs"(9_999_999)));
|
|
|
|
assert(SysTime(DateTime(2000, 6, 4, 12, 22, 9),
|
|
FracSec.from!"hnsecs"(12345)).endOfMonth ==
|
|
SysTime(DateTime(2000, 6, 30, 23, 59, 59),
|
|
FracSec.from!"hnsecs"(9_999_999)));
|
|
--------------------
|
|
+/
|
|
@property SysTime endOfMonth() const nothrow
|
|
{
|
|
immutable hnsecs = adjTime;
|
|
immutable days = getUnitsFromHNSecs!"days"(hnsecs);
|
|
|
|
auto date = Date(cast(int)days + 1).endOfMonth;
|
|
auto newDays = date.dayOfGregorianCal - 1;
|
|
long theTimeHNSecs;
|
|
|
|
if(newDays < 0)
|
|
{
|
|
theTimeHNSecs = -1;
|
|
++newDays;
|
|
}
|
|
else
|
|
theTimeHNSecs = convert!("days", "hnsecs")(1) - 1;
|
|
|
|
immutable newDaysHNSecs = convert!("days", "hnsecs")(newDays);
|
|
|
|
auto retval = SysTime(this._stdTime, this._timezone.get);
|
|
retval.adjTime = newDaysHNSecs + theTimeHNSecs;
|
|
|
|
return retval;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
_assertPred!"=="(SysTime(Date(1999, 1, 1)).endOfMonth, SysTime(DateTime(1999, 1, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
_assertPred!"=="(SysTime(Date(1999, 2, 1)).endOfMonth, SysTime(DateTime(1999, 2, 28, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
_assertPred!"=="(SysTime(Date(2000, 2, 1)).endOfMonth, SysTime(DateTime(2000, 2, 29, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
_assertPred!"=="(SysTime(Date(1999, 3, 1)).endOfMonth, SysTime(DateTime(1999, 3, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
_assertPred!"=="(SysTime(Date(1999, 4, 1)).endOfMonth, SysTime(DateTime(1999, 4, 30, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
_assertPred!"=="(SysTime(Date(1999, 5, 1)).endOfMonth, SysTime(DateTime(1999, 5, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
_assertPred!"=="(SysTime(Date(1999, 6, 1)).endOfMonth, SysTime(DateTime(1999, 6, 30, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
_assertPred!"=="(SysTime(Date(1999, 7, 1)).endOfMonth, SysTime(DateTime(1999, 7, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
_assertPred!"=="(SysTime(Date(1999, 8, 1)).endOfMonth, SysTime(DateTime(1999, 8, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
_assertPred!"=="(SysTime(Date(1999, 9, 1)).endOfMonth, SysTime(DateTime(1999, 9, 30, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
_assertPred!"=="(SysTime(Date(1999, 10, 1)).endOfMonth, SysTime(DateTime(1999, 10, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
_assertPred!"=="(SysTime(Date(1999, 11, 1)).endOfMonth, SysTime(DateTime(1999, 11, 30, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
_assertPred!"=="(SysTime(Date(1999, 12, 1)).endOfMonth, SysTime(DateTime(1999, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
|
|
//Test B.C.
|
|
_assertPred!"=="(SysTime(Date(-1999, 1, 1)).endOfMonth, SysTime(DateTime(-1999, 1, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
_assertPred!"=="(SysTime(Date(-1999, 2, 1)).endOfMonth, SysTime(DateTime(-1999, 2, 28, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
_assertPred!"=="(SysTime(Date(-2000, 2, 1)).endOfMonth, SysTime(DateTime(-2000, 2, 29, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
_assertPred!"=="(SysTime(Date(-1999, 3, 1)).endOfMonth, SysTime(DateTime(-1999, 3, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
_assertPred!"=="(SysTime(Date(-1999, 4, 1)).endOfMonth, SysTime(DateTime(-1999, 4, 30, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
_assertPred!"=="(SysTime(Date(-1999, 5, 1)).endOfMonth, SysTime(DateTime(-1999, 5, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
_assertPred!"=="(SysTime(Date(-1999, 6, 1)).endOfMonth, SysTime(DateTime(-1999, 6, 30, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
_assertPred!"=="(SysTime(Date(-1999, 7, 1)).endOfMonth, SysTime(DateTime(-1999, 7, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
_assertPred!"=="(SysTime(Date(-1999, 8, 1)).endOfMonth, SysTime(DateTime(-1999, 8, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
_assertPred!"=="(SysTime(Date(-1999, 9, 1)).endOfMonth, SysTime(DateTime(-1999, 9, 30, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
_assertPred!"=="(SysTime(Date(-1999, 10, 1)).endOfMonth, SysTime(DateTime(-1999, 10, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
_assertPred!"=="(SysTime(Date(-1999, 11, 1)).endOfMonth, SysTime(DateTime(-1999, 11, 30, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
_assertPred!"=="(SysTime(Date(-1999, 12, 1)).endOfMonth, SysTime(DateTime(-1999, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, cst.endOfMonth));
|
|
//static assert(__traits(compiles, ist.endOfMonth));
|
|
|
|
//Verify Examples.
|
|
assert(SysTime(DateTime(1999, 1, 6, 0, 0, 0)).endOfMonth == SysTime(DateTime(1999, 1, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
assert(SysTime(DateTime(1999, 2, 7, 19, 30, 0), FracSec.from!"msecs"(24)).endOfMonth == SysTime(DateTime(1999, 2, 28, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
assert(SysTime(DateTime(2000, 2, 7, 5, 12, 27), FracSec.from!"usecs"(5203)).endOfMonth == SysTime(DateTime(2000, 2, 29, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
assert(SysTime(DateTime(2000, 6, 4, 12, 22, 9), FracSec.from!"hnsecs"(12345)).endOfMonth == SysTime(DateTime(2000, 6, 30, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999)));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
The last day in the month that this $(D SysTime) is in.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(SysTime(DateTime(1999, 1, 6, 0, 0, 0)).daysInMonth == 31);
|
|
assert(SysTime(DateTime(1999, 2, 7, 19, 30, 0)).daysInMonth == 28);
|
|
assert(SysTime(DateTime(2000, 2, 7, 5, 12, 27)).daysInMonth == 29);
|
|
assert(SysTime(DateTime(2000, 6, 4, 12, 22, 9)).daysInMonth == 30);
|
|
--------------------
|
|
+/
|
|
@property ubyte daysInMonth() const nothrow
|
|
{
|
|
return Date(dayOfGregorianCal).daysInMonth;
|
|
}
|
|
|
|
/++
|
|
$(RED Scheduled for deprecation in January 2012.
|
|
Please use daysInMonth instead.)
|
|
+/
|
|
alias daysInMonth endofMonthDay;
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
_assertPred!"=="(SysTime(DateTime(1999, 1, 1, 12, 1, 13)).daysInMonth, 31);
|
|
_assertPred!"=="(SysTime(DateTime(1999, 2, 1, 17, 13, 12)).daysInMonth, 28);
|
|
_assertPred!"=="(SysTime(DateTime(2000, 2, 1, 13, 2, 12)).daysInMonth, 29);
|
|
_assertPred!"=="(SysTime(DateTime(1999, 3, 1, 12, 13, 12)).daysInMonth, 31);
|
|
_assertPred!"=="(SysTime(DateTime(1999, 4, 1, 12, 6, 13)).daysInMonth, 30);
|
|
_assertPred!"=="(SysTime(DateTime(1999, 5, 1, 15, 13, 12)).daysInMonth, 31);
|
|
_assertPred!"=="(SysTime(DateTime(1999, 6, 1, 13, 7, 12)).daysInMonth, 30);
|
|
_assertPred!"=="(SysTime(DateTime(1999, 7, 1, 12, 13, 17)).daysInMonth, 31);
|
|
_assertPred!"=="(SysTime(DateTime(1999, 8, 1, 12, 3, 13)).daysInMonth, 31);
|
|
_assertPred!"=="(SysTime(DateTime(1999, 9, 1, 12, 13, 12)).daysInMonth, 30);
|
|
_assertPred!"=="(SysTime(DateTime(1999, 10, 1, 13, 19, 12)).daysInMonth, 31);
|
|
_assertPred!"=="(SysTime(DateTime(1999, 11, 1, 12, 13, 17)).daysInMonth, 30);
|
|
_assertPred!"=="(SysTime(DateTime(1999, 12, 1, 12, 52, 13)).daysInMonth, 31);
|
|
|
|
//Test B.C.
|
|
_assertPred!"=="(SysTime(DateTime(-1999, 1, 1, 12, 1, 13)).daysInMonth, 31);
|
|
_assertPred!"=="(SysTime(DateTime(-1999, 2, 1, 7, 13, 12)).daysInMonth, 28);
|
|
_assertPred!"=="(SysTime(DateTime(-2000, 2, 1, 13, 2, 12)).daysInMonth, 29);
|
|
_assertPred!"=="(SysTime(DateTime(-1999, 3, 1, 12, 13, 12)).daysInMonth, 31);
|
|
_assertPred!"=="(SysTime(DateTime(-1999, 4, 1, 12, 6, 13)).daysInMonth, 30);
|
|
_assertPred!"=="(SysTime(DateTime(-1999, 5, 1, 5, 13, 12)).daysInMonth, 31);
|
|
_assertPred!"=="(SysTime(DateTime(-1999, 6, 1, 13, 7, 12)).daysInMonth, 30);
|
|
_assertPred!"=="(SysTime(DateTime(-1999, 7, 1, 12, 13, 17)).daysInMonth, 31);
|
|
_assertPred!"=="(SysTime(DateTime(-1999, 8, 1, 12, 3, 13)).daysInMonth, 31);
|
|
_assertPred!"=="(SysTime(DateTime(-1999, 9, 1, 12, 13, 12)).daysInMonth, 30);
|
|
_assertPred!"=="(SysTime(DateTime(-1999, 10, 1, 13, 19, 12)).daysInMonth, 31);
|
|
_assertPred!"=="(SysTime(DateTime(-1999, 11, 1, 12, 13, 17)).daysInMonth, 30);
|
|
_assertPred!"=="(SysTime(DateTime(-1999, 12, 1, 12, 52, 13)).daysInMonth, 31);
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, cst.daysInMonth));
|
|
//static assert(__traits(compiles, ist.daysInMonth));
|
|
|
|
//Verify Examples.
|
|
assert(SysTime(DateTime(1999, 1, 6, 0, 0, 0)).daysInMonth == 31);
|
|
assert(SysTime(DateTime(1999, 2, 7, 19, 30, 0)).daysInMonth == 28);
|
|
assert(SysTime(DateTime(2000, 2, 7, 5, 12, 27)).daysInMonth == 29);
|
|
assert(SysTime(DateTime(2000, 6, 4, 12, 22, 9)).daysInMonth == 30);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the current year is a date in A.D.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(SysTime(DateTime(1, 1, 1, 12, 7, 0)).isAD);
|
|
assert(SysTime(DateTime(2010, 12, 31, 0, 0, 0)).isAD);
|
|
assert(!SysTime(DateTime(0, 12, 31, 23, 59, 59)).isAD);
|
|
assert(!SysTime(DateTime(-2010, 1, 1, 2, 2, 2)).isAD);
|
|
--------------------
|
|
+/
|
|
@property bool isAD() const nothrow
|
|
{
|
|
return adjTime >= 0;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assert(SysTime(DateTime(2010, 7, 4, 12, 0, 9)).isAD);
|
|
assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).isAD);
|
|
assert(!SysTime(DateTime(0, 12, 31, 23, 59, 59)).isAD);
|
|
assert(!SysTime(DateTime(0, 1, 1, 23, 59, 59)).isAD);
|
|
assert(!SysTime(DateTime(-1, 1, 1, 23 ,59 ,59)).isAD);
|
|
assert(!SysTime(DateTime(-2010, 7, 4, 12, 2, 2)).isAD);
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, cst.isAD));
|
|
//static assert(__traits(compiles, ist.isAD));
|
|
|
|
//Verify Examples.
|
|
assert(SysTime(DateTime(1, 1, 1, 12, 7, 0)).isAD);
|
|
assert(SysTime(DateTime(2010, 12, 31, 0, 0, 0)).isAD);
|
|
assert(!SysTime(DateTime(0, 12, 31, 23, 59, 59)).isAD);
|
|
assert(!SysTime(DateTime(-2010, 1, 1, 2, 2, 2)).isAD);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
The julian day for this $(D SysTime) at the given time. For example,
|
|
prior to noon, 1996-03-31 would be the julian day number 2_450_173, so
|
|
this function returns 2_450_173, while from noon onward, the julian
|
|
day number would be 2_450_174, so this function returns 2_450_174.
|
|
+/
|
|
@property long julianDay() const nothrow
|
|
{
|
|
immutable jd = dayOfGregorianCal + 1_721_425;
|
|
|
|
return hour < 12 ? jd - 1 : jd;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(SysTime(DateTime(-4713, 11, 24, 0, 0, 0)).julianDay, -1);
|
|
_assertPred!"=="(SysTime(DateTime(-4713, 11, 24, 12, 0, 0)).julianDay, 0);
|
|
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 31, 0, 0, 0)).julianDay, 1_721_424);
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 31, 12, 0, 0)).julianDay, 1_721_425);
|
|
|
|
_assertPred!"=="(SysTime(DateTime(1, 1, 1, 0, 0, 0)).julianDay, 1_721_425);
|
|
_assertPred!"=="(SysTime(DateTime(1, 1, 1, 12, 0, 0)).julianDay, 1_721_426);
|
|
|
|
_assertPred!"=="(SysTime(DateTime(1582, 10, 15, 0, 0, 0)).julianDay, 2_299_160);
|
|
_assertPred!"=="(SysTime(DateTime(1582, 10, 15, 12, 0, 0)).julianDay, 2_299_161);
|
|
|
|
_assertPred!"=="(SysTime(DateTime(1858, 11, 17, 0, 0, 0)).julianDay, 2_400_000);
|
|
_assertPred!"=="(SysTime(DateTime(1858, 11, 17, 12, 0, 0)).julianDay, 2_400_001);
|
|
|
|
_assertPred!"=="(SysTime(DateTime(1982, 1, 4, 0, 0, 0)).julianDay, 2_444_973);
|
|
_assertPred!"=="(SysTime(DateTime(1982, 1, 4, 12, 0, 0)).julianDay, 2_444_974);
|
|
|
|
_assertPred!"=="(SysTime(DateTime(1996, 3, 31, 0, 0, 0)).julianDay, 2_450_173);
|
|
_assertPred!"=="(SysTime(DateTime(1996, 3, 31, 12, 0, 0)).julianDay, 2_450_174);
|
|
|
|
_assertPred!"=="(SysTime(DateTime(2010, 8, 24, 0, 0, 0)).julianDay, 2_455_432);
|
|
_assertPred!"=="(SysTime(DateTime(2010, 8, 24, 12, 0, 0)).julianDay, 2_455_433);
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, cst.julianDay));
|
|
//static assert(__traits(compiles, ist.julianDay));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
The modified julian day for any time on this date (since, the modified
|
|
julian day changes at midnight).
|
|
+/
|
|
@property long modJulianDay() const nothrow
|
|
{
|
|
return (dayOfGregorianCal + 1_721_425) - 2_400_001;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(SysTime(DateTime(1858, 11, 17, 0, 0, 0)).modJulianDay, 0);
|
|
_assertPred!"=="(SysTime(DateTime(1858, 11, 17, 12, 0, 0)).modJulianDay, 0);
|
|
|
|
_assertPred!"=="(SysTime(DateTime(2010, 8, 24, 0, 0, 0)).modJulianDay, 55_432);
|
|
_assertPred!"=="(SysTime(DateTime(2010, 8, 24, 12, 0, 0)).modJulianDay, 55_432);
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, cst.modJulianDay));
|
|
//static assert(__traits(compiles, ist.modJulianDay));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns a $(D Date) equivalent to this $(D SysTime).
|
|
+/
|
|
Date opCast(T)() const nothrow
|
|
if(is(Unqual!T == Date))
|
|
{
|
|
return Date(dayOfGregorianCal);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(cast(Date)SysTime(Date(1999, 7, 6)), Date(1999, 7, 6));
|
|
_assertPred!"=="(cast(Date)SysTime(Date(2000, 12, 31)), Date(2000, 12, 31));
|
|
_assertPred!"=="(cast(Date)SysTime(Date(2001, 1, 1)), Date(2001, 1, 1));
|
|
|
|
_assertPred!"=="(cast(Date)SysTime(DateTime(1999, 7, 6, 12, 10, 9)), Date(1999, 7, 6));
|
|
_assertPred!"=="(cast(Date)SysTime(DateTime(2000, 12, 31, 13, 11, 10)), Date(2000, 12, 31));
|
|
_assertPred!"=="(cast(Date)SysTime(DateTime(2001, 1, 1, 14, 12, 11)), Date(2001, 1, 1));
|
|
|
|
_assertPred!"=="(cast(Date)SysTime(Date(-1999, 7, 6)), Date(-1999, 7, 6));
|
|
_assertPred!"=="(cast(Date)SysTime(Date(-2000, 12, 31)), Date(-2000, 12, 31));
|
|
_assertPred!"=="(cast(Date)SysTime(Date(-2001, 1, 1)), Date(-2001, 1, 1));
|
|
|
|
_assertPred!"=="(cast(Date)SysTime(DateTime(-1999, 7, 6, 12, 10, 9)), Date(-1999, 7, 6));
|
|
_assertPred!"=="(cast(Date)SysTime(DateTime(-2000, 12, 31, 13, 11, 10)), Date(-2000, 12, 31));
|
|
_assertPred!"=="(cast(Date)SysTime(DateTime(-2001, 1, 1, 14, 12, 11)), Date(-2001, 1, 1));
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, cast(Date)cst));
|
|
//static assert(__traits(compiles, cast(Date)ist));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns a $(D DateTime) equivalent to this $(D SysTime).
|
|
+/
|
|
DateTime opCast(T)() const nothrow
|
|
if(is(Unqual!T == DateTime))
|
|
{
|
|
try
|
|
{
|
|
auto hnsecs = adjTime;
|
|
auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
|
|
|
|
if(hnsecs < 0)
|
|
{
|
|
hnsecs += convert!("hours", "hnsecs")(24);
|
|
--days;
|
|
}
|
|
|
|
immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs);
|
|
immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs);
|
|
immutable second = getUnitsFromHNSecs!"seconds"(hnsecs);
|
|
|
|
return DateTime(Date(cast(int)days), TimeOfDay(cast(int)hour, cast(int)minute, cast(int)second));
|
|
}
|
|
catch(Exception e)
|
|
assert(0, "Either DateTime's constructor or TimeOfDay's constructor threw.");
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(cast(DateTime)SysTime(DateTime(1, 1, 6, 7, 12, 22)), DateTime(1, 1, 6, 7, 12, 22));
|
|
_assertPred!"=="(cast(DateTime)SysTime(DateTime(1, 1, 6, 7, 12, 22), FracSec.from!"msecs"(22)), DateTime(1, 1, 6, 7, 12, 22));
|
|
_assertPred!"=="(cast(DateTime)SysTime(Date(1999, 7, 6)), DateTime(1999, 7, 6, 0, 0, 0));
|
|
_assertPred!"=="(cast(DateTime)SysTime(Date(2000, 12, 31)), DateTime(2000, 12, 31, 0, 0, 0));
|
|
_assertPred!"=="(cast(DateTime)SysTime(Date(2001, 1, 1)), DateTime(2001, 1, 1, 0, 0, 0));
|
|
|
|
_assertPred!"=="(cast(DateTime)SysTime(DateTime(1999, 7, 6, 12, 10, 9)), DateTime(1999, 7, 6, 12, 10, 9));
|
|
_assertPred!"=="(cast(DateTime)SysTime(DateTime(2000, 12, 31, 13, 11, 10)), DateTime(2000, 12, 31, 13, 11, 10));
|
|
_assertPred!"=="(cast(DateTime)SysTime(DateTime(2001, 1, 1, 14, 12, 11)), DateTime(2001, 1, 1, 14, 12, 11));
|
|
|
|
_assertPred!"=="(cast(DateTime)SysTime(DateTime(-1, 1, 6, 7, 12, 22)), DateTime(-1, 1, 6, 7, 12, 22));
|
|
_assertPred!"=="(cast(DateTime)SysTime(DateTime(-1, 1, 6, 7, 12, 22), FracSec.from!"msecs"(22)), DateTime(-1, 1, 6, 7, 12, 22));
|
|
_assertPred!"=="(cast(DateTime)SysTime(Date(-1999, 7, 6)), DateTime(-1999, 7, 6, 0, 0, 0));
|
|
_assertPred!"=="(cast(DateTime)SysTime(Date(-2000, 12, 31)), DateTime(-2000, 12, 31, 0, 0, 0));
|
|
_assertPred!"=="(cast(DateTime)SysTime(Date(-2001, 1, 1)), DateTime(-2001, 1, 1, 0, 0, 0));
|
|
|
|
_assertPred!"=="(cast(DateTime)SysTime(DateTime(-1999, 7, 6, 12, 10, 9)), DateTime(-1999, 7, 6, 12, 10, 9));
|
|
_assertPred!"=="(cast(DateTime)SysTime(DateTime(-2000, 12, 31, 13, 11, 10)), DateTime(-2000, 12, 31, 13, 11, 10));
|
|
_assertPred!"=="(cast(DateTime)SysTime(DateTime(-2001, 1, 1, 14, 12, 11)), DateTime(-2001, 1, 1, 14, 12, 11));
|
|
|
|
_assertPred!"=="(cast(DateTime)SysTime(DateTime(2011, 1, 13, 8, 17, 2), FracSec.from!"msecs"(296), LocalTime()),
|
|
DateTime(2011, 1, 13, 8, 17, 2));
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, cast(DateTime)cst));
|
|
//static assert(__traits(compiles, cast(DateTime)ist));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns a $(D TimeOfDay) equivalent to this $(D SysTime).
|
|
+/
|
|
TimeOfDay opCast(T)() const nothrow
|
|
if(is(Unqual!T == TimeOfDay))
|
|
{
|
|
try
|
|
{
|
|
auto hnsecs = adjTime;
|
|
hnsecs = removeUnitsFromHNSecs!"days"(hnsecs);
|
|
|
|
if(hnsecs < 0)
|
|
hnsecs += convert!("hours", "hnsecs")(24);
|
|
|
|
immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs);
|
|
immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs);
|
|
immutable second = getUnitsFromHNSecs!"seconds"(hnsecs);
|
|
|
|
return TimeOfDay(cast(int)hour, cast(int)minute, cast(int)second);
|
|
}
|
|
catch(Exception e)
|
|
assert(0, "TimeOfDay's constructor threw.");
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(cast(TimeOfDay)SysTime(Date(1999, 7, 6)), TimeOfDay(0, 0, 0));
|
|
_assertPred!"=="(cast(TimeOfDay)SysTime(Date(2000, 12, 31)), TimeOfDay(0, 0, 0));
|
|
_assertPred!"=="(cast(TimeOfDay)SysTime(Date(2001, 1, 1)), TimeOfDay(0, 0, 0));
|
|
|
|
_assertPred!"=="(cast(TimeOfDay)SysTime(DateTime(1999, 7, 6, 12, 10, 9)), TimeOfDay(12, 10, 9));
|
|
_assertPred!"=="(cast(TimeOfDay)SysTime(DateTime(2000, 12, 31, 13, 11, 10)), TimeOfDay(13, 11, 10));
|
|
_assertPred!"=="(cast(TimeOfDay)SysTime(DateTime(2001, 1, 1, 14, 12, 11)), TimeOfDay(14, 12, 11));
|
|
|
|
_assertPred!"=="(cast(TimeOfDay)SysTime(Date(-1999, 7, 6)), TimeOfDay(0, 0, 0));
|
|
_assertPred!"=="(cast(TimeOfDay)SysTime(Date(-2000, 12, 31)), TimeOfDay(0, 0, 0));
|
|
_assertPred!"=="(cast(TimeOfDay)SysTime(Date(-2001, 1, 1)), TimeOfDay(0, 0, 0));
|
|
|
|
_assertPred!"=="(cast(TimeOfDay)SysTime(DateTime(-1999, 7, 6, 12, 10, 9)), TimeOfDay(12, 10, 9));
|
|
_assertPred!"=="(cast(TimeOfDay)SysTime(DateTime(-2000, 12, 31, 13, 11, 10)), TimeOfDay(13, 11, 10));
|
|
_assertPred!"=="(cast(TimeOfDay)SysTime(DateTime(-2001, 1, 1, 14, 12, 11)), TimeOfDay(14, 12, 11));
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, cast(TimeOfDay)cst));
|
|
//static assert(__traits(compiles, cast(TimeOfDay)ist));
|
|
}
|
|
}
|
|
|
|
|
|
//Temporary hack until bug http://d.puremagic.com/issues/show_bug.cgi?id=4867 is fixed.
|
|
//This allows assignment from const(SysTime) to SysTime.
|
|
//It may be a good idea to keep it though, since casting from a type to itself
|
|
//should be allowed, and it doesn't work without this opCast() since opCast()
|
|
//has already been defined for other types.
|
|
SysTime opCast(T)() const pure nothrow
|
|
if(is(Unqual!T == SysTime))
|
|
{
|
|
return SysTime(_stdTime, _timezone.get);
|
|
}
|
|
|
|
|
|
/++
|
|
Converts this $(D SysTime) to a string with the format
|
|
YYYYMMDDTHHMMSS.FFFFFFFTZ (where F is fractional seconds and TZ is time
|
|
zone).
|
|
|
|
Note that the number of digits in the fractional seconds varies with the
|
|
number of fractional seconds. It's a maximum of 7 (which would be
|
|
hnsecs), but only has as many as are necessary to hold the correct value
|
|
(so no trailing zeroes), and if there are no fractional seconds, then
|
|
there is no decimal point.
|
|
|
|
If this $(D SysTime)'s time zone is $(D LocalTime), then TZ is empty.
|
|
If its time zone is $(D UTC), then it is "Z". Otherwise, it is the
|
|
offset from UTC (e.g. +1:00 or -7:00). Note that the offset from UTC
|
|
is $(I not) enough to uniquely identify the time zone.
|
|
|
|
Time zone offsets will be in the form +HH:MM or -HH:MM.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toISOString() ==
|
|
"20100704T070612");
|
|
|
|
assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0),
|
|
FracSec.from!"msecs"(24)).toISOString() ==
|
|
"19981225T021500.024");
|
|
|
|
assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toISOString() ==
|
|
"00000105T230959");
|
|
|
|
assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2),
|
|
FracSec.from!"hnsecs"(520_920)).toISOString() ==
|
|
"-00040105T000002.052092");
|
|
--------------------
|
|
+/
|
|
string toISOString() const nothrow
|
|
{
|
|
try
|
|
{
|
|
immutable adjustedTime = adjTime;
|
|
long hnsecs = adjustedTime;
|
|
|
|
auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
|
|
|
|
if(hnsecs < 0)
|
|
{
|
|
hnsecs += convert!("hours", "hnsecs")(24);
|
|
--days;
|
|
}
|
|
|
|
auto hour = splitUnitsFromHNSecs!"hours"(hnsecs);
|
|
auto minute = splitUnitsFromHNSecs!"minutes"(hnsecs);
|
|
auto second = splitUnitsFromHNSecs!"seconds"(hnsecs);
|
|
|
|
auto dateTime = DateTime(Date(cast(int)days), TimeOfDay(cast(int)hour, cast(int)minute, cast(int)second));
|
|
auto fracSecStr = fracSecToISOString(cast(int)hnsecs);
|
|
|
|
if(_timezone.get is LocalTime())
|
|
return dateTime.toISOString() ~ fracSecToISOString(cast(int)hnsecs);
|
|
|
|
if(_timezone.get is UTC())
|
|
return dateTime.toISOString() ~ fracSecToISOString(cast(int)hnsecs) ~ "Z";
|
|
|
|
immutable utcOffset = cast(int)convert!("hnsecs", "minutes")(adjustedTime - stdTime);
|
|
|
|
return dateTime.toISOString() ~ fracSecToISOString(cast(int)hnsecs) ~ SimpleTimeZone.toISOString(utcOffset);
|
|
}
|
|
catch(Exception e)
|
|
assert(0, "format() threw.");
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
_assertPred!"=="(SysTime(DateTime.init, UTC()).toISOString(), "00010101T000000Z");
|
|
_assertPred!"=="(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(1), UTC()).toISOString(), "00010101T000000.0000001Z");
|
|
|
|
_assertPred!"=="(SysTime(DateTime(9, 12, 4, 0, 0, 0)).toISOString(), "00091204T000000");
|
|
_assertPred!"=="(SysTime(DateTime(99, 12, 4, 5, 6, 12)).toISOString(), "00991204T050612");
|
|
_assertPred!"=="(SysTime(DateTime(999, 12, 4, 13, 44, 59)).toISOString(), "09991204T134459");
|
|
_assertPred!"=="(SysTime(DateTime(9999, 7, 4, 23, 59, 59)).toISOString(), "99990704T235959");
|
|
_assertPred!"=="(SysTime(DateTime(10000, 10, 20, 1, 1, 1)).toISOString(), "+100001020T010101");
|
|
|
|
_assertPred!"=="(SysTime(DateTime(9, 12, 4, 0, 0, 0), FracSec.from!"msecs"(42)).toISOString(), "00091204T000000.042");
|
|
_assertPred!"=="(SysTime(DateTime(99, 12, 4, 5, 6, 12), FracSec.from!"msecs"(100)).toISOString(), "00991204T050612.1");
|
|
_assertPred!"=="(SysTime(DateTime(999, 12, 4, 13, 44, 59), FracSec.from!"usecs"(45020)).toISOString(), "09991204T134459.04502");
|
|
_assertPred!"=="(SysTime(DateTime(9999, 7, 4, 23, 59, 59), FracSec.from!"hnsecs"(12)).toISOString(), "99990704T235959.0000012");
|
|
_assertPred!"=="(SysTime(DateTime(10000, 10, 20, 1, 1, 1), FracSec.from!"hnsecs"(507890)).toISOString(), "+100001020T010101.050789");
|
|
|
|
_assertPred!"=="(SysTime(DateTime(2012, 12, 21, 12, 12, 12),
|
|
new SimpleTimeZone(-360)).toISOString(),
|
|
"20121221T121212-06:00");
|
|
|
|
_assertPred!"=="(SysTime(DateTime(2012, 12, 21, 12, 12, 12),
|
|
new SimpleTimeZone(420)).toISOString(),
|
|
"20121221T121212+07:00");
|
|
|
|
//Test B.C.
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999), UTC()).toISOString(), "00001231T235959.9999999Z");
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(1), UTC()).toISOString(), "00001231T235959.0000001Z");
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 31, 23, 59, 59), UTC()).toISOString(), "00001231T235959Z");
|
|
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 4, 0, 12, 4)).toISOString(), "00001204T001204");
|
|
_assertPred!"=="(SysTime(DateTime(-9, 12, 4, 0, 0, 0)).toISOString(), "-00091204T000000");
|
|
_assertPred!"=="(SysTime(DateTime(-99, 12, 4, 5, 6, 12)).toISOString(), "-00991204T050612");
|
|
_assertPred!"=="(SysTime(DateTime(-999, 12, 4, 13, 44, 59)).toISOString(), "-09991204T134459");
|
|
_assertPred!"=="(SysTime(DateTime(-9999, 7, 4, 23, 59, 59)).toISOString(), "-99990704T235959");
|
|
_assertPred!"=="(SysTime(DateTime(-10000, 10, 20, 1, 1, 1)).toISOString(), "-100001020T010101");
|
|
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 4, 0, 0, 0), FracSec.from!"msecs"(7)).toISOString(), "00001204T000000.007");
|
|
_assertPred!"=="(SysTime(DateTime(-9, 12, 4, 0, 0, 0), FracSec.from!"msecs"(42)).toISOString(), "-00091204T000000.042");
|
|
_assertPred!"=="(SysTime(DateTime(-99, 12, 4, 5, 6, 12), FracSec.from!"msecs"(100)).toISOString(), "-00991204T050612.1");
|
|
_assertPred!"=="(SysTime(DateTime(-999, 12, 4, 13, 44, 59), FracSec.from!"usecs"(45020)).toISOString(), "-09991204T134459.04502");
|
|
_assertPred!"=="(SysTime(DateTime(-9999, 7, 4, 23, 59, 59), FracSec.from!"hnsecs"(12)).toISOString(), "-99990704T235959.0000012");
|
|
_assertPred!"=="(SysTime(DateTime(-10000, 10, 20, 1, 1, 1), FracSec.from!"hnsecs"(507890)).toISOString(), "-100001020T010101.050789");
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, cast(TimeOfDay)cst));
|
|
//static assert(__traits(compiles, cast(TimeOfDay)ist));
|
|
|
|
//Verify Examples.
|
|
assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toISOString() ==
|
|
"20100704T070612");
|
|
|
|
assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0),
|
|
FracSec.from!"msecs"(24)).toISOString() ==
|
|
"19981225T021500.024");
|
|
|
|
assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toISOString() ==
|
|
"00000105T230959");
|
|
|
|
assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2),
|
|
FracSec.from!"hnsecs"(520_920)).toISOString() ==
|
|
"-00040105T000002.052092");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/++
|
|
Converts this $(D SysTime) to a string with the format
|
|
YYYY-MM-DDTHH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ
|
|
is the time zone).
|
|
|
|
Note that the number of digits in the fractional seconds varies with the
|
|
number of fractional seconds. It's a maximum of 7 (which would be
|
|
hnsecs), but only has as many as are necessary to hold the correct value
|
|
(so no trailing zeroes), and if there are no fractional seconds, then
|
|
there is no decimal point.
|
|
|
|
If this $(D SysTime)'s time zone is $(D LocalTime), then TZ is empty. If
|
|
its time zone is $(D UTC), then it is "Z". Otherwise, it is the offset
|
|
from UTC (e.g. +1:00 or -7:00). Note that the offset from UTC is
|
|
$(I not) enough to uniquely identify the time zone.
|
|
|
|
Time zone offsets will be in the form +HH:MM or -HH:MM.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toISOExtString() ==
|
|
"2010-07-04T07:06:12");
|
|
|
|
assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0),
|
|
FracSec.from!"msecs"(24)).toISOExtString() ==
|
|
"1998-12-25T02:15:00.024");
|
|
|
|
assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toISOExtString() ==
|
|
"0000-01-05T23:09:59");
|
|
|
|
assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2),
|
|
FracSec.from!"hnsecs"(520_920)).toISOExtString() ==
|
|
"-0004-01-05T00:00:02.052092");
|
|
--------------------
|
|
+/
|
|
string toISOExtString() const nothrow
|
|
{
|
|
try
|
|
{
|
|
immutable adjustedTime = adjTime;
|
|
long hnsecs = adjustedTime;
|
|
|
|
auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
|
|
|
|
if(hnsecs < 0)
|
|
{
|
|
hnsecs += convert!("hours", "hnsecs")(24);
|
|
--days;
|
|
}
|
|
|
|
auto hour = splitUnitsFromHNSecs!"hours"(hnsecs);
|
|
auto minute = splitUnitsFromHNSecs!"minutes"(hnsecs);
|
|
auto second = splitUnitsFromHNSecs!"seconds"(hnsecs);
|
|
|
|
auto dateTime = DateTime(Date(cast(int)days), TimeOfDay(cast(int)hour, cast(int)minute, cast(int)second));
|
|
auto fracSecStr = fracSecToISOString(cast(int)hnsecs);
|
|
|
|
if(_timezone.get is LocalTime())
|
|
return dateTime.toISOExtString() ~ fracSecToISOString(cast(int)hnsecs);
|
|
|
|
if(_timezone.get is UTC())
|
|
return dateTime.toISOExtString() ~ fracSecToISOString(cast(int)hnsecs) ~ "Z";
|
|
|
|
immutable utcOffset = cast(int)convert!("hnsecs", "minutes")(adjustedTime - stdTime);
|
|
|
|
return dateTime.toISOExtString() ~ fracSecToISOString(cast(int)hnsecs) ~ SimpleTimeZone.toISOString(utcOffset);
|
|
}
|
|
catch(Exception e)
|
|
assert(0, "format() threw.");
|
|
}
|
|
|
|
/++
|
|
$(RED Scheduled for deprecation in November 2011.
|
|
Please use toISOExtString instead.)
|
|
+/
|
|
alias toISOExtString toISOExtendedString;
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
_assertPred!"=="(SysTime(DateTime.init, UTC()).toISOExtString(), "0001-01-01T00:00:00Z");
|
|
_assertPred!"=="(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(1), UTC()).toISOExtString(), "0001-01-01T00:00:00.0000001Z");
|
|
|
|
_assertPred!"=="(SysTime(DateTime(9, 12, 4, 0, 0, 0)).toISOExtString(), "0009-12-04T00:00:00");
|
|
_assertPred!"=="(SysTime(DateTime(99, 12, 4, 5, 6, 12)).toISOExtString(), "0099-12-04T05:06:12");
|
|
_assertPred!"=="(SysTime(DateTime(999, 12, 4, 13, 44, 59)).toISOExtString(), "0999-12-04T13:44:59");
|
|
_assertPred!"=="(SysTime(DateTime(9999, 7, 4, 23, 59, 59)).toISOExtString(), "9999-07-04T23:59:59");
|
|
_assertPred!"=="(SysTime(DateTime(10000, 10, 20, 1, 1, 1)).toISOExtString(), "+10000-10-20T01:01:01");
|
|
|
|
_assertPred!"=="(SysTime(DateTime(9, 12, 4, 0, 0, 0), FracSec.from!"msecs"(42)).toISOExtString(), "0009-12-04T00:00:00.042");
|
|
_assertPred!"=="(SysTime(DateTime(99, 12, 4, 5, 6, 12), FracSec.from!"msecs"(100)).toISOExtString(), "0099-12-04T05:06:12.1");
|
|
_assertPred!"=="(SysTime(DateTime(999, 12, 4, 13, 44, 59), FracSec.from!"usecs"(45020)).toISOExtString(), "0999-12-04T13:44:59.04502");
|
|
_assertPred!"=="(SysTime(DateTime(9999, 7, 4, 23, 59, 59), FracSec.from!"hnsecs"(12)).toISOExtString(), "9999-07-04T23:59:59.0000012");
|
|
_assertPred!"=="(SysTime(DateTime(10000, 10, 20, 1, 1, 1), FracSec.from!"hnsecs"(507890)).toISOExtString(), "+10000-10-20T01:01:01.050789");
|
|
|
|
_assertPred!"=="(SysTime(DateTime(2012, 12, 21, 12, 12, 12),
|
|
new SimpleTimeZone(-360)).toISOExtString(),
|
|
"2012-12-21T12:12:12-06:00");
|
|
|
|
_assertPred!"=="(SysTime(DateTime(2012, 12, 21, 12, 12, 12),
|
|
new SimpleTimeZone(420)).toISOExtString(),
|
|
"2012-12-21T12:12:12+07:00");
|
|
|
|
//Test B.C.
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999), UTC()).toISOExtString(), "0000-12-31T23:59:59.9999999Z");
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(1), UTC()).toISOExtString(), "0000-12-31T23:59:59.0000001Z");
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 31, 23, 59, 59), UTC()).toISOExtString(), "0000-12-31T23:59:59Z");
|
|
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 4, 0, 12, 4)).toISOExtString(), "0000-12-04T00:12:04");
|
|
_assertPred!"=="(SysTime(DateTime(-9, 12, 4, 0, 0, 0)).toISOExtString(), "-0009-12-04T00:00:00");
|
|
_assertPred!"=="(SysTime(DateTime(-99, 12, 4, 5, 6, 12)).toISOExtString(), "-0099-12-04T05:06:12");
|
|
_assertPred!"=="(SysTime(DateTime(-999, 12, 4, 13, 44, 59)).toISOExtString(), "-0999-12-04T13:44:59");
|
|
_assertPred!"=="(SysTime(DateTime(-9999, 7, 4, 23, 59, 59)).toISOExtString(), "-9999-07-04T23:59:59");
|
|
_assertPred!"=="(SysTime(DateTime(-10000, 10, 20, 1, 1, 1)).toISOExtString(), "-10000-10-20T01:01:01");
|
|
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 4, 0, 0, 0), FracSec.from!"msecs"(7)).toISOExtString(), "0000-12-04T00:00:00.007");
|
|
_assertPred!"=="(SysTime(DateTime(-9, 12, 4, 0, 0, 0), FracSec.from!"msecs"(42)).toISOExtString(), "-0009-12-04T00:00:00.042");
|
|
_assertPred!"=="(SysTime(DateTime(-99, 12, 4, 5, 6, 12), FracSec.from!"msecs"(100)).toISOExtString(), "-0099-12-04T05:06:12.1");
|
|
_assertPred!"=="(SysTime(DateTime(-999, 12, 4, 13, 44, 59), FracSec.from!"usecs"(45020)).toISOExtString(), "-0999-12-04T13:44:59.04502");
|
|
_assertPred!"=="(SysTime(DateTime(-9999, 7, 4, 23, 59, 59), FracSec.from!"hnsecs"(12)).toISOExtString(), "-9999-07-04T23:59:59.0000012");
|
|
_assertPred!"=="(SysTime(DateTime(-10000, 10, 20, 1, 1, 1), FracSec.from!"hnsecs"(507890)).toISOExtString(), "-10000-10-20T01:01:01.050789");
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, cast(TimeOfDay)cst));
|
|
//static assert(__traits(compiles, cast(TimeOfDay)ist));
|
|
|
|
//Verify Examples.
|
|
assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toISOExtString() ==
|
|
"2010-07-04T07:06:12");
|
|
|
|
assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0),
|
|
FracSec.from!"msecs"(24)).toISOExtString() ==
|
|
"1998-12-25T02:15:00.024");
|
|
|
|
assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toISOExtString() ==
|
|
"0000-01-05T23:09:59");
|
|
|
|
assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2),
|
|
FracSec.from!"hnsecs"(520_920)).toISOExtString() ==
|
|
"-0004-01-05T00:00:02.052092");
|
|
}
|
|
}
|
|
|
|
/++
|
|
Converts this $(D SysTime) to a string with the format
|
|
YYYY-Mon-DD HH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ
|
|
is the time zone).
|
|
|
|
Note that the number of digits in the fractional seconds varies with the
|
|
number of fractional seconds. It's a maximum of 7 (which would be
|
|
hnsecs), but only has as many as are necessary to hold the correct value
|
|
(so no trailing zeroes), and if there are no fractional seconds, then
|
|
there is no decimal point.
|
|
|
|
If this $(D SysTime)'s time zone is $(D LocalTime), then TZ is empty. If
|
|
its time zone is $(D UTC), then it is "Z". Otherwise, it is the offset
|
|
from UTC (e.g. +1:00 or -7:00). Note that the offset from UTC is
|
|
$(I not) enough to uniquely identify the time zone.
|
|
|
|
Time zone offsets will be in the form +HH:MM or -HH:MM.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toSimpleString() ==
|
|
"2010-Jul-04 07:06:12");
|
|
|
|
assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0),
|
|
FracSec.from!"msecs"(24)).toSimpleString() ==
|
|
"1998-Dec-25 02:15:00.024");
|
|
|
|
assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toSimpleString() ==
|
|
"0000-Jan-05 23:09:59");
|
|
|
|
assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2),
|
|
FracSec.from!"hnsecs"(520_920)).toSimpleString() ==
|
|
"-0004-Jan-05 00:00:02.052092");
|
|
--------------------
|
|
+/
|
|
string toSimpleString() const nothrow
|
|
{
|
|
try
|
|
{
|
|
immutable adjustedTime = adjTime;
|
|
long hnsecs = adjustedTime;
|
|
|
|
auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
|
|
|
|
if(hnsecs < 0)
|
|
{
|
|
hnsecs += convert!("hours", "hnsecs")(24);
|
|
--days;
|
|
}
|
|
|
|
auto hour = splitUnitsFromHNSecs!"hours"(hnsecs);
|
|
auto minute = splitUnitsFromHNSecs!"minutes"(hnsecs);
|
|
auto second = splitUnitsFromHNSecs!"seconds"(hnsecs);
|
|
|
|
auto dateTime = DateTime(Date(cast(int)days), TimeOfDay(cast(int)hour, cast(int)minute, cast(int)second));
|
|
auto fracSecStr = fracSecToISOString(cast(int)hnsecs);
|
|
|
|
if(_timezone.get is LocalTime())
|
|
return dateTime.toSimpleString() ~ fracSecToISOString(cast(int)hnsecs);
|
|
|
|
if(_timezone.get is UTC())
|
|
return dateTime.toSimpleString() ~ fracSecToISOString(cast(int)hnsecs) ~ "Z";
|
|
|
|
immutable utcOffset = cast(int)convert!("hnsecs", "minutes")(adjustedTime - stdTime);
|
|
|
|
return dateTime.toSimpleString() ~ fracSecToISOString(cast(int)hnsecs) ~ SimpleTimeZone.toISOString(utcOffset);
|
|
}
|
|
catch(Exception e)
|
|
assert(0, "format() threw.");
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
_assertPred!"=="(SysTime(DateTime.init, UTC()).toString(), "0001-Jan-01 00:00:00Z");
|
|
_assertPred!"=="(SysTime(DateTime(1, 1, 1, 0, 0, 0), FracSec.from!"hnsecs"(1), UTC()).toString(), "0001-Jan-01 00:00:00.0000001Z");
|
|
|
|
_assertPred!"=="(SysTime(DateTime(9, 12, 4, 0, 0, 0)).toSimpleString(), "0009-Dec-04 00:00:00");
|
|
_assertPred!"=="(SysTime(DateTime(99, 12, 4, 5, 6, 12)).toSimpleString(), "0099-Dec-04 05:06:12");
|
|
_assertPred!"=="(SysTime(DateTime(999, 12, 4, 13, 44, 59)).toSimpleString(), "0999-Dec-04 13:44:59");
|
|
_assertPred!"=="(SysTime(DateTime(9999, 7, 4, 23, 59, 59)).toSimpleString(), "9999-Jul-04 23:59:59");
|
|
_assertPred!"=="(SysTime(DateTime(10000, 10, 20, 1, 1, 1)).toSimpleString(), "+10000-Oct-20 01:01:01");
|
|
|
|
_assertPred!"=="(SysTime(DateTime(9, 12, 4, 0, 0, 0), FracSec.from!"msecs"(42)).toSimpleString(), "0009-Dec-04 00:00:00.042");
|
|
_assertPred!"=="(SysTime(DateTime(99, 12, 4, 5, 6, 12), FracSec.from!"msecs"(100)).toSimpleString(), "0099-Dec-04 05:06:12.1");
|
|
_assertPred!"=="(SysTime(DateTime(999, 12, 4, 13, 44, 59), FracSec.from!"usecs"(45020)).toSimpleString(), "0999-Dec-04 13:44:59.04502");
|
|
_assertPred!"=="(SysTime(DateTime(9999, 7, 4, 23, 59, 59), FracSec.from!"hnsecs"(12)).toSimpleString(), "9999-Jul-04 23:59:59.0000012");
|
|
_assertPred!"=="(SysTime(DateTime(10000, 10, 20, 1, 1, 1), FracSec.from!"hnsecs"(507890)).toSimpleString(), "+10000-Oct-20 01:01:01.050789");
|
|
|
|
_assertPred!"=="(SysTime(DateTime(2012, 12, 21, 12, 12, 12),
|
|
new SimpleTimeZone(-360)).toSimpleString(),
|
|
"2012-Dec-21 12:12:12-06:00");
|
|
|
|
_assertPred!"=="(SysTime(DateTime(2012, 12, 21, 12, 12, 12),
|
|
new SimpleTimeZone(420)).toSimpleString(),
|
|
"2012-Dec-21 12:12:12+07:00");
|
|
|
|
//Test B.C.
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(9_999_999), UTC()).toSimpleString(), "0000-Dec-31 23:59:59.9999999Z");
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 31, 23, 59, 59), FracSec.from!"hnsecs"(1), UTC()).toSimpleString(), "0000-Dec-31 23:59:59.0000001Z");
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 31, 23, 59, 59), UTC()).toSimpleString(), "0000-Dec-31 23:59:59Z");
|
|
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 4, 0, 12, 4)).toSimpleString(), "0000-Dec-04 00:12:04");
|
|
_assertPred!"=="(SysTime(DateTime(-9, 12, 4, 0, 0, 0)).toSimpleString(), "-0009-Dec-04 00:00:00");
|
|
_assertPred!"=="(SysTime(DateTime(-99, 12, 4, 5, 6, 12)).toSimpleString(), "-0099-Dec-04 05:06:12");
|
|
_assertPred!"=="(SysTime(DateTime(-999, 12, 4, 13, 44, 59)).toSimpleString(), "-0999-Dec-04 13:44:59");
|
|
_assertPred!"=="(SysTime(DateTime(-9999, 7, 4, 23, 59, 59)).toSimpleString(), "-9999-Jul-04 23:59:59");
|
|
_assertPred!"=="(SysTime(DateTime(-10000, 10, 20, 1, 1, 1)).toSimpleString(), "-10000-Oct-20 01:01:01");
|
|
|
|
_assertPred!"=="(SysTime(DateTime(0, 12, 4, 0, 0, 0), FracSec.from!"msecs"(7)).toSimpleString(), "0000-Dec-04 00:00:00.007");
|
|
_assertPred!"=="(SysTime(DateTime(-9, 12, 4, 0, 0, 0), FracSec.from!"msecs"(42)).toSimpleString(), "-0009-Dec-04 00:00:00.042");
|
|
_assertPred!"=="(SysTime(DateTime(-99, 12, 4, 5, 6, 12), FracSec.from!"msecs"(100)).toSimpleString(), "-0099-Dec-04 05:06:12.1");
|
|
_assertPred!"=="(SysTime(DateTime(-999, 12, 4, 13, 44, 59), FracSec.from!"usecs"(45020)).toSimpleString(), "-0999-Dec-04 13:44:59.04502");
|
|
_assertPred!"=="(SysTime(DateTime(-9999, 7, 4, 23, 59, 59), FracSec.from!"hnsecs"(12)).toSimpleString(), "-9999-Jul-04 23:59:59.0000012");
|
|
_assertPred!"=="(SysTime(DateTime(-10000, 10, 20, 1, 1, 1), FracSec.from!"hnsecs"(507890)).toSimpleString(), "-10000-Oct-20 01:01:01.050789");
|
|
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, cast(TimeOfDay)cst));
|
|
//static assert(__traits(compiles, cast(TimeOfDay)ist));
|
|
|
|
//Verify Examples.
|
|
assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toSimpleString() ==
|
|
"2010-Jul-04 07:06:12");
|
|
|
|
assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0),
|
|
FracSec.from!"msecs"(24)).toSimpleString() ==
|
|
"1998-Dec-25 02:15:00.024");
|
|
|
|
assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toSimpleString() ==
|
|
"0000-Jan-05 23:09:59");
|
|
|
|
assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2),
|
|
FracSec.from!"hnsecs"(520_920)).toSimpleString() ==
|
|
"-0004-Jan-05 00:00:02.052092");
|
|
}
|
|
}
|
|
|
|
|
|
/+
|
|
Converts this $(D SysTime) to a string.
|
|
+/
|
|
//Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't
|
|
//have versions of toString() with extra modifiers, so we define one version
|
|
//with modifiers and one without.
|
|
string toString()
|
|
{
|
|
return toSimpleString();
|
|
}
|
|
|
|
/++
|
|
Converts this $(D SysTime) to a string.
|
|
+/
|
|
//Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't
|
|
//have versions of toString() with extra modifiers, so we define one version
|
|
//with modifiers and one without.
|
|
string toString() const nothrow
|
|
{
|
|
return toSimpleString();
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
//immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
|
|
static assert(__traits(compiles, st.toString()));
|
|
static assert(__traits(compiles, cst.toString()));
|
|
//static assert(__traits(compiles, ist.toString()));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Creates a $(D SysTime) from a string with the format
|
|
YYYYMMDDTHHMMSS.FFFFFFFTZ (where F is fractional seconds is the time
|
|
zone). Whitespace is stripped from the given string.
|
|
|
|
The exact format is exactly as described in $(D toISOString) except that
|
|
trailing zeroes are permitted - including having fractional seconds with
|
|
all zeroes. However, a decimal point with nothing following it is
|
|
invalid.
|
|
|
|
If there is no time zone in the string, then $(D LocalTime) is used. If
|
|
the time zone is "Z", then $(D UTC) is used. Otherwise, a
|
|
$(D SimpleTimeZone) which corresponds to the given offset from UTC is
|
|
used. If you wish the returned $(D SysTime) to be a particular time
|
|
zone, then pass in that time zone and the $(D SysTime) to be returned
|
|
will be converted to that time zone (though it will still be read in as
|
|
whatever time zone is in its string).
|
|
|
|
The accepted formats for time zone offsets
|
|
are +H, -H, +HH, -HH, +H:MM, -H:MM, +HH:MM, and -HH:MM.
|
|
|
|
Params:
|
|
isoString = A string formatted in the ISO format for dates and times.
|
|
tz = The time zone to convert the given time to (no
|
|
conversion occurs if null).
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given string is not in the ISO format
|
|
or if the resulting $(D SysTime) would not be valid.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(SysTime.fromISOString("20100704T070612") ==
|
|
SysTime(DateTime(2010, 7, 4, 7, 6, 12)));
|
|
assert(SysTime.fromISOString("19981225T021500.007") ==
|
|
SysTime(DateTime(1998, 12, 25, 2, 15, 0), FracSec.from!"msecs"(7)));
|
|
assert(SysTime.fromISOString("00000105T230959.00002") ==
|
|
SysTime(DateTime(0, 1, 5, 23, 9, 59), FracSec.from!"usecs"(20)));
|
|
assert(SysTime.fromISOString("-00040105T000002") ==
|
|
SysTime(DateTime(-4, 1, 5, 0, 0, 2)));
|
|
assert(SysTime.fromISOString(" 20100704T070612 ") ==
|
|
SysTime(DateTime(2010, 7, 4, 7, 6, 12)));
|
|
|
|
assert(SysTime.fromISOString("20100704T070612Z") ==
|
|
SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC()));
|
|
assert(SysTime.fromISOString("20100704T070612-8:00") ==
|
|
SysTime(DateTime(2010, 7, 4, 7, 6, 12), new SimpleTimeZone(-480)));
|
|
assert(SysTime.fromISOString("20100704T070612+8:00") ==
|
|
SysTime(DateTime(2010, 7, 3, 7, 6, 12), new SimpleTimeZone(480)));
|
|
--------------------
|
|
+/
|
|
static SysTime fromISOString(S)(in S isoString, immutable TimeZone tz = null)
|
|
if(isSomeString!S)
|
|
{
|
|
auto dstr = to!dstring(strip(isoString));
|
|
immutable skipFirst = dstr.startsWith("+", "-") != 0;
|
|
|
|
auto found = (skipFirst ? dstr[1..$] : dstr).find(".", "Z", "+", "-");
|
|
auto dateTimeStr = dstr[0 .. $ - found[0].length];
|
|
|
|
dstring fracSecStr;
|
|
dstring zoneStr;
|
|
|
|
if(found[1] != 0)
|
|
{
|
|
if(found[1] == 1)
|
|
{
|
|
auto foundTZ = found[0].find("Z", "+", "-");
|
|
|
|
if(foundTZ[1] != 0)
|
|
{
|
|
fracSecStr = found[0][0 .. $ - foundTZ[0].length];
|
|
zoneStr = foundTZ[0];
|
|
}
|
|
else
|
|
fracSecStr = found[0];
|
|
}
|
|
else
|
|
zoneStr = found[0];
|
|
}
|
|
|
|
try
|
|
{
|
|
auto dateTime = DateTime.fromISOString(dateTimeStr);
|
|
auto fracSec = fracSecFromISOString(fracSecStr);
|
|
DTRebindable!(immutable TimeZone) parsedZone;
|
|
|
|
if(zoneStr.empty)
|
|
parsedZone = LocalTime();
|
|
else if(zoneStr == "Z")
|
|
parsedZone = UTC();
|
|
else
|
|
parsedZone = SimpleTimeZone.fromISOString(zoneStr);
|
|
|
|
auto retval = SysTime(dateTime, fracSec, parsedZone.get);
|
|
|
|
if(tz !is null)
|
|
retval.timezone = tz;
|
|
|
|
return retval;
|
|
}
|
|
catch(DateTimeException dte)
|
|
throw new DateTimeException(format("Invalid ISO String: %s", isoString));
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assertThrown!DateTimeException(SysTime.fromISOString(""));
|
|
assertThrown!DateTimeException(SysTime.fromISOString("20100704000000"));
|
|
assertThrown!DateTimeException(SysTime.fromISOString("20100704 000000"));
|
|
assertThrown!DateTimeException(SysTime.fromISOString("20100704t000000"));
|
|
assertThrown!DateTimeException(SysTime.fromISOString("20100704T000000."));
|
|
assertThrown!DateTimeException(SysTime.fromISOString("20100704T000000.A"));
|
|
assertThrown!DateTimeException(SysTime.fromISOString("20100704T000000.Z"));
|
|
assertThrown!DateTimeException(SysTime.fromISOString("20100704T000000.00000000"));
|
|
assertThrown!DateTimeException(SysTime.fromISOString("20100704T000000.00000000"));
|
|
assertThrown!DateTimeException(SysTime.fromISOString("20100704T000000+"));
|
|
assertThrown!DateTimeException(SysTime.fromISOString("20100704T000000-"));
|
|
assertThrown!DateTimeException(SysTime.fromISOString("20100704T000000:"));
|
|
assertThrown!DateTimeException(SysTime.fromISOString("20100704T000000-:"));
|
|
assertThrown!DateTimeException(SysTime.fromISOString("20100704T000000+:"));
|
|
assertThrown!DateTimeException(SysTime.fromISOString("20100704T000000-1:"));
|
|
assertThrown!DateTimeException(SysTime.fromISOString("20100704T000000+1:"));
|
|
assertThrown!DateTimeException(SysTime.fromISOString("20100704T000000+1:0"));
|
|
assertThrown!DateTimeException(SysTime.fromISOString("20100704T000000-24.00"));
|
|
assertThrown!DateTimeException(SysTime.fromISOString("20100704T000000+24.00"));
|
|
|
|
assertThrown!DateTimeException(SysTime.fromISOString("2010-07-0400:00:00"));
|
|
assertThrown!DateTimeException(SysTime.fromISOString("2010-07-04 00:00:00"));
|
|
assertThrown!DateTimeException(SysTime.fromISOString("2010-07-04t00:00:00"));
|
|
assertThrown!DateTimeException(SysTime.fromISOString("2010-07-04T00:00:00."));
|
|
|
|
assertThrown!DateTimeException(SysTime.fromISOString("2010-Jul-0400:00:00"));
|
|
assertThrown!DateTimeException(SysTime.fromISOString("2010-Jul-04 00:00:00"));
|
|
assertThrown!DateTimeException(SysTime.fromISOString("2010-Jul-04t00:00:00"));
|
|
assertThrown!DateTimeException(SysTime.fromISOString("2010-Jul-04T00:00:00"));
|
|
assertThrown!DateTimeException(SysTime.fromISOString("2010-Jul-04 00:00:00."));
|
|
|
|
assertThrown!DateTimeException(SysTime.fromISOString("2010-12-22T172201"));
|
|
assertThrown!DateTimeException(SysTime.fromISOString("2010-Dec-22 17:22:01"));
|
|
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201"), SysTime(DateTime(2010, 12, 22, 17, 22, 01)));
|
|
_assertPred!"=="(SysTime.fromISOString("19990706T123033"), SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
|
|
_assertPred!"=="(SysTime.fromISOString("-19990706T123033"), SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));
|
|
_assertPred!"=="(SysTime.fromISOString("+019990706T123033"), SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
|
|
_assertPred!"=="(SysTime.fromISOString("19990706T123033 "), SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
|
|
_assertPred!"=="(SysTime.fromISOString(" 19990706T123033"), SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
|
|
_assertPred!"=="(SysTime.fromISOString(" 19990706T123033 "), SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
|
|
|
|
_assertPred!"=="(SysTime.fromISOString("19070707T121212.0"), SysTime(DateTime(1907, 07, 07, 12, 12, 12)));
|
|
_assertPred!"=="(SysTime.fromISOString("19070707T121212.0000000"), SysTime(DateTime(1907, 07, 07, 12, 12, 12)));
|
|
_assertPred!"=="(SysTime.fromISOString("19070707T121212.0000001"), SysTime(DateTime(1907, 07, 07, 12, 12, 12), FracSec.from!"hnsecs"(1)));
|
|
_assertPred!"=="(SysTime.fromISOString("19070707T121212.000001"), SysTime(DateTime(1907, 07, 07, 12, 12, 12), FracSec.from!"usecs"(1)));
|
|
_assertPred!"=="(SysTime.fromISOString("19070707T121212.0000010"), SysTime(DateTime(1907, 07, 07, 12, 12, 12), FracSec.from!"usecs"(1)));
|
|
_assertPred!"=="(SysTime.fromISOString("19070707T121212.001"), SysTime(DateTime(1907, 07, 07, 12, 12, 12), FracSec.from!"msecs"(1)));
|
|
_assertPred!"=="(SysTime.fromISOString("19070707T121212.0010000"), SysTime(DateTime(1907, 07, 07, 12, 12, 12), FracSec.from!"msecs"(1)));
|
|
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201Z"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), UTC()));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201-1:00"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(-60)));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201-1"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(-60)));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201-1:30"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(-90)));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201-8:00"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(-480)));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201+1:00"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(60)));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201+1"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(60)));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201+1:30"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(90)));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201+8:00"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(480)));
|
|
|
|
_assertPred!"=="(SysTime.fromISOString("20101103T065106.57159Z"), SysTime(DateTime(2010, 11, 3, 6, 51, 6), FracSec.from!"hnsecs"(5715900), UTC()));
|
|
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201.23412Z"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(2_341_200), UTC()));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201.23112-1:00"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(2_311_200), new SimpleTimeZone(-60)));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201.45-1"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(4_500_000), new SimpleTimeZone(-60)));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201.1-1:30"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(1_000_000), new SimpleTimeZone(-90)));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201.55-8:00"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(5_500_000), new SimpleTimeZone(-480)));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201.1234567+1:00"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(1_234_567), new SimpleTimeZone(60)));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201.0+1"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(0), new SimpleTimeZone(60)));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201.0000000+1:30"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(0), new SimpleTimeZone(90)));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201.45+8:00"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(4_500_000), new SimpleTimeZone(480)));
|
|
|
|
//Verify Examples.
|
|
assert(SysTime.fromISOString("20100704T070612") == SysTime(DateTime(2010, 7, 4, 7, 6, 12)));
|
|
assert(SysTime.fromISOString("19981225T021500.007") == SysTime(DateTime(1998, 12, 25, 2, 15, 0), FracSec.from!"msecs"(7)));
|
|
assert(SysTime.fromISOString("00000105T230959.00002") == SysTime(DateTime(0, 1, 5, 23, 9, 59), FracSec.from!"usecs"(20)));
|
|
assert(SysTime.fromISOString("-00040105T000002") == SysTime(DateTime(-4, 1, 5, 0, 0, 2)));
|
|
assert(SysTime.fromISOString(" 20100704T070612 ") == SysTime(DateTime(2010, 7, 4, 7, 6, 12)));
|
|
|
|
assert(SysTime.fromISOString("20100704T070612Z") == SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC()));
|
|
assert(SysTime.fromISOString("20100704T070612-8:00") == SysTime(DateTime(2010, 7, 4, 7, 6, 12), new SimpleTimeZone(-480)));
|
|
assert(SysTime.fromISOString("20100704T070612+8:00") == SysTime(DateTime(2010, 7, 4, 7, 6, 12), new SimpleTimeZone(480)));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Creates a $(D SysTime) from a string with the format
|
|
YYYY-MM-DDTHH:MM:SS.FFFFFFFTZ (where F is fractional seconds is the
|
|
time zone). Whitespace is stripped from the given string.
|
|
|
|
The exact format is exactly as described in $(D toISOExtString)
|
|
except that trailing zeroes are permitted - including having fractional
|
|
seconds with all zeroes. However, a decimal point with nothing following
|
|
it is invalid.
|
|
|
|
If there is no time zone in the string, then $(D LocalTime) is used. If
|
|
the time zone is "Z", then $(D UTC) is used. Otherwise, a
|
|
$(D SimpleTimeZone) which corresponds to the given offset from UTC is
|
|
used. If you wish the returned $(D SysTime) to be a particular time
|
|
zone, then pass in that time zone and the $(D SysTime) to be returned
|
|
will be converted to that time zone (though it will still be read in as
|
|
whatever time zone is in its string).
|
|
|
|
The accepted formats for time zone offsets
|
|
are +H, -H, +HH, -HH, +H:MM, -H:MM, +HH:MM, and -HH:MM.
|
|
|
|
Params:
|
|
isoString = A string formatted in the ISO Extended format for dates
|
|
and times.
|
|
tz = The time zone to convert the given time to (no
|
|
conversion occurs if null).
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given string is not in the ISO format
|
|
or if the resulting $(D SysTime) would not be valid.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(SysTime.fromISOExtString("2010-07-04T07:06:12") ==
|
|
SysTime(DateTime(2010, 7, 4, 7, 6, 12)));
|
|
assert(SysTime.fromISOExtString("1998-12-25T02:15:00.007") ==
|
|
SysTime(DateTime(1998, 12, 25, 2, 15, 0), FracSec.from!"msecs"(7)));
|
|
assert(SysTime.fromISOExtString("0000-01-05T23:09:59.00002") ==
|
|
SysTime(DateTime(0, 1, 5, 23, 9, 59), FracSec.from!"usecs"(20)));
|
|
assert(SysTime.fromISOExtString("-0004-01-05T00:00:02") ==
|
|
SysTime(DateTime(-4, 1, 5, 0, 0, 2)));
|
|
assert(SysTime.fromISOExtString(" 2010-07-04T07:06:12 ") ==
|
|
SysTime(DateTime(2010, 7, 4, 7, 6, 12)));
|
|
|
|
assert(SysTime.fromISOExtString("2010-07-04T07:06:12Z") ==
|
|
SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC()));
|
|
assert(SysTime.fromISOExtString("2010-07-04T07:06:12-8:00") ==
|
|
SysTime(DateTime(2010, 7, 4, 7, 6, 12), new SimpleTimeZone(-480)));
|
|
assert(SysTime.fromISOExtString("2010-07-04T07:06:12+8:00") ==
|
|
SysTime(DateTime(2010, 7, 4, 7, 6, 12), new SimpleTimeZone(480)));
|
|
--------------------
|
|
+/
|
|
static SysTime fromISOExtString(S)(in S isoExtString, immutable TimeZone tz = null)
|
|
if(isSomeString!(S))
|
|
{
|
|
auto dstr = to!dstring(strip(isoExtString));
|
|
|
|
auto tIndex = dstr.stds_indexOf("T");
|
|
enforce(tIndex != -1, new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
|
|
|
|
auto found = dstr[tIndex + 1 .. $].find(".", "Z", "+", "-");
|
|
auto dateTimeStr = dstr[0 .. $ - found[0].length];
|
|
|
|
dstring fracSecStr;
|
|
dstring zoneStr;
|
|
|
|
if(found[1] != 0)
|
|
{
|
|
if(found[1] == 1)
|
|
{
|
|
auto foundTZ = found[0].find("Z", "+", "-");
|
|
|
|
if(foundTZ[1] != 0)
|
|
{
|
|
fracSecStr = found[0][0 .. $ - foundTZ[0].length];
|
|
zoneStr = foundTZ[0];
|
|
}
|
|
else
|
|
fracSecStr = found[0];
|
|
}
|
|
else
|
|
zoneStr = found[0];
|
|
}
|
|
|
|
try
|
|
{
|
|
auto dateTime = DateTime.fromISOExtString(dateTimeStr);
|
|
auto fracSec = fracSecFromISOString(fracSecStr);
|
|
DTRebindable!(immutable TimeZone) parsedZone;
|
|
|
|
if(zoneStr.empty)
|
|
parsedZone = LocalTime();
|
|
else if(zoneStr == "Z")
|
|
parsedZone = UTC();
|
|
else
|
|
parsedZone = SimpleTimeZone.fromISOString(zoneStr);
|
|
|
|
auto retval = SysTime(dateTime, fracSec, parsedZone.get);
|
|
|
|
if(tz !is null)
|
|
retval.timezone = tz;
|
|
|
|
return retval;
|
|
}
|
|
catch(DateTimeException dte)
|
|
throw new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString));
|
|
}
|
|
|
|
/++
|
|
$(RED Scheduled for deprecation in November 2011.
|
|
Please use fromISOExtString instead.)
|
|
+/
|
|
static SysTime fromISOExtendedString(S)(in S isoExtString, immutable TimeZone tz = null)
|
|
if(isSomeString!(S))
|
|
{
|
|
pragma(msg, softDeprec!("2.053", "November 2011", "fromISOExtendedString", "fromISOExtString"));
|
|
|
|
return fromISOExtString!string(isoExtString, tz);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString(""));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("20100704000000"));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("20100704 000000"));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("20100704t000000"));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("20100704T000000."));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("20100704T000000.0"));
|
|
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("2010-07:0400:00:00"));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("2010-07-04 00:00:00"));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("2010-07-04 00:00:00"));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("2010-07-04t00:00:00"));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("2010-07-04T00:00:00."));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("2010-07-04T00:00:00.A"));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("2010-07-04T00:00:00.Z"));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("2010-07-04T00:00:00.00000000"));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("2010-07-04T00:00:00.00000000"));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("2010-07-04T00:00:00+"));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("2010-07-04T00:00:00-"));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("2010-07-04T00:00:00:"));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("2010-07-04T00:00:00-:"));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("2010-07-04T00:00:00+:"));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("2010-07-04T00:00:00-1:"));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("2010-07-04T00:00:00+1:"));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("2010-07-04T00:00:00+1:0"));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("2010-07-04T00:00:00-24.00"));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("2010-07-04T00:00:00+24.00"));
|
|
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("2010-Jul-0400:00:00"));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("2010-Jul-04t00:00:00"));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("2010-Jul-04 00:00:00."));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("2010-Jul-04 00:00:00.0"));
|
|
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("20101222T172201"));
|
|
assertThrown!DateTimeException(SysTime.fromISOExtString("2010-Dec-22 17:22:01"));
|
|
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-12-22T17:22:01"), SysTime(DateTime(2010, 12, 22, 17, 22, 01)));
|
|
_assertPred!"=="(SysTime.fromISOExtString("1999-07-06T12:30:33"), SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
|
|
_assertPred!"=="(SysTime.fromISOExtString("-1999-07-06T12:30:33"), SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));
|
|
_assertPred!"=="(SysTime.fromISOExtString("+01999-07-06T12:30:33"), SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
|
|
_assertPred!"=="(SysTime.fromISOExtString("1999-07-06T12:30:33 "), SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
|
|
_assertPred!"=="(SysTime.fromISOExtString(" 1999-07-06T12:30:33"), SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
|
|
_assertPred!"=="(SysTime.fromISOExtString(" 1999-07-06T12:30:33 "), SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
|
|
|
|
_assertPred!"=="(SysTime.fromISOExtString("1907-07-07T12:12:12.0"), SysTime(DateTime(1907, 07, 07, 12, 12, 12)));
|
|
_assertPred!"=="(SysTime.fromISOExtString("1907-07-07T12:12:12.0000000"), SysTime(DateTime(1907, 07, 07, 12, 12, 12)));
|
|
_assertPred!"=="(SysTime.fromISOExtString("1907-07-07T12:12:12.0000001"), SysTime(DateTime(1907, 07, 07, 12, 12, 12), FracSec.from!"hnsecs"(1)));
|
|
_assertPred!"=="(SysTime.fromISOExtString("1907-07-07T12:12:12.000001"), SysTime(DateTime(1907, 07, 07, 12, 12, 12), FracSec.from!"usecs"(1)));
|
|
_assertPred!"=="(SysTime.fromISOExtString("1907-07-07T12:12:12.0000010"), SysTime(DateTime(1907, 07, 07, 12, 12, 12), FracSec.from!"usecs"(1)));
|
|
_assertPred!"=="(SysTime.fromISOExtString("1907-07-07T12:12:12.001"), SysTime(DateTime(1907, 07, 07, 12, 12, 12), FracSec.from!"msecs"(1)));
|
|
_assertPred!"=="(SysTime.fromISOExtString("1907-07-07T12:12:12.0010000"), SysTime(DateTime(1907, 07, 07, 12, 12, 12), FracSec.from!"msecs"(1)));
|
|
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-12-22T17:22:01Z"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), UTC()));
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-12-22T17:22:01-1:00"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(-60)));
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-12-22T17:22:01-1"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(-60)));
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-12-22T17:22:01-1:30"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(-90)));
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-12-22T17:22:01-8:00"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(-480)));
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-12-22T17:22:01+1:00"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(60)));
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-12-22T17:22:01+1"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(60)));
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-12-22T17:22:01+1:30"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(90)));
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-12-22T17:22:01+8:00"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(480)));
|
|
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-11-03T06:51:06.57159Z"), SysTime(DateTime(2010, 11, 3, 6, 51, 6), FracSec.from!"hnsecs"(5715900), UTC()));
|
|
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-12-22T17:22:01.23412Z"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(2_341_200), UTC()));
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-12-22T17:22:01.23112-1:00"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(2_311_200), new SimpleTimeZone(-60)));
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-12-22T17:22:01.45-1"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(4_500_000), new SimpleTimeZone(-60)));
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-12-22T17:22:01.1-1:30"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(1_000_000), new SimpleTimeZone(-90)));
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-12-22T17:22:01.55-8:00"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(5_500_000), new SimpleTimeZone(-480)));
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-12-22T17:22:01.1234567+1:00"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(1_234_567), new SimpleTimeZone(60)));
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-12-22T17:22:01.0+1"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(0), new SimpleTimeZone(60)));
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-12-22T17:22:01.0000000+1:30"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(0), new SimpleTimeZone(90)));
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-12-22T17:22:01.45+8:00"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(4_500_000), new SimpleTimeZone(480)));
|
|
|
|
//Verify Examples.
|
|
assert(SysTime.fromISOExtString("2010-07-04T07:06:12") == SysTime(DateTime(2010, 7, 4, 7, 6, 12)));
|
|
assert(SysTime.fromISOExtString("1998-12-25T02:15:00.007") == SysTime(DateTime(1998, 12, 25, 2, 15, 0), FracSec.from!"msecs"(7)));
|
|
assert(SysTime.fromISOExtString("0000-01-05T23:09:59.00002") == SysTime(DateTime(0, 1, 5, 23, 9, 59), FracSec.from!"usecs"(20)));
|
|
assert(SysTime.fromISOExtString("-0004-01-05T00:00:02") == SysTime(DateTime(-4, 1, 5, 0, 0, 2)));
|
|
assert(SysTime.fromISOExtString(" 2010-07-04T07:06:12 ") == SysTime(DateTime(2010, 7, 4, 7, 6, 12)));
|
|
|
|
assert(SysTime.fromISOExtString("2010-07-04T07:06:12Z") == SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC()));
|
|
assert(SysTime.fromISOExtString("2010-07-04T07:06:12-8:00") == SysTime(DateTime(2010, 7, 4, 7, 6, 12), new SimpleTimeZone(-480)));
|
|
assert(SysTime.fromISOExtString("2010-07-04T07:06:12+8:00") == SysTime(DateTime(2010, 7, 4, 7, 6, 12), new SimpleTimeZone(480)));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Creates a $(D SysTime) from a string with the format
|
|
YYYY-MM-DD HH:MM:SS.FFFFFFFTZ (where F is fractional seconds is the
|
|
time zone). Whitespace is stripped from the given string.
|
|
|
|
The exact format is exactly as described in $(D toSimpleString) except
|
|
that trailing zeroes are permitted - including having fractional seconds
|
|
with all zeroes. However, a decimal point with nothing following it is
|
|
invalid.
|
|
|
|
If there is no time zone in the string, then $(D LocalTime) is used. If
|
|
the time zone is "Z", then $(D UTC) is used. Otherwise, a
|
|
$(D SimpleTimeZone) which corresponds to the given offset from UTC is
|
|
used. If you wish the returned $(D SysTime) to be a particular time
|
|
zone, then pass in that time zone and the $(D SysTime) to be returned
|
|
will be converted to that time zone (though it will still be read in as
|
|
whatever time zone is in its string).
|
|
|
|
The accepted formats for time zone offsets
|
|
are +H, -H, +HH, -HH, +H:MM, -H:MM, +HH:MM, and -HH:MM.
|
|
|
|
|
|
Params:
|
|
simpleString = A string formatted in the way that
|
|
$(D toSimpleString) formats dates and times.
|
|
tz = The time zone to convert the given time to (no
|
|
conversion occurs if null).
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given string is not in the ISO format
|
|
or if the resulting $(D SysTime) would not be valid.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12") ==
|
|
SysTime(DateTime(2010, 7, 4, 7, 6, 12)));
|
|
assert(SysTime.fromSimpleString("1998-Dec-25 02:15:00.007") ==
|
|
SysTime(DateTime(1998, 12, 25, 2, 15, 0), FracSec.from!"msecs"(7)));
|
|
assert(SysTime.fromSimpleString("0000-Jan-05 23:09:59.00002") ==
|
|
SysTime(DateTime(0, 1, 5, 23, 9, 59), FracSec.from!"usecs"(20)));
|
|
assert(SysTime.fromSimpleString("-0004-Jan-05 00:00:02") ==
|
|
SysTime(DateTime(-4, 1, 5, 0, 0, 2)));
|
|
assert(SysTime.fromSimpleString(" 2010-Jul-04 07:06:12 ") ==
|
|
SysTime(DateTime(2010, 7, 4, 7, 6, 12)));
|
|
|
|
assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12Z") ==
|
|
SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC()));
|
|
assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12-8:00") ==
|
|
SysTime(DateTime(2010, 7, 4, 7, 6, 12), new SimpleTimeZone(-480)));
|
|
assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12+8:00") ==
|
|
SysTime(DateTime(2010, 7, 4, 7, 6, 12), new SimpleTimeZone(480)));
|
|
--------------------
|
|
+/
|
|
static SysTime fromSimpleString(S)(in S simpleString, immutable TimeZone tz = null)
|
|
if(isSomeString!(S))
|
|
{
|
|
auto dstr = to!dstring(strip(simpleString));
|
|
|
|
auto spaceIndex = dstr.stds_indexOf(" ");
|
|
enforce(spaceIndex != -1, new DateTimeException(format("Invalid Simple String: %s", simpleString)));
|
|
|
|
auto found = dstr[spaceIndex + 1 .. $].find(".", "Z", "+", "-");
|
|
auto dateTimeStr = dstr[0 .. $ - found[0].length];
|
|
|
|
dstring fracSecStr;
|
|
dstring zoneStr;
|
|
|
|
if(found[1] != 0)
|
|
{
|
|
if(found[1] == 1)
|
|
{
|
|
auto foundTZ = found[0].find("Z", "+", "-");
|
|
|
|
if(foundTZ[1] != 0)
|
|
{
|
|
fracSecStr = found[0][0 .. $ - foundTZ[0].length];
|
|
zoneStr = foundTZ[0];
|
|
}
|
|
else
|
|
fracSecStr = found[0];
|
|
}
|
|
else
|
|
zoneStr = found[0];
|
|
}
|
|
|
|
try
|
|
{
|
|
auto dateTime = DateTime.fromSimpleString(dateTimeStr);
|
|
auto fracSec = fracSecFromISOString(fracSecStr);
|
|
DTRebindable!(immutable TimeZone) parsedZone;
|
|
|
|
if(zoneStr.empty)
|
|
parsedZone = LocalTime();
|
|
else if(zoneStr == "Z")
|
|
parsedZone = UTC();
|
|
else
|
|
parsedZone = SimpleTimeZone.fromISOString(zoneStr);
|
|
|
|
auto retval = SysTime(dateTime, fracSec, parsedZone.get);
|
|
|
|
if(tz !is null)
|
|
retval.timezone = tz;
|
|
|
|
return retval;
|
|
}
|
|
catch(DateTimeException dte)
|
|
throw new DateTimeException(format("Invalid Simple String: %s", simpleString));
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString(""));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("20100704000000"));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("20100704 000000"));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("20100704t000000"));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("20100704T000000."));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("20100704T000000.0"));
|
|
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("2010-07-0400:00:00"));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("2010-07-04 00:00:00"));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("2010-07-04t00:00:00"));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("2010-07-04T00:00:00."));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("2010-07-04T00:00:00.0"));
|
|
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("2010-Jul-0400:00:00"));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("2010-Jul-04t00:00:00"));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("2010-Jul-04T00:00:00"));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("2010-Jul-04 00:00:00."));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("2010-Jul-04 00:00:00.A"));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("2010-Jul-04 00:00:00.Z"));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("2010-Jul-04 00:00:00.00000000"));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("2010-Jul-04 00:00:00.00000000"));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("2010-Jul-04 00:00:00+"));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("2010-Jul-04 00:00:00-"));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("2010-Jul-04 00:00:00:"));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("2010-Jul-04 00:00:00-:"));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("2010-Jul-04 00:00:00+:"));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("2010-Jul-04 00:00:00-1:"));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("2010-Jul-04 00:00:00+1:"));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("2010-Jul-04 00:00:00+1:0"));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("2010-Jul-04 00:00:00-24.00"));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("2010-Jul-04 00:00:00+24.00"));
|
|
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("20101222T172201"));
|
|
assertThrown!DateTimeException(SysTime.fromSimpleString("2010-12-22T172201"));
|
|
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Dec-22 17:22:01"), SysTime(DateTime(2010, 12, 22, 17, 22, 01)));
|
|
_assertPred!"=="(SysTime.fromSimpleString("1999-Jul-06 12:30:33"), SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
|
|
_assertPred!"=="(SysTime.fromSimpleString("-1999-Jul-06 12:30:33"), SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));
|
|
_assertPred!"=="(SysTime.fromSimpleString("+01999-Jul-06 12:30:33"), SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
|
|
_assertPred!"=="(SysTime.fromSimpleString("1999-Jul-06 12:30:33 "), SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
|
|
_assertPred!"=="(SysTime.fromSimpleString(" 1999-Jul-06 12:30:33"), SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
|
|
_assertPred!"=="(SysTime.fromSimpleString(" 1999-Jul-06 12:30:33 "), SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
|
|
|
|
_assertPred!"=="(SysTime.fromSimpleString("1907-Jul-07 12:12:12.0"), SysTime(DateTime(1907, 07, 07, 12, 12, 12)));
|
|
_assertPred!"=="(SysTime.fromSimpleString("1907-Jul-07 12:12:12.0000000"), SysTime(DateTime(1907, 07, 07, 12, 12, 12)));
|
|
_assertPred!"=="(SysTime.fromSimpleString("1907-Jul-07 12:12:12.0000001"), SysTime(DateTime(1907, 07, 07, 12, 12, 12), FracSec.from!"hnsecs"(1)));
|
|
_assertPred!"=="(SysTime.fromSimpleString("1907-Jul-07 12:12:12.000001"), SysTime(DateTime(1907, 07, 07, 12, 12, 12), FracSec.from!"usecs"(1)));
|
|
_assertPred!"=="(SysTime.fromSimpleString("1907-Jul-07 12:12:12.0000010"), SysTime(DateTime(1907, 07, 07, 12, 12, 12), FracSec.from!"usecs"(1)));
|
|
_assertPred!"=="(SysTime.fromSimpleString("1907-Jul-07 12:12:12.001"), SysTime(DateTime(1907, 07, 07, 12, 12, 12), FracSec.from!"msecs"(1)));
|
|
_assertPred!"=="(SysTime.fromSimpleString("1907-Jul-07 12:12:12.0010000"), SysTime(DateTime(1907, 07, 07, 12, 12, 12), FracSec.from!"msecs"(1)));
|
|
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Dec-22 17:22:01Z"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), UTC()));
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Dec-22 17:22:01-1:00"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(-60)));
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Dec-22 17:22:01-1"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(-60)));
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Dec-22 17:22:01-1:30"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(-90)));
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Dec-22 17:22:01-8:00"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(-480)));
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Dec-22 17:22:01+1:00"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(60)));
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Dec-22 17:22:01+1"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(60)));
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Dec-22 17:22:01+1:30"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(90)));
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Dec-22 17:22:01+8:00"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(480)));
|
|
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Nov-03 06:51:06.57159Z"), SysTime(DateTime(2010, 11, 3, 6, 51, 6), FracSec.from!"hnsecs"(5715900), UTC()));
|
|
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Dec-22 17:22:01.23412Z"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(2_341_200), UTC()));
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Dec-22 17:22:01.23112-1:00"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(2_311_200), new SimpleTimeZone(-60)));
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Dec-22 17:22:01.45-1"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(4_500_000), new SimpleTimeZone(-60)));
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Dec-22 17:22:01.1-1:30"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(1_000_000), new SimpleTimeZone(-90)));
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Dec-22 17:22:01.55-8:00"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(5_500_000), new SimpleTimeZone(-480)));
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Dec-22 17:22:01.1234567+1:00"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(1_234_567), new SimpleTimeZone(60)));
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Dec-22 17:22:01.0+1"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(0), new SimpleTimeZone(60)));
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Dec-22 17:22:01.0000000+1:30"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(0), new SimpleTimeZone(90)));
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Dec-22 17:22:01.45+8:00"), SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(4_500_000), new SimpleTimeZone(480)));
|
|
|
|
//Verify Examples.
|
|
assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12") == SysTime(DateTime(2010, 7, 4, 7, 6, 12)));
|
|
assert(SysTime.fromSimpleString("1998-Dec-25 02:15:00.007") == SysTime(DateTime(1998, 12, 25, 2, 15, 0), FracSec.from!"msecs"(7)));
|
|
assert(SysTime.fromSimpleString("0000-Jan-05 23:09:59.00002") == SysTime(DateTime(0, 1, 5, 23, 9, 59), FracSec.from!"usecs"(20)));
|
|
assert(SysTime.fromSimpleString("-0004-Jan-05 00:00:02") == SysTime(DateTime(-4, 1, 5, 0, 0, 2)));
|
|
assert(SysTime.fromSimpleString(" 2010-Jul-04 07:06:12 ") == SysTime(DateTime(2010, 7, 4, 7, 6, 12)));
|
|
|
|
assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12Z") == SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC()));
|
|
assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12-8:00") == SysTime(DateTime(2010, 7, 4, 7, 6, 12), new SimpleTimeZone(-480)));
|
|
assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12+8:00") == SysTime(DateTime(2010, 7, 4, 7, 6, 12), new SimpleTimeZone(480)));
|
|
}
|
|
}
|
|
|
|
|
|
//TODO Add function which takes a user-specified time format and produces a SysTime
|
|
|
|
//TODO Add function which takes pretty much any time-string and produces a SysTime.
|
|
// Obviously, it will be less efficient, and it probably won't manage _every_
|
|
// possible date format, but a smart conversion function would be nice.
|
|
|
|
|
|
/++
|
|
Returns the $(D SysTime) farthest in the past which is representable
|
|
by $(D SysTime).
|
|
|
|
The $(D SysTime) which is returned is in UTC.
|
|
+/
|
|
@property static SysTime min() pure nothrow
|
|
{
|
|
return SysTime(long.min, UTC());
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assert(SysTime.min.year < 0);
|
|
assert(SysTime.min < SysTime.max);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the $(D SysTime) farthest in the future which is representable
|
|
by $(D SysTime).
|
|
|
|
The $(D SysTime) which is returned is in UTC.
|
|
+/
|
|
@property static SysTime max() pure nothrow
|
|
{
|
|
return SysTime(long.max, UTC());
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assert(SysTime.max.year > 0);
|
|
assert(SysTime.max > SysTime.min);
|
|
}
|
|
}
|
|
|
|
|
|
private:
|
|
|
|
/+
|
|
Returns $(D stdTime) converted to $(D SysTime)'s time zone.
|
|
+/
|
|
@property long adjTime() const nothrow
|
|
{
|
|
return _timezone.utcToTZ(_stdTime);
|
|
}
|
|
|
|
|
|
/+
|
|
Converts the given hnsecs from $(D SysTime)'s time zone to std time.
|
|
+/
|
|
@property void adjTime(long adjTime) nothrow
|
|
{
|
|
_stdTime = _timezone.tzToUTC(adjTime);
|
|
}
|
|
|
|
|
|
//Commented out due to bug http://d.puremagic.com/issues/show_bug.cgi?id=5058
|
|
/+
|
|
invariant()
|
|
{
|
|
assert(_timezone.get !is null, "Invariant Failure: timezone is null. Were you foolish enough to use SysTime.init? (since timezone for SysTime.init can't be set at compile time).");
|
|
}
|
|
+/
|
|
|
|
|
|
long _stdTime;
|
|
DTRebindable!(immutable TimeZone) _timezone;
|
|
}
|
|
|
|
|
|
/++
|
|
Represents a date in the Proleptic Gregorian Calendar ranging from
|
|
32,768 B.C. to 32,767 A.D. Positive years are A.D. Non-positive years are
|
|
B.C.
|
|
|
|
Year, month, and day are kept separately internally so that $(D Date) is
|
|
optimized for calendar-based operations.
|
|
|
|
$(D Date) uses the Proleptic Gregorian Calendar, so it assumes the Gregorian
|
|
leap year calculations for its entire length. And, as per
|
|
$(WEB en.wikipedia.org/wiki/ISO_8601, ISO 8601), it also treats 1 B.C. as
|
|
year 0. So, 1 B.C. is 0, 2 B.C. is -1, etc. Use $(D yearBC) if want B.C. as
|
|
a positive integer with 1 B.C. being the year prior to 1 A.D.
|
|
|
|
Year 0 is a leap year.
|
|
+/
|
|
struct Date
|
|
{
|
|
public:
|
|
|
|
/++
|
|
Throws:
|
|
$(D DateTimeException) if the resulting $(D Date) would not be valid.
|
|
|
|
Params:
|
|
year = Year of the Gregorian Calendar. Positive values are A.D.
|
|
Non-positive values are B.C. with year 0 being the year
|
|
prior to 1 A.D.
|
|
month = Month of the year.
|
|
day = Day of the month.
|
|
+/
|
|
this(int year, int month, int day) pure
|
|
{
|
|
enforceValid!"months"(cast(Month)month);
|
|
enforceValid!"days"(year, cast(Month)month, day);
|
|
|
|
_year = cast(short)year;
|
|
_month = cast(Month)month;
|
|
_day = cast(ubyte)day;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(Date(1, 1, 1), Date.init);
|
|
|
|
static void testDate(in Date date, int year, int month, int day, size_t line = __LINE__)
|
|
{
|
|
_assertPred!"=="(date._year, year, "", __FILE__, line);
|
|
_assertPred!"=="(date._month, month, "", __FILE__, line);
|
|
_assertPred!"=="(date._day, day, "", __FILE__, line);
|
|
}
|
|
|
|
testDate(Date(1999, 1 , 1), 1999, Month.jan, 1);
|
|
testDate(Date(1999, 7 , 1), 1999, Month.jul, 1);
|
|
testDate(Date(1999, 7 , 6), 1999, Month.jul, 6);
|
|
|
|
//Test A.D.
|
|
assertThrown!DateTimeException(Date(1, 0, 1));
|
|
assertThrown!DateTimeException(Date(1, 1, 0));
|
|
assertThrown!DateTimeException(Date(1999, 13, 1));
|
|
assertThrown!DateTimeException(Date(1999, 1, 32));
|
|
assertThrown!DateTimeException(Date(1999, 2, 29));
|
|
assertThrown!DateTimeException(Date(2000, 2, 30));
|
|
assertThrown!DateTimeException(Date(1999, 3, 32));
|
|
assertThrown!DateTimeException(Date(1999, 4, 31));
|
|
assertThrown!DateTimeException(Date(1999, 5, 32));
|
|
assertThrown!DateTimeException(Date(1999, 6, 31));
|
|
assertThrown!DateTimeException(Date(1999, 7, 32));
|
|
assertThrown!DateTimeException(Date(1999, 8, 32));
|
|
assertThrown!DateTimeException(Date(1999, 9, 31));
|
|
assertThrown!DateTimeException(Date(1999, 10, 32));
|
|
assertThrown!DateTimeException(Date(1999, 11, 31));
|
|
assertThrown!DateTimeException(Date(1999, 12, 32));
|
|
|
|
assertNotThrown!DateTimeException(Date(1999, 1, 31));
|
|
assertNotThrown!DateTimeException(Date(1999, 2, 28));
|
|
assertNotThrown!DateTimeException(Date(2000, 2, 29));
|
|
assertNotThrown!DateTimeException(Date(1999, 3, 31));
|
|
assertNotThrown!DateTimeException(Date(1999, 4, 30));
|
|
assertNotThrown!DateTimeException(Date(1999, 5, 31));
|
|
assertNotThrown!DateTimeException(Date(1999, 6, 30));
|
|
assertNotThrown!DateTimeException(Date(1999, 7, 31));
|
|
assertNotThrown!DateTimeException(Date(1999, 8, 31));
|
|
assertNotThrown!DateTimeException(Date(1999, 9, 30));
|
|
assertNotThrown!DateTimeException(Date(1999, 10, 31));
|
|
assertNotThrown!DateTimeException(Date(1999, 11, 30));
|
|
assertNotThrown!DateTimeException(Date(1999, 12, 31));
|
|
|
|
//Test B.C.
|
|
assertNotThrown!DateTimeException(Date(0, 1, 1));
|
|
assertNotThrown!DateTimeException(Date(-1, 1, 1));
|
|
assertNotThrown!DateTimeException(Date(-1, 12, 31));
|
|
assertNotThrown!DateTimeException(Date(-1, 2, 28));
|
|
assertNotThrown!DateTimeException(Date(-4, 2, 29));
|
|
|
|
assertThrown!DateTimeException(Date(-1, 2, 29));
|
|
assertThrown!DateTimeException(Date(-2, 2, 29));
|
|
assertThrown!DateTimeException(Date(-3, 2, 29));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Params:
|
|
day = The Xth day of the Gregorian Calendar that the constructed
|
|
$(D Date) will be for.
|
|
+/
|
|
this(int day) pure nothrow
|
|
{
|
|
if(day > 0)
|
|
{
|
|
int years = (day / daysIn400Years) * 400 + 1;
|
|
day %= daysIn400Years;
|
|
|
|
{
|
|
immutable tempYears = day / daysIn100Years;
|
|
|
|
if(tempYears == 4)
|
|
{
|
|
years += 300;
|
|
day -= daysIn100Years * 3;
|
|
}
|
|
else
|
|
{
|
|
years += tempYears * 100;
|
|
day %= daysIn100Years;
|
|
}
|
|
}
|
|
|
|
years += (day / daysIn4Years) * 4;
|
|
day %= daysIn4Years;
|
|
|
|
{
|
|
immutable tempYears = day / daysInYear;
|
|
|
|
if(tempYears == 4)
|
|
{
|
|
years += 3;
|
|
day -= daysInYear * 3;
|
|
}
|
|
else
|
|
{
|
|
years += tempYears;
|
|
day %= daysInYear;
|
|
}
|
|
}
|
|
|
|
if(day == 0)
|
|
{
|
|
_year = cast(short)(years - 1);
|
|
_month = Month.dec;
|
|
_day = 31;
|
|
}
|
|
else
|
|
{
|
|
_year = cast(short)years;
|
|
|
|
try
|
|
dayOfYear = day;
|
|
catch(Exception e)
|
|
assert(0, "dayOfYear assignment threw.");
|
|
}
|
|
}
|
|
else if(day <= 0 && -day < daysInLeapYear)
|
|
{
|
|
_year = 0;
|
|
|
|
try
|
|
dayOfYear = (daysInLeapYear + day);
|
|
catch(Exception e)
|
|
assert(0, "dayOfYear assignment threw.");
|
|
}
|
|
else
|
|
{
|
|
day += daysInLeapYear - 1;
|
|
int years = (day / daysIn400Years) * 400 - 1;
|
|
day %= daysIn400Years;
|
|
|
|
{
|
|
immutable tempYears = day / daysIn100Years;
|
|
|
|
if(tempYears == -4)
|
|
{
|
|
years -= 300;
|
|
day += daysIn100Years * 3;
|
|
}
|
|
else
|
|
{
|
|
years += tempYears * 100;
|
|
day %= daysIn100Years;
|
|
}
|
|
}
|
|
|
|
years += (day / daysIn4Years) * 4;
|
|
day %= daysIn4Years;
|
|
|
|
{
|
|
immutable tempYears = day / daysInYear;
|
|
|
|
if(tempYears == -4)
|
|
{
|
|
years -= 3;
|
|
day += daysInYear * 3;
|
|
}
|
|
else
|
|
{
|
|
years += tempYears;
|
|
day %= daysInYear;
|
|
}
|
|
}
|
|
|
|
if(day == 0)
|
|
{
|
|
_year = cast(short)(years + 1);
|
|
_month = Month.jan;
|
|
_day = 1;
|
|
}
|
|
else
|
|
{
|
|
_year = cast(short)years;
|
|
immutable newDoY = (yearIsLeapYear(_year) ? daysInLeapYear : daysInYear) + day + 1;
|
|
|
|
try
|
|
dayOfYear = newDoY;
|
|
catch(Exception e)
|
|
assert(0, "dayOfYear assignment threw.");
|
|
}
|
|
}
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
//Test A.D.
|
|
foreach(gd; chain(testGregDaysBC, testGregDaysAD))
|
|
_assertPred!"=="(Date(gd.day), gd.date);
|
|
}
|
|
|
|
|
|
/++
|
|
Compares this $(D Date) with the given $(D Date).
|
|
|
|
Returns:
|
|
$(BOOKTABLE,
|
|
$(TR $(TD this < rhs) $(TD < 0))
|
|
$(TR $(TD this == rhs) $(TD 0))
|
|
$(TR $(TD this > rhs) $(TD > 0))
|
|
)
|
|
+/
|
|
int opCmp(in Date rhs) const pure nothrow
|
|
{
|
|
if(_year < rhs._year)
|
|
return -1;
|
|
if(_year > rhs._year)
|
|
return 1;
|
|
|
|
if(_month < rhs._month)
|
|
return -1;
|
|
if(_month > rhs._month)
|
|
return 1;
|
|
|
|
if(_day < rhs._day)
|
|
return -1;
|
|
if(_day > rhs._day)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
_assertPred!("opCmp", "==")(Date(1, 1, 1), Date.init);
|
|
|
|
_assertPred!("opCmp", "==")(Date(1999, 1, 1), Date(1999, 1, 1));
|
|
_assertPred!("opCmp", "==")(Date(1, 7, 1), Date(1, 7, 1));
|
|
_assertPred!("opCmp", "==")(Date(1, 1, 6), Date(1, 1, 6));
|
|
|
|
_assertPred!("opCmp", "==")(Date(1999, 7, 1), Date(1999, 7, 1));
|
|
_assertPred!("opCmp", "==")(Date(1999, 7, 6), Date(1999, 7, 6));
|
|
|
|
_assertPred!("opCmp", "==")(Date(1, 7, 6), Date(1, 7, 6));
|
|
|
|
_assertPred!("opCmp", "<")(Date(1999, 7, 6), Date(2000, 7, 6));
|
|
_assertPred!("opCmp", ">")(Date(2000, 7, 6), Date(1999, 7, 6));
|
|
_assertPred!("opCmp", "<")(Date(1999, 7, 6), Date(1999, 8, 6));
|
|
_assertPred!("opCmp", ">")(Date(1999, 8, 6), Date(1999, 7, 6));
|
|
_assertPred!("opCmp", "<")(Date(1999, 7, 6), Date(1999, 7, 7));
|
|
_assertPred!("opCmp", ">")(Date(1999, 7, 7), Date(1999, 7, 6));
|
|
|
|
_assertPred!("opCmp", "<")(Date(1999, 8, 7), Date(2000, 7, 6));
|
|
_assertPred!("opCmp", ">")(Date(2000, 8, 6), Date(1999, 7, 7));
|
|
_assertPred!("opCmp", "<")(Date(1999, 7, 7), Date(2000, 7, 6));
|
|
_assertPred!("opCmp", ">")(Date(2000, 7, 6), Date(1999, 7, 7));
|
|
_assertPred!("opCmp", "<")(Date(1999, 7, 7), Date(1999, 8, 6));
|
|
_assertPred!("opCmp", ">")(Date(1999, 8, 6), Date(1999, 7, 7));
|
|
|
|
//Test B.C.
|
|
_assertPred!("opCmp", "==")(Date(0, 1, 1), Date(0, 1, 1));
|
|
_assertPred!("opCmp", "==")(Date(-1, 1, 1), Date(-1, 1, 1));
|
|
_assertPred!("opCmp", "==")(Date(-1, 7, 1), Date(-1, 7, 1));
|
|
_assertPred!("opCmp", "==")(Date(-1, 1, 6), Date(-1, 1, 6));
|
|
|
|
_assertPred!("opCmp", "==")(Date(-1999, 7, 1), Date(-1999, 7, 1));
|
|
_assertPred!("opCmp", "==")(Date(-1999, 7, 6), Date(-1999, 7, 6));
|
|
|
|
_assertPred!("opCmp", "==")(Date(-1, 7, 6), Date(-1, 7, 6));
|
|
|
|
_assertPred!("opCmp", "<")(Date(-2000, 7, 6), Date(-1999, 7, 6));
|
|
_assertPred!("opCmp", ">")(Date(-1999, 7, 6), Date(-2000, 7, 6));
|
|
_assertPred!("opCmp", "<")(Date(-1999, 7, 6), Date(-1999, 8, 6));
|
|
_assertPred!("opCmp", ">")(Date(-1999, 8, 6), Date(-1999, 7, 6));
|
|
_assertPred!("opCmp", "<")(Date(-1999, 7, 6), Date(-1999, 7, 7));
|
|
_assertPred!("opCmp", ">")(Date(-1999, 7, 7), Date(-1999, 7, 6));
|
|
|
|
_assertPred!("opCmp", "<")(Date(-2000, 8, 6), Date(-1999, 7, 7));
|
|
_assertPred!("opCmp", ">")(Date(-1999, 8, 7), Date(-2000, 7, 6));
|
|
_assertPred!("opCmp", "<")(Date(-2000, 7, 6), Date(-1999, 7, 7));
|
|
_assertPred!("opCmp", ">")(Date(-1999, 7, 7), Date(-2000, 7, 6));
|
|
_assertPred!("opCmp", "<")(Date(-1999, 7, 7), Date(-1999, 8, 6));
|
|
_assertPred!("opCmp", ">")(Date(-1999, 8, 6), Date(-1999, 7, 7));
|
|
|
|
//Test Both
|
|
_assertPred!("opCmp", "<")(Date(-1999, 7, 6), Date(1999, 7, 6));
|
|
_assertPred!("opCmp", ">")(Date(1999, 7, 6), Date(-1999, 7, 6));
|
|
|
|
_assertPred!("opCmp", "<")(Date(-1999, 8, 6), Date(1999, 7, 6));
|
|
_assertPred!("opCmp", ">")(Date(1999, 7, 6), Date(-1999, 8, 6));
|
|
|
|
_assertPred!("opCmp", "<")(Date(-1999, 7, 7), Date(1999, 7, 6));
|
|
_assertPred!("opCmp", ">")(Date(1999, 7, 6), Date(-1999, 7, 7));
|
|
|
|
_assertPred!("opCmp", "<")(Date(-1999, 8, 7), Date(1999, 7, 6));
|
|
_assertPred!("opCmp", ">")(Date(1999, 7, 6), Date(-1999, 8, 7));
|
|
|
|
_assertPred!("opCmp", "<")(Date(-1999, 8, 6), Date(1999, 6, 6));
|
|
_assertPred!("opCmp", ">")(Date(1999, 6, 8), Date(-1999, 7, 6));
|
|
|
|
auto date = Date(1999, 7, 6);
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(__traits(compiles, date.opCmp(date)));
|
|
static assert(__traits(compiles, date.opCmp(cdate)));
|
|
static assert(__traits(compiles, date.opCmp(idate)));
|
|
static assert(__traits(compiles, cdate.opCmp(date)));
|
|
static assert(__traits(compiles, cdate.opCmp(cdate)));
|
|
static assert(__traits(compiles, cdate.opCmp(idate)));
|
|
static assert(__traits(compiles, idate.opCmp(date)));
|
|
static assert(__traits(compiles, idate.opCmp(cdate)));
|
|
static assert(__traits(compiles, idate.opCmp(idate)));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive
|
|
are B.C.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Date(1999, 7, 6).year == 1999);
|
|
assert(Date(2010, 10, 4).year == 2010);
|
|
assert(Date(-7, 4, 5).year == -7);
|
|
--------------------
|
|
+/
|
|
@property short year() const pure nothrow
|
|
{
|
|
return _year;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(Date.init.year, 1);
|
|
_assertPred!"=="(Date(1999, 7, 6).year, 1999);
|
|
_assertPred!"=="(Date(-1999, 7, 6).year, -1999);
|
|
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(__traits(compiles, cdate.year == 1999));
|
|
static assert(__traits(compiles, idate.year == 1999));
|
|
|
|
//Verify Examples.
|
|
assert(Date(1999, 7, 6).year == 1999);
|
|
assert(Date(2010, 10, 4).year == 2010);
|
|
assert(Date(-7, 4, 5).year == -7);
|
|
}
|
|
}
|
|
|
|
/++
|
|
Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive
|
|
are B.C.
|
|
|
|
Params:
|
|
year = The year to set this Date's year to.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the new year is not a leap year and the
|
|
resulting date would be on February 29th.
|
|
+/
|
|
@property void year(int year) pure
|
|
{
|
|
enforceValid!"days"(year, _month, _day);
|
|
_year = cast(short)year;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static void testDateInvalid(Date date, int year)
|
|
{
|
|
date.year = year;
|
|
}
|
|
|
|
static void testDate(Date date, int year, in Date expected, size_t line = __LINE__)
|
|
{
|
|
date.year = year;
|
|
_assertPred!"=="(date, expected, "", __FILE__, line);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testDateInvalid(Date(4, 2, 29), 1));
|
|
|
|
testDate(Date(1, 1, 1), 1999, Date(1999, 1, 1));
|
|
testDate(Date(1, 1, 1), 0, Date(0, 1, 1));
|
|
testDate(Date(1, 1, 1), -1999, Date(-1999, 1, 1));
|
|
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(!__traits(compiles, cdate.year = 1999));
|
|
static assert(!__traits(compiles, idate.year = 1999));
|
|
|
|
//Verify Examples.
|
|
assert(Date(1999, 7, 6).year == 1999);
|
|
assert(Date(2010, 10, 4).year == 2010);
|
|
assert(Date(-7, 4, 5).year == -7);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if $(D isAD) is true.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Date(0, 1, 1).yearBC == 1);
|
|
assert(Date(-1, 1, 1).yearBC == 2);
|
|
assert(Date(-100, 1, 1).yearBC == 101);
|
|
--------------------
|
|
+/
|
|
@property ushort yearBC() const pure
|
|
{
|
|
if(isAD)
|
|
throw new DateTimeException("Year " ~ numToString(_year) ~ " is A.D.");
|
|
//Once format is pure, this would be a better error message.
|
|
//throw new DateTimeException(format("%s is A.D.", this));
|
|
|
|
return cast(ushort)((_year * -1) + 1);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assertThrown!DateTimeException((in Date date){date.yearBC;}(Date(1, 1, 1)));
|
|
|
|
auto date = Date(0, 7, 6);
|
|
const cdate = Date(0, 7, 6);
|
|
immutable idate = Date(0, 7, 6);
|
|
static assert(__traits(compiles, date.yearBC));
|
|
static assert(__traits(compiles, cdate.yearBC));
|
|
static assert(__traits(compiles, idate.yearBC));
|
|
|
|
//Verify Examples.
|
|
assert(Date(0, 1, 1).yearBC == 1);
|
|
assert(Date(-1, 1, 1).yearBC == 2);
|
|
assert(Date(-100, 1, 1).yearBC == 101);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C.
|
|
|
|
Params:
|
|
year = The year B.C. to set this $(D Date)'s year to.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if a non-positive value is given.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto date = Date(2010, 1, 1);
|
|
date.yearBC = 1;
|
|
assert(date == Date(0, 1, 1));
|
|
|
|
date.yearBC = 10;
|
|
assert(date == Date(-9, 1, 1));
|
|
--------------------
|
|
+/
|
|
@property void yearBC(int year) pure
|
|
{
|
|
if(year <= 0)
|
|
throw new DateTimeException("The given year is not a year B.C.");
|
|
|
|
_year = cast(short)((year - 1) * -1);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assertThrown!DateTimeException((Date date){date.yearBC = -1;}(Date(1, 1, 1)));
|
|
|
|
{
|
|
auto date = Date(0, 7, 6);
|
|
const cdate = Date(0, 7, 6);
|
|
immutable idate = Date(0, 7, 6);
|
|
static assert(__traits(compiles, date.yearBC = 7));
|
|
static assert(!__traits(compiles, cdate.yearBC = 7));
|
|
static assert(!__traits(compiles, idate.yearBC = 7));
|
|
}
|
|
|
|
//Verify Examples.
|
|
{
|
|
auto date = Date(2010, 1, 1);
|
|
date.yearBC = 1;
|
|
assert(date == Date(0, 1, 1));
|
|
|
|
date.yearBC = 10;
|
|
assert(date == Date(-9, 1, 1));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Month of a Gregorian Year.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Date(1999, 7, 6).month == 7);
|
|
assert(Date(2010, 10, 4).month == 10);
|
|
assert(Date(-7, 4, 5).month == 4);
|
|
--------------------
|
|
+/
|
|
@property Month month() const pure nothrow
|
|
{
|
|
return _month;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(Date.init.month, 1);
|
|
_assertPred!"=="(Date(1999, 7, 6).month, 7);
|
|
_assertPred!"=="(Date(-1999, 7, 6).month, 7);
|
|
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(__traits(compiles, cdate.month == 7));
|
|
static assert(__traits(compiles, idate.month == 7));
|
|
|
|
//Verify Examples.
|
|
assert(Date(1999, 7, 6).month == 7);
|
|
assert(Date(2010, 10, 4).month == 10);
|
|
assert(Date(-7, 4, 5).month == 4);
|
|
}
|
|
}
|
|
|
|
/++
|
|
Month of a Gregorian Year.
|
|
|
|
Params:
|
|
month = The month to set this $(D Date)'s month to.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given month is not a valid month or if
|
|
the current day would not be valid in the given month.
|
|
+/
|
|
@property void month(Month month) pure
|
|
{
|
|
enforceValid!"months"(month);
|
|
enforceValid!"days"(_year, month, _day);
|
|
_month = cast(Month)month;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static void testDate(Date date, Month month, in Date expected = Date.init, size_t line = __LINE__)
|
|
{
|
|
date.month = month;
|
|
assert(expected != Date.init);
|
|
_assertPred!"=="(date, expected, "", __FILE__, line);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testDate(Date(1, 1, 1), cast(Month)0));
|
|
assertThrown!DateTimeException(testDate(Date(1, 1, 1), cast(Month)13));
|
|
assertThrown!DateTimeException(testDate(Date(1, 1, 29), cast(Month)2));
|
|
assertThrown!DateTimeException(testDate(Date(0, 1, 30), cast(Month)2));
|
|
|
|
testDate(Date(1, 1, 1), cast(Month)7, Date(1, 7, 1));
|
|
testDate(Date(-1, 1, 1), cast(Month)7, Date(-1, 7, 1));
|
|
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(!__traits(compiles, cdate.month = 7));
|
|
static assert(!__traits(compiles, idate.month = 7));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Day of a Gregorian Month.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Date(1999, 7, 6).day == 6);
|
|
assert(Date(2010, 10, 4).day == 4);
|
|
assert(Date(-7, 4, 5).day == 5);
|
|
--------------------
|
|
+/
|
|
@property ubyte day() const pure nothrow
|
|
{
|
|
return _day;
|
|
}
|
|
|
|
//Verify Examples.
|
|
version(testStdDateTime) unittest
|
|
{
|
|
assert(Date(1999, 7, 6).day == 6);
|
|
assert(Date(2010, 10, 4).day == 4);
|
|
assert(Date(-7, 4, 5).day == 5);
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
static void test(Date date, int expected, size_t line = __LINE__)
|
|
{
|
|
_assertPred!"=="(date.day, expected,
|
|
format("Value given: %s", date), __FILE__, line);
|
|
}
|
|
|
|
foreach(year; chain(testYearsBC, testYearsAD))
|
|
{
|
|
foreach(md; testMonthDays)
|
|
test(Date(year, md.month, md.day), md.day);
|
|
}
|
|
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(__traits(compiles, cdate.day == 6));
|
|
static assert(__traits(compiles, idate.day == 6));
|
|
}
|
|
|
|
/++
|
|
Day of a Gregorian Month.
|
|
|
|
Params:
|
|
day = The day of the month to set this $(D Date)'s day to.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given day is not a valid day of the
|
|
current month.
|
|
+/
|
|
@property void day(int day) pure
|
|
{
|
|
enforceValid!"days"(_year, _month, day);
|
|
_day = cast(ubyte)day;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static void testDate(Date date, int day)
|
|
{
|
|
date.day = day;
|
|
}
|
|
|
|
//Test A.D.
|
|
assertThrown!DateTimeException(testDate(Date(1, 1, 1), 0));
|
|
assertThrown!DateTimeException(testDate(Date(1, 1, 1), 32));
|
|
assertThrown!DateTimeException(testDate(Date(1, 2, 1), 29));
|
|
assertThrown!DateTimeException(testDate(Date(4, 2, 1), 30));
|
|
assertThrown!DateTimeException(testDate(Date(1, 3, 1), 32));
|
|
assertThrown!DateTimeException(testDate(Date(1, 4, 1), 31));
|
|
assertThrown!DateTimeException(testDate(Date(1, 5, 1), 32));
|
|
assertThrown!DateTimeException(testDate(Date(1, 6, 1), 31));
|
|
assertThrown!DateTimeException(testDate(Date(1, 7, 1), 32));
|
|
assertThrown!DateTimeException(testDate(Date(1, 8, 1), 32));
|
|
assertThrown!DateTimeException(testDate(Date(1, 9, 1), 31));
|
|
assertThrown!DateTimeException(testDate(Date(1, 10, 1), 32));
|
|
assertThrown!DateTimeException(testDate(Date(1, 11, 1), 31));
|
|
assertThrown!DateTimeException(testDate(Date(1, 12, 1), 32));
|
|
|
|
assertNotThrown!DateTimeException(testDate(Date(1, 1, 1), 31));
|
|
assertNotThrown!DateTimeException(testDate(Date(1, 2, 1), 28));
|
|
assertNotThrown!DateTimeException(testDate(Date(4, 2, 1), 29));
|
|
assertNotThrown!DateTimeException(testDate(Date(1, 3, 1), 31));
|
|
assertNotThrown!DateTimeException(testDate(Date(1, 4, 1), 30));
|
|
assertNotThrown!DateTimeException(testDate(Date(1, 5, 1), 31));
|
|
assertNotThrown!DateTimeException(testDate(Date(1, 6, 1), 30));
|
|
assertNotThrown!DateTimeException(testDate(Date(1, 7, 1), 31));
|
|
assertNotThrown!DateTimeException(testDate(Date(1, 8, 1), 31));
|
|
assertNotThrown!DateTimeException(testDate(Date(1, 9, 1), 30));
|
|
assertNotThrown!DateTimeException(testDate(Date(1, 10, 1), 31));
|
|
assertNotThrown!DateTimeException(testDate(Date(1, 11, 1), 30));
|
|
assertNotThrown!DateTimeException(testDate(Date(1, 12, 1), 31));
|
|
|
|
{
|
|
auto date = Date(1, 1, 1);
|
|
date.day = 6;
|
|
_assertPred!"=="(date, Date(1, 1, 6));
|
|
}
|
|
|
|
//Test B.C.
|
|
assertThrown!DateTimeException(testDate(Date(-1, 1, 1), 0));
|
|
assertThrown!DateTimeException(testDate(Date(-1, 1, 1), 32));
|
|
assertThrown!DateTimeException(testDate(Date(-1, 2, 1), 29));
|
|
assertThrown!DateTimeException(testDate(Date(0, 2, 1), 30));
|
|
assertThrown!DateTimeException(testDate(Date(-1, 3, 1), 32));
|
|
assertThrown!DateTimeException(testDate(Date(-1, 4, 1), 31));
|
|
assertThrown!DateTimeException(testDate(Date(-1, 5, 1), 32));
|
|
assertThrown!DateTimeException(testDate(Date(-1, 6, 1), 31));
|
|
assertThrown!DateTimeException(testDate(Date(-1, 7, 1), 32));
|
|
assertThrown!DateTimeException(testDate(Date(-1, 8, 1), 32));
|
|
assertThrown!DateTimeException(testDate(Date(-1, 9, 1), 31));
|
|
assertThrown!DateTimeException(testDate(Date(-1, 10, 1), 32));
|
|
assertThrown!DateTimeException(testDate(Date(-1, 11, 1), 31));
|
|
assertThrown!DateTimeException(testDate(Date(-1, 12, 1), 32));
|
|
|
|
assertNotThrown!DateTimeException(testDate(Date(-1, 1, 1), 31));
|
|
assertNotThrown!DateTimeException(testDate(Date(-1, 2, 1), 28));
|
|
assertNotThrown!DateTimeException(testDate(Date(0, 2, 1), 29));
|
|
assertNotThrown!DateTimeException(testDate(Date(-1, 3, 1), 31));
|
|
assertNotThrown!DateTimeException(testDate(Date(-1, 4, 1), 30));
|
|
assertNotThrown!DateTimeException(testDate(Date(-1, 5, 1), 31));
|
|
assertNotThrown!DateTimeException(testDate(Date(-1, 6, 1), 30));
|
|
assertNotThrown!DateTimeException(testDate(Date(-1, 7, 1), 31));
|
|
assertNotThrown!DateTimeException(testDate(Date(-1, 8, 1), 31));
|
|
assertNotThrown!DateTimeException(testDate(Date(-1, 9, 1), 30));
|
|
assertNotThrown!DateTimeException(testDate(Date(-1, 10, 1), 31));
|
|
assertNotThrown!DateTimeException(testDate(Date(-1, 11, 1), 30));
|
|
assertNotThrown!DateTimeException(testDate(Date(-1, 12, 1), 31));
|
|
|
|
{
|
|
auto date = Date(-1, 1, 1);
|
|
date.day = 6;
|
|
_assertPred!"=="(date, Date(-1, 1, 6));
|
|
}
|
|
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(!__traits(compiles, cdate.day = 6));
|
|
static assert(!__traits(compiles, idate.day = 6));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Adds the given number of years or months to this $(D Date). A negative
|
|
number will subtract.
|
|
|
|
Note that if day overflow is allowed, and the date with the adjusted
|
|
year/month overflows the number of days in the new month, then the month
|
|
will be incremented by one, and the day set to the number of days
|
|
overflowed. (e.g. if the day were 31 and the new month were June, then
|
|
the month would be incremented to July, and the new day would be 1). If
|
|
day overflow is not allowed, then the day will be set to the last valid
|
|
day in the month (e.g. June 31st would become June 30th).
|
|
|
|
Params:
|
|
units = The type of units to add ("years" or "months").
|
|
value = The number of months or years to add to this
|
|
$(D Date).
|
|
allowOverflow = Whether the day should be allowed to overflow,
|
|
causing the month to increment.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto d1 = Date(2010, 1, 1);
|
|
d1.add!"months"(11);
|
|
assert(d1 == Date(2010, 12, 1));
|
|
|
|
auto d2 = Date(2010, 1, 1);
|
|
d2.add!"months"(-11);
|
|
assert(d2 == Date(2009, 2, 1));
|
|
|
|
auto d3 = Date(2000, 2, 29);
|
|
d3.add!"years"(1);
|
|
assert(d3 == Date(2001, 3, 1));
|
|
|
|
auto d4 = Date(2000, 2, 29);
|
|
d4.add!"years"(1, AllowDayOverflow.no);
|
|
assert(d4 == Date(2001, 2, 28));
|
|
--------------------
|
|
+/
|
|
/+ref Date+/ void add(string units)(long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) pure nothrow
|
|
if(units == "years")
|
|
{
|
|
immutable newYear = _year + value;
|
|
|
|
_year += value;
|
|
|
|
if(_month == Month.feb && _day == 29 && !yearIsLeapYear(_year))
|
|
{
|
|
if(allowOverflow == AllowDayOverflow.yes)
|
|
{
|
|
_month = Month.mar;
|
|
_day = 1;
|
|
}
|
|
else
|
|
_day = 28;
|
|
}
|
|
}
|
|
|
|
//Verify Examples.
|
|
unittest
|
|
{
|
|
version(stdStdDateTime)
|
|
{
|
|
auto d1 = Date(2010, 1, 1);
|
|
d1.add!"months"(11);
|
|
assert(d1 == Date(2010, 12, 1));
|
|
|
|
auto d2 = Date(2010, 1, 1);
|
|
d2.add!"months"(-11);
|
|
assert(d2 == Date(2009, 2, 1));
|
|
|
|
auto d3 = Date(2000, 2, 29);
|
|
d3.add!"years"(1);
|
|
assert(d3 == Date(2001, 3, 1));
|
|
|
|
auto d4 = Date(2000, 2, 29);
|
|
d4.add!"years"(1, AllowDayOverflow.no);
|
|
assert(d4 == Date(2001, 2, 28));
|
|
}
|
|
}
|
|
|
|
//Test add!"years"() with AllowDayOverlow.yes
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
{
|
|
auto date = Date(1999, 7, 6);
|
|
date.add!"years"(7);
|
|
_assertPred!"=="(date, Date(2006, 7, 6));
|
|
date.add!"years"(-9);
|
|
_assertPred!"=="(date, Date(1997, 7, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 2, 28);
|
|
date.add!"years"(1);
|
|
_assertPred!"=="(date, Date(2000, 2, 28));
|
|
}
|
|
|
|
{
|
|
auto date = Date(2000, 2, 29);
|
|
date.add!"years"(-1);
|
|
_assertPred!"=="(date, Date(1999, 3, 1));
|
|
}
|
|
|
|
//Test B.C.
|
|
{
|
|
auto date = Date(-1999, 7, 6);
|
|
date.add!"years"(-7);
|
|
_assertPred!"=="(date, Date(-2006, 7, 6));
|
|
date.add!"years"(9);
|
|
_assertPred!"=="(date, Date(-1997, 7, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 2, 28);
|
|
date.add!"years"(-1);
|
|
_assertPred!"=="(date, Date(-2000, 2, 28));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-2000, 2, 29);
|
|
date.add!"years"(1);
|
|
_assertPred!"=="(date, Date(-1999, 3, 1));
|
|
}
|
|
|
|
//Test Both
|
|
{
|
|
auto date = Date(4, 7, 6);
|
|
date.add!"years"(-5);
|
|
_assertPred!"=="(date, Date(-1, 7, 6));
|
|
date.add!"years"(5);
|
|
_assertPred!"=="(date, Date(4, 7, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-4, 7, 6);
|
|
date.add!"years"(5);
|
|
_assertPred!"=="(date, Date(1, 7, 6));
|
|
date.add!"years"(-5);
|
|
_assertPred!"=="(date, Date(-4, 7, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(4, 7, 6);
|
|
date.add!"years"(-8);
|
|
_assertPred!"=="(date, Date(-4, 7, 6));
|
|
date.add!"years"(8);
|
|
_assertPred!"=="(date, Date(4, 7, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-4, 7, 6);
|
|
date.add!"years"(8);
|
|
_assertPred!"=="(date, Date(4, 7, 6));
|
|
date.add!"years"(-8);
|
|
_assertPred!"=="(date, Date(-4, 7, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-4, 2, 29);
|
|
date.add!"years"(5);
|
|
_assertPred!"=="(date, Date(1, 3, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(4, 2, 29);
|
|
date.add!"years"(-5);
|
|
_assertPred!"=="(date, Date(-1, 3, 1));
|
|
}
|
|
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(!__traits(compiles, cdate.add!"years"(7)));
|
|
static assert(!__traits(compiles, idate.add!"years"(7)));
|
|
}
|
|
}
|
|
|
|
//Test add!"years"() with AllowDayOverlow.no
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
{
|
|
auto date = Date(1999, 7, 6);
|
|
date.add!"years"(7, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(2006, 7, 6));
|
|
date.add!"years"(-9, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1997, 7, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 2, 28);
|
|
date.add!"years"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(2000, 2, 28));
|
|
}
|
|
|
|
{
|
|
auto date = Date(2000, 2, 29);
|
|
date.add!"years"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1999, 2, 28));
|
|
}
|
|
|
|
//Test B.C.
|
|
{
|
|
auto date = Date(-1999, 7, 6);
|
|
date.add!"years"(-7, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-2006, 7, 6));
|
|
date.add!"years"(9, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1997, 7, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 2, 28);
|
|
date.add!"years"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-2000, 2, 28));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-2000, 2, 29);
|
|
date.add!"years"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1999, 2, 28));
|
|
}
|
|
|
|
//Test Both
|
|
{
|
|
auto date = Date(4, 7, 6);
|
|
date.add!"years"(-5, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1, 7, 6));
|
|
date.add!"years"(5, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(4, 7, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-4, 7, 6);
|
|
date.add!"years"(5, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1, 7, 6));
|
|
date.add!"years"(-5, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-4, 7, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(4, 7, 6);
|
|
date.add!"years"(-8, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-4, 7, 6));
|
|
date.add!"years"(8, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(4, 7, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-4, 7, 6);
|
|
date.add!"years"(8, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(4, 7, 6));
|
|
date.add!"years"(-8, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-4, 7, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-4, 2, 29);
|
|
date.add!"years"(5, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1, 2, 28));
|
|
}
|
|
|
|
{
|
|
auto date = Date(4, 2, 29);
|
|
date.add!"years"(-5, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1, 2, 28));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//Shares documentation with "years" version.
|
|
/+ref Date+/ void add(string units)(long months, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) pure nothrow
|
|
if(units == "months")
|
|
{
|
|
auto years = months / 12;
|
|
months %= 12;
|
|
auto newMonth = _month + months;
|
|
|
|
if(months < 0)
|
|
{
|
|
if(newMonth < 1)
|
|
{
|
|
newMonth += 12;
|
|
--years;
|
|
}
|
|
}
|
|
else if(newMonth > 12)
|
|
{
|
|
newMonth -= 12;
|
|
++years;
|
|
}
|
|
|
|
_year += years;
|
|
_month = cast(Month)newMonth;
|
|
|
|
immutable currMaxDay = maxDay(_year, _month);
|
|
immutable overflow = _day - currMaxDay;
|
|
|
|
if(overflow > 0)
|
|
{
|
|
if(allowOverflow == AllowDayOverflow.yes)
|
|
{
|
|
++_month;
|
|
_day = cast(ubyte)overflow;
|
|
}
|
|
else
|
|
_day = cast(ubyte)currMaxDay;
|
|
}
|
|
}
|
|
|
|
//Test add!"months"() with AllowDayOverlow.yes
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
{
|
|
auto date = Date(1999, 7, 6);
|
|
date.add!"months"(3);
|
|
_assertPred!"=="(date, Date(1999, 10, 6));
|
|
date.add!"months"(-4);
|
|
_assertPred!"=="(date, Date(1999, 6, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 7, 6);
|
|
date.add!"months"(6);
|
|
_assertPred!"=="(date, Date(2000, 1, 6));
|
|
date.add!"months"(-6);
|
|
_assertPred!"=="(date, Date(1999, 7, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 7, 6);
|
|
date.add!"months"(27);
|
|
_assertPred!"=="(date, Date(2001, 10, 6));
|
|
date.add!"months"(-28);
|
|
_assertPred!"=="(date, Date(1999, 6, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 5, 31);
|
|
date.add!"months"(1);
|
|
_assertPred!"=="(date, Date(1999, 7, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 5, 31);
|
|
date.add!"months"(-1);
|
|
_assertPred!"=="(date, Date(1999, 5, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 2, 28);
|
|
date.add!"months"(12);
|
|
_assertPred!"=="(date, Date(2000, 2, 28));
|
|
}
|
|
|
|
{
|
|
auto date = Date(2000, 2, 29);
|
|
date.add!"months"(12);
|
|
_assertPred!"=="(date, Date(2001, 3, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 7, 31);
|
|
date.add!"months"(1);
|
|
_assertPred!"=="(date, Date(1999, 8, 31));
|
|
date.add!"months"(1);
|
|
_assertPred!"=="(date, Date(1999, 10, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1998, 8, 31);
|
|
date.add!"months"(13);
|
|
_assertPred!"=="(date, Date(1999, 10, 1));
|
|
date.add!"months"(-13);
|
|
_assertPred!"=="(date, Date(1998, 9, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1997, 12, 31);
|
|
date.add!"months"(13);
|
|
_assertPred!"=="(date, Date(1999, 1, 31));
|
|
date.add!"months"(-13);
|
|
_assertPred!"=="(date, Date(1997, 12, 31));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1997, 12, 31);
|
|
date.add!"months"(14);
|
|
_assertPred!"=="(date, Date(1999, 3, 3));
|
|
date.add!"months"(-14);
|
|
_assertPred!"=="(date, Date(1998, 1, 3));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1998, 12, 31);
|
|
date.add!"months"(14);
|
|
_assertPred!"=="(date, Date(2000, 3, 2));
|
|
date.add!"months"(-14);
|
|
_assertPred!"=="(date, Date(1999, 1, 2));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 12, 31);
|
|
date.add!"months"(14);
|
|
_assertPred!"=="(date, Date(2001, 3, 3));
|
|
date.add!"months"(-14);
|
|
_assertPred!"=="(date, Date(2000, 1, 3));
|
|
}
|
|
|
|
//Test B.C.
|
|
{
|
|
auto date = Date(-1999, 7, 6);
|
|
date.add!"months"(3);
|
|
_assertPred!"=="(date, Date(-1999, 10, 6));
|
|
date.add!"months"(-4);
|
|
_assertPred!"=="(date, Date(-1999, 6, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 7, 6);
|
|
date.add!"months"(6);
|
|
_assertPred!"=="(date, Date(-1998, 1, 6));
|
|
date.add!"months"(-6);
|
|
_assertPred!"=="(date, Date(-1999, 7, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 7, 6);
|
|
date.add!"months"(-27);
|
|
_assertPred!"=="(date, Date(-2001, 4, 6));
|
|
date.add!"months"(28);
|
|
_assertPred!"=="(date, Date(-1999, 8, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 5, 31);
|
|
date.add!"months"(1);
|
|
_assertPred!"=="(date, Date(-1999, 7, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 5, 31);
|
|
date.add!"months"(-1);
|
|
_assertPred!"=="(date, Date(-1999, 5, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 2, 28);
|
|
date.add!"months"(-12);
|
|
_assertPred!"=="(date, Date(-2000, 2, 28));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-2000, 2, 29);
|
|
date.add!"months"(-12);
|
|
_assertPred!"=="(date, Date(-2001, 3, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 7, 31);
|
|
date.add!"months"(1);
|
|
_assertPred!"=="(date, Date(-1999, 8, 31));
|
|
date.add!"months"(1);
|
|
_assertPred!"=="(date, Date(-1999, 10, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1998, 8, 31);
|
|
date.add!"months"(13);
|
|
_assertPred!"=="(date, Date(-1997, 10, 1));
|
|
date.add!"months"(-13);
|
|
_assertPred!"=="(date, Date(-1998, 9, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1997, 12, 31);
|
|
date.add!"months"(13);
|
|
_assertPred!"=="(date, Date(-1995, 1, 31));
|
|
date.add!"months"(-13);
|
|
_assertPred!"=="(date, Date(-1997, 12, 31));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1997, 12, 31);
|
|
date.add!"months"(14);
|
|
_assertPred!"=="(date, Date(-1995, 3, 3));
|
|
date.add!"months"(-14);
|
|
_assertPred!"=="(date, Date(-1996, 1, 3));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-2002, 12, 31);
|
|
date.add!"months"(14);
|
|
_assertPred!"=="(date, Date(-2000, 3, 2));
|
|
date.add!"months"(-14);
|
|
_assertPred!"=="(date, Date(-2001, 1, 2));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-2001, 12, 31);
|
|
date.add!"months"(14);
|
|
_assertPred!"=="(date, Date(-1999, 3, 3));
|
|
date.add!"months"(-14);
|
|
_assertPred!"=="(date, Date(-2000, 1, 3));
|
|
}
|
|
|
|
//Test Both
|
|
{
|
|
auto date = Date(1, 1, 1);
|
|
date.add!"months"(-1);
|
|
_assertPred!"=="(date, Date(0, 12, 1));
|
|
date.add!"months"(1);
|
|
_assertPred!"=="(date, Date(1, 1, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(4, 1, 1);
|
|
date.add!"months"(-48);
|
|
_assertPred!"=="(date, Date(0, 1, 1));
|
|
date.add!"months"(48);
|
|
_assertPred!"=="(date, Date(4, 1, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(4, 3, 31);
|
|
date.add!"months"(-49);
|
|
_assertPred!"=="(date, Date(0, 3, 2));
|
|
date.add!"months"(49);
|
|
_assertPred!"=="(date, Date(4, 4, 2));
|
|
}
|
|
|
|
{
|
|
auto date = Date(4, 3, 31);
|
|
date.add!"months"(-85);
|
|
_assertPred!"=="(date, Date(-3, 3, 3));
|
|
date.add!"months"(85);
|
|
_assertPred!"=="(date, Date(4, 4, 3));
|
|
}
|
|
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(!__traits(compiles, cdate.add!"months"(3)));
|
|
static assert(!__traits(compiles, idate.add!"months"(3)));
|
|
}
|
|
}
|
|
|
|
//Test add!"months"() with AllowDayOverlow.no
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
{
|
|
auto date = Date(1999, 7, 6);
|
|
date.add!"months"(3, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1999, 10, 6));
|
|
date.add!"months"(-4, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1999, 6, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 7, 6);
|
|
date.add!"months"(6, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(2000, 1, 6));
|
|
date.add!"months"(-6, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1999, 7, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 7, 6);
|
|
date.add!"months"(27, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(2001, 10, 6));
|
|
date.add!"months"(-28, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1999, 6, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 5, 31);
|
|
date.add!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1999, 6, 30));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 5, 31);
|
|
date.add!"months"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1999, 4, 30));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 2, 28);
|
|
date.add!"months"(12, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(2000, 2, 28));
|
|
}
|
|
|
|
{
|
|
auto date = Date(2000, 2, 29);
|
|
date.add!"months"(12, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(2001, 2, 28));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 7, 31);
|
|
date.add!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1999, 8, 31));
|
|
date.add!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1999, 9, 30));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1998, 8, 31);
|
|
date.add!"months"(13, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1999, 9, 30));
|
|
date.add!"months"(-13, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1998, 8, 30));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1997, 12, 31);
|
|
date.add!"months"(13, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1999, 1, 31));
|
|
date.add!"months"(-13, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1997, 12, 31));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1997, 12, 31);
|
|
date.add!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1999, 2, 28));
|
|
date.add!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1997, 12, 28));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1998, 12, 31);
|
|
date.add!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(2000, 2, 29));
|
|
date.add!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1998, 12, 29));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 12, 31);
|
|
date.add!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(2001, 2, 28));
|
|
date.add!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1999, 12, 28));
|
|
}
|
|
|
|
//Test B.C.
|
|
{
|
|
auto date = Date(-1999, 7, 6);
|
|
date.add!"months"(3, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1999, 10, 6));
|
|
date.add!"months"(-4, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1999, 6, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 7, 6);
|
|
date.add!"months"(6, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1998, 1, 6));
|
|
date.add!"months"(-6, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1999, 7, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 7, 6);
|
|
date.add!"months"(-27, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-2001, 4, 6));
|
|
date.add!"months"(28, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1999, 8, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 5, 31);
|
|
date.add!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1999, 6, 30));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 5, 31);
|
|
date.add!"months"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1999, 4, 30));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 2, 28);
|
|
date.add!"months"(-12, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-2000, 2, 28));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-2000, 2, 29);
|
|
date.add!"months"(-12, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-2001, 2, 28));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 7, 31);
|
|
date.add!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1999, 8, 31));
|
|
date.add!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1999, 9, 30));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1998, 8, 31);
|
|
date.add!"months"(13, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1997, 9, 30));
|
|
date.add!"months"(-13, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1998, 8, 30));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1997, 12, 31);
|
|
date.add!"months"(13, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1995, 1, 31));
|
|
date.add!"months"(-13, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1997, 12, 31));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1997, 12, 31);
|
|
date.add!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1995, 2, 28));
|
|
date.add!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1997, 12, 28));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-2002, 12, 31);
|
|
date.add!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-2000, 2, 29));
|
|
date.add!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-2002, 12, 29));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-2001, 12, 31);
|
|
date.add!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1999, 2, 28));
|
|
date.add!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-2001, 12, 28));
|
|
}
|
|
|
|
//Test Both
|
|
{
|
|
auto date = Date(1, 1, 1);
|
|
date.add!"months"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(0, 12, 1));
|
|
date.add!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1, 1, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(4, 1, 1);
|
|
date.add!"months"(-48, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(0, 1, 1));
|
|
date.add!"months"(48, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(4, 1, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(4, 3, 31);
|
|
date.add!"months"(-49, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(0, 2, 29));
|
|
date.add!"months"(49, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(4, 3, 29));
|
|
}
|
|
|
|
{
|
|
auto date = Date(4, 3, 31);
|
|
date.add!"months"(-85, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-3, 2, 28));
|
|
date.add!"months"(85, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(4, 3, 28));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Adds the given number of years or months to this $(D Date). A negative
|
|
number will subtract.
|
|
|
|
The difference between rolling and adding is that rolling does not
|
|
affect larger units. So, if you roll a $(D Date) 12 months, you get
|
|
the exact same $(D Date). However, the days can still be affected due to
|
|
the differing number of days in each month.
|
|
|
|
Because there are no units larger than years, there is no difference
|
|
between adding and rolling years.
|
|
|
|
Params:
|
|
units = The type of units to add ("years" or "months").
|
|
value = The number of months or years to add to this
|
|
$(D Date).
|
|
|
|
Examples:
|
|
--------------------
|
|
auto d1 = Date(2010, 1, 1);
|
|
d1.roll!"months"(1);
|
|
assert(d1 == Date(2010, 2, 1));
|
|
|
|
auto d2 = Date(2010, 1, 1);
|
|
d2.roll!"months"(-1);
|
|
assert(d2 == Date(2010, 12, 1));
|
|
|
|
auto d3 = Date(1999, 1, 29);
|
|
d3.roll!"months"(1);
|
|
assert(d3 == Date(1999, 3, 1));
|
|
|
|
auto d4 = Date(1999, 1, 29);
|
|
d4.roll!"months"(1, AllowDayOverflow.no);
|
|
assert(d4 == Date(1999, 2, 28));
|
|
|
|
auto d5 = Date(2000, 2, 29);
|
|
d5.roll!"years"(1);
|
|
assert(d5 == Date(2001, 3, 1));
|
|
|
|
auto d6 = Date(2000, 2, 29);
|
|
d6.roll!"years"(1, AllowDayOverflow.no);
|
|
assert(d6 == Date(2001, 2, 28));
|
|
--------------------
|
|
+/
|
|
/+ref Date+/ void roll(string units)(long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) pure nothrow
|
|
if(units == "years")
|
|
{
|
|
add!"years"(value, allowOverflow);
|
|
}
|
|
|
|
//Verify Examples.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto d1 = Date(2010, 1, 1);
|
|
d1.roll!"months"(1);
|
|
assert(d1 == Date(2010, 2, 1));
|
|
|
|
auto d2 = Date(2010, 1, 1);
|
|
d2.roll!"months"(-1);
|
|
assert(d2 == Date(2010, 12, 1));
|
|
|
|
auto d3 = Date(1999, 1, 29);
|
|
d3.roll!"months"(1);
|
|
assert(d3 == Date(1999, 3, 1));
|
|
|
|
auto d4 = Date(1999, 1, 29);
|
|
d4.roll!"months"(1, AllowDayOverflow.no);
|
|
assert(d4 == Date(1999, 2, 28));
|
|
|
|
auto d5 = Date(2000, 2, 29);
|
|
d5.roll!"years"(1);
|
|
assert(d5 == Date(2001, 3, 1));
|
|
|
|
auto d6 = Date(2000, 2, 29);
|
|
d6.roll!"years"(1, AllowDayOverflow.no);
|
|
assert(d6 == Date(2001, 2, 28));
|
|
}
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(!__traits(compiles, cdate.roll!"years"(3)));
|
|
static assert(!__traits(compiles, idate.rolYears(3)));
|
|
}
|
|
}
|
|
|
|
|
|
//Shares documentation with "years" version.
|
|
/+ref Date+/ void roll(string units)(long months, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) pure nothrow
|
|
if(units == "months")
|
|
{
|
|
months %= 12;
|
|
auto newMonth = _month + months;
|
|
|
|
if(months < 0)
|
|
{
|
|
if(newMonth < 1)
|
|
newMonth += 12;
|
|
}
|
|
else
|
|
{
|
|
if(newMonth > 12)
|
|
newMonth -= 12;
|
|
}
|
|
|
|
_month = cast(Month)newMonth;
|
|
|
|
immutable currMaxDay = maxDay(_year, _month);
|
|
immutable overflow = _day - currMaxDay;
|
|
|
|
if(overflow > 0)
|
|
{
|
|
if(allowOverflow == AllowDayOverflow.yes)
|
|
{
|
|
++_month;
|
|
_day = cast(ubyte)overflow;
|
|
}
|
|
else
|
|
_day = cast(ubyte)currMaxDay;
|
|
}
|
|
}
|
|
|
|
//Test roll!"months"() with AllowDayOverlow.yes
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
{
|
|
auto date = Date(1999, 7, 6);
|
|
date.roll!"months"(3);
|
|
_assertPred!"=="(date, Date(1999, 10, 6));
|
|
date.roll!"months"(-4);
|
|
_assertPred!"=="(date, Date(1999, 6, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 7, 6);
|
|
date.roll!"months"(6);
|
|
_assertPred!"=="(date, Date(1999, 1, 6));
|
|
date.roll!"months"(-6);
|
|
_assertPred!"=="(date, Date(1999, 7, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 7, 6);
|
|
date.roll!"months"(27);
|
|
_assertPred!"=="(date, Date(1999, 10, 6));
|
|
date.roll!"months"(-28);
|
|
_assertPred!"=="(date, Date(1999, 6, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 5, 31);
|
|
date.roll!"months"(1);
|
|
_assertPred!"=="(date, Date(1999, 7, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 5, 31);
|
|
date.roll!"months"(-1);
|
|
_assertPred!"=="(date, Date(1999, 5, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 2, 28);
|
|
date.roll!"months"(12);
|
|
_assertPred!"=="(date, Date(1999, 2, 28));
|
|
}
|
|
|
|
{
|
|
auto date = Date(2000, 2, 29);
|
|
date.roll!"months"(12);
|
|
_assertPred!"=="(date, Date(2000, 2, 29));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 7, 31);
|
|
date.roll!"months"(1);
|
|
_assertPred!"=="(date, Date(1999, 8, 31));
|
|
date.roll!"months"(1);
|
|
_assertPred!"=="(date, Date(1999, 10, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1998, 8, 31);
|
|
date.roll!"months"(13);
|
|
_assertPred!"=="(date, Date(1998, 10, 1));
|
|
date.roll!"months"(-13);
|
|
_assertPred!"=="(date, Date(1998, 9, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1997, 12, 31);
|
|
date.roll!"months"(13);
|
|
_assertPred!"=="(date, Date(1997, 1, 31));
|
|
date.roll!"months"(-13);
|
|
_assertPred!"=="(date, Date(1997, 12, 31));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1997, 12, 31);
|
|
date.roll!"months"(14);
|
|
_assertPred!"=="(date, Date(1997, 3, 3));
|
|
date.roll!"months"(-14);
|
|
_assertPred!"=="(date, Date(1997, 1, 3));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1998, 12, 31);
|
|
date.roll!"months"(14);
|
|
_assertPred!"=="(date, Date(1998, 3, 3));
|
|
date.roll!"months"(-14);
|
|
_assertPred!"=="(date, Date(1998, 1, 3));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 12, 31);
|
|
date.roll!"months"(14);
|
|
_assertPred!"=="(date, Date(1999, 3, 3));
|
|
date.roll!"months"(-14);
|
|
_assertPred!"=="(date, Date(1999, 1, 3));
|
|
}
|
|
|
|
//Test B.C.
|
|
{
|
|
auto date = Date(-1999, 7, 6);
|
|
date.roll!"months"(3);
|
|
_assertPred!"=="(date, Date(-1999, 10, 6));
|
|
date.roll!"months"(-4);
|
|
_assertPred!"=="(date, Date(-1999, 6, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 7, 6);
|
|
date.roll!"months"(6);
|
|
_assertPred!"=="(date, Date(-1999, 1, 6));
|
|
date.roll!"months"(-6);
|
|
_assertPred!"=="(date, Date(-1999, 7, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 7, 6);
|
|
date.roll!"months"(-27);
|
|
_assertPred!"=="(date, Date(-1999, 4, 6));
|
|
date.roll!"months"(28);
|
|
_assertPred!"=="(date, Date(-1999, 8, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 5, 31);
|
|
date.roll!"months"(1);
|
|
_assertPred!"=="(date, Date(-1999, 7, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 5, 31);
|
|
date.roll!"months"(-1);
|
|
_assertPred!"=="(date, Date(-1999, 5, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 2, 28);
|
|
date.roll!"months"(-12);
|
|
_assertPred!"=="(date, Date(-1999, 2, 28));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-2000, 2, 29);
|
|
date.roll!"months"(-12);
|
|
_assertPred!"=="(date, Date(-2000, 2, 29));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 7, 31);
|
|
date.roll!"months"(1);
|
|
_assertPred!"=="(date, Date(-1999, 8, 31));
|
|
date.roll!"months"(1);
|
|
_assertPred!"=="(date, Date(-1999, 10, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1998, 8, 31);
|
|
date.roll!"months"(13);
|
|
_assertPred!"=="(date, Date(-1998, 10, 1));
|
|
date.roll!"months"(-13);
|
|
_assertPred!"=="(date, Date(-1998, 9, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1997, 12, 31);
|
|
date.roll!"months"(13);
|
|
_assertPred!"=="(date, Date(-1997, 1, 31));
|
|
date.roll!"months"(-13);
|
|
_assertPred!"=="(date, Date(-1997, 12, 31));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1997, 12, 31);
|
|
date.roll!"months"(14);
|
|
_assertPred!"=="(date, Date(-1997, 3, 3));
|
|
date.roll!"months"(-14);
|
|
_assertPred!"=="(date, Date(-1997, 1, 3));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-2002, 12, 31);
|
|
date.roll!"months"(14);
|
|
_assertPred!"=="(date, Date(-2002, 3, 3));
|
|
date.roll!"months"(-14);
|
|
_assertPred!"=="(date, Date(-2002, 1, 3));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-2001, 12, 31);
|
|
date.roll!"months"(14);
|
|
_assertPred!"=="(date, Date(-2001, 3, 3));
|
|
date.roll!"months"(-14);
|
|
_assertPred!"=="(date, Date(-2001, 1, 3));
|
|
}
|
|
|
|
//Test Both
|
|
{
|
|
auto date = Date(1, 1, 1);
|
|
date.roll!"months"(-1);
|
|
_assertPred!"=="(date, Date(1, 12, 1));
|
|
date.roll!"months"(1);
|
|
_assertPred!"=="(date, Date(1, 1, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(4, 1, 1);
|
|
date.roll!"months"(-48);
|
|
_assertPred!"=="(date, Date(4, 1, 1));
|
|
date.roll!"months"(48);
|
|
_assertPred!"=="(date, Date(4, 1, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(4, 3, 31);
|
|
date.roll!"months"(-49);
|
|
_assertPred!"=="(date, Date(4, 3, 2));
|
|
date.roll!"months"(49);
|
|
_assertPred!"=="(date, Date(4, 4, 2));
|
|
}
|
|
|
|
{
|
|
auto date = Date(4, 3, 31);
|
|
date.roll!"months"(-85);
|
|
_assertPred!"=="(date, Date(4, 3, 2));
|
|
date.roll!"months"(85);
|
|
_assertPred!"=="(date, Date(4, 4, 2));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1, 1, 1);
|
|
date.roll!"months"(-1);
|
|
_assertPred!"=="(date, Date(-1, 12, 1));
|
|
date.roll!"months"(1);
|
|
_assertPred!"=="(date, Date(-1, 1, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-4, 1, 1);
|
|
date.roll!"months"(-48);
|
|
_assertPred!"=="(date, Date(-4, 1, 1));
|
|
date.roll!"months"(48);
|
|
_assertPred!"=="(date, Date(-4, 1, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-4, 3, 31);
|
|
date.roll!"months"(-49);
|
|
_assertPred!"=="(date, Date(-4, 3, 2));
|
|
date.roll!"months"(49);
|
|
_assertPred!"=="(date, Date(-4, 4, 2));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-4, 3, 31);
|
|
date.roll!"months"(-85);
|
|
_assertPred!"=="(date, Date(-4, 3, 2));
|
|
date.roll!"months"(85);
|
|
_assertPred!"=="(date, Date(-4, 4, 2));
|
|
}
|
|
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(!__traits(compiles, cdate.roll!"months"(3)));
|
|
static assert(!__traits(compiles, idate.roll!"months"(3)));
|
|
|
|
//Verify Examples.
|
|
auto date1 = Date(2010, 1, 1);
|
|
date1.roll!"months"(1);
|
|
assert(date1 == Date(2010, 2, 1));
|
|
|
|
auto date2 = Date(2010, 1, 1);
|
|
date2.roll!"months"(-1);
|
|
assert(date2 == Date(2010, 12, 1));
|
|
|
|
auto date3 = Date(1999, 1, 29);
|
|
date3.roll!"months"(1);
|
|
assert(date3 == Date(1999, 3, 1));
|
|
|
|
auto date4 = Date(1999, 1, 29);
|
|
date4.roll!"months"(1, AllowDayOverflow.no);
|
|
assert(date4 == Date(1999, 2, 28));
|
|
}
|
|
}
|
|
|
|
//Test roll!"months"() with AllowDayOverlow.no
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
{
|
|
auto date = Date(1999, 7, 6);
|
|
date.roll!"months"(3, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1999, 10, 6));
|
|
date.roll!"months"(-4, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1999, 6, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 7, 6);
|
|
date.roll!"months"(6, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1999, 1, 6));
|
|
date.roll!"months"(-6, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1999, 7, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 7, 6);
|
|
date.roll!"months"(27, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1999, 10, 6));
|
|
date.roll!"months"(-28, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1999, 6, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 5, 31);
|
|
date.roll!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1999, 6, 30));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 5, 31);
|
|
date.roll!"months"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1999, 4, 30));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 2, 28);
|
|
date.roll!"months"(12, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1999, 2, 28));
|
|
}
|
|
|
|
{
|
|
auto date = Date(2000, 2, 29);
|
|
date.roll!"months"(12, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(2000, 2, 29));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 7, 31);
|
|
date.roll!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1999, 8, 31));
|
|
date.roll!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1999, 9, 30));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1998, 8, 31);
|
|
date.roll!"months"(13, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1998, 9, 30));
|
|
date.roll!"months"(-13, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1998, 8, 30));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1997, 12, 31);
|
|
date.roll!"months"(13, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1997, 1, 31));
|
|
date.roll!"months"(-13, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1997, 12, 31));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1997, 12, 31);
|
|
date.roll!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1997, 2, 28));
|
|
date.roll!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1997, 12, 28));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1998, 12, 31);
|
|
date.roll!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1998, 2, 28));
|
|
date.roll!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1998, 12, 28));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 12, 31);
|
|
date.roll!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1999, 2, 28));
|
|
date.roll!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1999, 12, 28));
|
|
}
|
|
|
|
//Test B.C.
|
|
{
|
|
auto date = Date(-1999, 7, 6);
|
|
date.roll!"months"(3, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1999, 10, 6));
|
|
date.roll!"months"(-4, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1999, 6, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 7, 6);
|
|
date.roll!"months"(6, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1999, 1, 6));
|
|
date.roll!"months"(-6, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1999, 7, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 7, 6);
|
|
date.roll!"months"(-27, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1999, 4, 6));
|
|
date.roll!"months"(28, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1999, 8, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 5, 31);
|
|
date.roll!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1999, 6, 30));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 5, 31);
|
|
date.roll!"months"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1999, 4, 30));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 2, 28);
|
|
date.roll!"months"(-12, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1999, 2, 28));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-2000, 2, 29);
|
|
date.roll!"months"(-12, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-2000, 2, 29));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 7, 31);
|
|
date.roll!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1999, 8, 31));
|
|
date.roll!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1999, 9, 30));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1998, 8, 31);
|
|
date.roll!"months"(13, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1998, 9, 30));
|
|
date.roll!"months"(-13, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1998, 8, 30));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1997, 12, 31);
|
|
date.roll!"months"(13, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1997, 1, 31));
|
|
date.roll!"months"(-13, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1997, 12, 31));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1997, 12, 31);
|
|
date.roll!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1997, 2, 28));
|
|
date.roll!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1997, 12, 28));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-2002, 12, 31);
|
|
date.roll!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-2002, 2, 28));
|
|
date.roll!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-2002, 12, 28));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-2001, 12, 31);
|
|
date.roll!"months"(14, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-2001, 2, 28));
|
|
date.roll!"months"(-14, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-2001, 12, 28));
|
|
}
|
|
|
|
//Test Both
|
|
{
|
|
auto date = Date(1, 1, 1);
|
|
date.roll!"months"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1, 12, 1));
|
|
date.roll!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(1, 1, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(4, 1, 1);
|
|
date.roll!"months"(-48, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(4, 1, 1));
|
|
date.roll!"months"(48, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(4, 1, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(4, 3, 31);
|
|
date.roll!"months"(-49, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(4, 2, 29));
|
|
date.roll!"months"(49, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(4, 3, 29));
|
|
}
|
|
|
|
{
|
|
auto date = Date(4, 3, 31);
|
|
date.roll!"months"(-85, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(4, 2, 29));
|
|
date.roll!"months"(85, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(4, 3, 29));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1, 1, 1);
|
|
date.roll!"months"(-1, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1, 12, 1));
|
|
date.roll!"months"(1, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-1, 1, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-4, 1, 1);
|
|
date.roll!"months"(-48, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-4, 1, 1));
|
|
date.roll!"months"(48, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-4, 1, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-4, 3, 31);
|
|
date.roll!"months"(-49, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-4, 2, 29));
|
|
date.roll!"months"(49, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-4, 3, 29));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-4, 3, 31);
|
|
date.roll!"months"(-85, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-4, 2, 29));
|
|
date.roll!"months"(85, AllowDayOverflow.no);
|
|
_assertPred!"=="(date, Date(-4, 3, 29));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Adds the given number of units to this $(D Date). A negative number will
|
|
subtract.
|
|
|
|
The difference between rolling and adding is that rolling does not
|
|
affect larger units. So, for instance, if you roll a $(D Date) one
|
|
year's worth of days, then you get the exact same $(D Date).
|
|
|
|
The only accepted units are $(D "days").
|
|
|
|
Params:
|
|
units = The units to add. Must be $(D "days").
|
|
value = The number of days to add to this $(D Date).
|
|
|
|
Examples:
|
|
--------------------
|
|
auto d = Date(2010, 1, 1);
|
|
d.roll!"days"(1);
|
|
assert(d == Date(2010, 1, 2));
|
|
d.roll!"days"(365);
|
|
assert(d == Date(2010, 1, 26));
|
|
d.roll!"days"(-32);
|
|
assert(d == Date(2010, 1, 25));
|
|
--------------------
|
|
+/
|
|
/+ref Date+/ void roll(string units)(long days) pure nothrow
|
|
if(units == "days")
|
|
{
|
|
immutable limit = maxDay(_year, _month);
|
|
days %= limit;
|
|
auto newDay = _day + days;
|
|
|
|
if(days < 0)
|
|
{
|
|
if(newDay < 1)
|
|
newDay += limit;
|
|
}
|
|
else if(newDay > limit)
|
|
newDay -= limit;
|
|
|
|
_day = cast(ubyte)newDay;
|
|
}
|
|
|
|
//Verify Examples.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto d = Date(2010, 1, 1);
|
|
d.roll!"days"(1);
|
|
assert(d == Date(2010, 1, 2));
|
|
d.roll!"days"(365);
|
|
assert(d == Date(2010, 1, 26));
|
|
d.roll!"days"(-32);
|
|
assert(d == Date(2010, 1, 25));
|
|
}
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
{
|
|
auto date = Date(1999, 2, 28);
|
|
date.roll!"days"(1);
|
|
_assertPred!"=="(date, Date(1999, 2, 1));
|
|
date.roll!"days"(-1);
|
|
_assertPred!"=="(date, Date(1999, 2, 28));
|
|
}
|
|
|
|
{
|
|
auto date = Date(2000, 2, 28);
|
|
date.roll!"days"(1);
|
|
_assertPred!"=="(date, Date(2000, 2, 29));
|
|
date.roll!"days"(1);
|
|
_assertPred!"=="(date, Date(2000, 2, 1));
|
|
date.roll!"days"(-1);
|
|
_assertPred!"=="(date, Date(2000, 2, 29));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 6, 30);
|
|
date.roll!"days"(1);
|
|
_assertPred!"=="(date, Date(1999, 6, 1));
|
|
date.roll!"days"(-1);
|
|
_assertPred!"=="(date, Date(1999, 6, 30));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 7, 31);
|
|
date.roll!"days"(1);
|
|
_assertPred!"=="(date, Date(1999, 7, 1));
|
|
date.roll!"days"(-1);
|
|
_assertPred!"=="(date, Date(1999, 7, 31));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 1, 1);
|
|
date.roll!"days"(-1);
|
|
_assertPred!"=="(date, Date(1999, 1, 31));
|
|
date.roll!"days"(1);
|
|
_assertPred!"=="(date, Date(1999, 1, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 7, 6);
|
|
date.roll!"days"(9);
|
|
_assertPred!"=="(date, Date(1999, 7, 15));
|
|
date.roll!"days"(-11);
|
|
_assertPred!"=="(date, Date(1999, 7, 4));
|
|
date.roll!"days"(30);
|
|
_assertPred!"=="(date, Date(1999, 7, 3));
|
|
date.roll!"days"(-3);
|
|
_assertPred!"=="(date, Date(1999, 7, 31));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 7, 6);
|
|
date.roll!"days"(365);
|
|
_assertPred!"=="(date, Date(1999, 7, 30));
|
|
date.roll!"days"(-365);
|
|
_assertPred!"=="(date, Date(1999, 7, 6));
|
|
date.roll!"days"(366);
|
|
_assertPred!"=="(date, Date(1999, 7, 31));
|
|
date.roll!"days"(730);
|
|
_assertPred!"=="(date, Date(1999, 7, 17));
|
|
date.roll!"days"(-1096);
|
|
_assertPred!"=="(date, Date(1999, 7, 6));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 2, 6);
|
|
date.roll!"days"(365);
|
|
_assertPred!"=="(date, Date(1999, 2, 7));
|
|
date.roll!"days"(-365);
|
|
_assertPred!"=="(date, Date(1999, 2, 6));
|
|
date.roll!"days"(366);
|
|
_assertPred!"=="(date, Date(1999, 2, 8));
|
|
date.roll!"days"(730);
|
|
_assertPred!"=="(date, Date(1999, 2, 10));
|
|
date.roll!"days"(-1096);
|
|
_assertPred!"=="(date, Date(1999, 2, 6));
|
|
}
|
|
|
|
//Test B.C.
|
|
{
|
|
auto date = Date(-1999, 2, 28);
|
|
date.roll!"days"(1);
|
|
_assertPred!"=="(date, Date(-1999, 2, 1));
|
|
date.roll!"days"(-1);
|
|
_assertPred!"=="(date, Date(-1999, 2, 28));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-2000, 2, 28);
|
|
date.roll!"days"(1);
|
|
_assertPred!"=="(date, Date(-2000, 2, 29));
|
|
date.roll!"days"(1);
|
|
_assertPred!"=="(date, Date(-2000, 2, 1));
|
|
date.roll!"days"(-1);
|
|
_assertPred!"=="(date, Date(-2000, 2, 29));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 6, 30);
|
|
date.roll!"days"(1);
|
|
_assertPred!"=="(date, Date(-1999, 6, 1));
|
|
date.roll!"days"(-1);
|
|
_assertPred!"=="(date, Date(-1999, 6, 30));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 7, 31);
|
|
date.roll!"days"(1);
|
|
_assertPred!"=="(date, Date(-1999, 7, 1));
|
|
date.roll!"days"(-1);
|
|
_assertPred!"=="(date, Date(-1999, 7, 31));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 1, 1);
|
|
date.roll!"days"(-1);
|
|
_assertPred!"=="(date, Date(-1999, 1, 31));
|
|
date.roll!"days"(1);
|
|
_assertPred!"=="(date, Date(-1999, 1, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 7, 6);
|
|
date.roll!"days"(9);
|
|
_assertPred!"=="(date, Date(-1999, 7, 15));
|
|
date.roll!"days"(-11);
|
|
_assertPred!"=="(date, Date(-1999, 7, 4));
|
|
date.roll!"days"(30);
|
|
_assertPred!"=="(date, Date(-1999, 7, 3));
|
|
date.roll!"days"(-3);
|
|
_assertPred!"=="(date, Date(-1999, 7, 31));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 7, 6);
|
|
date.roll!"days"(365);
|
|
_assertPred!"=="(date, Date(-1999, 7, 30));
|
|
date.roll!"days"(-365);
|
|
_assertPred!"=="(date, Date(-1999, 7, 6));
|
|
date.roll!"days"(366);
|
|
_assertPred!"=="(date, Date(-1999, 7, 31));
|
|
date.roll!"days"(730);
|
|
_assertPred!"=="(date, Date(-1999, 7, 17));
|
|
date.roll!"days"(-1096);
|
|
_assertPred!"=="(date, Date(-1999, 7, 6));
|
|
}
|
|
|
|
//Test Both
|
|
{
|
|
auto date = Date(1, 7, 6);
|
|
date.roll!"days"(-365);
|
|
_assertPred!"=="(date, Date(1, 7, 13));
|
|
date.roll!"days"(365);
|
|
_assertPred!"=="(date, Date(1, 7, 6));
|
|
date.roll!"days"(-731);
|
|
_assertPred!"=="(date, Date(1, 7, 19));
|
|
date.roll!"days"(730);
|
|
_assertPred!"=="(date, Date(1, 7, 5));
|
|
}
|
|
|
|
{
|
|
auto date = Date(0, 7, 6);
|
|
date.roll!"days"(-365);
|
|
_assertPred!"=="(date, Date(0, 7, 13));
|
|
date.roll!"days"(365);
|
|
_assertPred!"=="(date, Date(0, 7, 6));
|
|
date.roll!"days"(-731);
|
|
_assertPred!"=="(date, Date(0, 7, 19));
|
|
date.roll!"days"(730);
|
|
_assertPred!"=="(date, Date(0, 7, 5));
|
|
}
|
|
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(!__traits(compiles, cdate.roll!"days"(12)));
|
|
static assert(!__traits(compiles, idate.roll!"days"(12)));
|
|
|
|
//Verify Examples.
|
|
auto date = Date(2010, 1, 1);
|
|
date.roll!"days"(1);
|
|
assert(date == Date(2010, 1, 2));
|
|
date.roll!"days"(365);
|
|
assert(date == Date(2010, 1, 26));
|
|
date.roll!"days"(-32);
|
|
assert(date == Date(2010, 1, 25));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Gives the result of adding or subtracting a duration from this
|
|
$(D Date).
|
|
|
|
The legal types of arithmetic for Date using this operator are
|
|
|
|
$(BOOKTABLE,
|
|
$(TR $(TD Date) $(TD +) $(TD duration) $(TD -->) $(TD Date))
|
|
$(TR $(TD Date) $(TD -) $(TD duration) $(TD -->) $(TD Date))
|
|
)
|
|
|
|
Params:
|
|
duration = The duration to add to or subtract from this $(D Date).
|
|
+/
|
|
Date opBinary(string op, D)(in D duration) const pure nothrow
|
|
if((op == "+" || op == "-") &&
|
|
(is(Unqual!D == Duration) ||
|
|
is(Unqual!D == TickDuration)))
|
|
{
|
|
Date retval = this;
|
|
|
|
static if(is(Unqual!D == Duration))
|
|
immutable days = duration.total!"days";
|
|
else static if(is(Unqual!D == TickDuration))
|
|
immutable days = convert!("hnsecs", "days")(duration.hnsecs);
|
|
|
|
//Ideally, this would just be
|
|
//return retval.addDays(unaryFun!(op ~ "a")(days));
|
|
//But there isn't currently a pure version of unaryFun!().
|
|
|
|
static if(op == "+")
|
|
immutable signedDays = days;
|
|
else static if(op == "-")
|
|
immutable signedDays = -days;
|
|
else
|
|
static assert(0);
|
|
|
|
return retval.addDays(signedDays);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto date = Date(1999, 7, 6);
|
|
|
|
_assertPred!"=="(date + dur!"weeks"(7), Date(1999, 8, 24));
|
|
_assertPred!"=="(date + dur!"weeks"(-7), Date(1999, 5, 18));
|
|
_assertPred!"=="(date + dur!"days"(7), Date(1999, 7, 13));
|
|
_assertPred!"=="(date + dur!"days"(-7), Date(1999, 6, 29));
|
|
|
|
_assertPred!"=="(date + dur!"hours"(24), Date(1999, 7, 7));
|
|
_assertPred!"=="(date + dur!"hours"(-24), Date(1999, 7, 5));
|
|
_assertPred!"=="(date + dur!"minutes"(1440), Date(1999, 7, 7));
|
|
_assertPred!"=="(date + dur!"minutes"(-1440), Date(1999, 7, 5));
|
|
_assertPred!"=="(date + dur!"seconds"(86_400), Date(1999, 7, 7));
|
|
_assertPred!"=="(date + dur!"seconds"(-86_400), Date(1999, 7, 5));
|
|
_assertPred!"=="(date + dur!"msecs"(86_400_000), Date(1999, 7, 7));
|
|
_assertPred!"=="(date + dur!"msecs"(-86_400_000), Date(1999, 7, 5));
|
|
_assertPred!"=="(date + dur!"usecs"(86_400_000_000), Date(1999, 7, 7));
|
|
_assertPred!"=="(date + dur!"usecs"(-86_400_000_000), Date(1999, 7, 5));
|
|
_assertPred!"=="(date + dur!"hnsecs"(864_000_000_000), Date(1999, 7, 7));
|
|
_assertPred!"=="(date + dur!"hnsecs"(-864_000_000_000), Date(1999, 7, 5));
|
|
|
|
//This probably only runs in cases where gettimeofday() is used, but it's
|
|
//hard to do this test correctly with variable ticksPerSec.
|
|
if(TickDuration.ticksPerSec == 1_000_000)
|
|
{
|
|
_assertPred!"=="(date + TickDuration.from!"usecs"(86_400_000_000), Date(1999, 7, 7));
|
|
_assertPred!"=="(date + TickDuration.from!"usecs"(-86_400_000_000), Date(1999, 7, 5));
|
|
}
|
|
|
|
_assertPred!"=="(date - dur!"weeks"(-7), Date(1999, 8, 24));
|
|
_assertPred!"=="(date - dur!"weeks"(7), Date(1999, 5, 18));
|
|
_assertPred!"=="(date - dur!"days"(-7), Date(1999, 7, 13));
|
|
_assertPred!"=="(date - dur!"days"(7), Date(1999, 6, 29));
|
|
|
|
_assertPred!"=="(date - dur!"hours"(-24), Date(1999, 7, 7));
|
|
_assertPred!"=="(date - dur!"hours"(24), Date(1999, 7, 5));
|
|
_assertPred!"=="(date - dur!"minutes"(-1440), Date(1999, 7, 7));
|
|
_assertPred!"=="(date - dur!"minutes"(1440), Date(1999, 7, 5));
|
|
_assertPred!"=="(date - dur!"seconds"(-86_400), Date(1999, 7, 7));
|
|
_assertPred!"=="(date - dur!"seconds"(86_400), Date(1999, 7, 5));
|
|
_assertPred!"=="(date - dur!"msecs"(-86_400_000), Date(1999, 7, 7));
|
|
_assertPred!"=="(date - dur!"msecs"(86_400_000), Date(1999, 7, 5));
|
|
_assertPred!"=="(date - dur!"usecs"(-86_400_000_000), Date(1999, 7, 7));
|
|
_assertPred!"=="(date - dur!"usecs"(86_400_000_000), Date(1999, 7, 5));
|
|
_assertPred!"=="(date - dur!"hnsecs"(-864_000_000_000), Date(1999, 7, 7));
|
|
_assertPred!"=="(date - dur!"hnsecs"(864_000_000_000), Date(1999, 7, 5));
|
|
|
|
//This probably only runs in cases where gettimeofday() is used, but it's
|
|
//hard to do this test correctly with variable ticksPerSec.
|
|
if(TickDuration.ticksPerSec == 1_000_000)
|
|
{
|
|
_assertPred!"=="(date - TickDuration.from!"usecs"(-86_400_000_000), Date(1999, 7, 7));
|
|
_assertPred!"=="(date - TickDuration.from!"usecs"(86_400_000_000), Date(1999, 7, 5));
|
|
}
|
|
|
|
auto duration = dur!"days"(12);
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(__traits(compiles, date + duration));
|
|
static assert(__traits(compiles, cdate + duration));
|
|
static assert(__traits(compiles, idate + duration));
|
|
|
|
static assert(__traits(compiles, date - duration));
|
|
static assert(__traits(compiles, cdate - duration));
|
|
static assert(__traits(compiles, idate - duration));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Gives the result of adding or subtracting a duration from this
|
|
$(D Date), as well as assigning the result to this $(D Date).
|
|
|
|
The legal types of arithmetic for $(D Date) using this operator are
|
|
|
|
$(BOOKTABLE,
|
|
$(TR $(TD Date) $(TD +) $(TD duration) $(TD -->) $(TD Date))
|
|
$(TR $(TD Date) $(TD -) $(TD duration) $(TD -->) $(TD Date))
|
|
)
|
|
|
|
Params:
|
|
duration = The duration to add to or subtract from this $(D Date).
|
|
+/
|
|
/+ref+/ Date opOpAssign(string op, D)(in D duration) pure nothrow
|
|
if((op == "+" || op == "-") &&
|
|
(is(Unqual!D == Duration) ||
|
|
is(Unqual!D == TickDuration)))
|
|
{
|
|
static if(is(Unqual!D == Duration))
|
|
immutable days = duration.total!"days";
|
|
else static if(is(Unqual!D == TickDuration))
|
|
immutable days = convert!("hnsecs", "days")(duration.hnsecs);
|
|
|
|
//Ideally, this would just be
|
|
//return addDays(unaryFun!(op ~ "a")(days));
|
|
//But there isn't currently a pure version of unaryFun!().
|
|
|
|
static if(op == "+")
|
|
immutable signedDays = days;
|
|
else static if(op == "-")
|
|
immutable signedDays = -days;
|
|
else
|
|
static assert(0);
|
|
|
|
return addDays(signedDays);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"+="(Date(1999, 7, 6), dur!"weeks"(7), Date(1999, 8, 24));
|
|
_assertPred!"+="(Date(1999, 7, 6), dur!"weeks"(-7), Date(1999, 5, 18));
|
|
_assertPred!"+="(Date(1999, 7, 6), dur!"days"(7), Date(1999, 7, 13));
|
|
_assertPred!"+="(Date(1999, 7, 6), dur!"days"(-7), Date(1999, 6, 29));
|
|
|
|
_assertPred!"+="(Date(1999, 7, 6), dur!"hours"(24), Date(1999, 7, 7));
|
|
_assertPred!"+="(Date(1999, 7, 6), dur!"hours"(-24), Date(1999, 7, 5));
|
|
_assertPred!"+="(Date(1999, 7, 6), dur!"minutes"(1440), Date(1999, 7, 7));
|
|
_assertPred!"+="(Date(1999, 7, 6), dur!"minutes"(-1440), Date(1999, 7, 5));
|
|
_assertPred!"+="(Date(1999, 7, 6), dur!"seconds"(86_400), Date(1999, 7, 7));
|
|
_assertPred!"+="(Date(1999, 7, 6), dur!"seconds"(-86_400), Date(1999, 7, 5));
|
|
_assertPred!"+="(Date(1999, 7, 6), dur!"msecs"(86_400_000), Date(1999, 7, 7));
|
|
_assertPred!"+="(Date(1999, 7, 6), dur!"msecs"(-86_400_000), Date(1999, 7, 5));
|
|
_assertPred!"+="(Date(1999, 7, 6), dur!"usecs"(86_400_000_000), Date(1999, 7, 7));
|
|
_assertPred!"+="(Date(1999, 7, 6), dur!"usecs"(-86_400_000_000), Date(1999, 7, 5));
|
|
_assertPred!"+="(Date(1999, 7, 6), dur!"hnsecs"(864_000_000_000), Date(1999, 7, 7));
|
|
_assertPred!"+="(Date(1999, 7, 6), dur!"hnsecs"(-864_000_000_000), Date(1999, 7, 5));
|
|
|
|
_assertPred!"-="(Date(1999, 7, 6), dur!"weeks"(-7), Date(1999, 8, 24));
|
|
_assertPred!"-="(Date(1999, 7, 6), dur!"weeks"(7), Date(1999, 5, 18));
|
|
_assertPred!"-="(Date(1999, 7, 6), dur!"days"(-7), Date(1999, 7, 13));
|
|
_assertPred!"-="(Date(1999, 7, 6), dur!"days"(7), Date(1999, 6, 29));
|
|
|
|
_assertPred!"-="(Date(1999, 7, 6), dur!"hours"(-24), Date(1999, 7, 7));
|
|
_assertPred!"-="(Date(1999, 7, 6), dur!"hours"(24), Date(1999, 7, 5));
|
|
_assertPred!"-="(Date(1999, 7, 6), dur!"minutes"(-1440), Date(1999, 7, 7));
|
|
_assertPred!"-="(Date(1999, 7, 6), dur!"minutes"(1440), Date(1999, 7, 5));
|
|
_assertPred!"-="(Date(1999, 7, 6), dur!"seconds"(-86_400), Date(1999, 7, 7));
|
|
_assertPred!"-="(Date(1999, 7, 6), dur!"seconds"(86_400), Date(1999, 7, 5));
|
|
_assertPred!"-="(Date(1999, 7, 6), dur!"msecs"(-86_400_000), Date(1999, 7, 7));
|
|
_assertPred!"-="(Date(1999, 7, 6), dur!"msecs"(86_400_000), Date(1999, 7, 5));
|
|
_assertPred!"-="(Date(1999, 7, 6), dur!"usecs"(-86_400_000_000), Date(1999, 7, 7));
|
|
_assertPred!"-="(Date(1999, 7, 6), dur!"usecs"(86_400_000_000), Date(1999, 7, 5));
|
|
_assertPred!"-="(Date(1999, 7, 6), dur!"hnsecs"(-864_000_000_000), Date(1999, 7, 7));
|
|
_assertPred!"-="(Date(1999, 7, 6), dur!"hnsecs"(864_000_000_000), Date(1999, 7, 5));
|
|
|
|
auto duration = dur!"days"(12);
|
|
auto date = Date(1999, 7, 6);
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(__traits(compiles, date += duration));
|
|
static assert(!__traits(compiles, cdate += duration));
|
|
static assert(!__traits(compiles, idate += duration));
|
|
|
|
static assert(__traits(compiles, date -= duration));
|
|
static assert(!__traits(compiles, cdate -= duration));
|
|
static assert(!__traits(compiles, idate -= duration));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Gives the difference between two $(D Date)s.
|
|
|
|
The legal types of arithmetic for Date using this operator are
|
|
|
|
$(BOOKTABLE,
|
|
$(TR $(TD Date) $(TD -) $(TD Date) $(TD -->) $(TD duration))
|
|
)
|
|
+/
|
|
Duration opBinary(string op)(in Date rhs) const pure nothrow
|
|
if(op == "-")
|
|
{
|
|
return dur!"days"(this.dayOfGregorianCal - rhs.dayOfGregorianCal);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto date = Date(1999, 7, 6);
|
|
|
|
_assertPred!"=="(Date(1999, 7, 6) - Date(1998, 7, 6), dur!"days"(365));
|
|
_assertPred!"=="(Date(1998, 7, 6) - Date(1999, 7, 6), dur!"days"(-365));
|
|
_assertPred!"=="(Date(1999, 6, 6) - Date(1999, 5, 6), dur!"days"(31));
|
|
_assertPred!"=="(Date(1999, 5, 6) - Date(1999, 6, 6), dur!"days"(-31));
|
|
_assertPred!"=="(Date(1999, 1, 1) - Date(1998, 12, 31), dur!"days"(1));
|
|
_assertPred!"=="(Date(1998, 12, 31) - Date(1999, 1, 1), dur!"days"(-1));
|
|
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(__traits(compiles, date - date));
|
|
static assert(__traits(compiles, cdate - date));
|
|
static assert(__traits(compiles, idate - date));
|
|
|
|
static assert(__traits(compiles, date - cdate));
|
|
static assert(__traits(compiles, cdate - cdate));
|
|
static assert(__traits(compiles, idate - cdate));
|
|
|
|
static assert(__traits(compiles, date - idate));
|
|
static assert(__traits(compiles, cdate - idate));
|
|
static assert(__traits(compiles, idate - idate));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the difference between the two $(D Date)s in months.
|
|
|
|
You can get the difference in years by subtracting the year property
|
|
of two $(D Date)s, and you can get the difference in days or weeks by
|
|
subtracting the $(D Date)s themselves and using the $(D Duration) that
|
|
results, but because you cannot convert between months and smaller units
|
|
without a specific date (which $(D Duration)s don't have), you cannot
|
|
get the difference in months without doing some math using both the year
|
|
and month properties, so this is a convenience function for getting the
|
|
difference in months.
|
|
|
|
Note that the number of days in the months or how far into the month
|
|
either $(D Date) is is irrelevant. It is the difference in the month
|
|
property combined with the difference in years * 12. So, for instance,
|
|
December 31st and January 1st are one month apart just as December 1st
|
|
and January 31st are one month apart.
|
|
|
|
Params:
|
|
rhs = The $(D Date) to subtract from this one.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Date(1999, 2, 1).diffMonths(Date(1999, 1, 31)) == 1);
|
|
assert(Date(1999, 1, 31).diffMonths(Date(1999, 2, 1)) == -1);
|
|
assert(Date(1999, 3, 1).diffMonths(Date(1999, 1, 1)) == 2);
|
|
assert(Date(1999, 1, 1).diffMonths(Date(1999, 3, 31)) == -2);
|
|
--------------------
|
|
+/
|
|
int diffMonths(in Date rhs) const pure nothrow
|
|
{
|
|
immutable yearDiff = _year - rhs._year;
|
|
immutable monthDiff = _month - rhs._month;
|
|
|
|
return yearDiff * 12 + monthDiff;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto date = Date(1999, 7, 6);
|
|
|
|
//Test A.D.
|
|
_assertPred!"=="(date.diffMonths(Date(1998, 6, 5)), 13);
|
|
_assertPred!"=="(date.diffMonths(Date(1998, 7, 5)), 12);
|
|
_assertPred!"=="(date.diffMonths(Date(1998, 8, 5)), 11);
|
|
_assertPred!"=="(date.diffMonths(Date(1998, 9, 5)), 10);
|
|
_assertPred!"=="(date.diffMonths(Date(1998, 10, 5)), 9);
|
|
_assertPred!"=="(date.diffMonths(Date(1998, 11, 5)), 8);
|
|
_assertPred!"=="(date.diffMonths(Date(1998, 12, 5)), 7);
|
|
_assertPred!"=="(date.diffMonths(Date(1999, 1, 5)), 6);
|
|
_assertPred!"=="(date.diffMonths(Date(1999, 2, 6)), 5);
|
|
_assertPred!"=="(date.diffMonths(Date(1999, 3, 6)), 4);
|
|
_assertPred!"=="(date.diffMonths(Date(1999, 4, 6)), 3);
|
|
_assertPred!"=="(date.diffMonths(Date(1999, 5, 6)), 2);
|
|
_assertPred!"=="(date.diffMonths(Date(1999, 6, 6)), 1);
|
|
_assertPred!"=="(date.diffMonths(date), 0);
|
|
_assertPred!"=="(date.diffMonths(Date(1999, 8, 6)), -1);
|
|
_assertPred!"=="(date.diffMonths(Date(1999, 9, 6)), -2);
|
|
_assertPred!"=="(date.diffMonths(Date(1999, 10, 6)), -3);
|
|
_assertPred!"=="(date.diffMonths(Date(1999, 11, 6)), -4);
|
|
_assertPred!"=="(date.diffMonths(Date(1999, 12, 6)), -5);
|
|
_assertPred!"=="(date.diffMonths(Date(2000, 1, 6)), -6);
|
|
_assertPred!"=="(date.diffMonths(Date(2000, 2, 6)), -7);
|
|
_assertPred!"=="(date.diffMonths(Date(2000, 3, 6)), -8);
|
|
_assertPred!"=="(date.diffMonths(Date(2000, 4, 6)), -9);
|
|
_assertPred!"=="(date.diffMonths(Date(2000, 5, 6)), -10);
|
|
_assertPred!"=="(date.diffMonths(Date(2000, 6, 6)), -11);
|
|
_assertPred!"=="(date.diffMonths(Date(2000, 7, 6)), -12);
|
|
_assertPred!"=="(date.diffMonths(Date(2000, 8, 6)), -13);
|
|
|
|
_assertPred!"=="(Date(1998, 6, 5).diffMonths(date), -13);
|
|
_assertPred!"=="(Date(1998, 7, 5).diffMonths(date), -12);
|
|
_assertPred!"=="(Date(1998, 8, 5).diffMonths(date), -11);
|
|
_assertPred!"=="(Date(1998, 9, 5).diffMonths(date), -10);
|
|
_assertPred!"=="(Date(1998, 10, 5).diffMonths(date), -9);
|
|
_assertPred!"=="(Date(1998, 11, 5).diffMonths(date), -8);
|
|
_assertPred!"=="(Date(1998, 12, 5).diffMonths(date), -7);
|
|
_assertPred!"=="(Date(1999, 1, 5).diffMonths(date), -6);
|
|
_assertPred!"=="(Date(1999, 2, 6).diffMonths(date), -5);
|
|
_assertPred!"=="(Date(1999, 3, 6).diffMonths(date), -4);
|
|
_assertPred!"=="(Date(1999, 4, 6).diffMonths(date), -3);
|
|
_assertPred!"=="(Date(1999, 5, 6).diffMonths(date), -2);
|
|
_assertPred!"=="(Date(1999, 6, 6).diffMonths(date), -1);
|
|
_assertPred!"=="(Date(1999, 8, 6).diffMonths(date), 1);
|
|
_assertPred!"=="(Date(1999, 9, 6).diffMonths(date), 2);
|
|
_assertPred!"=="(Date(1999, 10, 6).diffMonths(date), 3);
|
|
_assertPred!"=="(Date(1999, 11, 6).diffMonths(date), 4);
|
|
_assertPred!"=="(Date(1999, 12, 6).diffMonths(date), 5);
|
|
_assertPred!"=="(Date(2000, 1, 6).diffMonths(date), 6);
|
|
_assertPred!"=="(Date(2000, 2, 6).diffMonths(date), 7);
|
|
_assertPred!"=="(Date(2000, 3, 6).diffMonths(date), 8);
|
|
_assertPred!"=="(Date(2000, 4, 6).diffMonths(date), 9);
|
|
_assertPred!"=="(Date(2000, 5, 6).diffMonths(date), 10);
|
|
_assertPred!"=="(Date(2000, 6, 6).diffMonths(date), 11);
|
|
_assertPred!"=="(Date(2000, 7, 6).diffMonths(date), 12);
|
|
_assertPred!"=="(Date(2000, 8, 6).diffMonths(date), 13);
|
|
|
|
_assertPred!"=="(date.diffMonths(Date(1999, 6, 30)), 1);
|
|
_assertPred!"=="(date.diffMonths(Date(1999, 7, 1)), 0);
|
|
_assertPred!"=="(date.diffMonths(Date(1999, 7, 6)), 0);
|
|
_assertPred!"=="(date.diffMonths(Date(1999, 7, 11)), 0);
|
|
_assertPred!"=="(date.diffMonths(Date(1999, 7, 16)), 0);
|
|
_assertPred!"=="(date.diffMonths(Date(1999, 7, 21)), 0);
|
|
_assertPred!"=="(date.diffMonths(Date(1999, 7, 26)), 0);
|
|
_assertPred!"=="(date.diffMonths(Date(1999, 7, 31)), 0);
|
|
_assertPred!"=="(date.diffMonths(Date(1999, 8, 1)), -1);
|
|
|
|
_assertPred!"=="(date.diffMonths(Date(1990, 6, 30)), 109);
|
|
_assertPred!"=="(date.diffMonths(Date(1990, 7, 1)), 108);
|
|
_assertPred!"=="(date.diffMonths(Date(1990, 7, 6)), 108);
|
|
_assertPred!"=="(date.diffMonths(Date(1990, 7, 11)), 108);
|
|
_assertPred!"=="(date.diffMonths(Date(1990, 7, 16)), 108);
|
|
_assertPred!"=="(date.diffMonths(Date(1990, 7, 21)), 108);
|
|
_assertPred!"=="(date.diffMonths(Date(1990, 7, 26)), 108);
|
|
_assertPred!"=="(date.diffMonths(Date(1990, 7, 31)), 108);
|
|
_assertPred!"=="(date.diffMonths(Date(1990, 8, 1)), 107);
|
|
|
|
_assertPred!"=="(Date(1999, 6, 30).diffMonths(date), -1);
|
|
_assertPred!"=="(Date(1999, 7, 1).diffMonths(date), 0);
|
|
_assertPred!"=="(Date(1999, 7, 6).diffMonths(date), 0);
|
|
_assertPred!"=="(Date(1999, 7, 11).diffMonths(date), 0);
|
|
_assertPred!"=="(Date(1999, 7, 16).diffMonths(date), 0);
|
|
_assertPred!"=="(Date(1999, 7, 21).diffMonths(date), 0);
|
|
_assertPred!"=="(Date(1999, 7, 26).diffMonths(date), 0);
|
|
_assertPred!"=="(Date(1999, 7, 31).diffMonths(date), 0);
|
|
_assertPred!"=="(Date(1999, 8, 1).diffMonths(date), 1);
|
|
|
|
_assertPred!"=="(Date(1990, 6, 30).diffMonths(date), -109);
|
|
_assertPred!"=="(Date(1990, 7, 1).diffMonths(date), -108);
|
|
_assertPred!"=="(Date(1990, 7, 6).diffMonths(date), -108);
|
|
_assertPred!"=="(Date(1990, 7, 11).diffMonths(date), -108);
|
|
_assertPred!"=="(Date(1990, 7, 16).diffMonths(date), -108);
|
|
_assertPred!"=="(Date(1990, 7, 21).diffMonths(date), -108);
|
|
_assertPred!"=="(Date(1990, 7, 26).diffMonths(date), -108);
|
|
_assertPred!"=="(Date(1990, 7, 31).diffMonths(date), -108);
|
|
_assertPred!"=="(Date(1990, 8, 1).diffMonths(date), -107);
|
|
|
|
//Test B.C.
|
|
auto dateBC = Date(-1999, 7, 6);
|
|
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-2000, 6, 5)), 13);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-2000, 7, 5)), 12);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-2000, 8, 5)), 11);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-2000, 9, 5)), 10);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-2000, 10, 5)), 9);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-2000, 11, 5)), 8);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-2000, 12, 5)), 7);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1999, 1, 5)), 6);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1999, 2, 6)), 5);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1999, 3, 6)), 4);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1999, 4, 6)), 3);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1999, 5, 6)), 2);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1999, 6, 6)), 1);
|
|
_assertPred!"=="(dateBC.diffMonths(dateBC), 0);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1999, 8, 6)), -1);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1999, 9, 6)), -2);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1999, 10, 6)), -3);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1999, 11, 6)), -4);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1999, 12, 6)), -5);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1998, 1, 6)), -6);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1998, 2, 6)), -7);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1998, 3, 6)), -8);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1998, 4, 6)), -9);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1998, 5, 6)), -10);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1998, 6, 6)), -11);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1998, 7, 6)), -12);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1998, 8, 6)), -13);
|
|
|
|
_assertPred!"=="(Date(-2000, 6, 5).diffMonths(dateBC), -13);
|
|
_assertPred!"=="(Date(-2000, 7, 5).diffMonths(dateBC), -12);
|
|
_assertPred!"=="(Date(-2000, 8, 5).diffMonths(dateBC), -11);
|
|
_assertPred!"=="(Date(-2000, 9, 5).diffMonths(dateBC), -10);
|
|
_assertPred!"=="(Date(-2000, 10, 5).diffMonths(dateBC), -9);
|
|
_assertPred!"=="(Date(-2000, 11, 5).diffMonths(dateBC), -8);
|
|
_assertPred!"=="(Date(-2000, 12, 5).diffMonths(dateBC), -7);
|
|
_assertPred!"=="(Date(-1999, 1, 5).diffMonths(dateBC), -6);
|
|
_assertPred!"=="(Date(-1999, 2, 6).diffMonths(dateBC), -5);
|
|
_assertPred!"=="(Date(-1999, 3, 6).diffMonths(dateBC), -4);
|
|
_assertPred!"=="(Date(-1999, 4, 6).diffMonths(dateBC), -3);
|
|
_assertPred!"=="(Date(-1999, 5, 6).diffMonths(dateBC), -2);
|
|
_assertPred!"=="(Date(-1999, 6, 6).diffMonths(dateBC), -1);
|
|
_assertPred!"=="(Date(-1999, 8, 6).diffMonths(dateBC), 1);
|
|
_assertPred!"=="(Date(-1999, 9, 6).diffMonths(dateBC), 2);
|
|
_assertPred!"=="(Date(-1999, 10, 6).diffMonths(dateBC), 3);
|
|
_assertPred!"=="(Date(-1999, 11, 6).diffMonths(dateBC), 4);
|
|
_assertPred!"=="(Date(-1999, 12, 6).diffMonths(dateBC), 5);
|
|
_assertPred!"=="(Date(-1998, 1, 6).diffMonths(dateBC), 6);
|
|
_assertPred!"=="(Date(-1998, 2, 6).diffMonths(dateBC), 7);
|
|
_assertPred!"=="(Date(-1998, 3, 6).diffMonths(dateBC), 8);
|
|
_assertPred!"=="(Date(-1998, 4, 6).diffMonths(dateBC), 9);
|
|
_assertPred!"=="(Date(-1998, 5, 6).diffMonths(dateBC), 10);
|
|
_assertPred!"=="(Date(-1998, 6, 6).diffMonths(dateBC), 11);
|
|
_assertPred!"=="(Date(-1998, 7, 6).diffMonths(dateBC), 12);
|
|
_assertPred!"=="(Date(-1998, 8, 6).diffMonths(dateBC), 13);
|
|
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1999, 6, 30)), 1);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1999, 7, 1)), 0);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1999, 7, 6)), 0);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1999, 7, 11)), 0);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1999, 7, 16)), 0);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1999, 7, 21)), 0);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1999, 7, 26)), 0);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1999, 7, 31)), 0);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-1999, 8, 1)), -1);
|
|
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-2008, 6, 30)), 109);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-2008, 7, 1)), 108);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-2008, 7, 6)), 108);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-2008, 7, 11)), 108);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-2008, 7, 16)), 108);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-2008, 7, 21)), 108);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-2008, 7, 26)), 108);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-2008, 7, 31)), 108);
|
|
_assertPred!"=="(dateBC.diffMonths(Date(-2008, 8, 1)), 107);
|
|
|
|
_assertPred!"=="(Date(-1999, 6, 30).diffMonths(dateBC), -1);
|
|
_assertPred!"=="(Date(-1999, 7, 1).diffMonths(dateBC), 0);
|
|
_assertPred!"=="(Date(-1999, 7, 6).diffMonths(dateBC), 0);
|
|
_assertPred!"=="(Date(-1999, 7, 11).diffMonths(dateBC), 0);
|
|
_assertPred!"=="(Date(-1999, 7, 16).diffMonths(dateBC), 0);
|
|
_assertPred!"=="(Date(-1999, 7, 21).diffMonths(dateBC), 0);
|
|
_assertPred!"=="(Date(-1999, 7, 26).diffMonths(dateBC), 0);
|
|
_assertPred!"=="(Date(-1999, 7, 31).diffMonths(dateBC), 0);
|
|
_assertPred!"=="(Date(-1999, 8, 1).diffMonths(dateBC), 1);
|
|
|
|
_assertPred!"=="(Date(-2008, 6, 30).diffMonths(dateBC), -109);
|
|
_assertPred!"=="(Date(-2008, 7, 1).diffMonths(dateBC), -108);
|
|
_assertPred!"=="(Date(-2008, 7, 6).diffMonths(dateBC), -108);
|
|
_assertPred!"=="(Date(-2008, 7, 11).diffMonths(dateBC), -108);
|
|
_assertPred!"=="(Date(-2008, 7, 16).diffMonths(dateBC), -108);
|
|
_assertPred!"=="(Date(-2008, 7, 21).diffMonths(dateBC), -108);
|
|
_assertPred!"=="(Date(-2008, 7, 26).diffMonths(dateBC), -108);
|
|
_assertPred!"=="(Date(-2008, 7, 31).diffMonths(dateBC), -108);
|
|
_assertPred!"=="(Date(-2008, 8, 1).diffMonths(dateBC), -107);
|
|
|
|
//Test Both
|
|
_assertPred!"=="(Date(3, 3, 3).diffMonths(Date(-5, 5, 5)), 94);
|
|
_assertPred!"=="(Date(-5, 5, 5).diffMonths(Date(3, 3, 3)), -94);
|
|
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(__traits(compiles, date.diffMonths(date)));
|
|
static assert(__traits(compiles, cdate.diffMonths(date)));
|
|
static assert(__traits(compiles, idate.diffMonths(date)));
|
|
|
|
static assert(__traits(compiles, date.diffMonths(cdate)));
|
|
static assert(__traits(compiles, cdate.diffMonths(cdate)));
|
|
static assert(__traits(compiles, idate.diffMonths(cdate)));
|
|
|
|
static assert(__traits(compiles, date.diffMonths(idate)));
|
|
static assert(__traits(compiles, cdate.diffMonths(idate)));
|
|
static assert(__traits(compiles, idate.diffMonths(idate)));
|
|
|
|
//Verify Examples.
|
|
assert(Date(1999, 2, 1).diffMonths(Date(1999, 1, 31)) == 1);
|
|
assert(Date(1999, 1, 31).diffMonths(Date(1999, 2, 1)) == -1);
|
|
assert(Date(1999, 3, 1).diffMonths(Date(1999, 1, 1)) == 2);
|
|
assert(Date(1999, 1, 1).diffMonths(Date(1999, 3, 31)) == -2);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this $(D Date) is in a leap year.
|
|
+/
|
|
@property bool isLeapYear() const pure nothrow
|
|
{
|
|
return yearIsLeapYear(_year);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto date = Date(1999, 7, 6);
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(!__traits(compiles, date.isLeapYear = true));
|
|
static assert(!__traits(compiles, cdate.isLeapYear = true));
|
|
static assert(!__traits(compiles, idate.isLeapYear = true));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Day of the week this $(D Date) is on.
|
|
+/
|
|
@property DayOfWeek dayOfWeek() const pure nothrow
|
|
{
|
|
return getDayOfWeek(dayOfGregorianCal);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(__traits(compiles, cdate.dayOfWeek == DayOfWeek.sun));
|
|
static assert(!__traits(compiles, cdate.dayOfWeek = DayOfWeek.sun));
|
|
static assert(__traits(compiles, idate.dayOfWeek == DayOfWeek.sun));
|
|
static assert(!__traits(compiles, idate.dayOfWeek = DayOfWeek.sun));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Day of the year this $(D Date) is on.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Date(1999, 1, 1).dayOfYear == 1);
|
|
assert(Date(1999, 12, 31).dayOfYear == 365);
|
|
assert(Date(2000, 12, 31).dayOfYear == 366);
|
|
--------------------
|
|
+/
|
|
@property ushort dayOfYear() const pure nothrow
|
|
{
|
|
switch(_month)
|
|
{
|
|
case Month.jan:
|
|
return _day;
|
|
case Month.feb:
|
|
return cast(ushort)(31 + _day);
|
|
case Month.mar:
|
|
return cast(ushort)((isLeapYear ? 60 : 59) + _day);
|
|
case Month.apr:
|
|
return cast(ushort)((isLeapYear ? 91 : 90) + _day);
|
|
case Month.may:
|
|
return cast(ushort)((isLeapYear ? 121 : 120) + _day);
|
|
case Month.jun:
|
|
return cast(ushort)((isLeapYear ? 152 : 151) + _day);
|
|
case Month.jul:
|
|
return cast(ushort)((isLeapYear ? 182 : 181) + _day);
|
|
case Month.aug:
|
|
return cast(ushort)((isLeapYear ? 213 : 212) + _day);
|
|
case Month.sep:
|
|
return cast(ushort)((isLeapYear ? 244 : 243) + _day);
|
|
case Month.oct:
|
|
return cast(ushort)((isLeapYear ? 274 : 273) + _day);
|
|
case Month.nov:
|
|
return cast(ushort)((isLeapYear ? 305 : 304) + _day);
|
|
case Month.dec:
|
|
return cast(ushort)((isLeapYear ? 335 : 334) + _day);
|
|
default:
|
|
assert(0, "Invalid month.");
|
|
}
|
|
}
|
|
|
|
//Verify Examples.
|
|
version(testStdDateTime) unittest
|
|
{
|
|
assert(Date(1999, 1, 1).dayOfYear == 1);
|
|
assert(Date(1999, 12, 31).dayOfYear == 365);
|
|
assert(Date(2000, 12, 31).dayOfYear == 366);
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
foreach(year; filter!((a){return !yearIsLeapYear(a);})
|
|
(chain(testYearsBC, testYearsAD)))
|
|
{
|
|
foreach(doy; testDaysOfYear)
|
|
{
|
|
_assertPred!"=="(Date(year, doy.md.month, doy.md.day).dayOfYear,
|
|
doy.day);
|
|
}
|
|
}
|
|
|
|
foreach(year; filter!((a){return yearIsLeapYear(a);})
|
|
(chain(testYearsBC, testYearsAD)))
|
|
{
|
|
foreach(doy; testDaysOfLeapYear)
|
|
{
|
|
_assertPred!"=="(Date(year, doy.md.month, doy.md.day).dayOfYear,
|
|
doy.day);
|
|
}
|
|
}
|
|
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(__traits(compiles, cdate.dayOfYear == 187));
|
|
static assert(__traits(compiles, idate.dayOfYear == 187));
|
|
}
|
|
|
|
/++
|
|
Day of the year.
|
|
|
|
Params:
|
|
day = The day of the year to set which day of the year this
|
|
$(D Date) is on.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given day is an invalid day of the
|
|
year.
|
|
+/
|
|
@property void dayOfYear(int day) pure
|
|
{
|
|
if(isLeapYear)
|
|
{
|
|
if(day <= 0 || day > daysInLeapYear)
|
|
throw new DateTimeException("Invalid day of the year.");
|
|
|
|
switch(day)
|
|
{
|
|
case 1: .. case 31:
|
|
{
|
|
_month = Month.jan;
|
|
_day = cast(ubyte)day;
|
|
break;
|
|
}
|
|
case 32: .. case 60:
|
|
{
|
|
_month = Month.feb;
|
|
_day = cast(ubyte)(day - 31);
|
|
break;
|
|
}
|
|
case 61: .. case 91:
|
|
{
|
|
_month = Month.mar;
|
|
_day = cast(ubyte)(day - 60);
|
|
break;
|
|
}
|
|
case 92: .. case 121:
|
|
{
|
|
_month = Month.apr;
|
|
_day = cast(ubyte)(day - 91);
|
|
break;
|
|
}
|
|
case 122: .. case 152:
|
|
{
|
|
_month = Month.may;
|
|
_day = cast(ubyte)(day - 121);
|
|
break;
|
|
}
|
|
case 153: .. case 182:
|
|
{
|
|
_month = Month.jun;
|
|
_day = cast(ubyte)(day - 152);
|
|
break;
|
|
}
|
|
case 183: .. case 213:
|
|
{
|
|
_month = Month.jul;
|
|
_day = cast(ubyte)(day - 182);
|
|
break;
|
|
}
|
|
case 214: .. case 244:
|
|
{
|
|
_month = Month.aug;
|
|
_day = cast(ubyte)(day - 213);
|
|
break;
|
|
}
|
|
case 245: .. case 274:
|
|
{
|
|
_month = Month.sep;
|
|
_day = cast(ubyte)(day - 244);
|
|
break;
|
|
}
|
|
case 275: .. case 305:
|
|
{
|
|
_month = Month.oct;
|
|
_day = cast(ubyte)(day - 274);
|
|
break;
|
|
}
|
|
case 306: .. case 335:
|
|
{
|
|
_month = Month.nov;
|
|
_day = cast(ubyte)(day - 305);
|
|
break;
|
|
}
|
|
case 336: .. case 366:
|
|
{
|
|
_month = Month.dec;
|
|
_day = cast(ubyte)(day - 335);
|
|
break;
|
|
}
|
|
default:
|
|
assert(0, "Invalid day of the year.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(day <= 0 || day > daysInYear)
|
|
throw new DateTimeException("Invalid day of the year.");
|
|
|
|
switch(day)
|
|
{
|
|
case 1: .. case 31:
|
|
{
|
|
_month = Month.jan;
|
|
_day = cast(ubyte)day;
|
|
break;
|
|
}
|
|
case 32: .. case 59:
|
|
{
|
|
_month = Month.feb;
|
|
_day = cast(ubyte)(day - 31);
|
|
break;
|
|
}
|
|
case 60: .. case 90:
|
|
{
|
|
_month = Month.mar;
|
|
_day = cast(ubyte)(day - 59);
|
|
break;
|
|
}
|
|
case 91: .. case 120:
|
|
{
|
|
_month = Month.apr;
|
|
_day = cast(ubyte)(day - 90);
|
|
break;
|
|
}
|
|
case 121: .. case 151:
|
|
{
|
|
_month = Month.may;
|
|
_day = cast(ubyte)(day - 120);
|
|
break;
|
|
}
|
|
case 152: .. case 181:
|
|
{
|
|
_month = Month.jun;
|
|
_day = cast(ubyte)(day - 151);
|
|
break;
|
|
}
|
|
case 182: .. case 212:
|
|
{
|
|
_month = Month.jul;
|
|
_day = cast(ubyte)(day - 181);
|
|
break;
|
|
}
|
|
case 213: .. case 243:
|
|
{
|
|
_month = Month.aug;
|
|
_day = cast(ubyte)(day - 212);
|
|
break;
|
|
}
|
|
case 244: .. case 273:
|
|
{
|
|
_month = Month.sep;
|
|
_day = cast(ubyte)(day - 243);
|
|
break;
|
|
}
|
|
case 274: .. case 304:
|
|
{
|
|
_month = Month.oct;
|
|
_day = cast(ubyte)(day - 273);
|
|
break;
|
|
}
|
|
case 305: .. case 334:
|
|
{
|
|
_month = Month.nov;
|
|
_day = cast(ubyte)(day - 304);
|
|
break;
|
|
}
|
|
case 335: .. case 365:
|
|
{
|
|
_month = Month.dec;
|
|
_day = cast(ubyte)(day - 334);
|
|
break;
|
|
}
|
|
default:
|
|
assert(0, "Invalid day of the year.");
|
|
}
|
|
}
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
static void test(Date date, int day, MonthDay expected, size_t line = __LINE__)
|
|
{
|
|
date.dayOfYear = day;
|
|
_assertPred!"=="(date.month, expected.month, "", __FILE__, line);
|
|
_assertPred!"=="(date.day, expected.day, "", __FILE__, line);
|
|
}
|
|
|
|
foreach(doy; testDaysOfYear)
|
|
{
|
|
test(Date(1999, 1, 1), doy.day, doy.md);
|
|
test(Date(-1, 1, 1), doy.day, doy.md);
|
|
}
|
|
|
|
foreach(doy; testDaysOfLeapYear)
|
|
{
|
|
test(Date(2000, 1, 1), doy.day, doy.md);
|
|
test(Date(-4, 1, 1), doy.day, doy.md);
|
|
}
|
|
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(!__traits(compiles, cdate.dayOfYear = 187));
|
|
static assert(!__traits(compiles, idate.dayOfYear = 187));
|
|
}
|
|
|
|
|
|
/++
|
|
The Xth day of the Gregorian Calendar that this $(D Date) is on.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Date(1, 1, 1).dayOfGregorianCal == 1);
|
|
assert(Date(1, 12, 31).dayOfGregorianCal == 365);
|
|
assert(Date(2, 1, 1).dayOfGregorianCal == 366);
|
|
|
|
assert(Date(0, 12, 31).dayOfGregorianCal == 0);
|
|
assert(Date(0, 1, 1).dayOfGregorianCal == -365);
|
|
assert(Date(-1, 12, 31).dayOfGregorianCal == -366);
|
|
|
|
assert(Date(2000, 1, 1).dayOfGregorianCal == 730_120);
|
|
assert(Date(2010, 12, 31).dayOfGregorianCal == 734_137);
|
|
--------------------
|
|
+/
|
|
@property int dayOfGregorianCal() const pure nothrow
|
|
{
|
|
if(isAD)
|
|
{
|
|
if(_year == 1)
|
|
return dayOfYear;
|
|
|
|
int years = _year - 1;
|
|
auto days = (years / 400) * daysIn400Years;
|
|
years %= 400;
|
|
|
|
days += (years / 100) * daysIn100Years;
|
|
years %= 100;
|
|
|
|
days += (years / 4) * daysIn4Years;
|
|
years %= 4;
|
|
|
|
days += years * daysInYear;
|
|
|
|
days += dayOfYear;
|
|
|
|
return days;
|
|
}
|
|
else if(_year == 0)
|
|
return dayOfYear - daysInLeapYear;
|
|
else
|
|
{
|
|
int years = _year;
|
|
auto days = (years / 400) * daysIn400Years;
|
|
years %= 400;
|
|
|
|
days += (years / 100) * daysIn100Years;
|
|
years %= 100;
|
|
|
|
days += (years / 4) * daysIn4Years;
|
|
years %= 4;
|
|
|
|
if(years < 0)
|
|
{
|
|
days -= daysInLeapYear;
|
|
++years;
|
|
|
|
days += years * daysInYear;
|
|
|
|
days -= daysInYear - dayOfYear;
|
|
}
|
|
else
|
|
days -= daysInLeapYear - dayOfYear;
|
|
|
|
return days;
|
|
}
|
|
}
|
|
|
|
//Verify Examples.
|
|
version(testStdDateTime) unittest
|
|
{
|
|
assert(Date(1, 1, 1).dayOfGregorianCal == 1);
|
|
assert(Date(1, 12, 31).dayOfGregorianCal == 365);
|
|
assert(Date(2, 1, 1).dayOfGregorianCal == 366);
|
|
|
|
assert(Date(0, 12, 31).dayOfGregorianCal == 0);
|
|
assert(Date(0, 1, 1).dayOfGregorianCal == -365);
|
|
assert(Date(-1, 12, 31).dayOfGregorianCal == -366);
|
|
|
|
assert(Date(2000, 1, 1).dayOfGregorianCal == 730_120);
|
|
assert(Date(2010, 12, 31).dayOfGregorianCal == 734_137);
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
foreach(gd; chain(testGregDaysBC, testGregDaysAD))
|
|
_assertPred!"=="(gd.date.dayOfGregorianCal, gd.day);
|
|
|
|
auto date = Date(1999, 7, 6);
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(__traits(compiles, date.dayOfGregorianCal));
|
|
static assert(__traits(compiles, cdate.dayOfGregorianCal));
|
|
static assert(__traits(compiles, idate.dayOfGregorianCal));
|
|
}
|
|
|
|
/++
|
|
The Xth day of the Gregorian Calendar that this $(D Date) is on.
|
|
|
|
Params:
|
|
day = The day of the Gregorian Calendar to set this $(D Date) to.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto date = Date.init;
|
|
date.dayOfGregorianCal = 1;
|
|
assert(date == Date(1, 1, 1));
|
|
|
|
date.dayOfGregorianCal = 365;
|
|
assert(date == Date(1, 12, 31));
|
|
|
|
date.dayOfGregorianCal = 366;
|
|
assert(date == Date(2, 1, 1));
|
|
|
|
date.dayOfGregorianCal = 0;
|
|
assert(date == Date(0, 12, 31));
|
|
|
|
date.dayOfGregorianCal = -365;
|
|
assert(date == Date(-0, 1, 1));
|
|
|
|
date.dayOfGregorianCal = -366;
|
|
assert(date == Date(-1, 12, 31));
|
|
|
|
date.dayOfGregorianCal = 730_120;
|
|
assert(date == Date(2000, 1, 1));
|
|
|
|
date.dayOfGregorianCal = 734_137;
|
|
assert(date == Date(2010, 12, 31));
|
|
--------------------
|
|
+/
|
|
@property void dayOfGregorianCal(int day) pure nothrow
|
|
{
|
|
this = Date(day);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
{
|
|
auto date = Date(1999, 7, 6);
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(__traits(compiles, date.dayOfGregorianCal = 187));
|
|
static assert(!__traits(compiles, cdate.dayOfGregorianCal = 187));
|
|
static assert(!__traits(compiles, idate.dayOfGregorianCal = 187));
|
|
}
|
|
|
|
//Verify Examples.
|
|
{
|
|
auto date = Date.init;
|
|
date.dayOfGregorianCal = 1;
|
|
assert(date == Date(1, 1, 1));
|
|
|
|
date.dayOfGregorianCal = 365;
|
|
assert(date == Date(1, 12, 31));
|
|
|
|
date.dayOfGregorianCal = 366;
|
|
assert(date == Date(2, 1, 1));
|
|
|
|
date.dayOfGregorianCal = 0;
|
|
assert(date == Date(0, 12, 31));
|
|
|
|
date.dayOfGregorianCal = -365;
|
|
assert(date == Date(-0, 1, 1));
|
|
|
|
date.dayOfGregorianCal = -366;
|
|
assert(date == Date(-1, 12, 31));
|
|
|
|
date.dayOfGregorianCal = 730_120;
|
|
assert(date == Date(2000, 1, 1));
|
|
|
|
date.dayOfGregorianCal = 734_137;
|
|
assert(date == Date(2010, 12, 31));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
The ISO 8601 week of the year that this $(D Date) is in.
|
|
|
|
See_Also:
|
|
$(WEB en.wikipedia.org/wiki/ISO_week_date, ISO Week Date)
|
|
+/
|
|
@property ubyte isoWeek() const pure nothrow
|
|
{
|
|
immutable weekday = dayOfWeek;
|
|
immutable adjustedWeekday = weekday == DayOfWeek.sun ? 7 : weekday;
|
|
immutable week = (dayOfYear - adjustedWeekday + 10) / 7;
|
|
|
|
try
|
|
{
|
|
if(week == 53)
|
|
{
|
|
switch(Date(_year + 1, 1, 1).dayOfWeek)
|
|
{
|
|
case DayOfWeek.mon:
|
|
case DayOfWeek.tue:
|
|
case DayOfWeek.wed:
|
|
case DayOfWeek.thu:
|
|
return 1;
|
|
case DayOfWeek.fri:
|
|
case DayOfWeek.sat:
|
|
case DayOfWeek.sun:
|
|
return 53;
|
|
default:
|
|
assert(0, "Invalid ISO Week");
|
|
}
|
|
}
|
|
else if(week > 0)
|
|
return cast(ubyte)week;
|
|
else
|
|
return Date(_year - 1, 12, 31).isoWeek;
|
|
}
|
|
catch(Exception e)
|
|
assert(0, "Date's constructor threw.");
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
_assertPred!"=="(Date(2009, 12, 28).isoWeek, 53);
|
|
_assertPred!"=="(Date(2009, 12, 29).isoWeek, 53);
|
|
_assertPred!"=="(Date(2009, 12, 30).isoWeek, 53);
|
|
_assertPred!"=="(Date(2009, 12, 31).isoWeek, 53);
|
|
_assertPred!"=="(Date(2010, 1, 1).isoWeek, 53);
|
|
_assertPred!"=="(Date(2010, 1, 2).isoWeek, 53);
|
|
_assertPred!"=="(Date(2010, 1, 3).isoWeek, 53);
|
|
_assertPred!"=="(Date(2010, 1, 4).isoWeek, 1);
|
|
_assertPred!"=="(Date(2010, 1, 5).isoWeek, 1);
|
|
_assertPred!"=="(Date(2010, 1, 6).isoWeek, 1);
|
|
_assertPred!"=="(Date(2010, 1, 7).isoWeek, 1);
|
|
_assertPred!"=="(Date(2010, 1, 8).isoWeek, 1);
|
|
_assertPred!"=="(Date(2010, 1, 9).isoWeek, 1);
|
|
_assertPred!"=="(Date(2010, 1, 10).isoWeek, 1);
|
|
_assertPred!"=="(Date(2010, 1, 11).isoWeek, 2);
|
|
_assertPred!"=="(Date(2010, 12, 31).isoWeek, 52);
|
|
|
|
_assertPred!"=="(Date(2004, 12, 26).isoWeek, 52);
|
|
_assertPred!"=="(Date(2004, 12, 27).isoWeek, 53);
|
|
_assertPred!"=="(Date(2004, 12, 28).isoWeek, 53);
|
|
_assertPred!"=="(Date(2004, 12, 29).isoWeek, 53);
|
|
_assertPred!"=="(Date(2004, 12, 30).isoWeek, 53);
|
|
_assertPred!"=="(Date(2004, 12, 31).isoWeek, 53);
|
|
_assertPred!"=="(Date(2005, 1, 1).isoWeek, 53);
|
|
_assertPred!"=="(Date(2005, 1, 2).isoWeek, 53);
|
|
|
|
_assertPred!"=="(Date(2005, 12, 31).isoWeek, 52);
|
|
_assertPred!"=="(Date(2007, 1, 1).isoWeek, 1);
|
|
|
|
_assertPred!"=="(Date(2007, 12, 30).isoWeek, 52);
|
|
_assertPred!"=="(Date(2007, 12, 31).isoWeek, 1);
|
|
_assertPred!"=="(Date(2008, 1, 1).isoWeek, 1);
|
|
|
|
_assertPred!"=="(Date(2008, 12, 28).isoWeek, 52);
|
|
_assertPred!"=="(Date(2008, 12, 29).isoWeek, 1);
|
|
_assertPred!"=="(Date(2008, 12, 30).isoWeek, 1);
|
|
_assertPred!"=="(Date(2008, 12, 31).isoWeek, 1);
|
|
_assertPred!"=="(Date(2009, 1, 1).isoWeek, 1);
|
|
_assertPred!"=="(Date(2009, 1, 2).isoWeek, 1);
|
|
_assertPred!"=="(Date(2009, 1, 3).isoWeek, 1);
|
|
_assertPred!"=="(Date(2009, 1, 4).isoWeek, 1);
|
|
|
|
//Test B.C.
|
|
//The algorithm should work identically for both A.D. and B.C. since
|
|
//it doesn't really take the year into account, so B.C. testing
|
|
//probably isn't really needed.
|
|
_assertPred!"=="(Date(0, 12, 31).isoWeek, 52);
|
|
_assertPred!"=="(Date(0, 1, 4).isoWeek, 1);
|
|
_assertPred!"=="(Date(0, 1, 1).isoWeek, 52);
|
|
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(__traits(compiles, cdate.isoWeek == 3));
|
|
static assert(!__traits(compiles, cdate.isoWeek = 3));
|
|
static assert(__traits(compiles, idate.isoWeek == 3));
|
|
static assert(!__traits(compiles, idate.isoWeek = 3));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
$(D Date) for the last day in the month that this $(D Date) is in.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Date(1999, 1, 6).endOfMonth == Date(1999, 1, 31));
|
|
assert(Date(1999, 2, 7).endOfMonth == Date(1999, 2, 28));
|
|
assert(Date(2000, 2, 7).endOfMonth == Date(1999, 2, 29));
|
|
assert(Date(2000, 6, 4).endOfMonth == Date(1999, 6, 30));
|
|
--------------------
|
|
+/
|
|
@property Date endOfMonth() const pure nothrow
|
|
{
|
|
try
|
|
return Date(_year, _month, maxDay(_year, _month));
|
|
catch(Exception e)
|
|
assert(0, "Date's constructor threw.");
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
_assertPred!"=="(Date(1999, 1, 1).endOfMonth, Date(1999, 1, 31));
|
|
_assertPred!"=="(Date(1999, 2, 1).endOfMonth, Date(1999, 2, 28));
|
|
_assertPred!"=="(Date(2000, 2, 1).endOfMonth, Date(2000, 2, 29));
|
|
_assertPred!"=="(Date(1999, 3, 1).endOfMonth, Date(1999, 3, 31));
|
|
_assertPred!"=="(Date(1999, 4, 1).endOfMonth, Date(1999, 4, 30));
|
|
_assertPred!"=="(Date(1999, 5, 1).endOfMonth, Date(1999, 5, 31));
|
|
_assertPred!"=="(Date(1999, 6, 1).endOfMonth, Date(1999, 6, 30));
|
|
_assertPred!"=="(Date(1999, 7, 1).endOfMonth, Date(1999, 7, 31));
|
|
_assertPred!"=="(Date(1999, 8, 1).endOfMonth, Date(1999, 8, 31));
|
|
_assertPred!"=="(Date(1999, 9, 1).endOfMonth, Date(1999, 9, 30));
|
|
_assertPred!"=="(Date(1999, 10, 1).endOfMonth, Date(1999, 10, 31));
|
|
_assertPred!"=="(Date(1999, 11, 1).endOfMonth, Date(1999, 11, 30));
|
|
_assertPred!"=="(Date(1999, 12, 1).endOfMonth, Date(1999, 12, 31));
|
|
|
|
//Test B.C.
|
|
_assertPred!"=="(Date(-1999, 1, 1).endOfMonth, Date(-1999, 1, 31));
|
|
_assertPred!"=="(Date(-1999, 2, 1).endOfMonth, Date(-1999, 2, 28));
|
|
_assertPred!"=="(Date(-2000, 2, 1).endOfMonth, Date(-2000, 2, 29));
|
|
_assertPred!"=="(Date(-1999, 3, 1).endOfMonth, Date(-1999, 3, 31));
|
|
_assertPred!"=="(Date(-1999, 4, 1).endOfMonth, Date(-1999, 4, 30));
|
|
_assertPred!"=="(Date(-1999, 5, 1).endOfMonth, Date(-1999, 5, 31));
|
|
_assertPred!"=="(Date(-1999, 6, 1).endOfMonth, Date(-1999, 6, 30));
|
|
_assertPred!"=="(Date(-1999, 7, 1).endOfMonth, Date(-1999, 7, 31));
|
|
_assertPred!"=="(Date(-1999, 8, 1).endOfMonth, Date(-1999, 8, 31));
|
|
_assertPred!"=="(Date(-1999, 9, 1).endOfMonth, Date(-1999, 9, 30));
|
|
_assertPred!"=="(Date(-1999, 10, 1).endOfMonth, Date(-1999, 10, 31));
|
|
_assertPred!"=="(Date(-1999, 11, 1).endOfMonth, Date(-1999, 11, 30));
|
|
_assertPred!"=="(Date(-1999, 12, 1).endOfMonth, Date(-1999, 12, 31));
|
|
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(!__traits(compiles, cdate.endOfMonth = Date(1999, 7, 30)));
|
|
static assert(!__traits(compiles, idate.endOfMonth = Date(1999, 7, 30)));
|
|
|
|
//Verify Examples.
|
|
assert(Date(1999, 1, 6).endOfMonth == Date(1999, 1, 31));
|
|
assert(Date(1999, 2, 7).endOfMonth == Date(1999, 2, 28));
|
|
assert(Date(2000, 2, 7).endOfMonth == Date(2000, 2, 29));
|
|
assert(Date(2000, 6, 4).endOfMonth == Date(2000, 6, 30));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
The last day in the month that this $(D Date) is in.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Date(1999, 1, 6).daysInMonth == 31);
|
|
assert(Date(1999, 2, 7).daysInMonth == 28);
|
|
assert(Date(2000, 2, 7).daysInMonth == 29);
|
|
assert(Date(2000, 6, 4).daysInMonth == 30);
|
|
--------------------
|
|
+/
|
|
@property ubyte daysInMonth() const pure nothrow
|
|
{
|
|
return maxDay(_year, _month);
|
|
}
|
|
|
|
/++
|
|
$(RED Scheduled for deprecation in January 2012.
|
|
Please use daysInMonth instead.)
|
|
+/
|
|
alias daysInMonth endofMonthDay;
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
_assertPred!"=="(Date(1999, 1, 1).daysInMonth, 31);
|
|
_assertPred!"=="(Date(1999, 2, 1).daysInMonth, 28);
|
|
_assertPred!"=="(Date(2000, 2, 1).daysInMonth, 29);
|
|
_assertPred!"=="(Date(1999, 3, 1).daysInMonth, 31);
|
|
_assertPred!"=="(Date(1999, 4, 1).daysInMonth, 30);
|
|
_assertPred!"=="(Date(1999, 5, 1).daysInMonth, 31);
|
|
_assertPred!"=="(Date(1999, 6, 1).daysInMonth, 30);
|
|
_assertPred!"=="(Date(1999, 7, 1).daysInMonth, 31);
|
|
_assertPred!"=="(Date(1999, 8, 1).daysInMonth, 31);
|
|
_assertPred!"=="(Date(1999, 9, 1).daysInMonth, 30);
|
|
_assertPred!"=="(Date(1999, 10, 1).daysInMonth, 31);
|
|
_assertPred!"=="(Date(1999, 11, 1).daysInMonth, 30);
|
|
_assertPred!"=="(Date(1999, 12, 1).daysInMonth, 31);
|
|
|
|
//Test B.C.
|
|
_assertPred!"=="(Date(-1999, 1, 1).daysInMonth, 31);
|
|
_assertPred!"=="(Date(-1999, 2, 1).daysInMonth, 28);
|
|
_assertPred!"=="(Date(-2000, 2, 1).daysInMonth, 29);
|
|
_assertPred!"=="(Date(-1999, 3, 1).daysInMonth, 31);
|
|
_assertPred!"=="(Date(-1999, 4, 1).daysInMonth, 30);
|
|
_assertPred!"=="(Date(-1999, 5, 1).daysInMonth, 31);
|
|
_assertPred!"=="(Date(-1999, 6, 1).daysInMonth, 30);
|
|
_assertPred!"=="(Date(-1999, 7, 1).daysInMonth, 31);
|
|
_assertPred!"=="(Date(-1999, 8, 1).daysInMonth, 31);
|
|
_assertPred!"=="(Date(-1999, 9, 1).daysInMonth, 30);
|
|
_assertPred!"=="(Date(-1999, 10, 1).daysInMonth, 31);
|
|
_assertPred!"=="(Date(-1999, 11, 1).daysInMonth, 30);
|
|
_assertPred!"=="(Date(-1999, 12, 1).daysInMonth, 31);
|
|
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(!__traits(compiles, cdate.daysInMonth = 30));
|
|
static assert(!__traits(compiles, idate.daysInMonth = 30));
|
|
|
|
//Verify Examples.
|
|
assert(Date(1999, 1, 6).daysInMonth == 31);
|
|
assert(Date(1999, 2, 7).daysInMonth == 28);
|
|
assert(Date(2000, 2, 7).daysInMonth == 29);
|
|
assert(Date(2000, 6, 4).daysInMonth == 30);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the current year is a date in A.D.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Date(1, 1, 1).isAD);
|
|
assert(Date(2010, 12, 31).isAD);
|
|
assert(!Date(0, 12, 31).isAD);
|
|
assert(!Date(-2010, 1, 1).isAD);
|
|
--------------------
|
|
+/
|
|
@property bool isAD() const pure nothrow
|
|
{
|
|
return _year > 0;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assert(Date(2010, 7, 4).isAD);
|
|
assert(Date(1, 1, 1).isAD);
|
|
assert(!Date(0, 1, 1).isAD);
|
|
assert(!Date(-1, 1, 1).isAD);
|
|
assert(!Date(-2010, 7, 4).isAD);
|
|
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(__traits(compiles, cdate.isAD));
|
|
static assert(__traits(compiles, idate.isAD));
|
|
|
|
//Verify Examples.
|
|
assert(Date(1, 1, 1).isAD);
|
|
assert(Date(2010, 12, 31).isAD);
|
|
assert(!Date(0, 12, 31).isAD);
|
|
assert(!Date(-2010, 1, 1).isAD);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
The julian day for this $(D Date) at noon (since the julian day changes
|
|
at noon).
|
|
+/
|
|
@property long julianDay() const pure nothrow
|
|
{
|
|
return dayOfGregorianCal + 1_721_425;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(Date(-4713, 11, 24).julianDay, 0);
|
|
_assertPred!"=="(Date(0, 12, 31).julianDay, 1_721_425);
|
|
_assertPred!"=="(Date(1, 1, 1).julianDay, 1_721_426);
|
|
_assertPred!"=="(Date(1582, 10, 15).julianDay, 2_299_161);
|
|
_assertPred!"=="(Date(1858, 11, 17).julianDay, 2_400_001);
|
|
_assertPred!"=="(Date(1982, 1, 4).julianDay, 2_444_974);
|
|
_assertPred!"=="(Date(1996, 3, 31).julianDay, 2_450_174);
|
|
_assertPred!"=="(Date(2010, 8, 24).julianDay, 2_455_433);
|
|
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(__traits(compiles, cdate.julianDay));
|
|
static assert(__traits(compiles, idate.julianDay));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
The modified julian day for any time on this date (since, the modified
|
|
julian day changes at midnight).
|
|
+/
|
|
@property long modJulianDay() const pure nothrow
|
|
{
|
|
return julianDay - 2_400_001;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(Date(1858, 11, 17).modJulianDay, 0);
|
|
_assertPred!"=="(Date(2010, 8, 24).modJulianDay, 55_432);
|
|
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(__traits(compiles, cdate.modJulianDay));
|
|
static assert(__traits(compiles, idate.modJulianDay));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Converts this $(D Date) to a string with the format YYYYMMDD.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Date(2010, 7, 4).toISOString() == "20100704");
|
|
assert(Date(1998, 12, 25).toISOString() == "19981225");
|
|
assert(Date(0, 1, 5).toISOString() == "00000105");
|
|
assert(Date(-4, 1, 5).toISOString() == "-00040105");
|
|
--------------------
|
|
+/
|
|
string toISOString() const nothrow
|
|
{
|
|
try
|
|
{
|
|
if(_year >= 0)
|
|
{
|
|
if(_year < 10_000)
|
|
return format("%04d%02d%02d", _year, _month, _day);
|
|
else
|
|
return format("+%05d%02d%02d", _year, _month, _day);
|
|
}
|
|
else if(_year > -10_000)
|
|
return format("%05d%02d%02d", _year, _month, _day);
|
|
else
|
|
return format("%06d%02d%02d", _year, _month, _day);
|
|
}
|
|
catch(Exception e)
|
|
assert(0, "format() threw.");
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
_assertPred!"=="(Date(9, 12, 4).toISOString(), "00091204");
|
|
_assertPred!"=="(Date(99, 12, 4).toISOString(), "00991204");
|
|
_assertPred!"=="(Date(999, 12, 4).toISOString(), "09991204");
|
|
_assertPred!"=="(Date(9999, 7, 4).toISOString(), "99990704");
|
|
_assertPred!"=="(Date(10000, 10, 20).toISOString(), "+100001020");
|
|
|
|
//Test B.C.
|
|
_assertPred!"=="(Date(0, 12, 4).toISOString(), "00001204");
|
|
_assertPred!"=="(Date(-9, 12, 4).toISOString(), "-00091204");
|
|
_assertPred!"=="(Date(-99, 12, 4).toISOString(), "-00991204");
|
|
_assertPred!"=="(Date(-999, 12, 4).toISOString(), "-09991204");
|
|
_assertPred!"=="(Date(-9999, 7, 4).toISOString(), "-99990704");
|
|
_assertPred!"=="(Date(-10000, 10, 20).toISOString(), "-100001020");
|
|
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(__traits(compiles, cdate.toISOString()));
|
|
static assert(__traits(compiles, idate.toISOString()));
|
|
|
|
//Verify Examples.
|
|
assert(Date(2010, 7, 4).toISOString() == "20100704");
|
|
assert(Date(1998, 12, 25).toISOString() == "19981225");
|
|
assert(Date(0, 1, 5).toISOString() == "00000105");
|
|
assert(Date(-4, 1, 5).toISOString() == "-00040105");
|
|
}
|
|
}
|
|
|
|
/++
|
|
Converts this $(D Date) to a string with the format YYYY-MM-DD.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Date(2010, 7, 4).toISOExtString() == "2010-07-04");
|
|
assert(Date(1998, 12, 25).toISOExtString() == "1998-12-25");
|
|
assert(Date(0, 1, 5).toISOExtString() == "0000-01-05");
|
|
assert(Date(-4, 1, 5).toISOExtString() == "-0004-01-05");
|
|
--------------------
|
|
+/
|
|
string toISOExtString() const nothrow
|
|
{
|
|
try
|
|
{
|
|
if(_year >= 0)
|
|
{
|
|
if(_year < 10_000)
|
|
return format("%04d-%02d-%02d", _year, _month, _day);
|
|
else
|
|
return format("+%05d-%02d-%02d", _year, _month, _day);
|
|
}
|
|
else if(_year > -10_000)
|
|
return format("%05d-%02d-%02d", _year, _month, _day);
|
|
else
|
|
return format("%06d-%02d-%02d", _year, _month, _day);
|
|
}
|
|
catch(Exception e)
|
|
assert(0, "format() threw.");
|
|
}
|
|
|
|
/++
|
|
$(RED Scheduled for deprecation in November 2011.
|
|
Please use toISOExtString instead.)
|
|
+/
|
|
alias toISOExtString toISOExtendedString;
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
_assertPred!"=="(Date(9, 12, 4).toISOExtString(), "0009-12-04");
|
|
_assertPred!"=="(Date(99, 12, 4).toISOExtString(), "0099-12-04");
|
|
_assertPred!"=="(Date(999, 12, 4).toISOExtString(), "0999-12-04");
|
|
_assertPred!"=="(Date(9999, 7, 4).toISOExtString(), "9999-07-04");
|
|
_assertPred!"=="(Date(10000, 10, 20).toISOExtString(), "+10000-10-20");
|
|
|
|
//Test B.C.
|
|
_assertPred!"=="(Date(0, 12, 4).toISOExtString(), "0000-12-04");
|
|
_assertPred!"=="(Date(-9, 12, 4).toISOExtString(), "-0009-12-04");
|
|
_assertPred!"=="(Date(-99, 12, 4).toISOExtString(), "-0099-12-04");
|
|
_assertPred!"=="(Date(-999, 12, 4).toISOExtString(), "-0999-12-04");
|
|
_assertPred!"=="(Date(-9999, 7, 4).toISOExtString(), "-9999-07-04");
|
|
_assertPred!"=="(Date(-10000, 10, 20).toISOExtString(), "-10000-10-20");
|
|
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(__traits(compiles, cdate.toISOExtString()));
|
|
static assert(__traits(compiles, idate.toISOExtString()));
|
|
|
|
//Verify Examples.
|
|
assert(Date(2010, 7, 4).toISOExtString() == "2010-07-04");
|
|
assert(Date(1998, 12, 25).toISOExtString() == "1998-12-25");
|
|
assert(Date(0, 1, 5).toISOExtString() == "0000-01-05");
|
|
assert(Date(-4, 1, 5).toISOExtString() == "-0004-01-05");
|
|
}
|
|
}
|
|
|
|
/++
|
|
Converts this $(D Date) to a string with the format YYYY-Mon-DD.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Date(2010, 7, 4).toSimpleString() == "2010-Jul-04");
|
|
assert(Date(1998, 12, 25).toSimpleString() == "1998-Dec-25");
|
|
assert(Date(0, 1, 5).toSimpleString() == "0000-Jan-05");
|
|
assert(Date(-4, 1, 5).toSimpleString() == "-0004-Jan-05");
|
|
--------------------
|
|
+/
|
|
string toSimpleString() const nothrow
|
|
{
|
|
try
|
|
{
|
|
if(_year >= 0)
|
|
{
|
|
if(_year < 10_000)
|
|
return format("%04d-%s-%02d", _year, monthToString(_month, false), _day);
|
|
else
|
|
return format("+%05d-%s-%02d", _year, monthToString(_month, false), _day);
|
|
}
|
|
else if(_year > -10_000)
|
|
return format("%05d-%s-%02d", _year, monthToString(_month, false), _day);
|
|
else
|
|
return format("%06d-%s-%02d", _year, monthToString(_month, false), _day);
|
|
}
|
|
catch(Exception e)
|
|
assert(0, "format() threw.");
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
_assertPred!"=="(Date(9, 12, 4).toSimpleString(), "0009-Dec-04");
|
|
_assertPred!"=="(Date(99, 12, 4).toSimpleString(), "0099-Dec-04");
|
|
_assertPred!"=="(Date(999, 12, 4).toSimpleString(), "0999-Dec-04");
|
|
_assertPred!"=="(Date(9999, 7, 4).toSimpleString(), "9999-Jul-04");
|
|
_assertPred!"=="(Date(10000, 10, 20).toSimpleString(), "+10000-Oct-20");
|
|
|
|
//Test B.C.
|
|
_assertPred!"=="(Date(0, 12, 4).toSimpleString(), "0000-Dec-04");
|
|
_assertPred!"=="(Date(-9, 12, 4).toSimpleString(), "-0009-Dec-04");
|
|
_assertPred!"=="(Date(-99, 12, 4).toSimpleString(), "-0099-Dec-04");
|
|
_assertPred!"=="(Date(-999, 12, 4).toSimpleString(), "-0999-Dec-04");
|
|
_assertPred!"=="(Date(-9999, 7, 4).toSimpleString(), "-9999-Jul-04");
|
|
_assertPred!"=="(Date(-10000, 10, 20).toSimpleString(), "-10000-Oct-20");
|
|
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(__traits(compiles, cdate.toSimpleString()));
|
|
static assert(__traits(compiles, idate.toSimpleString()));
|
|
|
|
//Verify Examples.
|
|
assert(Date(2010, 7, 4).toSimpleString() == "2010-Jul-04");
|
|
assert(Date(1998, 12, 25).toSimpleString() == "1998-Dec-25");
|
|
assert(Date(0, 1, 5).toSimpleString() == "0000-Jan-05");
|
|
assert(Date(-4, 1, 5).toSimpleString() == "-0004-Jan-05");
|
|
}
|
|
}
|
|
|
|
//TODO Add a function which returns a string in a user-specified format.
|
|
|
|
|
|
/+
|
|
Converts this $(D Date) to a string.
|
|
+/
|
|
//Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't
|
|
//have versions of toString() with extra modifiers, so we define one version
|
|
//with modifiers and one without.
|
|
string toString()
|
|
{
|
|
return toSimpleString();
|
|
}
|
|
|
|
/++
|
|
Converts this $(D Date) to a string.
|
|
+/
|
|
//Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't
|
|
//have versions of toString() with extra modifiers, so we define one version
|
|
//with modifiers and one without.
|
|
string toString() const nothrow
|
|
{
|
|
return toSimpleString();
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto date = Date(1999, 7, 6);
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(__traits(compiles, date.toString()));
|
|
static assert(__traits(compiles, cdate.toString()));
|
|
static assert(__traits(compiles, idate.toString()));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Creates a $(D Date) from a string with the format YYYYMMDD. Whitespace
|
|
is stripped from the given string.
|
|
|
|
Params:
|
|
isoString = A string formatted in the ISO format for dates.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given string is not in the ISO format
|
|
or if the resulting $(D Date) would not be valid.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Date.fromISOString("20100704") == Date(2010, 7, 4));
|
|
assert(Date.fromISOString("19981225") == Date(1998, 12, 25));
|
|
assert(Date.fromISOString("00000105") == Date(0, 1, 5));
|
|
assert(Date.fromISOString("-00040105") == Date(-4, 1, 5));
|
|
assert(Date.fromISOString(" 20100704 ") == Date(2010, 7, 4));
|
|
--------------------
|
|
+/
|
|
static Date fromISOString(S)(in S isoString)
|
|
if(isSomeString!S)
|
|
{
|
|
auto dstr = to!dstring(strip(isoString));
|
|
|
|
enforce(dstr.length >= 8, new DateTimeException(format("Invalid ISO String: %s", isoString)));
|
|
|
|
auto day = dstr[$-2 .. $];
|
|
auto month = dstr[$-4 .. $-2];
|
|
auto year = dstr[0 .. $-4];
|
|
|
|
enforce(!canFind!(not!isDigit)(day), new DateTimeException(format("Invalid ISO String: %s", isoString)));
|
|
enforce(!canFind!(not!isDigit)(month), new DateTimeException(format("Invalid ISO String: %s", isoString)));
|
|
|
|
if(year.length > 4)
|
|
{
|
|
enforce(year.startsWith("-") || year.startsWith("+"),
|
|
new DateTimeException(format("Invalid ISO String: %s", isoString)));
|
|
enforce(!canFind!(not!isDigit)(year[1..$]),
|
|
new DateTimeException(format("Invalid ISO String: %s", isoString)));
|
|
}
|
|
else
|
|
enforce(!canFind!(not!isDigit)(year), new DateTimeException(format("Invalid ISO String: %s", isoString)));
|
|
|
|
return Date(to!short(year), to!ubyte(month), to!ubyte(day));
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assertThrown!DateTimeException(Date.fromISOString(""));
|
|
assertThrown!DateTimeException(Date.fromISOString("990704"));
|
|
assertThrown!DateTimeException(Date.fromISOString("0100704"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010070"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010070 "));
|
|
assertThrown!DateTimeException(Date.fromISOString("120100704"));
|
|
assertThrown!DateTimeException(Date.fromISOString("-0100704"));
|
|
assertThrown!DateTimeException(Date.fromISOString("+0100704"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010070a"));
|
|
assertThrown!DateTimeException(Date.fromISOString("20100a04"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010a704"));
|
|
|
|
assertThrown!DateTimeException(Date.fromISOString("99-07-04"));
|
|
assertThrown!DateTimeException(Date.fromISOString("010-07-04"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010-07-0"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010-07-0 "));
|
|
assertThrown!DateTimeException(Date.fromISOString("12010-07-04"));
|
|
assertThrown!DateTimeException(Date.fromISOString("-010-07-04"));
|
|
assertThrown!DateTimeException(Date.fromISOString("+010-07-04"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010-07-0a"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010-0a-04"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010-a7-04"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010/07/04"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010/7/04"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010/7/4"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010/07/4"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010-7-04"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010-7-4"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010-07-4"));
|
|
|
|
assertThrown!DateTimeException(Date.fromISOString("99Jul04"));
|
|
assertThrown!DateTimeException(Date.fromISOString("010Jul04"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010Jul0"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010Jul0 "));
|
|
assertThrown!DateTimeException(Date.fromISOString("12010Jul04"));
|
|
assertThrown!DateTimeException(Date.fromISOString("-010Jul04"));
|
|
assertThrown!DateTimeException(Date.fromISOString("+010Jul04"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010Jul0a"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010Jua04"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010aul04"));
|
|
|
|
assertThrown!DateTimeException(Date.fromISOString("99-Jul-04"));
|
|
assertThrown!DateTimeException(Date.fromISOString("010-Jul-04"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010-Jul-0"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010-Jul-0 "));
|
|
assertThrown!DateTimeException(Date.fromISOString("12010-Jul-04"));
|
|
assertThrown!DateTimeException(Date.fromISOString("-010-Jul-04"));
|
|
assertThrown!DateTimeException(Date.fromISOString("+010-Jul-04"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010-Jul-0a"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010-Jua-04"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010-Jal-04"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010-aul-04"));
|
|
|
|
assertThrown!DateTimeException(Date.fromISOString("2010-07-04"));
|
|
assertThrown!DateTimeException(Date.fromISOString("2010-Jul-04"));
|
|
|
|
_assertPred!"=="(Date.fromISOString("19990706"), Date(1999, 7, 6));
|
|
_assertPred!"=="(Date.fromISOString("-19990706"), Date(-1999, 7, 6));
|
|
_assertPred!"=="(Date.fromISOString("+019990706"), Date(1999, 7, 6));
|
|
_assertPred!"=="(Date.fromISOString("19990706 "), Date(1999, 7, 6));
|
|
_assertPred!"=="(Date.fromISOString(" 19990706"), Date(1999, 7, 6));
|
|
_assertPred!"=="(Date.fromISOString(" 19990706 "), Date(1999, 7, 6));
|
|
|
|
//Verify Examples.
|
|
assert(Date.fromISOString("20100704") == Date(2010, 7, 4));
|
|
assert(Date.fromISOString("19981225") == Date(1998, 12, 25));
|
|
assert(Date.fromISOString("00000105") == Date(0, 1, 5));
|
|
assert(Date.fromISOString("-00040105") == Date(-4, 1, 5));
|
|
assert(Date.fromISOString(" 20100704 ") == Date(2010, 7, 4));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Creates a $(D Date) from a string with the format YYYY-MM-DD. Whitespace
|
|
is stripped from the given string.
|
|
|
|
Params:
|
|
isoExtString = A string formatted in the ISO Extended format for
|
|
dates.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given string is not in the ISO
|
|
Extended format or if the resulting $(D Date) would not be valid.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Date.fromISOExtString("2010-07-04") == Date(2010, 7, 4));
|
|
assert(Date.fromISOExtString("1998-12-25") == Date(1998, 12, 25));
|
|
assert(Date.fromISOExtString("0000-01-05") == Date(0, 1, 5));
|
|
assert(Date.fromISOExtString("-0004-01-05") == Date(-4, 1, 5));
|
|
assert(Date.fromISOExtString(" 2010-07-04 ") == Date(2010, 7, 4));
|
|
--------------------
|
|
+/
|
|
static Date fromISOExtString(S)(in S isoExtString)
|
|
if(isSomeString!(S))
|
|
{
|
|
auto dstr = to!dstring(strip(isoExtString));
|
|
|
|
enforce(dstr.length >= 10, new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
|
|
|
|
auto day = dstr[$-2 .. $];
|
|
auto month = dstr[$-5 .. $-3];
|
|
auto year = dstr[0 .. $-6];
|
|
|
|
enforce(dstr[$-3] == '-', new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
|
|
enforce(dstr[$-6] == '-', new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
|
|
enforce(!canFind!(not!isDigit)(day),
|
|
new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
|
|
enforce(!canFind!(not!isDigit)(month),
|
|
new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
|
|
|
|
if(year.length > 4)
|
|
{
|
|
enforce(year.startsWith("-") || year.startsWith("+"),
|
|
new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
|
|
enforce(!canFind!(not!isDigit)(year[1..$]),
|
|
new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
|
|
}
|
|
else
|
|
enforce(!canFind!(not!isDigit)(year),
|
|
new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
|
|
|
|
return Date(to!short(year), to!ubyte(month), to!ubyte(day));
|
|
}
|
|
|
|
/++
|
|
$(RED Scheduled for deprecation in November 2011.
|
|
Please use fromISOExtString instead.)
|
|
+/
|
|
static Date fromISOExtendedString(S)(in S isoExtString)
|
|
if(isSomeString!(S))
|
|
{
|
|
pragma(msg, softDeprec!("2.053", "November 2011", "fromISOExtendedString", "fromISOExtString"));
|
|
|
|
return fromISOExtString!string(isoExtString);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assertThrown!DateTimeException(Date.fromISOExtString(""));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("990704"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("0100704"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010070"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010070 "));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("120100704"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("-0100704"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("+0100704"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010070a"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("20100a04"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010a704"));
|
|
|
|
assertThrown!DateTimeException(Date.fromISOExtString("99-07-04"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("010-07-04"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010-07-0"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010-07-0 "));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("12010-07-04"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("-010-07-04"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("+010-07-04"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010-07-0a"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010-0a-04"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010-a7-04"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010/07/04"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010/7/04"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010/7/4"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010/07/4"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010-7-04"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010-7-4"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010-07-4"));
|
|
|
|
assertThrown!DateTimeException(Date.fromISOExtString("99Jul04"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("010Jul04"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010Jul0"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010-Jul-0 "));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("12010Jul04"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("-010Jul04"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("+010Jul04"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010Jul0a"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010Jua04"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010aul04"));
|
|
|
|
assertThrown!DateTimeException(Date.fromISOExtString("99-Jul-04"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("010-Jul-04"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010-Jul-0"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010Jul0 "));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("12010-Jul-04"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("-010-Jul-04"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("+010-Jul-04"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010-Jul-0a"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010-Jua-04"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010-Jal-04"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010-aul-04"));
|
|
|
|
assertThrown!DateTimeException(Date.fromISOExtString("20100704"));
|
|
assertThrown!DateTimeException(Date.fromISOExtString("2010-Jul-04"));
|
|
|
|
_assertPred!"=="(Date.fromISOExtString("1999-07-06"), Date(1999, 7, 6));
|
|
_assertPred!"=="(Date.fromISOExtString("-1999-07-06"), Date(-1999, 7, 6));
|
|
_assertPred!"=="(Date.fromISOExtString("+01999-07-06"), Date(1999, 7, 6));
|
|
_assertPred!"=="(Date.fromISOExtString("1999-07-06 "), Date(1999, 7, 6));
|
|
_assertPred!"=="(Date.fromISOExtString(" 1999-07-06"), Date(1999, 7, 6));
|
|
_assertPred!"=="(Date.fromISOExtString(" 1999-07-06 "), Date(1999, 7, 6));
|
|
|
|
//Verify Examples.
|
|
assert(Date.fromISOExtString("2010-07-04") == Date(2010, 7, 4));
|
|
assert(Date.fromISOExtString("1998-12-25") == Date(1998, 12, 25));
|
|
assert(Date.fromISOExtString("0000-01-05") == Date(0, 1, 5));
|
|
assert(Date.fromISOExtString("-0004-01-05") == Date(-4, 1, 5));
|
|
assert(Date.fromISOExtString(" 2010-07-04 ") == Date(2010, 7, 4));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Creates a $(D Date) from a string with the format YYYY-Mon-DD.
|
|
Whitespace is stripped from the given string.
|
|
|
|
Params:
|
|
simpleString = A string formatted in the way that toSimpleString
|
|
formats dates.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given string is not in the correct
|
|
format or if the resulting $(D Date) would not be valid.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Date.fromSimpleString("2010-Jul-04") == Date(2010, 7, 4));
|
|
assert(Date.fromSimpleString("1998-Dec-25") == Date(1998, 12, 25));
|
|
assert(Date.fromSimpleString("0000-Jan-05") == Date(0, 1, 5));
|
|
assert(Date.fromSimpleString("-0004-Jan-05") == Date(-4, 1, 5));
|
|
assert(Date.fromSimpleString(" 2010-Jul-04 ") == Date(2010, 7, 4));
|
|
--------------------
|
|
+/
|
|
static Date fromSimpleString(S)(in S simpleString)
|
|
if(isSomeString!(S))
|
|
{
|
|
auto dstr = to!dstring(strip(simpleString));
|
|
|
|
enforce(dstr.length >= 11, new DateTimeException(format("Invalid string format: %s", simpleString)));
|
|
|
|
auto day = dstr[$-2 .. $];
|
|
auto month = monthFromString(to!string(dstr[$-6 .. $-3]));
|
|
auto year = dstr[0 .. $-7];
|
|
|
|
enforce(dstr[$-3] == '-', new DateTimeException(format("Invalid string format: %s", simpleString)));
|
|
enforce(dstr[$-7] == '-', new DateTimeException(format("Invalid string format: %s", simpleString)));
|
|
enforce(!canFind!(not!isDigit)(day), new DateTimeException(format("Invalid string format: %s", simpleString)));
|
|
|
|
if(year.length > 4)
|
|
{
|
|
enforce(year.startsWith("-") || year.startsWith("+"),
|
|
new DateTimeException(format("Invalid string format: %s", simpleString)));
|
|
enforce(!canFind!(not!isDigit)(year[1..$]),
|
|
new DateTimeException(format("Invalid string format: %s", simpleString)));
|
|
}
|
|
else
|
|
enforce(!canFind!(not!isDigit)(year),
|
|
new DateTimeException(format("Invalid string format: %s", simpleString)));
|
|
|
|
return Date(to!short(year), month, to!ubyte(day));
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assertThrown!DateTimeException(Date.fromSimpleString(""));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("990704"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("0100704"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010070"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010070 "));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("120100704"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("-0100704"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("+0100704"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010070a"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("20100a04"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010a704"));
|
|
|
|
assertThrown!DateTimeException(Date.fromSimpleString("99-07-04"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("010-07-04"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010-07-0"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010-07-0 "));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("12010-07-04"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("-010-07-04"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("+010-07-04"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010-07-0a"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010-0a-04"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010-a7-04"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010/07/04"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010/7/04"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010/7/4"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010/07/4"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010-7-04"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010-7-4"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010-07-4"));
|
|
|
|
assertThrown!DateTimeException(Date.fromSimpleString("99Jul04"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("010Jul04"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010Jul0"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010Jul0 "));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("12010Jul04"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("-010Jul04"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("+010Jul04"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010Jul0a"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010Jua04"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010aul04"));
|
|
|
|
assertThrown!DateTimeException(Date.fromSimpleString("99-Jul-04"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("010-Jul-04"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010-Jul-0"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010-Jul-0 "));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("12010-Jul-04"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("-010-Jul-04"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("+010-Jul-04"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010-Jul-0a"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010-Jua-04"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010-Jal-04"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010-aul-04"));
|
|
|
|
assertThrown!DateTimeException(Date.fromSimpleString("20100704"));
|
|
assertThrown!DateTimeException(Date.fromSimpleString("2010-07-04"));
|
|
|
|
_assertPred!"=="(Date.fromSimpleString("1999-Jul-06"), Date(1999, 7, 6));
|
|
_assertPred!"=="(Date.fromSimpleString("-1999-Jul-06"), Date(-1999, 7, 6));
|
|
_assertPred!"=="(Date.fromSimpleString("+01999-Jul-06"), Date(1999, 7, 6));
|
|
_assertPred!"=="(Date.fromSimpleString("1999-Jul-06 "), Date(1999, 7, 6));
|
|
_assertPred!"=="(Date.fromSimpleString(" 1999-Jul-06"), Date(1999, 7, 6));
|
|
_assertPred!"=="(Date.fromSimpleString(" 1999-Jul-06 "), Date(1999, 7, 6));
|
|
|
|
//Verify Examples.
|
|
assert(Date.fromSimpleString("2010-Jul-04") == Date(2010, 7, 4));
|
|
assert(Date.fromSimpleString("1998-Dec-25") == Date(1998, 12, 25));
|
|
assert(Date.fromSimpleString("0000-Jan-05") == Date(0, 1, 5));
|
|
assert(Date.fromSimpleString("-0004-Jan-05") == Date(-4, 1, 5));
|
|
assert(Date.fromSimpleString(" 2010-Jul-04 ") == Date(2010, 7, 4));
|
|
}
|
|
}
|
|
|
|
|
|
//TODO Add function which takes a user-specified time format and produces a Date
|
|
|
|
//TODO Add function which takes pretty much any time-string and produces a Date
|
|
// Obviously, it will be less efficient, and it probably won't manage _every_
|
|
// possible date format, but a smart conversion function would be nice.
|
|
|
|
|
|
/++
|
|
Returns the $(D Date) farthest in the past which is representable by
|
|
$(D Date).
|
|
+/
|
|
@property static Date min() pure nothrow
|
|
{
|
|
auto date = Date.init;
|
|
date._year = short.min;
|
|
date._month = Month.jan;
|
|
date._day = 1;
|
|
|
|
return date;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assert(Date.min.year < 0);
|
|
assert(Date.min < Date.max);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the $(D Date) farthest in the future which is representable by
|
|
$(D Date).
|
|
+/
|
|
@property static Date max() pure nothrow
|
|
{
|
|
auto date = Date.init;
|
|
date._year = short.max;
|
|
date._month = Month.dec;
|
|
date._day = 31;
|
|
|
|
return date;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assert(Date.max.year > 0);
|
|
assert(Date.max > Date.min);
|
|
}
|
|
}
|
|
|
|
|
|
private:
|
|
|
|
/+
|
|
Whether the given values form a valid date.
|
|
|
|
Params:
|
|
year = The year to test.
|
|
month = The month of the Gregorian Calendar to test.
|
|
day = The day of the month to test.
|
|
+/
|
|
static bool _valid(int year, int month, int day) pure nothrow
|
|
{
|
|
if(!valid!"months"(month))
|
|
return false;
|
|
|
|
return valid!"days"(year, month, day);
|
|
}
|
|
|
|
/+
|
|
Adds the given number of days to this $(D Date). A negative number will
|
|
subtract.
|
|
|
|
The month will be adjusted along with the day if the number of days
|
|
added (or subtracted) would overflow (or underflow) the current month.
|
|
The year will be adjusted along with the month if the increase (or
|
|
decrease) to the month would cause it to overflow (or underflow) the
|
|
current year.
|
|
|
|
$(D addDays(numDays)) is effectively equivalent to
|
|
$(D date.dayOfGregorianCal = date.dayOfGregorianCal + days).
|
|
|
|
Params:
|
|
days = The number of days to add to this Date.
|
|
+/
|
|
ref Date addDays(long days) pure nothrow
|
|
{
|
|
dayOfGregorianCal = cast(int)(dayOfGregorianCal + days);
|
|
|
|
return this;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
{
|
|
auto date = Date(1999, 2, 28);
|
|
date.addDays(1);
|
|
_assertPred!"=="(date, Date(1999, 3, 1));
|
|
date.addDays(-1);
|
|
_assertPred!"=="(date, Date(1999, 2, 28));
|
|
}
|
|
|
|
{
|
|
auto date = Date(2000, 2, 28);
|
|
date.addDays(1);
|
|
_assertPred!"=="(date, Date(2000, 2, 29));
|
|
date.addDays(1);
|
|
_assertPred!"=="(date, Date(2000, 3, 1));
|
|
date.addDays(-1);
|
|
_assertPred!"=="(date, Date(2000, 2, 29));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 6, 30);
|
|
date.addDays(1);
|
|
_assertPred!"=="(date, Date(1999, 7, 1));
|
|
date.addDays(-1);
|
|
_assertPred!"=="(date, Date(1999, 6, 30));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 7, 31);
|
|
date.addDays(1);
|
|
_assertPred!"=="(date, Date(1999, 8, 1));
|
|
date.addDays(-1);
|
|
_assertPred!"=="(date, Date(1999, 7, 31));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 1, 1);
|
|
date.addDays(-1);
|
|
_assertPred!"=="(date, Date(1998, 12, 31));
|
|
date.addDays(1);
|
|
_assertPred!"=="(date, Date(1999, 1, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 7, 6);
|
|
date.addDays(9);
|
|
_assertPred!"=="(date, Date(1999, 7, 15));
|
|
date.addDays(-11);
|
|
_assertPred!"=="(date, Date(1999, 7, 4));
|
|
date.addDays(30);
|
|
_assertPred!"=="(date, Date(1999, 8, 3));
|
|
date.addDays(-3);
|
|
_assertPred!"=="(date, Date(1999, 7, 31));
|
|
}
|
|
|
|
{
|
|
auto date = Date(1999, 7, 6);
|
|
date.addDays(365);
|
|
_assertPred!"=="(date, Date(2000, 7, 5));
|
|
date.addDays(-365);
|
|
_assertPred!"=="(date, Date(1999, 7, 6));
|
|
date.addDays(366);
|
|
_assertPred!"=="(date, Date(2000, 7, 6));
|
|
date.addDays(730);
|
|
_assertPred!"=="(date, Date(2002, 7, 6));
|
|
date.addDays(-1096);
|
|
_assertPred!"=="(date, Date(1999, 7, 6));
|
|
}
|
|
|
|
//Test B.C.
|
|
{
|
|
auto date = Date(-1999, 2, 28);
|
|
date.addDays(1);
|
|
_assertPred!"=="(date, Date(-1999, 3, 1));
|
|
date.addDays(-1);
|
|
_assertPred!"=="(date, Date(-1999, 2, 28));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-2000, 2, 28);
|
|
date.addDays(1);
|
|
_assertPred!"=="(date, Date(-2000, 2, 29));
|
|
date.addDays(1);
|
|
_assertPred!"=="(date, Date(-2000, 3, 1));
|
|
date.addDays(-1);
|
|
_assertPred!"=="(date, Date(-2000, 2, 29));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 6, 30);
|
|
date.addDays(1);
|
|
_assertPred!"=="(date, Date(-1999, 7, 1));
|
|
date.addDays(-1);
|
|
_assertPred!"=="(date, Date(-1999, 6, 30));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 7, 31);
|
|
date.addDays(1);
|
|
_assertPred!"=="(date, Date(-1999, 8, 1));
|
|
date.addDays(-1);
|
|
_assertPred!"=="(date, Date(-1999, 7, 31));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 1, 1);
|
|
date.addDays(-1);
|
|
_assertPred!"=="(date, Date(-2000, 12, 31));
|
|
date.addDays(1);
|
|
_assertPred!"=="(date, Date(-1999, 1, 1));
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 7, 6);
|
|
date.addDays(9);
|
|
_assertPred!"=="(date, Date(-1999, 7, 15));
|
|
date.addDays(-11);
|
|
_assertPred!"=="(date, Date(-1999, 7, 4));
|
|
date.addDays(30);
|
|
_assertPred!"=="(date, Date(-1999, 8, 3));
|
|
date.addDays(-3);
|
|
}
|
|
|
|
{
|
|
auto date = Date(-1999, 7, 6);
|
|
date.addDays(365);
|
|
_assertPred!"=="(date, Date(-1998, 7, 6));
|
|
date.addDays(-365);
|
|
_assertPred!"=="(date, Date(-1999, 7, 6));
|
|
date.addDays(366);
|
|
_assertPred!"=="(date, Date(-1998, 7, 7));
|
|
date.addDays(730);
|
|
_assertPred!"=="(date, Date(-1996, 7, 6));
|
|
date.addDays(-1096);
|
|
_assertPred!"=="(date, Date(-1999, 7, 6));
|
|
}
|
|
|
|
//Test Both
|
|
{
|
|
auto date = Date(1, 7, 6);
|
|
date.addDays(-365);
|
|
_assertPred!"=="(date, Date(0, 7, 6));
|
|
date.addDays(365);
|
|
_assertPred!"=="(date, Date(1, 7, 6));
|
|
date.addDays(-731);
|
|
_assertPred!"=="(date, Date(-1, 7, 6));
|
|
date.addDays(730);
|
|
_assertPred!"=="(date, Date(1, 7, 5));
|
|
}
|
|
|
|
const cdate = Date(1999, 7, 6);
|
|
immutable idate = Date(1999, 7, 6);
|
|
static assert(!__traits(compiles, cdate.addDays(12)));
|
|
static assert(!__traits(compiles, idate.addDays(12)));
|
|
}
|
|
}
|
|
|
|
|
|
pure invariant()
|
|
{
|
|
assert(valid!"months"(_month), "Invariant Failure: year [" ~
|
|
numToString(_year) ~
|
|
"] month [" ~
|
|
numToString(_month) ~
|
|
"] day [" ~
|
|
numToString(_day) ~
|
|
"]");
|
|
assert(valid!"days"(_year, _month, _day), "Invariant Failure: year [" ~
|
|
numToString(_year) ~
|
|
"] month [" ~
|
|
numToString(_month) ~
|
|
"] day [" ~
|
|
numToString(_day) ~
|
|
"]");
|
|
}
|
|
|
|
|
|
short _year = 1;
|
|
Month _month = Month.jan;
|
|
ubyte _day = 1;
|
|
}
|
|
|
|
|
|
|
|
/++
|
|
Represents a time of day with hours, minutes, and seconds. It uses 24 hour
|
|
time.
|
|
+/
|
|
struct TimeOfDay
|
|
{
|
|
public:
|
|
|
|
/++
|
|
Params:
|
|
hour = Hour of the day [0 - 24$(RPAREN).
|
|
minute = Minute of the hour [0 - 60$(RPAREN).
|
|
second = Second of the minute [0 - 60$(RPAREN).
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the resulting $(D TimeOfDay) would be not
|
|
be valid.
|
|
+/
|
|
this(int hour, int minute, int second = 0) pure
|
|
{
|
|
enforceValid!"hours"(hour);
|
|
enforceValid!"minutes"(minute);
|
|
enforceValid!"seconds"(second);
|
|
|
|
_hour = cast(ubyte)hour;
|
|
_minute = cast(ubyte)minute;
|
|
_second = cast(ubyte)second;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assert(TimeOfDay(0, 0) == TimeOfDay.init);
|
|
|
|
{
|
|
auto tod = TimeOfDay(0, 0);
|
|
_assertPred!"=="(tod._hour, 0);
|
|
_assertPred!"=="(tod._minute, 0);
|
|
_assertPred!"=="(tod._second, 0);
|
|
}
|
|
|
|
{
|
|
auto tod = TimeOfDay(12, 30, 33);
|
|
_assertPred!"=="(tod._hour, 12);
|
|
_assertPred!"=="(tod._minute, 30);
|
|
_assertPred!"=="(tod._second, 33);
|
|
}
|
|
|
|
{
|
|
auto tod = TimeOfDay(23, 59, 59);
|
|
_assertPred!"=="(tod._hour, 23);
|
|
_assertPred!"=="(tod._minute, 59);
|
|
_assertPred!"=="(tod._second, 59);
|
|
}
|
|
|
|
assertThrown!DateTimeException(TimeOfDay(24, 0, 0));
|
|
assertThrown!DateTimeException(TimeOfDay(0, 60, 0));
|
|
assertThrown!DateTimeException(TimeOfDay(0, 0, 60));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Compares this $(D TimeOfDay) with the given $(D TimeOfDay).
|
|
|
|
Returns:
|
|
$(BOOKTABLE,
|
|
$(TR $(TD this < rhs) $(TD < 0))
|
|
$(TR $(TD this == rhs) $(TD 0))
|
|
$(TR $(TD this > rhs) $(TD > 0))
|
|
)
|
|
+/
|
|
int opCmp(in TimeOfDay rhs) const pure nothrow
|
|
{
|
|
if(_hour < rhs._hour)
|
|
return -1;
|
|
if(_hour > rhs._hour)
|
|
return 1;
|
|
|
|
if(_minute < rhs._minute)
|
|
return -1;
|
|
if(_minute > rhs._minute)
|
|
return 1;
|
|
|
|
if(_second < rhs._second)
|
|
return -1;
|
|
if(_second > rhs._second)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!("opCmp", "==")(TimeOfDay(0, 0, 0), TimeOfDay.init);
|
|
|
|
_assertPred!("opCmp", "==")(TimeOfDay(0, 0, 0), TimeOfDay(0, 0, 0));
|
|
_assertPred!("opCmp", "==")(TimeOfDay(12, 0, 0), TimeOfDay(12, 0, 0));
|
|
_assertPred!("opCmp", "==")(TimeOfDay(0, 30, 0), TimeOfDay(0, 30, 0));
|
|
_assertPred!("opCmp", "==")(TimeOfDay(0, 0, 33), TimeOfDay(0, 0, 33));
|
|
|
|
_assertPred!("opCmp", "==")(TimeOfDay(12, 30, 0), TimeOfDay(12, 30, 0));
|
|
_assertPred!("opCmp", "==")(TimeOfDay(12, 30, 33), TimeOfDay(12, 30, 33));
|
|
|
|
_assertPred!("opCmp", "==")(TimeOfDay(0, 30, 33), TimeOfDay(0, 30, 33));
|
|
_assertPred!("opCmp", "==")(TimeOfDay(0, 0, 33), TimeOfDay(0, 0, 33));
|
|
|
|
_assertPred!("opCmp", "<")(TimeOfDay(12, 30, 33), TimeOfDay(13, 30, 33));
|
|
_assertPred!("opCmp", ">")(TimeOfDay(13, 30, 33), TimeOfDay(12, 30, 33));
|
|
_assertPred!("opCmp", "<")(TimeOfDay(12, 30, 33), TimeOfDay(12, 31, 33));
|
|
_assertPred!("opCmp", ">")(TimeOfDay(12, 31, 33), TimeOfDay(12, 30, 33));
|
|
_assertPred!("opCmp", "<")(TimeOfDay(12, 30, 33), TimeOfDay(12, 30, 34));
|
|
_assertPred!("opCmp", ">")(TimeOfDay(12, 30, 34), TimeOfDay(12, 30, 33));
|
|
|
|
_assertPred!("opCmp", ">")(TimeOfDay(13, 30, 33), TimeOfDay(12, 30, 34));
|
|
_assertPred!("opCmp", "<")(TimeOfDay(12, 30, 34), TimeOfDay(13, 30, 33));
|
|
_assertPred!("opCmp", ">")(TimeOfDay(13, 30, 33), TimeOfDay(12, 31, 33));
|
|
_assertPred!("opCmp", "<")(TimeOfDay(12, 31, 33), TimeOfDay(13, 30, 33));
|
|
|
|
_assertPred!("opCmp", ">")(TimeOfDay(12, 31, 33), TimeOfDay(12, 30, 34));
|
|
_assertPred!("opCmp", "<")(TimeOfDay(12, 30, 34), TimeOfDay(12, 31, 33));
|
|
|
|
const ctod = TimeOfDay(12, 30, 33);
|
|
immutable itod = TimeOfDay(12, 30, 33);
|
|
static assert(__traits(compiles, ctod.opCmp(itod)));
|
|
static assert(__traits(compiles, itod.opCmp(ctod)));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Hours passed midnight.
|
|
+/
|
|
@property ubyte hour() const pure nothrow
|
|
{
|
|
return _hour;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(TimeOfDay.init.hour, 0);
|
|
_assertPred!"=="(TimeOfDay(12, 0, 0).hour, 12);
|
|
|
|
const ctod = TimeOfDay(12, 0, 0);
|
|
immutable itod = TimeOfDay(12, 0, 0);
|
|
static assert(__traits(compiles, ctod.hour == 12));
|
|
static assert(__traits(compiles, itod.hour == 12));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Hours passed midnight.
|
|
|
|
Params:
|
|
hour = The hour of the day to set this $(D TimeOfDay)'s hour to.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given hour would result in an invalid
|
|
$(D TimeOfDay).
|
|
+/
|
|
@property void hour(int hour) pure
|
|
{
|
|
enforceValid!"hours"(hour);
|
|
_hour = cast(ubyte)hour;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assertThrown!DateTimeException((){TimeOfDay(0, 0, 0).hour = 24;}());
|
|
|
|
auto tod = TimeOfDay(0, 0, 0);
|
|
tod.hour = 12;
|
|
_assertPred!"=="(tod, TimeOfDay(12, 0, 0));
|
|
|
|
const ctod = TimeOfDay(0, 0, 0);
|
|
immutable itod = TimeOfDay(0, 0, 0);
|
|
static assert(!__traits(compiles, ctod.hour = 12));
|
|
static assert(!__traits(compiles, itod.hour = 12));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Minutes passed the hour.
|
|
+/
|
|
@property ubyte minute() const pure nothrow
|
|
{
|
|
return _minute;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(TimeOfDay.init.minute, 0);
|
|
_assertPred!"=="(TimeOfDay(0, 30, 0).minute, 30);
|
|
|
|
const ctod = TimeOfDay(0, 30, 0);
|
|
immutable itod = TimeOfDay(0, 30, 0);
|
|
static assert(__traits(compiles, ctod.minute == 30));
|
|
static assert(__traits(compiles, itod.minute == 30));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Minutes passed the hour.
|
|
|
|
Params:
|
|
minute = The minute to set this $(D TimeOfDay)'s minute to.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given minute would result in an
|
|
invalid $(D TimeOfDay).
|
|
+/
|
|
@property void minute(int minute) pure
|
|
{
|
|
enforceValid!"minutes"(minute);
|
|
_minute = cast(ubyte)minute;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assertThrown!DateTimeException((){TimeOfDay(0, 0, 0).minute = 60;}());
|
|
|
|
auto tod = TimeOfDay(0, 0, 0);
|
|
tod.minute = 30;
|
|
_assertPred!"=="(tod, TimeOfDay(0, 30, 0));
|
|
|
|
const ctod = TimeOfDay(0, 0, 0);
|
|
immutable itod = TimeOfDay(0, 0, 0);
|
|
static assert(!__traits(compiles, ctod.minute = 30));
|
|
static assert(!__traits(compiles, itod.minute = 30));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Seconds passed the minute.
|
|
+/
|
|
@property ubyte second() const pure nothrow
|
|
{
|
|
return _second;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(TimeOfDay.init.second, 0);
|
|
_assertPred!"=="(TimeOfDay(0, 0, 33).second, 33);
|
|
|
|
const ctod = TimeOfDay(0, 0, 33);
|
|
immutable itod = TimeOfDay(0, 0, 33);
|
|
static assert(__traits(compiles, ctod.second == 33));
|
|
static assert(__traits(compiles, itod.second == 33));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Seconds passed the minute.
|
|
|
|
Params:
|
|
second = The second to set this $(D TimeOfDay)'s second to.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given second would result in an
|
|
invalid $(D TimeOfDay).
|
|
+/
|
|
@property void second(int second) pure
|
|
{
|
|
enforceValid!"seconds"(second);
|
|
_second = cast(ubyte)second;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assertThrown!DateTimeException((){TimeOfDay(0, 0, 0).second = 60;}());
|
|
|
|
auto tod = TimeOfDay(0, 0, 0);
|
|
tod.second = 33;
|
|
_assertPred!"=="(tod, TimeOfDay(0, 0, 33));
|
|
|
|
const ctod = TimeOfDay(0, 0, 0);
|
|
immutable itod = TimeOfDay(0, 0, 0);
|
|
static assert(!__traits(compiles, ctod.second = 33));
|
|
static assert(!__traits(compiles, itod.second = 33));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Adds the given number of units to this $(D TimeOfDay). A negative number
|
|
will subtract.
|
|
|
|
The difference between rolling and adding is that rolling does not
|
|
affect larger units. So, for instance, if you roll a $(D TimeOfDay)
|
|
one hours's worth of minutes, then you get the exact same
|
|
$(D TimeOfDay).
|
|
|
|
Accepted units are $(D "hours"), $(D "minutes"), and $(D "seconds").
|
|
|
|
Params:
|
|
units = The units to add.
|
|
value = The number of $(D_PARAM units) to add to this
|
|
$(D TimeOfDay).
|
|
|
|
Examples:
|
|
--------------------
|
|
auto tod1 = TimeOfDay(7, 12, 0);
|
|
tod1.roll!"hours"(1);
|
|
assert(tod1 == TimeOfDay(8, 12, 0));
|
|
|
|
auto tod2 = TimeOfDay(7, 12, 0);
|
|
tod2.roll!"hours"(-1);
|
|
assert(tod2 == TimeOfDay(6, 12, 0));
|
|
|
|
auto tod3 = TimeOfDay(23, 59, 0);
|
|
tod3.roll!"minutes"(1);
|
|
assert(tod3 == TimeOfDay(23, 0, 0));
|
|
|
|
auto tod4 = TimeOfDay(0, 0, 0);
|
|
tod4.roll!"minutes"(-1);
|
|
assert(tod4 == TimeOfDay(0, 59, 0));
|
|
|
|
auto tod5 = TimeOfDay(23, 59, 59);
|
|
tod5.roll!"seconds"(1);
|
|
assert(tod5 == TimeOfDay(23, 59, 0));
|
|
|
|
auto tod6 = TimeOfDay(0, 0, 0);
|
|
tod6.roll!"seconds"(-1);
|
|
assert(tod6 == TimeOfDay(0, 0, 59));
|
|
--------------------
|
|
+/
|
|
/+ref TimeOfDay+/ void roll(string units)(long value) pure nothrow
|
|
if(units == "hours")
|
|
{
|
|
this += dur!"hours"(value);
|
|
}
|
|
|
|
//Verify Examples.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto tod1 = TimeOfDay(7, 12, 0);
|
|
tod1.roll!"hours"(1);
|
|
assert(tod1 == TimeOfDay(8, 12, 0));
|
|
|
|
auto tod2 = TimeOfDay(7, 12, 0);
|
|
tod2.roll!"hours"(-1);
|
|
assert(tod2 == TimeOfDay(6, 12, 0));
|
|
|
|
auto tod3 = TimeOfDay(23, 59, 0);
|
|
tod3.roll!"minutes"(1);
|
|
assert(tod3 == TimeOfDay(23, 0, 0));
|
|
|
|
auto tod4 = TimeOfDay(0, 0, 0);
|
|
tod4.roll!"minutes"(-1);
|
|
assert(tod4 == TimeOfDay(0, 59, 0));
|
|
|
|
auto tod5 = TimeOfDay(23, 59, 59);
|
|
tod5.roll!"seconds"(1);
|
|
assert(tod5 == TimeOfDay(23, 59, 0));
|
|
|
|
auto tod6 = TimeOfDay(0, 0, 0);
|
|
tod6.roll!"seconds"(-1);
|
|
assert(tod6 == TimeOfDay(0, 0, 59));
|
|
}
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
const ctod = TimeOfDay(0, 0, 0);
|
|
immutable itod = TimeOfDay(0, 0, 0);
|
|
static assert(!__traits(compiles, ctod.roll!"hours"(53)));
|
|
static assert(!__traits(compiles, itod.roll!"hours"(53)));
|
|
}
|
|
}
|
|
|
|
|
|
//Shares documentation with "hours" version.
|
|
/+ref TimeOfDay+/ void roll(string units)(long value) pure nothrow
|
|
if(units == "minutes" ||
|
|
units == "seconds")
|
|
{
|
|
static if(units == "minutes")
|
|
enum memberVarStr = "minute";
|
|
else static if(units == "seconds")
|
|
enum memberVarStr = "second";
|
|
else
|
|
static assert(0);
|
|
|
|
value %= 60;
|
|
mixin("auto newVal = cast(ubyte)(_" ~ memberVarStr ~ ") + value;");
|
|
|
|
if(value < 0)
|
|
{
|
|
if(newVal < 0)
|
|
newVal += 60;
|
|
}
|
|
else if(newVal >= 60)
|
|
newVal -= 60;
|
|
|
|
mixin("_" ~ memberVarStr ~ " = cast(ubyte)newVal;");
|
|
}
|
|
|
|
//Test roll!"minutes"().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static void testTOD(TimeOfDay orig, int minutes, in TimeOfDay expected, size_t line = __LINE__)
|
|
{
|
|
orig.roll!"minutes"(minutes);
|
|
_assertPred!"=="(orig, expected, "", __FILE__, line);
|
|
}
|
|
|
|
testTOD(TimeOfDay(12, 30, 33), 0, TimeOfDay(12, 30, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 1, TimeOfDay(12, 31, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 2, TimeOfDay(12, 32, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 3, TimeOfDay(12, 33, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 4, TimeOfDay(12, 34, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 5, TimeOfDay(12, 35, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 10, TimeOfDay(12, 40, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 15, TimeOfDay(12, 45, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 29, TimeOfDay(12, 59, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 30, TimeOfDay(12, 0, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 45, TimeOfDay(12, 15, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 60, TimeOfDay(12, 30, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 75, TimeOfDay(12, 45, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 90, TimeOfDay(12, 0, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 100, TimeOfDay(12, 10, 33));
|
|
|
|
testTOD(TimeOfDay(12, 30, 33), 689, TimeOfDay(12, 59, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 690, TimeOfDay(12, 0, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 691, TimeOfDay(12, 1, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 960, TimeOfDay(12, 30, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 1439, TimeOfDay(12, 29, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 1440, TimeOfDay(12, 30, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 1441, TimeOfDay(12, 31, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 2880, TimeOfDay(12, 30, 33));
|
|
|
|
testTOD(TimeOfDay(12, 30, 33), -1, TimeOfDay(12, 29, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), -2, TimeOfDay(12, 28, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), -3, TimeOfDay(12, 27, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), -4, TimeOfDay(12, 26, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), -5, TimeOfDay(12, 25, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), -10, TimeOfDay(12, 20, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), -15, TimeOfDay(12, 15, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), -29, TimeOfDay(12, 1, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), -30, TimeOfDay(12, 0, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), -45, TimeOfDay(12, 45, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), -60, TimeOfDay(12, 30, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), -75, TimeOfDay(12, 15, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), -90, TimeOfDay(12, 0, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), -100, TimeOfDay(12, 50, 33));
|
|
|
|
testTOD(TimeOfDay(12, 30, 33), -749, TimeOfDay(12, 1, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), -750, TimeOfDay(12, 0, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), -751, TimeOfDay(12, 59, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), -960, TimeOfDay(12, 30, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), -1439, TimeOfDay(12, 31, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), -1440, TimeOfDay(12, 30, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), -1441, TimeOfDay(12, 29, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), -2880, TimeOfDay(12, 30, 33));
|
|
|
|
testTOD(TimeOfDay(12, 0, 33), 1, TimeOfDay(12, 1, 33));
|
|
testTOD(TimeOfDay(12, 0, 33), 0, TimeOfDay(12, 0, 33));
|
|
testTOD(TimeOfDay(12, 0, 33), -1, TimeOfDay(12, 59, 33));
|
|
|
|
testTOD(TimeOfDay(11, 59, 33), 1, TimeOfDay(11, 0, 33));
|
|
testTOD(TimeOfDay(11, 59, 33), 0, TimeOfDay(11, 59, 33));
|
|
testTOD(TimeOfDay(11, 59, 33), -1, TimeOfDay(11, 58, 33));
|
|
|
|
testTOD(TimeOfDay(0, 0, 33), 1, TimeOfDay(0, 1, 33));
|
|
testTOD(TimeOfDay(0, 0, 33), 0, TimeOfDay(0, 0, 33));
|
|
testTOD(TimeOfDay(0, 0, 33), -1, TimeOfDay(0, 59, 33));
|
|
|
|
testTOD(TimeOfDay(23, 59, 33), 1, TimeOfDay(23, 0, 33));
|
|
testTOD(TimeOfDay(23, 59, 33), 0, TimeOfDay(23, 59, 33));
|
|
testTOD(TimeOfDay(23, 59, 33), -1, TimeOfDay(23, 58, 33));
|
|
|
|
const ctod = TimeOfDay(0, 0, 0);
|
|
immutable itod = TimeOfDay(0, 0, 0);
|
|
static assert(!__traits(compiles, ctod.roll!"minutes"(7)));
|
|
static assert(!__traits(compiles, itod.roll!"minutes"(7)));
|
|
|
|
//Verify Examples.
|
|
auto tod1 = TimeOfDay(7, 12, 0);
|
|
tod1.roll!"minutes"(1);
|
|
assert(tod1 == TimeOfDay(7, 13, 0));
|
|
|
|
auto tod2 = TimeOfDay(7, 12, 0);
|
|
tod2.roll!"minutes"(-1);
|
|
assert(tod2 == TimeOfDay(7, 11, 0));
|
|
|
|
auto tod3 = TimeOfDay(23, 59, 0);
|
|
tod3.roll!"minutes"(1);
|
|
assert(tod3 == TimeOfDay(23, 0, 0));
|
|
|
|
auto tod4 = TimeOfDay(0, 0, 0);
|
|
tod4.roll!"minutes"(-1);
|
|
assert(tod4 == TimeOfDay(0, 59, 0));
|
|
|
|
auto tod5 = TimeOfDay(7, 32, 12);
|
|
tod5.roll!"seconds"(1);
|
|
assert(tod5 == TimeOfDay(7, 32, 13));
|
|
|
|
auto tod6 = TimeOfDay(7, 32, 12);
|
|
tod6.roll!"seconds"(-1);
|
|
assert(tod6 == TimeOfDay(7, 32, 11));
|
|
|
|
auto tod7 = TimeOfDay(23, 59, 59);
|
|
tod7.roll!"seconds"(1);
|
|
assert(tod7 == TimeOfDay(23, 59, 0));
|
|
|
|
auto tod8 = TimeOfDay(0, 0, 0);
|
|
tod8.roll!"seconds"(-1);
|
|
assert(tod8 == TimeOfDay(0, 0, 59));
|
|
}
|
|
}
|
|
|
|
//Test roll!"seconds"().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static void testTOD(TimeOfDay orig, int seconds, in TimeOfDay expected, size_t line = __LINE__)
|
|
{
|
|
orig.roll!"seconds"(seconds);
|
|
_assertPred!"=="(orig, expected, "", __FILE__, line);
|
|
}
|
|
|
|
testTOD(TimeOfDay(12, 30, 33), 0, TimeOfDay(12, 30, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 1, TimeOfDay(12, 30, 34));
|
|
testTOD(TimeOfDay(12, 30, 33), 2, TimeOfDay(12, 30, 35));
|
|
testTOD(TimeOfDay(12, 30, 33), 3, TimeOfDay(12, 30, 36));
|
|
testTOD(TimeOfDay(12, 30, 33), 4, TimeOfDay(12, 30, 37));
|
|
testTOD(TimeOfDay(12, 30, 33), 5, TimeOfDay(12, 30, 38));
|
|
testTOD(TimeOfDay(12, 30, 33), 10, TimeOfDay(12, 30, 43));
|
|
testTOD(TimeOfDay(12, 30, 33), 15, TimeOfDay(12, 30, 48));
|
|
testTOD(TimeOfDay(12, 30, 33), 26, TimeOfDay(12, 30, 59));
|
|
testTOD(TimeOfDay(12, 30, 33), 27, TimeOfDay(12, 30, 0));
|
|
testTOD(TimeOfDay(12, 30, 33), 30, TimeOfDay(12, 30, 3));
|
|
testTOD(TimeOfDay(12, 30, 33), 59, TimeOfDay(12, 30, 32));
|
|
testTOD(TimeOfDay(12, 30, 33), 60, TimeOfDay(12, 30, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 61, TimeOfDay(12, 30, 34));
|
|
|
|
testTOD(TimeOfDay(12, 30, 33), 1766, TimeOfDay(12, 30, 59));
|
|
testTOD(TimeOfDay(12, 30, 33), 1767, TimeOfDay(12, 30, 0));
|
|
testTOD(TimeOfDay(12, 30, 33), 1768, TimeOfDay(12, 30, 1));
|
|
testTOD(TimeOfDay(12, 30, 33), 2007, TimeOfDay(12, 30, 0));
|
|
testTOD(TimeOfDay(12, 30, 33), 3599, TimeOfDay(12, 30, 32));
|
|
testTOD(TimeOfDay(12, 30, 33), 3600, TimeOfDay(12, 30, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 3601, TimeOfDay(12, 30, 34));
|
|
testTOD(TimeOfDay(12, 30, 33), 7200, TimeOfDay(12, 30, 33));
|
|
|
|
testTOD(TimeOfDay(12, 30, 33), -1, TimeOfDay(12, 30, 32));
|
|
testTOD(TimeOfDay(12, 30, 33), -2, TimeOfDay(12, 30, 31));
|
|
testTOD(TimeOfDay(12, 30, 33), -3, TimeOfDay(12, 30, 30));
|
|
testTOD(TimeOfDay(12, 30, 33), -4, TimeOfDay(12, 30, 29));
|
|
testTOD(TimeOfDay(12, 30, 33), -5, TimeOfDay(12, 30, 28));
|
|
testTOD(TimeOfDay(12, 30, 33), -10, TimeOfDay(12, 30, 23));
|
|
testTOD(TimeOfDay(12, 30, 33), -15, TimeOfDay(12, 30, 18));
|
|
testTOD(TimeOfDay(12, 30, 33), -33, TimeOfDay(12, 30, 0));
|
|
testTOD(TimeOfDay(12, 30, 33), -34, TimeOfDay(12, 30, 59));
|
|
testTOD(TimeOfDay(12, 30, 33), -35, TimeOfDay(12, 30, 58));
|
|
testTOD(TimeOfDay(12, 30, 33), -59, TimeOfDay(12, 30, 34));
|
|
testTOD(TimeOfDay(12, 30, 33), -60, TimeOfDay(12, 30, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), -61, TimeOfDay(12, 30, 32));
|
|
|
|
testTOD(TimeOfDay(12, 30, 0), 1, TimeOfDay(12, 30, 1));
|
|
testTOD(TimeOfDay(12, 30, 0), 0, TimeOfDay(12, 30, 0));
|
|
testTOD(TimeOfDay(12, 30, 0), -1, TimeOfDay(12, 30, 59));
|
|
|
|
testTOD(TimeOfDay(12, 0, 0), 1, TimeOfDay(12, 0, 1));
|
|
testTOD(TimeOfDay(12, 0, 0), 0, TimeOfDay(12, 0, 0));
|
|
testTOD(TimeOfDay(12, 0, 0), -1, TimeOfDay(12, 0, 59));
|
|
|
|
testTOD(TimeOfDay(0, 0, 0), 1, TimeOfDay(0, 0, 1));
|
|
testTOD(TimeOfDay(0, 0, 0), 0, TimeOfDay(0, 0, 0));
|
|
testTOD(TimeOfDay(0, 0, 0), -1, TimeOfDay(0, 0, 59));
|
|
|
|
testTOD(TimeOfDay(23, 59, 59), 1, TimeOfDay(23, 59, 0));
|
|
testTOD(TimeOfDay(23, 59, 59), 0, TimeOfDay(23, 59, 59));
|
|
testTOD(TimeOfDay(23, 59, 59), -1, TimeOfDay(23, 59, 58));
|
|
|
|
const ctod = TimeOfDay(0, 0, 0);
|
|
immutable itod = TimeOfDay(0, 0, 0);
|
|
static assert(!__traits(compiles, ctod.roll!"seconds"(7)));
|
|
static assert(!__traits(compiles, itod.roll!"seconds"(7)));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Gives the result of adding or subtracting a duration from this
|
|
$(D TimeOfDay).
|
|
|
|
The legal types of arithmetic for $(D TimeOfDay) using this operator are
|
|
|
|
$(BOOKTABLE,
|
|
$(TR $(TD TimeOfDay) $(TD +) $(TD duration) $(TD -->) $(TD TimeOfDay))
|
|
$(TR $(TD TimeOfDay) $(TD -) $(TD duration) $(TD -->) $(TD TimeOfDay))
|
|
)
|
|
|
|
Params:
|
|
duration = The duration to add to or subtract from this
|
|
$(D TimeOfDay).
|
|
+/
|
|
TimeOfDay opBinary(string op, D)(in D duration) const pure nothrow
|
|
if((op == "+" || op == "-") &&
|
|
(is(Unqual!D == Duration) ||
|
|
is(Unqual!D == TickDuration)))
|
|
{
|
|
TimeOfDay retval = this;
|
|
|
|
static if(is(Unqual!D == Duration))
|
|
immutable hnsecs = duration.total!"hnsecs";
|
|
else static if(is(Unqual!D == TickDuration))
|
|
immutable hnsecs = duration.hnsecs;
|
|
|
|
//Ideally, this would just be
|
|
//return retval.addSeconds(convert!("hnsecs", "seconds")(unaryFun!(op ~ "a")(hnsecs)));
|
|
//But there isn't currently a pure version of unaryFun!().
|
|
|
|
static if(op == "+")
|
|
immutable signedHNSecs = hnsecs;
|
|
else static if(op == "-")
|
|
immutable signedHNSecs = -hnsecs;
|
|
else
|
|
static assert(0);
|
|
|
|
return retval.addSeconds(convert!("hnsecs", "seconds")(signedHNSecs));
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto tod = TimeOfDay(12, 30, 33);
|
|
|
|
_assertPred!"=="(tod + dur!"hours"(7), TimeOfDay(19, 30, 33));
|
|
_assertPred!"=="(tod + dur!"hours"(-7), TimeOfDay(5, 30, 33));
|
|
_assertPred!"=="(tod + dur!"minutes"(7), TimeOfDay(12, 37, 33));
|
|
_assertPred!"=="(tod + dur!"minutes"(-7), TimeOfDay(12, 23, 33));
|
|
_assertPred!"=="(tod + dur!"seconds"(7), TimeOfDay(12, 30, 40));
|
|
_assertPred!"=="(tod + dur!"seconds"(-7), TimeOfDay(12, 30, 26));
|
|
|
|
_assertPred!"=="(tod + dur!"msecs"(7000), TimeOfDay(12, 30, 40));
|
|
_assertPred!"=="(tod + dur!"msecs"(-7000), TimeOfDay(12, 30, 26));
|
|
_assertPred!"=="(tod + dur!"usecs"(7_000_000), TimeOfDay(12, 30, 40));
|
|
_assertPred!"=="(tod + dur!"usecs"(-7_000_000), TimeOfDay(12, 30, 26));
|
|
_assertPred!"=="(tod + dur!"hnsecs"(70_000_000), TimeOfDay(12, 30, 40));
|
|
_assertPred!"=="(tod + dur!"hnsecs"(-70_000_000), TimeOfDay(12, 30, 26));
|
|
|
|
//This probably only runs in cases where gettimeofday() is used, but it's
|
|
//hard to do this test correctly with variable ticksPerSec.
|
|
if(TickDuration.ticksPerSec == 1_000_000)
|
|
{
|
|
_assertPred!"=="(tod + TickDuration.from!"usecs"(7_000_000), TimeOfDay(12, 30, 40));
|
|
_assertPred!"=="(tod + TickDuration.from!"usecs"(-7_000_000), TimeOfDay(12, 30, 26));
|
|
}
|
|
|
|
_assertPred!"=="(tod - dur!"hours"(-7), TimeOfDay(19, 30, 33));
|
|
_assertPred!"=="(tod - dur!"hours"(7), TimeOfDay(5, 30, 33));
|
|
_assertPred!"=="(tod - dur!"minutes"(-7), TimeOfDay(12, 37, 33));
|
|
_assertPred!"=="(tod - dur!"minutes"(7), TimeOfDay(12, 23, 33));
|
|
_assertPred!"=="(tod - dur!"seconds"(-7), TimeOfDay(12, 30, 40));
|
|
_assertPred!"=="(tod - dur!"seconds"(7), TimeOfDay(12, 30, 26));
|
|
|
|
_assertPred!"=="(tod - dur!"msecs"(-7000), TimeOfDay(12, 30, 40));
|
|
_assertPred!"=="(tod - dur!"msecs"(7000), TimeOfDay(12, 30, 26));
|
|
_assertPred!"=="(tod - dur!"usecs"(-7_000_000), TimeOfDay(12, 30, 40));
|
|
_assertPred!"=="(tod - dur!"usecs"(7_000_000), TimeOfDay(12, 30, 26));
|
|
_assertPred!"=="(tod - dur!"hnsecs"(-70_000_000), TimeOfDay(12, 30, 40));
|
|
_assertPred!"=="(tod - dur!"hnsecs"(70_000_000), TimeOfDay(12, 30, 26));
|
|
|
|
//This probably only runs in cases where gettimeofday() is used, but it's
|
|
//hard to do this test correctly with variable ticksPerSec.
|
|
if(TickDuration.ticksPerSec == 1_000_000)
|
|
{
|
|
_assertPred!"=="(tod - TickDuration.from!"usecs"(-7_000_000), TimeOfDay(12, 30, 40));
|
|
_assertPred!"=="(tod - TickDuration.from!"usecs"(7_000_000), TimeOfDay(12, 30, 26));
|
|
}
|
|
|
|
auto duration = dur!"hours"(11);
|
|
const ctod = TimeOfDay(12, 33, 30);
|
|
immutable itod = TimeOfDay(12, 33, 30);
|
|
static assert(__traits(compiles, tod + duration));
|
|
static assert(__traits(compiles, ctod + duration));
|
|
static assert(__traits(compiles, itod + duration));
|
|
|
|
static assert(__traits(compiles, tod - duration));
|
|
static assert(__traits(compiles, ctod - duration));
|
|
static assert(__traits(compiles, itod - duration));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Gives the result of adding or subtracting a duration from this
|
|
$(D TimeOfDay), as well as assigning the result to this
|
|
$(D TimeOfDay).
|
|
|
|
The legal types of arithmetic for $(D TimeOfDay) using this operator are
|
|
|
|
$(BOOKTABLE,
|
|
$(TR $(TD TimeOfDay) $(TD +) $(TD duration) $(TD -->) $(TD TimeOfDay))
|
|
$(TR $(TD TimeOfDay) $(TD -) $(TD duration) $(TD -->) $(TD TimeOfDay))
|
|
)
|
|
|
|
Params:
|
|
duration = The duration to add to or subtract from this
|
|
$(D TimeOfDay).
|
|
+/
|
|
/+ref+/ TimeOfDay opOpAssign(string op, D)(in D duration) pure nothrow
|
|
if((op == "+" || op == "-") &&
|
|
(is(Unqual!D == Duration) ||
|
|
is(Unqual!D == TickDuration)))
|
|
{
|
|
static if(is(Unqual!D == Duration))
|
|
immutable hnsecs = duration.total!"hnsecs";
|
|
else static if(is(Unqual!D == TickDuration))
|
|
immutable hnsecs = duration.hnsecs;
|
|
|
|
//Ideally, this would just be
|
|
//return addSeconds(convert!("hnsecs", "seconds")(unaryFun!(op ~ "a")(hnsecs)));
|
|
//But there isn't currently a pure version of unaryFun!().
|
|
|
|
static if(op == "+")
|
|
immutable signedHNSecs = hnsecs;
|
|
else static if(op == "-")
|
|
immutable signedHNSecs = -hnsecs;
|
|
else
|
|
static assert(0);
|
|
|
|
return addSeconds(convert!("hnsecs", "seconds")(signedHNSecs));
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto duration = dur!"hours"(12);
|
|
|
|
_assertPred!"+="(TimeOfDay(12, 30, 33), dur!"hours"(7), TimeOfDay(19, 30, 33));
|
|
_assertPred!"+="(TimeOfDay(12, 30, 33), dur!"hours"(-7), TimeOfDay(5, 30, 33));
|
|
_assertPred!"+="(TimeOfDay(12, 30, 33), dur!"minutes"(7), TimeOfDay(12, 37, 33));
|
|
_assertPred!"+="(TimeOfDay(12, 30, 33), dur!"minutes"(-7), TimeOfDay(12, 23, 33));
|
|
_assertPred!"+="(TimeOfDay(12, 30, 33), dur!"seconds"(7), TimeOfDay(12, 30, 40));
|
|
_assertPred!"+="(TimeOfDay(12, 30, 33), dur!"seconds"(-7), TimeOfDay(12, 30, 26));
|
|
|
|
_assertPred!"+="(TimeOfDay(12, 30, 33), dur!"msecs"(7000), TimeOfDay(12, 30, 40));
|
|
_assertPred!"+="(TimeOfDay(12, 30, 33), dur!"msecs"(-7000), TimeOfDay(12, 30, 26));
|
|
_assertPred!"+="(TimeOfDay(12, 30, 33), dur!"usecs"(7_000_000), TimeOfDay(12, 30, 40));
|
|
_assertPred!"+="(TimeOfDay(12, 30, 33), dur!"usecs"(-7_000_000), TimeOfDay(12, 30, 26));
|
|
_assertPred!"+="(TimeOfDay(12, 30, 33), dur!"hnsecs"(70_000_000), TimeOfDay(12, 30, 40));
|
|
_assertPred!"+="(TimeOfDay(12, 30, 33), dur!"hnsecs"(-70_000_000), TimeOfDay(12, 30, 26));
|
|
|
|
_assertPred!"-="(TimeOfDay(12, 30, 33), dur!"hours"(-7), TimeOfDay(19, 30, 33));
|
|
_assertPred!"-="(TimeOfDay(12, 30, 33), dur!"hours"(7), TimeOfDay(5, 30, 33));
|
|
_assertPred!"-="(TimeOfDay(12, 30, 33), dur!"minutes"(-7), TimeOfDay(12, 37, 33));
|
|
_assertPred!"-="(TimeOfDay(12, 30, 33), dur!"minutes"(7), TimeOfDay(12, 23, 33));
|
|
_assertPred!"-="(TimeOfDay(12, 30, 33), dur!"seconds"(-7), TimeOfDay(12, 30, 40));
|
|
_assertPred!"-="(TimeOfDay(12, 30, 33), dur!"seconds"(7), TimeOfDay(12, 30, 26));
|
|
|
|
_assertPred!"-="(TimeOfDay(12, 30, 33), dur!"msecs"(-7000), TimeOfDay(12, 30, 40));
|
|
_assertPred!"-="(TimeOfDay(12, 30, 33), dur!"msecs"(7000), TimeOfDay(12, 30, 26));
|
|
_assertPred!"-="(TimeOfDay(12, 30, 33), dur!"usecs"(-7_000_000), TimeOfDay(12, 30, 40));
|
|
_assertPred!"-="(TimeOfDay(12, 30, 33), dur!"usecs"(7_000_000), TimeOfDay(12, 30, 26));
|
|
_assertPred!"-="(TimeOfDay(12, 30, 33), dur!"hnsecs"(-70_000_000), TimeOfDay(12, 30, 40));
|
|
_assertPred!"-="(TimeOfDay(12, 30, 33), dur!"hnsecs"(70_000_000), TimeOfDay(12, 30, 26));
|
|
|
|
const ctod = TimeOfDay(12, 33, 30);
|
|
immutable itod = TimeOfDay(12, 33, 30);
|
|
static assert(!__traits(compiles, ctod += duration));
|
|
static assert(!__traits(compiles, itod += duration));
|
|
static assert(!__traits(compiles, ctod -= duration));
|
|
static assert(!__traits(compiles, itod -= duration));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Gives the difference between two $(D TimeOfDay)s.
|
|
|
|
The legal types of arithmetic for $(D TimeOfDay) using this operator are
|
|
|
|
$(BOOKTABLE,
|
|
$(TR $(TD TimeOfDay) $(TD -) $(TD TimeOfDay) $(TD -->) $(TD duration))
|
|
)
|
|
|
|
Params:
|
|
rhs = The $(D TimeOfDay) to subtract from this one.
|
|
+/
|
|
Duration opBinary(string op)(in TimeOfDay rhs) const pure nothrow
|
|
if(op == "-")
|
|
{
|
|
immutable lhsSec = _hour * 3600 + _minute * 60 + _second;
|
|
immutable rhsSec = rhs._hour * 3600 + rhs._minute * 60 + rhs._second;
|
|
|
|
return dur!"seconds"(lhsSec - rhsSec);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto tod = TimeOfDay(12, 30, 33);
|
|
|
|
_assertPred!"=="(TimeOfDay(7, 12, 52) - TimeOfDay(12, 30, 33), dur!"seconds"(-19_061));
|
|
_assertPred!"=="(TimeOfDay(12, 30, 33) - TimeOfDay(7, 12, 52), dur!"seconds"(19_061));
|
|
_assertPred!"=="(TimeOfDay(12, 30, 33) - TimeOfDay(14, 30, 33), dur!"seconds"(-7200));
|
|
_assertPred!"=="(TimeOfDay(14, 30, 33) - TimeOfDay(12, 30, 33), dur!"seconds"(7200));
|
|
_assertPred!"=="(TimeOfDay(12, 30, 33) - TimeOfDay(12, 34, 33), dur!"seconds"(-240));
|
|
_assertPred!"=="(TimeOfDay(12, 34, 33) - TimeOfDay(12, 30, 33), dur!"seconds"(240));
|
|
_assertPred!"=="(TimeOfDay(12, 30, 33) - TimeOfDay(12, 30, 34), dur!"seconds"(-1));
|
|
_assertPred!"=="(TimeOfDay(12, 30, 34) - TimeOfDay(12, 30, 33), dur!"seconds"(1));
|
|
|
|
const ctod = TimeOfDay(12, 30, 33);
|
|
immutable itod = TimeOfDay(12, 30, 33);
|
|
static assert(__traits(compiles, tod - tod));
|
|
static assert(__traits(compiles, ctod - tod));
|
|
static assert(__traits(compiles, itod - tod));
|
|
|
|
static assert(__traits(compiles, tod - ctod));
|
|
static assert(__traits(compiles, ctod - ctod));
|
|
static assert(__traits(compiles, itod - ctod));
|
|
|
|
static assert(__traits(compiles, tod - itod));
|
|
static assert(__traits(compiles, ctod - itod));
|
|
static assert(__traits(compiles, itod - itod));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Converts this $(D TimeOfDay) to a string with the format HHMMSS.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(TimeOfDay(0, 0, 0).toISOString() == "000000");
|
|
assert(TimeOfDay(12, 30, 33).toISOString() == "123033");
|
|
--------------------
|
|
+/
|
|
string toISOString() const nothrow
|
|
{
|
|
try
|
|
return format("%02d%02d%02d", _hour, _minute, _second);
|
|
catch(Exception e)
|
|
assert(0, "format() threw.");
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto tod = TimeOfDay(12, 30, 33);
|
|
const ctod = TimeOfDay(12, 30, 33);
|
|
immutable itod = TimeOfDay(12, 30, 33);
|
|
static assert(__traits(compiles, tod.toISOString()));
|
|
static assert(__traits(compiles, ctod.toISOString()));
|
|
static assert(__traits(compiles, itod.toISOString()));
|
|
|
|
//Verify Examples.
|
|
assert(TimeOfDay(0, 0, 0).toISOString() == "000000");
|
|
assert(TimeOfDay(12, 30, 33).toISOString() == "123033");
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Converts this $(D TimeOfDay) to a string with the format HH:MM:SS.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(TimeOfDay(0, 0, 0).toISOExtString() == "000000");
|
|
assert(TimeOfDay(12, 30, 33).toISOExtString() == "123033");
|
|
--------------------
|
|
+/
|
|
string toISOExtString() const nothrow
|
|
{
|
|
try
|
|
return format("%02d:%02d:%02d", _hour, _minute, _second);
|
|
catch(Exception e)
|
|
assert(0, "format() threw.");
|
|
}
|
|
|
|
/++
|
|
$(RED Scheduled for deprecation in November 2011.
|
|
Please use toISOExtString instead.)
|
|
+/
|
|
alias toISOExtString toISOExtendedString;
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto tod = TimeOfDay(12, 30, 33);
|
|
const ctod = TimeOfDay(12, 30, 33);
|
|
immutable itod = TimeOfDay(12, 30, 33);
|
|
static assert(__traits(compiles, tod.toISOExtString()));
|
|
static assert(__traits(compiles, ctod.toISOExtString()));
|
|
static assert(__traits(compiles, itod.toISOExtString()));
|
|
|
|
//Verify Examples.
|
|
assert(TimeOfDay(0, 0, 0).toISOExtString() == "00:00:00");
|
|
assert(TimeOfDay(12, 30, 33).toISOExtString() == "12:30:33");
|
|
}
|
|
}
|
|
|
|
|
|
/+
|
|
Converts this $(D TimeOfDay) to a string.
|
|
+/
|
|
//Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't
|
|
//have versions of toString() with extra modifiers, so we define one version
|
|
//with modifiers and one without.
|
|
string toString()
|
|
{
|
|
return toISOExtString();
|
|
}
|
|
|
|
|
|
/++
|
|
Converts this TimeOfDay to a string.
|
|
+/
|
|
//Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't
|
|
//have versions of toString() with extra modifiers, so we define one version
|
|
//with modifiers and one without.
|
|
string toString() const nothrow
|
|
{
|
|
return toISOExtString();
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto tod = TimeOfDay(12, 30, 33);
|
|
const ctod = TimeOfDay(12, 30, 33);
|
|
immutable itod = TimeOfDay(12, 30, 33);
|
|
static assert(__traits(compiles, tod.toString()));
|
|
static assert(__traits(compiles, ctod.toString()));
|
|
static assert(__traits(compiles, itod.toString()));
|
|
}
|
|
}
|
|
|
|
//TODO Add a function which returns a string in a user-specified format.
|
|
|
|
|
|
|
|
/++
|
|
Creates a $(D TimeOfDay) from a string with the format HHMMSS.
|
|
Whitespace is stripped from the given string.
|
|
|
|
Params:
|
|
isoString = A string formatted in the ISO format for times.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given string is not in the ISO format
|
|
or if the resulting $(D TimeOfDay) would not be valid.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(TimeOfDay.fromISOString("000000") == TimeOfDay(0, 0, 0));
|
|
assert(TimeOfDay.fromISOString("123033") == TimeOfDay(12, 30, 33));
|
|
assert(TimeOfDay.fromISOString(" 123033 ") == TimeOfDay(12, 30, 33));
|
|
--------------------
|
|
+/
|
|
static TimeOfDay fromISOString(S)(in S isoString)
|
|
if(isSomeString!S)
|
|
{
|
|
auto dstr = to!dstring(strip(isoString));
|
|
|
|
enforce(dstr.length == 6, new DateTimeException(format("Invalid ISO String: %s", isoString)));
|
|
|
|
auto hours = dstr[0 .. 2];
|
|
auto minutes = dstr[2 .. 4];
|
|
auto seconds = dstr[4 .. $];
|
|
|
|
enforce(!canFind!(not!isDigit)(hours), new DateTimeException(format("Invalid ISO String: %s", isoString)));
|
|
enforce(!canFind!(not!isDigit)(minutes), new DateTimeException(format("Invalid ISO String: %s", isoString)));
|
|
enforce(!canFind!(not!isDigit)(seconds), new DateTimeException(format("Invalid ISO String: %s", isoString)));
|
|
|
|
return TimeOfDay(to!int(hours), to!int(minutes), to!int(seconds));
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString(""));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("0"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("00"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("000"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("0000"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("00000"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("13033"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("1277"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("12707"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("12070"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("12303a"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("1230a3"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("123a33"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("12a033"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("1a0033"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("a20033"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("1200330"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("0120033"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("-120033"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("+120033"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("120033am"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("120033pm"));
|
|
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("0::"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString(":0:"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("::0"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("0:0:0"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("0:0:00"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("0:00:0"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("00:0:0"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("00:00:0"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("00:0:00"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("13:0:33"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("12:7:7"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("12:7:07"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("12:07:0"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("12:30:3a"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("12:30:a3"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("12:3a:33"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("12:a0:33"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("1a:00:33"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("a2:00:33"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("12:003:30"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("120:03:30"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("012:00:33"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("01:200:33"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("-12:00:33"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("+12:00:33"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("12:00:33am"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("12:00:33pm"));
|
|
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOString("12:00:33"));
|
|
|
|
_assertPred!"=="(TimeOfDay.fromISOString("011217"), TimeOfDay(1, 12, 17));
|
|
_assertPred!"=="(TimeOfDay.fromISOString("001412"), TimeOfDay(0, 14, 12));
|
|
_assertPred!"=="(TimeOfDay.fromISOString("000007"), TimeOfDay(0, 0, 7));
|
|
_assertPred!"=="(TimeOfDay.fromISOString("011217 "), TimeOfDay(1, 12, 17));
|
|
_assertPred!"=="(TimeOfDay.fromISOString(" 011217"), TimeOfDay(1, 12, 17));
|
|
_assertPred!"=="(TimeOfDay.fromISOString(" 011217 "), TimeOfDay(1, 12, 17));
|
|
|
|
//Verify Examples.
|
|
assert(TimeOfDay.fromISOString("000000") == TimeOfDay(0, 0, 0));
|
|
assert(TimeOfDay.fromISOString("123033") == TimeOfDay(12, 30, 33));
|
|
assert(TimeOfDay.fromISOString(" 123033 ") == TimeOfDay(12, 30, 33));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Creates a $(D TimeOfDay) from a string with the format HH:MM:SS.
|
|
Whitespace is stripped from the given string.
|
|
|
|
Params:
|
|
isoString = A string formatted in the ISO Extended format for times.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given string is not in the ISO
|
|
Extended format or if the resulting $(D TimeOfDay) would not be
|
|
valid.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(TimeOfDay.fromISOExtString("00:00:00") == TimeOfDay(0, 0, 0));
|
|
assert(TimeOfDay.fromISOExtString("12:30:33") == TimeOfDay(12, 30, 33));
|
|
assert(TimeOfDay.fromISOExtString(" 12:30:33 ") == TimeOfDay(12, 30, 33));
|
|
--------------------
|
|
+/
|
|
static TimeOfDay fromISOExtString(S)(in S isoExtString)
|
|
if(isSomeString!S)
|
|
{
|
|
auto dstr = to!dstring(strip(isoExtString));
|
|
|
|
enforce(dstr.length == 8, new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
|
|
|
|
auto hours = dstr[0 .. 2];
|
|
auto minutes = dstr[3 .. 5];
|
|
auto seconds = dstr[6 .. $];
|
|
|
|
enforce(dstr[2] == ':', new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
|
|
enforce(dstr[5] == ':', new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
|
|
enforce(!canFind!(not!isDigit)(hours),
|
|
new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
|
|
enforce(!canFind!(not!isDigit)(minutes),
|
|
new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
|
|
enforce(!canFind!(not!isDigit)(seconds),
|
|
new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
|
|
|
|
return TimeOfDay(to!int(hours), to!int(minutes), to!int(seconds));
|
|
}
|
|
|
|
/++
|
|
$(RED Scheduled for deprecation in November 2011.
|
|
Please use fromISOExtString instead.)
|
|
+/
|
|
static TimeOfDay fromISOExtendedString(S)(in S isoExtString)
|
|
if(isSomeString!(S))
|
|
{
|
|
pragma(msg, softDeprec!("2.053", "November 2011", "fromISOExtendedString", "fromISOExtString"));
|
|
|
|
return fromISOExtString!string(isoExtString);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString(""));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("0"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("00"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("000"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("0000"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("00000"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("13033"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("1277"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12707"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12070"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12303a"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("1230a3"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("123a33"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12a033"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("1a0033"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("a20033"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("1200330"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("0120033"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("-120033"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("+120033"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("120033am"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("120033pm"));
|
|
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("0::"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString(":0:"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("::0"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("0:0:0"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("0:0:00"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("0:00:0"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("00:0:0"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("00:00:0"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("00:0:00"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("13:0:33"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12:7:7"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12:7:07"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12:07:0"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12:30:3a"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12:30:a3"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12:3a:33"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12:a0:33"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("1a:00:33"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("a2:00:33"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12:003:30"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("120:03:30"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("012:00:33"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("01:200:33"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("-12:00:33"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("+12:00:33"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12:00:33am"));
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12:00:33pm"));
|
|
|
|
assertThrown!DateTimeException(TimeOfDay.fromISOExtString("120033"));
|
|
|
|
_assertPred!"=="(TimeOfDay.fromISOExtString("01:12:17"), TimeOfDay(1, 12, 17));
|
|
_assertPred!"=="(TimeOfDay.fromISOExtString("00:14:12"), TimeOfDay(0, 14, 12));
|
|
_assertPred!"=="(TimeOfDay.fromISOExtString("00:00:07"), TimeOfDay(0, 0, 7));
|
|
_assertPred!"=="(TimeOfDay.fromISOExtString("01:12:17 "), TimeOfDay(1, 12, 17));
|
|
_assertPred!"=="(TimeOfDay.fromISOExtString(" 01:12:17"), TimeOfDay(1, 12, 17));
|
|
_assertPred!"=="(TimeOfDay.fromISOExtString(" 01:12:17 "), TimeOfDay(1, 12, 17));
|
|
|
|
//Verify Examples.
|
|
assert(TimeOfDay.fromISOExtString("00:00:00") == TimeOfDay(0, 0, 0));
|
|
assert(TimeOfDay.fromISOExtString("12:30:33") == TimeOfDay(12, 30, 33));
|
|
assert(TimeOfDay.fromISOExtString(" 12:30:33 ") == TimeOfDay(12, 30, 33));
|
|
}
|
|
}
|
|
|
|
|
|
//TODO Add function which takes a user-specified time format and produces a TimeOfDay
|
|
|
|
//TODO Add function which takes pretty much any time-string and produces a TimeOfDay
|
|
// Obviously, it will be less efficient, and it probably won't manage _every_
|
|
// possible date format, but a smart conversion function would be nice.
|
|
|
|
|
|
/++
|
|
Returns midnight.
|
|
+/
|
|
@property static TimeOfDay min() pure nothrow
|
|
{
|
|
return TimeOfDay.init;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assert(TimeOfDay.min.hour == 0);
|
|
assert(TimeOfDay.min.minute == 0);
|
|
assert(TimeOfDay.min.second == 0);
|
|
assert(TimeOfDay.min < TimeOfDay.max);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns one second short of midnight.
|
|
+/
|
|
@property static TimeOfDay max() pure nothrow
|
|
{
|
|
auto tod = TimeOfDay.init;
|
|
tod._hour = maxHour;
|
|
tod._minute = maxMinute;
|
|
tod._second = maxSecond;
|
|
|
|
return tod;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assert(TimeOfDay.max.hour == 23);
|
|
assert(TimeOfDay.max.minute == 59);
|
|
assert(TimeOfDay.max.second == 59);
|
|
assert(TimeOfDay.max > TimeOfDay.min);
|
|
}
|
|
}
|
|
|
|
|
|
private:
|
|
|
|
/+
|
|
Add seconds to the time of day. Negative values will subtract. If the
|
|
number of seconds overflows (or underflows), then the seconds will wrap,
|
|
increasing (or decreasing) the number of minutes accordingly. If the
|
|
number of minutes overflows (or underflows), then the minutes will wrap.
|
|
If the number of minutes overflows(or underflows), then the hour will
|
|
wrap. (e.g. adding 90 seconds to 23:59:00 would result in 00:00:30).
|
|
|
|
Params:
|
|
seconds = The number of seconds to add to this TimeOfDay.
|
|
+/
|
|
ref TimeOfDay addSeconds(long seconds) pure nothrow
|
|
{
|
|
long hnsecs = convert!("seconds", "hnsecs")(seconds);
|
|
hnsecs += convert!("hours", "hnsecs")(_hour);
|
|
hnsecs += convert!("minutes", "hnsecs")(_minute);
|
|
hnsecs += convert!("seconds", "hnsecs")(_second);
|
|
|
|
hnsecs %= convert!("days", "hnsecs")(1);
|
|
|
|
if(hnsecs < 0)
|
|
hnsecs += convert!("days", "hnsecs")(1);
|
|
|
|
immutable newHours = splitUnitsFromHNSecs!"hours"(hnsecs);
|
|
immutable newMinutes = splitUnitsFromHNSecs!"minutes"(hnsecs);
|
|
immutable newSeconds = splitUnitsFromHNSecs!"seconds"(hnsecs);
|
|
|
|
_hour = cast(ubyte)newHours;
|
|
_minute = cast(ubyte)newMinutes;
|
|
_second = cast(ubyte)newSeconds;
|
|
|
|
return this;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static void testTOD(TimeOfDay orig, int seconds, in TimeOfDay expected, size_t line = __LINE__)
|
|
{
|
|
orig.addSeconds(seconds);
|
|
_assertPred!"=="(orig, expected, "", __FILE__, line);
|
|
}
|
|
|
|
testTOD(TimeOfDay(12, 30, 33), 0, TimeOfDay(12, 30, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 1, TimeOfDay(12, 30, 34));
|
|
testTOD(TimeOfDay(12, 30, 33), 2, TimeOfDay(12, 30, 35));
|
|
testTOD(TimeOfDay(12, 30, 33), 3, TimeOfDay(12, 30, 36));
|
|
testTOD(TimeOfDay(12, 30, 33), 4, TimeOfDay(12, 30, 37));
|
|
testTOD(TimeOfDay(12, 30, 33), 5, TimeOfDay(12, 30, 38));
|
|
testTOD(TimeOfDay(12, 30, 33), 10, TimeOfDay(12, 30, 43));
|
|
testTOD(TimeOfDay(12, 30, 33), 15, TimeOfDay(12, 30, 48));
|
|
testTOD(TimeOfDay(12, 30, 33), 26, TimeOfDay(12, 30, 59));
|
|
testTOD(TimeOfDay(12, 30, 33), 27, TimeOfDay(12, 31, 0));
|
|
testTOD(TimeOfDay(12, 30, 33), 30, TimeOfDay(12, 31, 3));
|
|
testTOD(TimeOfDay(12, 30, 33), 59, TimeOfDay(12, 31, 32));
|
|
testTOD(TimeOfDay(12, 30, 33), 60, TimeOfDay(12, 31, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 61, TimeOfDay(12, 31, 34));
|
|
|
|
testTOD(TimeOfDay(12, 30, 33), 1766, TimeOfDay(12, 59, 59));
|
|
testTOD(TimeOfDay(12, 30, 33), 1767, TimeOfDay(13, 0, 0));
|
|
testTOD(TimeOfDay(12, 30, 33), 1768, TimeOfDay(13, 0, 1));
|
|
testTOD(TimeOfDay(12, 30, 33), 2007, TimeOfDay(13, 4, 0));
|
|
testTOD(TimeOfDay(12, 30, 33), 3599, TimeOfDay(13, 30, 32));
|
|
testTOD(TimeOfDay(12, 30, 33), 3600, TimeOfDay(13, 30, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), 3601, TimeOfDay(13, 30, 34));
|
|
testTOD(TimeOfDay(12, 30, 33), 7200, TimeOfDay(14, 30, 33));
|
|
|
|
testTOD(TimeOfDay(12, 30, 33), -1, TimeOfDay(12, 30, 32));
|
|
testTOD(TimeOfDay(12, 30, 33), -2, TimeOfDay(12, 30, 31));
|
|
testTOD(TimeOfDay(12, 30, 33), -3, TimeOfDay(12, 30, 30));
|
|
testTOD(TimeOfDay(12, 30, 33), -4, TimeOfDay(12, 30, 29));
|
|
testTOD(TimeOfDay(12, 30, 33), -5, TimeOfDay(12, 30, 28));
|
|
testTOD(TimeOfDay(12, 30, 33), -10, TimeOfDay(12, 30, 23));
|
|
testTOD(TimeOfDay(12, 30, 33), -15, TimeOfDay(12, 30, 18));
|
|
testTOD(TimeOfDay(12, 30, 33), -33, TimeOfDay(12, 30, 0));
|
|
testTOD(TimeOfDay(12, 30, 33), -34, TimeOfDay(12, 29, 59));
|
|
testTOD(TimeOfDay(12, 30, 33), -35, TimeOfDay(12, 29, 58));
|
|
testTOD(TimeOfDay(12, 30, 33), -59, TimeOfDay(12, 29, 34));
|
|
testTOD(TimeOfDay(12, 30, 33), -60, TimeOfDay(12, 29, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), -61, TimeOfDay(12, 29, 32));
|
|
|
|
testTOD(TimeOfDay(12, 30, 33), -1833, TimeOfDay(12, 0, 0));
|
|
testTOD(TimeOfDay(12, 30, 33), -1834, TimeOfDay(11, 59, 59));
|
|
testTOD(TimeOfDay(12, 30, 33), -3600, TimeOfDay(11, 30, 33));
|
|
testTOD(TimeOfDay(12, 30, 33), -3601, TimeOfDay(11, 30, 32));
|
|
testTOD(TimeOfDay(12, 30, 33), -5134, TimeOfDay(11, 4, 59));
|
|
testTOD(TimeOfDay(12, 30, 33), -7200, TimeOfDay(10, 30, 33));
|
|
|
|
testTOD(TimeOfDay(12, 30, 0), 1, TimeOfDay(12, 30, 1));
|
|
testTOD(TimeOfDay(12, 30, 0), 0, TimeOfDay(12, 30, 0));
|
|
testTOD(TimeOfDay(12, 30, 0), -1, TimeOfDay(12, 29, 59));
|
|
|
|
testTOD(TimeOfDay(12, 0, 0), 1, TimeOfDay(12, 0, 1));
|
|
testTOD(TimeOfDay(12, 0, 0), 0, TimeOfDay(12, 0, 0));
|
|
testTOD(TimeOfDay(12, 0, 0), -1, TimeOfDay(11, 59, 59));
|
|
|
|
testTOD(TimeOfDay(0, 0, 0), 1, TimeOfDay(0, 0, 1));
|
|
testTOD(TimeOfDay(0, 0, 0), 0, TimeOfDay(0, 0, 0));
|
|
testTOD(TimeOfDay(0, 0, 0), -1, TimeOfDay(23, 59, 59));
|
|
|
|
testTOD(TimeOfDay(23, 59, 59), 1, TimeOfDay(0, 0, 0));
|
|
testTOD(TimeOfDay(23, 59, 59), 0, TimeOfDay(23, 59, 59));
|
|
testTOD(TimeOfDay(23, 59, 59), -1, TimeOfDay(23, 59, 58));
|
|
|
|
const ctod = TimeOfDay(0, 0, 0);
|
|
immutable itod = TimeOfDay(0, 0, 0);
|
|
static assert(!__traits(compiles, ctod.addSeconds(7)));
|
|
static assert(!__traits(compiles, itod.addSeconds(7)));
|
|
}
|
|
}
|
|
|
|
|
|
/+
|
|
Whether the given values form a valid $(D TimeOfDay).
|
|
+/
|
|
static bool _valid(int hour, int minute, int second) pure nothrow
|
|
{
|
|
return valid!"hours"(hour) && valid!"minutes"(minute) && valid!"seconds"(second);
|
|
}
|
|
|
|
|
|
pure invariant()
|
|
{
|
|
assert(_valid(_hour, _minute, _second),
|
|
"Invariant Failure: hour [" ~
|
|
numToString(_hour) ~
|
|
"] minute [" ~
|
|
numToString(_minute) ~
|
|
"] second [" ~
|
|
numToString(_second) ~
|
|
"]");
|
|
}
|
|
|
|
ubyte _hour;
|
|
ubyte _minute;
|
|
ubyte _second;
|
|
|
|
enum ubyte maxHour = 24 - 1;
|
|
enum ubyte maxMinute = 60 - 1;
|
|
enum ubyte maxSecond = 60 - 1;
|
|
}
|
|
|
|
|
|
/++
|
|
Combines the $(D Date) and $(D TimeOfDay) structs to give you an object
|
|
which holds both the date and the time. It is optimized for calendar-based
|
|
operations and has no concept of time zone. If you want an object which is
|
|
optimized for time operations based on the system time, then use
|
|
$(D SysTime). $(D SysTime) has a concept of time zone and has much higher
|
|
precision (hnsecs). $(D DateTime) is intended primarily for calendar-based
|
|
uses rather than precise time operations.
|
|
+/
|
|
struct DateTime
|
|
{
|
|
public:
|
|
|
|
/++
|
|
Params:
|
|
date = The date portion of $(D DateTime).
|
|
tod = The time portion of $(D DateTime).
|
|
+/
|
|
this(in Date date, in TimeOfDay tod = TimeOfDay.init) pure nothrow
|
|
{
|
|
_date = date;
|
|
_tod = tod;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
{
|
|
auto dt = DateTime.init;
|
|
_assertPred!"=="(dt._date, Date.init);
|
|
_assertPred!"=="(dt._tod, TimeOfDay.init);
|
|
}
|
|
|
|
{
|
|
auto dt = DateTime(Date(1999, 7 ,6));
|
|
_assertPred!"=="(dt._date, Date(1999, 7, 6));
|
|
_assertPred!"=="(dt._tod, TimeOfDay.init);
|
|
}
|
|
|
|
{
|
|
auto dt = DateTime(Date(1999, 7 ,6), TimeOfDay(12, 30, 33));
|
|
_assertPred!"=="(dt._date, Date(1999, 7, 6));
|
|
_assertPred!"=="(dt._tod, TimeOfDay(12, 30, 33));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Params:
|
|
year = The year portion of the date.
|
|
month = The month portion of the date.
|
|
day = The day portion of the date.
|
|
hour = The hour portion of the time;
|
|
minute = The minute portion of the time;
|
|
second = The second portion of the time;
|
|
+/
|
|
this(int year, int month, int day,
|
|
int hour = 0, int minute = 0, int second = 0) pure
|
|
{
|
|
_date = Date(year, month, day);
|
|
_tod = TimeOfDay(hour, minute, second);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
{
|
|
auto dt = DateTime(1999, 7 ,6);
|
|
_assertPred!"=="(dt._date, Date(1999, 7, 6));
|
|
_assertPred!"=="(dt._tod, TimeOfDay.init);
|
|
}
|
|
|
|
{
|
|
auto dt = DateTime(1999, 7 ,6, 12, 30, 33);
|
|
_assertPred!"=="(dt._date, Date(1999, 7, 6));
|
|
_assertPred!"=="(dt._tod, TimeOfDay(12, 30, 33));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Compares this $(D DateTime) with the given $(D DateTime.).
|
|
|
|
Returns:
|
|
$(BOOKTABLE,
|
|
$(TR $(TD this < rhs) $(TD < 0))
|
|
$(TR $(TD this == rhs) $(TD 0))
|
|
$(TR $(TD this > rhs) $(TD > 0))
|
|
)
|
|
+/
|
|
int opCmp(in DateTime rhs) const pure nothrow
|
|
{
|
|
immutable dateResult = _date.opCmp(rhs._date);
|
|
|
|
if(dateResult != 0)
|
|
return dateResult;
|
|
|
|
return _tod.opCmp(rhs._tod);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
_assertPred!("opCmp", "==")(DateTime(Date.init, TimeOfDay.init), DateTime.init);
|
|
|
|
_assertPred!("opCmp", "==")(DateTime(Date(1999, 1, 1)), DateTime(Date(1999, 1, 1)));
|
|
_assertPred!("opCmp", "==")(DateTime(Date(1, 7, 1)), DateTime(Date(1, 7, 1)));
|
|
_assertPred!("opCmp", "==")(DateTime(Date(1, 1, 6)), DateTime(Date(1, 1, 6)));
|
|
|
|
_assertPred!("opCmp", "==")(DateTime(Date(1999, 7, 1)), DateTime(Date(1999, 7, 1)));
|
|
_assertPred!("opCmp", "==")(DateTime(Date(1999, 7, 6)), DateTime(Date(1999, 7, 6)));
|
|
|
|
_assertPred!("opCmp", "==")(DateTime(Date(1, 7, 6)), DateTime(Date(1, 7, 6)));
|
|
|
|
_assertPred!("opCmp", "<")(DateTime(Date(1999, 7, 6)), DateTime(Date(2000, 7, 6)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(2000, 7, 6)), DateTime(Date(1999, 7, 6)));
|
|
_assertPred!("opCmp", "<")(DateTime(Date(1999, 7, 6)), DateTime(Date(1999, 8, 6)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(1999, 8, 6)), DateTime(Date(1999, 7, 6)));
|
|
_assertPred!("opCmp", "<")(DateTime(Date(1999, 7, 6)), DateTime(Date(1999, 7, 7)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(1999, 7, 7)), DateTime(Date(1999, 7, 6)));
|
|
|
|
_assertPred!("opCmp", "<")(DateTime(Date(1999, 8, 7)), DateTime(Date(2000, 7, 6)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(2000, 8, 6)), DateTime(Date(1999, 7, 7)));
|
|
_assertPred!("opCmp", "<")(DateTime(Date(1999, 7, 7)), DateTime(Date(2000, 7, 6)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(2000, 7, 6)), DateTime(Date(1999, 7, 7)));
|
|
_assertPred!("opCmp", "<")(DateTime(Date(1999, 7, 7)), DateTime(Date(1999, 8, 6)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(1999, 8, 6)), DateTime(Date(1999, 7, 7)));
|
|
|
|
|
|
_assertPred!("opCmp", "==")(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0)));
|
|
_assertPred!("opCmp", "==")(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 0)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 0)));
|
|
_assertPred!("opCmp", "==")(DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 0)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 0)));
|
|
_assertPred!("opCmp", "==")(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33)));
|
|
|
|
_assertPred!("opCmp", "==")(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)));
|
|
_assertPred!("opCmp", "==")(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
|
|
_assertPred!("opCmp", "==")(DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)));
|
|
_assertPred!("opCmp", "==")(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33)));
|
|
|
|
_assertPred!("opCmp", "<")(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", "<")(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", "<")(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
|
|
_assertPred!("opCmp", ">")(DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)));
|
|
_assertPred!("opCmp", "<")(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)));
|
|
_assertPred!("opCmp", "<")(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)));
|
|
|
|
_assertPred!("opCmp", ">")(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)));
|
|
_assertPred!("opCmp", "<")(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)));
|
|
|
|
_assertPred!("opCmp", "<")(DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)),
|
|
DateTime(Date(2000, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(2000, 7, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)));
|
|
_assertPred!("opCmp", "<")(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)),
|
|
DateTime(Date(2000, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(2000, 7, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)));
|
|
_assertPred!("opCmp", "<")(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)),
|
|
DateTime(Date(2000, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(2000, 7, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)));
|
|
|
|
_assertPred!("opCmp", "<")(DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)),
|
|
DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)));
|
|
_assertPred!("opCmp", "<")(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)),
|
|
DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)));
|
|
_assertPred!("opCmp", "<")(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)),
|
|
DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)));
|
|
|
|
_assertPred!("opCmp", "<")(DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)),
|
|
DateTime(Date(1999, 7, 7), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(1999, 7, 7), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)));
|
|
_assertPred!("opCmp", "<")(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)),
|
|
DateTime(Date(1999, 7, 7), TimeOfDay(12, 31, 33)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(1999, 7, 7), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", "<")(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)),
|
|
DateTime(Date(1999, 7, 7), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(1999, 7, 7), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)));
|
|
|
|
//Test B.C.
|
|
_assertPred!("opCmp", "==")(DateTime(Date(-1, 1, 1), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(-1, 1, 1), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", "==")(DateTime(Date(-1, 7, 1), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(-1, 7, 1), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", "==")(DateTime(Date(-1, 1, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(-1, 1, 6), TimeOfDay(12, 30, 33)));
|
|
|
|
_assertPred!("opCmp", "==")(DateTime(Date(-1999, 7, 1), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(-1999, 7, 1), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", "==")(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
|
|
_assertPred!("opCmp", "==")(DateTime(Date(-1, 7, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(-1, 7, 6), TimeOfDay(12, 30, 33)));
|
|
|
|
_assertPred!("opCmp", "<")(DateTime(Date(-2000, 7, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(-2000, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", "<")(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", "<")(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
|
|
_assertPred!("opCmp", "<")(DateTime(Date(-2000, 8, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(-1999, 8, 7), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(-2000, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", "<")(DateTime(Date(-2000, 7, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(-2000, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", "<")(DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33)));
|
|
|
|
//Test Both
|
|
_assertPred!("opCmp", "<")(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
|
|
_assertPred!("opCmp", "<")(DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33)));
|
|
|
|
_assertPred!("opCmp", "<")(DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33)));
|
|
|
|
_assertPred!("opCmp", "<")(DateTime(Date(-1999, 8, 7), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(-1999, 8, 7), TimeOfDay(12, 30, 33)));
|
|
|
|
_assertPred!("opCmp", "<")(DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(1999, 6, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!("opCmp", ">")(DateTime(Date(1999, 6, 8), TimeOfDay(12, 30, 33)),
|
|
DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
|
|
auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 33, 30));
|
|
const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 33, 30));
|
|
immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 33, 30));
|
|
static assert(__traits(compiles, dt.opCmp(dt)));
|
|
static assert(__traits(compiles, dt.opCmp(cdt)));
|
|
static assert(__traits(compiles, dt.opCmp(idt)));
|
|
static assert(__traits(compiles, cdt.opCmp(dt)));
|
|
static assert(__traits(compiles, cdt.opCmp(cdt)));
|
|
static assert(__traits(compiles, cdt.opCmp(idt)));
|
|
static assert(__traits(compiles, idt.opCmp(dt)));
|
|
static assert(__traits(compiles, idt.opCmp(cdt)));
|
|
static assert(__traits(compiles, idt.opCmp(idt)));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
The date portion of $(D DateTime).
|
|
+/
|
|
@property Date date() const pure nothrow
|
|
{
|
|
return _date;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
{
|
|
auto dt = DateTime.init;
|
|
_assertPred!"=="(dt.date, Date.init);
|
|
}
|
|
|
|
{
|
|
auto dt = DateTime(Date(1999, 7, 6));
|
|
_assertPred!"=="(dt.date, Date(1999, 7, 6));
|
|
}
|
|
|
|
const cdt = DateTime(1999, 7, 6);
|
|
immutable idt = DateTime(1999, 7, 6);
|
|
static assert(__traits(compiles, cdt.date == Date(2010, 1, 1)));
|
|
static assert(__traits(compiles, idt.date == Date(2010, 1, 1)));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
The date portion of $(D DateTime).
|
|
|
|
Params:
|
|
date = The Date to set this $(D DateTime)'s date portion to.
|
|
+/
|
|
@property void date(in Date date) pure nothrow
|
|
{
|
|
_date = date;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto dt = DateTime.init;
|
|
dt.date = Date(1999, 7, 6);
|
|
_assertPred!"=="(dt._date, Date(1999, 7, 6));
|
|
_assertPred!"=="(dt._tod, TimeOfDay.init);
|
|
|
|
const cdt = DateTime(1999, 7, 6);
|
|
immutable idt = DateTime(1999, 7, 6);
|
|
static assert(!__traits(compiles, cdt.date = Date(2010, 1, 1)));
|
|
static assert(!__traits(compiles, idt.date = Date(2010, 1, 1)));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
The time portion of $(D DateTime).
|
|
+/
|
|
@property TimeOfDay timeOfDay() const pure nothrow
|
|
{
|
|
return _tod;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
{
|
|
auto dt = DateTime.init;
|
|
_assertPred!"=="(dt.timeOfDay, TimeOfDay.init);
|
|
}
|
|
|
|
{
|
|
auto dt = DateTime(Date.init, TimeOfDay(12, 30, 33));
|
|
_assertPred!"=="(dt.timeOfDay, TimeOfDay(12, 30, 33));
|
|
}
|
|
|
|
const cdt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
static assert(__traits(compiles, cdt.timeOfDay == TimeOfDay(12, 30, 33)));
|
|
static assert(__traits(compiles, idt.timeOfDay == TimeOfDay(12, 30, 33)));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
The time portion of $(D DateTime).
|
|
|
|
Params:
|
|
tod = The $(D TimeOfDay) to set this $(D DateTime)'s time portion
|
|
to.
|
|
+/
|
|
@property void timeOfDay(in TimeOfDay tod) pure nothrow
|
|
{
|
|
_tod = tod;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto dt = DateTime.init;
|
|
dt.timeOfDay = TimeOfDay(12, 30, 33);
|
|
_assertPred!"=="(dt._date, date.init);
|
|
_assertPred!"=="(dt._tod, TimeOfDay(12, 30, 33));
|
|
|
|
const cdt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
static assert(!__traits(compiles, cdt.timeOfDay = TimeOfDay(12, 30, 33)));
|
|
static assert(!__traits(compiles, idt.timeOfDay = TimeOfDay(12, 30, 33)));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive
|
|
are B.C.
|
|
+/
|
|
@property short year() const pure nothrow
|
|
{
|
|
return _date.year;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(Date.init.year, 1);
|
|
_assertPred!"=="(Date(1999, 7, 6).year, 1999);
|
|
_assertPred!"=="(Date(-1999, 7, 6).year, -1999);
|
|
|
|
const cdt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
static assert(__traits(compiles, idt.year));
|
|
static assert(__traits(compiles, idt.year));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive
|
|
are B.C.
|
|
|
|
Params:
|
|
year = The year to set this $(D DateTime)'s year to.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the new year is not a leap year and if the
|
|
resulting date would be on February 29th.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(DateTime(Date(1999, 7, 6), TimeOfDay(9, 7, 5)).year == 1999);
|
|
assert(DateTime(Date(2010, 10, 4), TimeOfDay(0, 0, 30)).year == 2010);
|
|
assert(DateTime(Date(-7, 4, 5), TimeOfDay(7, 45, 2)).year == -7);
|
|
--------------------
|
|
+/
|
|
@property void year(int year) pure
|
|
{
|
|
_date.year = year;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static void testDT(DateTime dt, int year, in DateTime expected, size_t line = __LINE__)
|
|
{
|
|
dt.year = year;
|
|
_assertPred!"=="(dt, expected, "", __FILE__, line);
|
|
}
|
|
|
|
testDT(DateTime(Date(1, 1, 1), TimeOfDay(12, 30, 33)), 1999, DateTime(Date(1999, 1, 1), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(1, 1, 1), TimeOfDay(12, 30, 33)), 0, DateTime(Date(0, 1, 1), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(1, 1, 1), TimeOfDay(12, 30, 33)), -1999, DateTime(Date(-1999, 1, 1), TimeOfDay(12, 30, 33)));
|
|
|
|
const cdt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
static assert(!__traits(compiles, cdt.year = 7));
|
|
static assert(!__traits(compiles, idt.year = 7));
|
|
|
|
//Verify Examples.
|
|
assert(DateTime(Date(1999, 7, 6), TimeOfDay(9, 7, 5)).year == 1999);
|
|
assert(DateTime(Date(2010, 10, 4), TimeOfDay(0, 0, 30)).year == 2010);
|
|
assert(DateTime(Date(-7, 4, 5), TimeOfDay(7, 45, 2)).year == -7);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if $(D isAD) is true.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(DateTime(Date(0, 1, 1), TimeOfDay(12, 30, 33)).yearBC == 1);
|
|
assert(DateTime(Date(-1, 1, 1), TimeOfDay(10, 7, 2)).yearBC == 2);
|
|
assert(DateTime(Date(-100, 1, 1), TimeOfDay(4, 59, 0)).yearBC == 101);
|
|
--------------------
|
|
+/
|
|
@property short yearBC() const pure
|
|
{
|
|
return _date.yearBC;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assertThrown!DateTimeException((in DateTime dt){dt.yearBC;}(DateTime(Date(1, 1, 1))));
|
|
|
|
auto dt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
const cdt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
static assert(__traits(compiles, dt.yearBC = 12));
|
|
static assert(!__traits(compiles, cdt.yearBC = 12));
|
|
static assert(!__traits(compiles, idt.yearBC = 12));
|
|
|
|
//Verify Examples.
|
|
assert(DateTime(Date(0, 1, 1), TimeOfDay(12, 30, 33)).yearBC == 1);
|
|
assert(DateTime(Date(-1, 1, 1), TimeOfDay(10, 7, 2)).yearBC == 2);
|
|
assert(DateTime(Date(-100, 1, 1), TimeOfDay(4, 59, 0)).yearBC == 101);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C.
|
|
|
|
Params:
|
|
year = The year B.C. to set this $(D DateTime)'s year to.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if a non-positive value is given.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto dt = DateTime(Date(2010, 1, 1), TimeOfDay(7, 30, 0));
|
|
dt.yearBC = 1;
|
|
assert(dt == DateTime(Date(0, 1, 1), TimeOfDay(7, 30, 0)));
|
|
|
|
dt.yearBC = 10;
|
|
assert(dt == DateTime(Date(-9, 1, 1), TimeOfDay(7, 30, 0)));
|
|
--------------------
|
|
+/
|
|
@property void yearBC(int year) pure
|
|
{
|
|
_date.yearBC = year;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assertThrown!DateTimeException((DateTime dt){dt.yearBC = -1;}(DateTime(Date(1, 1, 1))));
|
|
|
|
{
|
|
auto dt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
const cdt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
static assert(__traits(compiles, dt.yearBC = 12));
|
|
static assert(!__traits(compiles, cdt.yearBC = 12));
|
|
static assert(!__traits(compiles, idt.yearBC = 12));
|
|
}
|
|
|
|
//Verify Examples.
|
|
{
|
|
auto dt = DateTime(Date(2010, 1, 1), TimeOfDay(7, 30, 0));
|
|
dt.yearBC = 1;
|
|
assert(dt == DateTime(Date(0, 1, 1), TimeOfDay(7, 30, 0)));
|
|
|
|
dt.yearBC = 10;
|
|
assert(dt == DateTime(Date(-9, 1, 1), TimeOfDay(7, 30, 0)));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Month of a Gregorian Year.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(DateTime(Date(1999, 7, 6), TimeOfDay(9, 7, 5)).month == 7);
|
|
assert(DateTime(Date(2010, 10, 4), TimeOfDay(0, 0, 30)).month == 10);
|
|
assert(DateTime(Date(-7, 4, 5), TimeOfDay(7, 45, 2)).month == 4);
|
|
--------------------
|
|
+/
|
|
@property Month month() const pure nothrow
|
|
{
|
|
return _date.month;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(DateTime.init.month, 1);
|
|
_assertPred!"=="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).month, 7);
|
|
_assertPred!"=="(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)).month, 7);
|
|
|
|
const cdt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
static assert(__traits(compiles, cdt.month));
|
|
static assert(__traits(compiles, idt.month));
|
|
|
|
//Verify Examples.
|
|
assert(DateTime(Date(1999, 7, 6), TimeOfDay(9, 7, 5)).month == 7);
|
|
assert(DateTime(Date(2010, 10, 4), TimeOfDay(0, 0, 30)).month == 10);
|
|
assert(DateTime(Date(-7, 4, 5), TimeOfDay(7, 45, 2)).month == 4);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Month of a Gregorian Year.
|
|
|
|
Params:
|
|
month = The month to set this $(D DateTime)'s month to.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given month is not a valid month.
|
|
+/
|
|
@property void month(Month month) pure
|
|
{
|
|
_date.month = month;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static void testDT(DateTime dt, Month month, in DateTime expected = DateTime.init, size_t line = __LINE__)
|
|
{
|
|
dt.month = month;
|
|
assert(expected != DateTime.init);
|
|
_assertPred!"=="(dt, expected, "", __FILE__, line);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(1, 1, 1), TimeOfDay(12, 30, 33)), cast(Month)0));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(1, 1, 1), TimeOfDay(12, 30, 33)), cast(Month)13));
|
|
|
|
testDT(DateTime(Date(1, 1, 1), TimeOfDay(12, 30, 33)), cast(Month)7, DateTime(Date(1, 7, 1), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(-1, 1, 1), TimeOfDay(12, 30, 33)), cast(Month)7, DateTime(Date(-1, 7, 1), TimeOfDay(12, 30, 33)));
|
|
|
|
const cdt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
static assert(!__traits(compiles, cdt.month = 12));
|
|
static assert(!__traits(compiles, idt.month = 12));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Day of a Gregorian Month.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(DateTime(Date(1999, 7, 6), TimeOfDay(9, 7, 5)).day == 6);
|
|
assert(DateTime(Date(2010, 10, 4), TimeOfDay(0, 0, 30)).day == 4);
|
|
assert(DateTime(Date(-7, 4, 5), TimeOfDay(7, 45, 2)).day == 5);
|
|
--------------------
|
|
+/
|
|
@property ubyte day() const pure nothrow
|
|
{
|
|
return _date.day;
|
|
}
|
|
|
|
//Verify Examples.
|
|
version(testStdDateTime) unittest
|
|
{
|
|
assert(DateTime(Date(1999, 7, 6), TimeOfDay(9, 7, 5)).day == 6);
|
|
assert(DateTime(Date(2010, 10, 4), TimeOfDay(0, 0, 30)).day == 4);
|
|
assert(DateTime(Date(-7, 4, 5), TimeOfDay(7, 45, 2)).day == 5);
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
static void test(DateTime dateTime, int expected, size_t line = __LINE__)
|
|
{
|
|
_assertPred!"=="(dateTime.day, expected,
|
|
format("Value given: %s", dateTime), __FILE__, line);
|
|
}
|
|
|
|
foreach(year; chain(testYearsBC, testYearsAD))
|
|
{
|
|
foreach(md; testMonthDays)
|
|
{
|
|
foreach(tod; testTODs)
|
|
test(DateTime(Date(year, md.month, md.day), tod), md.day);
|
|
}
|
|
}
|
|
|
|
const cdt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
static assert(__traits(compiles, cdt.day));
|
|
static assert(__traits(compiles, idt.day));
|
|
}
|
|
|
|
|
|
/++
|
|
Day of a Gregorian Month.
|
|
|
|
Params:
|
|
day = The day of the month to set this $(D DateTime)'s day to.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given day is not a valid day of the
|
|
current month.
|
|
+/
|
|
@property void day(int day) pure
|
|
{
|
|
_date.day = day;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static void testDT(DateTime dt, int day)
|
|
{
|
|
dt.day = day;
|
|
}
|
|
|
|
//Test A.D.
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(1, 1, 1)), 0));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(1, 1, 1)), 32));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(1, 2, 1)), 29));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(4, 2, 1)), 30));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(1, 3, 1)), 32));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(1, 4, 1)), 31));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(1, 5, 1)), 32));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(1, 6, 1)), 31));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(1, 7, 1)), 32));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(1, 8, 1)), 32));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(1, 9, 1)), 31));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(1, 10, 1)), 32));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(1, 11, 1)), 31));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(1, 12, 1)), 32));
|
|
|
|
assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 1, 1)), 31));
|
|
assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 2, 1)), 28));
|
|
assertNotThrown!DateTimeException(testDT(DateTime(Date(4, 2, 1)), 29));
|
|
assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 3, 1)), 31));
|
|
assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 4, 1)), 30));
|
|
assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 5, 1)), 31));
|
|
assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 6, 1)), 30));
|
|
assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 7, 1)), 31));
|
|
assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 8, 1)), 31));
|
|
assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 9, 1)), 30));
|
|
assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 10, 1)), 31));
|
|
assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 11, 1)), 30));
|
|
assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 12, 1)), 31));
|
|
|
|
{
|
|
auto dt = DateTime(Date(1, 1, 1), TimeOfDay(7, 12, 22));
|
|
dt.day = 6;
|
|
_assertPred!"=="(dt, DateTime(Date(1, 1, 6), TimeOfDay(7, 12, 22)));
|
|
}
|
|
|
|
//Test B.C.
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(-1, 1, 1)), 0));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(-1, 1, 1)), 32));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(-1, 2, 1)), 29));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(0, 2, 1)), 30));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(-1, 3, 1)), 32));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(-1, 4, 1)), 31));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(-1, 5, 1)), 32));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(-1, 6, 1)), 31));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(-1, 7, 1)), 32));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(-1, 8, 1)), 32));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(-1, 9, 1)), 31));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(-1, 10, 1)), 32));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(-1, 11, 1)), 31));
|
|
assertThrown!DateTimeException(testDT(DateTime(Date(-1, 12, 1)), 32));
|
|
|
|
assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 1, 1)), 31));
|
|
assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 2, 1)), 28));
|
|
assertNotThrown!DateTimeException(testDT(DateTime(Date(0, 2, 1)), 29));
|
|
assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 3, 1)), 31));
|
|
assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 4, 1)), 30));
|
|
assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 5, 1)), 31));
|
|
assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 6, 1)), 30));
|
|
assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 7, 1)), 31));
|
|
assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 8, 1)), 31));
|
|
assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 9, 1)), 30));
|
|
assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 10, 1)), 31));
|
|
assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 11, 1)), 30));
|
|
assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 12, 1)), 31));
|
|
|
|
auto dt = DateTime(Date(-1, 1, 1), TimeOfDay(7, 12, 22));
|
|
dt.day = 6;
|
|
_assertPred!"=="(dt, DateTime(Date(-1, 1, 6), TimeOfDay(7, 12, 22)));
|
|
|
|
const cdt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
static assert(!__traits(compiles, cdt.day = 27));
|
|
static assert(!__traits(compiles, idt.day = 27));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Hours passed midnight.
|
|
+/
|
|
@property ubyte hour() const pure nothrow
|
|
{
|
|
return _tod.hour;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(DateTime.init.hour, 0);
|
|
_assertPred!"=="(DateTime(Date.init, TimeOfDay(12, 0, 0)).hour, 12);
|
|
|
|
const cdt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
static assert(__traits(compiles, cdt.hour));
|
|
static assert(__traits(compiles, idt.hour));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Hours passed midnight.
|
|
|
|
Params:
|
|
hour = The hour of the day to set this $(D DateTime)'s hour to.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given hour would result in an invalid
|
|
$(D DateTime).
|
|
+/
|
|
@property void hour(int hour) pure
|
|
{
|
|
_tod.hour = hour;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assertThrown!DateTimeException((){DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0)).hour = 24;}());
|
|
|
|
auto dt = DateTime.init;
|
|
dt.hour = 12;
|
|
_assertPred!"=="(dt, DateTime(1, 1, 1, 12, 0, 0));
|
|
|
|
const cdt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
static assert(!__traits(compiles, cdt.hour = 27));
|
|
static assert(!__traits(compiles, idt.hour = 27));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Minutes passed the hour.
|
|
+/
|
|
@property ubyte minute() const pure nothrow
|
|
{
|
|
return _tod.minute;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(DateTime.init.minute, 0);
|
|
_assertPred!"=="(DateTime(1, 1, 1, 0, 30, 0).minute, 30);
|
|
|
|
const cdt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
static assert(__traits(compiles, cdt.minute));
|
|
static assert(__traits(compiles, idt.minute));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Minutes passed the hour.
|
|
|
|
Params:
|
|
minute = The minute to set this $(D DateTime)'s minute to.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given minute would result in an
|
|
invalid $(D DateTime).
|
|
+/
|
|
@property void minute(int minute) pure
|
|
{
|
|
_tod.minute = minute;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assertThrown!DateTimeException((){DateTime.init.minute = 60;}());
|
|
|
|
auto dt = DateTime.init;
|
|
dt.minute = 30;
|
|
_assertPred!"=="(dt, DateTime(1, 1, 1, 0, 30, 0));
|
|
|
|
const cdt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
static assert(!__traits(compiles, cdt.minute = 27));
|
|
static assert(!__traits(compiles, idt.minute = 27));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Seconds passed the minute.
|
|
+/
|
|
@property ubyte second() const pure nothrow
|
|
{
|
|
return _tod.second;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(DateTime.init.second, 0);
|
|
_assertPred!"=="(DateTime(1, 1, 1, 0, 0, 33).second, 33);
|
|
|
|
const cdt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
static assert(__traits(compiles, cdt.second));
|
|
static assert(__traits(compiles, idt.second));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Seconds passed the minute.
|
|
|
|
Params:
|
|
second = The second to set this $(D DateTime)'s second to.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given seconds would result in an
|
|
invalid $(D DateTime).
|
|
+/
|
|
@property void second(int second) pure
|
|
{
|
|
_tod.second = second;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assertThrown!DateTimeException((){DateTime.init.second = 60;}());
|
|
|
|
auto dt = DateTime.init;
|
|
dt.second = 33;
|
|
_assertPred!"=="(dt, DateTime(1, 1, 1, 0, 0, 33));
|
|
|
|
const cdt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
static assert(!__traits(compiles, cdt.second = 27));
|
|
static assert(!__traits(compiles, idt.second = 27));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Adds the given number of years or months to this $(D DateTime). A
|
|
negative number will subtract.
|
|
|
|
Note that if day overflow is allowed, and the date with the adjusted
|
|
year/month overflows the number of days in the new month, then the month
|
|
will be incremented by one, and the day set to the number of days
|
|
overflowed. (e.g. if the day were 31 and the new month were June, then
|
|
the month would be incremented to July, and the new day would be 1). If
|
|
day overflow is not allowed, then the day will be set to the last valid
|
|
day in the month (e.g. June 31st would become June 30th).
|
|
|
|
Params:
|
|
units = The type of units to add ("years" or "months").
|
|
value = The number of months or years to add to this
|
|
$(D DateTime).
|
|
allowOverflow = Whether the days should be allowed to overflow,
|
|
causing the month to increment.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto dt1 = DateTime(2010, 1, 1, 12, 30, 33);
|
|
dt1.add!"months"(11);
|
|
assert(dt1 == DateTime(2010, 12, 1, 12, 30, 33));
|
|
|
|
auto dt2 = DateTime(2010, 1, 1, 12, 30, 33);
|
|
dt2.add!"months"(-11);
|
|
assert(dt2 == DateTime(2009, 2, 1, 12, 30, 33));
|
|
|
|
auto dt3 = DateTime(2000, 2, 29, 12, 30, 33);
|
|
dt3.add!"years"(1);
|
|
assert(dt3 == DateTime(2001, 3, 1, 12, 30, 33));
|
|
|
|
auto dt4 = DateTime(2000, 2, 29, 12, 30, 33);
|
|
dt4.add!"years"(1, AllowDayOverflow.no);
|
|
assert(dt4 == DateTime(2001, 2, 28, 12, 30, 33));
|
|
--------------------
|
|
+/
|
|
/+ref DateTime+/ void add(string units)(long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) pure nothrow
|
|
if(units == "years" ||
|
|
units == "months")
|
|
{
|
|
_date.add!units(value, allowOverflow);
|
|
}
|
|
|
|
//Verify Examples.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto dt1 = DateTime(2010, 1, 1, 12, 30, 33);
|
|
dt1.add!"months"(11);
|
|
assert(dt1 == DateTime(2010, 12, 1, 12, 30, 33));
|
|
|
|
auto dt2 = DateTime(2010, 1, 1, 12, 30, 33);
|
|
dt2.add!"months"(-11);
|
|
assert(dt2 == DateTime(2009, 2, 1, 12, 30, 33));
|
|
|
|
auto dt3 = DateTime(2000, 2, 29, 12, 30, 33);
|
|
dt3.add!"years"(1);
|
|
assert(dt3 == DateTime(2001, 3, 1, 12, 30, 33));
|
|
|
|
auto dt4 = DateTime(2000, 2, 29, 12, 30, 33);
|
|
dt4.add!"years"(1, AllowDayOverflow.no);
|
|
assert(dt4 == DateTime(2001, 2, 28, 12, 30, 33));
|
|
}
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
const cdt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
static assert(!__traits(compiles, cdt.add!"years"(4)));
|
|
static assert(!__traits(compiles, idt.add!"years"(4)));
|
|
static assert(!__traits(compiles, cdt.add!"months"(4)));
|
|
static assert(!__traits(compiles, idt.add!"months"(4)));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Adds the given number of years or months to this $(D DateTime). A
|
|
negative number will subtract.
|
|
|
|
The difference between rolling and adding is that rolling does not
|
|
affect larger units. So, if you roll a $(D DateTime) 12 months, you
|
|
get the exact same $(D DateTime). However, the days can still be
|
|
affected due to the differing number of days in each month.
|
|
|
|
Because there are no units larger than years, there is no difference
|
|
between adding and rolling years.
|
|
|
|
Params:
|
|
units = The type of units to add ("years" or "months").
|
|
value = The number of months or years to add to this
|
|
$(D DateTime).
|
|
allowOverflow = Whether the days should be allowed to overflow,
|
|
causing the month to increment.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto dt1 = DateTime(2010, 1, 1, 12, 33, 33);
|
|
dt1.roll!"months"(1);
|
|
assert(dt1 == DateTime(2010, 2, 1, 12, 33, 33));
|
|
|
|
auto dt2 = DateTime(2010, 1, 1, 12, 33, 33);
|
|
dt2.roll!"months"(-1);
|
|
assert(dt2 == DateTime(2010, 12, 1, 12, 33, 33));
|
|
|
|
auto dt3 = DateTime(1999, 1, 29, 12, 33, 33);
|
|
dt3.roll!"months"(1);
|
|
assert(dt3 == DateTime(1999, 3, 1, 12, 33, 33));
|
|
|
|
auto dt4 = DateTime(1999, 1, 29, 12, 33, 33);
|
|
dt4.roll!"months"(1, AllowDayOverflow.no);
|
|
assert(dt4 == DateTime(1999, 2, 28, 12, 33, 33));
|
|
|
|
auto dt5 = DateTime(2000, 2, 29, 12, 30, 33);
|
|
dt5.roll!"years"(1);
|
|
assert(dt5 == DateTime(2001, 3, 1, 12, 30, 33));
|
|
|
|
auto dt6 = DateTime(2000, 2, 29, 12, 30, 33);
|
|
dt6.roll!"years"(1, AllowDayOverflow.no);
|
|
assert(dt6 == DateTime(2001, 2, 28, 12, 30, 33));
|
|
--------------------
|
|
+/
|
|
/+ref DateTime+/ void roll(string units)(long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) pure nothrow
|
|
if(units == "years" ||
|
|
units == "months")
|
|
{
|
|
_date.roll!units(value, allowOverflow);
|
|
}
|
|
|
|
//Verify Examples.
|
|
unittest
|
|
{
|
|
version(testdStdDateTime)
|
|
{
|
|
auto dt1 = DateTime(2010, 1, 1, 12, 33, 33);
|
|
dt1.roll!"months"(1);
|
|
assert(dt1 == DateTime(2010, 2, 1, 12, 33, 33));
|
|
|
|
auto dt2 = DateTime(2010, 1, 1, 12, 33, 33);
|
|
dt2.roll!"months"(-1);
|
|
assert(dt2 == DateTime(2010, 12, 1, 12, 33, 33));
|
|
|
|
auto dt3 = DateTime(1999, 1, 29, 12, 33, 33);
|
|
dt3.roll!"months"(1);
|
|
assert(dt3 == DateTime(1999, 3, 1, 12, 33, 33));
|
|
|
|
auto dt4 = DateTime(1999, 1, 29, 12, 33, 33);
|
|
dt4.roll!"months"(1, AllowDayOverflow.no);
|
|
assert(dt4 == DateTime(1999, 2, 28, 12, 33, 33));
|
|
|
|
auto dt5 = DateTime(2000, 2, 29, 12, 30, 33);
|
|
dt5.roll!"years"(1);
|
|
assert(dt5 == DateTime(2001, 3, 1, 12, 30, 33));
|
|
|
|
auto dt6 = DateTime(2000, 2, 29, 12, 30, 33);
|
|
dt6.roll!"years"(1, AllowDayOverflow.no);
|
|
assert(dt6 == DateTime(2001, 2, 28, 12, 30, 33));
|
|
}
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
const cdt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
static assert(!__traits(compiles, cdt.roll!"years"(4)));
|
|
static assert(!__traits(compiles, idt.roll!"years"(4)));
|
|
static assert(!__traits(compiles, cdt.roll!"months"(4)));
|
|
static assert(!__traits(compiles, idt.roll!"months"(4)));
|
|
static assert(!__traits(compiles, cdt.roll!"days"(4)));
|
|
static assert(!__traits(compiles, idt.roll!"days"(4)));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Adds the given number of units to this $(D DateTime). A negative number
|
|
will subtract.
|
|
|
|
The difference between rolling and adding is that rolling does not
|
|
affect larger units. So, for instance, if you roll a $(D DateTime) one
|
|
year's worth of days, then you get the exact same $(D DateTime).
|
|
|
|
Accepted units are $(D "days"), $(D "minutes"), $(D "hours"),
|
|
$(D "minutes"), and $(D "seconds").
|
|
|
|
Params:
|
|
units = The units to add.
|
|
value = The number of $(D_PARAM units) to add to this $(D DateTime).
|
|
|
|
Examples:
|
|
--------------------
|
|
auto dt1 = DateTime(2010, 1, 1, 11, 23, 12);
|
|
dt1.roll!"days"(1);
|
|
assert(dt1 == DateTime(2010, 1, 2, 11, 23, 12));
|
|
dt1.roll!"days"(365);
|
|
assert(dt1 == DateTime(2010, 1, 26, 11, 23, 12));
|
|
dt1.roll!"days"(-32);
|
|
assert(dt1 == DateTime(2010, 1, 25, 11, 23, 12));
|
|
|
|
auto dt2 = DateTime(2010, 7, 4, 12, 0, 0);
|
|
dt2.roll!"hours"(1);
|
|
assert(dt2 == DateTime(2010, 7, 4, 13, 0, 0));
|
|
|
|
auto dt3 = DateTime(2010, 1, 1, 0, 0, 0);
|
|
dt3.roll!"seconds"(-1);
|
|
assert(dt3 == DateTime(2010, 1, 1, 0, 0, 59));
|
|
--------------------
|
|
+/
|
|
/+ref DateTime+/ void roll(string units)(long days) pure nothrow
|
|
if(units == "days")
|
|
{
|
|
_date.roll!"days"(days);
|
|
}
|
|
|
|
//Verify Examples.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto dt1 = DateTime(2010, 1, 1, 11, 23, 12);
|
|
dt1.roll!"days"(1);
|
|
assert(dt1 == DateTime(2010, 1, 2, 11, 23, 12));
|
|
dt1.roll!"days"(365);
|
|
assert(dt1 == DateTime(2010, 1, 26, 11, 23, 12));
|
|
dt1.roll!"days"(-32);
|
|
assert(dt1 == DateTime(2010, 1, 25, 11, 23, 12));
|
|
|
|
auto dt2 = DateTime(2010, 7, 4, 12, 0, 0);
|
|
dt2.roll!"hours"(1);
|
|
assert(dt2 == DateTime(2010, 7, 4, 13, 0, 0));
|
|
|
|
auto dt3 = DateTime(2010, 1, 1, 0, 0, 0);
|
|
dt3.roll!"seconds"(-1);
|
|
assert(dt3 == DateTime(2010, 1, 1, 0, 0, 59));
|
|
}
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
const cdt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
static assert(!__traits(compiles, cdt.roll!"days"(4)));
|
|
static assert(!__traits(compiles, idt.roll!"days"(4)));
|
|
}
|
|
}
|
|
|
|
|
|
//Shares documentation with "days" version.
|
|
/+ref DateTime+/ void roll(string units)(long value) pure nothrow
|
|
if(units == "hours" ||
|
|
units == "minutes" ||
|
|
units == "seconds")
|
|
{
|
|
_tod.roll!units(value);
|
|
}
|
|
|
|
//Test roll!"hours"().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static void testDT(DateTime orig, int hours, in DateTime expected, size_t line = __LINE__)
|
|
{
|
|
orig.roll!"hours"(hours);
|
|
_assertPred!"=="(orig, expected, "", __FILE__, line);
|
|
}
|
|
|
|
//Test A.D.
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 0, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1, DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 2, DateTime(Date(1999, 7, 6), TimeOfDay(14, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 3, DateTime(Date(1999, 7, 6), TimeOfDay(15, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 4, DateTime(Date(1999, 7, 6), TimeOfDay(16, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 5, DateTime(Date(1999, 7, 6), TimeOfDay(17, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 6, DateTime(Date(1999, 7, 6), TimeOfDay(18, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 7, DateTime(Date(1999, 7, 6), TimeOfDay(19, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 8, DateTime(Date(1999, 7, 6), TimeOfDay(20, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 9, DateTime(Date(1999, 7, 6), TimeOfDay(21, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 10, DateTime(Date(1999, 7, 6), TimeOfDay(22, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 11, DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 12, DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 13, DateTime(Date(1999, 7, 6), TimeOfDay(1, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 14, DateTime(Date(1999, 7, 6), TimeOfDay(2, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 15, DateTime(Date(1999, 7, 6), TimeOfDay(3, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 16, DateTime(Date(1999, 7, 6), TimeOfDay(4, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 17, DateTime(Date(1999, 7, 6), TimeOfDay(5, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 18, DateTime(Date(1999, 7, 6), TimeOfDay(6, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 19, DateTime(Date(1999, 7, 6), TimeOfDay(7, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 20, DateTime(Date(1999, 7, 6), TimeOfDay(8, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 21, DateTime(Date(1999, 7, 6), TimeOfDay(9, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 22, DateTime(Date(1999, 7, 6), TimeOfDay(10, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 23, DateTime(Date(1999, 7, 6), TimeOfDay(11, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 24, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 25, DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)));
|
|
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -1, DateTime(Date(1999, 7, 6), TimeOfDay(11, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -2, DateTime(Date(1999, 7, 6), TimeOfDay(10, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -3, DateTime(Date(1999, 7, 6), TimeOfDay(9, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -4, DateTime(Date(1999, 7, 6), TimeOfDay(8, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -5, DateTime(Date(1999, 7, 6), TimeOfDay(7, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -6, DateTime(Date(1999, 7, 6), TimeOfDay(6, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -7, DateTime(Date(1999, 7, 6), TimeOfDay(5, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -8, DateTime(Date(1999, 7, 6), TimeOfDay(4, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -9, DateTime(Date(1999, 7, 6), TimeOfDay(3, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -10, DateTime(Date(1999, 7, 6), TimeOfDay(2, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -11, DateTime(Date(1999, 7, 6), TimeOfDay(1, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -12, DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -13, DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -14, DateTime(Date(1999, 7, 6), TimeOfDay(22, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -15, DateTime(Date(1999, 7, 6), TimeOfDay(21, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -16, DateTime(Date(1999, 7, 6), TimeOfDay(20, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -17, DateTime(Date(1999, 7, 6), TimeOfDay(19, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -18, DateTime(Date(1999, 7, 6), TimeOfDay(18, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -19, DateTime(Date(1999, 7, 6), TimeOfDay(17, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -20, DateTime(Date(1999, 7, 6), TimeOfDay(16, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -21, DateTime(Date(1999, 7, 6), TimeOfDay(15, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -22, DateTime(Date(1999, 7, 6), TimeOfDay(14, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -23, DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -24, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -25, DateTime(Date(1999, 7, 6), TimeOfDay(11, 30, 33)));
|
|
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)), 1, DateTime(Date(1999, 7, 6), TimeOfDay(1, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)), 0, DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)), -1, DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33)));
|
|
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33)), 1, DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33)), 0, DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33)), -1, DateTime(Date(1999, 7, 6), TimeOfDay(22, 30, 33)));
|
|
|
|
testDT(DateTime(Date(1999, 7, 31), TimeOfDay(23, 30, 33)), 1, DateTime(Date(1999, 7, 31), TimeOfDay(0, 30, 33)));
|
|
testDT(DateTime(Date(1999, 8, 1), TimeOfDay(0, 30, 33)), -1, DateTime(Date(1999, 8, 1), TimeOfDay(23, 30, 33)));
|
|
|
|
testDT(DateTime(Date(1999, 12, 31), TimeOfDay(23, 30, 33)), 1, DateTime(Date(1999, 12, 31), TimeOfDay(0, 30, 33)));
|
|
testDT(DateTime(Date(2000, 1, 1), TimeOfDay(0, 30, 33)), -1, DateTime(Date(2000, 1, 1), TimeOfDay(23, 30, 33)));
|
|
|
|
testDT(DateTime(Date(1999, 2, 28), TimeOfDay(23, 30, 33)), 25, DateTime(Date(1999, 2, 28), TimeOfDay(0, 30, 33)));
|
|
testDT(DateTime(Date(1999, 3, 2), TimeOfDay(0, 30, 33)), -25, DateTime(Date(1999, 3, 2), TimeOfDay(23, 30, 33)));
|
|
|
|
testDT(DateTime(Date(2000, 2, 28), TimeOfDay(23, 30, 33)), 25, DateTime(Date(2000, 2, 28), TimeOfDay(0, 30, 33)));
|
|
testDT(DateTime(Date(2000, 3, 1), TimeOfDay(0, 30, 33)), -25, DateTime(Date(2000, 3, 1), TimeOfDay(23, 30, 33)));
|
|
|
|
//Test B.C.
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 0, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1, DateTime(Date(-1999, 7, 6), TimeOfDay(13, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 2, DateTime(Date(-1999, 7, 6), TimeOfDay(14, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 3, DateTime(Date(-1999, 7, 6), TimeOfDay(15, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 4, DateTime(Date(-1999, 7, 6), TimeOfDay(16, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 5, DateTime(Date(-1999, 7, 6), TimeOfDay(17, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 6, DateTime(Date(-1999, 7, 6), TimeOfDay(18, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 7, DateTime(Date(-1999, 7, 6), TimeOfDay(19, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 8, DateTime(Date(-1999, 7, 6), TimeOfDay(20, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 9, DateTime(Date(-1999, 7, 6), TimeOfDay(21, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 10, DateTime(Date(-1999, 7, 6), TimeOfDay(22, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 11, DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 12, DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 13, DateTime(Date(-1999, 7, 6), TimeOfDay(1, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 14, DateTime(Date(-1999, 7, 6), TimeOfDay(2, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 15, DateTime(Date(-1999, 7, 6), TimeOfDay(3, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 16, DateTime(Date(-1999, 7, 6), TimeOfDay(4, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 17, DateTime(Date(-1999, 7, 6), TimeOfDay(5, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 18, DateTime(Date(-1999, 7, 6), TimeOfDay(6, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 19, DateTime(Date(-1999, 7, 6), TimeOfDay(7, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 20, DateTime(Date(-1999, 7, 6), TimeOfDay(8, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 21, DateTime(Date(-1999, 7, 6), TimeOfDay(9, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 22, DateTime(Date(-1999, 7, 6), TimeOfDay(10, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 23, DateTime(Date(-1999, 7, 6), TimeOfDay(11, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 24, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 25, DateTime(Date(-1999, 7, 6), TimeOfDay(13, 30, 33)));
|
|
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -1, DateTime(Date(-1999, 7, 6), TimeOfDay(11, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -2, DateTime(Date(-1999, 7, 6), TimeOfDay(10, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -3, DateTime(Date(-1999, 7, 6), TimeOfDay(9, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -4, DateTime(Date(-1999, 7, 6), TimeOfDay(8, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -5, DateTime(Date(-1999, 7, 6), TimeOfDay(7, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -6, DateTime(Date(-1999, 7, 6), TimeOfDay(6, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -7, DateTime(Date(-1999, 7, 6), TimeOfDay(5, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -8, DateTime(Date(-1999, 7, 6), TimeOfDay(4, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -9, DateTime(Date(-1999, 7, 6), TimeOfDay(3, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -10, DateTime(Date(-1999, 7, 6), TimeOfDay(2, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -11, DateTime(Date(-1999, 7, 6), TimeOfDay(1, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -12, DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -13, DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -14, DateTime(Date(-1999, 7, 6), TimeOfDay(22, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -15, DateTime(Date(-1999, 7, 6), TimeOfDay(21, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -16, DateTime(Date(-1999, 7, 6), TimeOfDay(20, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -17, DateTime(Date(-1999, 7, 6), TimeOfDay(19, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -18, DateTime(Date(-1999, 7, 6), TimeOfDay(18, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -19, DateTime(Date(-1999, 7, 6), TimeOfDay(17, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -20, DateTime(Date(-1999, 7, 6), TimeOfDay(16, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -21, DateTime(Date(-1999, 7, 6), TimeOfDay(15, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -22, DateTime(Date(-1999, 7, 6), TimeOfDay(14, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -23, DateTime(Date(-1999, 7, 6), TimeOfDay(13, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -24, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -25, DateTime(Date(-1999, 7, 6), TimeOfDay(11, 30, 33)));
|
|
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33)), 1, DateTime(Date(-1999, 7, 6), TimeOfDay(1, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33)), 0, DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33)), -1, DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33)));
|
|
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33)), 1, DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33)), 0, DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33)), -1, DateTime(Date(-1999, 7, 6), TimeOfDay(22, 30, 33)));
|
|
|
|
testDT(DateTime(Date(-1999, 7, 31), TimeOfDay(23, 30, 33)), 1, DateTime(Date(-1999, 7, 31), TimeOfDay(0, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 8, 1), TimeOfDay(0, 30, 33)), -1, DateTime(Date(-1999, 8, 1), TimeOfDay(23, 30, 33)));
|
|
|
|
testDT(DateTime(Date(-2001, 12, 31), TimeOfDay(23, 30, 33)), 1, DateTime(Date(-2001, 12, 31), TimeOfDay(0, 30, 33)));
|
|
testDT(DateTime(Date(-2000, 1, 1), TimeOfDay(0, 30, 33)), -1, DateTime(Date(-2000, 1, 1), TimeOfDay(23, 30, 33)));
|
|
|
|
testDT(DateTime(Date(-2001, 2, 28), TimeOfDay(23, 30, 33)), 25, DateTime(Date(-2001, 2, 28), TimeOfDay(0, 30, 33)));
|
|
testDT(DateTime(Date(-2001, 3, 2), TimeOfDay(0, 30, 33)), -25, DateTime(Date(-2001, 3, 2), TimeOfDay(23, 30, 33)));
|
|
|
|
testDT(DateTime(Date(-2000, 2, 28), TimeOfDay(23, 30, 33)), 25, DateTime(Date(-2000, 2, 28), TimeOfDay(0, 30, 33)));
|
|
testDT(DateTime(Date(-2000, 3, 1), TimeOfDay(0, 30, 33)), -25, DateTime(Date(-2000, 3, 1), TimeOfDay(23, 30, 33)));
|
|
|
|
//Test Both
|
|
testDT(DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33)), 17_546, DateTime(Date(-1, 1, 1), TimeOfDay(13, 30, 33)));
|
|
testDT(DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33)), -17_546, DateTime(Date(1, 1, 1), TimeOfDay(11, 30, 33)));
|
|
|
|
const cdt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
static assert(!__traits(compiles, cdt.roll!"hours"(4)));
|
|
static assert(!__traits(compiles, idt.roll!"hours"(4)));
|
|
|
|
//Verify Examples.
|
|
auto dt1 = DateTime(Date(2010, 7, 4), TimeOfDay(12, 0, 0));
|
|
dt1.roll!"hours"(1);
|
|
assert(dt1 == DateTime(Date(2010, 7, 4), TimeOfDay(13, 0, 0)));
|
|
|
|
auto dt2 = DateTime(Date(2010, 2, 12), TimeOfDay(12, 0, 0));
|
|
dt2.roll!"hours"(-1);
|
|
assert(dt2 == DateTime(Date(2010, 2, 12), TimeOfDay(11, 0, 0)));
|
|
|
|
auto dt3 = DateTime(Date(2009, 12, 31), TimeOfDay(23, 0, 0));
|
|
dt3.roll!"hours"(1);
|
|
assert(dt3 == DateTime(Date(2009, 12, 31), TimeOfDay(0, 0, 0)));
|
|
|
|
auto dt4 = DateTime(Date(2010, 1, 1), TimeOfDay(0, 0, 0));
|
|
dt4.roll!"hours"(-1);
|
|
assert(dt4 == DateTime(Date(2010, 1, 1), TimeOfDay(23, 0, 0)));
|
|
}
|
|
}
|
|
|
|
//Test roll!"minutes"().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static void testDT(DateTime orig, int minutes, in DateTime expected, size_t line = __LINE__)
|
|
{
|
|
orig.roll!"minutes"(minutes);
|
|
_assertPred!"=="(orig, expected, "", __FILE__, line);
|
|
}
|
|
|
|
//Test A.D.
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 0, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1, DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 2, DateTime(Date(1999, 7, 6), TimeOfDay(12, 32, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 3, DateTime(Date(1999, 7, 6), TimeOfDay(12, 33, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 4, DateTime(Date(1999, 7, 6), TimeOfDay(12, 34, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 5, DateTime(Date(1999, 7, 6), TimeOfDay(12, 35, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 10, DateTime(Date(1999, 7, 6), TimeOfDay(12, 40, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 15, DateTime(Date(1999, 7, 6), TimeOfDay(12, 45, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 29, DateTime(Date(1999, 7, 6), TimeOfDay(12, 59, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 30, DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 45, DateTime(Date(1999, 7, 6), TimeOfDay(12, 15, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 60, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 75, DateTime(Date(1999, 7, 6), TimeOfDay(12, 45, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 90, DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 100, DateTime(Date(1999, 7, 6), TimeOfDay(12, 10, 33)));
|
|
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 689, DateTime(Date(1999, 7, 6), TimeOfDay(12, 59, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 690, DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 691, DateTime(Date(1999, 7, 6), TimeOfDay(12, 1, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 960, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1439, DateTime(Date(1999, 7, 6), TimeOfDay(12, 29, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1440, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1441, DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 2880, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -1, DateTime(Date(1999, 7, 6), TimeOfDay(12, 29, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -2, DateTime(Date(1999, 7, 6), TimeOfDay(12, 28, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -3, DateTime(Date(1999, 7, 6), TimeOfDay(12, 27, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -4, DateTime(Date(1999, 7, 6), TimeOfDay(12, 26, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -5, DateTime(Date(1999, 7, 6), TimeOfDay(12, 25, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -10, DateTime(Date(1999, 7, 6), TimeOfDay(12, 20, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -15, DateTime(Date(1999, 7, 6), TimeOfDay(12, 15, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -29, DateTime(Date(1999, 7, 6), TimeOfDay(12, 1, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -30, DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -45, DateTime(Date(1999, 7, 6), TimeOfDay(12, 45, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -60, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -75, DateTime(Date(1999, 7, 6), TimeOfDay(12, 15, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -90, DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -100, DateTime(Date(1999, 7, 6), TimeOfDay(12, 50, 33)));
|
|
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -749, DateTime(Date(1999, 7, 6), TimeOfDay(12, 1, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -750, DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -751, DateTime(Date(1999, 7, 6), TimeOfDay(12, 59, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -960, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -1439, DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -1440, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -1441, DateTime(Date(1999, 7, 6), TimeOfDay(12, 29, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -2880, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)), 1, DateTime(Date(1999, 7, 6), TimeOfDay(12, 1, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)), 0, DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)), -1, DateTime(Date(1999, 7, 6), TimeOfDay(12, 59, 33)));
|
|
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(11, 59, 33)), 1, DateTime(Date(1999, 7, 6), TimeOfDay(11, 0, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(11, 59, 33)), 0, DateTime(Date(1999, 7, 6), TimeOfDay(11, 59, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(11, 59, 33)), -1, DateTime(Date(1999, 7, 6), TimeOfDay(11, 58, 33)));
|
|
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33)), 1, DateTime(Date(1999, 7, 6), TimeOfDay(0, 1, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33)), 0, DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33)), -1, DateTime(Date(1999, 7, 6), TimeOfDay(0, 59, 33)));
|
|
|
|
testDT(DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 33)), 1, DateTime(Date(1999, 7, 5), TimeOfDay(23, 0, 33)));
|
|
testDT(DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 33)), 0, DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 33)));
|
|
testDT(DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 33)), -1, DateTime(Date(1999, 7, 5), TimeOfDay(23, 58, 33)));
|
|
|
|
testDT(DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 33)), 1, DateTime(Date(1998, 12, 31), TimeOfDay(23, 0, 33)));
|
|
testDT(DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 33)), 0, DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 33)));
|
|
testDT(DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 33)), -1, DateTime(Date(1998, 12, 31), TimeOfDay(23, 58, 33)));
|
|
|
|
//Test B.C.
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 0, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 31, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 2, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 32, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 3, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 33, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 4, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 34, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 5, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 35, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 10, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 40, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 15, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 45, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 29, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 59, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 30, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 45, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 15, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 60, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 75, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 45, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 90, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 100, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 10, 33)));
|
|
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 689, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 59, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 690, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 691, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 1, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 960, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1439, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 29, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1440, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1441, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 31, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 2880, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -1, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 29, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -2, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 28, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -3, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 27, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -4, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 26, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -5, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 25, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -10, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 20, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -15, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 15, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -29, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 1, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -30, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -45, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 45, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -60, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -75, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 15, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -90, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -100, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 50, 33)));
|
|
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -749, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 1, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -750, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -751, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 59, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -960, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -1439, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 31, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -1440, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -1441, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 29, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -2880, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)), 1, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 1, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)), 0, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)), -1, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 59, 33)));
|
|
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(11, 59, 33)), 1, DateTime(Date(-1999, 7, 6), TimeOfDay(11, 0, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(11, 59, 33)), 0, DateTime(Date(-1999, 7, 6), TimeOfDay(11, 59, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(11, 59, 33)), -1, DateTime(Date(-1999, 7, 6), TimeOfDay(11, 58, 33)));
|
|
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 33)), 1, DateTime(Date(-1999, 7, 6), TimeOfDay(0, 1, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 33)), 0, DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 33)), -1, DateTime(Date(-1999, 7, 6), TimeOfDay(0, 59, 33)));
|
|
|
|
testDT(DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 33)), 1, DateTime(Date(-1999, 7, 5), TimeOfDay(23, 0, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 33)), 0, DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 33)), -1, DateTime(Date(-1999, 7, 5), TimeOfDay(23, 58, 33)));
|
|
|
|
testDT(DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 33)), 1, DateTime(Date(-2000, 12, 31), TimeOfDay(23, 0, 33)));
|
|
testDT(DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 33)), 0, DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 33)));
|
|
testDT(DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 33)), -1, DateTime(Date(-2000, 12, 31), TimeOfDay(23, 58, 33)));
|
|
|
|
//Test Both
|
|
testDT(DateTime(Date(1, 1, 1), TimeOfDay(0, 0, 0)), -1, DateTime(Date(1, 1, 1), TimeOfDay(0, 59, 0)));
|
|
testDT(DateTime(Date(0, 12, 31), TimeOfDay(23, 59, 0)), 1, DateTime(Date(0, 12, 31), TimeOfDay(23, 0, 0)));
|
|
|
|
testDT(DateTime(Date(0, 1, 1), TimeOfDay(0, 0, 0)), -1, DateTime(Date(0, 1, 1), TimeOfDay(0, 59, 0)));
|
|
testDT(DateTime(Date(-1, 12, 31), TimeOfDay(23, 59, 0)), 1, DateTime(Date(-1, 12, 31), TimeOfDay(23, 0, 0)));
|
|
|
|
testDT(DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33)), 1_052_760, DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33)));
|
|
testDT(DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33)), -1_052_760, DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33)));
|
|
|
|
testDT(DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33)), 1_052_782, DateTime(Date(-1, 1, 1), TimeOfDay(11, 52, 33)));
|
|
testDT(DateTime(Date(1, 1, 1), TimeOfDay(13, 52, 33)), -1_052_782, DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33)));
|
|
|
|
const cdt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
static assert(!__traits(compiles, cdt.roll!"minutes"(4)));
|
|
static assert(!__traits(compiles, idt.roll!"minutes"(4)));
|
|
}
|
|
}
|
|
|
|
//Test roll!"seconds"().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static void testDT(DateTime orig, int seconds, in DateTime expected, size_t line = __LINE__)
|
|
{
|
|
orig.roll!"seconds"(seconds);
|
|
_assertPred!"=="(orig, expected, "", __FILE__, line);
|
|
}
|
|
|
|
//Test A.D.
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 0, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 2, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 35)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 3, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 36)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 4, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 37)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 5, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 38)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 10, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 43)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 15, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 48)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 26, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 59)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 27, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 30, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 3)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 59, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 32)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 60, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 61, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)));
|
|
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1766, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 59)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1767, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1768, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 1)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 2007, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 3599, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 32)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 3600, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 3601, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 7200, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -1, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 32)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -2, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 31)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -3, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 30)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -4, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 29)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -5, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 28)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -10, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 23)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -15, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 18)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -33, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -34, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 59)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -35, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 58)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -59, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -60, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -61, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 32)));
|
|
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)), 1, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 1)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)), 0, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)), -1, DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 59)));
|
|
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 0)), 1, DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 1)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 0)), 0, DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 0)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 0)), -1, DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 59)));
|
|
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0)), 1, DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 1)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0)), 0, DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0)));
|
|
testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0)), -1, DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 59)));
|
|
|
|
testDT(DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 59)), 1, DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 0)));
|
|
testDT(DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 59)), 0, DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 59)));
|
|
testDT(DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 59)), -1, DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 58)));
|
|
|
|
testDT(DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 59)), 1, DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 0)));
|
|
testDT(DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 59)), 0, DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 59)));
|
|
testDT(DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 59)), -1, DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 58)));
|
|
|
|
//Test B.C.
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 0, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 34)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 2, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 35)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 3, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 36)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 4, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 37)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 5, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 38)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 10, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 43)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 15, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 48)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 26, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 59)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 27, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 30, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 3)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 59, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 32)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 60, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 61, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 34)));
|
|
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1766, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 59)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1767, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1768, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 1)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 2007, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 3599, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 32)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 3600, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 3601, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 34)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 7200, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -1, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 32)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -2, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 31)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -3, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 30)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -4, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 29)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -5, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 28)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -10, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 23)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -15, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 18)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -33, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -34, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 59)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -35, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 58)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -59, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 34)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -60, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -61, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 32)));
|
|
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)), 1, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 1)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)), 0, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)), -1, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 59)));
|
|
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 0)), 1, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 1)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 0)), 0, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 0)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 0)), -1, DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 59)));
|
|
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 0)), 1, DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 1)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 0)), 0, DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 0)));
|
|
testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 0)), -1, DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 59)));
|
|
|
|
testDT(DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 59)), 1, DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 0)));
|
|
testDT(DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 59)), 0, DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 59)));
|
|
testDT(DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 59)), -1, DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 58)));
|
|
|
|
testDT(DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 59)), 1, DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 0)));
|
|
testDT(DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 59)), 0, DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 59)));
|
|
testDT(DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 59)), -1, DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 58)));
|
|
|
|
//Test Both
|
|
testDT(DateTime(Date(1, 1, 1), TimeOfDay(0, 0, 0)), -1, DateTime(Date(1, 1, 1), TimeOfDay(0, 0, 59)));
|
|
testDT(DateTime(Date(0, 12, 31), TimeOfDay(23, 59, 59)), 1, DateTime(Date(0, 12, 31), TimeOfDay(23, 59, 0)));
|
|
|
|
testDT(DateTime(Date(0, 1, 1), TimeOfDay(0, 0, 0)), -1, DateTime(Date(0, 1, 1), TimeOfDay(0, 0, 59)));
|
|
testDT(DateTime(Date(-1, 12, 31), TimeOfDay(23, 59, 59)), 1, DateTime(Date(-1, 12, 31), TimeOfDay(23, 59, 0)));
|
|
|
|
testDT(DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33)), 63_165_600L, DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33)));
|
|
testDT(DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33)), -63_165_600L, DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33)));
|
|
|
|
testDT(DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33)), 63_165_617L, DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 50)));
|
|
testDT(DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 50)), -63_165_617L, DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33)));
|
|
|
|
const cdt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
static assert(!__traits(compiles, cdt.roll!"seconds"(4)));
|
|
static assert(!__traits(compiles, idt.roll!"seconds"(4)));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Gives the result of adding or subtracting a duration from this
|
|
$(D DateTime).
|
|
|
|
The legal types of arithmetic for $(D DateTime) using this operator are
|
|
|
|
$(BOOKTABLE,
|
|
$(TR $(TD DateTime) $(TD +) $(TD duration) $(TD -->) $(TD DateTime))
|
|
$(TR $(TD DateTime) $(TD -) $(TD duration) $(TD -->) $(TD DateTime))
|
|
)
|
|
|
|
Params:
|
|
duration = The duration to add to or subtract from this
|
|
$(D DateTime).
|
|
+/
|
|
DateTime opBinary(string op, D)(in D duration) const pure nothrow
|
|
if((op == "+" || op == "-") &&
|
|
(is(Unqual!D == Duration) ||
|
|
is(Unqual!D == TickDuration)))
|
|
{
|
|
DateTime retval = this;
|
|
|
|
static if(is(Unqual!D == Duration))
|
|
immutable hnsecs = duration.total!"hnsecs";
|
|
else static if(is(Unqual!D == TickDuration))
|
|
immutable hnsecs = duration.hnsecs;
|
|
|
|
//Ideally, this would just be
|
|
//return retval.addSeconds(convert!("hnsecs", "seconds")(unaryFun!(op ~ "a")(hnsecs)));
|
|
//But there isn't currently a pure version of unaryFun!().
|
|
|
|
static if(op == "+")
|
|
immutable signedHNSecs = hnsecs;
|
|
else static if(op == "-")
|
|
immutable signedHNSecs = -hnsecs;
|
|
else
|
|
static assert(0);
|
|
|
|
return retval.addSeconds(convert!("hnsecs", "seconds")(signedHNSecs));
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
|
|
_assertPred!"=="(dt + dur!"weeks"(7), DateTime(Date(1999, 8, 24), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"=="(dt + dur!"weeks"(-7), DateTime(Date(1999, 5, 18), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"=="(dt + dur!"days"(7), DateTime(Date(1999, 7, 13), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"=="(dt + dur!"days"(-7), DateTime(Date(1999, 6, 29), TimeOfDay(12, 30, 33)));
|
|
|
|
_assertPred!"=="(dt + dur!"hours"(7), DateTime(Date(1999, 7, 6), TimeOfDay(19, 30, 33)));
|
|
_assertPred!"=="(dt + dur!"hours"(-7), DateTime(Date(1999, 7, 6), TimeOfDay(5, 30, 33)));
|
|
_assertPred!"=="(dt + dur!"minutes"(7), DateTime(Date(1999, 7, 6), TimeOfDay(12, 37, 33)));
|
|
_assertPred!"=="(dt + dur!"minutes"(-7), DateTime(Date(1999, 7, 6), TimeOfDay(12, 23, 33)));
|
|
_assertPred!"=="(dt + dur!"seconds"(7), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
|
|
_assertPred!"=="(dt + dur!"seconds"(-7), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
|
|
_assertPred!"=="(dt + dur!"msecs"(7_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
|
|
_assertPred!"=="(dt + dur!"msecs"(-7_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
|
|
_assertPred!"=="(dt + dur!"usecs"(7_000_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
|
|
_assertPred!"=="(dt + dur!"usecs"(-7_000_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
|
|
_assertPred!"=="(dt + dur!"hnsecs"(70_000_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
|
|
_assertPred!"=="(dt + dur!"hnsecs"(-70_000_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
|
|
|
|
//This probably only runs in cases where gettimeofday() is used, but it's
|
|
//hard to do this test correctly with variable ticksPerSec.
|
|
if(TickDuration.ticksPerSec == 1_000_000)
|
|
{
|
|
_assertPred!"=="(dt + TickDuration.from!"usecs"(7_000_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
|
|
_assertPred!"=="(dt + TickDuration.from!"usecs"(-7_000_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
|
|
}
|
|
|
|
_assertPred!"=="(dt - dur!"weeks"(-7), DateTime(Date(1999, 8, 24), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"=="(dt - dur!"weeks"(7), DateTime(Date(1999, 5, 18), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"=="(dt - dur!"days"(-7), DateTime(Date(1999, 7, 13), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"=="(dt - dur!"days"(7), DateTime(Date(1999, 6, 29), TimeOfDay(12, 30, 33)));
|
|
|
|
_assertPred!"=="(dt - dur!"hours"(-7), DateTime(Date(1999, 7, 6), TimeOfDay(19, 30, 33)));
|
|
_assertPred!"=="(dt - dur!"hours"(7), DateTime(Date(1999, 7, 6), TimeOfDay(5, 30, 33)));
|
|
_assertPred!"=="(dt - dur!"minutes"(-7), DateTime(Date(1999, 7, 6), TimeOfDay(12, 37, 33)));
|
|
_assertPred!"=="(dt - dur!"minutes"(7), DateTime(Date(1999, 7, 6), TimeOfDay(12, 23, 33)));
|
|
_assertPred!"=="(dt - dur!"seconds"(-7), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
|
|
_assertPred!"=="(dt - dur!"seconds"(7), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
|
|
_assertPred!"=="(dt - dur!"msecs"(-7_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
|
|
_assertPred!"=="(dt - dur!"msecs"(7_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
|
|
_assertPred!"=="(dt - dur!"usecs"(-7_000_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
|
|
_assertPred!"=="(dt - dur!"usecs"(7_000_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
|
|
_assertPred!"=="(dt - dur!"hnsecs"(-70_000_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
|
|
_assertPred!"=="(dt - dur!"hnsecs"(70_000_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
|
|
|
|
//This probably only runs in cases where gettimeofday() is used, but it's
|
|
//hard to do this test correctly with variable ticksPerSec.
|
|
if(TickDuration.ticksPerSec == 1_000_000)
|
|
{
|
|
_assertPred!"=="(dt - TickDuration.from!"usecs"(-7_000_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
|
|
_assertPred!"=="(dt - TickDuration.from!"usecs"(7_000_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
|
|
}
|
|
|
|
auto duration = dur!"seconds"(12);
|
|
const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
static assert(__traits(compiles, cdt + duration));
|
|
static assert(__traits(compiles, idt + duration));
|
|
static assert(__traits(compiles, cdt - duration));
|
|
static assert(__traits(compiles, idt - duration));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Gives the result of adding or subtracting a duration from this
|
|
$(D DateTime), as well as assigning the result to this $(D DateTime).
|
|
|
|
The legal types of arithmetic for $(D DateTime) using this operator are
|
|
|
|
$(BOOKTABLE,
|
|
$(TR $(TD DateTime) $(TD +) $(TD duration) $(TD -->) $(TD DateTime))
|
|
$(TR $(TD DateTime) $(TD -) $(TD duration) $(TD -->) $(TD DateTime))
|
|
)
|
|
|
|
Params:
|
|
duration = The duration to add to or subtract from this
|
|
$(D DateTime).
|
|
+/
|
|
/+ref+/ DateTime opOpAssign(string op, D)(in D duration) pure nothrow
|
|
if((op == "+" || op == "-") &&
|
|
(is(Unqual!D == Duration) ||
|
|
is(Unqual!D == TickDuration)))
|
|
{
|
|
DateTime retval = this;
|
|
|
|
static if(is(Unqual!D == Duration))
|
|
immutable hnsecs = duration.total!"hnsecs";
|
|
else static if(is(Unqual!D == TickDuration))
|
|
immutable hnsecs = duration.hnsecs;
|
|
|
|
//Ideally, this would just be
|
|
//return addSeconds(convert!("hnsecs", "seconds")(unaryFun!(op ~ "a")(hnsecs)));
|
|
//But there isn't currently a pure version of unaryFun!().
|
|
|
|
static if(op == "+")
|
|
immutable signedHNSecs = hnsecs;
|
|
else static if(op == "-")
|
|
immutable signedHNSecs = -hnsecs;
|
|
else
|
|
static assert(0);
|
|
|
|
return addSeconds(convert!("hnsecs", "seconds")(signedHNSecs));
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"+="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"weeks"(7), DateTime(Date(1999, 8, 24), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"+="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"weeks"(-7), DateTime(Date(1999, 5, 18), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"+="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"days"(7), DateTime(Date(1999, 7, 13), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"+="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"days"(-7), DateTime(Date(1999, 6, 29), TimeOfDay(12, 30, 33)));
|
|
|
|
_assertPred!"+="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"hours"(7), DateTime(Date(1999, 7, 6), TimeOfDay(19, 30, 33)));
|
|
_assertPred!"+="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"hours"(-7), DateTime(Date(1999, 7, 6), TimeOfDay(5, 30, 33)));
|
|
_assertPred!"+="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"minutes"(7), DateTime(Date(1999, 7, 6), TimeOfDay(12, 37, 33)));
|
|
_assertPred!"+="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"minutes"(-7), DateTime(Date(1999, 7, 6), TimeOfDay(12, 23, 33)));
|
|
_assertPred!"+="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"seconds"(7), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
|
|
_assertPred!"+="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"seconds"(-7), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
|
|
_assertPred!"+="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"msecs"(7_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
|
|
_assertPred!"+="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"msecs"(-7_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
|
|
_assertPred!"+="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"usecs"(7_000_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
|
|
_assertPred!"+="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"usecs"(-7_000_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
|
|
_assertPred!"+="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"hnsecs"(70_000_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
|
|
_assertPred!"+="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"hnsecs"(-70_000_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
|
|
|
|
_assertPred!"-="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"weeks"(-7), DateTime(Date(1999, 8, 24), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"-="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"weeks"(7), DateTime(Date(1999, 5, 18), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"-="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"days"(-7), DateTime(Date(1999, 7, 13), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"-="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"days"(7), DateTime(Date(1999, 6, 29), TimeOfDay(12, 30, 33)));
|
|
|
|
_assertPred!"-="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"hours"(-7), DateTime(Date(1999, 7, 6), TimeOfDay(19, 30, 33)));
|
|
_assertPred!"-="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"hours"(7), DateTime(Date(1999, 7, 6), TimeOfDay(5, 30, 33)));
|
|
_assertPred!"-="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"minutes"(-7), DateTime(Date(1999, 7, 6), TimeOfDay(12, 37, 33)));
|
|
_assertPred!"-="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"minutes"(7), DateTime(Date(1999, 7, 6), TimeOfDay(12, 23, 33)));
|
|
_assertPred!"-="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"seconds"(-7), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
|
|
_assertPred!"-="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"seconds"(7), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
|
|
_assertPred!"-="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"msecs"(-7_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
|
|
_assertPred!"-="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"msecs"(7_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
|
|
_assertPred!"-="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"usecs"(-7_000_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
|
|
_assertPred!"-="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"usecs"(7_000_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
|
|
_assertPred!"-="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"hnsecs"(-70_000_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
|
|
_assertPred!"-="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), dur!"hnsecs"(70_000_000), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
|
|
|
|
auto duration = dur!"seconds"(12);
|
|
const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
static assert(!__traits(compiles, cdt += duration));
|
|
static assert(!__traits(compiles, idt += duration));
|
|
static assert(!__traits(compiles, cdt -= duration));
|
|
static assert(!__traits(compiles, idt -= duration));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Gives the difference between two $(D DateTime)s.
|
|
|
|
The legal types of arithmetic for $(D DateTime) using this operator are
|
|
|
|
$(BOOKTABLE,
|
|
$(TR $(TD DateTime) $(TD -) $(TD DateTime) $(TD -->) $(TD duration))
|
|
)
|
|
+/
|
|
Duration opBinary(string op)(in DateTime rhs) const pure nothrow
|
|
if(op == "-")
|
|
{
|
|
immutable dateResult = _date - rhs.date;
|
|
immutable todResult = _tod - rhs._tod;
|
|
|
|
return dur!"hnsecs"(dateResult.total!"hnsecs" + todResult.total!"hnsecs");
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto dt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
|
|
_assertPred!"=="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) -
|
|
DateTime(Date(1998, 7, 6), TimeOfDay(12, 30, 33)),
|
|
dur!"seconds"(31_536_000));
|
|
_assertPred!"=="(DateTime(Date(1998, 7, 6), TimeOfDay(12, 30, 33)) -
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)),
|
|
dur!"seconds"(-31_536_000));
|
|
|
|
_assertPred!"=="(DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33)) -
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)),
|
|
dur!"seconds"(26_78_400));
|
|
_assertPred!"=="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) -
|
|
DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33)),
|
|
dur!"seconds"(-26_78_400));
|
|
|
|
_assertPred!"=="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) -
|
|
DateTime(Date(1999, 7, 5), TimeOfDay(12, 30, 33)),
|
|
dur!"seconds"(86_400));
|
|
_assertPred!"=="(DateTime(Date(1999, 7, 5), TimeOfDay(12, 30, 33)) -
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)),
|
|
dur!"seconds"(-86_400));
|
|
|
|
_assertPred!"=="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) -
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(11, 30, 33)),
|
|
dur!"seconds"(3600));
|
|
_assertPred!"=="(DateTime(Date(1999, 7, 6), TimeOfDay(11, 30, 33)) -
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)),
|
|
dur!"seconds"(-3600));
|
|
|
|
_assertPred!"=="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)) -
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)),
|
|
dur!"seconds"(60));
|
|
_assertPred!"=="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) -
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)),
|
|
dur!"seconds"(-60));
|
|
|
|
_assertPred!"=="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)) -
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)),
|
|
dur!"seconds"(1));
|
|
_assertPred!"=="(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) -
|
|
DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)),
|
|
dur!"seconds"(-1));
|
|
|
|
_assertPred!"=="(DateTime(1, 1, 1, 12, 30, 33) - DateTime(1, 1, 1, 0, 0, 0), dur!"seconds"(45033));
|
|
_assertPred!"=="(DateTime(1, 1, 1, 0, 0, 0) - DateTime(1, 1, 1, 12, 30, 33), dur!"seconds"(-45033));
|
|
_assertPred!"=="(DateTime(0, 12, 31, 12, 30, 33) - DateTime(1, 1, 1, 0, 0, 0), dur!"seconds"(-41367));
|
|
_assertPred!"=="(DateTime(1, 1, 1, 0, 0, 0) - DateTime(0, 12, 31, 12, 30, 33), dur!"seconds"(41367));
|
|
|
|
const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
static assert(__traits(compiles, dt - dt));
|
|
static assert(__traits(compiles, cdt - dt));
|
|
static assert(__traits(compiles, idt - dt));
|
|
|
|
static assert(__traits(compiles, dt - cdt));
|
|
static assert(__traits(compiles, cdt - cdt));
|
|
static assert(__traits(compiles, idt - cdt));
|
|
|
|
static assert(__traits(compiles, dt - idt));
|
|
static assert(__traits(compiles, cdt - idt));
|
|
static assert(__traits(compiles, idt - idt));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the difference between the two $(D DateTime)s in months.
|
|
|
|
You can get the difference in years by subtracting the year property
|
|
of two $(D DateTime)s, and you can get the difference in days or weeks
|
|
by subtracting the $(D DateTime)s themselves and using the Duration that
|
|
results, but because you cannot convert between months and smaller units
|
|
without a specific date (which $(D Duration)s don't have), you cannot
|
|
get the difference in months without doing some math using both the year
|
|
and month properties, so this is a convenience function for getting the
|
|
difference in months.
|
|
|
|
Note that the number of days in the months or how far into the month
|
|
either date is is irrelevant. It is the difference in the month property
|
|
combined with the difference in years * 12. So, for instance,
|
|
December 31st and January 1st are one month apart just as December 1st
|
|
and January 31st are one month apart.
|
|
|
|
Params:
|
|
rhs = The $(D DateTime) to subtract from this one.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(DateTime(1999, 2, 1, 12, 2, 3).diffMonths(
|
|
DateTime(1999, 1, 31, 23, 59, 59)) == 1);
|
|
|
|
assert(DateTime(1999, 1, 31, 0, 0, 0).diffMonths(
|
|
DateTime(1999, 2, 1, 12, 3, 42)) == -1);
|
|
|
|
assert(DateTime(1999, 3, 1, 5, 30, 0).diffMonths(
|
|
DateTime(1999, 1, 1, 2, 4, 7)) == 2);
|
|
|
|
assert(DateTime(1999, 1, 1, 7, 2, 4).diffMonths(
|
|
DateTime(1999, 3, 31, 0, 30, 58)) == -2);
|
|
--------------------
|
|
+/
|
|
int diffMonths(in DateTime rhs) const pure nothrow
|
|
{
|
|
return _date.diffMonths(rhs._date);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
static assert(__traits(compiles, dt.diffMonths(dt)));
|
|
static assert(__traits(compiles, cdt.diffMonths(dt)));
|
|
static assert(__traits(compiles, idt.diffMonths(dt)));
|
|
|
|
static assert(__traits(compiles, dt.diffMonths(cdt)));
|
|
static assert(__traits(compiles, cdt.diffMonths(cdt)));
|
|
static assert(__traits(compiles, idt.diffMonths(cdt)));
|
|
|
|
static assert(__traits(compiles, dt.diffMonths(idt)));
|
|
static assert(__traits(compiles, cdt.diffMonths(idt)));
|
|
static assert(__traits(compiles, idt.diffMonths(idt)));
|
|
|
|
//Verify Examples.
|
|
assert(DateTime(1999, 2, 1, 12, 2, 3).diffMonths(DateTime(1999, 1, 31, 23, 59, 59)) == 1);
|
|
assert(DateTime(1999, 1, 31, 0, 0, 0).diffMonths(DateTime(1999, 2, 1, 12, 3, 42)) == -1);
|
|
assert(DateTime(1999, 3, 1, 5, 30, 0).diffMonths(DateTime(1999, 1, 1, 2, 4, 7)) == 2);
|
|
assert(DateTime(1999, 1, 1, 7, 2, 4).diffMonths(DateTime(1999, 3, 31, 0, 30, 58)) == -2);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this $(D DateTime) is in a leap year.
|
|
+/
|
|
@property bool isLeapYear() const pure nothrow
|
|
{
|
|
return _date.isLeapYear;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
static assert(__traits(compiles, dt.isLeapYear));
|
|
static assert(__traits(compiles, cdt.isLeapYear));
|
|
static assert(__traits(compiles, idt.isLeapYear));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Day of the week this $(D DateTime) is on.
|
|
+/
|
|
@property DayOfWeek dayOfWeek() const pure nothrow
|
|
{
|
|
return _date.dayOfWeek;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
static assert(__traits(compiles, dt.dayOfWeek));
|
|
static assert(__traits(compiles, cdt.dayOfWeek));
|
|
static assert(__traits(compiles, idt.dayOfWeek));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Day of the year this $(D DateTime) is on.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(DateTime(Date(1999, 1, 1), TimeOfDay(12, 22, 7)).dayOfYear == 1);
|
|
assert(DateTime(Date(1999, 12, 31), TimeOfDay(7, 2, 59)).dayOfYear == 365);
|
|
assert(DateTime(Date(2000, 12, 31), TimeOfDay(21, 20, 0)).dayOfYear == 366);
|
|
--------------------
|
|
+/
|
|
@property ushort dayOfYear() const pure nothrow
|
|
{
|
|
return _date.dayOfYear;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
static assert(__traits(compiles, dt.dayOfYear));
|
|
static assert(__traits(compiles, cdt.dayOfYear));
|
|
static assert(__traits(compiles, idt.dayOfYear));
|
|
|
|
//Verify Examples.
|
|
assert(DateTime(Date(1999, 1, 1), TimeOfDay(12, 22, 7)).dayOfYear == 1);
|
|
assert(DateTime(Date(1999, 12, 31), TimeOfDay(7, 2, 59)).dayOfYear == 365);
|
|
assert(DateTime(Date(2000, 12, 31), TimeOfDay(21, 20, 0)).dayOfYear == 366);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Day of the year.
|
|
|
|
Params:
|
|
day = The day of the year to set which day of the year this
|
|
$(D DateTime) is on.
|
|
+/
|
|
@property void dayOfYear(int day) pure
|
|
{
|
|
_date.dayOfYear = day;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
static assert(__traits(compiles, dt.dayOfYear = 12));
|
|
static assert(!__traits(compiles, cdt.dayOfYear = 12));
|
|
static assert(!__traits(compiles, idt.dayOfYear = 12));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
The Xth day of the Gregorian Calendar that this $(D DateTime) is on.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(DateTime(Date(1, 1, 1), TimeOfDay(0, 0, 0)).dayOfGregorianCal ==
|
|
1);
|
|
assert(DateTime(Date(1, 12, 31), TimeOfDay(23, 59, 59)).dayOfGregorianCal ==
|
|
365);
|
|
assert(DateTime(Date(2, 1, 1), TimeOfDay(2, 2, 2)).dayOfGregorianCal ==
|
|
366);
|
|
|
|
assert(DateTime(Date(0, 12, 31), TimeOfDay(7, 7, 7)).dayOfGregorianCal ==
|
|
0);
|
|
assert(DateTime(Date(0, 1, 1), TimeOfDay(19, 30, 0)).dayOfGregorianCal ==
|
|
-365);
|
|
assert(DateTime(Date(-1, 12, 31), TimeOfDay(4, 7, 0)).dayOfGregorianCal ==
|
|
-366);
|
|
|
|
assert(DateTime(Date(2000, 1, 1), TimeOfDay(9, 30, 20)).dayOfGregorianCal ==
|
|
730_120);
|
|
assert(DateTime(Date(2010, 12, 31), TimeOfDay(15, 45, 50)).dayOfGregorianCal ==
|
|
734_137);
|
|
--------------------
|
|
+/
|
|
@property int dayOfGregorianCal() const pure nothrow
|
|
{
|
|
return _date.dayOfGregorianCal;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
static assert(__traits(compiles, cdt.dayOfGregorianCal));
|
|
static assert(__traits(compiles, idt.dayOfGregorianCal));
|
|
|
|
//Verify Examples.
|
|
assert(DateTime(Date(1, 1, 1), TimeOfDay(0, 0, 0)).dayOfGregorianCal == 1);
|
|
assert(DateTime(Date(1, 12, 31), TimeOfDay(23, 59, 59)).dayOfGregorianCal == 365);
|
|
assert(DateTime(Date(2, 1, 1), TimeOfDay(2, 2, 2)).dayOfGregorianCal == 366);
|
|
|
|
assert(DateTime(Date(0, 12, 31), TimeOfDay(7, 7, 7)).dayOfGregorianCal == 0);
|
|
assert(DateTime(Date(0, 1, 1), TimeOfDay(19, 30, 0)).dayOfGregorianCal == -365);
|
|
assert(DateTime(Date(-1, 12, 31), TimeOfDay(4, 7, 0)).dayOfGregorianCal == -366);
|
|
|
|
assert(DateTime(Date(2000, 1, 1), TimeOfDay(9, 30, 20)).dayOfGregorianCal == 730_120);
|
|
assert(DateTime(Date(2010, 12, 31), TimeOfDay(15, 45, 50)).dayOfGregorianCal == 734_137);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
The Xth day of the Gregorian Calendar that this $(D DateTime) is on.
|
|
Setting this property does not affect the time portion of
|
|
$(D DateTime).
|
|
|
|
Params:
|
|
days = The day of the Gregorian Calendar to set this $(D DateTime)
|
|
to.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto dt = DateTime(Date.init, TimeOfDay(12, 0, 0));
|
|
dt.dayOfGregorianCal = 1;
|
|
assert(dt == DateTime(Date(1, 1, 1), TimeOfDay(12, 0, 0)));
|
|
|
|
dt.dayOfGregorianCal = 365;
|
|
assert(dt == DateTime(Date(1, 12, 31), TimeOfDay(12, 0, 0)));
|
|
|
|
dt.dayOfGregorianCal = 366;
|
|
assert(dt == DateTime(Date(2, 1, 1), TimeOfDay(12, 0, 0)));
|
|
|
|
dt.dayOfGregorianCal = 0;
|
|
assert(dt == DateTime(Date(0, 12, 31), TimeOfDay(12, 0, 0)));
|
|
|
|
dt.dayOfGregorianCal = -365;
|
|
assert(dt == DateTime(Date(-0, 1, 1), TimeOfDay(12, 0, 0)));
|
|
|
|
dt.dayOfGregorianCal = -366;
|
|
assert(dt == DateTime(Date(-1, 12, 31), TimeOfDay(12, 0, 0)));
|
|
|
|
dt.dayOfGregorianCal = 730_120;
|
|
assert(dt == DateTime(Date(2000, 1, 1), TimeOfDay(12, 0, 0)));
|
|
|
|
dt.dayOfGregorianCal = 734_137;
|
|
assert(dt == DateTime(Date(2010, 12, 31), TimeOfDay(12, 0, 0)));
|
|
--------------------
|
|
+/
|
|
@property void dayOfGregorianCal(int days) pure nothrow
|
|
{
|
|
_date.dayOfGregorianCal = days;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
static assert(!__traits(compiles, cdt.dayOfGregorianCal = 7));
|
|
static assert(!__traits(compiles, idt.dayOfGregorianCal = 7));
|
|
|
|
//Verify Examples.
|
|
auto dt = DateTime(Date.init, TimeOfDay(12, 0, 0));
|
|
dt.dayOfGregorianCal = 1;
|
|
assert(dt == DateTime(Date(1, 1, 1), TimeOfDay(12, 0, 0)));
|
|
|
|
dt.dayOfGregorianCal = 365;
|
|
assert(dt == DateTime(Date(1, 12, 31), TimeOfDay(12, 0, 0)));
|
|
|
|
dt.dayOfGregorianCal = 366;
|
|
assert(dt == DateTime(Date(2, 1, 1), TimeOfDay(12, 0, 0)));
|
|
|
|
dt.dayOfGregorianCal = 0;
|
|
assert(dt == DateTime(Date(0, 12, 31), TimeOfDay(12, 0, 0)));
|
|
|
|
dt.dayOfGregorianCal = -365;
|
|
assert(dt == DateTime(Date(-0, 1, 1), TimeOfDay(12, 0, 0)));
|
|
|
|
dt.dayOfGregorianCal = -366;
|
|
assert(dt == DateTime(Date(-1, 12, 31), TimeOfDay(12, 0, 0)));
|
|
|
|
dt.dayOfGregorianCal = 730_120;
|
|
assert(dt == DateTime(Date(2000, 1, 1), TimeOfDay(12, 0, 0)));
|
|
|
|
dt.dayOfGregorianCal = 734_137;
|
|
assert(dt == DateTime(Date(2010, 12, 31), TimeOfDay(12, 0, 0)));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
The ISO 8601 week of the year that this $(D DateTime) is in.
|
|
|
|
See_Also:
|
|
$(WEB en.wikipedia.org/wiki/ISO_week_date, ISO Week Date)
|
|
+/
|
|
@property ubyte isoWeek() const pure nothrow
|
|
{
|
|
return _date.isoWeek;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
static assert(__traits(compiles, dt.isoWeek));
|
|
static assert(__traits(compiles, cdt.isoWeek));
|
|
static assert(__traits(compiles, idt.isoWeek));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
$(D DateTime) for the last day in the month that this $(D DateTime) is
|
|
in. The time portion of endOfMonth is always 23:59:59.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(DateTime(Date(1999, 1, 6), TimeOfDay(0, 0, 0)).endOfMonth ==
|
|
DateTime(Date(1999, 1, 31), TimeOfDay(23, 59, 59)));
|
|
|
|
assert(DateTime(Date(1999, 2, 7), TimeOfDay(19, 30, 0)).endOfMonth ==
|
|
DateTime(Date(1999, 2, 28), TimeOfDay(23, 59, 59)));
|
|
|
|
assert(DateTime(Date(2000, 2, 7), TimeOfDay(5, 12, 27)).endOfMonth ==
|
|
DateTime(Date(2000, 2, 29), TimeOfDay(23, 59, 59)));
|
|
|
|
assert(DateTime(Date(2000, 6, 4), TimeOfDay(12, 22, 9)).endOfMonth ==
|
|
DateTime(Date(2000, 6, 30), TimeOfDay(23, 59, 59)));
|
|
--------------------
|
|
+/
|
|
@property DateTime endOfMonth() const pure nothrow
|
|
{
|
|
try
|
|
return DateTime(_date.endOfMonth, TimeOfDay(23, 59, 59));
|
|
catch(Exception e)
|
|
assert(0, "DateTime constructor threw.");
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
_assertPred!"=="(DateTime(1999, 1, 1, 0, 13, 26).endOfMonth, DateTime(1999, 1, 31, 23, 59, 59));
|
|
_assertPred!"=="(DateTime(1999, 2, 1, 1, 14, 27).endOfMonth, DateTime(1999, 2, 28, 23, 59, 59));
|
|
_assertPred!"=="(DateTime(2000, 2, 1, 2, 15, 28).endOfMonth, DateTime(2000, 2, 29, 23, 59, 59));
|
|
_assertPred!"=="(DateTime(1999, 3, 1, 3, 16, 29).endOfMonth, DateTime(1999, 3, 31, 23, 59, 59));
|
|
_assertPred!"=="(DateTime(1999, 4, 1, 4, 17, 30).endOfMonth, DateTime(1999, 4, 30, 23, 59, 59));
|
|
_assertPred!"=="(DateTime(1999, 5, 1, 5, 18, 31).endOfMonth, DateTime(1999, 5, 31, 23, 59, 59));
|
|
_assertPred!"=="(DateTime(1999, 6, 1, 6, 19, 32).endOfMonth, DateTime(1999, 6, 30, 23, 59, 59));
|
|
_assertPred!"=="(DateTime(1999, 7, 1, 7, 20, 33).endOfMonth, DateTime(1999, 7, 31, 23, 59, 59));
|
|
_assertPred!"=="(DateTime(1999, 8, 1, 8, 21, 34).endOfMonth, DateTime(1999, 8, 31, 23, 59, 59));
|
|
_assertPred!"=="(DateTime(1999, 9, 1, 9, 22, 35).endOfMonth, DateTime(1999, 9, 30, 23, 59, 59));
|
|
_assertPred!"=="(DateTime(1999, 10, 1, 10, 23, 36).endOfMonth, DateTime(1999, 10, 31, 23, 59, 59));
|
|
_assertPred!"=="(DateTime(1999, 11, 1, 11, 24, 37).endOfMonth, DateTime(1999, 11, 30, 23, 59, 59));
|
|
_assertPred!"=="(DateTime(1999, 12, 1, 12, 25, 38).endOfMonth, DateTime(1999, 12, 31, 23, 59, 59));
|
|
|
|
//Test B.C.
|
|
_assertPred!"=="(DateTime(-1999, 1, 1, 0, 13, 26).endOfMonth, DateTime(-1999, 1, 31, 23, 59, 59));
|
|
_assertPred!"=="(DateTime(-1999, 2, 1, 1, 14, 27).endOfMonth, DateTime(-1999, 2, 28, 23, 59, 59));
|
|
_assertPred!"=="(DateTime(-2000, 2, 1, 2, 15, 28).endOfMonth, DateTime(-2000, 2, 29, 23, 59, 59));
|
|
_assertPred!"=="(DateTime(-1999, 3, 1, 3, 16, 29).endOfMonth, DateTime(-1999, 3, 31, 23, 59, 59));
|
|
_assertPred!"=="(DateTime(-1999, 4, 1, 4, 17, 30).endOfMonth, DateTime(-1999, 4, 30, 23, 59, 59));
|
|
_assertPred!"=="(DateTime(-1999, 5, 1, 5, 18, 31).endOfMonth, DateTime(-1999, 5, 31, 23, 59, 59));
|
|
_assertPred!"=="(DateTime(-1999, 6, 1, 6, 19, 32).endOfMonth, DateTime(-1999, 6, 30, 23, 59, 59));
|
|
_assertPred!"=="(DateTime(-1999, 7, 1, 7, 20, 33).endOfMonth, DateTime(-1999, 7, 31, 23, 59, 59));
|
|
_assertPred!"=="(DateTime(-1999, 8, 1, 8, 21, 34).endOfMonth, DateTime(-1999, 8, 31, 23, 59, 59));
|
|
_assertPred!"=="(DateTime(-1999, 9, 1, 9, 22, 35).endOfMonth, DateTime(-1999, 9, 30, 23, 59, 59));
|
|
_assertPred!"=="(DateTime(-1999, 10, 1, 10, 23, 36).endOfMonth, DateTime(-1999, 10, 31, 23, 59, 59));
|
|
_assertPred!"=="(DateTime(-1999, 11, 1, 11, 24, 37).endOfMonth, DateTime(-1999, 11, 30, 23, 59, 59));
|
|
_assertPred!"=="(DateTime(-1999, 12, 1, 12, 25, 38).endOfMonth, DateTime(-1999, 12, 31, 23, 59, 59));
|
|
|
|
const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
static assert(__traits(compiles, cdt.endOfMonth));
|
|
static assert(__traits(compiles, idt.endOfMonth));
|
|
|
|
//Verify Examples.
|
|
assert(DateTime(Date(1999, 1, 6), TimeOfDay(0, 0, 0)).endOfMonth == DateTime(Date(1999, 1, 31), TimeOfDay(23, 59, 59)));
|
|
assert(DateTime(Date(1999, 2, 7), TimeOfDay(19, 30, 0)).endOfMonth == DateTime(Date(1999, 2, 28), TimeOfDay(23, 59, 59)));
|
|
assert(DateTime(Date(2000, 2, 7), TimeOfDay(5, 12, 27)).endOfMonth == DateTime(Date(2000, 2, 29), TimeOfDay(23, 59, 59)));
|
|
assert(DateTime(Date(2000, 6, 4), TimeOfDay(12, 22, 9)).endOfMonth == DateTime(Date(2000, 6, 30), TimeOfDay(23, 59, 59)));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
The last day in the month that this $(D DateTime) is in.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(DateTime(Date(1999, 1, 6), TimeOfDay(0, 0, 0)).daysInMonth == 31);
|
|
assert(DateTime(Date(1999, 2, 7), TimeOfDay(19, 30, 0)).daysInMonth == 28);
|
|
assert(DateTime(Date(2000, 2, 7), TimeOfDay(5, 12, 27)).daysInMonth == 29);
|
|
assert(DateTime(Date(2000, 6, 4), TimeOfDay(12, 22, 9)).daysInMonth == 30);
|
|
--------------------
|
|
+/
|
|
@property ubyte daysInMonth() const pure nothrow
|
|
{
|
|
return _date.daysInMonth;
|
|
}
|
|
|
|
/++
|
|
$(RED Scheduled for deprecation in January 2012.
|
|
Please use daysInMonth instead.)
|
|
+/
|
|
alias daysInMonth endofMonthDay;
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
static assert(__traits(compiles, cdt.daysInMonth));
|
|
static assert(__traits(compiles, idt.daysInMonth));
|
|
|
|
//Verify Examples.
|
|
assert(DateTime(Date(1999, 1, 6), TimeOfDay(0, 0, 0)).daysInMonth == 31);
|
|
assert(DateTime(Date(1999, 2, 7), TimeOfDay(19, 30, 0)).daysInMonth == 28);
|
|
assert(DateTime(Date(2000, 2, 7), TimeOfDay(5, 12, 27)).daysInMonth == 29);
|
|
assert(DateTime(Date(2000, 6, 4), TimeOfDay(12, 22, 9)).daysInMonth == 30);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the current year is a date in A.D.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(DateTime(Date(1, 1, 1), TimeOfDay(12, 7, 0)).isAD);
|
|
assert(DateTime(Date(2010, 12, 31), TimeOfDay(0, 0, 0)).isAD);
|
|
assert(!DateTime(Date(0, 12, 31), TimeOfDay(23, 59, 59)).isAD);
|
|
assert(!DateTime(Date(-2010, 1, 1), TimeOfDay(2, 2, 2)).isAD);
|
|
--------------------
|
|
+/
|
|
@property bool isAD() const pure nothrow
|
|
{
|
|
return _date.isAD;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
static assert(__traits(compiles, cdt.isAD));
|
|
static assert(__traits(compiles, idt.isAD));
|
|
|
|
//Verify Examples.
|
|
assert(DateTime(Date(1, 1, 1), TimeOfDay(12, 7, 0)).isAD);
|
|
assert(DateTime(Date(2010, 12, 31), TimeOfDay(0, 0, 0)).isAD);
|
|
assert(!DateTime(Date(0, 12, 31), TimeOfDay(23, 59, 59)).isAD);
|
|
assert(!DateTime(Date(-2010, 1, 1), TimeOfDay(2, 2, 2)).isAD);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
The julian day for this $(D DateTime) at the given time. For example,
|
|
prior to noon, 1996-03-31 would be the julian day number 2_450_173, so
|
|
this function returns 2_450_173, while from noon onward, the julian
|
|
day number would be 2_450_174, so this function returns 2_450_174.
|
|
+/
|
|
@property long julianDay() const pure nothrow
|
|
{
|
|
if(_tod._hour < 12)
|
|
return _date.julianDay - 1;
|
|
else
|
|
return _date.julianDay;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(DateTime(Date(-4713, 11, 24), TimeOfDay(0, 0, 0)).julianDay, -1);
|
|
_assertPred!"=="(DateTime(Date(-4713, 11, 24), TimeOfDay(12, 0, 0)).julianDay, 0);
|
|
|
|
_assertPred!"=="(DateTime(Date(0, 12, 31), TimeOfDay(0, 0, 0)).julianDay, 1_721_424);
|
|
_assertPred!"=="(DateTime(Date(0, 12, 31), TimeOfDay(12, 0, 0)).julianDay, 1_721_425);
|
|
|
|
_assertPred!"=="(DateTime(Date(1, 1, 1), TimeOfDay(0, 0, 0)).julianDay, 1_721_425);
|
|
_assertPred!"=="(DateTime(Date(1, 1, 1), TimeOfDay(12, 0, 0)).julianDay, 1_721_426);
|
|
|
|
_assertPred!"=="(DateTime(Date(1582, 10, 15), TimeOfDay(0, 0, 0)).julianDay, 2_299_160);
|
|
_assertPred!"=="(DateTime(Date(1582, 10, 15), TimeOfDay(12, 0, 0)).julianDay, 2_299_161);
|
|
|
|
_assertPred!"=="(DateTime(Date(1858, 11, 17), TimeOfDay(0, 0, 0)).julianDay, 2_400_000);
|
|
_assertPred!"=="(DateTime(Date(1858, 11, 17), TimeOfDay(12, 0, 0)).julianDay, 2_400_001);
|
|
|
|
_assertPred!"=="(DateTime(Date(1982, 1, 4), TimeOfDay(0, 0, 0)).julianDay, 2_444_973);
|
|
_assertPred!"=="(DateTime(Date(1982, 1, 4), TimeOfDay(12, 0, 0)).julianDay, 2_444_974);
|
|
|
|
_assertPred!"=="(DateTime(Date(1996, 3, 31), TimeOfDay(0, 0, 0)).julianDay, 2_450_173);
|
|
_assertPred!"=="(DateTime(Date(1996, 3, 31), TimeOfDay(12, 0, 0)).julianDay, 2_450_174);
|
|
|
|
_assertPred!"=="(DateTime(Date(2010, 8, 24), TimeOfDay(0, 0, 0)).julianDay, 2_455_432);
|
|
_assertPred!"=="(DateTime(Date(2010, 8, 24), TimeOfDay(12, 0, 0)).julianDay, 2_455_433);
|
|
|
|
const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
static assert(__traits(compiles, cdt.julianDay));
|
|
static assert(__traits(compiles, idt.julianDay));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
The modified julian day for any time on this date (since, the modified
|
|
julian day changes at midnight).
|
|
+/
|
|
@property long modJulianDay() const pure nothrow
|
|
{
|
|
return _date.modJulianDay;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(DateTime(Date(1858, 11, 17), TimeOfDay(0, 0, 0)).modJulianDay, 0);
|
|
_assertPred!"=="(DateTime(Date(1858, 11, 17), TimeOfDay(12, 0, 0)).modJulianDay, 0);
|
|
|
|
_assertPred!"=="(DateTime(Date(2010, 8, 24), TimeOfDay(0, 0, 0)).modJulianDay, 55_432);
|
|
_assertPred!"=="(DateTime(Date(2010, 8, 24), TimeOfDay(12, 0, 0)).modJulianDay, 55_432);
|
|
|
|
const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
static assert(__traits(compiles, cdt.modJulianDay));
|
|
static assert(__traits(compiles, idt.modJulianDay));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Converts this $(D DateTime) to a string with the format YYYYMMDDTHHMMSS.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)).toISOString() ==
|
|
"20100704T070612");
|
|
|
|
assert(DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)).toISOString() ==
|
|
"19981225T021500");
|
|
|
|
assert(DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)).toISOString() ==
|
|
"00000105T230959");
|
|
|
|
assert(DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2)).toISOString() ==
|
|
"-00040105T000002");
|
|
--------------------
|
|
+/
|
|
string toISOString() const nothrow
|
|
{
|
|
try
|
|
return format("%sT%s", _date.toISOString(), _tod.toISOString());
|
|
catch(Exception e)
|
|
assert(0, "format() threw.");
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
_assertPred!"=="(DateTime(Date(9, 12, 4), TimeOfDay(0, 0, 0)).toISOString(), "00091204T000000");
|
|
_assertPred!"=="(DateTime(Date(99, 12, 4), TimeOfDay(5, 6, 12)).toISOString(), "00991204T050612");
|
|
_assertPred!"=="(DateTime(Date(999, 12, 4), TimeOfDay(13, 44, 59)).toISOString(), "09991204T134459");
|
|
_assertPred!"=="(DateTime(Date(9999, 7, 4), TimeOfDay(23, 59, 59)).toISOString(), "99990704T235959");
|
|
_assertPred!"=="(DateTime(Date(10000, 10, 20), TimeOfDay(1, 1, 1)).toISOString(), "+100001020T010101");
|
|
|
|
//Test B.C.
|
|
_assertPred!"=="(DateTime(Date(0, 12, 4), TimeOfDay(0, 12, 4)).toISOString(), "00001204T001204");
|
|
_assertPred!"=="(DateTime(Date(-9, 12, 4), TimeOfDay(0, 0, 0)).toISOString(), "-00091204T000000");
|
|
_assertPred!"=="(DateTime(Date(-99, 12, 4), TimeOfDay(5, 6, 12)).toISOString(), "-00991204T050612");
|
|
_assertPred!"=="(DateTime(Date(-999, 12, 4), TimeOfDay(13, 44, 59)).toISOString(), "-09991204T134459");
|
|
_assertPred!"=="(DateTime(Date(-9999, 7, 4), TimeOfDay(23, 59, 59)).toISOString(), "-99990704T235959");
|
|
_assertPred!"=="(DateTime(Date(-10000, 10, 20), TimeOfDay(1, 1, 1)).toISOString(), "-100001020T010101");
|
|
|
|
const cdt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
static assert(__traits(compiles, cdt.toISOString()));
|
|
static assert(__traits(compiles, idt.toISOString()));
|
|
|
|
//Verify Examples.
|
|
assert(DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)).toISOString() == "20100704T070612");
|
|
assert(DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)).toISOString() == "19981225T021500");
|
|
assert(DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)).toISOString() == "00000105T230959");
|
|
assert(DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2)).toISOString() == "-00040105T000002");
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Converts this $(D DateTime) to a string with the format
|
|
YYYY-MM-DDTHH:MM:SS.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)).toISOExtString() ==
|
|
"2010-07-04T07:06:12");
|
|
|
|
assert(DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)).toISOExtString() ==
|
|
"1998-12-25T02:15:00");
|
|
|
|
assert(DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)).toISOExtString() ==
|
|
"0000-01-05T23:09:59");
|
|
|
|
assert(DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2)).toISOExtString() ==
|
|
"-0004-01-05T00:00:02");
|
|
--------------------
|
|
+/
|
|
string toISOExtString() const nothrow
|
|
{
|
|
try
|
|
return format("%sT%s", _date.toISOExtString(), _tod.toISOExtString());
|
|
catch(Exception e)
|
|
assert(0, "format() threw.");
|
|
}
|
|
|
|
/++
|
|
$(RED Scheduled for deprecation in November 2011.
|
|
Please use toISOExtString instead.)
|
|
+/
|
|
alias toISOExtString toISOExtendedString;
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
_assertPred!"=="(DateTime(Date(9, 12, 4), TimeOfDay(0, 0, 0)).toISOExtString(), "0009-12-04T00:00:00");
|
|
_assertPred!"=="(DateTime(Date(99, 12, 4), TimeOfDay(5, 6, 12)).toISOExtString(), "0099-12-04T05:06:12");
|
|
_assertPred!"=="(DateTime(Date(999, 12, 4), TimeOfDay(13, 44, 59)).toISOExtString(), "0999-12-04T13:44:59");
|
|
_assertPred!"=="(DateTime(Date(9999, 7, 4), TimeOfDay(23, 59, 59)).toISOExtString(), "9999-07-04T23:59:59");
|
|
_assertPred!"=="(DateTime(Date(10000, 10, 20), TimeOfDay(1, 1, 1)).toISOExtString(), "+10000-10-20T01:01:01");
|
|
|
|
//Test B.C.
|
|
_assertPred!"=="(DateTime(Date(0, 12, 4), TimeOfDay(0, 12, 4)).toISOExtString(), "0000-12-04T00:12:04");
|
|
_assertPred!"=="(DateTime(Date(-9, 12, 4), TimeOfDay(0, 0, 0)).toISOExtString(), "-0009-12-04T00:00:00");
|
|
_assertPred!"=="(DateTime(Date(-99, 12, 4), TimeOfDay(5, 6, 12)).toISOExtString(), "-0099-12-04T05:06:12");
|
|
_assertPred!"=="(DateTime(Date(-999, 12, 4), TimeOfDay(13, 44, 59)).toISOExtString(), "-0999-12-04T13:44:59");
|
|
_assertPred!"=="(DateTime(Date(-9999, 7, 4), TimeOfDay(23, 59, 59)).toISOExtString(), "-9999-07-04T23:59:59");
|
|
_assertPred!"=="(DateTime(Date(-10000, 10, 20), TimeOfDay(1, 1, 1)).toISOExtString(), "-10000-10-20T01:01:01");
|
|
|
|
const cdt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
static assert(__traits(compiles, cdt.toISOExtString()));
|
|
static assert(__traits(compiles, idt.toISOExtString()));
|
|
|
|
//Verify Examples.
|
|
assert(DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)).toISOExtString() == "2010-07-04T07:06:12");
|
|
assert(DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)).toISOExtString() == "1998-12-25T02:15:00");
|
|
assert(DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)).toISOExtString() == "0000-01-05T23:09:59");
|
|
assert(DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2)).toISOExtString() == "-0004-01-05T00:00:02");
|
|
}
|
|
}
|
|
|
|
/++
|
|
Converts this $(D DateTime) to a string with the format
|
|
YYYY-Mon-DD HH:MM:SS.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)).toSimpleString() ==
|
|
"2010-Jul-04 07:06:12");
|
|
|
|
assert(DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)).toSimpleString() ==
|
|
"1998-Dec-25 02:15:00");
|
|
|
|
assert(DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)).toSimpleString() ==
|
|
"0000-Jan-05 23:09:59");
|
|
|
|
assert(DateTime(Dte(-4, 1, 5), TimeOfDay(0, 0, 2)).toSimpleString() ==
|
|
"-0004-Jan-05 00:00:02");
|
|
--------------------
|
|
+/
|
|
string toSimpleString() const nothrow
|
|
{
|
|
try
|
|
return format("%s %s", _date.toSimpleString(), _tod.toString());
|
|
catch(Exception e)
|
|
assert(0, "format() threw.");
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
_assertPred!"=="(DateTime(Date(9, 12, 4), TimeOfDay(0, 0, 0)).toSimpleString(), "0009-Dec-04 00:00:00");
|
|
_assertPred!"=="(DateTime(Date(99, 12, 4), TimeOfDay(5, 6, 12)).toSimpleString(), "0099-Dec-04 05:06:12");
|
|
_assertPred!"=="(DateTime(Date(999, 12, 4), TimeOfDay(13, 44, 59)).toSimpleString(), "0999-Dec-04 13:44:59");
|
|
_assertPred!"=="(DateTime(Date(9999, 7, 4), TimeOfDay(23, 59, 59)).toSimpleString(), "9999-Jul-04 23:59:59");
|
|
_assertPred!"=="(DateTime(Date(10000, 10, 20), TimeOfDay(1, 1, 1)).toSimpleString(), "+10000-Oct-20 01:01:01");
|
|
|
|
//Test B.C.
|
|
_assertPred!"=="(DateTime(Date(0, 12, 4), TimeOfDay(0, 12, 4)).toSimpleString(), "0000-Dec-04 00:12:04");
|
|
_assertPred!"=="(DateTime(Date(-9, 12, 4), TimeOfDay(0, 0, 0)).toSimpleString(), "-0009-Dec-04 00:00:00");
|
|
_assertPred!"=="(DateTime(Date(-99, 12, 4), TimeOfDay(5, 6, 12)).toSimpleString(), "-0099-Dec-04 05:06:12");
|
|
_assertPred!"=="(DateTime(Date(-999, 12, 4), TimeOfDay(13, 44, 59)).toSimpleString(), "-0999-Dec-04 13:44:59");
|
|
_assertPred!"=="(DateTime(Date(-9999, 7, 4), TimeOfDay(23, 59, 59)).toSimpleString(), "-9999-Jul-04 23:59:59");
|
|
_assertPred!"=="(DateTime(Date(-10000, 10, 20), TimeOfDay(1, 1, 1)).toSimpleString(), "-10000-Oct-20 01:01:01");
|
|
|
|
const cdt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
static assert(__traits(compiles, cdt.toSimpleString()));
|
|
static assert(__traits(compiles, idt.toSimpleString()));
|
|
|
|
//Verify Examples.
|
|
assert(DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)).toSimpleString() == "2010-Jul-04 07:06:12");
|
|
assert(DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)).toSimpleString() == "1998-Dec-25 02:15:00");
|
|
assert(DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)).toSimpleString() == "0000-Jan-05 23:09:59");
|
|
assert(DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2)).toSimpleString() == "-0004-Jan-05 00:00:02");
|
|
}
|
|
}
|
|
|
|
|
|
/+
|
|
Converts this $(D DateTime) to a string.
|
|
+/
|
|
//Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't
|
|
//have versions of toString() with extra modifiers, so we define one version
|
|
//with modifiers and one without.
|
|
string toString()
|
|
{
|
|
return toSimpleString();
|
|
}
|
|
|
|
/++
|
|
Converts this $(D DateTime) to a string.
|
|
+/
|
|
//Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't
|
|
//have versions of toString() with extra modifiers, so we define one version
|
|
//with modifiers and one without.
|
|
string toString() const nothrow
|
|
{
|
|
return toSimpleString();
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
|
|
static assert(__traits(compiles, dt.toString()));
|
|
static assert(__traits(compiles, cdt.toString()));
|
|
static assert(__traits(compiles, idt.toString()));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/++
|
|
Creates a $(D DateTime) from a string with the format YYYYMMDDTHHMMSS.
|
|
Whitespace is stripped from the given string.
|
|
|
|
Params:
|
|
isoString = A string formatted in the ISO format for dates and times.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given string is not in the ISO format
|
|
or if the resulting $(D DateTime) would not be valid.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(DateTime.fromISOString("20100704T070612") ==
|
|
DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)));
|
|
|
|
assert(DateTime.fromISOString("19981225T021500") ==
|
|
DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)));
|
|
|
|
assert(DateTime.fromISOString("00000105T230959") ==
|
|
DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)));
|
|
|
|
assert(DateTime.fromISOString("-00040105T000002") ==
|
|
DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2)));
|
|
|
|
assert(DateTime.fromISOString(" 20100704T070612 ") ==
|
|
DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)));
|
|
--------------------
|
|
+/
|
|
static DateTime fromISOString(S)(in S isoString)
|
|
if(isSomeString!S)
|
|
{
|
|
immutable dstr = to!dstring(strip(isoString));
|
|
|
|
enforce(dstr.length >= 15, new DateTimeException(format("Invalid ISO String: %s", isoString)));
|
|
auto t = dstr.stds_indexOf('T');
|
|
|
|
enforce(t != -1, new DateTimeException(format("Invalid ISO String: %s", isoString)));
|
|
|
|
immutable date = Date.fromISOString(dstr[0..t]);
|
|
immutable tod = TimeOfDay.fromISOString(dstr[t+1 .. $]);
|
|
|
|
return DateTime(date, tod);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assertThrown!DateTimeException(DateTime.fromISOString(""));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("20100704000000"));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("20100704 000000"));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("20100704t000000"));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("20100704T000000."));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("20100704T000000.0"));
|
|
|
|
assertThrown!DateTimeException(DateTime.fromISOString("2010-07-0400:00:00"));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("2010-07-04 00:00:00"));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("2010-07-04t00:00:00"));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("2010-07-04T00:00:00."));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("2010-07-04T00:00:00.0"));
|
|
|
|
assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-0400:00:00"));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04 00:00:00"));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04t00:00:00"));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04T00:00:00"));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04 00:00:00."));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04 00:00:00.0"));
|
|
|
|
assertThrown!DateTimeException(DateTime.fromISOString("2010-12-22T172201"));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("2010-Dec-22 17:22:01"));
|
|
|
|
_assertPred!"=="(DateTime.fromISOString("20101222T172201"), DateTime(Date(2010, 12, 22), TimeOfDay(17, 22, 01)));
|
|
_assertPred!"=="(DateTime.fromISOString("19990706T123033"), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"=="(DateTime.fromISOString("-19990706T123033"), DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"=="(DateTime.fromISOString("+019990706T123033"), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"=="(DateTime.fromISOString("19990706T123033 "), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"=="(DateTime.fromISOString(" 19990706T123033"), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"=="(DateTime.fromISOString(" 19990706T123033 "), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
|
|
//Verify Examples.
|
|
assert(DateTime.fromISOString("20100704T070612") == DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)));
|
|
assert(DateTime.fromISOString("19981225T021500") == DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)));
|
|
assert(DateTime.fromISOString("00000105T230959") == DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)));
|
|
assert(DateTime.fromISOString("-00040105T000002") == DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2)));
|
|
assert(DateTime.fromISOString(" 20100704T070612 ") == DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Creates a $(D DateTime) from a string with the format
|
|
YYYY-MM-DDTHH:MM:SS. Whitespace is stripped from the given string.
|
|
|
|
Params:
|
|
isoString = A string formatted in the ISO Extended format for dates
|
|
and times.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given string is not in the ISO
|
|
Extended format or if the resulting $(D DateTime) would not be
|
|
valid.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(DateTime.fromISOExtString("2010-07-04T07:06:12") ==
|
|
DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)));
|
|
|
|
assert(DateTime.fromISOExtString("1998-12-25T02:15:00") ==
|
|
DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)));
|
|
|
|
assert(DateTime.fromISOExtString("0000-01-05T23:09:59") ==
|
|
DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)));
|
|
|
|
assert(DateTime.fromISOExtString("-0004-01-05T00:00:02") ==
|
|
DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2)));
|
|
|
|
assert(DateTime.fromISOExtString(" 2010-07-04T07:06:12 ") ==
|
|
DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)));
|
|
--------------------
|
|
+/
|
|
static DateTime fromISOExtString(S)(in S isoExtString)
|
|
if(isSomeString!(S))
|
|
{
|
|
immutable dstr = to!dstring(strip(isoExtString));
|
|
|
|
enforce(dstr.length >= 15, new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
|
|
auto t = dstr.stds_indexOf('T');
|
|
|
|
enforce(t != -1, new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
|
|
|
|
immutable date = Date.fromISOExtString(dstr[0..t]);
|
|
immutable tod = TimeOfDay.fromISOExtString(dstr[t+1 .. $]);
|
|
|
|
return DateTime(date, tod);
|
|
}
|
|
|
|
/++
|
|
$(RED Scheduled for deprecation in November 2011.
|
|
Please use fromISOExtString instead.)
|
|
+/
|
|
static DateTime fromISOExtendedString(S)(in S isoExtString)
|
|
if(isSomeString!(S))
|
|
{
|
|
pragma(msg, softDeprec!("2.053", "November 2011", "fromISOExtendedString", "fromISOExtString"));
|
|
|
|
return fromISOExtString!string(isoExtString);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assertThrown!DateTimeException(DateTime.fromISOExtString(""));
|
|
assertThrown!DateTimeException(DateTime.fromISOExtString("20100704000000"));
|
|
assertThrown!DateTimeException(DateTime.fromISOExtString("20100704 000000"));
|
|
assertThrown!DateTimeException(DateTime.fromISOExtString("20100704t000000"));
|
|
assertThrown!DateTimeException(DateTime.fromISOExtString("20100704T000000."));
|
|
assertThrown!DateTimeException(DateTime.fromISOExtString("20100704T000000.0"));
|
|
|
|
assertThrown!DateTimeException(DateTime.fromISOExtString("2010-07:0400:00:00"));
|
|
assertThrown!DateTimeException(DateTime.fromISOExtString("2010-07-04 00:00:00"));
|
|
assertThrown!DateTimeException(DateTime.fromISOExtString("2010-07-04 00:00:00"));
|
|
assertThrown!DateTimeException(DateTime.fromISOExtString("2010-07-04t00:00:00"));
|
|
assertThrown!DateTimeException(DateTime.fromISOExtString("2010-07-04T00:00:00."));
|
|
assertThrown!DateTimeException(DateTime.fromISOExtString("2010-07-04T00:00:00.0"));
|
|
|
|
assertThrown!DateTimeException(DateTime.fromISOExtString("2010-Jul-0400:00:00"));
|
|
assertThrown!DateTimeException(DateTime.fromISOExtString("2010-Jul-04t00:00:00"));
|
|
assertThrown!DateTimeException(DateTime.fromISOExtString("2010-Jul-04 00:00:00."));
|
|
assertThrown!DateTimeException(DateTime.fromISOExtString("2010-Jul-04 00:00:00.0"));
|
|
|
|
assertThrown!DateTimeException(DateTime.fromISOExtString("20101222T172201"));
|
|
assertThrown!DateTimeException(DateTime.fromISOExtString("2010-Dec-22 17:22:01"));
|
|
|
|
_assertPred!"=="(DateTime.fromISOExtString("2010-12-22T17:22:01"), DateTime(Date(2010, 12, 22), TimeOfDay(17, 22, 01)));
|
|
_assertPred!"=="(DateTime.fromISOExtString("1999-07-06T12:30:33"), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"=="(DateTime.fromISOExtString("-1999-07-06T12:30:33"), DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"=="(DateTime.fromISOExtString("+01999-07-06T12:30:33"), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"=="(DateTime.fromISOExtString("1999-07-06T12:30:33 "), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"=="(DateTime.fromISOExtString(" 1999-07-06T12:30:33"), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"=="(DateTime.fromISOExtString(" 1999-07-06T12:30:33 "), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
|
|
//Verify Examples.
|
|
assert(DateTime.fromISOExtString("2010-07-04T07:06:12") == DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)));
|
|
assert(DateTime.fromISOExtString("1998-12-25T02:15:00") == DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)));
|
|
assert(DateTime.fromISOExtString("0000-01-05T23:09:59") == DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)));
|
|
assert(DateTime.fromISOExtString("-0004-01-05T00:00:02") == DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2)));
|
|
assert(DateTime.fromISOExtString(" 2010-07-04T07:06:12 ") == DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Creates a $(D DateTime) from a string with the format
|
|
YYYY-Mon-DD HH:MM:SS. Whitespace is stripped from the given string.
|
|
|
|
Params:
|
|
simpleString = A string formatted in the way that toSimpleString
|
|
formats dates and times.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given string is not in the correct
|
|
format or if the resulting $(D DateTime) would not be valid.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(DateTime.fromSimpleString("2010-Jul-04 07:06:12") ==
|
|
DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)));
|
|
assert(DateTime.fromSimpleString("1998-Dec-25 02:15:00") ==
|
|
DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)));
|
|
assert(DateTime.fromSimpleString("0000-Jan-05 23:09:59") ==
|
|
DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)));
|
|
assert(DateTime.fromSimpleString("-0004-Jan-05 00:00:02") ==
|
|
DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2)));
|
|
assert(DateTime.fromSimpleString(" 2010-Jul-04 07:06:12 ") ==
|
|
DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)));
|
|
--------------------
|
|
+/
|
|
static DateTime fromSimpleString(S)(in S simpleString)
|
|
if(isSomeString!(S))
|
|
{
|
|
immutable dstr = to!dstring(strip(simpleString));
|
|
|
|
enforce(dstr.length >= 15, new DateTimeException(format("Invalid string format: %s", simpleString)));
|
|
auto t = dstr.stds_indexOf(' ');
|
|
|
|
enforce(t != -1, new DateTimeException(format("Invalid string format: %s", simpleString)));
|
|
|
|
immutable date = Date.fromSimpleString(dstr[0..t]);
|
|
immutable tod = TimeOfDay.fromISOExtString(dstr[t+1 .. $]);
|
|
|
|
return DateTime(date, tod);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assertThrown!DateTimeException(DateTime.fromISOString(""));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("20100704000000"));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("20100704 000000"));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("20100704t000000"));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("20100704T000000."));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("20100704T000000.0"));
|
|
|
|
assertThrown!DateTimeException(DateTime.fromISOString("2010-07-0400:00:00"));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("2010-07-04 00:00:00"));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("2010-07-04t00:00:00"));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("2010-07-04T00:00:00."));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("2010-07-04T00:00:00.0"));
|
|
|
|
assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-0400:00:00"));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04 00:00:00"));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04t00:00:00"));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04T00:00:00"));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04 00:00:00."));
|
|
assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04 00:00:00.0"));
|
|
|
|
assertThrown!DateTimeException(DateTime.fromSimpleString("20101222T172201"));
|
|
assertThrown!DateTimeException(DateTime.fromSimpleString("2010-12-22T172201"));
|
|
|
|
_assertPred!"=="(DateTime.fromSimpleString("2010-Dec-22 17:22:01"), DateTime(Date(2010, 12, 22), TimeOfDay(17, 22, 01)));
|
|
_assertPred!"=="(DateTime.fromSimpleString("1999-Jul-06 12:30:33"), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"=="(DateTime.fromSimpleString("-1999-Jul-06 12:30:33"), DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"=="(DateTime.fromSimpleString("+01999-Jul-06 12:30:33"), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"=="(DateTime.fromSimpleString("1999-Jul-06 12:30:33 "), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"=="(DateTime.fromSimpleString(" 1999-Jul-06 12:30:33"), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
_assertPred!"=="(DateTime.fromSimpleString(" 1999-Jul-06 12:30:33 "), DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
|
|
|
|
//Verify Examples.
|
|
assert(DateTime.fromSimpleString("2010-Jul-04 07:06:12") == DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)));
|
|
assert(DateTime.fromSimpleString("1998-Dec-25 02:15:00") == DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)));
|
|
assert(DateTime.fromSimpleString("0000-Jan-05 23:09:59") == DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)));
|
|
assert(DateTime.fromSimpleString("-0004-Jan-05 00:00:02") == DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2)));
|
|
assert(DateTime.fromSimpleString(" 2010-Jul-04 07:06:12 ") == DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)));
|
|
}
|
|
}
|
|
|
|
|
|
//TODO Add function which takes a user-specified time format and produces a DateTime
|
|
|
|
//TODO Add function which takes pretty much any time-string and produces a DateTime
|
|
// Obviously, it will be less efficient, and it probably won't manage _every_
|
|
// possible date format, but a smart conversion function would be nice.
|
|
|
|
|
|
/++
|
|
Returns the $(D DateTime) farthest in the past which is representable by
|
|
$(D DateTime).
|
|
+/
|
|
@property static DateTime min() pure nothrow
|
|
out(result)
|
|
{
|
|
assert(result._date == Date.min);
|
|
assert(result._tod == TimeOfDay.min);
|
|
}
|
|
body
|
|
{
|
|
auto dt = DateTime.init;
|
|
dt._date._year = short.min;
|
|
dt._date._month = Month.jan;
|
|
dt._date._day = 1;
|
|
|
|
return dt;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assert(DateTime.min.year < 0);
|
|
assert(DateTime.min < DateTime.max);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the $(D DateTime) farthest in the future which is representable
|
|
by $(D DateTime).
|
|
+/
|
|
@property static DateTime max() pure nothrow
|
|
out(result)
|
|
{
|
|
assert(result._date == Date.max);
|
|
assert(result._tod == TimeOfDay.max);
|
|
}
|
|
body
|
|
{
|
|
auto dt = DateTime.init;
|
|
dt._date._year = short.max;
|
|
dt._date._month = Month.dec;
|
|
dt._date._day = 31;
|
|
dt._tod._hour = TimeOfDay.maxHour;
|
|
dt._tod._minute = TimeOfDay.maxMinute;
|
|
dt._tod._second = TimeOfDay.maxSecond;
|
|
|
|
return dt;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assert(DateTime.max.year > 0);
|
|
assert(DateTime.max > DateTime.min);
|
|
}
|
|
}
|
|
|
|
|
|
private:
|
|
|
|
/+
|
|
Add seconds to the time of day. Negative values will subtract. If the
|
|
number of seconds overflows (or underflows), then the seconds will wrap,
|
|
increasing (or decreasing) the number of minutes accordingly. The
|
|
same goes for any larger units.
|
|
|
|
Params:
|
|
seconds = The number of seconds to add to this $(D DateTime).
|
|
+/
|
|
ref DateTime addSeconds(long seconds) pure nothrow
|
|
{
|
|
long hnsecs = convert!("seconds", "hnsecs")(seconds);
|
|
hnsecs += convert!("hours", "hnsecs")(_tod._hour);
|
|
hnsecs += convert!("minutes", "hnsecs")(_tod._minute);
|
|
hnsecs += convert!("seconds", "hnsecs")(_tod._second);
|
|
|
|
auto days = splitUnitsFromHNSecs!"days"(hnsecs);
|
|
|
|
if(hnsecs < 0)
|
|
{
|
|
hnsecs += convert!("days", "hnsecs")(1);
|
|
--days;
|
|
}
|
|
|
|
_date.addDays(days);
|
|
|
|
immutable newHours = splitUnitsFromHNSecs!"hours"(hnsecs);
|
|
immutable newMinutes = splitUnitsFromHNSecs!"minutes"(hnsecs);
|
|
immutable newSeconds = splitUnitsFromHNSecs!"seconds"(hnsecs);
|
|
|
|
_tod._hour = cast(ubyte)newHours;
|
|
_tod._minute = cast(ubyte)newMinutes;
|
|
_tod._second = cast(ubyte)newSeconds;
|
|
|
|
return this;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static void testDT(DateTime orig, int seconds, in DateTime expected, size_t line = __LINE__)
|
|
{
|
|
orig.addSeconds(seconds);
|
|
_assertPred!"=="(orig, expected, "", __FILE__, line);
|
|
}
|
|
|
|
//Test A.D.
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), 0, DateTime(1999, 7, 6, 12, 30, 33));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), 1, DateTime(1999, 7, 6, 12, 30, 34));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), 2, DateTime(1999, 7, 6, 12, 30, 35));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), 3, DateTime(1999, 7, 6, 12, 30, 36));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), 4, DateTime(1999, 7, 6, 12, 30, 37));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), 5, DateTime(1999, 7, 6, 12, 30, 38));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), 10, DateTime(1999, 7, 6, 12, 30, 43));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), 15, DateTime(1999, 7, 6, 12, 30, 48));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), 26, DateTime(1999, 7, 6, 12, 30, 59));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), 27, DateTime(1999, 7, 6, 12, 31, 0));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), 30, DateTime(1999, 7, 6, 12, 31, 3));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), 59, DateTime(1999, 7, 6, 12, 31, 32));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), 60, DateTime(1999, 7, 6, 12, 31, 33));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), 61, DateTime(1999, 7, 6, 12, 31, 34));
|
|
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), 1766, DateTime(1999, 7, 6, 12, 59, 59));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), 1767, DateTime(1999, 7, 6, 13, 0, 0));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), 1768, DateTime(1999, 7, 6, 13, 0, 1));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), 2007, DateTime(1999, 7, 6, 13, 4, 0));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), 3599, DateTime(1999, 7, 6, 13, 30, 32));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), 3600, DateTime(1999, 7, 6, 13, 30, 33));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), 3601, DateTime(1999, 7, 6, 13, 30, 34));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), 7200, DateTime(1999, 7, 6, 14, 30, 33));
|
|
testDT(DateTime(1999, 7, 6, 23, 0, 0), 432_123, DateTime(1999, 7, 11, 23, 2, 3));
|
|
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), -1, DateTime(1999, 7, 6, 12, 30, 32));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), -2, DateTime(1999, 7, 6, 12, 30, 31));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), -3, DateTime(1999, 7, 6, 12, 30, 30));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), -4, DateTime(1999, 7, 6, 12, 30, 29));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), -5, DateTime(1999, 7, 6, 12, 30, 28));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), -10, DateTime(1999, 7, 6, 12, 30, 23));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), -15, DateTime(1999, 7, 6, 12, 30, 18));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), -33, DateTime(1999, 7, 6, 12, 30, 0));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), -34, DateTime(1999, 7, 6, 12, 29, 59));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), -35, DateTime(1999, 7, 6, 12, 29, 58));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), -59, DateTime(1999, 7, 6, 12, 29, 34));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), -60, DateTime(1999, 7, 6, 12, 29, 33));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), -61, DateTime(1999, 7, 6, 12, 29, 32));
|
|
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), -1833, DateTime(1999, 7, 6, 12, 0, 0));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), -1834, DateTime(1999, 7, 6, 11, 59, 59));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), -3600, DateTime(1999, 7, 6, 11, 30, 33));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), -3601, DateTime(1999, 7, 6, 11, 30, 32));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 33), -5134, DateTime(1999, 7, 6, 11, 4, 59));
|
|
testDT(DateTime(1999, 7, 6, 23, 0, 0), -432_123, DateTime(1999, 7, 1, 22, 57, 57));
|
|
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 0), 1, DateTime(1999, 7, 6, 12, 30, 1));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 0), 0, DateTime(1999, 7, 6, 12, 30, 0));
|
|
testDT(DateTime(1999, 7, 6, 12, 30, 0), -1, DateTime(1999, 7, 6, 12, 29, 59));
|
|
|
|
testDT(DateTime(1999, 7, 6, 12, 0, 0), 1, DateTime(1999, 7, 6, 12, 0, 1));
|
|
testDT(DateTime(1999, 7, 6, 12, 0, 0), 0, DateTime(1999, 7, 6, 12, 0, 0));
|
|
testDT(DateTime(1999, 7, 6, 12, 0, 0), -1, DateTime(1999, 7, 6, 11, 59, 59));
|
|
|
|
testDT(DateTime(1999, 7, 6, 0, 0, 0), 1, DateTime(1999, 7, 6, 0, 0, 1));
|
|
testDT(DateTime(1999, 7, 6, 0, 0, 0), 0, DateTime(1999, 7, 6, 0, 0, 0));
|
|
testDT(DateTime(1999, 7, 6, 0, 0, 0), -1, DateTime(1999, 7, 5, 23, 59, 59));
|
|
|
|
testDT(DateTime(1999, 7, 5, 23, 59, 59), 1, DateTime(1999, 7, 6, 0, 0, 0));
|
|
testDT(DateTime(1999, 7, 5, 23, 59, 59), 0, DateTime(1999, 7, 5, 23, 59, 59));
|
|
testDT(DateTime(1999, 7, 5, 23, 59, 59), -1, DateTime(1999, 7, 5, 23, 59, 58));
|
|
|
|
testDT(DateTime(1998, 12, 31, 23, 59, 59), 1, DateTime(1999, 1, 1, 0, 0, 0));
|
|
testDT(DateTime(1998, 12, 31, 23, 59, 59), 0, DateTime(1998, 12, 31, 23, 59, 59));
|
|
testDT(DateTime(1998, 12, 31, 23, 59, 59), -1, DateTime(1998, 12, 31, 23, 59, 58));
|
|
|
|
testDT(DateTime(1998, 1, 1, 0, 0, 0), 1, DateTime(1998, 1, 1, 0, 0, 1));
|
|
testDT(DateTime(1998, 1, 1, 0, 0, 0), 0, DateTime(1998, 1, 1, 0, 0, 0));
|
|
testDT(DateTime(1998, 1, 1, 0, 0, 0), -1, DateTime(1997, 12, 31, 23, 59, 59));
|
|
|
|
//Test B.C.
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), 0, DateTime(-1999, 7, 6, 12, 30, 33));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), 1, DateTime(-1999, 7, 6, 12, 30, 34));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), 2, DateTime(-1999, 7, 6, 12, 30, 35));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), 3, DateTime(-1999, 7, 6, 12, 30, 36));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), 4, DateTime(-1999, 7, 6, 12, 30, 37));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), 5, DateTime(-1999, 7, 6, 12, 30, 38));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), 10, DateTime(-1999, 7, 6, 12, 30, 43));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), 15, DateTime(-1999, 7, 6, 12, 30, 48));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), 26, DateTime(-1999, 7, 6, 12, 30, 59));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), 27, DateTime(-1999, 7, 6, 12, 31, 0));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), 30, DateTime(-1999, 7, 6, 12, 31, 3));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), 59, DateTime(-1999, 7, 6, 12, 31, 32));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), 60, DateTime(-1999, 7, 6, 12, 31, 33));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), 61, DateTime(-1999, 7, 6, 12, 31, 34));
|
|
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), 1766, DateTime(-1999, 7, 6, 12, 59, 59));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), 1767, DateTime(-1999, 7, 6, 13, 0, 0));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), 1768, DateTime(-1999, 7, 6, 13, 0, 1));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), 2007, DateTime(-1999, 7, 6, 13, 4, 0));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), 3599, DateTime(-1999, 7, 6, 13, 30, 32));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), 3600, DateTime(-1999, 7, 6, 13, 30, 33));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), 3601, DateTime(-1999, 7, 6, 13, 30, 34));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), 7200, DateTime(-1999, 7, 6, 14, 30, 33));
|
|
testDT(DateTime(-1999, 7, 6, 23, 0, 0), 432_123, DateTime(-1999, 7, 11, 23, 2, 3));
|
|
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), -1, DateTime(-1999, 7, 6, 12, 30, 32));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), -2, DateTime(-1999, 7, 6, 12, 30, 31));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), -3, DateTime(-1999, 7, 6, 12, 30, 30));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), -4, DateTime(-1999, 7, 6, 12, 30, 29));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), -5, DateTime(-1999, 7, 6, 12, 30, 28));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), -10, DateTime(-1999, 7, 6, 12, 30, 23));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), -15, DateTime(-1999, 7, 6, 12, 30, 18));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), -33, DateTime(-1999, 7, 6, 12, 30, 0));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), -34, DateTime(-1999, 7, 6, 12, 29, 59));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), -35, DateTime(-1999, 7, 6, 12, 29, 58));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), -59, DateTime(-1999, 7, 6, 12, 29, 34));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), -60, DateTime(-1999, 7, 6, 12, 29, 33));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), -61, DateTime(-1999, 7, 6, 12, 29, 32));
|
|
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), -1833, DateTime(-1999, 7, 6, 12, 0, 0));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), -1834, DateTime(-1999, 7, 6, 11, 59, 59));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), -3600, DateTime(-1999, 7, 6, 11, 30, 33));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), -3601, DateTime(-1999, 7, 6, 11, 30, 32));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), -5134, DateTime(-1999, 7, 6, 11, 4, 59));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 33), -7200, DateTime(-1999, 7, 6, 10, 30, 33));
|
|
testDT(DateTime(-1999, 7, 6, 23, 0, 0), -432_123, DateTime(-1999, 7, 1, 22, 57, 57));
|
|
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 0), 1, DateTime(-1999, 7, 6, 12, 30, 1));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 0), 0, DateTime(-1999, 7, 6, 12, 30, 0));
|
|
testDT(DateTime(-1999, 7, 6, 12, 30, 0), -1, DateTime(-1999, 7, 6, 12, 29, 59));
|
|
|
|
testDT(DateTime(-1999, 7, 6, 12, 0, 0), 1, DateTime(-1999, 7, 6, 12, 0, 1));
|
|
testDT(DateTime(-1999, 7, 6, 12, 0, 0), 0, DateTime(-1999, 7, 6, 12, 0, 0));
|
|
testDT(DateTime(-1999, 7, 6, 12, 0, 0), -1, DateTime(-1999, 7, 6, 11, 59, 59));
|
|
|
|
testDT(DateTime(-1999, 7, 6, 0, 0, 0), 1, DateTime(-1999, 7, 6, 0, 0, 1));
|
|
testDT(DateTime(-1999, 7, 6, 0, 0, 0), 0, DateTime(-1999, 7, 6, 0, 0, 0));
|
|
testDT(DateTime(-1999, 7, 6, 0, 0, 0), -1, DateTime(-1999, 7, 5, 23, 59, 59));
|
|
|
|
testDT(DateTime(-1999, 7, 5, 23, 59, 59), 1, DateTime(-1999, 7, 6, 0, 0, 0));
|
|
testDT(DateTime(-1999, 7, 5, 23, 59, 59), 0, DateTime(-1999, 7, 5, 23, 59, 59));
|
|
testDT(DateTime(-1999, 7, 5, 23, 59, 59), -1, DateTime(-1999, 7, 5, 23, 59, 58));
|
|
|
|
testDT(DateTime(-2000, 12, 31, 23, 59, 59), 1, DateTime(-1999, 1, 1, 0, 0, 0));
|
|
testDT(DateTime(-2000, 12, 31, 23, 59, 59), 0, DateTime(-2000, 12, 31, 23, 59, 59));
|
|
testDT(DateTime(-2000, 12, 31, 23, 59, 59), -1, DateTime(-2000, 12, 31, 23, 59, 58));
|
|
|
|
testDT(DateTime(-2000, 1, 1, 0, 0, 0), 1, DateTime(-2000, 1, 1, 0, 0, 1));
|
|
testDT(DateTime(-2000, 1, 1, 0, 0, 0), 0, DateTime(-2000, 1, 1, 0, 0, 0));
|
|
testDT(DateTime(-2000, 1, 1, 0, 0, 0), -1, DateTime(-2001, 12, 31, 23, 59, 59));
|
|
|
|
//Test Both
|
|
testDT(DateTime(1, 1, 1, 0, 0, 0), -1, DateTime(0, 12, 31, 23, 59, 59));
|
|
testDT(DateTime(0, 12, 31, 23, 59, 59), 1, DateTime(1, 1, 1, 0, 0, 0));
|
|
|
|
testDT(DateTime(0, 1, 1, 0, 0, 0), -1, DateTime(-1, 12, 31, 23, 59, 59));
|
|
testDT(DateTime(-1, 12, 31, 23, 59, 59), 1, DateTime(0, 1, 1, 0, 0, 0));
|
|
|
|
testDT(DateTime(-1, 1, 1, 11, 30, 33), 63_165_600L, DateTime(1, 1, 1, 13, 30, 33));
|
|
testDT(DateTime(1, 1, 1, 13, 30, 33), -63_165_600L, DateTime(-1, 1, 1, 11, 30, 33));
|
|
|
|
testDT(DateTime(-1, 1, 1, 11, 30, 33), 63_165_617L, DateTime(1, 1, 1, 13, 30, 50));
|
|
testDT(DateTime(1, 1, 1, 13, 30, 50), -63_165_617L, DateTime(-1, 1, 1, 11, 30, 33));
|
|
|
|
const cdt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
|
|
static assert(!__traits(compiles, cdt.addSeconds(4)));
|
|
static assert(!__traits(compiles, idt.addSeconds(4)));
|
|
}
|
|
}
|
|
|
|
|
|
Date _date;
|
|
TimeOfDay _tod;
|
|
}
|
|
|
|
|
|
//==============================================================================
|
|
// Section with intervals.
|
|
//==============================================================================
|
|
|
|
/++
|
|
Represents an interval of time.
|
|
|
|
An $(D Interval) has a starting point and an end point. The interval of time
|
|
is therefore the time starting at the starting point up to, but not
|
|
including, the end point. e.g.
|
|
|
|
$(BOOKTABLE,
|
|
$(TR $(TD [January 5th, 2010 - March 10th, 2010$(RPAREN)))
|
|
$(TR $(TD [05:00:30 - 12:00:00$(RPAREN)))
|
|
$(TR $(TD [1982-01-04T08:59:00 - 2010-07-04T12:00:00$(RPAREN)))
|
|
)
|
|
|
|
A range can be obtained from an $(D Interval), allowing you to iterate over
|
|
that interval, with the exact time points which are iterated over depending
|
|
on the function which generates the range.
|
|
+/
|
|
struct Interval(TP)
|
|
{
|
|
public:
|
|
|
|
/++
|
|
Params:
|
|
begin = The time point which begins the interval.
|
|
end = The time point which ends (but is not included in) the
|
|
interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if $(D_PARAM end) is before $(D_PARAM begin).
|
|
|
|
Examples:
|
|
--------------------
|
|
Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
|
|
--------------------
|
|
+/
|
|
this(U)(in TP begin, in U end) pure
|
|
if(is(Unqual!TP == Unqual!U))
|
|
{
|
|
if(!_valid(begin, end))
|
|
throw new DateTimeException("Arguments would result in an invalid Interval.");
|
|
|
|
_begin = cast(TP)begin;
|
|
_end = cast(TP)end;
|
|
}
|
|
|
|
|
|
/++
|
|
Params:
|
|
begin = The time point which begins the interval.
|
|
duration = The duration from the starting point to the end point.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the resulting $(D end) is before
|
|
$(D begin).
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Interval!Date(Date(1996, 1, 2), Dur.years(3)) ==
|
|
Interval!Date(Date(1996, 1, 2), Date(1999, 1, 2)));
|
|
--------------------
|
|
+/
|
|
this(D)(in TP begin, in D duration) pure
|
|
if(__traits(compiles, begin + duration))
|
|
{
|
|
_begin = cast(TP)begin;
|
|
_end = begin + duration;
|
|
|
|
if(!_valid(_begin, _end))
|
|
throw new DateTimeException("Arguments would result in an invalid Interval.");
|
|
}
|
|
|
|
|
|
/++
|
|
Params:
|
|
rhs = The $(D Interval) to assign to this one.
|
|
+/
|
|
/+ref+/ Interval opAssign(const ref Interval rhs) pure nothrow
|
|
{
|
|
_begin = cast(TP)rhs._begin;
|
|
_end = cast(TP)rhs._end;
|
|
|
|
return this;
|
|
}
|
|
|
|
|
|
/++
|
|
Params:
|
|
rhs = The $(D Interval) to assign to this one.
|
|
+/
|
|
/+ref+/ Interval opAssign(Interval rhs) pure nothrow
|
|
{
|
|
_begin = cast(TP)rhs._begin;
|
|
_end = cast(TP)rhs._end;
|
|
|
|
return this;
|
|
}
|
|
|
|
|
|
/++
|
|
The starting point of the interval. It is included in the interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).begin ==
|
|
Date(1996, 1, 2));
|
|
--------------------
|
|
+/
|
|
@property TP begin() const pure nothrow
|
|
{
|
|
return cast(TP)_begin;
|
|
}
|
|
|
|
|
|
/++
|
|
The starting point of the interval. It is included in the interval.
|
|
|
|
Params:
|
|
timePoint = The time point to set $(D begin) to.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the resulting interval would be invalid.
|
|
+/
|
|
@property void begin(TP timePoint) pure
|
|
{
|
|
if(!_valid(timePoint, _end))
|
|
throw new DateTimeException("Arguments would result in an invalid Interval.");
|
|
|
|
_begin = timePoint;
|
|
}
|
|
|
|
|
|
/++
|
|
The end point of the interval. It is excluded from the interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).end ==
|
|
Date(2012, 3, 1));
|
|
--------------------
|
|
+/
|
|
@property TP end() const pure nothrow
|
|
{
|
|
return cast(TP)_end;
|
|
}
|
|
|
|
|
|
/++
|
|
The end point of the interval. It is excluded from the interval.
|
|
|
|
Params:
|
|
timePoint = The time point to set end to.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the resulting interval would be invalid.
|
|
+/
|
|
@property void end(TP timePoint) pure
|
|
{
|
|
if(!_valid(_begin, timePoint))
|
|
throw new DateTimeException("Arguments would result in an invalid Interval.");
|
|
|
|
_end = timePoint;
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the duration between $(D begin) and $(D end).
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).length ==
|
|
dur!"days"(5903));
|
|
--------------------
|
|
+/
|
|
@property typeof(end - begin) length() const pure nothrow
|
|
{
|
|
return _end - _begin;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the interval's length is 0, that is, whether $(D begin == end).
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(1996, 1, 2)).empty);
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).empty);
|
|
--------------------
|
|
+/
|
|
@property bool empty() const pure nothrow
|
|
{
|
|
return _begin == _end;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given time point is within this interval.
|
|
|
|
Params:
|
|
timePoint = The time point to check for inclusion in this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if this interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(
|
|
Date(1994, 12, 24)));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(
|
|
Date(2000, 1, 5)));
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(
|
|
Date(2012, 3, 1)));
|
|
--------------------
|
|
+/
|
|
bool contains(in TP timePoint) const pure
|
|
{
|
|
_enforceNotEmpty();
|
|
|
|
return timePoint >= _begin && timePoint < _end;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval is completely within this interval.
|
|
|
|
Params:
|
|
interval = The interval to check for inclusion in this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if either interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(
|
|
Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(
|
|
Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
|
|
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(
|
|
Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1))));
|
|
--------------------
|
|
+/
|
|
bool contains(in Interval interval) const pure
|
|
{
|
|
_enforceNotEmpty();
|
|
interval._enforceNotEmpty();
|
|
|
|
return interval._begin >= _begin &&
|
|
interval._begin < _end &&
|
|
interval._end <= _end;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval is completely within this interval.
|
|
|
|
Always returns false (unless this interval is empty), because an
|
|
interval going to positive infinity can never be contained in a finite
|
|
interval.
|
|
|
|
Params:
|
|
interval = The interval to check for inclusion in this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if this interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(
|
|
PosInfInterval!Date(Date(1999, 5, 4))));
|
|
--------------------
|
|
+/
|
|
bool contains(in PosInfInterval!TP interval) const pure
|
|
{
|
|
_enforceNotEmpty();
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval is completely within this interval.
|
|
|
|
Always returns false (unless this interval is empty), because an
|
|
interval beginning at negative infinity can never be contained in a
|
|
finite interval.
|
|
|
|
Params:
|
|
interval = The interval to check for inclusion in this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if this interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(
|
|
NegInfInterval!Date(Date(1996, 5, 4))));
|
|
--------------------
|
|
+/
|
|
bool contains(in NegInfInterval!TP interval) const pure
|
|
{
|
|
_enforceNotEmpty();
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this interval is before the given time point.
|
|
|
|
Params:
|
|
timePoint = The time point to check whether this interval is before
|
|
it.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if this interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(
|
|
Date(1994, 12, 24)));
|
|
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(
|
|
Date(2000, 1, 5)));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(
|
|
Date(2012, 3, 1)));
|
|
--------------------
|
|
+/
|
|
bool isBefore(in TP timePoint) const pure
|
|
{
|
|
_enforceNotEmpty();
|
|
|
|
return _end <= timePoint;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this interval is before the given interval and does not
|
|
intersect with it.
|
|
|
|
Params:
|
|
interval = The interval to check for against this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if either interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(
|
|
Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
|
|
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(
|
|
Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(
|
|
Interval!Date(Date(2012, 3, 1), Date(2013, 5, 1))));
|
|
--------------------
|
|
+/
|
|
bool isBefore(in Interval interval) const pure
|
|
{
|
|
_enforceNotEmpty();
|
|
interval._enforceNotEmpty();
|
|
|
|
return _end <= interval._begin;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this interval is before the given interval and does not
|
|
intersect with it.
|
|
|
|
Params:
|
|
interval = The interval to check for against this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if this interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(
|
|
PosInfInterval!Date(Date(1999, 5, 4))));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(
|
|
PosInfInterval!Date(Date(2013, 3, 7))));
|
|
--------------------
|
|
+/
|
|
bool isBefore(in PosInfInterval!TP interval) const pure
|
|
{
|
|
_enforceNotEmpty();
|
|
|
|
return _end <= interval._begin;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this interval is before the given interval and does not
|
|
intersect with it.
|
|
|
|
Always returns false (unless this interval is empty) because a finite
|
|
interval can never be before an interval beginning at negative infinity.
|
|
|
|
Params:
|
|
interval = The interval to check for against this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if this interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(
|
|
NegInfInterval!Date(Date(1996, 5, 4))));
|
|
--------------------
|
|
+/
|
|
bool isBefore(in NegInfInterval!TP interval) const pure
|
|
{
|
|
_enforceNotEmpty();
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this interval is after the given time point.
|
|
|
|
Params:
|
|
timePoint = The time point to check whether this interval is after
|
|
it.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if this interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(
|
|
Date(1994, 12, 24)));
|
|
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(
|
|
Date(2000, 1, 5)));
|
|
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(
|
|
Date(2012, 3, 1)));
|
|
--------------------
|
|
+/
|
|
bool isAfter(in TP timePoint) const pure
|
|
{
|
|
_enforceNotEmpty();
|
|
|
|
return timePoint < _begin;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this interval is after the given interval and does not intersect
|
|
it.
|
|
|
|
Params:
|
|
interval = The interval to check against this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if either interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(
|
|
Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
|
|
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(
|
|
Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(
|
|
Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));
|
|
--------------------
|
|
+/
|
|
bool isAfter(in Interval interval) const pure
|
|
{
|
|
_enforceNotEmpty();
|
|
interval._enforceNotEmpty();
|
|
|
|
return _begin >= interval._end;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this interval is after the given interval and does not intersect
|
|
it.
|
|
|
|
Always returns false (unless this interval is empty) because a finite
|
|
interval can never be after an interval going to positive infinity.
|
|
|
|
Params:
|
|
interval = The interval to check against this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if this interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(
|
|
PosInfInterval!Date(Date(1999, 5, 4))));
|
|
--------------------
|
|
+/
|
|
bool isAfter(in PosInfInterval!TP interval) const pure
|
|
{
|
|
_enforceNotEmpty();
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this interval is after the given interval and does not intersect
|
|
it.
|
|
|
|
Params:
|
|
interval = The interval to check against this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if this interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(
|
|
NegInfInterval!Date(Date(1996, 1, 2))));
|
|
--------------------
|
|
+/
|
|
bool isAfter(in NegInfInterval!TP interval) const pure
|
|
{
|
|
_enforceNotEmpty();
|
|
|
|
return _begin >= interval._end;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval overlaps this interval.
|
|
|
|
Params:
|
|
interval = The interval to check for intersection with this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if either interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(
|
|
Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(
|
|
Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
|
|
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(
|
|
Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));
|
|
--------------------
|
|
+/
|
|
bool intersects(in Interval interval) const pure
|
|
{
|
|
_enforceNotEmpty();
|
|
interval._enforceNotEmpty();
|
|
|
|
return interval._begin < _end && interval._end > _begin;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval overlaps this interval.
|
|
|
|
Params:
|
|
interval = The interval to check for intersection with this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if this interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(
|
|
PosInfInterval!Date(Date(1999, 5, 4))));
|
|
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(
|
|
PosInfInterval!Date(Date(2012, 3, 1))));
|
|
--------------------
|
|
+/
|
|
bool intersects(in PosInfInterval!TP interval) const pure
|
|
{
|
|
_enforceNotEmpty();
|
|
|
|
return _end > interval._begin;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval overlaps this interval.
|
|
|
|
Params:
|
|
interval = The interval to check for intersection with this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if this interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(
|
|
NegInfInterval!Date(Date(1996, 1, 2))));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(
|
|
NegInfInterval!Date(Date(2000, 1, 2))));
|
|
--------------------
|
|
+/
|
|
bool intersects(in NegInfInterval!TP interval) const pure
|
|
{
|
|
_enforceNotEmpty();
|
|
|
|
return _begin < interval._end;
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the intersection of two intervals
|
|
|
|
Params:
|
|
interval = The interval to intersect with this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the two intervals do not intersect or if
|
|
either interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(
|
|
Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==
|
|
Interval!Date(Date(1996, 1 , 2), Date(2000, 8, 2)));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(
|
|
Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) ==
|
|
Interval!Date(Date(1999, 1 , 12), Date(2011, 9, 17)));
|
|
--------------------
|
|
+/
|
|
Interval intersection(in Interval interval) const
|
|
{
|
|
enforce(this.intersects(interval), new DateTimeException(format("%s and %s do not intersect.", this, interval)));
|
|
|
|
auto begin = _begin > interval._begin ? _begin : interval._begin;
|
|
auto end = _end < interval._end ? _end : interval._end;
|
|
|
|
return Interval(begin, end);
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the intersection of two intervals
|
|
|
|
Params:
|
|
interval = The interval to intersect with this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the two intervals do not intersect or if
|
|
this interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(
|
|
PosInfInterval!Date(Date(1990, 7, 6))) ==
|
|
Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1)));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(
|
|
PosInfInterval!Date(Date(1999, 1, 12))) ==
|
|
Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1)));
|
|
--------------------
|
|
+/
|
|
Interval intersection(in PosInfInterval!TP interval) const
|
|
{
|
|
enforce(this.intersects(interval), new DateTimeException(format("%s and %s do not intersect.", this, interval)));
|
|
|
|
return Interval(_begin > interval._begin ? _begin : interval._begin, _end);
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the intersection of two intervals
|
|
|
|
Params:
|
|
interval = The interval to intersect with this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the two intervals do not intersect or if
|
|
this interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(
|
|
NegInfInterval!Date(Date(1999, 7, 6))) ==
|
|
Interval!Date(Date(1996, 1 , 2), Date(1999, 7, 6)));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(
|
|
NegInfInterval!Date(Date(2013, 1, 12))) ==
|
|
Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1)));
|
|
--------------------
|
|
+/
|
|
Interval intersection(in NegInfInterval!TP interval) const
|
|
{
|
|
enforce(this.intersects(interval), new DateTimeException(format("%s and %s do not intersect.", this, interval)));
|
|
|
|
return Interval(_begin, _end < interval._end ? _end : interval._end);
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval is adjacent to this interval.
|
|
|
|
Params:
|
|
interval = The interval to check whether its adjecent to this
|
|
interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if either interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(
|
|
Interval!Date(Date(1990, 7, 6), Date(1996, 1, 2))));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(
|
|
Interval!Date(Date(2012, 3, 1), Date(2013, 9, 17))));
|
|
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(
|
|
Interval!Date(Date(1989, 3, 1), Date(2012, 3, 1))));
|
|
--------------------
|
|
+/
|
|
bool isAdjacent(in Interval interval) const pure
|
|
{
|
|
_enforceNotEmpty();
|
|
interval._enforceNotEmpty();
|
|
|
|
return _begin == interval._end || _end == interval._begin;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval is adjacent to this interval.
|
|
|
|
Params:
|
|
interval = The interval to check whether its adjecent to this
|
|
interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if this interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(
|
|
PosInfInterval!Date(Date(1999, 5, 4))));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(
|
|
PosInfInterval!Date(Date(2012, 3, 1))));
|
|
--------------------
|
|
+/
|
|
bool isAdjacent(in PosInfInterval!TP interval) const pure
|
|
{
|
|
_enforceNotEmpty();
|
|
|
|
return _end == interval._begin;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval is adjacent to this interval.
|
|
|
|
Params:
|
|
interval = The interval to check whether its adjecent to this
|
|
interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if this interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(
|
|
NegInfInterval!Date(Date(1996, 1, 2))));
|
|
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(
|
|
NegInfInterval!Date(Date(2000, 1, 2))));
|
|
--------------------
|
|
+/
|
|
bool isAdjacent(in NegInfInterval!TP interval) const pure
|
|
{
|
|
_enforceNotEmpty();
|
|
|
|
return _begin == interval._end;
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the union of two intervals
|
|
|
|
Params:
|
|
interval = The interval to merge with this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the two intervals do not intersect and are
|
|
not adjacent or if either interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(
|
|
Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==
|
|
Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1)));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(
|
|
Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) ==
|
|
Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7)));
|
|
--------------------
|
|
+/
|
|
Interval merge(in Interval interval) const
|
|
{
|
|
enforce(this.isAdjacent(interval) || this.intersects(interval),
|
|
new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval)));
|
|
|
|
auto begin = _begin < interval._begin ? _begin : interval._begin;
|
|
auto end = _end > interval._end ? _end : interval._end;
|
|
|
|
return Interval(begin, end);
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the union of two intervals
|
|
|
|
Params:
|
|
interval = The interval to merge with this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the two intervals do not intersect and are
|
|
not adjacent or if this interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(
|
|
PosInfInterval!Date(Date(1990, 7, 6))) ==
|
|
PosInfInterval!Date(Date(1990, 7 , 6)));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(
|
|
PosInfInterval!Date(Date(2012, 3, 1))) ==
|
|
PosInfInterval!Date(Date(1996, 1 , 2)));
|
|
--------------------
|
|
+/
|
|
PosInfInterval!TP merge(in PosInfInterval!TP interval) const
|
|
{
|
|
enforce(this.isAdjacent(interval) || this.intersects(interval),
|
|
new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval)));
|
|
|
|
return PosInfInterval!TP(_begin < interval._begin ? _begin : interval._begin);
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the union of two intervals
|
|
|
|
Params:
|
|
interval = The interval to merge with this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the two intervals do not intersect and are not
|
|
adjacent or if this interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(
|
|
NegInfInterval!Date(Date(1996, 1, 2))) ==
|
|
NegInfInterval!Date(Date(2012, 3 , 1)));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(
|
|
NegInfInterval!Date(Date(2013, 1, 12))) ==
|
|
NegInfInterval!Date(Date(2013, 1 , 12)));
|
|
--------------------
|
|
+/
|
|
NegInfInterval!TP merge(in NegInfInterval!TP interval) const
|
|
{
|
|
enforce(this.isAdjacent(interval) || this.intersects(interval),
|
|
new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval)));
|
|
|
|
return NegInfInterval!TP(_end > interval._end ? _end : interval._end);
|
|
}
|
|
|
|
|
|
/++
|
|
Returns an interval that covers from the earliest time point of two
|
|
intervals up to (but not including) the latest time point of two
|
|
intervals.
|
|
|
|
Params:
|
|
interval = The interval to create a span together with this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if either interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(
|
|
Interval!Date(Date(1990, 7, 6), Date(1991, 1, 8))) ==
|
|
Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1)));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(
|
|
Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) ==
|
|
Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7)));
|
|
--------------------
|
|
+/
|
|
Interval span(in Interval interval) const pure
|
|
{
|
|
_enforceNotEmpty();
|
|
interval._enforceNotEmpty();
|
|
|
|
auto begin = _begin < interval._begin ? _begin : interval._begin;
|
|
auto end = _end > interval._end ? _end : interval._end;
|
|
|
|
return Interval(begin, end);
|
|
}
|
|
|
|
|
|
/++
|
|
Returns an interval that covers from the earliest time point of two
|
|
intervals up to (but not including) the latest time point of two
|
|
intervals.
|
|
|
|
Params:
|
|
interval = The interval to create a span together with this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if this interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(
|
|
PosInfInterval!Date(Date(1990, 7, 6))) ==
|
|
PosInfInterval!Date(Date(1990, 7 , 6)));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(
|
|
PosInfInterval!Date(Date(2050, 1, 1))) ==
|
|
PosInfInterval!Date(Date(1996, 1 , 2)));
|
|
--------------------
|
|
+/
|
|
PosInfInterval!TP span(in PosInfInterval!TP interval) const pure
|
|
{
|
|
_enforceNotEmpty();
|
|
|
|
return PosInfInterval!TP(_begin < interval._begin ? _begin : interval._begin);
|
|
}
|
|
|
|
|
|
/++
|
|
Returns an interval that covers from the earliest time point of two
|
|
intervals up to (but not including) the latest time point of two
|
|
intervals.
|
|
|
|
Params:
|
|
interval = The interval to create a span together with this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if this interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(
|
|
NegInfInterval!Date(Date(1602, 5, 21))) ==
|
|
NegInfInterval!Date(Date(2012, 3 , 1)));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(
|
|
NegInfInterval!Date(Date(2013, 1, 12))) ==
|
|
NegInfInterval!Date(Date(2013, 1 , 12)));
|
|
--------------------
|
|
+/
|
|
NegInfInterval!TP span(in NegInfInterval!TP interval) const pure
|
|
{
|
|
_enforceNotEmpty();
|
|
|
|
return NegInfInterval!TP(_end > interval._end ? _end : interval._end);
|
|
}
|
|
|
|
|
|
/++
|
|
Shifts the interval forward or backwards in time by the given duration
|
|
(a positive duration shifts the interval forward; a negative duration
|
|
shifts it backward). Effectively, it does $(D begin += duration) and
|
|
$(D end += duration).
|
|
|
|
Params:
|
|
duration = The duration to shift the interval by.
|
|
|
|
Throws:
|
|
$(D DateTimeException) this interval is empty or if the resulting
|
|
interval would be invalid.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5));
|
|
auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5));
|
|
|
|
interval1.shift(dur!"days"(50));
|
|
assert(interval1 == Interval!Date(Date(1996, 2, 21), Date(2012, 5, 25)));
|
|
|
|
interval2.shift(dur!"days"(-50));
|
|
assert(interval2 == Interval!Date(Date(1995, 11, 13), Date(2012, 2, 15)));
|
|
--------------------
|
|
+/
|
|
void shift(D)(D duration) pure
|
|
if(__traits(compiles, begin + duration))
|
|
{
|
|
_enforceNotEmpty();
|
|
|
|
auto begin = _begin + duration;
|
|
auto end = _end + duration;
|
|
|
|
if(!_valid(begin, end))
|
|
throw new DateTimeException("Argument would result in an invalid Interval.");
|
|
|
|
_begin = begin;
|
|
_end = end;
|
|
}
|
|
|
|
|
|
static if(__traits(compiles, begin.add!"months"(1)) &&
|
|
__traits(compiles, begin.add!"years"(1)))
|
|
{
|
|
/++
|
|
Shifts the interval forward or backwards in time by the given number
|
|
of years and/or months (a positive number of years and months shifts
|
|
the interval forward; a negative number shifts it backward).
|
|
It adds the years the given years and months to both begin and end.
|
|
It effectively calls $(D add!"years"()) and then $(D add!"months"())
|
|
on begin and end with the given number of years and months.
|
|
|
|
Params:
|
|
years = The number of years to shift the interval by.
|
|
months = The number of months to shift the interval by.
|
|
allowOverflow = Whether the days should be allowed to overflow
|
|
on $(D begin) and $(D end), causing their month
|
|
to increment.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if this interval is empty or if the
|
|
resulting interval would be invalid.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
|
|
auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
|
|
|
|
interval1.shift(2);
|
|
assert(interval1 == Interval!Date(Date(1998, 1, 2), Date(2014, 3, 1)));
|
|
|
|
interval2.shift(-2);
|
|
assert(interval2 == Interval!Date(Date(1994, 1, 2), Date(2010, 3, 1)));
|
|
--------------------
|
|
+/
|
|
void shift(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes)
|
|
if(isIntegral!T)
|
|
{
|
|
_enforceNotEmpty();
|
|
|
|
auto begin = _begin;
|
|
auto end = _end;
|
|
|
|
begin.add!"years"(years, allowOverflow);
|
|
begin.add!"months"(months, allowOverflow);
|
|
end.add!"years"(years, allowOverflow);
|
|
end.add!"months"(months, allowOverflow);
|
|
|
|
enforce(_valid(begin, end), new DateTimeException("Argument would result in an invalid Interval."));
|
|
|
|
_begin = begin;
|
|
_end = end;
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Expands the interval forwards and/or backwards in time. Effectively,
|
|
it does $(D begin -= duration) and/or $(D end += duration). Whether
|
|
it expands forwards and/or backwards in time is determined by
|
|
$(D_PARAM dir).
|
|
|
|
Params:
|
|
duration = The duration to expand the interval by.
|
|
dir = The direction in time to expand the interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) this interval is empty or if the resulting
|
|
interval would be invalid.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
|
|
auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
|
|
|
|
interval1.expand(2);
|
|
assert(interval1 == Interval!Date(Date(1994, 1, 2), Date(2014, 3, 1)));
|
|
|
|
interval2.expand(-2);
|
|
assert(interval2 == Interval!Date(Date(1998, 1, 2), Date(2010, 3, 1)));
|
|
--------------------
|
|
+/
|
|
void expand(D)(D duration, Direction dir = Direction.both) pure
|
|
if(__traits(compiles, begin + duration))
|
|
{
|
|
_enforceNotEmpty();
|
|
|
|
switch(dir)
|
|
{
|
|
case Direction.both:
|
|
{
|
|
auto begin = _begin - duration;
|
|
auto end = _end + duration;
|
|
|
|
if(!_valid(begin, end))
|
|
throw new DateTimeException("Argument would result in an invalid Interval.");
|
|
|
|
_begin = begin;
|
|
_end = end;
|
|
|
|
return;
|
|
}
|
|
case Direction.fwd:
|
|
{
|
|
auto end = _end + duration;
|
|
|
|
if(!_valid(_begin, end))
|
|
throw new DateTimeException("Argument would result in an invalid Interval.");
|
|
_end = end;
|
|
|
|
return;
|
|
}
|
|
case Direction.bwd:
|
|
{
|
|
auto begin = _begin - duration;
|
|
|
|
if(!_valid(begin, _end))
|
|
throw new DateTimeException("Argument would result in an invalid Interval.");
|
|
_begin = begin;
|
|
|
|
return;
|
|
}
|
|
default:
|
|
assert(0, "Invalid Direction.");
|
|
}
|
|
}
|
|
|
|
static if(__traits(compiles, begin.add!"months"(1)) &&
|
|
__traits(compiles, begin.add!"years"(1)))
|
|
{
|
|
/++
|
|
Expands the interval forwards and/or backwards in time. Effectively,
|
|
it subtracts the given number of months/years from $(D begin) and
|
|
adds them to $(D end). Whether it expands forwards and/or backwards
|
|
in time is determined by $(D_PARAM dir).
|
|
|
|
Params:
|
|
years = The number of years to expand the interval by.
|
|
months = The number of months to expand the interval by.
|
|
allowOverflow = Whether the days should be allowed to overflow
|
|
on $(D begin) and $(D end), causing their month
|
|
to increment.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if this interval is empty or if the
|
|
resulting interval would be invalid.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
|
|
auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
|
|
|
|
interval1.expand(2);
|
|
assert(interval1 == Interval!Date(Date(1994, 1, 2), Date(2014, 3, 1)));
|
|
|
|
interval2.expand(-2);
|
|
assert(interval2 == Interval!Date(Date(1998, 1, 2), Date(2010, 3, 1)));
|
|
--------------------
|
|
+/
|
|
void expand(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes, Direction dir = Direction.both)
|
|
if(isIntegral!T)
|
|
{
|
|
_enforceNotEmpty();
|
|
|
|
switch(dir)
|
|
{
|
|
case Direction.both:
|
|
{
|
|
auto begin = _begin;
|
|
auto end = _end;
|
|
|
|
begin.add!"years"(-years, allowOverflow);
|
|
begin.add!"months"(-months, allowOverflow);
|
|
end.add!"years"(years, allowOverflow);
|
|
end.add!"months"(months, allowOverflow);
|
|
|
|
enforce(_valid(begin, end), new DateTimeException("Argument would result in an invalid Interval."));
|
|
_begin = begin;
|
|
_end = end;
|
|
|
|
return;
|
|
}
|
|
case Direction.fwd:
|
|
{
|
|
auto end = _end;
|
|
|
|
end.add!"years"(years, allowOverflow);
|
|
end.add!"months"(months, allowOverflow);
|
|
|
|
enforce(_valid(_begin, end), new DateTimeException("Argument would result in an invalid Interval."));
|
|
_end = end;
|
|
|
|
return;
|
|
}
|
|
case Direction.bwd:
|
|
{
|
|
auto begin = _begin;
|
|
|
|
begin.add!"years"(-years, allowOverflow);
|
|
begin.add!"months"(-months, allowOverflow);
|
|
|
|
enforce(_valid(begin, _end), new DateTimeException("Argument would result in an invalid Interval."));
|
|
_begin = begin;
|
|
|
|
return;
|
|
}
|
|
default:
|
|
assert(0, "Invalid Direction.");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns a range which iterates forward over the interval, starting
|
|
at $(D begin), using $(D_PARAM func) to generate each successive time
|
|
point.
|
|
|
|
The range's $(D front) is the interval's $(D begin). $(D_PARAM func) is
|
|
used to generate the next $(D front) when $(D popFront) is called. If
|
|
$(D_PARAM popFirst) is $(D PopFirst.yes), then $(D popFront) is called
|
|
before the range is returned (so that $(D front) is a time point which
|
|
$(D_PARAM func) would generate).
|
|
|
|
If $(D_PARAM func) ever generates a time point less than or equal to the
|
|
current $(D front) of the range, then a $(D DateTimeException) will be
|
|
thrown. The range will be empty and iteration complete when
|
|
$(D_PARAM func) generates a time point equal to or beyond the $(D end)
|
|
of the interval.
|
|
|
|
There are helper functions in this module which generate common
|
|
delegates to pass to $(D fwdRange). Their documentation starts with
|
|
"Range-generating function," so you can easily search for them.
|
|
|
|
Params:
|
|
func = The function used to generate the time points of the
|
|
range over the interval.
|
|
popFirst = Whether $(D popFront) should be called on the range
|
|
before returning it.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if this interval is empty.
|
|
|
|
Warning:
|
|
$(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func)
|
|
would be a function pointer to a pure function, but forcing
|
|
$(D_PARAM func) to be pure is far too restrictive to be useful, and
|
|
in order to have the ease of use of having functions which generate
|
|
functions to pass to $(D fwdRange), $(D_PARAM func) must be a
|
|
delegate.
|
|
|
|
If $(D_PARAM func) retains state which changes as it is called, then
|
|
some algorithms will not work correctly, because the range's
|
|
$(D save) will have failed to have really saved the range's state.
|
|
So, if you want to avoid such bugs, don't pass a delegate which is
|
|
not logically pure to $(D fwdRange). If $(D_PARAM func) is given the
|
|
same time point with two different calls, it must return the same
|
|
result both times.
|
|
|
|
Of course, none of the functions in this module have this problem,
|
|
so it's only relevant if you're creating your own delegate.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9));
|
|
auto func = (in Date date) //For iterating over even-numbered days.
|
|
{
|
|
if((date.day & 1) == 0)
|
|
return date + dur!"days"(2);
|
|
|
|
return date + dur!"days"(1);
|
|
};
|
|
auto range = interval.fwdRange(func);
|
|
|
|
//An odd day. Using PopFirst.yes would have made this Date(2010, 9, 2).
|
|
assert(range.front == Date(2010, 9, 1));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 2));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 4));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 6));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 8));
|
|
|
|
range.popFront();
|
|
assert(range.empty);
|
|
--------------------
|
|
+/
|
|
IntervalRange!(TP, Direction.fwd) fwdRange(TP delegate(in TP) func, PopFirst popFirst = PopFirst.no) const
|
|
{
|
|
_enforceNotEmpty();
|
|
|
|
auto range = IntervalRange!(TP, Direction.fwd)(this, func);
|
|
|
|
if(popFirst == PopFirst.yes)
|
|
range.popFront();
|
|
|
|
return range;
|
|
}
|
|
|
|
|
|
/++
|
|
Returns a range which iterates backwards over the interval, starting
|
|
at $(D end), using $(D_PARAM func) to generate each successive time
|
|
point.
|
|
|
|
The range's $(D front) is the interval's $(D end). $(D_PARAM func) is
|
|
used to generate the next $(D front) when $(D popFront) is called. If
|
|
$(D_PARAM popFirst) is $(D PopFirst.yes), then $(D popFront) is called
|
|
before the range is returned (so that $(D front) is a time point which
|
|
$(D_PARAM func) would generate).
|
|
|
|
If $(D_PARAM func) ever generates a time point greater than or equal to
|
|
the current $(D front) of the range, then a $(D DateTimeException) will
|
|
be thrown. The range will be empty and iteration complete when
|
|
$(D_PARAM func) generates a time point equal to or less than the
|
|
$(D begin) of the interval.
|
|
|
|
There are helper functions in this module which generate common
|
|
delegates to pass to $(D bwdRange). Their documentation starts with
|
|
"Range-generating function," so you can easily search for them.
|
|
|
|
Params:
|
|
func = The function used to generate the time points of the
|
|
range over the interval.
|
|
popFirst = Whether $(D popFront) should be called on the range
|
|
before returning it.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if this interval is empty.
|
|
|
|
Warning:
|
|
$(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func)
|
|
would be a function pointer to a pure function, but forcing
|
|
$(D_PARAM func) to be pure is far too restrictive to be useful, and
|
|
in order to have the ease of use of having functions which generate
|
|
functions to pass to $(D fwdRange), $(D_PARAM func) must be a
|
|
delegate.
|
|
|
|
If $(D_PARAM func) retains state which changes as it is called, then
|
|
some algorithms will not work correctly, because the range's
|
|
$(D save) will have failed to have really saved the range's state.
|
|
So, if you want to avoid such bugs, don't pass a delegate which is
|
|
not logically pure to $(D fwdRange). If $(D_PARAM func) is given the
|
|
same time point with two different calls, it must return the same
|
|
result both times.
|
|
|
|
Of course, none of the functions in this module have this problem,
|
|
so it's only relevant if you're creating your own delegate.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9));
|
|
auto func = (in Date date) //For iterating over even-numbered days.
|
|
{
|
|
if((date.day & 1) == 0)
|
|
return date - dur!"days"(2);
|
|
|
|
return date - dur!"days"(1);
|
|
};
|
|
auto range = interval.bwdRange(func);
|
|
|
|
//An odd day. Using PopFirst.yes would have made this Date(2010, 9, 8).
|
|
assert(range.front == Date(2010, 9, 9));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 8));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 6));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 4));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 2));
|
|
|
|
range.popFront();
|
|
assert(range.empty);
|
|
--------------------
|
|
+/
|
|
IntervalRange!(TP, Direction.bwd) bwdRange(TP delegate(in TP) func, PopFirst popFirst = PopFirst.no) const
|
|
{
|
|
_enforceNotEmpty();
|
|
|
|
auto range = IntervalRange!(TP, Direction.bwd)(this, func);
|
|
|
|
if(popFirst == PopFirst.yes)
|
|
range.popFront();
|
|
|
|
return range;
|
|
}
|
|
|
|
|
|
/+
|
|
Converts this interval to a string.
|
|
+/
|
|
//Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't
|
|
//have versions of toString() with extra modifiers, so we define one version
|
|
//with modifiers and one without.
|
|
string toString()
|
|
{
|
|
return _toStringImpl();
|
|
}
|
|
|
|
|
|
/++
|
|
Converts this interval to a string.
|
|
+/
|
|
//Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't
|
|
//have versions of toString() with extra modifiers, so we define one version
|
|
//with modifiers and one without.
|
|
string toString() const nothrow
|
|
{
|
|
return _toStringImpl();
|
|
}
|
|
|
|
|
|
private:
|
|
|
|
/+
|
|
Since we have two versions of toString, we have _toStringImpl
|
|
so that they can share implementations.
|
|
+/
|
|
string _toStringImpl() const nothrow
|
|
{
|
|
try
|
|
return format("[%s - %s)", _begin, _end);
|
|
catch(Exception e)
|
|
assert(0, "format() threw.");
|
|
}
|
|
|
|
|
|
/+
|
|
Throws:
|
|
$(D DateTimeException) if this interval is empty.
|
|
+/
|
|
void _enforceNotEmpty(size_t line = __LINE__) const pure
|
|
{
|
|
if(empty)
|
|
throw new DateTimeException("Invalid operation for an empty Interval.", __FILE__, line);
|
|
}
|
|
|
|
|
|
/+
|
|
Whether the given values form a valid time interval.
|
|
|
|
Params:
|
|
begin = The starting point of the interval.
|
|
end = The end point of the interval.
|
|
+/
|
|
static bool _valid(in TP begin, in TP end) pure nothrow
|
|
{
|
|
return begin <= end;
|
|
}
|
|
|
|
|
|
pure invariant()
|
|
{
|
|
assert(_valid(_begin, _end), "Invariant Failure: begin is not before or equal to end.");
|
|
}
|
|
|
|
|
|
TP _begin;
|
|
TP _end;
|
|
}
|
|
|
|
//Test Interval's constructors.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assertThrown!DateTimeException(Interval!Date(Date(2010, 1, 1), Date(1, 1, 1)));
|
|
|
|
Interval!Date(Date.init, Date.init);
|
|
Interval!TimeOfDay(TimeOfDay.init, TimeOfDay.init);
|
|
Interval!DateTime(DateTime.init, DateTime.init);
|
|
Interval!SysTime(SysTime(0), SysTime(0));
|
|
|
|
Interval!DateTime(DateTime.init, dur!"days"(7));
|
|
|
|
//Verify Examples.
|
|
Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
|
|
assert(Interval!Date(Date(1996, 1, 2), dur!"weeks"(3)) == Interval!Date(Date(1996, 1, 2), Date(1996, 1, 23)));
|
|
assert(Interval!Date(Date(1996, 1, 2), dur!"days"(3)) == Interval!Date(Date(1996, 1, 2), Date(1996, 1, 5)));
|
|
assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"hours"(3)) == Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 15, 0, 0)));
|
|
assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"minutes"(3)) == Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 12, 3, 0)));
|
|
assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"seconds"(3)) == Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 12, 0, 3)));
|
|
assert(Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), dur!"msecs"(3000)) == Interval!DateTime(DateTime(1996, 1, 2, 12, 0, 0), DateTime(1996, 1, 2, 12, 0, 3)));
|
|
}
|
|
}
|
|
|
|
//Test Interval's begin.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(Interval!Date(Date(1, 1, 1), Date(2010, 1, 1)).begin, Date(1, 1, 1));
|
|
_assertPred!"=="(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).begin, Date(2010, 1, 1));
|
|
_assertPred!"=="(Interval!Date(Date(1997, 12, 31), Date(1998, 1, 1)).begin, Date(1997, 12, 31));
|
|
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
static assert(__traits(compiles, cInterval.begin));
|
|
static assert(__traits(compiles, iInterval.begin));
|
|
|
|
//Verify Examples.
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).begin == Date(1996, 1, 2));
|
|
}
|
|
}
|
|
|
|
//Test Interval's end.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(Interval!Date(Date(1, 1, 1), Date(2010, 1, 1)).end, Date(2010, 1, 1));
|
|
_assertPred!"=="(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).end, Date(2010, 1, 1));
|
|
_assertPred!"=="(Interval!Date(Date(1997, 12, 31), Date(1998, 1, 1)).end, Date(1998, 1, 1));
|
|
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
static assert(__traits(compiles, cInterval.end));
|
|
static assert(__traits(compiles, iInterval.end));
|
|
|
|
//Verify Examples.
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).end == Date(2012, 3, 1));
|
|
}
|
|
}
|
|
|
|
//Test Interval's length.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).length, dur!"days"(0));
|
|
_assertPred!"=="(Interval!Date(Date(2010, 1, 1), Date(2010, 4, 1)).length, dur!"days"(90));
|
|
_assertPred!"=="(Interval!TimeOfDay(TimeOfDay(0, 30, 0), TimeOfDay(12, 22, 7)).length, dur!"seconds"(42_727));
|
|
_assertPred!"=="(Interval!DateTime(DateTime(2010, 1, 1, 0, 30, 0), DateTime(2010, 1, 2, 12, 22, 7)).length, dur!"seconds"(129_127));
|
|
_assertPred!"=="(Interval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0)), SysTime(DateTime(2010, 1, 2, 12, 22, 7))).length, dur!"seconds"(129_127));
|
|
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
static assert(__traits(compiles, cInterval.length));
|
|
static assert(__traits(compiles, iInterval.length));
|
|
|
|
//Verify Examples.
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).length == dur!"days"(5903));
|
|
}
|
|
}
|
|
|
|
//Test Interval's empty.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assert(Interval!Date(Date(2010, 1, 1), Date(2010, 1, 1)).empty);
|
|
assert(!Interval!Date(Date(2010, 1, 1), Date(2010, 4, 1)).empty);
|
|
assert(!Interval!TimeOfDay(TimeOfDay(0, 30, 0), TimeOfDay(12, 22, 7)).empty);
|
|
assert(!Interval!DateTime(DateTime(2010, 1, 1, 0, 30, 0), DateTime(2010, 1, 2, 12, 22, 7)).empty);
|
|
assert(!Interval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0)), SysTime(DateTime(2010, 1, 2, 12, 22, 7))).empty);
|
|
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
static assert(__traits(compiles, cInterval.empty));
|
|
static assert(__traits(compiles, iInterval.empty));
|
|
|
|
//Verify Examples.
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(1996, 1, 2)).empty);
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).empty);
|
|
}
|
|
}
|
|
|
|
//Test Interval's contains(time point).
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
|
|
assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).contains(Date(2010, 7, 4)));
|
|
|
|
assert(!interval.contains(Date(2009, 7, 4)));
|
|
assert(!interval.contains(Date(2010, 7, 3)));
|
|
assert(interval.contains(Date(2010, 7, 4)));
|
|
assert(interval.contains(Date(2010, 7, 5)));
|
|
assert(interval.contains(Date(2011, 7, 1)));
|
|
assert(interval.contains(Date(2012, 1, 6)));
|
|
assert(!interval.contains(Date(2012, 1, 7)));
|
|
assert(!interval.contains(Date(2012, 1, 8)));
|
|
assert(!interval.contains(Date(2013, 1, 7)));
|
|
|
|
const cdate = Date(2010, 7, 6);
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
static assert(__traits(compiles, interval.contains(cdate)));
|
|
static assert(__traits(compiles, cInterval.contains(cdate)));
|
|
static assert(__traits(compiles, iInterval.contains(cdate)));
|
|
|
|
//Verify Examples.
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Date(1994, 12, 24)));
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Date(2000, 1, 5)));
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Date(2012, 3, 1)));
|
|
}
|
|
}
|
|
|
|
//Test Interval's contains(Interval).
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
|
|
assertThrown!DateTimeException(interval.contains(Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).contains(interval));
|
|
assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).contains(Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
|
|
assert(interval.contains(interval));
|
|
assert(!interval.contains(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
|
|
assert(!interval.contains(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
|
|
assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
|
|
assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
|
|
assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
|
|
assert(!interval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
|
|
assert(interval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
|
|
assert(interval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
|
|
assert(interval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
|
|
assert(!interval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
|
|
assert(!interval.contains(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
|
|
assert(!interval.contains(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
|
|
|
|
assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).contains(interval));
|
|
assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).contains(interval));
|
|
assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).contains(interval));
|
|
assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).contains(interval));
|
|
assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).contains(interval));
|
|
assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).contains(interval));
|
|
assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).contains(interval));
|
|
assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).contains(interval));
|
|
assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).contains(interval));
|
|
assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).contains(interval));
|
|
assert(!Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).contains(interval));
|
|
assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).contains(interval));
|
|
|
|
assert(!interval.contains(PosInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(!interval.contains(PosInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(!interval.contains(PosInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(!interval.contains(PosInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(!interval.contains(PosInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(!interval.contains(PosInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
assert(!interval.contains(NegInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(!interval.contains(NegInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(!interval.contains(NegInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(!interval.contains(NegInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(!interval.contains(NegInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(!interval.contains(NegInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, interval.contains(interval)));
|
|
static assert(__traits(compiles, interval.contains(cInterval)));
|
|
static assert(__traits(compiles, interval.contains(iInterval)));
|
|
static assert(__traits(compiles, interval.contains(posInfInterval)));
|
|
static assert(__traits(compiles, interval.contains(cPosInfInterval)));
|
|
static assert(__traits(compiles, interval.contains(iPosInfInterval)));
|
|
static assert(__traits(compiles, interval.contains(negInfInterval)));
|
|
static assert(__traits(compiles, interval.contains(cNegInfInterval)));
|
|
static assert(__traits(compiles, interval.contains(iNegInfInterval)));
|
|
static assert(__traits(compiles, cInterval.contains(interval)));
|
|
static assert(__traits(compiles, cInterval.contains(cInterval)));
|
|
static assert(__traits(compiles, cInterval.contains(iInterval)));
|
|
static assert(__traits(compiles, cInterval.contains(posInfInterval)));
|
|
static assert(__traits(compiles, cInterval.contains(cPosInfInterval)));
|
|
static assert(__traits(compiles, cInterval.contains(iPosInfInterval)));
|
|
static assert(__traits(compiles, cInterval.contains(negInfInterval)));
|
|
static assert(__traits(compiles, cInterval.contains(cNegInfInterval)));
|
|
static assert(__traits(compiles, cInterval.contains(iNegInfInterval)));
|
|
static assert(__traits(compiles, iInterval.contains(interval)));
|
|
static assert(__traits(compiles, iInterval.contains(cInterval)));
|
|
static assert(__traits(compiles, iInterval.contains(iInterval)));
|
|
static assert(__traits(compiles, iInterval.contains(posInfInterval)));
|
|
static assert(__traits(compiles, iInterval.contains(cPosInfInterval)));
|
|
static assert(__traits(compiles, iInterval.contains(iPosInfInterval)));
|
|
static assert(__traits(compiles, iInterval.contains(negInfInterval)));
|
|
static assert(__traits(compiles, iInterval.contains(cNegInfInterval)));
|
|
static assert(__traits(compiles, iInterval.contains(iNegInfInterval)));
|
|
|
|
//Verify Examples.
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1))));
|
|
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(PosInfInterval!Date(Date(1999, 5, 4))));
|
|
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).contains(NegInfInterval!Date(Date(1996, 5, 4))));
|
|
}
|
|
}
|
|
|
|
//Test Interval's isBefore(time point).
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
|
|
assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isBefore(Date(2010, 7, 4)));
|
|
|
|
assert(!interval.isBefore(Date(2009, 7, 3)));
|
|
assert(!interval.isBefore(Date(2010, 7, 3)));
|
|
assert(!interval.isBefore(Date(2010, 7, 4)));
|
|
assert(!interval.isBefore(Date(2010, 7, 5)));
|
|
assert(!interval.isBefore(Date(2011, 7, 1)));
|
|
assert(!interval.isBefore(Date(2012, 1, 6)));
|
|
assert(interval.isBefore(Date(2012, 1, 7)));
|
|
assert(interval.isBefore(Date(2012, 1, 8)));
|
|
assert(interval.isBefore(Date(2013, 1, 7)));
|
|
|
|
const cdate = Date(2010, 7, 6);
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
static assert(__traits(compiles, interval.isBefore(cdate)));
|
|
static assert(__traits(compiles, cInterval.isBefore(cdate)));
|
|
static assert(__traits(compiles, iInterval.isBefore(cdate)));
|
|
|
|
//Verify Examples.
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Date(1994, 12, 24)));
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Date(2000, 1, 5)));
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Date(2012, 3, 1)));
|
|
}
|
|
}
|
|
|
|
//Test Interval's isBefore(Interval).
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
|
|
assertThrown!DateTimeException(interval.isBefore(Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isBefore(interval));
|
|
assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isBefore(Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
|
|
assert(!interval.isBefore(interval));
|
|
assert(!interval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
|
|
assert(!interval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
|
|
assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
|
|
assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
|
|
assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
|
|
assert(!interval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
|
|
assert(!interval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
|
|
assert(!interval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
|
|
assert(!interval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
|
|
assert(!interval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
|
|
assert(interval.isBefore(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
|
|
assert(interval.isBefore(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
|
|
|
|
assert(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).isBefore(interval));
|
|
assert(!Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).isBefore(interval));
|
|
assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).isBefore(interval));
|
|
assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).isBefore(interval));
|
|
assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).isBefore(interval));
|
|
assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).isBefore(interval));
|
|
assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).isBefore(interval));
|
|
assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).isBefore(interval));
|
|
assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).isBefore(interval));
|
|
assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).isBefore(interval));
|
|
assert(!Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).isBefore(interval));
|
|
assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).isBefore(interval));
|
|
|
|
assert(!interval.isBefore(PosInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(!interval.isBefore(PosInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(!interval.isBefore(PosInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(!interval.isBefore(PosInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(interval.isBefore(PosInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(interval.isBefore(PosInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
assert(!interval.isBefore(NegInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(!interval.isBefore(NegInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(!interval.isBefore(NegInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(!interval.isBefore(NegInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(!interval.isBefore(NegInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(!interval.isBefore(NegInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, interval.isBefore(interval)));
|
|
static assert(__traits(compiles, interval.isBefore(cInterval)));
|
|
static assert(__traits(compiles, interval.isBefore(iInterval)));
|
|
static assert(__traits(compiles, interval.isBefore(posInfInterval)));
|
|
static assert(__traits(compiles, interval.isBefore(cPosInfInterval)));
|
|
static assert(__traits(compiles, interval.isBefore(iPosInfInterval)));
|
|
static assert(__traits(compiles, interval.isBefore(negInfInterval)));
|
|
static assert(__traits(compiles, interval.isBefore(cNegInfInterval)));
|
|
static assert(__traits(compiles, interval.isBefore(iNegInfInterval)));
|
|
static assert(__traits(compiles, cInterval.isBefore(interval)));
|
|
static assert(__traits(compiles, cInterval.isBefore(cInterval)));
|
|
static assert(__traits(compiles, cInterval.isBefore(iInterval)));
|
|
static assert(__traits(compiles, cInterval.isBefore(posInfInterval)));
|
|
static assert(__traits(compiles, cInterval.isBefore(cPosInfInterval)));
|
|
static assert(__traits(compiles, cInterval.isBefore(iPosInfInterval)));
|
|
static assert(__traits(compiles, cInterval.isBefore(negInfInterval)));
|
|
static assert(__traits(compiles, cInterval.isBefore(cNegInfInterval)));
|
|
static assert(__traits(compiles, cInterval.isBefore(iNegInfInterval)));
|
|
static assert(__traits(compiles, iInterval.isBefore(interval)));
|
|
static assert(__traits(compiles, iInterval.isBefore(cInterval)));
|
|
static assert(__traits(compiles, iInterval.isBefore(iInterval)));
|
|
static assert(__traits(compiles, iInterval.isBefore(posInfInterval)));
|
|
static assert(__traits(compiles, iInterval.isBefore(cPosInfInterval)));
|
|
static assert(__traits(compiles, iInterval.isBefore(iPosInfInterval)));
|
|
static assert(__traits(compiles, iInterval.isBefore(negInfInterval)));
|
|
static assert(__traits(compiles, iInterval.isBefore(cNegInfInterval)));
|
|
static assert(__traits(compiles, iInterval.isBefore(iNegInfInterval)));
|
|
|
|
//Verify Examples.
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(Interval!Date(Date(2012, 3, 1), Date(2013, 5, 1))));
|
|
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(1999, 5, 4))));
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(2013, 3, 7))));
|
|
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isBefore(NegInfInterval!Date(Date(1996, 5, 4))));
|
|
}
|
|
}
|
|
|
|
//Test Interval's isAfter(time point).
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
|
|
assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isAfter(Date(2010, 7, 4)));
|
|
|
|
assert(interval.isAfter(Date(2009, 7, 4)));
|
|
assert(interval.isAfter(Date(2010, 7, 3)));
|
|
assert(!interval.isAfter(Date(2010, 7, 4)));
|
|
assert(!interval.isAfter(Date(2010, 7, 5)));
|
|
assert(!interval.isAfter(Date(2011, 7, 1)));
|
|
assert(!interval.isAfter(Date(2012, 1, 6)));
|
|
assert(!interval.isAfter(Date(2012, 1, 7)));
|
|
assert(!interval.isAfter(Date(2012, 1, 8)));
|
|
assert(!interval.isAfter(Date(2013, 1, 7)));
|
|
|
|
const cdate = Date(2010, 7, 6);
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
static assert(__traits(compiles, interval.isAfter(cdate)));
|
|
static assert(__traits(compiles, cInterval.isAfter(cdate)));
|
|
static assert(__traits(compiles, iInterval.isAfter(cdate)));
|
|
|
|
//Verify Examples.
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Date(1994, 12, 24)));
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Date(2000, 1, 5)));
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Date(2012, 3, 1)));
|
|
}
|
|
}
|
|
|
|
//Test Interval's isAfter(Interval).
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
|
|
assertThrown!DateTimeException(interval.isAfter(Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isAfter(interval));
|
|
assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).isAfter(Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
|
|
assert(!interval.isAfter(interval));
|
|
assert(interval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
|
|
assert(!interval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
|
|
assert(interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
|
|
assert(!interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
|
|
assert(!interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
|
|
assert(!interval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
|
|
assert(!interval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
|
|
assert(!interval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
|
|
assert(!interval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
|
|
assert(!interval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
|
|
assert(!interval.isAfter(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
|
|
assert(!interval.isAfter(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
|
|
|
|
assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).isAfter(interval));
|
|
assert(!Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).isAfter(interval));
|
|
assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).isAfter(interval));
|
|
assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).isAfter(interval));
|
|
assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).isAfter(interval));
|
|
assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).isAfter(interval));
|
|
assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).isAfter(interval));
|
|
assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).isAfter(interval));
|
|
assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).isAfter(interval));
|
|
assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).isAfter(interval));
|
|
assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).isAfter(interval));
|
|
assert(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).isAfter(interval));
|
|
|
|
assert(!interval.isAfter(PosInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(!interval.isAfter(PosInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(!interval.isAfter(PosInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(!interval.isAfter(PosInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(!interval.isAfter(PosInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(!interval.isAfter(PosInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
assert(interval.isAfter(NegInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(interval.isAfter(NegInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(!interval.isAfter(NegInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(!interval.isAfter(NegInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(!interval.isAfter(NegInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(!interval.isAfter(NegInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, interval.isAfter(interval)));
|
|
static assert(__traits(compiles, interval.isAfter(cInterval)));
|
|
static assert(__traits(compiles, interval.isAfter(iInterval)));
|
|
static assert(__traits(compiles, interval.isAfter(posInfInterval)));
|
|
static assert(__traits(compiles, interval.isAfter(cPosInfInterval)));
|
|
static assert(__traits(compiles, interval.isAfter(iPosInfInterval)));
|
|
static assert(__traits(compiles, interval.isAfter(negInfInterval)));
|
|
static assert(__traits(compiles, interval.isAfter(cNegInfInterval)));
|
|
static assert(__traits(compiles, interval.isAfter(iNegInfInterval)));
|
|
static assert(__traits(compiles, cInterval.isAfter(interval)));
|
|
static assert(__traits(compiles, cInterval.isAfter(cInterval)));
|
|
static assert(__traits(compiles, cInterval.isAfter(iInterval)));
|
|
static assert(__traits(compiles, cInterval.isAfter(posInfInterval)));
|
|
static assert(__traits(compiles, cInterval.isAfter(cPosInfInterval)));
|
|
static assert(__traits(compiles, cInterval.isAfter(iPosInfInterval)));
|
|
static assert(__traits(compiles, cInterval.isAfter(negInfInterval)));
|
|
static assert(__traits(compiles, cInterval.isAfter(cNegInfInterval)));
|
|
static assert(__traits(compiles, cInterval.isAfter(iNegInfInterval)));
|
|
static assert(__traits(compiles, iInterval.isAfter(interval)));
|
|
static assert(__traits(compiles, iInterval.isAfter(cInterval)));
|
|
static assert(__traits(compiles, iInterval.isAfter(iInterval)));
|
|
static assert(__traits(compiles, iInterval.isAfter(posInfInterval)));
|
|
static assert(__traits(compiles, iInterval.isAfter(cPosInfInterval)));
|
|
static assert(__traits(compiles, iInterval.isAfter(iPosInfInterval)));
|
|
static assert(__traits(compiles, iInterval.isAfter(negInfInterval)));
|
|
static assert(__traits(compiles, iInterval.isAfter(cNegInfInterval)));
|
|
static assert(__traits(compiles, iInterval.isAfter(iNegInfInterval)));
|
|
|
|
//Verify Examples.
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));
|
|
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(PosInfInterval!Date(Date(1999, 5, 4))));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAfter(NegInfInterval!Date(Date(1996, 1, 2))));
|
|
}
|
|
}
|
|
|
|
//Test Interval's intersects().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
|
|
assertThrown!DateTimeException(interval.intersects(Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).intersects(interval));
|
|
assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).intersects(Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
|
|
assert(interval.intersects(interval));
|
|
assert(!interval.intersects(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
|
|
assert(interval.intersects(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
|
|
assert(!interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
|
|
assert(interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
|
|
assert(interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
|
|
assert(interval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
|
|
assert(interval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
|
|
assert(interval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
|
|
assert(interval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
|
|
assert(interval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
|
|
assert(!interval.intersects(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
|
|
assert(!interval.intersects(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
|
|
|
|
assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).intersects(interval));
|
|
assert(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).intersects(interval));
|
|
assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).intersects(interval));
|
|
assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).intersects(interval));
|
|
assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).intersects(interval));
|
|
assert(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).intersects(interval));
|
|
assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).intersects(interval));
|
|
assert(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).intersects(interval));
|
|
assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).intersects(interval));
|
|
assert(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).intersects(interval));
|
|
assert(!Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).intersects(interval));
|
|
assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).intersects(interval));
|
|
|
|
assert(interval.intersects(PosInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(interval.intersects(PosInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(interval.intersects(PosInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(interval.intersects(PosInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(!interval.intersects(PosInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(!interval.intersects(PosInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
assert(!interval.intersects(NegInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(!interval.intersects(NegInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(interval.intersects(NegInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(interval.intersects(NegInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(interval.intersects(NegInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(interval.intersects(NegInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, interval.intersects(interval)));
|
|
static assert(__traits(compiles, interval.intersects(cInterval)));
|
|
static assert(__traits(compiles, interval.intersects(iInterval)));
|
|
static assert(__traits(compiles, interval.intersects(posInfInterval)));
|
|
static assert(__traits(compiles, interval.intersects(cPosInfInterval)));
|
|
static assert(__traits(compiles, interval.intersects(iPosInfInterval)));
|
|
static assert(__traits(compiles, interval.intersects(negInfInterval)));
|
|
static assert(__traits(compiles, interval.intersects(cNegInfInterval)));
|
|
static assert(__traits(compiles, interval.intersects(iNegInfInterval)));
|
|
static assert(__traits(compiles, cInterval.intersects(interval)));
|
|
static assert(__traits(compiles, cInterval.intersects(cInterval)));
|
|
static assert(__traits(compiles, cInterval.intersects(iInterval)));
|
|
static assert(__traits(compiles, cInterval.intersects(posInfInterval)));
|
|
static assert(__traits(compiles, cInterval.intersects(cPosInfInterval)));
|
|
static assert(__traits(compiles, cInterval.intersects(iPosInfInterval)));
|
|
static assert(__traits(compiles, cInterval.intersects(negInfInterval)));
|
|
static assert(__traits(compiles, cInterval.intersects(cNegInfInterval)));
|
|
static assert(__traits(compiles, cInterval.intersects(iNegInfInterval)));
|
|
static assert(__traits(compiles, iInterval.intersects(interval)));
|
|
static assert(__traits(compiles, iInterval.intersects(cInterval)));
|
|
static assert(__traits(compiles, iInterval.intersects(iInterval)));
|
|
static assert(__traits(compiles, iInterval.intersects(posInfInterval)));
|
|
static assert(__traits(compiles, iInterval.intersects(cPosInfInterval)));
|
|
static assert(__traits(compiles, iInterval.intersects(iPosInfInterval)));
|
|
static assert(__traits(compiles, iInterval.intersects(negInfInterval)));
|
|
static assert(__traits(compiles, iInterval.intersects(cNegInfInterval)));
|
|
static assert(__traits(compiles, iInterval.intersects(iNegInfInterval)));
|
|
|
|
//Verify Examples.
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(1999, 5, 4))));
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(2012, 3, 1))));
|
|
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(1996, 1, 2))));
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(2000, 1, 2))));
|
|
}
|
|
}
|
|
|
|
//Test Interval's intersection().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
|
|
assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).intersection(interval));
|
|
assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 4), dur!"days"(0)).intersection(Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
|
|
assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
|
|
assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
|
|
assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
|
|
assertThrown!DateTimeException(interval.intersection(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
|
|
|
|
assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).intersection(interval));
|
|
assertThrown!DateTimeException(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).intersection(interval));
|
|
assertThrown!DateTimeException(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).intersection(interval));
|
|
assertThrown!DateTimeException(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).intersection(interval));
|
|
|
|
assertThrown!DateTimeException(interval.intersection(PosInfInterval!Date(Date(2012, 1, 7))));
|
|
assertThrown!DateTimeException(interval.intersection(PosInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
assertThrown!DateTimeException(interval.intersection(NegInfInterval!Date(Date(2010, 7, 3))));
|
|
assertThrown!DateTimeException(interval.intersection(NegInfInterval!Date(Date(2010, 7, 4))));
|
|
|
|
_assertPred!"=="(interval.intersection(interval), interval);
|
|
_assertPred!"=="(interval.intersection(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5)));
|
|
_assertPred!"=="(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))),
|
|
Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)));
|
|
_assertPred!"=="(interval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))),
|
|
Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))),
|
|
Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))),
|
|
Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)));
|
|
|
|
_assertPred!"=="(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).intersection(interval),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
|
|
_assertPred!"=="(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).intersection(interval),
|
|
Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5)));
|
|
_assertPred!"=="(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).intersection(interval),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
|
|
_assertPred!"=="(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).intersection(interval),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
|
|
_assertPred!"=="(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).intersection(interval),
|
|
Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)));
|
|
_assertPred!"=="(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).intersection(interval),
|
|
Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)));
|
|
_assertPred!"=="(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).intersection(interval),
|
|
Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)));
|
|
_assertPred!"=="(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).intersection(interval),
|
|
Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)));
|
|
|
|
_assertPred!"=="(interval.intersection(PosInfInterval!Date(Date(2010, 7, 3))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.intersection(PosInfInterval!Date(Date(2010, 7, 4))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.intersection(PosInfInterval!Date(Date(2010, 7, 5))),
|
|
Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.intersection(PosInfInterval!Date(Date(2012, 1, 6))),
|
|
Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)));
|
|
|
|
_assertPred!"=="(interval.intersection(NegInfInterval!Date(Date(2010, 7, 5))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5)));
|
|
_assertPred!"=="(interval.intersection(NegInfInterval!Date(Date(2012, 1, 6))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 6)));
|
|
_assertPred!"=="(interval.intersection(NegInfInterval!Date(Date(2012, 1, 7))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.intersection(NegInfInterval!Date(Date(2012, 1, 8))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
|
|
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, interval.intersection(interval)));
|
|
static assert(__traits(compiles, interval.intersection(cInterval)));
|
|
static assert(__traits(compiles, interval.intersection(iInterval)));
|
|
static assert(__traits(compiles, interval.intersection(posInfInterval)));
|
|
static assert(__traits(compiles, interval.intersection(cPosInfInterval)));
|
|
static assert(__traits(compiles, interval.intersection(iPosInfInterval)));
|
|
static assert(__traits(compiles, interval.intersection(negInfInterval)));
|
|
static assert(__traits(compiles, interval.intersection(cNegInfInterval)));
|
|
static assert(__traits(compiles, interval.intersection(iNegInfInterval)));
|
|
static assert(__traits(compiles, cInterval.intersection(interval)));
|
|
static assert(__traits(compiles, cInterval.intersection(cInterval)));
|
|
static assert(__traits(compiles, cInterval.intersection(iInterval)));
|
|
static assert(__traits(compiles, cInterval.intersection(posInfInterval)));
|
|
static assert(__traits(compiles, cInterval.intersection(cPosInfInterval)));
|
|
static assert(__traits(compiles, cInterval.intersection(iPosInfInterval)));
|
|
static assert(__traits(compiles, cInterval.intersection(negInfInterval)));
|
|
static assert(__traits(compiles, cInterval.intersection(cNegInfInterval)));
|
|
static assert(__traits(compiles, cInterval.intersection(iNegInfInterval)));
|
|
static assert(__traits(compiles, iInterval.intersection(interval)));
|
|
static assert(__traits(compiles, iInterval.intersection(cInterval)));
|
|
static assert(__traits(compiles, iInterval.intersection(iInterval)));
|
|
static assert(__traits(compiles, iInterval.intersection(posInfInterval)));
|
|
static assert(__traits(compiles, iInterval.intersection(cPosInfInterval)));
|
|
static assert(__traits(compiles, iInterval.intersection(iPosInfInterval)));
|
|
static assert(__traits(compiles, iInterval.intersection(negInfInterval)));
|
|
static assert(__traits(compiles, iInterval.intersection(cNegInfInterval)));
|
|
static assert(__traits(compiles, iInterval.intersection(iNegInfInterval)));
|
|
|
|
//Verify Examples.
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == Interval!Date(Date(1996, 1 , 2), Date(2000, 8, 2)));
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == Interval!Date(Date(1999, 1 , 12), Date(2011, 9, 17)));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(PosInfInterval!Date(Date(1990, 7, 6))) == Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1)));
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(PosInfInterval!Date(Date(1999, 1, 12))) == Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1)));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(NegInfInterval!Date(Date(1999, 7, 6))) == Interval!Date(Date(1996, 1 , 2), Date(1999, 7, 6)));
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).intersection(NegInfInterval!Date(Date(2013, 1, 12))) == Interval!Date(Date(1996, 1 , 2), Date(2012, 3, 1)));
|
|
}
|
|
}
|
|
|
|
//Test Interval's isAdjacent().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
|
|
static void testInterval(in Interval!Date interval1, in Interval!Date interval2)
|
|
{
|
|
interval1.isAdjacent(interval2);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), interval));
|
|
assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
|
|
assert(!interval.isAdjacent(interval));
|
|
assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
|
|
assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
|
|
assert(interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
|
|
assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
|
|
assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
|
|
assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
|
|
assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
|
|
assert(!interval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
|
|
assert(!interval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
|
|
assert(!interval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
|
|
assert(interval.isAdjacent(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
|
|
assert(!interval.isAdjacent(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
|
|
|
|
assert(!Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).isAdjacent(interval));
|
|
assert(!Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).isAdjacent(interval));
|
|
assert(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).isAdjacent(interval));
|
|
assert(!Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).isAdjacent(interval));
|
|
assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).isAdjacent(interval));
|
|
assert(!Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).isAdjacent(interval));
|
|
assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).isAdjacent(interval));
|
|
assert(!Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).isAdjacent(interval));
|
|
assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).isAdjacent(interval));
|
|
assert(!Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).isAdjacent(interval));
|
|
assert(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).isAdjacent(interval));
|
|
assert(!Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).isAdjacent(interval));
|
|
|
|
assert(!interval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(!interval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(!interval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(!interval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(interval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(!interval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
assert(!interval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(interval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(!interval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(!interval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(!interval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(!interval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, interval.isAdjacent(interval)));
|
|
static assert(__traits(compiles, interval.isAdjacent(cInterval)));
|
|
static assert(__traits(compiles, interval.isAdjacent(iInterval)));
|
|
static assert(__traits(compiles, interval.isAdjacent(posInfInterval)));
|
|
static assert(__traits(compiles, interval.isAdjacent(cPosInfInterval)));
|
|
static assert(__traits(compiles, interval.isAdjacent(iPosInfInterval)));
|
|
static assert(__traits(compiles, interval.isAdjacent(negInfInterval)));
|
|
static assert(__traits(compiles, interval.isAdjacent(cNegInfInterval)));
|
|
static assert(__traits(compiles, interval.isAdjacent(iNegInfInterval)));
|
|
static assert(__traits(compiles, cInterval.isAdjacent(interval)));
|
|
static assert(__traits(compiles, cInterval.isAdjacent(cInterval)));
|
|
static assert(__traits(compiles, cInterval.isAdjacent(iInterval)));
|
|
static assert(__traits(compiles, cInterval.isAdjacent(posInfInterval)));
|
|
static assert(__traits(compiles, cInterval.isAdjacent(cPosInfInterval)));
|
|
static assert(__traits(compiles, cInterval.isAdjacent(iPosInfInterval)));
|
|
static assert(__traits(compiles, cInterval.isAdjacent(negInfInterval)));
|
|
static assert(__traits(compiles, cInterval.isAdjacent(cNegInfInterval)));
|
|
static assert(__traits(compiles, cInterval.isAdjacent(iNegInfInterval)));
|
|
static assert(__traits(compiles, iInterval.isAdjacent(interval)));
|
|
static assert(__traits(compiles, iInterval.isAdjacent(cInterval)));
|
|
static assert(__traits(compiles, iInterval.isAdjacent(iInterval)));
|
|
static assert(__traits(compiles, iInterval.isAdjacent(posInfInterval)));
|
|
static assert(__traits(compiles, iInterval.isAdjacent(cPosInfInterval)));
|
|
static assert(__traits(compiles, iInterval.isAdjacent(iPosInfInterval)));
|
|
static assert(__traits(compiles, iInterval.isAdjacent(negInfInterval)));
|
|
static assert(__traits(compiles, iInterval.isAdjacent(cNegInfInterval)));
|
|
static assert(__traits(compiles, iInterval.isAdjacent(iNegInfInterval)));
|
|
|
|
//Verify Examples.
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(1990, 7, 6), Date(1996, 1, 2))));
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(2012, 3, 1), Date(2013, 9, 17))));
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(1989, 3, 1), Date(2012, 3, 1))));
|
|
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(PosInfInterval!Date(Date(1999, 5, 4))));
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(PosInfInterval!Date(Date(2012, 3, 1))));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(NegInfInterval!Date(Date(1996, 1, 2))));
|
|
assert(!Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).isAdjacent(NegInfInterval!Date(Date(2000, 1, 2))));
|
|
}
|
|
}
|
|
|
|
//Test Interval's merge().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
|
|
static void testInterval(I)(in Interval!Date interval1, in I interval2)
|
|
{
|
|
interval1.merge(interval2);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), interval));
|
|
assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
|
|
assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
|
|
assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
|
|
|
|
assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)), interval));
|
|
assertThrown!DateTimeException(testInterval(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)), interval));
|
|
|
|
assertThrown!DateTimeException(testInterval(interval, PosInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
assertThrown!DateTimeException(testInterval(interval, NegInfInterval!Date(Date(2010, 7, 3))));
|
|
|
|
_assertPred!"=="(interval.merge(interval), interval);
|
|
_assertPred!"=="(interval.merge(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))),
|
|
Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)));
|
|
_assertPred!"=="(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))),
|
|
Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))),
|
|
Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))),
|
|
Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))),
|
|
Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)));
|
|
_assertPred!"=="(interval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));
|
|
_assertPred!"=="(interval.merge(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));
|
|
|
|
_assertPred!"=="(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).merge(interval),
|
|
Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)));
|
|
_assertPred!"=="(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).merge(interval),
|
|
Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
|
|
_assertPred!"=="(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).merge(interval),
|
|
Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
|
|
_assertPred!"=="(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).merge(interval),
|
|
Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
|
|
_assertPred!"=="(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).merge(interval),
|
|
Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)));
|
|
_assertPred!"=="(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).merge(interval),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
|
|
_assertPred!"=="(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).merge(interval),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
|
|
_assertPred!"=="(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).merge(interval),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
|
|
_assertPred!"=="(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).merge(interval),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));
|
|
_assertPred!"=="(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).merge(interval),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));
|
|
|
|
_assertPred!"=="(interval.merge(PosInfInterval!Date(Date(2010, 7, 3))),
|
|
PosInfInterval!Date(Date(2010, 7, 3)));
|
|
_assertPred!"=="(interval.merge(PosInfInterval!Date(Date(2010, 7, 4))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(interval.merge(PosInfInterval!Date(Date(2010, 7, 5))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(interval.merge(PosInfInterval!Date(Date(2012, 1, 6))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(interval.merge(PosInfInterval!Date(Date(2012, 1, 7))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
|
|
_assertPred!"=="(interval.merge(NegInfInterval!Date(Date(2010, 7, 4))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.merge(NegInfInterval!Date(Date(2010, 7, 5))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.merge(NegInfInterval!Date(Date(2012, 1, 6))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.merge(NegInfInterval!Date(Date(2012, 1, 7))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.merge(NegInfInterval!Date(Date(2012, 1, 8))),
|
|
NegInfInterval!Date(Date(2012, 1, 8)));
|
|
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, interval.merge(interval)));
|
|
static assert(__traits(compiles, interval.merge(cInterval)));
|
|
static assert(__traits(compiles, interval.merge(iInterval)));
|
|
static assert(__traits(compiles, interval.merge(posInfInterval)));
|
|
static assert(__traits(compiles, interval.merge(cPosInfInterval)));
|
|
static assert(__traits(compiles, interval.merge(iPosInfInterval)));
|
|
static assert(__traits(compiles, interval.merge(negInfInterval)));
|
|
static assert(__traits(compiles, interval.merge(cNegInfInterval)));
|
|
static assert(__traits(compiles, interval.merge(iNegInfInterval)));
|
|
static assert(__traits(compiles, cInterval.merge(interval)));
|
|
static assert(__traits(compiles, cInterval.merge(cInterval)));
|
|
static assert(__traits(compiles, cInterval.merge(iInterval)));
|
|
static assert(__traits(compiles, cInterval.merge(posInfInterval)));
|
|
static assert(__traits(compiles, cInterval.merge(cPosInfInterval)));
|
|
static assert(__traits(compiles, cInterval.merge(iPosInfInterval)));
|
|
static assert(__traits(compiles, cInterval.merge(negInfInterval)));
|
|
static assert(__traits(compiles, cInterval.merge(cNegInfInterval)));
|
|
static assert(__traits(compiles, cInterval.merge(iNegInfInterval)));
|
|
static assert(__traits(compiles, iInterval.merge(interval)));
|
|
static assert(__traits(compiles, iInterval.merge(cInterval)));
|
|
static assert(__traits(compiles, iInterval.merge(iInterval)));
|
|
static assert(__traits(compiles, iInterval.merge(posInfInterval)));
|
|
static assert(__traits(compiles, iInterval.merge(cPosInfInterval)));
|
|
static assert(__traits(compiles, iInterval.merge(iPosInfInterval)));
|
|
static assert(__traits(compiles, iInterval.merge(negInfInterval)));
|
|
static assert(__traits(compiles, iInterval.merge(cNegInfInterval)));
|
|
static assert(__traits(compiles, iInterval.merge(iNegInfInterval)));
|
|
|
|
//Verify Examples.
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1)));
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) == Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7)));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(PosInfInterval!Date(Date(1990, 7, 6))) == PosInfInterval!Date(Date(1990, 7 , 6)));
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(PosInfInterval!Date(Date(2012, 3, 1))) == PosInfInterval!Date(Date(1996, 1 , 2)));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(NegInfInterval!Date(Date(1996, 1, 2))) == NegInfInterval!Date(Date(2012, 3 , 1)));
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).merge(NegInfInterval!Date(Date(2013, 1, 12))) == NegInfInterval!Date(Date(2013, 1 , 12)));
|
|
}
|
|
}
|
|
|
|
//Test Interval's span().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
|
|
static void testInterval(in Interval!Date interval1, in Interval!Date interval2)
|
|
{
|
|
interval1.span(interval2);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testInterval(interval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), interval));
|
|
assertThrown!DateTimeException(testInterval(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
|
|
_assertPred!"=="(interval.span(interval), interval);
|
|
_assertPred!"=="(interval.span(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))),
|
|
Interval!Date(Date(2010, 7, 1), Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.span(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))),
|
|
Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)));
|
|
_assertPred!"=="(interval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))),
|
|
Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))),
|
|
Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))),
|
|
Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))),
|
|
Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)));
|
|
_assertPred!"=="(interval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));
|
|
_assertPred!"=="(interval.span(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));
|
|
_assertPred!"=="(interval.span(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 9)));
|
|
|
|
_assertPred!"=="(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)).span(interval),
|
|
Interval!Date(Date(2010, 7, 1), Date(2012, 1, 7)));
|
|
_assertPred!"=="(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)).span(interval),
|
|
Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3)));
|
|
_assertPred!"=="(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)).span(interval),
|
|
Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
|
|
_assertPred!"=="(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)).span(interval),
|
|
Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
|
|
_assertPred!"=="(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)).span(interval),
|
|
Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
|
|
_assertPred!"=="(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)).span(interval),
|
|
Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8)));
|
|
_assertPred!"=="(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)).span(interval),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
|
|
_assertPred!"=="(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)).span(interval),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
|
|
_assertPred!"=="(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)).span(interval),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
|
|
_assertPred!"=="(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)).span(interval),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));
|
|
_assertPred!"=="(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)).span(interval),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));
|
|
_assertPred!"=="(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)).span(interval),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 9)));
|
|
|
|
_assertPred!"=="(interval.span(PosInfInterval!Date(Date(2010, 7, 3))),
|
|
PosInfInterval!Date(Date(2010, 7, 3)));
|
|
_assertPred!"=="(interval.span(PosInfInterval!Date(Date(2010, 7, 4))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(interval.span(PosInfInterval!Date(Date(2010, 7, 5))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(interval.span(PosInfInterval!Date(Date(2012, 1, 6))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(interval.span(PosInfInterval!Date(Date(2012, 1, 7))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(interval.span(PosInfInterval!Date(Date(2012, 1, 8))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
|
|
_assertPred!"=="(interval.span(NegInfInterval!Date(Date(2010, 7, 3))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.span(NegInfInterval!Date(Date(2010, 7, 4))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.span(NegInfInterval!Date(Date(2010, 7, 5))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.span(NegInfInterval!Date(Date(2012, 1, 6))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.span(NegInfInterval!Date(Date(2012, 1, 7))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(interval.span(NegInfInterval!Date(Date(2012, 1, 8))),
|
|
NegInfInterval!Date(Date(2012, 1, 8)));
|
|
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, interval.span(interval)));
|
|
static assert(__traits(compiles, interval.span(cInterval)));
|
|
static assert(__traits(compiles, interval.span(iInterval)));
|
|
static assert(__traits(compiles, interval.span(posInfInterval)));
|
|
static assert(__traits(compiles, interval.span(cPosInfInterval)));
|
|
static assert(__traits(compiles, interval.span(iPosInfInterval)));
|
|
static assert(__traits(compiles, interval.span(negInfInterval)));
|
|
static assert(__traits(compiles, interval.span(cNegInfInterval)));
|
|
static assert(__traits(compiles, interval.span(iNegInfInterval)));
|
|
static assert(__traits(compiles, cInterval.span(interval)));
|
|
static assert(__traits(compiles, cInterval.span(cInterval)));
|
|
static assert(__traits(compiles, cInterval.span(iInterval)));
|
|
static assert(__traits(compiles, cInterval.span(posInfInterval)));
|
|
static assert(__traits(compiles, cInterval.span(cPosInfInterval)));
|
|
static assert(__traits(compiles, cInterval.span(iPosInfInterval)));
|
|
static assert(__traits(compiles, cInterval.span(negInfInterval)));
|
|
static assert(__traits(compiles, cInterval.span(cNegInfInterval)));
|
|
static assert(__traits(compiles, cInterval.span(iNegInfInterval)));
|
|
static assert(__traits(compiles, iInterval.span(interval)));
|
|
static assert(__traits(compiles, iInterval.span(cInterval)));
|
|
static assert(__traits(compiles, iInterval.span(iInterval)));
|
|
static assert(__traits(compiles, iInterval.span(posInfInterval)));
|
|
static assert(__traits(compiles, iInterval.span(cPosInfInterval)));
|
|
static assert(__traits(compiles, iInterval.span(iPosInfInterval)));
|
|
static assert(__traits(compiles, iInterval.span(negInfInterval)));
|
|
static assert(__traits(compiles, iInterval.span(cNegInfInterval)));
|
|
static assert(__traits(compiles, iInterval.span(iNegInfInterval)));
|
|
|
|
//Verify Examples.
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(Interval!Date(Date(1990, 7, 6), Date(1991, 1, 8))) == Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1)));
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(Interval!Date(Date(2012, 3, 1), Date(2013, 5, 7))) == Interval!Date(Date(1996, 1 , 2), Date(2013, 5, 7)));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(PosInfInterval!Date(Date(1990, 7, 6))) == PosInfInterval!Date(Date(1990, 7 , 6)));
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(PosInfInterval!Date(Date(2050, 1, 1))) == PosInfInterval!Date(Date(1996, 1 , 2)));
|
|
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(NegInfInterval!Date(Date(1602, 5, 21))) == NegInfInterval!Date(Date(2012, 3 , 1)));
|
|
assert(Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1)).span(NegInfInterval!Date(Date(2013, 1, 12))) == NegInfInterval!Date(Date(2013, 1 , 12)));
|
|
}
|
|
}
|
|
|
|
//Test Interval's shift(duration).
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
|
|
static void testIntervalFail(Interval!Date interval, in Duration duration)
|
|
{
|
|
interval.shift(duration);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), dur!"days"(1)));
|
|
|
|
static void testInterval(I)(I interval, in Duration duration, in I expected, size_t line = __LINE__)
|
|
{
|
|
interval.shift(duration);
|
|
_assertPred!"=="(interval, expected, "", __FILE__, line);
|
|
}
|
|
|
|
testInterval(interval, dur!"days"(22), Interval!Date(Date(2010, 7, 26), Date(2012, 1, 29)));
|
|
testInterval(interval, dur!"days"(-22), Interval!Date(Date(2010, 6, 12), Date(2011, 12, 16)));
|
|
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
static assert(!__traits(compiles, cInterval.shift(dur!"days"(5))));
|
|
static assert(!__traits(compiles, iInterval.shift(dur!"days"(5))));
|
|
|
|
//Verify Examples.
|
|
auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5));
|
|
auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 4, 5));
|
|
|
|
interval1.shift(dur!"days"(50));
|
|
assert(interval1 == Interval!Date(Date(1996, 2, 21), Date(2012, 5, 25)));
|
|
|
|
interval2.shift(dur!"days"(-50));
|
|
assert(interval2 == Interval!Date(Date(1995, 11, 13), Date(2012, 2, 15)));
|
|
}
|
|
}
|
|
|
|
//Test Interval's shift(int, int, AllowDayOverflow).
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
{
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
|
|
static void testIntervalFail(Interval!Date interval, int years, int months)
|
|
{
|
|
interval.shift(years, months);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), 1, 0));
|
|
|
|
static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, in I expected, size_t line = __LINE__)
|
|
{
|
|
interval.shift(years, months, allow);
|
|
_assertPred!"=="(interval, expected, "", __FILE__, line);
|
|
}
|
|
|
|
testInterval(interval, 5, 0, AllowDayOverflow.yes, Interval!Date(Date(2015, 7, 4), Date(2017, 1, 7)));
|
|
testInterval(interval, -5, 0, AllowDayOverflow.yes, Interval!Date(Date(2005, 7, 4), Date(2007, 1, 7)));
|
|
|
|
auto interval2 = Interval!Date(Date(2000, 1, 29), Date(2010, 5, 31));
|
|
|
|
testInterval(interval2, 1, 1, AllowDayOverflow.yes, Interval!Date(Date(2001, 3, 1), Date(2011, 7, 1)));
|
|
testInterval(interval2, 1, -1, AllowDayOverflow.yes, Interval!Date(Date(2000, 12, 29), Date(2011, 5, 1)));
|
|
testInterval(interval2, -1, -1, AllowDayOverflow.yes, Interval!Date(Date(1998, 12, 29), Date(2009, 5, 1)));
|
|
testInterval(interval2, -1, 1, AllowDayOverflow.yes, Interval!Date(Date(1999, 3, 1), Date(2009, 7, 1)));
|
|
|
|
testInterval(interval2, 1, 1, AllowDayOverflow.no, Interval!Date(Date(2001, 2, 28), Date(2011, 6, 30)));
|
|
testInterval(interval2, 1, -1, AllowDayOverflow.no, Interval!Date(Date(2000, 12, 29), Date(2011, 4, 30)));
|
|
testInterval(interval2, -1, -1, AllowDayOverflow.no, Interval!Date(Date(1998, 12, 29), Date(2009, 4, 30)));
|
|
testInterval(interval2, -1, 1, AllowDayOverflow.no, Interval!Date(Date(1999, 2, 28), Date(2009, 6, 30)));
|
|
}
|
|
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
static assert(!__traits(compiles, cInterval.shift(5)));
|
|
static assert(!__traits(compiles, iInterval.shift(5)));
|
|
|
|
//Verify Examples.
|
|
auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
|
|
auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
|
|
|
|
interval1.shift(2);
|
|
assert(interval1 == Interval!Date(Date(1998, 1, 2), Date(2014, 3, 1)));
|
|
|
|
interval2.shift(-2);
|
|
assert(interval2 == Interval!Date(Date(1994, 1, 2), Date(2010, 3, 1)));
|
|
}
|
|
}
|
|
|
|
//Test Interval's expand(Duration).
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto interval = Interval!Date(Date(2000, 7, 4), Date(2012, 1, 7));
|
|
|
|
static void testIntervalFail(I)(I interval, in Duration duration)
|
|
{
|
|
interval.expand(duration);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), dur!"days"(1)));
|
|
assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5)), dur!"days"(-5)));
|
|
|
|
static void testInterval(I)(I interval, in Duration duration, in I expected, size_t line = __LINE__)
|
|
{
|
|
interval.expand(duration);
|
|
_assertPred!"=="(interval, expected, "", __FILE__, line);
|
|
}
|
|
|
|
testInterval(interval, dur!"days"(22), Interval!Date(Date(2000, 6, 12), Date(2012, 1, 29)));
|
|
testInterval(interval, dur!"days"(-22), Interval!Date(Date(2000, 7, 26), Date(2011, 12, 16)));
|
|
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
static assert(!__traits(compiles, cInterval.expand(dur!"days"(5))));
|
|
static assert(!__traits(compiles, iInterval.expand(dur!"days"(5))));
|
|
|
|
//Verify Examples.
|
|
auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
|
|
auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
|
|
|
|
interval1.expand(dur!"days"(2));
|
|
assert(interval1 == Interval!Date(Date(1995, 12, 31), Date(2012, 3, 3)));
|
|
|
|
interval2.expand(dur!"days"(-2));
|
|
assert(interval2 == Interval!Date(Date(1996, 1, 4), Date(2012, 2, 28)));
|
|
}
|
|
}
|
|
|
|
//Test Interval's expand(int, int, AllowDayOverflow, Direction)
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
{
|
|
auto interval = Interval!Date(Date(2000, 7, 4), Date(2012, 1, 7));
|
|
|
|
static void testIntervalFail(Interval!Date interval, int years, int months)
|
|
{
|
|
interval.expand(years, months);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), dur!"days"(0)), 1, 0));
|
|
assertThrown!DateTimeException(testIntervalFail(Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)), -5, 0));
|
|
|
|
static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, Direction dir, in I expected, size_t line = __LINE__)
|
|
{
|
|
interval.expand(years, months, allow, dir);
|
|
_assertPred!"=="(interval, expected, "", __FILE__, line);
|
|
}
|
|
|
|
testInterval(interval, 5, 0, AllowDayOverflow.yes, Direction.both, Interval!Date(Date(1995, 7, 4), Date(2017, 1, 7)));
|
|
testInterval(interval, -5, 0, AllowDayOverflow.yes, Direction.both, Interval!Date(Date(2005, 7, 4), Date(2007, 1, 7)));
|
|
|
|
testInterval(interval, 5, 0, AllowDayOverflow.yes, Direction.fwd, Interval!Date(Date(2000, 7, 4), Date(2017, 1, 7)));
|
|
testInterval(interval, -5, 0, AllowDayOverflow.yes, Direction.fwd, Interval!Date(Date(2000, 7, 4), Date(2007, 1, 7)));
|
|
|
|
testInterval(interval, 5, 0, AllowDayOverflow.yes, Direction.bwd, Interval!Date(Date(1995, 7, 4), Date(2012, 1, 7)));
|
|
testInterval(interval, -5, 0, AllowDayOverflow.yes, Direction.bwd, Interval!Date(Date(2005, 7, 4), Date(2012, 1, 7)));
|
|
|
|
auto interval2 = Interval!Date(Date(2000, 1, 29), Date(2010, 5, 31));
|
|
|
|
testInterval(interval2, 1, 1, AllowDayOverflow.yes, Direction.both, Interval!Date(Date(1998, 12, 29), Date(2011, 7, 1)));
|
|
testInterval(interval2, 1, -1, AllowDayOverflow.yes, Direction.both, Interval!Date(Date(1999, 3, 1), Date(2011, 5, 1)));
|
|
testInterval(interval2, -1, -1, AllowDayOverflow.yes, Direction.both, Interval!Date(Date(2001, 3, 1), Date(2009, 5, 1)));
|
|
testInterval(interval2, -1, 1, AllowDayOverflow.yes, Direction.both, Interval!Date(Date(2000, 12, 29), Date(2009, 7, 1)));
|
|
|
|
testInterval(interval2, 1, 1, AllowDayOverflow.no, Direction.both, Interval!Date(Date(1998, 12, 29), Date(2011, 6, 30)));
|
|
testInterval(interval2, 1, -1, AllowDayOverflow.no, Direction.both, Interval!Date(Date(1999, 2, 28), Date(2011, 4, 30)));
|
|
testInterval(interval2, -1, -1, AllowDayOverflow.no, Direction.both, Interval!Date(Date(2001, 2, 28), Date(2009, 4, 30)));
|
|
testInterval(interval2, -1, 1, AllowDayOverflow.no, Direction.both, Interval!Date(Date(2000, 12, 29), Date(2009, 6, 30)));
|
|
|
|
testInterval(interval2, 1, 1, AllowDayOverflow.yes, Direction.fwd, Interval!Date(Date(2000, 1, 29), Date(2011, 7, 1)));
|
|
testInterval(interval2, 1, -1, AllowDayOverflow.yes, Direction.fwd, Interval!Date(Date(2000, 1, 29), Date(2011, 5, 1)));
|
|
testInterval(interval2, -1, -1, AllowDayOverflow.yes, Direction.fwd, Interval!Date(Date(2000, 1, 29), Date(2009, 5, 1)));
|
|
testInterval(interval2, -1, 1, AllowDayOverflow.yes, Direction.fwd, Interval!Date(Date(2000, 1, 29), Date(2009, 7, 1)));
|
|
|
|
testInterval(interval2, 1, 1, AllowDayOverflow.no, Direction.fwd, Interval!Date(Date(2000, 1, 29), Date(2011, 6, 30)));
|
|
testInterval(interval2, 1, -1, AllowDayOverflow.no, Direction.fwd, Interval!Date(Date(2000, 1, 29), Date(2011, 4, 30)));
|
|
testInterval(interval2, -1, -1, AllowDayOverflow.no, Direction.fwd, Interval!Date(Date(2000, 1, 29), Date(2009, 4, 30)));
|
|
testInterval(interval2, -1, 1, AllowDayOverflow.no, Direction.fwd, Interval!Date(Date(2000, 1, 29), Date(2009, 6, 30)));
|
|
|
|
testInterval(interval2, 1, 1, AllowDayOverflow.yes, Direction.bwd, Interval!Date(Date(1998, 12, 29), Date(2010, 5, 31)));
|
|
testInterval(interval2, 1, -1, AllowDayOverflow.yes, Direction.bwd, Interval!Date(Date(1999, 3, 1), Date(2010, 5, 31)));
|
|
testInterval(interval2, -1, -1, AllowDayOverflow.yes, Direction.bwd, Interval!Date(Date(2001, 3, 1), Date(2010, 5, 31)));
|
|
testInterval(interval2, -1, 1, AllowDayOverflow.yes, Direction.bwd, Interval!Date(Date(2000, 12, 29), Date(2010, 5, 31)));
|
|
|
|
testInterval(interval2, 1, 1, AllowDayOverflow.no, Direction.bwd, Interval!Date(Date(1998, 12, 29), Date(2010, 5, 31)));
|
|
testInterval(interval2, 1, -1, AllowDayOverflow.no, Direction.bwd, Interval!Date(Date(1999, 2, 28), Date(2010, 5, 31)));
|
|
testInterval(interval2, -1, -1, AllowDayOverflow.no, Direction.bwd, Interval!Date(Date(2001, 2, 28), Date(2010, 5, 31)));
|
|
testInterval(interval2, -1, 1, AllowDayOverflow.no, Direction.bwd, Interval!Date(Date(2000, 12, 29), Date(2010, 5, 31)));
|
|
}
|
|
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
static assert(!__traits(compiles, cInterval.expand(5)));
|
|
static assert(!__traits(compiles, iInterval.expand(5)));
|
|
|
|
//Verify Examples.
|
|
auto interval1 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
|
|
auto interval2 = Interval!Date(Date(1996, 1, 2), Date(2012, 3, 1));
|
|
|
|
interval1.expand(2);
|
|
assert(interval1 == Interval!Date(Date(1994, 1, 2), Date(2014, 3, 1)));
|
|
|
|
interval2.expand(-2);
|
|
assert(interval2 == Interval!Date(Date(1998, 1, 2), Date(2010, 3, 1)));
|
|
}
|
|
}
|
|
|
|
//Test Interval's fwdRange.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
{
|
|
auto interval = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21));
|
|
|
|
static void testInterval1(Interval!Date interval)
|
|
{
|
|
interval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri));
|
|
}
|
|
|
|
assertThrown!DateTimeException(testInterval1(Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
|
|
static void testInterval2(Interval!Date interval)
|
|
{
|
|
interval.fwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).popFront();
|
|
}
|
|
|
|
assertThrown!DateTimeException(testInterval2(interval));
|
|
|
|
assert(!interval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).empty);
|
|
assert(interval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri), PopFirst.yes).empty);
|
|
|
|
_assertPred!"=="(Interval!Date(Date(2010, 9, 12), Date(2010, 10, 1)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).front,
|
|
Date(2010, 9, 12));
|
|
|
|
_assertPred!"=="(Interval!Date(Date(2010, 9, 12), Date(2010, 10, 1)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri), PopFirst.yes).front,
|
|
Date(2010, 9, 17));
|
|
}
|
|
|
|
//Verify Examples.
|
|
{
|
|
auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9));
|
|
auto func = (in Date date)
|
|
{
|
|
if((date.day & 1) == 0)
|
|
return date + dur!"days"(2);
|
|
|
|
return date + dur!"days"(1);
|
|
};
|
|
auto range = interval.fwdRange(func);
|
|
|
|
assert(range.front == Date(2010, 9, 1)); //An odd day. Using PopFirst.yes would have made this Date(2010, 9, 2).
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 2));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 4));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 6));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 8));
|
|
|
|
range.popFront();
|
|
assert(range.empty);
|
|
}
|
|
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
static assert(__traits(compiles, cInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri))));
|
|
static assert(__traits(compiles, iInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri))));
|
|
}
|
|
}
|
|
|
|
//Test Interval's bwdRange.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
{
|
|
auto interval = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21));
|
|
|
|
static void testInterval1(Interval!Date interval)
|
|
{
|
|
interval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri));
|
|
}
|
|
|
|
assertThrown!DateTimeException(testInterval1(Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
|
|
static void testInterval2(Interval!Date interval)
|
|
{
|
|
interval.bwdRange(everyDayOfWeek!(Date, Direction.fwd)(DayOfWeek.fri)).popFront();
|
|
}
|
|
|
|
assertThrown!DateTimeException(testInterval2(interval));
|
|
|
|
assert(!interval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).empty);
|
|
assert(interval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri), PopFirst.yes).empty);
|
|
|
|
_assertPred!"=="(Interval!Date(Date(2010, 9, 19), Date(2010, 10, 1)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).front,
|
|
Date(2010, 10, 1));
|
|
|
|
_assertPred!"=="(Interval!Date(Date(2010, 9, 19), Date(2010, 10, 1)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri), PopFirst.yes).front,
|
|
Date(2010, 9, 24));
|
|
}
|
|
|
|
//Verify Examples.
|
|
{
|
|
auto interval = Interval!Date(Date(2010, 9, 1), Date(2010, 9, 9));
|
|
auto func = (in Date date)
|
|
{
|
|
if((date.day & 1) == 0)
|
|
return date - dur!"days"(2);
|
|
|
|
return date - dur!"days"(1);
|
|
};
|
|
auto range = interval.bwdRange(func);
|
|
|
|
assert(range.front == Date(2010, 9, 9)); //An odd day. Using PopFirst.yes would have made this Date(2010, 9, 8).
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 8));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 6));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 4));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 2));
|
|
|
|
range.popFront();
|
|
assert(range.empty);
|
|
}
|
|
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
static assert(__traits(compiles, cInterval.bwdRange(everyDayOfWeek!Date(DayOfWeek.fri))));
|
|
static assert(__traits(compiles, iInterval.bwdRange(everyDayOfWeek!Date(DayOfWeek.fri))));
|
|
}
|
|
}
|
|
|
|
//Test Interval's toString().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).toString(), "[2010-Jul-04 - 2012-Jan-07)");
|
|
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
static assert(__traits(compiles, cInterval.toString()));
|
|
static assert(__traits(compiles, iInterval.toString()));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Represents an interval of time which has positive infinity as its end point.
|
|
|
|
Any ranges which iterate over a $(D PosInfInterval) are infinite. So, the
|
|
main purpose of using $(D PosInfInterval) is to create an infinite range
|
|
which starts at a fixed point in time and goes to positive infinity.
|
|
+/
|
|
struct PosInfInterval(TP)
|
|
{
|
|
public:
|
|
|
|
/++
|
|
Params:
|
|
begin = The time point which begins the interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto interval = PosInfInterval!Date(Date(1996, 1, 2));
|
|
--------------------
|
|
+/
|
|
this(in TP begin) pure nothrow
|
|
{
|
|
_begin = cast(TP)begin;
|
|
}
|
|
|
|
|
|
/++
|
|
Params:
|
|
rhs = The $(D PosInfInterval) to assign to this one.
|
|
+/
|
|
/+ref+/ PosInfInterval opAssign(const ref PosInfInterval rhs) pure nothrow
|
|
{
|
|
_begin = cast(TP)rhs._begin;
|
|
|
|
return this;
|
|
}
|
|
|
|
|
|
/++
|
|
Params:
|
|
rhs = The $(D PosInfInterval) to assign to this one.
|
|
+/
|
|
/+ref+/ PosInfInterval opAssign(PosInfInterval rhs) pure nothrow
|
|
{
|
|
_begin = cast(TP)rhs._begin;
|
|
|
|
return this;
|
|
}
|
|
|
|
|
|
/++
|
|
The starting point of the interval. It is included in the interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).begin == Date(1996, 1, 2));
|
|
--------------------
|
|
+/
|
|
@property TP begin() const pure nothrow
|
|
{
|
|
return cast(TP)_begin;
|
|
}
|
|
|
|
|
|
/++
|
|
The starting point of the interval. It is included in the interval.
|
|
|
|
Params:
|
|
timePoint = The time point to set $(D begin) to.
|
|
+/
|
|
@property void begin(TP timePoint) pure nothrow
|
|
{
|
|
_begin = timePoint;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the interval's length is 0. Always returns false.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).empty);
|
|
--------------------
|
|
+/
|
|
@property bool empty() const pure nothrow
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given time point is within this interval.
|
|
|
|
Params:
|
|
timePoint = The time point to check for inclusion in this interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(Date(1994, 12, 24)));
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(Date(2000, 1, 5)));
|
|
--------------------
|
|
+/
|
|
bool contains(TP timePoint) const pure nothrow
|
|
{
|
|
return timePoint >= _begin;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval is completely within this interval.
|
|
|
|
Params:
|
|
interval = The interval to check for inclusion in this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(
|
|
Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
|
|
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(
|
|
Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
|
|
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(
|
|
Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1))));
|
|
--------------------
|
|
+/
|
|
bool contains(in Interval!TP interval) const pure
|
|
{
|
|
interval._enforceNotEmpty();
|
|
|
|
return interval._begin >= _begin;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval is completely within this interval.
|
|
|
|
Params:
|
|
interval = The interval to check for inclusion in this interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(
|
|
PosInfInterval!Date(Date(1999, 5, 4))));
|
|
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(
|
|
PosInfInterval!Date(Date(1995, 7, 2))));
|
|
--------------------
|
|
+/
|
|
bool contains(in PosInfInterval interval) const pure nothrow
|
|
{
|
|
return interval._begin >= _begin;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval is completely within this interval.
|
|
|
|
Always returns false because an interval going to positive infinity
|
|
can never contain an interval beginning at negative infinity.
|
|
|
|
Params:
|
|
interval = The interval to check for inclusion in this interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(
|
|
NegInfInterval!Date(Date(1996, 5, 4))));
|
|
--------------------
|
|
+/
|
|
bool contains(in NegInfInterval!TP interval) const pure nothrow
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this interval is before the given time point.
|
|
|
|
Always returns false because an interval going to positive infinity
|
|
can never be before any time point.
|
|
|
|
Params:
|
|
timePoint = The time point to check whether this interval is before
|
|
it.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Date(1994, 12, 24)));
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Date(2000, 1, 5)));
|
|
--------------------
|
|
+/
|
|
bool isBefore(in TP timePoint) const pure nothrow
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this interval is before the given interval and does not
|
|
intersect it.
|
|
|
|
Always returns false (unless the given interval is empty) because an
|
|
interval going to positive infinity can never be before any other
|
|
interval.
|
|
|
|
Params:
|
|
interval = The interval to check for against this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(
|
|
Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
|
|
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(
|
|
Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
|
|
--------------------
|
|
+/
|
|
bool isBefore(in Interval!TP interval) const pure
|
|
{
|
|
interval._enforceNotEmpty();
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this interval is before the given interval and does not
|
|
intersect it.
|
|
|
|
Always returns false because an interval going to positive infinity can
|
|
never be before any other interval.
|
|
|
|
Params:
|
|
interval = The interval to check for against this interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(
|
|
PosInfInterval!Date(Date(1992, 5, 4))));
|
|
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(
|
|
PosInfInterval!Date(Date(2013, 3, 7))));
|
|
--------------------
|
|
+/
|
|
bool isBefore(in PosInfInterval interval) const pure nothrow
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this interval is before the given interval and does not
|
|
intersect it.
|
|
|
|
Always returns false because an interval going to positive infinity can
|
|
never be before any other interval.
|
|
|
|
Params:
|
|
interval = The interval to check for against this interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(
|
|
NegInfInterval!Date(Date(1996, 5, 4))));
|
|
--------------------
|
|
+/
|
|
bool isBefore(in NegInfInterval!TP interval) const pure nothrow
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this interval is after the given time point.
|
|
|
|
Params:
|
|
timePoint = The time point to check whether this interval is after
|
|
it.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Date(1994, 12, 24)));
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Date(2000, 1, 5)));
|
|
--------------------
|
|
+/
|
|
bool isAfter(in TP timePoint) const pure nothrow
|
|
{
|
|
return timePoint < _begin;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this interval is after the given interval and does not intersect
|
|
it.
|
|
|
|
Params:
|
|
interval = The interval to check against this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(
|
|
Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
|
|
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(
|
|
Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
|
|
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(
|
|
Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));
|
|
--------------------
|
|
+/
|
|
bool isAfter(in Interval!TP interval) const pure
|
|
{
|
|
interval._enforceNotEmpty();
|
|
|
|
return _begin >= interval._end;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this interval is after the given interval and does not intersect
|
|
it.
|
|
|
|
Always returns false because an interval going to positive infinity can
|
|
never be after another interval going to positive infinity.
|
|
|
|
Params:
|
|
interval = The interval to check against this interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(
|
|
PosInfInterval!Date(Date(1990, 1, 7))));
|
|
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(
|
|
PosInfInterval!Date(Date(1999, 5, 4))));
|
|
--------------------
|
|
+/
|
|
bool isAfter(in PosInfInterval interval) const pure nothrow
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this interval is after the given interval and does not intersect
|
|
it.
|
|
|
|
Params:
|
|
interval = The interval to check against this interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(
|
|
NegInfInterval!Date(Date(1996, 1, 2))));
|
|
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(
|
|
NegInfInterval!Date(Date(2000, 7, 1))));
|
|
--------------------
|
|
+/
|
|
bool isAfter(in NegInfInterval!TP interval) const pure nothrow
|
|
{
|
|
return _begin >= interval._end;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval overlaps this interval.
|
|
|
|
Params:
|
|
interval = The interval to check for intersection with this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(
|
|
Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
|
|
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(
|
|
Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
|
|
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).intersects(
|
|
Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));
|
|
--------------------
|
|
+/
|
|
bool intersects(in Interval!TP interval) const pure
|
|
{
|
|
interval._enforceNotEmpty();
|
|
|
|
return interval._end > _begin;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval overlaps this interval.
|
|
|
|
Always returns true because two intervals going to positive infinity
|
|
always overlap.
|
|
|
|
Params:
|
|
interval = The interval to check for intersection with this
|
|
interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(
|
|
PosInfInterval!Date(Date(1990, 1, 7))));
|
|
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(
|
|
PosInfInterval!Date(Date(1999, 5, 4))));
|
|
--------------------
|
|
+/
|
|
bool intersects(in PosInfInterval interval) const pure nothrow
|
|
{
|
|
return true;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval overlaps this interval.
|
|
|
|
Params:
|
|
interval = The interval to check for intersection with this
|
|
interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).intersects(
|
|
NegInfInterval!Date(Date(1996, 1, 2))));
|
|
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(
|
|
NegInfInterval!Date(Date(2000, 7, 1))));
|
|
--------------------
|
|
+/
|
|
bool intersects(in NegInfInterval!TP interval) const pure nothrow
|
|
{
|
|
return _begin < interval._end;
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the intersection of two intervals
|
|
|
|
Params:
|
|
interval = The interval to intersect with this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the two intervals do not intersect or if
|
|
the given interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(
|
|
Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==
|
|
Interval!Date(Date(1996, 1 , 2), Date(2000, 8, 2)));
|
|
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(
|
|
Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) ==
|
|
Interval!Date(Date(1999, 1 , 12), Date(2011, 9, 17)));
|
|
--------------------
|
|
+/
|
|
Interval!TP intersection(in Interval!TP interval) const
|
|
{
|
|
enforce(this.intersects(interval), new DateTimeException(format("%s and %s do not intersect.", this, interval)));
|
|
|
|
auto begin = _begin > interval._begin ? _begin : interval._begin;
|
|
|
|
return Interval!TP(begin, interval._end);
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the intersection of two intervals
|
|
|
|
Params:
|
|
interval = The interval to intersect with this interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(
|
|
PosInfInterval!Date(Date(1990, 7, 6))) ==
|
|
PosInfInterval!Date(Date(1996, 1 , 2)));
|
|
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(
|
|
PosInfInterval!Date(Date(1999, 1, 12))) ==
|
|
PosInfInterval!Date(Date(1999, 1 , 12)));
|
|
--------------------
|
|
+/
|
|
PosInfInterval intersection(in PosInfInterval interval) const pure nothrow
|
|
{
|
|
return PosInfInterval(_begin < interval._begin ? interval._begin : _begin);
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the intersection of two intervals
|
|
|
|
Params:
|
|
interval = The interval to intersect with this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the two intervals do not intersect.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(
|
|
NegInfInterval!Date(Date(1999, 7, 6))) ==
|
|
Interval!Date(Date(1996, 1 , 2), Date(1999, 7, 6)));
|
|
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(
|
|
NegInfInterval!Date(Date(2013, 1, 12))) ==
|
|
Interval!Date(Date(1996, 1 , 2), Date(2013, 1, 12)));
|
|
--------------------
|
|
+/
|
|
Interval!TP intersection(in NegInfInterval!TP interval) const
|
|
{
|
|
enforce(this.intersects(interval), new DateTimeException(format("%s and %s do not intersect.", this, interval)));
|
|
|
|
return Interval!TP(_begin, interval._end);
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval is adjacent to this interval.
|
|
|
|
Params:
|
|
interval = The interval to check whether its adjecent to this
|
|
interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(
|
|
Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));
|
|
|
|
assert(!PosInfInterval!Date(Date(1999, 1, 12)).isAdjacent(
|
|
Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
|
|
--------------------
|
|
+/
|
|
bool isAdjacent(in Interval!TP interval) const pure
|
|
{
|
|
interval._enforceNotEmpty();
|
|
|
|
return _begin == interval._end;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval is adjacent to this interval.
|
|
|
|
Always returns false because two intervals going to positive infinity
|
|
can never be adjacent to one another.
|
|
|
|
Params:
|
|
interval = The interval to check whether its adjecent to this
|
|
interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(
|
|
PosInfInterval!Date(Date(1990, 1, 7))));
|
|
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(
|
|
PosInfInterval!Date(Date(1996, 1, 2))));
|
|
--------------------
|
|
+/
|
|
bool isAdjacent(in PosInfInterval interval) const pure nothrow
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval is adjacent to this interval.
|
|
|
|
Params:
|
|
interval = The interval to check whether its adjecent to this
|
|
interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(
|
|
NegInfInterval!Date(Date(1996, 1, 2))));
|
|
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(
|
|
NegInfInterval!Date(Date(2000, 7, 1))));
|
|
--------------------
|
|
+/
|
|
bool isAdjacent(in NegInfInterval!TP interval) const pure nothrow
|
|
{
|
|
return _begin == interval._end;
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the union of two intervals
|
|
|
|
Params:
|
|
interval = The interval to merge with this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the two intervals do not intersect and are
|
|
not adjacent or if the given interval is empty.
|
|
|
|
Note:
|
|
There is no overload for $(D merge) which takes a
|
|
$(D NegInfInterval). This is because you can't have an interval
|
|
which goes from negative infinity to positive infinity.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(
|
|
Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==
|
|
PosInfInterval!Date(Date(1990, 7 , 6)));
|
|
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(
|
|
Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) ==
|
|
PosInfInterval!Date(Date(1996, 1 , 2)));
|
|
--------------------
|
|
+/
|
|
PosInfInterval merge(in Interval!TP interval) const
|
|
{
|
|
enforce(this.isAdjacent(interval) || this.intersects(interval),
|
|
new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval)));
|
|
|
|
return PosInfInterval(_begin < interval._begin ? _begin : interval._begin);
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the union of two intervals
|
|
|
|
Params:
|
|
interval = The interval to merge with this interval.
|
|
|
|
Note:
|
|
There is no overload for $(D merge) which takes a
|
|
$(D NegInfInterval). This is because you can't have an interval
|
|
which goes from negative infinity to positive infinity.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(
|
|
PosInfInterval!Date(Date(1990, 7, 6))) ==
|
|
PosInfInterval!Date(Date(1990, 7 , 6)));
|
|
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(
|
|
PosInfInterval!Date(Date(1999, 1, 12))) ==
|
|
PosInfInterval!Date(Date(1996, 1 , 2)));
|
|
--------------------
|
|
+/
|
|
PosInfInterval merge(in PosInfInterval interval) const pure nothrow
|
|
{
|
|
return PosInfInterval(_begin < interval._begin ? _begin : interval._begin);
|
|
}
|
|
|
|
|
|
/++
|
|
Returns an interval that covers from the earliest time point of two
|
|
intervals up to (but not including) the latest time point of two
|
|
intervals.
|
|
|
|
Params:
|
|
interval = The interval to create a span together with this
|
|
interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given interval is empty.
|
|
|
|
Note:
|
|
There is no overload for $(D span) which takes a
|
|
$(D NegInfInterval). This is because you can't have an interval
|
|
which goes from negative infinity to positive infinity.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).span(
|
|
Interval!Date(Date(500, 8, 9), Date(1602, 1, 31))) ==
|
|
PosInfInterval!Date(Date(500, 8, 9)));
|
|
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).span(
|
|
Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==
|
|
PosInfInterval!Date(Date(1990, 7 , 6)));
|
|
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).span(
|
|
Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) ==
|
|
PosInfInterval!Date(Date(1996, 1 , 2)));
|
|
--------------------
|
|
+/
|
|
PosInfInterval span(in Interval!TP interval) const pure
|
|
{
|
|
interval._enforceNotEmpty();
|
|
|
|
return PosInfInterval(_begin < interval._begin ? _begin : interval._begin);
|
|
}
|
|
|
|
|
|
/++
|
|
Returns an interval that covers from the earliest time point of two
|
|
intervals up to (but not including) the latest time point of two
|
|
intervals.
|
|
|
|
Params:
|
|
interval = The interval to create a span together with this
|
|
interval.
|
|
|
|
Note:
|
|
There is no overload for $(D span) which takes a
|
|
$(D NegInfInterval). This is because you can't have an interval
|
|
which goes from negative infinity to positive infinity.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).span(
|
|
PosInfInterval!Date(Date(1990, 7, 6))) ==
|
|
PosInfInterval!Date(Date(1990, 7 , 6)));
|
|
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).span(
|
|
PosInfInterval!Date(Date(1999, 1, 12))) ==
|
|
PosInfInterval!Date(Date(1996, 1 , 2)));
|
|
--------------------
|
|
+/
|
|
PosInfInterval span(in PosInfInterval interval) const pure nothrow
|
|
{
|
|
return PosInfInterval(_begin < interval._begin ? _begin : interval._begin);
|
|
}
|
|
|
|
|
|
/++
|
|
Shifts the $(D begin) of this interval forward or backwards in time by
|
|
the given duration (a positive duration shifts the interval forward; a
|
|
negative duration shifts it backward). Effectively, it does
|
|
$(D begin += duration).
|
|
|
|
Params:
|
|
duration = The duration to shift the interval by.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto interval1 = PosInfInterval!Date(Date(1996, 1, 2));
|
|
auto interval2 = PosInfInterval!Date(Date(1996, 1, 2));
|
|
|
|
interval1.shift(dur!"days"(50));
|
|
assert(interval1 == PosInfInterval!Date(Date(1996, 2, 21)));
|
|
|
|
interval2.shift(dur!"days"(-50));
|
|
assert(interval2 == PosInfInterval!Date(Date(1995, 11, 13)));
|
|
--------------------
|
|
+/
|
|
void shift(D)(D duration) pure nothrow
|
|
if(__traits(compiles, begin + duration))
|
|
{
|
|
_begin += duration;
|
|
}
|
|
|
|
|
|
static if(__traits(compiles, begin.add!"months"(1)) &&
|
|
__traits(compiles, begin.add!"years"(1)))
|
|
{
|
|
/++
|
|
Shifts the $(D begin) of this interval forward or backwards in time
|
|
by the given number of years and/or months (a positive number of years
|
|
and months shifts the interval forward; a negative number shifts it
|
|
backward). It adds the years the given years and months to
|
|
$(D begin). It effectively calls $(D add!"years"()) and then
|
|
$(D add!"months"()) on $(D begin) with the given number of years and
|
|
months.
|
|
|
|
Params:
|
|
years = The number of years to shift the interval by.
|
|
months = The number of months to shift the interval by.
|
|
allowOverflow = Whether the days should be allowed to overflow
|
|
on $(D begin), causing its month to increment.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if this interval is empty or if the
|
|
resulting interval would be invalid.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto interval1 = PosInfInterval!Date(Date(1996, 1, 2));
|
|
auto interval2 = PosInfInterval!Date(Date(1996, 1, 2));
|
|
|
|
interval1.shift(dur!"days"(50));
|
|
assert(interval1 == PosInfInterval!Date(Date(1996, 2, 21)));
|
|
|
|
interval2.shift(dur!"days"(-50));
|
|
assert(interval2 == PosInfInterval!Date(Date(1995, 11, 13)));
|
|
--------------------
|
|
+/
|
|
void shift(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes)
|
|
if(isIntegral!T)
|
|
{
|
|
auto begin = _begin;
|
|
|
|
begin.add!"years"(years, allowOverflow);
|
|
begin.add!"months"(months, allowOverflow);
|
|
|
|
_begin = begin;
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Expands the interval backwards in time. Effectively, it does
|
|
$(D begin -= duration).
|
|
|
|
Params:
|
|
duration = The duration to expand the interval by.
|
|
dir = The direction in time to expand the interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto interval1 = PosInfInterval!Date(Date(1996, 1, 2));
|
|
auto interval2 = PosInfInterval!Date(Date(1996, 1, 2));
|
|
|
|
interval1.expand(dur!"days"(2));
|
|
assert(interval1 == PosInfInterval!Date(Date(1995, 12, 31)));
|
|
|
|
interval2.expand(dur!"days"(-2));
|
|
assert(interval2 == PosInfInterval!Date(Date(1996, 1, 4)));
|
|
--------------------
|
|
+/
|
|
void expand(D)(D duration) pure nothrow
|
|
if(__traits(compiles, begin + duration))
|
|
{
|
|
_begin -= duration;
|
|
}
|
|
|
|
|
|
static if(__traits(compiles, begin.add!"months"(1)) &&
|
|
__traits(compiles, begin.add!"years"(1)))
|
|
{
|
|
/++
|
|
Expands the interval forwards and/or backwards in time. Effectively,
|
|
it subtracts the given number of months/years from $(D begin).
|
|
|
|
Params:
|
|
years = The number of years to expand the interval by.
|
|
months = The number of months to expand the interval by.
|
|
allowOverflow = Whether the days should be allowed to overflow
|
|
on $(D begin), causing its month to increment.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if this interval is empty or if the
|
|
resulting interval would be invalid.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto interval1 = PosInfInterval!Date(Date(1996, 1, 2));
|
|
auto interval2 = PosInfInterval!Date(Date(1996, 1, 2));
|
|
|
|
interval1.expand(2);
|
|
assert(interval1 == PosInfInterval!Date(Date(1994, 1, 2)));
|
|
|
|
interval2.expand(-2);
|
|
assert(interval2 == PosInfInterval!Date(Date(1998, 1, 2)));
|
|
--------------------
|
|
+/
|
|
void expand(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes)
|
|
if(isIntegral!T)
|
|
{
|
|
auto begin = _begin;
|
|
|
|
begin.add!"years"(-years, allowOverflow);
|
|
begin.add!"months"(-months, allowOverflow);
|
|
|
|
_begin = begin;
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns a range which iterates forward over the interval, starting
|
|
at $(D begin), using $(D_PARAM func) to generate each successive time
|
|
point.
|
|
|
|
The range's $(D front) is the interval's $(D begin). $(D_PARAM func) is
|
|
used to generate the next $(D front) when $(D popFront) is called. If
|
|
$(D_PARAM popFirst) is $(D PopFirst.yes), then $(D popFront) is called
|
|
before the range is returned (so that $(D front) is a time point which
|
|
$(D_PARAM func) would generate).
|
|
|
|
If $(D_PARAM func) ever generates a time point less than or equal to the
|
|
current $(D front) of the range, then a $(D DateTimeException) will be
|
|
thrown.
|
|
|
|
There are helper functions in this module which generate common
|
|
delegates to pass to $(D fwdRange). Their documentation starts with
|
|
"Range-generating function," so you can easily search for them.
|
|
|
|
Params:
|
|
func = The function used to generate the time points of the
|
|
range over the interval.
|
|
popFirst = Whether $(D popFront) should be called on the range
|
|
before returning it.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if this interval is empty.
|
|
|
|
Warning:
|
|
$(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func)
|
|
would be a function pointer to a pure function, but forcing
|
|
$(D_PARAM func) to be pure is far too restrictive to be useful, and
|
|
in order to have the ease of use of having functions which generate
|
|
functions to pass to $(D fwdRange), $(D_PARAM func) must be a
|
|
delegate.
|
|
|
|
If $(D_PARAM func) retains state which changes as it is called, then
|
|
some algorithms will not work correctly, because the range's
|
|
$(D save) will have failed to have really saved the range's state.
|
|
So, if you want to avoid such bugs, don't pass a delegate which is
|
|
not logically pure to $(D fwdRange). If $(D_PARAM func) is given the
|
|
same time point with two different calls, it must return the same
|
|
result both times.
|
|
|
|
Of course, none of the functions in this module have this problem,
|
|
so it's only relevant if you're creating your own delegate.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto interval = PosInfInterval!Date(Date(2010, 9, 1));
|
|
auto func = (in Date date) //For iterating over even-numbered days.
|
|
{
|
|
if((date.day & 1) == 0)
|
|
return date + dur!"days"(2);
|
|
|
|
return date + dur!"days"(1);
|
|
};
|
|
auto range = interval.fwdRange(func);
|
|
|
|
//An odd day. Using PopFirst.yes would have made this Date(2010, 9, 2).
|
|
assert(range.front == Date(2010, 9, 1));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 2));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 4));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 6));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 8));
|
|
|
|
range.popFront();
|
|
assert(!range.empty);
|
|
--------------------
|
|
+/
|
|
PosInfIntervalRange!(TP) fwdRange(TP delegate(in TP) func, PopFirst popFirst = PopFirst.no) const
|
|
{
|
|
auto range = PosInfIntervalRange!(TP)(this, func);
|
|
|
|
if(popFirst == PopFirst.yes)
|
|
range.popFront();
|
|
|
|
return range;
|
|
}
|
|
|
|
|
|
/+
|
|
Converts this interval to a string.
|
|
+/
|
|
//Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't
|
|
//have versions of toString() with extra modifiers, so we define one version
|
|
//with modifiers and one without.
|
|
string toString()
|
|
{
|
|
return _toStringImpl();
|
|
}
|
|
|
|
|
|
/++
|
|
Converts this interval to a string.
|
|
+/
|
|
//Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't
|
|
//have versions of toString() with extra modifiers, so we define one version
|
|
//with modifiers and one without.
|
|
string toString() const nothrow
|
|
{
|
|
return _toStringImpl();
|
|
}
|
|
|
|
private:
|
|
|
|
/+
|
|
Since we have two versions of toString(), we have _toStringImpl()
|
|
so that they can share implementations.
|
|
+/
|
|
string _toStringImpl() const nothrow
|
|
{
|
|
try
|
|
return format("[%s - ∞)", _begin);
|
|
catch(Exception e)
|
|
assert(0, "format() threw.");
|
|
}
|
|
|
|
|
|
TP _begin;
|
|
}
|
|
|
|
//Test PosInfInterval's constructor.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
PosInfInterval!Date(Date.init);
|
|
PosInfInterval!TimeOfDay(TimeOfDay.init);
|
|
PosInfInterval!DateTime(DateTime.init);
|
|
PosInfInterval!SysTime(SysTime(0));
|
|
|
|
//Verify Examples.
|
|
auto interval = PosInfInterval!Date(Date(1996, 1, 2));
|
|
}
|
|
}
|
|
|
|
//Test PosInfInterval's begin.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(PosInfInterval!Date(Date(1, 1, 1)).begin, Date(1, 1, 1));
|
|
_assertPred!"=="(PosInfInterval!Date(Date(2010, 1, 1)).begin, Date(2010, 1, 1));
|
|
_assertPred!"=="(PosInfInterval!Date(Date(1997, 12, 31)).begin, Date(1997, 12, 31));
|
|
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
static assert(__traits(compiles, cPosInfInterval.begin));
|
|
static assert(__traits(compiles, iPosInfInterval.begin));
|
|
|
|
//Verify Examples.
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).begin == Date(1996, 1, 2));
|
|
}
|
|
}
|
|
|
|
//Test PosInfInterval's empty.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assert(!PosInfInterval!Date(Date(2010, 1, 1)).empty);
|
|
assert(!PosInfInterval!TimeOfDay(TimeOfDay(0, 30, 0)).empty);
|
|
assert(!PosInfInterval!DateTime(DateTime(2010, 1, 1, 0, 30, 0)).empty);
|
|
assert(!PosInfInterval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0))).empty);
|
|
|
|
const cPosInfInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iPosInfInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
static assert(__traits(compiles, cPosInfInterval.empty));
|
|
static assert(__traits(compiles, iPosInfInterval.empty));
|
|
|
|
//Verify Examples.
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).empty);
|
|
}
|
|
}
|
|
|
|
//Test PosInfInterval's contains(time point).
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
|
|
assert(!posInfInterval.contains(Date(2009, 7, 4)));
|
|
assert(!posInfInterval.contains(Date(2010, 7, 3)));
|
|
assert(posInfInterval.contains(Date(2010, 7, 4)));
|
|
assert(posInfInterval.contains(Date(2010, 7, 5)));
|
|
assert(posInfInterval.contains(Date(2011, 7, 1)));
|
|
assert(posInfInterval.contains(Date(2012, 1, 6)));
|
|
assert(posInfInterval.contains(Date(2012, 1, 7)));
|
|
assert(posInfInterval.contains(Date(2012, 1, 8)));
|
|
assert(posInfInterval.contains(Date(2013, 1, 7)));
|
|
|
|
const cdate = Date(2010, 7, 6);
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
static assert(__traits(compiles, posInfInterval.contains(cdate)));
|
|
static assert(__traits(compiles, cPosInfInterval.contains(cdate)));
|
|
static assert(__traits(compiles, iPosInfInterval.contains(cdate)));
|
|
|
|
//Verify Examples.
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(Date(1994, 12, 24)));
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(Date(2000, 1, 5)));
|
|
}
|
|
}
|
|
|
|
//Test PosInfInterval's contains(Interval).
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
|
|
static void testInterval(in PosInfInterval!Date posInfInterval, in Interval!Date interval)
|
|
{
|
|
posInfInterval.contains(interval);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
|
|
assert(posInfInterval.contains(posInfInterval));
|
|
assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
|
|
assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
|
|
assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
|
|
assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
|
|
assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
|
|
assert(!posInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
|
|
assert(posInfInterval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
|
|
assert(posInfInterval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
|
|
assert(posInfInterval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
|
|
assert(posInfInterval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
|
|
assert(posInfInterval.contains(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
|
|
assert(posInfInterval.contains(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
|
|
|
|
assert(!posInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(posInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(posInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(posInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(posInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(posInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
assert(PosInfInterval!Date(Date(2010, 7, 3)).contains(posInfInterval));
|
|
assert(PosInfInterval!Date(Date(2010, 7, 4)).contains(posInfInterval));
|
|
assert(!PosInfInterval!Date(Date(2010, 7, 5)).contains(posInfInterval));
|
|
assert(!PosInfInterval!Date(Date(2012, 1, 6)).contains(posInfInterval));
|
|
assert(!PosInfInterval!Date(Date(2012, 1, 7)).contains(posInfInterval));
|
|
assert(!PosInfInterval!Date(Date(2012, 1, 8)).contains(posInfInterval));
|
|
|
|
assert(!posInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(!posInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(!posInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(!posInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(!posInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(!posInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, posInfInterval.contains(interval)));
|
|
static assert(__traits(compiles, posInfInterval.contains(cInterval)));
|
|
static assert(__traits(compiles, posInfInterval.contains(iInterval)));
|
|
static assert(__traits(compiles, posInfInterval.contains(posInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.contains(cPosInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.contains(iPosInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.contains(negInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.contains(cNegInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.contains(iNegInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.contains(interval)));
|
|
static assert(__traits(compiles, cPosInfInterval.contains(cInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.contains(iInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.contains(posInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.contains(cPosInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.contains(iPosInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.contains(negInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.contains(cNegInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.contains(iNegInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.contains(interval)));
|
|
static assert(__traits(compiles, iPosInfInterval.contains(cInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.contains(iInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.contains(posInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.contains(cPosInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.contains(iPosInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.contains(negInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.contains(cNegInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.contains(iNegInfInterval)));
|
|
|
|
//Verify Examples.
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1))));
|
|
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).contains(PosInfInterval!Date(Date(1999, 5, 4))));
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(PosInfInterval!Date(Date(1995, 7, 2))));
|
|
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).contains(NegInfInterval!Date(Date(1996, 5, 4))));
|
|
}
|
|
}
|
|
|
|
//Test PosInfInterval's isBefore(time point).
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
|
|
assert(!posInfInterval.isBefore(Date(2009, 7, 3)));
|
|
assert(!posInfInterval.isBefore(Date(2010, 7, 3)));
|
|
assert(!posInfInterval.isBefore(Date(2010, 7, 4)));
|
|
assert(!posInfInterval.isBefore(Date(2010, 7, 5)));
|
|
assert(!posInfInterval.isBefore(Date(2011, 7, 1)));
|
|
assert(!posInfInterval.isBefore(Date(2012, 1, 6)));
|
|
assert(!posInfInterval.isBefore(Date(2012, 1, 7)));
|
|
assert(!posInfInterval.isBefore(Date(2012, 1, 8)));
|
|
assert(!posInfInterval.isBefore(Date(2013, 1, 7)));
|
|
|
|
const cdate = Date(2010, 7, 6);
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
static assert(__traits(compiles, posInfInterval.isBefore(cdate)));
|
|
static assert(__traits(compiles, cPosInfInterval.isBefore(cdate)));
|
|
static assert(__traits(compiles, iPosInfInterval.isBefore(cdate)));
|
|
|
|
//Verify Examples.
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Date(1994, 12, 24)));
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Date(2000, 1, 5)));
|
|
}
|
|
}
|
|
|
|
//Test PosInfInterval's isBefore(Interval).
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
|
|
static void testInterval(in PosInfInterval!Date posInfInterval, in Interval!Date interval)
|
|
{
|
|
posInfInterval.isBefore(interval);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
|
|
assert(!posInfInterval.isBefore(posInfInterval));
|
|
assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
|
|
assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
|
|
assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
|
|
assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
|
|
assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
|
|
assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
|
|
assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
|
|
assert(!posInfInterval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
|
|
assert(!posInfInterval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
|
|
assert(!posInfInterval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
|
|
assert(!posInfInterval.isBefore(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
|
|
assert(!posInfInterval.isBefore(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
|
|
|
|
assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(!posInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
assert(!PosInfInterval!Date(Date(2010, 7, 3)).isBefore(posInfInterval));
|
|
assert(!PosInfInterval!Date(Date(2010, 7, 4)).isBefore(posInfInterval));
|
|
assert(!PosInfInterval!Date(Date(2010, 7, 5)).isBefore(posInfInterval));
|
|
assert(!PosInfInterval!Date(Date(2012, 1, 6)).isBefore(posInfInterval));
|
|
assert(!PosInfInterval!Date(Date(2012, 1, 7)).isBefore(posInfInterval));
|
|
assert(!PosInfInterval!Date(Date(2012, 1, 8)).isBefore(posInfInterval));
|
|
|
|
assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(!posInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, posInfInterval.isBefore(interval)));
|
|
static assert(__traits(compiles, posInfInterval.isBefore(cInterval)));
|
|
static assert(__traits(compiles, posInfInterval.isBefore(iInterval)));
|
|
static assert(__traits(compiles, posInfInterval.isBefore(posInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.isBefore(cPosInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.isBefore(iPosInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.isBefore(negInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.isBefore(cNegInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.isBefore(iNegInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isBefore(interval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isBefore(cInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isBefore(iInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isBefore(posInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isBefore(cPosInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isBefore(iPosInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isBefore(negInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isBefore(cNegInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isBefore(iNegInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isBefore(interval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isBefore(cInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isBefore(iInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isBefore(posInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isBefore(cPosInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isBefore(iPosInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isBefore(negInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isBefore(cNegInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isBefore(iNegInfInterval)));
|
|
|
|
//Verify Examples.
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
|
|
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(PosInfInterval!Date(Date(1992, 5, 4))));
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(PosInfInterval!Date(Date(2013, 3, 7))));
|
|
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isBefore(NegInfInterval!Date(Date(1996, 5, 4))));
|
|
}
|
|
}
|
|
|
|
//Test PosInfInterval's isAfter(time point).
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
|
|
assert(posInfInterval.isAfter(Date(2009, 7, 3)));
|
|
assert(posInfInterval.isAfter(Date(2010, 7, 3)));
|
|
assert(!posInfInterval.isAfter(Date(2010, 7, 4)));
|
|
assert(!posInfInterval.isAfter(Date(2010, 7, 5)));
|
|
assert(!posInfInterval.isAfter(Date(2011, 7, 1)));
|
|
assert(!posInfInterval.isAfter(Date(2012, 1, 6)));
|
|
assert(!posInfInterval.isAfter(Date(2012, 1, 7)));
|
|
assert(!posInfInterval.isAfter(Date(2012, 1, 8)));
|
|
assert(!posInfInterval.isAfter(Date(2013, 1, 7)));
|
|
|
|
const cdate = Date(2010, 7, 6);
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
static assert(__traits(compiles, posInfInterval.isAfter(cdate)));
|
|
static assert(__traits(compiles, cPosInfInterval.isAfter(cdate)));
|
|
static assert(__traits(compiles, iPosInfInterval.isAfter(cdate)));
|
|
|
|
//Verify Examples.
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Date(1994, 12, 24)));
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Date(2000, 1, 5)));
|
|
}
|
|
}
|
|
|
|
//Test PosInfInterval's isAfter(Interval).
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
|
|
static void testInterval(in PosInfInterval!Date posInfInterval, in Interval!Date interval)
|
|
{
|
|
posInfInterval.isAfter(interval);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
|
|
assert(!posInfInterval.isAfter(posInfInterval));
|
|
assert(posInfInterval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
|
|
assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
|
|
assert(posInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
|
|
assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
|
|
assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
|
|
assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
|
|
assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
|
|
assert(!posInfInterval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
|
|
assert(!posInfInterval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
|
|
assert(!posInfInterval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
|
|
assert(!posInfInterval.isAfter(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
|
|
assert(!posInfInterval.isAfter(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
|
|
|
|
assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(!posInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
assert(!PosInfInterval!Date(Date(2010, 7, 3)).isAfter(posInfInterval));
|
|
assert(!PosInfInterval!Date(Date(2010, 7, 4)).isAfter(posInfInterval));
|
|
assert(!PosInfInterval!Date(Date(2010, 7, 5)).isAfter(posInfInterval));
|
|
assert(!PosInfInterval!Date(Date(2012, 1, 6)).isAfter(posInfInterval));
|
|
assert(!PosInfInterval!Date(Date(2012, 1, 7)).isAfter(posInfInterval));
|
|
assert(!PosInfInterval!Date(Date(2012, 1, 8)).isAfter(posInfInterval));
|
|
|
|
assert(posInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(posInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(!posInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(!posInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(!posInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(!posInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, posInfInterval.isAfter(interval)));
|
|
static assert(__traits(compiles, posInfInterval.isAfter(cInterval)));
|
|
static assert(__traits(compiles, posInfInterval.isAfter(iInterval)));
|
|
static assert(__traits(compiles, posInfInterval.isAfter(posInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.isAfter(cPosInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.isAfter(iPosInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.isAfter(negInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.isAfter(cNegInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.isAfter(iNegInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isAfter(interval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isAfter(cInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isAfter(iInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isAfter(posInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isAfter(cPosInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isAfter(iPosInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isAfter(negInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isAfter(cNegInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isAfter(iNegInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isAfter(interval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isAfter(cInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isAfter(iInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isAfter(posInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isAfter(cPosInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isAfter(iPosInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isAfter(negInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isAfter(cNegInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isAfter(iNegInfInterval)));
|
|
|
|
//Verify Examples.
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));
|
|
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(PosInfInterval!Date(Date(1990, 1, 7))));
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(PosInfInterval!Date(Date(1999, 5, 4))));
|
|
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).isAfter(NegInfInterval!Date(Date(1996, 1, 2))));
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAfter(NegInfInterval!Date(Date(2000, 7, 1))));
|
|
}
|
|
}
|
|
|
|
//Test PosInfInterval's intersects().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
|
|
static void testInterval(in PosInfInterval!Date posInfInterval, in Interval!Date interval)
|
|
{
|
|
posInfInterval.intersects(interval);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
|
|
assert(posInfInterval.intersects(posInfInterval));
|
|
assert(!posInfInterval.intersects(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
|
|
assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
|
|
assert(!posInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
|
|
assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
|
|
assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
|
|
assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
|
|
assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
|
|
assert(posInfInterval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
|
|
assert(posInfInterval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
|
|
assert(posInfInterval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
|
|
assert(posInfInterval.intersects(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
|
|
assert(posInfInterval.intersects(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
|
|
|
|
assert(posInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(posInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(posInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(posInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(posInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(posInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
assert(PosInfInterval!Date(Date(2010, 7, 3)).intersects(posInfInterval));
|
|
assert(PosInfInterval!Date(Date(2010, 7, 4)).intersects(posInfInterval));
|
|
assert(PosInfInterval!Date(Date(2010, 7, 5)).intersects(posInfInterval));
|
|
assert(PosInfInterval!Date(Date(2012, 1, 6)).intersects(posInfInterval));
|
|
assert(PosInfInterval!Date(Date(2012, 1, 7)).intersects(posInfInterval));
|
|
assert(PosInfInterval!Date(Date(2012, 1, 8)).intersects(posInfInterval));
|
|
|
|
assert(!posInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(!posInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(posInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(posInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(posInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(posInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, posInfInterval.intersects(interval)));
|
|
static assert(__traits(compiles, posInfInterval.intersects(cInterval)));
|
|
static assert(__traits(compiles, posInfInterval.intersects(iInterval)));
|
|
static assert(__traits(compiles, posInfInterval.intersects(posInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.intersects(cPosInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.intersects(iPosInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.intersects(negInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.intersects(cNegInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.intersects(iNegInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.intersects(interval)));
|
|
static assert(__traits(compiles, cPosInfInterval.intersects(cInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.intersects(iInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.intersects(posInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.intersects(cPosInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.intersects(iPosInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.intersects(negInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.intersects(cNegInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.intersects(iNegInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.intersects(interval)));
|
|
static assert(__traits(compiles, iPosInfInterval.intersects(cInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.intersects(iInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.intersects(posInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.intersects(cPosInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.intersects(iPosInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.intersects(negInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.intersects(cNegInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.intersects(iNegInfInterval)));
|
|
|
|
//Verify Examples.
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).intersects(Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));
|
|
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(PosInfInterval!Date(Date(1990, 1, 7))));
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(PosInfInterval!Date(Date(1999, 5, 4))));
|
|
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).intersects(NegInfInterval!Date(Date(1996, 1, 2))));
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).intersects(NegInfInterval!Date(Date(2000, 7, 1))));
|
|
}
|
|
}
|
|
|
|
//Test PosInfInterval's intersection().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
|
|
static void testInterval(I, J)(in I interval1, in J interval2)
|
|
{
|
|
interval1.intersection(interval2);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
|
|
assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
|
|
assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
|
|
|
|
assertThrown!DateTimeException(testInterval(posInfInterval, NegInfInterval!Date(Date(2010, 7, 3))));
|
|
assertThrown!DateTimeException(testInterval(posInfInterval, NegInfInterval!Date(Date(2010, 7, 4))));
|
|
|
|
_assertPred!"=="(posInfInterval.intersection(posInfInterval),
|
|
posInfInterval);
|
|
_assertPred!"=="(posInfInterval.intersection(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2013, 7, 3)));
|
|
_assertPred!"=="(posInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5)));
|
|
_assertPred!"=="(posInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
|
|
_assertPred!"=="(posInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));
|
|
_assertPred!"=="(posInfInterval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))),
|
|
Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)));
|
|
_assertPred!"=="(posInfInterval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))),
|
|
Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)));
|
|
_assertPred!"=="(posInfInterval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))),
|
|
Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)));
|
|
_assertPred!"=="(posInfInterval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))),
|
|
Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8)));
|
|
_assertPred!"=="(posInfInterval.intersection(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))),
|
|
Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8)));
|
|
_assertPred!"=="(posInfInterval.intersection(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))),
|
|
Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9)));
|
|
|
|
_assertPred!"=="(posInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 3))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(posInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 4))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(posInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 5))),
|
|
PosInfInterval!Date(Date(2010, 7, 5)));
|
|
_assertPred!"=="(posInfInterval.intersection(PosInfInterval!Date(Date(2012, 1, 6))),
|
|
PosInfInterval!Date(Date(2012, 1, 6)));
|
|
_assertPred!"=="(posInfInterval.intersection(PosInfInterval!Date(Date(2012, 1, 7))),
|
|
PosInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(posInfInterval.intersection(PosInfInterval!Date(Date(2012, 1, 8))),
|
|
PosInfInterval!Date(Date(2012, 1, 8)));
|
|
|
|
_assertPred!"=="(PosInfInterval!Date(Date(2010, 7, 3)).intersection(posInfInterval),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(PosInfInterval!Date(Date(2010, 7, 4)).intersection(posInfInterval),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(PosInfInterval!Date(Date(2010, 7, 5)).intersection(posInfInterval),
|
|
PosInfInterval!Date(Date(2010, 7, 5)));
|
|
_assertPred!"=="(PosInfInterval!Date(Date(2012, 1, 6)).intersection(posInfInterval),
|
|
PosInfInterval!Date(Date(2012, 1, 6)));
|
|
_assertPred!"=="(PosInfInterval!Date(Date(2012, 1, 7)).intersection(posInfInterval),
|
|
PosInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(PosInfInterval!Date(Date(2012, 1, 8)).intersection(posInfInterval),
|
|
PosInfInterval!Date(Date(2012, 1, 8)));
|
|
|
|
_assertPred!"=="(posInfInterval.intersection(NegInfInterval!Date(Date(2010, 7, 5))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2010, 7, 5)));
|
|
_assertPred!"=="(posInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 6))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 6)));
|
|
_assertPred!"=="(posInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 7))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)));
|
|
_assertPred!"=="(posInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 8))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1, 8)));
|
|
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, posInfInterval.intersection(interval)));
|
|
static assert(__traits(compiles, posInfInterval.intersection(cInterval)));
|
|
static assert(__traits(compiles, posInfInterval.intersection(iInterval)));
|
|
static assert(__traits(compiles, posInfInterval.intersection(posInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.intersection(cPosInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.intersection(iPosInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.intersection(negInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.intersection(cNegInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.intersection(iNegInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.intersection(interval)));
|
|
static assert(__traits(compiles, cPosInfInterval.intersection(cInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.intersection(iInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.intersection(posInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.intersection(cPosInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.intersection(iPosInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.intersection(negInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.intersection(cNegInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.intersection(iNegInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.intersection(interval)));
|
|
static assert(__traits(compiles, iPosInfInterval.intersection(cInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.intersection(iInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.intersection(posInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.intersection(cPosInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.intersection(iPosInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.intersection(negInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.intersection(cNegInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.intersection(iNegInfInterval)));
|
|
|
|
//Verify Examples.
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == Interval!Date(Date(1996, 1 , 2), Date(2000, 8, 2)));
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == Interval!Date(Date(1999, 1 , 12), Date(2011, 9, 17)));
|
|
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(PosInfInterval!Date(Date(1990, 7, 6))) == PosInfInterval!Date(Date(1996, 1 , 2)));
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(PosInfInterval!Date(Date(1999, 1, 12))) == PosInfInterval!Date(Date(1999, 1 , 12)));
|
|
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(NegInfInterval!Date(Date(1999, 7, 6))) == Interval!Date(Date(1996, 1 , 2), Date(1999, 7, 6)));
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).intersection(NegInfInterval!Date(Date(2013, 1, 12))) == Interval!Date(Date(1996, 1 , 2), Date(2013, 1, 12)));
|
|
}
|
|
}
|
|
|
|
//Test PosInfInterval's isAdjacent().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
|
|
static void testInterval(in PosInfInterval!Date posInfInterval, in Interval!Date interval)
|
|
{
|
|
posInfInterval.isAdjacent(interval);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
|
|
assert(!posInfInterval.isAdjacent(posInfInterval));
|
|
assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
|
|
assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
|
|
assert(posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
|
|
assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
|
|
assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
|
|
assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
|
|
assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
|
|
assert(!posInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
|
|
assert(!posInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
|
|
assert(!posInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
|
|
assert(!posInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
|
|
assert(!posInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
|
|
|
|
assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(!posInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
assert(!PosInfInterval!Date(Date(2010, 7, 3)).isAdjacent(posInfInterval));
|
|
assert(!PosInfInterval!Date(Date(2010, 7, 4)).isAdjacent(posInfInterval));
|
|
assert(!PosInfInterval!Date(Date(2010, 7, 5)).isAdjacent(posInfInterval));
|
|
assert(!PosInfInterval!Date(Date(2012, 1, 6)).isAdjacent(posInfInterval));
|
|
assert(!PosInfInterval!Date(Date(2012, 1, 7)).isAdjacent(posInfInterval));
|
|
assert(!PosInfInterval!Date(Date(2012, 1, 8)).isAdjacent(posInfInterval));
|
|
|
|
assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(posInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(!posInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, posInfInterval.isAdjacent(interval)));
|
|
static assert(__traits(compiles, posInfInterval.isAdjacent(cInterval)));
|
|
static assert(__traits(compiles, posInfInterval.isAdjacent(iInterval)));
|
|
static assert(__traits(compiles, posInfInterval.isAdjacent(posInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.isAdjacent(cPosInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.isAdjacent(iPosInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.isAdjacent(negInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.isAdjacent(cNegInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.isAdjacent(iNegInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isAdjacent(interval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isAdjacent(cInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isAdjacent(iInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isAdjacent(posInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isAdjacent(cPosInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isAdjacent(iPosInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isAdjacent(negInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isAdjacent(cNegInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.isAdjacent(iNegInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isAdjacent(interval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isAdjacent(cInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isAdjacent(iInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isAdjacent(posInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isAdjacent(cPosInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isAdjacent(iPosInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isAdjacent(negInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isAdjacent(cNegInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.isAdjacent(iNegInfInterval)));
|
|
|
|
//Verify Examples.
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(Interval!Date(Date(1989, 3, 1), Date(1996, 1, 2))));
|
|
assert(!PosInfInterval!Date(Date(1999, 1, 12)).isAdjacent(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
|
|
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(PosInfInterval!Date(Date(1990, 1, 7))));
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(PosInfInterval!Date(Date(1996, 1, 2))));
|
|
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(NegInfInterval!Date(Date(1996, 1, 2))));
|
|
assert(!PosInfInterval!Date(Date(1996, 1, 2)).isAdjacent(NegInfInterval!Date(Date(2000, 7, 1))));
|
|
}
|
|
}
|
|
|
|
//Test PosInfInterval's merge().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
|
|
static void testInterval(in PosInfInterval!Date posInfInterval, in Interval!Date interval)
|
|
{
|
|
posInfInterval.merge(interval);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
|
|
assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
|
|
|
|
_assertPred!"=="(posInfInterval.merge(posInfInterval),
|
|
posInfInterval);
|
|
_assertPred!"=="(posInfInterval.merge(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))),
|
|
PosInfInterval!Date(Date(2010, 7, 1)));
|
|
_assertPred!"=="(posInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))),
|
|
PosInfInterval!Date(Date(2010, 7, 3)));
|
|
_assertPred!"=="(posInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))),
|
|
PosInfInterval!Date(Date(2010, 7, 3)));
|
|
_assertPred!"=="(posInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))),
|
|
PosInfInterval!Date(Date(2010, 7, 3)));
|
|
_assertPred!"=="(posInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))),
|
|
PosInfInterval!Date(Date(2010, 7, 3)));
|
|
_assertPred!"=="(posInfInterval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(posInfInterval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(posInfInterval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(posInfInterval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(posInfInterval.merge(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(posInfInterval.merge(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
|
|
_assertPred!"=="(posInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 3))),
|
|
PosInfInterval!Date(Date(2010, 7, 3)));
|
|
_assertPred!"=="(posInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 4))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(posInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 5))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(posInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 6))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(posInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 7))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(posInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 8))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
|
|
_assertPred!"=="(PosInfInterval!Date(Date(2010, 7, 3)).merge(posInfInterval),
|
|
PosInfInterval!Date(Date(2010, 7, 3)));
|
|
_assertPred!"=="(PosInfInterval!Date(Date(2010, 7, 4)).merge(posInfInterval),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(PosInfInterval!Date(Date(2010, 7, 5)).merge(posInfInterval),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(PosInfInterval!Date(Date(2012, 1, 6)).merge(posInfInterval),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(PosInfInterval!Date(Date(2012, 1, 7)).merge(posInfInterval),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(PosInfInterval!Date(Date(2012, 1, 8)).merge(posInfInterval),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
|
|
static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 3)))));
|
|
static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 4)))));
|
|
static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 5)))));
|
|
static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 6)))));
|
|
static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 7)))));
|
|
static assert(!__traits(compiles, posInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 8)))));
|
|
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, posInfInterval.merge(interval)));
|
|
static assert(__traits(compiles, posInfInterval.merge(cInterval)));
|
|
static assert(__traits(compiles, posInfInterval.merge(iInterval)));
|
|
static assert(__traits(compiles, posInfInterval.merge(posInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.merge(cPosInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.merge(iPosInfInterval)));
|
|
static assert(!__traits(compiles, posInfInterval.merge(negInfInterval)));
|
|
static assert(!__traits(compiles, posInfInterval.merge(cNegInfInterval)));
|
|
static assert(!__traits(compiles, posInfInterval.merge(iNegInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.merge(interval)));
|
|
static assert(__traits(compiles, cPosInfInterval.merge(cInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.merge(iInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.merge(posInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.merge(cPosInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.merge(iPosInfInterval)));
|
|
static assert(!__traits(compiles, cPosInfInterval.merge(negInfInterval)));
|
|
static assert(!__traits(compiles, cPosInfInterval.merge(cNegInfInterval)));
|
|
static assert(!__traits(compiles, cPosInfInterval.merge(iNegInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.merge(interval)));
|
|
static assert(__traits(compiles, iPosInfInterval.merge(cInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.merge(iInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.merge(posInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.merge(cPosInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.merge(iPosInfInterval)));
|
|
static assert(!__traits(compiles, iPosInfInterval.merge(negInfInterval)));
|
|
static assert(!__traits(compiles, iPosInfInterval.merge(cNegInfInterval)));
|
|
static assert(!__traits(compiles, iPosInfInterval.merge(iNegInfInterval)));
|
|
|
|
//Verify Examples.
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == PosInfInterval!Date(Date(1990, 7 , 6)));
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == PosInfInterval!Date(Date(1996, 1 , 2)));
|
|
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(PosInfInterval!Date(Date(1990, 7, 6))) == PosInfInterval!Date(Date(1990, 7 , 6)));
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).merge(PosInfInterval!Date(Date(1999, 1, 12))) == PosInfInterval!Date(Date(1996, 1 , 2)));
|
|
}
|
|
}
|
|
|
|
//Test PosInfInterval's span().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
|
|
static void testInterval(in PosInfInterval!Date posInfInterval, in Interval!Date interval)
|
|
{
|
|
posInfInterval.span(interval);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testInterval(posInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
|
|
_assertPred!"=="(posInfInterval.span(posInfInterval),
|
|
posInfInterval);
|
|
_assertPred!"=="(posInfInterval.span(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))),
|
|
PosInfInterval!Date(Date(2010, 7, 1)));
|
|
_assertPred!"=="(posInfInterval.span(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))),
|
|
PosInfInterval!Date(Date(2010, 7, 1)));
|
|
_assertPred!"=="(posInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))),
|
|
PosInfInterval!Date(Date(2010, 7, 3)));
|
|
_assertPred!"=="(posInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))),
|
|
PosInfInterval!Date(Date(2010, 7, 3)));
|
|
_assertPred!"=="(posInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))),
|
|
PosInfInterval!Date(Date(2010, 7, 3)));
|
|
_assertPred!"=="(posInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))),
|
|
PosInfInterval!Date(Date(2010, 7, 3)));
|
|
_assertPred!"=="(posInfInterval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(posInfInterval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(posInfInterval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(posInfInterval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(posInfInterval.span(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(posInfInterval.span(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
|
|
_assertPred!"=="(posInfInterval.span(PosInfInterval!Date(Date(2010, 7, 3))),
|
|
PosInfInterval!Date(Date(2010, 7, 3)));
|
|
_assertPred!"=="(posInfInterval.span(PosInfInterval!Date(Date(2010, 7, 4))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(posInfInterval.span(PosInfInterval!Date(Date(2010, 7, 5))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(posInfInterval.span(PosInfInterval!Date(Date(2012, 1, 6))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(posInfInterval.span(PosInfInterval!Date(Date(2012, 1, 7))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(posInfInterval.span(PosInfInterval!Date(Date(2012, 1, 8))),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
|
|
_assertPred!"=="(PosInfInterval!Date(Date(2010, 7, 3)).span(posInfInterval),
|
|
PosInfInterval!Date(Date(2010, 7, 3)));
|
|
_assertPred!"=="(PosInfInterval!Date(Date(2010, 7, 4)).span(posInfInterval),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(PosInfInterval!Date(Date(2010, 7, 5)).span(posInfInterval),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(PosInfInterval!Date(Date(2012, 1, 6)).span(posInfInterval),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(PosInfInterval!Date(Date(2012, 1, 7)).span(posInfInterval),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(PosInfInterval!Date(Date(2012, 1, 8)).span(posInfInterval),
|
|
PosInfInterval!Date(Date(2010, 7, 4)));
|
|
|
|
static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2010, 7, 3)))));
|
|
static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2010, 7, 4)))));
|
|
static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2010, 7, 5)))));
|
|
static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2012, 1, 6)))));
|
|
static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2012, 1, 7)))));
|
|
static assert(!__traits(compiles, posInfInterval.span(NegInfInterval!Date(Date(2012, 1, 8)))));
|
|
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, posInfInterval.span(interval)));
|
|
static assert(__traits(compiles, posInfInterval.span(cInterval)));
|
|
static assert(__traits(compiles, posInfInterval.span(iInterval)));
|
|
static assert(__traits(compiles, posInfInterval.span(posInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.span(cPosInfInterval)));
|
|
static assert(__traits(compiles, posInfInterval.span(iPosInfInterval)));
|
|
static assert(!__traits(compiles, posInfInterval.span(negInfInterval)));
|
|
static assert(!__traits(compiles, posInfInterval.span(cNegInfInterval)));
|
|
static assert(!__traits(compiles, posInfInterval.span(iNegInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.span(interval)));
|
|
static assert(__traits(compiles, cPosInfInterval.span(cInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.span(iInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.span(posInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.span(cPosInfInterval)));
|
|
static assert(__traits(compiles, cPosInfInterval.span(iPosInfInterval)));
|
|
static assert(!__traits(compiles, cPosInfInterval.span(negInfInterval)));
|
|
static assert(!__traits(compiles, cPosInfInterval.span(cNegInfInterval)));
|
|
static assert(!__traits(compiles, cPosInfInterval.span(iNegInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.span(interval)));
|
|
static assert(__traits(compiles, iPosInfInterval.span(cInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.span(iInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.span(posInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.span(cPosInfInterval)));
|
|
static assert(__traits(compiles, iPosInfInterval.span(iPosInfInterval)));
|
|
static assert(!__traits(compiles, iPosInfInterval.span(negInfInterval)));
|
|
static assert(!__traits(compiles, iPosInfInterval.span(cNegInfInterval)));
|
|
static assert(!__traits(compiles, iPosInfInterval.span(iNegInfInterval)));
|
|
|
|
//Verify Examples.
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).span(Interval!Date(Date(500, 8, 9), Date(1602, 1, 31))) == PosInfInterval!Date(Date(500, 8, 9)));
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).span(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == PosInfInterval!Date(Date(1990, 7 , 6)));
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).span(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))) == PosInfInterval!Date(Date(1996, 1 , 2)));
|
|
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).span(PosInfInterval!Date(Date(1990, 7, 6))) == PosInfInterval!Date(Date(1990, 7 , 6)));
|
|
assert(PosInfInterval!Date(Date(1996, 1, 2)).span(PosInfInterval!Date(Date(1999, 1, 12))) == PosInfInterval!Date(Date(1996, 1 , 2)));
|
|
}
|
|
}
|
|
|
|
//Test PosInfInterval's shift().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto interval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
|
|
static void testInterval(I)(I interval, in Duration duration, in I expected, size_t line = __LINE__)
|
|
{
|
|
interval.shift(duration);
|
|
_assertPred!"=="(interval, expected, "", __FILE__, line);
|
|
}
|
|
|
|
testInterval(interval, dur!"days"(22), PosInfInterval!Date(Date(2010, 7, 26)));
|
|
testInterval(interval, dur!"days"(-22), PosInfInterval!Date(Date(2010, 6, 12)));
|
|
|
|
const cInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
static assert(!__traits(compiles, cInterval.shift(dur!"days"(5))));
|
|
static assert(!__traits(compiles, iInterval.shift(dur!"days"(5))));
|
|
|
|
//Verify Examples.
|
|
auto interval1 = PosInfInterval!Date(Date(1996, 1, 2));
|
|
auto interval2 = PosInfInterval!Date(Date(1996, 1, 2));
|
|
|
|
interval1.shift(dur!"days"(50));
|
|
assert(interval1 == PosInfInterval!Date(Date(1996, 2, 21)));
|
|
|
|
interval2.shift(dur!"days"(-50));
|
|
assert(interval2 == PosInfInterval!Date(Date(1995, 11, 13)));
|
|
}
|
|
}
|
|
|
|
//Test PosInfInterval's shift(int, int, AllowDayOverflow).
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
{
|
|
auto interval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
|
|
static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, in I expected, size_t line = __LINE__)
|
|
{
|
|
interval.shift(years, months, allow);
|
|
_assertPred!"=="(interval, expected, "", __FILE__, line);
|
|
}
|
|
|
|
testInterval(interval, 5, 0, AllowDayOverflow.yes, PosInfInterval!Date(Date(2015, 7, 4)));
|
|
testInterval(interval, -5, 0, AllowDayOverflow.yes, PosInfInterval!Date(Date(2005, 7, 4)));
|
|
|
|
auto interval2 = PosInfInterval!Date(Date(2000, 1, 29));
|
|
|
|
testInterval(interval2, 1, 1, AllowDayOverflow.yes, PosInfInterval!Date(Date(2001, 3, 1)));
|
|
testInterval(interval2, 1, -1, AllowDayOverflow.yes, PosInfInterval!Date(Date(2000, 12, 29)));
|
|
testInterval(interval2, -1, -1, AllowDayOverflow.yes, PosInfInterval!Date(Date(1998, 12, 29)));
|
|
testInterval(interval2, -1, 1, AllowDayOverflow.yes, PosInfInterval!Date(Date(1999, 3, 1)));
|
|
|
|
testInterval(interval2, 1, 1, AllowDayOverflow.no, PosInfInterval!Date(Date(2001, 2, 28)));
|
|
testInterval(interval2, 1, -1, AllowDayOverflow.no, PosInfInterval!Date(Date(2000, 12, 29)));
|
|
testInterval(interval2, -1, -1, AllowDayOverflow.no, PosInfInterval!Date(Date(1998, 12, 29)));
|
|
testInterval(interval2, -1, 1, AllowDayOverflow.no, PosInfInterval!Date(Date(1999, 2, 28)));
|
|
}
|
|
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
static assert(!__traits(compiles, cPosInfInterval.shift(1)));
|
|
static assert(!__traits(compiles, iPosInfInterval.shift(1)));
|
|
|
|
//Verify Examples.
|
|
auto interval1 = PosInfInterval!Date(Date(1996, 1, 2));
|
|
auto interval2 = PosInfInterval!Date(Date(1996, 1, 2));
|
|
|
|
interval1.shift(2);
|
|
assert(interval1 == PosInfInterval!Date(Date(1998, 1, 2)));
|
|
|
|
interval2.shift(-2);
|
|
assert(interval2 == PosInfInterval!Date(Date(1994, 1, 2)));
|
|
}
|
|
}
|
|
|
|
//Test PosInfInterval's expand().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto interval = PosInfInterval!Date(Date(2000, 7, 4));
|
|
|
|
static void testInterval(I)(I interval, in Duration duration, in I expected, size_t line = __LINE__)
|
|
{
|
|
interval.expand(duration);
|
|
_assertPred!"=="(interval, expected, "", __FILE__, line);
|
|
}
|
|
|
|
testInterval(interval, dur!"days"(22), PosInfInterval!Date(Date(2000, 6, 12)));
|
|
testInterval(interval, dur!"days"(-22), PosInfInterval!Date(Date(2000, 7, 26)));
|
|
|
|
const cInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
static assert(!__traits(compiles, cInterval.expand(dur!"days"(5))));
|
|
static assert(!__traits(compiles, iInterval.expand(dur!"days"(5))));
|
|
|
|
//Verify Examples.
|
|
auto interval1 = PosInfInterval!Date(Date(1996, 1, 2));
|
|
auto interval2 = PosInfInterval!Date(Date(1996, 1, 2));
|
|
|
|
interval1.expand(dur!"days"(2));
|
|
assert(interval1 == PosInfInterval!Date(Date(1995, 12, 31)));
|
|
|
|
interval2.expand(dur!"days"(-2));
|
|
assert(interval2 == PosInfInterval!Date(Date(1996, 1, 4)));
|
|
}
|
|
}
|
|
|
|
//Test PosInfInterval's expand(int, int, AllowDayOverflow).
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
{
|
|
auto interval = PosInfInterval!Date(Date(2000, 7, 4));
|
|
|
|
static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, in I expected, size_t line = __LINE__)
|
|
{
|
|
interval.expand(years, months, allow);
|
|
_assertPred!"=="(interval, expected, "", __FILE__, line);
|
|
}
|
|
|
|
testInterval(interval, 5, 0, AllowDayOverflow.yes, PosInfInterval!Date(Date(1995, 7, 4)));
|
|
testInterval(interval, -5, 0, AllowDayOverflow.yes, PosInfInterval!Date(Date(2005, 7, 4)));
|
|
|
|
auto interval2 = PosInfInterval!Date(Date(2000, 1, 29));
|
|
|
|
testInterval(interval2, 1, 1, AllowDayOverflow.yes, PosInfInterval!Date(Date(1998, 12, 29)));
|
|
testInterval(interval2, 1, -1, AllowDayOverflow.yes, PosInfInterval!Date(Date(1999, 3, 1)));
|
|
testInterval(interval2, -1, -1, AllowDayOverflow.yes, PosInfInterval!Date(Date(2001, 3, 1)));
|
|
testInterval(interval2, -1, 1, AllowDayOverflow.yes, PosInfInterval!Date(Date(2000, 12, 29)));
|
|
|
|
testInterval(interval2, 1, 1, AllowDayOverflow.no, PosInfInterval!Date(Date(1998, 12, 29)));
|
|
testInterval(interval2, 1, -1, AllowDayOverflow.no, PosInfInterval!Date(Date(1999, 2, 28)));
|
|
testInterval(interval2, -1, -1, AllowDayOverflow.no, PosInfInterval!Date(Date(2001, 2, 28)));
|
|
testInterval(interval2, -1, 1, AllowDayOverflow.no, PosInfInterval!Date(Date(2000, 12, 29)));
|
|
}
|
|
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
static assert(!__traits(compiles, cPosInfInterval.expand(1)));
|
|
static assert(!__traits(compiles, iPosInfInterval.expand(1)));
|
|
|
|
//Verify Examples.
|
|
auto interval1 = PosInfInterval!Date(Date(1996, 1, 2));
|
|
auto interval2 = PosInfInterval!Date(Date(1996, 1, 2));
|
|
|
|
interval1.expand(2);
|
|
assert(interval1 == PosInfInterval!Date(Date(1994, 1, 2)));
|
|
|
|
interval2.expand(-2);
|
|
assert(interval2 == PosInfInterval!Date(Date(1998, 1, 2)));
|
|
}
|
|
}
|
|
|
|
//Test PosInfInterval's fwdRange().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 9, 19));
|
|
|
|
static void testInterval(PosInfInterval!Date posInfInterval)
|
|
{
|
|
posInfInterval.fwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).popFront();
|
|
}
|
|
|
|
assertThrown!DateTimeException(testInterval(posInfInterval));
|
|
|
|
_assertPred!"=="(PosInfInterval!Date(Date(2010, 9, 12)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri)).front,
|
|
Date(2010, 9, 12));
|
|
|
|
_assertPred!"=="(PosInfInterval!Date(Date(2010, 9, 12)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri), PopFirst.yes).front,
|
|
Date(2010, 9, 17));
|
|
|
|
//Verify Examples.
|
|
auto interval = PosInfInterval!Date(Date(2010, 9, 1));
|
|
auto func = (in Date date)
|
|
{
|
|
if((date.day & 1) == 0)
|
|
return date + dur!"days"(2);
|
|
|
|
return date + dur!"days"(1);
|
|
};
|
|
auto range = interval.fwdRange(func);
|
|
|
|
assert(range.front == Date(2010, 9, 1)); //An odd day. Using PopFirst.yes would have made this Date(2010, 9, 2).
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 2));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 4));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 6));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 8));
|
|
|
|
range.popFront();
|
|
assert(!range.empty);
|
|
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
static assert(__traits(compiles, cPosInfInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri))));
|
|
static assert(__traits(compiles, iPosInfInterval.fwdRange(everyDayOfWeek!Date(DayOfWeek.fri))));
|
|
}
|
|
}
|
|
|
|
//Test PosInfInterval's toString().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(PosInfInterval!Date(Date(2010, 7, 4)).toString(), "[2010-Jul-04 - ∞)");
|
|
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
static assert(__traits(compiles, cPosInfInterval.toString()));
|
|
static assert(__traits(compiles, iPosInfInterval.toString()));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Represents an interval of time which has negative infinity as its starting
|
|
point.
|
|
|
|
Any ranges which iterate over a $(D NegInfInterval) are infinite. So, the
|
|
main purpose of using $(D NegInfInterval) is to create an infinite range
|
|
which starts at negative infinity and goes to a fixed end point. You would
|
|
then iterate over it in reverse.
|
|
+/
|
|
struct NegInfInterval(TP)
|
|
{
|
|
public:
|
|
|
|
/++
|
|
Params:
|
|
begin = The time point which begins the interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto interval = PosInfInterval!Date(Date(1996, 1, 2));
|
|
--------------------
|
|
+/
|
|
this(in TP end) pure nothrow
|
|
{
|
|
_end = cast(TP)end;
|
|
}
|
|
|
|
|
|
/++
|
|
Params:
|
|
rhs = The $(D NegInfInterval) to assign to this one.
|
|
+/
|
|
/+ref+/ NegInfInterval opAssign(const ref NegInfInterval rhs) pure nothrow
|
|
{
|
|
_end = cast(TP)rhs._end;
|
|
|
|
return this;
|
|
}
|
|
|
|
|
|
/++
|
|
Params:
|
|
rhs = The $(D NegInfInterval) to assign to this one.
|
|
+/
|
|
/+ref+/ NegInfInterval opAssign(NegInfInterval rhs) pure nothrow
|
|
{
|
|
_end = cast(TP)rhs._end;
|
|
|
|
return this;
|
|
}
|
|
|
|
|
|
/++
|
|
The end point of the interval. It is excluded from the interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).end == Date(2012, 3, 1));
|
|
--------------------
|
|
+/
|
|
@property TP end() const pure nothrow
|
|
{
|
|
return cast(TP)_end;
|
|
}
|
|
|
|
|
|
/++
|
|
The end point of the interval. It is excluded from the interval.
|
|
|
|
Params:
|
|
timePoint = The time point to set end to.
|
|
+/
|
|
@property void end(TP timePoint) pure nothrow
|
|
{
|
|
_end = timePoint;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the interval's length is 0. Always returns false.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!NegInfInterval!Date(Date(1996, 1, 2)).empty);
|
|
--------------------
|
|
+/
|
|
@property bool empty() const pure nothrow
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given time point is within this interval.
|
|
|
|
Params:
|
|
timePoint = The time point to check for inclusion in this interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(1994, 12, 24)));
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(2000, 1, 5)));
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(2012, 3, 1)));
|
|
--------------------
|
|
+/
|
|
bool contains(TP timePoint) const pure nothrow
|
|
{
|
|
return timePoint < _end;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval is completely within this interval.
|
|
|
|
Params:
|
|
interval = The interval to check for inclusion in this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(
|
|
Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
|
|
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(
|
|
Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
|
|
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(
|
|
Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1))));
|
|
--------------------
|
|
+/
|
|
bool contains(in Interval!TP interval) const pure
|
|
{
|
|
interval._enforceNotEmpty();
|
|
|
|
return interval._end <= _end;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval is completely within this interval.
|
|
|
|
Always returns false because an interval beginning at negative
|
|
infinity can never contain an interval going to positive infinity.
|
|
|
|
Params:
|
|
interval = The interval to check for inclusion in this interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(
|
|
PosInfInterval!Date(Date(1999, 5, 4))));
|
|
--------------------
|
|
+/
|
|
bool contains(in PosInfInterval!TP interval) const pure nothrow
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval is completely within this interval.
|
|
|
|
Params:
|
|
interval = The interval to check for inclusion in this interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(
|
|
NegInfInterval!Date(Date(1996, 5, 4))));
|
|
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(
|
|
NegInfInterval!Date(Date(2013, 7, 9))));
|
|
--------------------
|
|
+/
|
|
bool contains(in NegInfInterval interval) const pure nothrow
|
|
{
|
|
return interval._end <= _end;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this interval is before the given time point.
|
|
|
|
Params:
|
|
timePoint = The time point to check whether this interval is
|
|
before it.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(1994, 12, 24)));
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(2000, 1, 5)));
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(2012, 3, 1)));
|
|
--------------------
|
|
+/
|
|
bool isBefore(in TP timePoint) const pure nothrow
|
|
{
|
|
return timePoint >= _end;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this interval is before the given interval and does not
|
|
intersect it.
|
|
|
|
Params:
|
|
interval = The interval to check for against this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given interval is empty
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(
|
|
Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
|
|
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(
|
|
Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
|
|
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(
|
|
Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3))));
|
|
--------------------
|
|
+/
|
|
bool isBefore(in Interval!TP interval) const pure
|
|
{
|
|
interval._enforceNotEmpty();
|
|
|
|
return _end <= interval._begin;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this interval is before the given interval and does not
|
|
intersect it.
|
|
|
|
Params:
|
|
interval = The interval to check for against this interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(
|
|
PosInfInterval!Date(Date(1999, 5, 4))));
|
|
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(
|
|
PosInfInterval!Date(Date(2012, 3, 1))));
|
|
--------------------
|
|
+/
|
|
bool isBefore(in PosInfInterval!TP interval) const pure nothrow
|
|
{
|
|
return _end <= interval._begin;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this interval is before the given interval and does not
|
|
intersect it.
|
|
|
|
Always returns false because an interval beginning at negative
|
|
infinity can never be before another interval beginning at negative
|
|
infinity.
|
|
|
|
Params:
|
|
interval = The interval to check for against this interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(
|
|
NegInfInterval!Date(Date(1996, 5, 4))));
|
|
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(
|
|
NegInfInterval!Date(Date(2013, 7, 9))));
|
|
--------------------
|
|
+/
|
|
bool isBefore(in NegInfInterval interval) const pure nothrow
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this interval is after the given time point.
|
|
|
|
Always returns false because an interval beginning at negative infinity
|
|
can never be after any time point.
|
|
|
|
Params:
|
|
timePoint = The time point to check whether this interval is after
|
|
it.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(1994, 12, 24)));
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(2000, 1, 5)));
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(2012, 3, 1)));
|
|
--------------------
|
|
+/
|
|
bool isAfter(in TP timePoint) const pure nothrow
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this interval is after the given interval and does not
|
|
intersect it.
|
|
|
|
Always returns false (unless the given interval is empty) because an
|
|
interval beginning at negative infinity can never be after any other
|
|
interval.
|
|
|
|
Params:
|
|
interval = The interval to check against this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(
|
|
Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
|
|
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(
|
|
Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
|
|
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(
|
|
Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3))));
|
|
--------------------
|
|
+/
|
|
bool isAfter(in Interval!TP interval) const pure
|
|
{
|
|
interval._enforceNotEmpty();
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this interval is after the given interval and does not intersect
|
|
it.
|
|
|
|
Always returns false because an interval beginning at negative infinity
|
|
can never be after any other interval.
|
|
|
|
Params:
|
|
interval = The interval to check against this interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(
|
|
PosInfInterval!Date(Date(1999, 5, 4))));
|
|
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(
|
|
PosInfInterval!Date(Date(2012, 3, 1))));
|
|
--------------------
|
|
+/
|
|
bool isAfter(in PosInfInterval!TP interval) const pure nothrow
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this interval is after the given interval and does not intersect
|
|
it.
|
|
|
|
Always returns false because an interval beginning at negative infinity
|
|
can never be after any other interval.
|
|
|
|
Params:
|
|
interval = The interval to check against this interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(
|
|
NegInfInterval!Date(Date(1996, 5, 4))));
|
|
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(
|
|
NegInfInterval!Date(Date(2013, 7, 9))));
|
|
--------------------
|
|
+/
|
|
bool isAfter(in NegInfInterval interval) const pure nothrow
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval overlaps this interval.
|
|
|
|
Params:
|
|
interval = The interval to check for intersection with this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(
|
|
Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
|
|
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(
|
|
Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
|
|
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).intersects(
|
|
Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3))));
|
|
--------------------
|
|
+/
|
|
bool intersects(in Interval!TP interval) const pure
|
|
{
|
|
interval._enforceNotEmpty();
|
|
|
|
return interval._begin < _end;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval overlaps this interval.
|
|
|
|
Params:
|
|
interval = The interval to check for intersection with this
|
|
interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(
|
|
PosInfInterval!Date(Date(1999, 5, 4))));
|
|
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).intersects(
|
|
PosInfInterval!Date(Date(2012, 3, 1))));
|
|
--------------------
|
|
+/
|
|
bool intersects(in PosInfInterval!TP interval) const pure nothrow
|
|
{
|
|
return interval._begin < _end;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval overlaps this interval.
|
|
|
|
Always returns true because two intervals beginning at negative infinity
|
|
always overlap.
|
|
|
|
Params:
|
|
interval = The interval to check for intersection with this interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(
|
|
NegInfInterval!Date(Date(1996, 5, 4))));
|
|
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(
|
|
NegInfInterval!Date(Date(2013, 7, 9))));
|
|
--------------------
|
|
+/
|
|
bool intersects(in NegInfInterval!TP interval) const pure nothrow
|
|
{
|
|
return true;
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the intersection of two intervals
|
|
|
|
Params:
|
|
interval = The interval to intersect with this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the two intervals do not intersect or if
|
|
the given interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(
|
|
Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==
|
|
Interval!Date(Date(1990, 7 , 6), Date(2000, 8, 2)));
|
|
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(
|
|
Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) ==
|
|
Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1)));
|
|
--------------------
|
|
+/
|
|
Interval!TP intersection(in Interval!TP interval) const
|
|
{
|
|
enforce(this.intersects(interval), new DateTimeException(format("%s and %s do not intersect.", this, interval)));
|
|
|
|
auto end = _end < interval._end ? _end : interval._end;
|
|
|
|
return Interval!TP(interval._begin, end);
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the intersection of two intervals
|
|
|
|
Params:
|
|
interval = The interval to intersect with this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the two intervals do not intersect.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(
|
|
PosInfInterval!Date(Date(1990, 7, 6))) ==
|
|
Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1)));
|
|
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(
|
|
PosInfInterval!Date(Date(1999, 1, 12))) ==
|
|
Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1)));
|
|
--------------------
|
|
+/
|
|
Interval!TP intersection(in PosInfInterval!TP interval) const
|
|
{
|
|
enforce(this.intersects(interval), new DateTimeException(format("%s and %s do not intersect.", this, interval)));
|
|
|
|
return Interval!TP(interval._begin, _end);
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the intersection of two intervals
|
|
|
|
Params:
|
|
interval = The interval to intersect with this interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(
|
|
NegInfInterval!Date(Date(1999, 7, 6))) ==
|
|
NegInfInterval!Date(Date(1999, 7 , 6)));
|
|
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(
|
|
NegInfInterval!Date(Date(2013, 1, 12))) ==
|
|
NegInfInterval!Date(Date(2012, 3 , 1)));
|
|
--------------------
|
|
+/
|
|
NegInfInterval intersection(in NegInfInterval interval) const nothrow
|
|
{
|
|
return NegInfInterval(_end < interval._end ? _end : interval._end);
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval is adjacent to this interval.
|
|
|
|
Params:
|
|
interval = The interval to check whether its adjecent to this
|
|
interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given interval is empty.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(
|
|
Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
|
|
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(
|
|
Interval!Date(Date(1999, 1, 12), Date(2012, 3, 1))));
|
|
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(
|
|
Interval!Date(Date(2012, 3, 1), Date(2019, 2, 2))));
|
|
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(
|
|
Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3))));
|
|
--------------------
|
|
+/
|
|
bool isAdjacent(in Interval!TP interval) const pure
|
|
{
|
|
interval._enforceNotEmpty();
|
|
|
|
return interval._begin == _end;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval is adjacent to this interval.
|
|
|
|
Params:
|
|
interval = The interval to check whether its adjecent to this
|
|
interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(
|
|
PosInfInterval!Date(Date(1999, 5, 4))));
|
|
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(
|
|
PosInfInterval!Date(Date(2012, 3, 1))));
|
|
--------------------
|
|
+/
|
|
bool isAdjacent(in PosInfInterval!TP interval) const pure nothrow
|
|
{
|
|
return interval._begin == _end;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given interval is adjacent to this interval.
|
|
|
|
Always returns false because two intervals beginning at negative
|
|
infinity can never be adjacent to one another.
|
|
|
|
Params:
|
|
interval = The interval to check whether its adjecent to this
|
|
interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(
|
|
NegInfInterval!Date(Date(1996, 5, 4))));
|
|
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(
|
|
NegInfInterval!Date(Date(2012, 3, 1))));
|
|
--------------------
|
|
+/
|
|
bool isAdjacent(in NegInfInterval interval) const pure nothrow
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the union of two intervals
|
|
|
|
Params:
|
|
interval = The interval to merge with this interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the two intervals do not intersect and are
|
|
not adjacent or if the given interval is empty.
|
|
|
|
Note:
|
|
There is no overload for $(D merge) which takes a
|
|
$(D PosInfInterval). This is because you can't have an interval
|
|
which goes from negative infinity to positive infinity.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(
|
|
Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==
|
|
NegInfInterval!Date(Date(2012, 3 , 1)));
|
|
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(
|
|
Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) ==
|
|
NegInfInterval!Date(Date(2015, 9 , 2)));
|
|
--------------------
|
|
+/
|
|
NegInfInterval merge(in Interval!TP interval) const
|
|
{
|
|
enforce(this.isAdjacent(interval) || this.intersects(interval),
|
|
new DateTimeException(format("%s and %s are not adjacent and do not intersect.", this, interval)));
|
|
|
|
return NegInfInterval(_end > interval._end ? _end : interval._end);
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the union of two intervals
|
|
|
|
Params:
|
|
interval = The interval to merge with this interval.
|
|
|
|
Note:
|
|
There is no overload for $(D merge) which takes a
|
|
$(D PosInfInterval). This is because you can't have an interval
|
|
which goes from negative infinity to positive infinity.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(
|
|
NegInfInterval!Date(Date(1999, 7, 6))) ==
|
|
NegInfInterval!Date(Date(2012, 3 , 1)));
|
|
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(
|
|
NegInfInterval!Date(Date(2013, 1, 12))) ==
|
|
NegInfInterval!Date(Date(2013, 1 , 12)));
|
|
--------------------
|
|
+/
|
|
NegInfInterval merge(in NegInfInterval interval) const pure nothrow
|
|
{
|
|
return NegInfInterval(_end > interval._end ? _end : interval._end);
|
|
}
|
|
|
|
|
|
/++
|
|
Returns an interval that covers from the earliest time point of two
|
|
intervals up to (but not including) the latest time point of two
|
|
intervals.
|
|
|
|
Params:
|
|
interval = The interval to create a span together with this
|
|
interval.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given interval is empty.
|
|
|
|
Note:
|
|
There is no overload for $(D span) which takes a
|
|
$(D PosInfInterval). This is because you can't have an interval
|
|
which goes from negative infinity to positive infinity.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).span(
|
|
Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) ==
|
|
NegInfInterval!Date(Date(2012, 3 , 1)));
|
|
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).span(
|
|
Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) ==
|
|
NegInfInterval!Date(Date(2015, 9 , 2)));
|
|
|
|
assert(NegInfInterval!Date(Date(1600, 1, 7)).span(
|
|
Interval!Date(Date(2012, 3, 11), Date(2017, 7, 1))) ==
|
|
NegInfInterval!Date(Date(2017, 7 , 1)));
|
|
--------------------
|
|
+/
|
|
NegInfInterval span(in Interval!TP interval) const pure
|
|
{
|
|
interval._enforceNotEmpty();
|
|
|
|
return NegInfInterval(_end > interval._end ? _end : interval._end);
|
|
}
|
|
|
|
|
|
/++
|
|
Returns an interval that covers from the earliest time point of two
|
|
intervals up to (but not including) the latest time point of two
|
|
intervals.
|
|
|
|
Params:
|
|
interval = The interval to create a span together with this
|
|
interval.
|
|
|
|
Note:
|
|
There is no overload for $(D span) which takes a
|
|
$(D PosInfInterval). This is because you can't have an interval
|
|
which goes from negative infinity to positive infinity.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).span(
|
|
NegInfInterval!Date(Date(1999, 7, 6))) ==
|
|
NegInfInterval!Date(Date(2012, 3 , 1)));
|
|
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).span(
|
|
NegInfInterval!Date(Date(2013, 1, 12))) ==
|
|
NegInfInterval!Date(Date(2013, 1 , 12)));
|
|
--------------------
|
|
+/
|
|
NegInfInterval span(in NegInfInterval interval) const pure nothrow
|
|
{
|
|
return NegInfInterval(_end > interval._end ? _end : interval._end);
|
|
}
|
|
|
|
|
|
/++
|
|
Shifts the $(D end) of this interval forward or backwards in time by the
|
|
given duration (a positive duration shifts the interval forward; a
|
|
negative duration shifts it backward). Effectively, it does
|
|
$(D end += duration).
|
|
|
|
Params:
|
|
duration = The duration to shift the interval by.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto interval1 = NegInfInterval!Date(Date(2012, 4, 5));
|
|
auto interval2 = NegInfInterval!Date(Date(2012, 4, 5));
|
|
|
|
interval1.shift(dur!"days"(50));
|
|
assert(interval1 == NegInfInterval!Date(Date(2012, 5, 25)));
|
|
|
|
interval2.shift(dur!"days"(-50));
|
|
assert(interval2 == NegInfInterval!Date( Date(2012, 2, 15)));
|
|
--------------------
|
|
+/
|
|
void shift(D)(D duration) pure nothrow
|
|
if(__traits(compiles, end + duration))
|
|
{
|
|
_end += duration;
|
|
}
|
|
|
|
|
|
static if(__traits(compiles, end.add!"months"(1)) &&
|
|
__traits(compiles, end.add!"years"(1)))
|
|
{
|
|
/++
|
|
Shifts the $(D end) of this interval forward or backwards in time by
|
|
the given number of years and/or months (a positive number of years
|
|
and months shifts the interval forward; a negative number shifts it
|
|
backward). It adds the years the given years and months to end. It
|
|
effectively calls $(D add!"years"()) and then $(D add!"months"())
|
|
on end with the given number of years and months.
|
|
|
|
Params:
|
|
years = The number of years to shift the interval by.
|
|
months = The number of months to shift the interval by.
|
|
allowOverflow = Whether the days should be allowed to overflow
|
|
on $(D end), causing its month to increment.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if empty is true or if the resulting
|
|
interval would be invalid.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto interval1 = NegInfInterval!Date(Date(2012, 3, 1));
|
|
auto interval2 = NegInfInterval!Date(Date(2012, 3, 1));
|
|
|
|
interval1.shift(2);
|
|
assert(interval1 == NegInfInterval!Date(Date(2014, 3, 1)));
|
|
|
|
interval2.shift(-2);
|
|
assert(interval2 == NegInfInterval!Date(Date(2010, 3, 1)));
|
|
--------------------
|
|
+/
|
|
void shift(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes)
|
|
if(isIntegral!T)
|
|
{
|
|
auto end = _end;
|
|
|
|
end.add!"years"(years, allowOverflow);
|
|
end.add!"months"(months, allowOverflow);
|
|
|
|
_end = end;
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Expands the interval forwards in time. Effectively, it does
|
|
$(D end += duration).
|
|
|
|
Params:
|
|
duration = The duration to expand the interval by.
|
|
dir = The direction in time to expand the interval.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto interval1 = NegInfInterval!Date(Date(2012, 3, 1));
|
|
auto interval2 = NegInfInterval!Date(Date(2012, 3, 1));
|
|
|
|
interval1.expand(dur!"days"(2));
|
|
assert(interval1 == NegInfInterval!Date(Date(2012, 3, 3)));
|
|
|
|
interval2.expand(dur!"days"(-2));
|
|
assert(interval2 == NegInfInterval!Date(Date(2012, 2, 28)));
|
|
--------------------
|
|
+/
|
|
void expand(D)(D duration) pure nothrow
|
|
if(__traits(compiles, end + duration))
|
|
{
|
|
_end += duration;
|
|
}
|
|
|
|
|
|
static if(__traits(compiles, end.add!"months"(1)) &&
|
|
__traits(compiles, end.add!"years"(1)))
|
|
{
|
|
/++
|
|
Expands the interval forwards and/or backwards in time. Effectively,
|
|
it adds the given number of months/years to end.
|
|
|
|
Params:
|
|
years = The number of years to expand the interval by.
|
|
months = The number of months to expand the interval by.
|
|
allowOverflow = Whether the days should be allowed to overflow
|
|
on $(D end), causing their month to increment.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if empty is true or if the resulting
|
|
interval would be invalid.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto interval1 = NegInfInterval!Date(Date(2012, 3, 1));
|
|
auto interval2 = NegInfInterval!Date(Date(2012, 3, 1));
|
|
|
|
interval1.expand(2);
|
|
assert(interval1 == NegInfInterval!Date(Date(2014, 3, 1)));
|
|
|
|
interval2.expand(-2);
|
|
assert(interval2 == NegInfInterval!Date(Date(2010, 3, 1)));
|
|
--------------------
|
|
+/
|
|
void expand(T)(T years, T months = 0, AllowDayOverflow allowOverflow = AllowDayOverflow.yes)
|
|
if(isIntegral!T)
|
|
{
|
|
auto end = _end;
|
|
|
|
end.add!"years"(years, allowOverflow);
|
|
end.add!"months"(months, allowOverflow);
|
|
|
|
_end = end;
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns a range which iterates backwards over the interval, starting
|
|
at $(D end), using $(D_PARAM func) to generate each successive time
|
|
point.
|
|
|
|
The range's $(D front) is the interval's $(D end). $(D_PARAM func) is
|
|
used to generate the next $(D front) when $(D popFront) is called. If
|
|
$(D_PARAM popFirst) is $(D PopFirst.yes), then $(D popFront) is called
|
|
before the range is returned (so that $(D front) is a time point which
|
|
$(D_PARAM func) would generate).
|
|
|
|
If $(D_PARAM func) ever generates a time point greater than or equal to
|
|
the current $(D front) of the range, then a $(D DateTimeException) will
|
|
be thrown.
|
|
|
|
There are helper functions in this module which generate common
|
|
delegates to pass to $(D bwdRange). Their documentation starts with
|
|
"Range-generating function," so you can easily search for them.
|
|
|
|
Params:
|
|
func = The function used to generate the time points of the
|
|
range over the interval.
|
|
popFirst = Whether $(D popFront) should be called on the range
|
|
before returning it.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if this interval is empty.
|
|
|
|
Warning:
|
|
$(D_PARAM func) must be logically pure. Ideally, $(D_PARAM func)
|
|
would be a function pointer to a pure function, but forcing
|
|
$(D_PARAM func) to be pure is far too restrictive to be useful, and
|
|
in order to have the ease of use of having functions which generate
|
|
functions to pass to $(D fwdRange), $(D_PARAM func) must be a
|
|
delegate.
|
|
|
|
If $(D_PARAM func) retains state which changes as it is called, then
|
|
some algorithms will not work correctly, because the range's
|
|
$(D save) will have failed to have really saved the range's state.
|
|
So, if you want to avoid such bugs, don't pass a delegate which is
|
|
not logically pure to $(D fwdRange). If $(D_PARAM func) is given the
|
|
same time point with two different calls, it must return the same
|
|
result both times.
|
|
|
|
Of course, none of the functions in this module have this problem,
|
|
so it's only relevant if you're creating your own delegate.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto interval = NegInfInterval!Date(Date(2010, 9, 9));
|
|
auto func = (in Date date) //For iterating over even-numbered days.
|
|
{
|
|
if((date.day & 1) == 0)
|
|
return date - dur!"days"(2);
|
|
|
|
return date - dur!"days"(1);
|
|
};
|
|
auto range = interval.bwdRange(func);
|
|
|
|
assert(range.front == Date(2010, 9, 9)); //An odd day. Using PopFirst.yes would have made this Date(2010, 9, 8).
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 8));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 6));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 4));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 2));
|
|
|
|
range.popFront();
|
|
assert(!range.empty);
|
|
--------------------
|
|
+/
|
|
NegInfIntervalRange!(TP) bwdRange(TP delegate(in TP) func, PopFirst popFirst = PopFirst.no) const
|
|
{
|
|
auto range = NegInfIntervalRange!(TP)(this, func);
|
|
|
|
if(popFirst == PopFirst.yes)
|
|
range.popFront();
|
|
|
|
return range;
|
|
}
|
|
|
|
|
|
/+
|
|
Converts this interval to a string.
|
|
+/
|
|
//Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't
|
|
//have versions of toString() with extra modifiers, so we define one version
|
|
//with modifiers and one without.
|
|
string toString()
|
|
{
|
|
return _toStringImpl();
|
|
}
|
|
|
|
|
|
/++
|
|
Converts this interval to a string.
|
|
+/
|
|
//Due to bug http://d.puremagic.com/issues/show_bug.cgi?id=3715 , we can't
|
|
//have versions of toString() with extra modifiers, so we define one version
|
|
//with modifiers and one without.
|
|
string toString() const nothrow
|
|
{
|
|
return _toStringImpl();
|
|
}
|
|
|
|
private:
|
|
|
|
/+
|
|
Since we have two versions of toString(), we have _toStringImpl()
|
|
so that they can share implementations.
|
|
+/
|
|
string _toStringImpl() const nothrow
|
|
{
|
|
try
|
|
return format("[-∞ - %s)", _end);
|
|
catch(Exception e)
|
|
assert(0, "format() threw.");
|
|
}
|
|
|
|
|
|
TP _end;
|
|
}
|
|
|
|
//Test NegInfInterval's constructor.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
NegInfInterval!Date(Date.init);
|
|
NegInfInterval!TimeOfDay(TimeOfDay.init);
|
|
NegInfInterval!DateTime(DateTime.init);
|
|
NegInfInterval!SysTime(SysTime(0));
|
|
}
|
|
}
|
|
|
|
//Test NegInfInterval's end.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(NegInfInterval!Date(Date(2010, 1, 1)).end, Date(2010, 1, 1));
|
|
_assertPred!"=="(NegInfInterval!Date(Date(2010, 1, 1)).end, Date(2010, 1, 1));
|
|
_assertPred!"=="(NegInfInterval!Date(Date(1998, 1, 1)).end, Date(1998, 1, 1));
|
|
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, cNegInfInterval.end));
|
|
static assert(__traits(compiles, iNegInfInterval.end));
|
|
|
|
//Verify Examples.
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).end == Date(2012, 3, 1));
|
|
}
|
|
}
|
|
|
|
//Test NegInfInterval's empty.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assert(!NegInfInterval!Date(Date(2010, 1, 1)).empty);
|
|
assert(!NegInfInterval!TimeOfDay(TimeOfDay(0, 30, 0)).empty);
|
|
assert(!NegInfInterval!DateTime(DateTime(2010, 1, 1, 0, 30, 0)).empty);
|
|
assert(!NegInfInterval!SysTime(SysTime(DateTime(2010, 1, 1, 0, 30, 0))).empty);
|
|
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, cNegInfInterval.empty));
|
|
static assert(__traits(compiles, iNegInfInterval.empty));
|
|
|
|
//Verify Examples.
|
|
assert(!NegInfInterval!Date(Date(1996, 1, 2)).empty);
|
|
}
|
|
}
|
|
|
|
//Test NegInfInterval's contains(time point).
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
|
|
assert(negInfInterval.contains(Date(2009, 7, 4)));
|
|
assert(negInfInterval.contains(Date(2010, 7, 3)));
|
|
assert(negInfInterval.contains(Date(2010, 7, 4)));
|
|
assert(negInfInterval.contains(Date(2010, 7, 5)));
|
|
assert(negInfInterval.contains(Date(2011, 7, 1)));
|
|
assert(negInfInterval.contains(Date(2012, 1, 6)));
|
|
assert(!negInfInterval.contains(Date(2012, 1, 7)));
|
|
assert(!negInfInterval.contains(Date(2012, 1, 8)));
|
|
assert(!negInfInterval.contains(Date(2013, 1, 7)));
|
|
|
|
const cdate = Date(2010, 7, 6);
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, negInfInterval.contains(cdate)));
|
|
static assert(__traits(compiles, cNegInfInterval.contains(cdate)));
|
|
static assert(__traits(compiles, iNegInfInterval.contains(cdate)));
|
|
|
|
//Verify Examples.
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(1994, 12, 24)));
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(2000, 1, 5)));
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(Date(2012, 3, 1)));
|
|
}
|
|
}
|
|
|
|
//Test NegInfInterval's contains(Interval).
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
|
|
static void testInterval(in NegInfInterval!Date negInfInterval, in Interval!Date interval)
|
|
{
|
|
negInfInterval.contains(interval);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
|
|
assert(negInfInterval.contains(negInfInterval));
|
|
assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
|
|
assert(!negInfInterval.contains(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
|
|
assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
|
|
assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
|
|
assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
|
|
assert(!negInfInterval.contains(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
|
|
assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
|
|
assert(negInfInterval.contains(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
|
|
assert(negInfInterval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
|
|
assert(!negInfInterval.contains(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
|
|
assert(!negInfInterval.contains(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
|
|
assert(!negInfInterval.contains(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
|
|
|
|
assert(negInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(negInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(negInfInterval.contains(NegInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(negInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(negInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(!negInfInterval.contains(NegInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
assert(!NegInfInterval!Date(Date(2010, 7, 3)).contains(negInfInterval));
|
|
assert(!NegInfInterval!Date(Date(2010, 7, 4)).contains(negInfInterval));
|
|
assert(!NegInfInterval!Date(Date(2010, 7, 5)).contains(negInfInterval));
|
|
assert(!NegInfInterval!Date(Date(2012, 1, 6)).contains(negInfInterval));
|
|
assert(NegInfInterval!Date(Date(2012, 1, 7)).contains(negInfInterval));
|
|
assert(NegInfInterval!Date(Date(2012, 1, 8)).contains(negInfInterval));
|
|
|
|
assert(!negInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(!negInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(!negInfInterval.contains(PosInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(!negInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(!negInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(!negInfInterval.contains(PosInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, negInfInterval.contains(interval)));
|
|
static assert(__traits(compiles, negInfInterval.contains(cInterval)));
|
|
static assert(__traits(compiles, negInfInterval.contains(iInterval)));
|
|
static assert(__traits(compiles, negInfInterval.contains(posInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.contains(cPosInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.contains(iPosInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.contains(negInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.contains(cNegInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.contains(iNegInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.contains(interval)));
|
|
static assert(__traits(compiles, cNegInfInterval.contains(cInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.contains(iInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.contains(posInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.contains(cPosInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.contains(iPosInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.contains(negInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.contains(cNegInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.contains(iNegInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.contains(interval)));
|
|
static assert(__traits(compiles, iNegInfInterval.contains(cInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.contains(iInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.contains(posInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.contains(cPosInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.contains(iPosInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.contains(negInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.contains(cNegInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.contains(iNegInfInterval)));
|
|
|
|
//Verify Examples.
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(Interval!Date(Date(1998, 2, 28), Date(2013, 5, 1))));
|
|
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(PosInfInterval!Date(Date(1999, 5, 4))));
|
|
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).contains(NegInfInterval!Date(Date(1996, 5, 4))));
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).contains(NegInfInterval!Date(Date(2013, 7, 9))));
|
|
}
|
|
}
|
|
|
|
//Test NegInfInterval's isBefore(time point).
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
|
|
assert(!negInfInterval.isBefore(Date(2009, 7, 4)));
|
|
assert(!negInfInterval.isBefore(Date(2010, 7, 3)));
|
|
assert(!negInfInterval.isBefore(Date(2010, 7, 4)));
|
|
assert(!negInfInterval.isBefore(Date(2010, 7, 5)));
|
|
assert(!negInfInterval.isBefore(Date(2011, 7, 1)));
|
|
assert(!negInfInterval.isBefore(Date(2012, 1, 6)));
|
|
assert(negInfInterval.isBefore(Date(2012, 1, 7)));
|
|
assert(negInfInterval.isBefore(Date(2012, 1, 8)));
|
|
assert(negInfInterval.isBefore(Date(2013, 1, 7)));
|
|
|
|
const cdate = Date(2010, 7, 6);
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, negInfInterval.isBefore(cdate)));
|
|
static assert(__traits(compiles, cNegInfInterval.isBefore(cdate)));
|
|
static assert(__traits(compiles, iNegInfInterval.isBefore(cdate)));
|
|
|
|
//Verify Examples.
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(1994, 12, 24)));
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(2000, 1, 5)));
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Date(2012, 3, 1)));
|
|
}
|
|
}
|
|
|
|
//Test NegInfInterval's isBefore(Interval).
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
|
|
static void testInterval(in NegInfInterval!Date negInfInterval, in Interval!Date interval)
|
|
{
|
|
negInfInterval.isBefore(interval);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
|
|
assert(!negInfInterval.isBefore(negInfInterval));
|
|
assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
|
|
assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
|
|
assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
|
|
assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
|
|
assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
|
|
assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
|
|
assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
|
|
assert(!negInfInterval.isBefore(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
|
|
assert(!negInfInterval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
|
|
assert(!negInfInterval.isBefore(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
|
|
assert(negInfInterval.isBefore(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
|
|
assert(negInfInterval.isBefore(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
|
|
|
|
assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(!negInfInterval.isBefore(NegInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
assert(!NegInfInterval!Date(Date(2010, 7, 3)).isBefore(negInfInterval));
|
|
assert(!NegInfInterval!Date(Date(2010, 7, 4)).isBefore(negInfInterval));
|
|
assert(!NegInfInterval!Date(Date(2010, 7, 5)).isBefore(negInfInterval));
|
|
assert(!NegInfInterval!Date(Date(2012, 1, 6)).isBefore(negInfInterval));
|
|
assert(!NegInfInterval!Date(Date(2012, 1, 7)).isBefore(negInfInterval));
|
|
assert(!NegInfInterval!Date(Date(2012, 1, 8)).isBefore(negInfInterval));
|
|
|
|
assert(!negInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(!negInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(!negInfInterval.isBefore(PosInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(!negInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(negInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(negInfInterval.isBefore(PosInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, negInfInterval.isBefore(interval)));
|
|
static assert(__traits(compiles, negInfInterval.isBefore(cInterval)));
|
|
static assert(__traits(compiles, negInfInterval.isBefore(iInterval)));
|
|
static assert(__traits(compiles, negInfInterval.isBefore(posInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.isBefore(cPosInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.isBefore(iPosInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.isBefore(negInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.isBefore(cNegInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.isBefore(iNegInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isBefore(interval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isBefore(cInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isBefore(iInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isBefore(posInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isBefore(cPosInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isBefore(iPosInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isBefore(negInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isBefore(cNegInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isBefore(iNegInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isBefore(interval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isBefore(cInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isBefore(iInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isBefore(posInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isBefore(cPosInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isBefore(iPosInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isBefore(negInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isBefore(cNegInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isBefore(iNegInfInterval)));
|
|
|
|
//Verify Examples.
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3))));
|
|
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(1999, 5, 4))));
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).isBefore(PosInfInterval!Date(Date(2012, 3, 1))));
|
|
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(NegInfInterval!Date(Date(1996, 5, 4))));
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isBefore(NegInfInterval!Date(Date(2013, 7, 9))));
|
|
}
|
|
}
|
|
|
|
//Test NegInfInterval's isAfter(time point).
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
|
|
assert(!negInfInterval.isAfter(Date(2009, 7, 4)));
|
|
assert(!negInfInterval.isAfter(Date(2010, 7, 3)));
|
|
assert(!negInfInterval.isAfter(Date(2010, 7, 4)));
|
|
assert(!negInfInterval.isAfter(Date(2010, 7, 5)));
|
|
assert(!negInfInterval.isAfter(Date(2011, 7, 1)));
|
|
assert(!negInfInterval.isAfter(Date(2012, 1, 6)));
|
|
assert(!negInfInterval.isAfter(Date(2012, 1, 7)));
|
|
assert(!negInfInterval.isAfter(Date(2012, 1, 8)));
|
|
assert(!negInfInterval.isAfter(Date(2013, 1, 7)));
|
|
|
|
const cdate = Date(2010, 7, 6);
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, negInfInterval.isAfter(cdate)));
|
|
static assert(__traits(compiles, cNegInfInterval.isAfter(cdate)));
|
|
static assert(__traits(compiles, iNegInfInterval.isAfter(cdate)));
|
|
}
|
|
}
|
|
|
|
//Test NegInfInterval's isAfter(Interval).
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
|
|
static void testInterval(in NegInfInterval!Date negInfInterval, in Interval!Date interval)
|
|
{
|
|
negInfInterval.isAfter(interval);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
|
|
assert(!negInfInterval.isAfter(negInfInterval));
|
|
assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
|
|
assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
|
|
assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
|
|
assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
|
|
assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
|
|
assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
|
|
assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
|
|
assert(!negInfInterval.isAfter(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
|
|
assert(!negInfInterval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
|
|
assert(!negInfInterval.isAfter(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
|
|
assert(!negInfInterval.isAfter(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
|
|
assert(!negInfInterval.isAfter(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
|
|
|
|
assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(!negInfInterval.isAfter(NegInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
assert(!NegInfInterval!Date(Date(2010, 7, 3)).isAfter(negInfInterval));
|
|
assert(!NegInfInterval!Date(Date(2010, 7, 4)).isAfter(negInfInterval));
|
|
assert(!NegInfInterval!Date(Date(2010, 7, 5)).isAfter(negInfInterval));
|
|
assert(!NegInfInterval!Date(Date(2012, 1, 6)).isAfter(negInfInterval));
|
|
assert(!NegInfInterval!Date(Date(2012, 1, 7)).isAfter(negInfInterval));
|
|
assert(!NegInfInterval!Date(Date(2012, 1, 8)).isAfter(negInfInterval));
|
|
|
|
assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(!negInfInterval.isAfter(PosInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, negInfInterval.isAfter(interval)));
|
|
static assert(__traits(compiles, negInfInterval.isAfter(cInterval)));
|
|
static assert(__traits(compiles, negInfInterval.isAfter(iInterval)));
|
|
static assert(__traits(compiles, negInfInterval.isAfter(posInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.isAfter(cPosInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.isAfter(iPosInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.isAfter(negInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.isAfter(cNegInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.isAfter(iNegInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isAfter(interval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isAfter(cInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isAfter(iInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isAfter(posInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isAfter(cPosInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isAfter(iPosInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isAfter(negInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isAfter(cNegInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isAfter(iNegInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isAfter(interval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isAfter(cInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isAfter(iInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isAfter(posInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isAfter(cPosInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isAfter(iPosInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isAfter(negInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isAfter(cNegInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isAfter(iNegInfInterval)));
|
|
|
|
//Verify Examples.
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(1994, 12, 24)));
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(2000, 1, 5)));
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Date(2012, 3, 1)));
|
|
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3))));
|
|
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(PosInfInterval!Date(Date(1999, 5, 4))));
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(PosInfInterval!Date(Date(2012, 3, 1))));
|
|
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(NegInfInterval!Date(Date(1996, 5, 4))));
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAfter(NegInfInterval!Date(Date(2013, 7, 9))));
|
|
}
|
|
}
|
|
|
|
//Test NegInfInterval's intersects().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
|
|
static void testInterval(in NegInfInterval!Date negInfInterval, in Interval!Date interval)
|
|
{
|
|
negInfInterval.intersects(interval);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
|
|
assert(negInfInterval.intersects(negInfInterval));
|
|
assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
|
|
assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
|
|
assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
|
|
assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
|
|
assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
|
|
assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
|
|
assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
|
|
assert(negInfInterval.intersects(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
|
|
assert(negInfInterval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
|
|
assert(negInfInterval.intersects(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
|
|
assert(!negInfInterval.intersects(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
|
|
assert(!negInfInterval.intersects(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
|
|
|
|
assert(negInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(negInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(negInfInterval.intersects(NegInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(negInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(negInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(negInfInterval.intersects(NegInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
assert(NegInfInterval!Date(Date(2010, 7, 3)).intersects(negInfInterval));
|
|
assert(NegInfInterval!Date(Date(2010, 7, 4)).intersects(negInfInterval));
|
|
assert(NegInfInterval!Date(Date(2010, 7, 5)).intersects(negInfInterval));
|
|
assert(NegInfInterval!Date(Date(2012, 1, 6)).intersects(negInfInterval));
|
|
assert(NegInfInterval!Date(Date(2012, 1, 7)).intersects(negInfInterval));
|
|
assert(NegInfInterval!Date(Date(2012, 1, 8)).intersects(negInfInterval));
|
|
|
|
assert(negInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(negInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(negInfInterval.intersects(PosInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(negInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(!negInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(!negInfInterval.intersects(PosInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, negInfInterval.intersects(interval)));
|
|
static assert(__traits(compiles, negInfInterval.intersects(cInterval)));
|
|
static assert(__traits(compiles, negInfInterval.intersects(iInterval)));
|
|
static assert(__traits(compiles, negInfInterval.intersects(posInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.intersects(cPosInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.intersects(iPosInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.intersects(negInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.intersects(cNegInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.intersects(iNegInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.intersects(interval)));
|
|
static assert(__traits(compiles, cNegInfInterval.intersects(cInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.intersects(iInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.intersects(posInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.intersects(cPosInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.intersects(iPosInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.intersects(negInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.intersects(cNegInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.intersects(iNegInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.intersects(interval)));
|
|
static assert(__traits(compiles, iNegInfInterval.intersects(cInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.intersects(iInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.intersects(posInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.intersects(cPosInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.intersects(iPosInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.intersects(negInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.intersects(cNegInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.intersects(iNegInfInterval)));
|
|
|
|
//Verify Examples.
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(Interval!Date(Date(1999, 1, 12), Date(2011, 9, 17))));
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).intersects(Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3))));
|
|
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(1999, 5, 4))));
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).intersects(PosInfInterval!Date(Date(2012, 3, 1))));
|
|
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(1996, 5, 4))));
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).intersects(NegInfInterval!Date(Date(2013, 7, 9))));
|
|
}
|
|
}
|
|
|
|
//Test NegInfInterval's intersection().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
|
|
static void testInterval(I, J)(in I interval1, in J interval2)
|
|
{
|
|
interval1.intersection(interval2);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
|
|
assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
|
|
assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
|
|
|
|
assertThrown!DateTimeException(testInterval(negInfInterval, PosInfInterval!Date(Date(2012, 1, 7))));
|
|
assertThrown!DateTimeException(testInterval(negInfInterval, PosInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
_assertPred!"=="(negInfInterval.intersection(negInfInterval),
|
|
negInfInterval);
|
|
_assertPred!"=="(negInfInterval.intersection(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))),
|
|
Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3)));
|
|
_assertPred!"=="(negInfInterval.intersection(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))),
|
|
Interval!Date(Date(2010, 7, 1), Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))),
|
|
Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4)));
|
|
_assertPred!"=="(negInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))),
|
|
Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5)));
|
|
_assertPred!"=="(negInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))),
|
|
Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.intersection(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))),
|
|
Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))),
|
|
Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6)));
|
|
_assertPred!"=="(negInfInterval.intersection(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))),
|
|
Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))),
|
|
Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.intersection(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))),
|
|
Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7)));
|
|
|
|
_assertPred!"=="(negInfInterval.intersection(NegInfInterval!Date(Date(2010, 7, 3))),
|
|
NegInfInterval!Date(Date(2010, 7, 3)));
|
|
_assertPred!"=="(negInfInterval.intersection(NegInfInterval!Date(Date(2010, 7, 4))),
|
|
NegInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(negInfInterval.intersection(NegInfInterval!Date(Date(2010, 7, 5))),
|
|
NegInfInterval!Date(Date(2010, 7, 5)));
|
|
_assertPred!"=="(negInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 6))),
|
|
NegInfInterval!Date(Date(2012, 1, 6)));
|
|
_assertPred!"=="(negInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 7))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.intersection(NegInfInterval!Date(Date(2012, 1, 8))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
|
|
_assertPred!"=="(NegInfInterval!Date(Date(2010, 7, 3)).intersection(negInfInterval),
|
|
NegInfInterval!Date(Date(2010, 7, 3)));
|
|
_assertPred!"=="(NegInfInterval!Date(Date(2010, 7, 4)).intersection(negInfInterval),
|
|
NegInfInterval!Date(Date(2010, 7, 4)));
|
|
_assertPred!"=="(NegInfInterval!Date(Date(2010, 7, 5)).intersection(negInfInterval),
|
|
NegInfInterval!Date(Date(2010, 7, 5)));
|
|
_assertPred!"=="(NegInfInterval!Date(Date(2012, 1, 6)).intersection(negInfInterval),
|
|
NegInfInterval!Date(Date(2012, 1, 6)));
|
|
_assertPred!"=="(NegInfInterval!Date(Date(2012, 1, 7)).intersection(negInfInterval),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(NegInfInterval!Date(Date(2012, 1, 8)).intersection(negInfInterval),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
|
|
_assertPred!"=="(negInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 3))),
|
|
Interval!Date(Date(2010, 7, 3), Date(2012, 1 ,7)));
|
|
_assertPred!"=="(negInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 4))),
|
|
Interval!Date(Date(2010, 7, 4), Date(2012, 1 ,7)));
|
|
_assertPred!"=="(negInfInterval.intersection(PosInfInterval!Date(Date(2010, 7, 5))),
|
|
Interval!Date(Date(2010, 7, 5), Date(2012, 1 ,7)));
|
|
_assertPred!"=="(negInfInterval.intersection(PosInfInterval!Date(Date(2012, 1, 6))),
|
|
Interval!Date(Date(2012, 1, 6), Date(2012, 1 ,7)));
|
|
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, negInfInterval.intersection(interval)));
|
|
static assert(__traits(compiles, negInfInterval.intersection(cInterval)));
|
|
static assert(__traits(compiles, negInfInterval.intersection(iInterval)));
|
|
static assert(__traits(compiles, negInfInterval.intersection(posInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.intersection(cPosInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.intersection(iPosInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.intersection(negInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.intersection(cNegInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.intersection(iNegInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.intersection(interval)));
|
|
static assert(__traits(compiles, cNegInfInterval.intersection(cInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.intersection(iInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.intersection(posInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.intersection(cPosInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.intersection(iPosInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.intersection(negInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.intersection(cNegInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.intersection(iNegInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.intersection(interval)));
|
|
static assert(__traits(compiles, iNegInfInterval.intersection(cInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.intersection(iInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.intersection(posInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.intersection(cPosInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.intersection(iPosInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.intersection(negInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.intersection(cNegInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.intersection(iNegInfInterval)));
|
|
|
|
//Verify Examples.
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == Interval!Date(Date(1990, 7 , 6), Date(2000, 8, 2)));
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) == Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1)));
|
|
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(PosInfInterval!Date(Date(1990, 7, 6))) == Interval!Date(Date(1990, 7 , 6), Date(2012, 3, 1)));
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(PosInfInterval!Date(Date(1999, 1, 12))) == Interval!Date(Date(1999, 1 , 12), Date(2012, 3, 1)));
|
|
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(NegInfInterval!Date(Date(1999, 7, 6))) == NegInfInterval!Date(Date(1999, 7 , 6)));
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).intersection(NegInfInterval!Date(Date(2013, 1, 12))) == NegInfInterval!Date(Date(2012, 3 , 1)));
|
|
}
|
|
}
|
|
|
|
//Test NegInfInterval's isAdjacent().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
|
|
static void testInterval(in NegInfInterval!Date negInfInterval, in Interval!Date interval)
|
|
{
|
|
negInfInterval.isAdjacent(interval);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
|
|
assert(!negInfInterval.isAdjacent(negInfInterval));
|
|
assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))));
|
|
assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))));
|
|
assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))));
|
|
assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))));
|
|
assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))));
|
|
assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))));
|
|
assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))));
|
|
assert(!negInfInterval.isAdjacent(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))));
|
|
assert(!negInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))));
|
|
assert(!negInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))));
|
|
assert(negInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))));
|
|
assert(!negInfInterval.isAdjacent(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
|
|
|
|
assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(!negInfInterval.isAdjacent(NegInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
assert(!NegInfInterval!Date(Date(2010, 7, 3)).isAdjacent(negInfInterval));
|
|
assert(!NegInfInterval!Date(Date(2010, 7, 4)).isAdjacent(negInfInterval));
|
|
assert(!NegInfInterval!Date(Date(2010, 7, 5)).isAdjacent(negInfInterval));
|
|
assert(!NegInfInterval!Date(Date(2012, 1, 6)).isAdjacent(negInfInterval));
|
|
assert(!NegInfInterval!Date(Date(2012, 1, 7)).isAdjacent(negInfInterval));
|
|
assert(!NegInfInterval!Date(Date(2012, 1, 8)).isAdjacent(negInfInterval));
|
|
|
|
assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 3))));
|
|
assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 4))));
|
|
assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2010, 7, 5))));
|
|
assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 6))));
|
|
assert(negInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 7))));
|
|
assert(!negInfInterval.isAdjacent(PosInfInterval!Date(Date(2012, 1, 8))));
|
|
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, negInfInterval.isAdjacent(interval)));
|
|
static assert(__traits(compiles, negInfInterval.isAdjacent(cInterval)));
|
|
static assert(__traits(compiles, negInfInterval.isAdjacent(iInterval)));
|
|
static assert(__traits(compiles, negInfInterval.isAdjacent(posInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.isAdjacent(cPosInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.isAdjacent(iPosInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.isAdjacent(negInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.isAdjacent(cNegInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.isAdjacent(iNegInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isAdjacent(interval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isAdjacent(cInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isAdjacent(iInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isAdjacent(posInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isAdjacent(cPosInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isAdjacent(iPosInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isAdjacent(negInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isAdjacent(cNegInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.isAdjacent(iNegInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isAdjacent(interval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isAdjacent(cInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isAdjacent(iInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isAdjacent(posInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isAdjacent(cPosInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isAdjacent(iPosInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isAdjacent(negInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isAdjacent(cNegInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.isAdjacent(iNegInfInterval)));
|
|
|
|
//Verify Examples.
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))));
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(1999, 1, 12), Date(2012, 3, 1))));
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(2012, 3, 1), Date(2019, 2, 2))));
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(Interval!Date(Date(2022, 10, 19), Date(2027, 6, 3))));
|
|
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(PosInfInterval!Date(Date(1999, 5, 4))));
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(PosInfInterval!Date(Date(2012, 3, 1))));
|
|
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(NegInfInterval!Date(Date(1996, 5, 4))));
|
|
assert(!NegInfInterval!Date(Date(2012, 3, 1)).isAdjacent(NegInfInterval!Date(Date(2012, 3, 1))));
|
|
}
|
|
}
|
|
|
|
//Test NegInfInterval's merge().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
|
|
static void testInterval(I, J)(in I interval1, in J interval2)
|
|
{
|
|
interval1.merge(interval2);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
|
|
assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))));
|
|
|
|
_assertPred!"=="(negInfInterval.merge(negInfInterval),
|
|
negInfInterval);
|
|
_assertPred!"=="(negInfInterval.merge(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.merge(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))),
|
|
NegInfInterval!Date(Date(2013, 7, 3)));
|
|
_assertPred!"=="(negInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.merge(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))),
|
|
NegInfInterval!Date(Date(2012, 1, 8)));
|
|
_assertPred!"=="(negInfInterval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.merge(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.merge(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))),
|
|
NegInfInterval!Date(Date(2012, 1, 8)));
|
|
_assertPred!"=="(negInfInterval.merge(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))),
|
|
NegInfInterval!Date(Date(2012, 1, 8)));
|
|
|
|
_assertPred!"=="(negInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 3))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 4))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.merge(NegInfInterval!Date(Date(2010, 7, 5))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 6))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 7))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.merge(NegInfInterval!Date(Date(2012, 1, 8))),
|
|
NegInfInterval!Date(Date(2012, 1, 8)));
|
|
|
|
_assertPred!"=="(NegInfInterval!Date(Date(2010, 7, 3)).merge(negInfInterval),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(NegInfInterval!Date(Date(2010, 7, 4)).merge(negInfInterval),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(NegInfInterval!Date(Date(2010, 7, 5)).merge(negInfInterval),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(NegInfInterval!Date(Date(2012, 1, 6)).merge(negInfInterval),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(NegInfInterval!Date(Date(2012, 1, 7)).merge(negInfInterval),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(NegInfInterval!Date(Date(2012, 1, 8)).merge(negInfInterval),
|
|
NegInfInterval!Date(Date(2012, 1, 8)));
|
|
|
|
static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 3)))));
|
|
static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 4)))));
|
|
static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2010, 7, 5)))));
|
|
static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 6)))));
|
|
static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 7)))));
|
|
static assert(!__traits(compiles, negInfInterval.merge(PosInfInterval!Date(Date(2012, 1, 8)))));
|
|
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, negInfInterval.merge(interval)));
|
|
static assert(__traits(compiles, negInfInterval.merge(cInterval)));
|
|
static assert(__traits(compiles, negInfInterval.merge(iInterval)));
|
|
static assert(!__traits(compiles, negInfInterval.merge(posInfInterval)));
|
|
static assert(!__traits(compiles, negInfInterval.merge(cPosInfInterval)));
|
|
static assert(!__traits(compiles, negInfInterval.merge(iPosInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.merge(negInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.merge(cNegInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.merge(iNegInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.merge(interval)));
|
|
static assert(__traits(compiles, cNegInfInterval.merge(cInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.merge(iInterval)));
|
|
static assert(!__traits(compiles, cNegInfInterval.merge(posInfInterval)));
|
|
static assert(!__traits(compiles, cNegInfInterval.merge(cPosInfInterval)));
|
|
static assert(!__traits(compiles, cNegInfInterval.merge(iPosInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.merge(negInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.merge(cNegInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.merge(iNegInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.merge(interval)));
|
|
static assert(__traits(compiles, iNegInfInterval.merge(cInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.merge(iInterval)));
|
|
static assert(!__traits(compiles, iNegInfInterval.merge(posInfInterval)));
|
|
static assert(!__traits(compiles, iNegInfInterval.merge(cPosInfInterval)));
|
|
static assert(!__traits(compiles, iNegInfInterval.merge(iPosInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.merge(negInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.merge(cNegInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.merge(iNegInfInterval)));
|
|
|
|
//Verify Examples.
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == NegInfInterval!Date(Date(2012, 3 , 1)));
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) == NegInfInterval!Date(Date(2015, 9 , 2)));
|
|
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(NegInfInterval!Date(Date(1999, 7, 6))) == NegInfInterval!Date(Date(2012, 3 , 1)));
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).merge(NegInfInterval!Date(Date(2013, 1, 12))) == NegInfInterval!Date(Date(2013, 1 , 12)));
|
|
}
|
|
}
|
|
|
|
//Test NegInfInterval's span().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
|
|
static void testInterval(I, J)(in I interval1, in J interval2)
|
|
{
|
|
interval1.span(interval2);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testInterval(negInfInterval, Interval!Date(Date(2010, 7, 4), dur!"days"(0))));
|
|
|
|
_assertPred!"=="(negInfInterval.span(negInfInterval),
|
|
negInfInterval);
|
|
_assertPred!"=="(negInfInterval.span(Interval!Date(Date(2010, 7, 1), Date(2010, 7, 3))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.span(Interval!Date(Date(2010, 7, 1), Date(2013, 7, 3))),
|
|
NegInfInterval!Date(Date(2013, 7, 3)));
|
|
_assertPred!"=="(negInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 4))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2010, 7, 5))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 7))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.span(Interval!Date(Date(2010, 7, 3), Date(2012, 1, 8))),
|
|
NegInfInterval!Date(Date(2012, 1, 8)));
|
|
_assertPred!"=="(negInfInterval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 6))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.span(Interval!Date(Date(2010, 7, 5), Date(2012, 1, 7))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 7))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.span(Interval!Date(Date(2012, 1, 6), Date(2012, 1, 8))),
|
|
NegInfInterval!Date(Date(2012, 1, 8)));
|
|
_assertPred!"=="(negInfInterval.span(Interval!Date(Date(2012, 1, 7), Date(2012, 1, 8))),
|
|
NegInfInterval!Date(Date(2012, 1, 8)));
|
|
_assertPred!"=="(negInfInterval.span(Interval!Date(Date(2012, 1, 8), Date(2012, 1, 9))),
|
|
NegInfInterval!Date(Date(2012, 1, 9)));
|
|
|
|
_assertPred!"=="(negInfInterval.span(NegInfInterval!Date(Date(2010, 7, 3))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.span(NegInfInterval!Date(Date(2010, 7, 4))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.span(NegInfInterval!Date(Date(2010, 7, 5))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.span(NegInfInterval!Date(Date(2012, 1, 6))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.span(NegInfInterval!Date(Date(2012, 1, 7))),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(negInfInterval.span(NegInfInterval!Date(Date(2012, 1, 8))),
|
|
NegInfInterval!Date(Date(2012, 1, 8)));
|
|
|
|
_assertPred!"=="(NegInfInterval!Date(Date(2010, 7, 3)).span(negInfInterval),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(NegInfInterval!Date(Date(2010, 7, 4)).span(negInfInterval),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(NegInfInterval!Date(Date(2010, 7, 5)).span(negInfInterval),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(NegInfInterval!Date(Date(2012, 1, 6)).span(negInfInterval),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(NegInfInterval!Date(Date(2012, 1, 7)).span(negInfInterval),
|
|
NegInfInterval!Date(Date(2012, 1, 7)));
|
|
_assertPred!"=="(NegInfInterval!Date(Date(2012, 1, 8)).span(negInfInterval),
|
|
NegInfInterval!Date(Date(2012, 1, 8)));
|
|
|
|
static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2010, 7, 3)))));
|
|
static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2010, 7, 4)))));
|
|
static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2010, 7, 5)))));
|
|
static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2012, 1, 6)))));
|
|
static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2012, 1, 7)))));
|
|
static assert(!__traits(compiles, negInfInterval.span(PosInfInterval!Date(Date(2012, 1, 8)))));
|
|
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
const cInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
immutable iInterval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
const cPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
immutable iPosInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, negInfInterval.span(interval)));
|
|
static assert(__traits(compiles, negInfInterval.span(cInterval)));
|
|
static assert(__traits(compiles, negInfInterval.span(iInterval)));
|
|
static assert(!__traits(compiles, negInfInterval.span(posInfInterval)));
|
|
static assert(!__traits(compiles, negInfInterval.span(cPosInfInterval)));
|
|
static assert(!__traits(compiles, negInfInterval.span(iPosInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.span(negInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.span(cNegInfInterval)));
|
|
static assert(__traits(compiles, negInfInterval.span(iNegInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.span(interval)));
|
|
static assert(__traits(compiles, cNegInfInterval.span(cInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.span(iInterval)));
|
|
static assert(!__traits(compiles, cNegInfInterval.span(posInfInterval)));
|
|
static assert(!__traits(compiles, cNegInfInterval.span(cPosInfInterval)));
|
|
static assert(!__traits(compiles, cNegInfInterval.span(iPosInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.span(negInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.span(cNegInfInterval)));
|
|
static assert(__traits(compiles, cNegInfInterval.span(iNegInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.span(interval)));
|
|
static assert(__traits(compiles, iNegInfInterval.span(cInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.span(iInterval)));
|
|
static assert(!__traits(compiles, iNegInfInterval.span(posInfInterval)));
|
|
static assert(!__traits(compiles, iNegInfInterval.span(cPosInfInterval)));
|
|
static assert(!__traits(compiles, iNegInfInterval.span(iPosInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.span(negInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.span(cNegInfInterval)));
|
|
static assert(__traits(compiles, iNegInfInterval.span(iNegInfInterval)));
|
|
|
|
//Verify Examples.
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).span(Interval!Date(Date(1990, 7, 6), Date(2000, 8, 2))) == NegInfInterval!Date(Date(2012, 3 , 1)));
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).span(Interval!Date(Date(1999, 1, 12), Date(2015, 9, 2))) == NegInfInterval!Date(Date(2015, 9 , 2)));
|
|
assert(NegInfInterval!Date(Date(1600, 1, 7)).span(Interval!Date(Date(2012, 3, 11), Date(2017, 7, 1))) == NegInfInterval!Date(Date(2017, 7 , 1)));
|
|
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).span(NegInfInterval!Date(Date(1999, 7, 6))) == NegInfInterval!Date(Date(2012, 3 , 1)));
|
|
assert(NegInfInterval!Date(Date(2012, 3, 1)).span(NegInfInterval!Date(Date(2013, 1, 12))) == NegInfInterval!Date(Date(2013, 1 , 12)));
|
|
}
|
|
}
|
|
|
|
//Test NegInfInterval's shift().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto interval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
|
|
static void testInterval(I)(I interval, in Duration duration, in I expected, size_t line = __LINE__)
|
|
{
|
|
interval.shift(duration);
|
|
_assertPred!"=="(interval, expected, "", __FILE__, line);
|
|
}
|
|
|
|
testInterval(interval, dur!"days"(22), NegInfInterval!Date(Date(2012, 1, 29)));
|
|
testInterval(interval, dur!"days"(-22), NegInfInterval!Date(Date(2011, 12, 16)));
|
|
|
|
const cInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(!__traits(compiles, cInterval.shift(dur!"days"(5))));
|
|
static assert(!__traits(compiles, iInterval.shift(dur!"days"(5))));
|
|
|
|
//Verify Examples.
|
|
auto interval1 = NegInfInterval!Date(Date(2012, 4, 5));
|
|
auto interval2 = NegInfInterval!Date(Date(2012, 4, 5));
|
|
|
|
interval1.shift(dur!"days"(50));
|
|
assert(interval1 == NegInfInterval!Date(Date(2012, 5, 25)));
|
|
|
|
interval2.shift(dur!"days"(-50));
|
|
assert(interval2 == NegInfInterval!Date( Date(2012, 2, 15)));
|
|
}
|
|
}
|
|
|
|
//Test NegInfInterval's shift(int, int, AllowDayOverflow).
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
{
|
|
auto interval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
|
|
static void testIntervalFail(I)(I interval, int years, int months)
|
|
{
|
|
interval.shift(years, months);
|
|
}
|
|
|
|
static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, in I expected, size_t line = __LINE__)
|
|
{
|
|
interval.shift(years, months, allow);
|
|
_assertPred!"=="(interval, expected, "", __FILE__, line);
|
|
}
|
|
|
|
testInterval(interval, 5, 0, AllowDayOverflow.yes, NegInfInterval!Date(Date(2017, 1, 7)));
|
|
testInterval(interval, -5, 0, AllowDayOverflow.yes, NegInfInterval!Date(Date(2007, 1, 7)));
|
|
|
|
auto interval2 = NegInfInterval!Date(Date(2010, 5, 31));
|
|
|
|
testInterval(interval2, 1, 1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2011, 7, 1)));
|
|
testInterval(interval2, 1, -1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2011, 5, 1)));
|
|
testInterval(interval2, -1, -1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2009, 5, 1)));
|
|
testInterval(interval2, -1, 1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2009, 7, 1)));
|
|
|
|
testInterval(interval2, 1, 1, AllowDayOverflow.no, NegInfInterval!Date(Date(2011, 6, 30)));
|
|
testInterval(interval2, 1, -1, AllowDayOverflow.no, NegInfInterval!Date(Date(2011, 4, 30)));
|
|
testInterval(interval2, -1, -1, AllowDayOverflow.no, NegInfInterval!Date(Date(2009, 4, 30)));
|
|
testInterval(interval2, -1, 1, AllowDayOverflow.no, NegInfInterval!Date(Date(2009, 6, 30)));
|
|
}
|
|
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(!__traits(compiles, cNegInfInterval.shift(1)));
|
|
static assert(!__traits(compiles, iNegInfInterval.shift(1)));
|
|
|
|
//Verify Examples.
|
|
auto interval1 = NegInfInterval!Date(Date(2012, 3, 1));
|
|
auto interval2 = NegInfInterval!Date(Date(2012, 3, 1));
|
|
|
|
interval1.shift(2);
|
|
assert(interval1 == NegInfInterval!Date(Date(2014, 3, 1)));
|
|
|
|
interval2.shift(-2);
|
|
assert(interval2 == NegInfInterval!Date(Date(2010, 3, 1)));
|
|
}
|
|
}
|
|
|
|
//Test NegInfInterval's expand().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto interval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
|
|
static void testInterval(I)(I interval, in Duration duration, in I expected, size_t line = __LINE__)
|
|
{
|
|
interval.expand(duration);
|
|
_assertPred!"=="(interval, expected, "", __FILE__, line);
|
|
}
|
|
|
|
testInterval(interval, dur!"days"(22), NegInfInterval!Date(Date(2012, 1, 29)));
|
|
testInterval(interval, dur!"days"(-22), NegInfInterval!Date(Date(2011, 12, 16)));
|
|
|
|
const cInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(!__traits(compiles, cInterval.expand(dur!"days"(5))));
|
|
static assert(!__traits(compiles, iInterval.expand(dur!"days"(5))));
|
|
|
|
//Verify Examples.
|
|
auto interval1 = NegInfInterval!Date(Date(2012, 3, 1));
|
|
auto interval2 = NegInfInterval!Date(Date(2012, 3, 1));
|
|
|
|
interval1.expand(dur!"days"(2));
|
|
assert(interval1 == NegInfInterval!Date(Date(2012, 3, 3)));
|
|
|
|
interval2.expand(dur!"days"(-2));
|
|
assert(interval2 == NegInfInterval!Date(Date(2012, 2, 28)));
|
|
}
|
|
}
|
|
|
|
//Test NegInfInterval's expand(int, int, AllowDayOverflow).
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
{
|
|
auto interval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
|
|
static void testInterval(I)(I interval, int years, int months, AllowDayOverflow allow, in I expected, size_t line = __LINE__)
|
|
{
|
|
interval.expand(years, months, allow);
|
|
_assertPred!"=="(interval, expected, "", __FILE__, line);
|
|
}
|
|
|
|
testInterval(interval, 5, 0, AllowDayOverflow.yes, NegInfInterval!Date(Date(2017, 1, 7)));
|
|
testInterval(interval, -5, 0, AllowDayOverflow.yes, NegInfInterval!Date(Date(2007, 1, 7)));
|
|
|
|
auto interval2 = NegInfInterval!Date(Date(2010, 5, 31));
|
|
|
|
testInterval(interval2, 1, 1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2011, 7, 1)));
|
|
testInterval(interval2, 1, -1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2011, 5, 1)));
|
|
testInterval(interval2, -1, -1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2009, 5, 1)));
|
|
testInterval(interval2, -1, 1, AllowDayOverflow.yes, NegInfInterval!Date(Date(2009, 7, 1)));
|
|
|
|
testInterval(interval2, 1, 1, AllowDayOverflow.no, NegInfInterval!Date(Date(2011, 6, 30)));
|
|
testInterval(interval2, 1, -1, AllowDayOverflow.no, NegInfInterval!Date(Date(2011, 4, 30)));
|
|
testInterval(interval2, -1, -1, AllowDayOverflow.no, NegInfInterval!Date(Date(2009, 4, 30)));
|
|
testInterval(interval2, -1, 1, AllowDayOverflow.no, NegInfInterval!Date( Date(2009, 6, 30)));
|
|
}
|
|
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(!__traits(compiles, cNegInfInterval.expand(1)));
|
|
static assert(!__traits(compiles, iNegInfInterval.expand(1)));
|
|
|
|
//Verify Examples.
|
|
auto interval1 = NegInfInterval!Date(Date(2012, 3, 1));
|
|
auto interval2 = NegInfInterval!Date(Date(2012, 3, 1));
|
|
|
|
interval1.expand(2);
|
|
assert(interval1 == NegInfInterval!Date(Date(2014, 3, 1)));
|
|
|
|
interval2.expand(-2);
|
|
assert(interval2 == NegInfInterval!Date(Date(2010, 3, 1)));
|
|
}
|
|
}
|
|
|
|
//Test NegInfInterval's bwdRange().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
|
|
static void testInterval(NegInfInterval!Date negInfInterval)
|
|
{
|
|
negInfInterval.bwdRange(everyDayOfWeek!(Date, Direction.fwd)(DayOfWeek.fri)).popFront();
|
|
}
|
|
|
|
assertThrown!DateTimeException(testInterval(negInfInterval));
|
|
|
|
_assertPred!"=="(NegInfInterval!Date(Date(2010, 10, 1)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri)).front,
|
|
Date(2010, 10, 1));
|
|
|
|
_assertPred!"=="(NegInfInterval!Date(Date(2010, 10, 1)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri), PopFirst.yes).front,
|
|
Date(2010, 9, 24));
|
|
|
|
//Verify Examples.
|
|
auto interval = NegInfInterval!Date(Date(2010, 9, 9));
|
|
auto func = (in Date date)
|
|
{
|
|
if((date.day & 1) == 0)
|
|
return date - dur!"days"(2);
|
|
|
|
return date - dur!"days"(1);
|
|
};
|
|
auto range = interval.bwdRange(func);
|
|
|
|
//An odd day. Using PopFirst.yes would have made this Date(2010, 9, 8).
|
|
assert(range.front == Date(2010, 9, 9));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 8));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 6));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 4));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 2));
|
|
|
|
range.popFront();
|
|
assert(!range.empty);
|
|
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, cNegInfInterval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri))));
|
|
static assert(__traits(compiles, iNegInfInterval.bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri))));
|
|
}
|
|
}
|
|
|
|
//Test NegInfInterval's toString().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(NegInfInterval!Date(Date(2012, 1, 7)).toString(), "[-∞ - 2012-Jan-07)");
|
|
|
|
const cNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
immutable iNegInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
static assert(__traits(compiles, cNegInfInterval.toString()));
|
|
static assert(__traits(compiles, iNegInfInterval.toString()));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Range-generating function.
|
|
|
|
Returns a delegate which returns the next time point with the given
|
|
$(D DayOfWeek) in a range.
|
|
|
|
Using this delegate allows you to iterate over successive time points which
|
|
are all the same day of the week. e.g. passing $(D DayOfWeek.mon) to
|
|
$(D everyDayOfWeek) would result in a delegate which could be used to
|
|
iterate over all of the Mondays in a range.
|
|
|
|
Params:
|
|
dir = The direction to iterate in. If passing the return value to
|
|
$(D fwdRange), use $(D Direction.fwd). If passing it to
|
|
$(D bwdRange), use $(D Direction.bwd).
|
|
dayOfWeek = The week that each time point in the range will be.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto interval = Interval!Date(Date(2010, 9, 2), Date(2010, 9, 27));
|
|
auto func = everyDayOfWeek!Date(DayOfWeek.mon);
|
|
auto range = interval.fwdRange(func);
|
|
|
|
//A Thursday. Using PopFirst.yes would have made this Date(2010, 9, 6).
|
|
assert(range.front == Date(2010, 9, 2));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 6));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 13));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 20));
|
|
|
|
range.popFront();
|
|
assert(range.empty);
|
|
--------------------
|
|
+/
|
|
static TP delegate(in TP) everyDayOfWeek(TP, Direction dir = Direction.fwd)(DayOfWeek dayOfWeek) nothrow
|
|
if(isTimePoint!TP &&
|
|
(dir == Direction.fwd || dir == Direction.bwd) &&
|
|
__traits(hasMember, TP, "dayOfWeek") &&
|
|
!__traits(isStaticFunction, TP.dayOfWeek) &&
|
|
is(ReturnType!(TP.dayOfWeek) == DayOfWeek) &&
|
|
(functionAttributes!(TP.dayOfWeek) & FunctionAttribute.PROPERTY) &&
|
|
(functionAttributes!(TP.dayOfWeek) & FunctionAttribute.NOTHROW))
|
|
{
|
|
TP func(in TP tp)
|
|
{
|
|
TP retval = cast(TP)tp;
|
|
immutable days = daysToDayOfWeek(retval.dayOfWeek, dayOfWeek);
|
|
|
|
static if(dir == Direction.fwd)
|
|
immutable adjustedDays = days == 0 ? 7 : days;
|
|
else
|
|
immutable adjustedDays = days == 0 ? -7 : days - 7;
|
|
|
|
return retval += dur!"days"(adjustedDays);
|
|
}
|
|
|
|
return &func;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto funcFwd = everyDayOfWeek!Date(DayOfWeek.mon);
|
|
auto funcBwd = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.mon);
|
|
|
|
_assertPred!"=="(funcFwd(Date(2010, 8, 28)), Date(2010, 8, 30));
|
|
_assertPred!"=="(funcFwd(Date(2010, 8, 29)), Date(2010, 8, 30));
|
|
_assertPred!"=="(funcFwd(Date(2010, 8, 30)), Date(2010, 9, 6));
|
|
_assertPred!"=="(funcFwd(Date(2010, 8, 31)), Date(2010, 9, 6));
|
|
_assertPred!"=="(funcFwd(Date(2010, 9, 1)), Date(2010, 9, 6));
|
|
_assertPred!"=="(funcFwd(Date(2010, 9, 2)), Date(2010, 9, 6));
|
|
_assertPred!"=="(funcFwd(Date(2010, 9, 3)), Date(2010, 9, 6));
|
|
_assertPred!"=="(funcFwd(Date(2010, 9, 4)), Date(2010, 9, 6));
|
|
_assertPred!"=="(funcFwd(Date(2010, 9, 5)), Date(2010, 9, 6));
|
|
_assertPred!"=="(funcFwd(Date(2010, 9, 6)), Date(2010, 9, 13));
|
|
_assertPred!"=="(funcFwd(Date(2010, 9, 7)), Date(2010, 9, 13));
|
|
|
|
_assertPred!"=="(funcBwd(Date(2010, 8, 28)), Date(2010, 8, 23));
|
|
_assertPred!"=="(funcBwd(Date(2010, 8, 29)), Date(2010, 8, 23));
|
|
_assertPred!"=="(funcBwd(Date(2010, 8, 30)), Date(2010, 8, 23));
|
|
_assertPred!"=="(funcBwd(Date(2010, 8, 31)), Date(2010, 8, 30));
|
|
_assertPred!"=="(funcBwd(Date(2010, 9, 1)), Date(2010, 8, 30));
|
|
_assertPred!"=="(funcBwd(Date(2010, 9, 2)), Date(2010, 8, 30));
|
|
_assertPred!"=="(funcBwd(Date(2010, 9, 3)), Date(2010, 8, 30));
|
|
_assertPred!"=="(funcBwd(Date(2010, 9, 4)), Date(2010, 8, 30));
|
|
_assertPred!"=="(funcBwd(Date(2010, 9, 5)), Date(2010, 8, 30));
|
|
_assertPred!"=="(funcBwd(Date(2010, 9, 6)), Date(2010, 8, 30));
|
|
_assertPred!"=="(funcBwd(Date(2010, 9, 7)), Date(2010, 9, 6));
|
|
|
|
static assert(!__traits(compiles, everyDayOfWeek!(TimeOfDay)(DayOfWeek.mon)));
|
|
static assert(__traits(compiles, everyDayOfWeek!(DateTime)(DayOfWeek.mon)));
|
|
static assert(__traits(compiles, everyDayOfWeek!(SysTime)(DayOfWeek.mon)));
|
|
|
|
//Verify Examples.
|
|
auto interval = Interval!Date(Date(2010, 9, 2), Date(2010, 9, 27));
|
|
auto func = everyDayOfWeek!Date(DayOfWeek.mon);
|
|
auto range = interval.fwdRange(func);
|
|
|
|
//A Thursday. Using PopFirst.yes would have made this Date(2010, 9, 6).
|
|
assert(range.front == Date(2010, 9, 2));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 6));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 13));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 20));
|
|
|
|
range.popFront();
|
|
assert(range.empty);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Range-generating function.
|
|
|
|
Returns a delegate which returns the next time point with the given month
|
|
which would be reached by adding months to the given time point.
|
|
|
|
So, using this delegate allows you to iterate over successive time points
|
|
which are in the same month but different years. For example, you could
|
|
iterate over each successive December 25th in an interval by starting with a
|
|
date which had the 25th as its day and passed $(D Month.dec) to
|
|
$(D everyMonth) to create the delegate.
|
|
|
|
Since it wouldn't really make sense to be iterating over a specific month
|
|
and end up with some of the time points in the succeeding month or two years
|
|
after the previous time point, $(D AllowDayOverflow.no) is always used when
|
|
calculating the next time point.
|
|
|
|
Params:
|
|
dir = The direction to iterate in. If passing the return value to
|
|
$(D fwdRange), use $(D Direction.fwd). If passing it to
|
|
$(D bwdRange), use $(D Direction.bwd).
|
|
month = The month that each time point in the range will be in.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto interval = Interval!Date(Date(2000, 1, 30), Date(2004, 8, 5));
|
|
auto func = everyMonth!(Date)(Month.feb);
|
|
auto range = interval.fwdRange(func);
|
|
|
|
//Using PopFirst.yes would have made this Date(2010, 2, 29).
|
|
assert(range.front == Date(2000, 1, 30));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2000, 2, 29));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2001, 2, 28));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2002, 2, 28));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2003, 2, 28));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2004, 2, 28));
|
|
|
|
range.popFront();
|
|
assert(range.empty);
|
|
--------------------
|
|
+/
|
|
static TP delegate(in TP) everyMonth(TP, Direction dir = Direction.fwd)(int month)
|
|
if(isTimePoint!TP &&
|
|
(dir == Direction.fwd || dir == Direction.bwd) &&
|
|
__traits(hasMember, TP, "month") &&
|
|
!__traits(isStaticFunction, TP.month) &&
|
|
is(ReturnType!(TP.month) == Month) &&
|
|
(functionAttributes!(TP.month) & FunctionAttribute.PROPERTY) &&
|
|
(functionAttributes!(TP.month) & FunctionAttribute.NOTHROW))
|
|
{
|
|
enforceValid!"months"(month);
|
|
|
|
TP func(in TP tp)
|
|
{
|
|
TP retval = cast(TP)tp;
|
|
immutable months = monthsToMonth(retval.month, month);
|
|
|
|
static if(dir == Direction.fwd)
|
|
immutable adjustedMonths = months == 0 ? 12 : months;
|
|
else
|
|
immutable adjustedMonths = months == 0 ? -12 : months - 12;
|
|
|
|
retval.add!"months"(adjustedMonths, AllowDayOverflow.no);
|
|
|
|
if(retval.month != month)
|
|
{
|
|
retval.add!"months"(-1);
|
|
assert(retval.month == month);
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
return &func;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto funcFwd = everyMonth!Date(Month.jun);
|
|
auto funcBwd = everyMonth!(Date, Direction.bwd)(Month.jun);
|
|
|
|
_assertPred!"=="(funcFwd(Date(2010, 5, 31)), Date(2010, 6, 30));
|
|
_assertPred!"=="(funcFwd(Date(2010, 6, 30)), Date(2011, 6, 30));
|
|
_assertPred!"=="(funcFwd(Date(2010, 7, 31)), Date(2011, 6, 30));
|
|
_assertPred!"=="(funcFwd(Date(2010, 8, 31)), Date(2011, 6, 30));
|
|
_assertPred!"=="(funcFwd(Date(2010, 9, 30)), Date(2011, 6, 30));
|
|
_assertPred!"=="(funcFwd(Date(2010, 10, 31)), Date(2011, 6, 30));
|
|
_assertPred!"=="(funcFwd(Date(2010, 11, 30)), Date(2011, 6, 30));
|
|
_assertPred!"=="(funcFwd(Date(2010, 12, 31)), Date(2011, 6, 30));
|
|
_assertPred!"=="(funcFwd(Date(2011, 1, 31)), Date(2011, 6, 30));
|
|
_assertPred!"=="(funcFwd(Date(2011, 2, 28)), Date(2011, 6, 28));
|
|
_assertPred!"=="(funcFwd(Date(2011, 3, 31)), Date(2011, 6, 30));
|
|
_assertPred!"=="(funcFwd(Date(2011, 4, 30)), Date(2011, 6, 30));
|
|
_assertPred!"=="(funcFwd(Date(2011, 5, 31)), Date(2011, 6, 30));
|
|
_assertPred!"=="(funcFwd(Date(2011, 6, 30)), Date(2012, 6, 30));
|
|
_assertPred!"=="(funcFwd(Date(2011, 7, 31)), Date(2012, 6, 30));
|
|
|
|
_assertPred!"=="(funcBwd(Date(2010, 5, 31)), Date(2009, 6, 30));
|
|
_assertPred!"=="(funcBwd(Date(2010, 6, 30)), Date(2009, 6, 30));
|
|
_assertPred!"=="(funcBwd(Date(2010, 7, 31)), Date(2010, 6, 30));
|
|
_assertPred!"=="(funcBwd(Date(2010, 8, 31)), Date(2010, 6, 30));
|
|
_assertPred!"=="(funcBwd(Date(2010, 9, 30)), Date(2010, 6, 30));
|
|
_assertPred!"=="(funcBwd(Date(2010, 10, 31)), Date(2010, 6, 30));
|
|
_assertPred!"=="(funcBwd(Date(2010, 11, 30)), Date(2010, 6, 30));
|
|
_assertPred!"=="(funcBwd(Date(2010, 12, 31)), Date(2010, 6, 30));
|
|
_assertPred!"=="(funcBwd(Date(2011, 1, 31)), Date(2010, 6, 30));
|
|
_assertPred!"=="(funcBwd(Date(2011, 2, 28)), Date(2010, 6, 28));
|
|
_assertPred!"=="(funcBwd(Date(2011, 3, 31)), Date(2010, 6, 30));
|
|
_assertPred!"=="(funcBwd(Date(2011, 4, 30)), Date(2010, 6, 30));
|
|
_assertPred!"=="(funcBwd(Date(2011, 5, 31)), Date(2010, 6, 30));
|
|
_assertPred!"=="(funcBwd(Date(2011, 6, 30)), Date(2010, 6, 30));
|
|
_assertPred!"=="(funcBwd(Date(2011, 7, 30)), Date(2011, 6, 30));
|
|
|
|
static assert(!__traits(compiles, everyMonth!(TimeOfDay)(Month.jan)));
|
|
static assert(__traits(compiles, everyMonth!(DateTime)(Month.jan)));
|
|
static assert(__traits(compiles, everyMonth!(SysTime)(Month.jan)));
|
|
|
|
//Verify Examples.
|
|
auto interval = Interval!Date(Date(2000, 1, 30), Date(2004, 8, 5));
|
|
auto func = everyMonth!(Date)(Month.feb);
|
|
auto range = interval.fwdRange(func);
|
|
|
|
//Using PopFirst.yes would have made this Date(2010, 2, 29).
|
|
assert(range.front == Date(2000, 1, 30));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2000, 2, 29));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2001, 2, 28));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2002, 2, 28));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2003, 2, 28));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2004, 2, 28));
|
|
|
|
range.popFront();
|
|
assert(range.empty);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Range-generating function.
|
|
|
|
Returns a delegate which returns the next time point which is the given
|
|
duration later.
|
|
|
|
Using this delegate allows you to iterate over successive time points which
|
|
are apart by the given duration e.g. passing $(D dur!"days"(3)) to
|
|
$(D everyDuration) would result in a delegate which could be used to iterate
|
|
over a range of days which are each 3 days apart.
|
|
|
|
Params:
|
|
dir = The direction to iterate in. If passing the return value to
|
|
$(D fwdRange), use $(D Direction.fwd). If passing it to
|
|
$(D bwdRange), use $(D Direction.bwd).
|
|
duration = The duration which separates each successive time point in
|
|
the range.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto interval = Interval!Date(Date(2010, 9, 2), Date(2010, 9, 27));
|
|
auto func = everyDuration!Date(dur!"days"(8));
|
|
auto range = interval.fwdRange(func);
|
|
|
|
//Using PopFirst.yes would have made this Date(2010, 9, 10).
|
|
assert(range.front == Date(2010, 9, 2));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 10));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 18));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 26));
|
|
|
|
range.popFront();
|
|
assert(range.empty);
|
|
--------------------
|
|
+/
|
|
static TP delegate(in TP) everyDuration(TP, Direction dir = Direction.fwd, D)
|
|
(D duration) nothrow
|
|
if(isTimePoint!TP &&
|
|
__traits(compiles, TP.init + duration) &&
|
|
(dir == Direction.fwd || dir == Direction.bwd))
|
|
{
|
|
TP func(in TP tp)
|
|
{
|
|
static if(dir == Direction.fwd)
|
|
return tp + duration;
|
|
else
|
|
return tp - duration;
|
|
}
|
|
|
|
return &func;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto funcFwd = everyDuration!Date(dur!"days"(27));
|
|
auto funcBwd = everyDuration!(Date, Direction.bwd)(dur!"days"(27));
|
|
|
|
_assertPred!"=="(funcFwd(Date(2009, 12, 25)), Date(2010, 1, 21));
|
|
_assertPred!"=="(funcFwd(Date(2009, 12, 26)), Date(2010, 1, 22));
|
|
_assertPred!"=="(funcFwd(Date(2009, 12, 27)), Date(2010, 1, 23));
|
|
_assertPred!"=="(funcFwd(Date(2009, 12, 28)), Date(2010, 1, 24));
|
|
|
|
_assertPred!"=="(funcBwd(Date(2010, 1, 21)), Date(2009, 12, 25));
|
|
_assertPred!"=="(funcBwd(Date(2010, 1, 22)), Date(2009, 12, 26));
|
|
_assertPred!"=="(funcBwd(Date(2010, 1, 23)), Date(2009, 12, 27));
|
|
_assertPred!"=="(funcBwd(Date(2010, 1, 24)), Date(2009, 12, 28));
|
|
|
|
static assert(__traits(compiles, everyDuration!Date(dur!"hnsecs"(1))));
|
|
static assert(__traits(compiles, everyDuration!TimeOfDay(dur!"hnsecs"(1))));
|
|
static assert(__traits(compiles, everyDuration!DateTime(dur!"hnsecs"(1))));
|
|
static assert(__traits(compiles, everyDuration!SysTime(dur!"hnsecs"(1))));
|
|
|
|
//Verify Examples.
|
|
auto interval = Interval!Date(Date(2010, 9, 2), Date(2010, 9, 27));
|
|
auto func = everyDuration!Date(dur!"days"(8));
|
|
auto range = interval.fwdRange(func);
|
|
|
|
//Using PopFirst.yes would have made this Date(2010, 9, 10).
|
|
assert(range.front == Date(2010, 9, 2));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 10));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 18));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2010, 9, 26));
|
|
|
|
range.popFront();
|
|
assert(range.empty);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Range-generating function.
|
|
|
|
Returns a delegate which returns the next time point which is the given
|
|
number of years, month, and duration later.
|
|
|
|
The difference between this version of $(D everyDuration) and the version
|
|
which just takes a $(D Duration) is that this one also takes the number of
|
|
years and months (along with an $(D AllowDayOverflow) to indicate whether
|
|
adding years and months should allow the days to overflow).
|
|
|
|
Note that if iterating forward, $(D add!"years"()) is called on the given
|
|
time point, then $(D add!"months"()), and finally the duration is added
|
|
to it. However, if iterating backwards, the duration is added first, then
|
|
$(D add!"months"()) is called, and finally $(D add!"years"()) is called.
|
|
That way, going backwards generates close to the same time points that
|
|
iterating forward does, but since adding years and months is not entirely
|
|
reversible (due to possible day overflow, regardless of whether
|
|
$(D AllowDayOverflow.yes) or $(D AllowDayOverflow.no) is used), it can't be
|
|
guaranteed that iterating backwards will give you the same time points as
|
|
iterating forward would have (even assuming that the end of the range is a
|
|
time point which would be returned by the delegate when iterating forward
|
|
from $(D begin)).
|
|
|
|
Params:
|
|
dir = The direction to iterate in. If passing the return
|
|
value to $(D fwdRange), use $(D Direction.fwd). If
|
|
passing it to $(D bwdRange), use $(D Direction.bwd).
|
|
years = The number of years to add to the time point passed to
|
|
the delegate.
|
|
months = The number of months to add to the time point passed to
|
|
the delegate.
|
|
allowOverflow = Whether the days should be allowed to overflow on
|
|
$(D begin) and $(D end), causing their month to
|
|
increment.
|
|
duration = The duration to add to the time point passed to the
|
|
delegate.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto interval = Interval!Date(Date(2010, 9, 2), Date(2025, 9, 27));
|
|
auto func = everyDuration!Date(4, 1, AllowDayOverflow.yes, dur!"days"(2));
|
|
auto range = interval.fwdRange(func);
|
|
|
|
//Using PopFirst.yes would have made this Date(2014, 10, 12).
|
|
assert(range.front == Date(2010, 9, 2));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2014, 10, 4));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2018, 11, 6));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2022, 12, 8));
|
|
|
|
range.popFront();
|
|
assert(range.empty);
|
|
--------------------
|
|
+/
|
|
static TP delegate(in TP) everyDuration(TP, Direction dir = Direction.fwd, D)
|
|
(int years,
|
|
int months = 0,
|
|
AllowDayOverflow allowOverflow = AllowDayOverflow.yes,
|
|
D duration = dur!"days"(0)) nothrow
|
|
if(isTimePoint!TP &&
|
|
__traits(compiles, TP.init + duration) &&
|
|
__traits(compiles, TP.init.add!"years"(years)) &&
|
|
__traits(compiles, TP.init.add!"months"(months)) &&
|
|
(dir == Direction.fwd || dir == Direction.bwd))
|
|
{
|
|
TP func(in TP tp)
|
|
{
|
|
static if(dir == Direction.fwd)
|
|
{
|
|
TP retval = cast(TP)tp;
|
|
|
|
retval.add!"years"(years, allowOverflow);
|
|
retval.add!"months"(months, allowOverflow);
|
|
|
|
return retval + duration;
|
|
}
|
|
else
|
|
{
|
|
TP retval = tp - duration;
|
|
|
|
retval.add!"months"(-months, allowOverflow);
|
|
retval.add!"years"(-years, allowOverflow);
|
|
|
|
return retval;
|
|
}
|
|
}
|
|
|
|
return &func;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
{
|
|
auto funcFwd = everyDuration!Date(1, 2, AllowDayOverflow.yes, dur!"days"(3));
|
|
auto funcBwd = everyDuration!(Date, Direction.bwd)(1, 2, AllowDayOverflow.yes, dur!"days"(3));
|
|
|
|
_assertPred!"=="(funcFwd(Date(2009, 12, 25)), Date(2011, 2, 28));
|
|
_assertPred!"=="(funcFwd(Date(2009, 12, 26)), Date(2011, 3, 1));
|
|
_assertPred!"=="(funcFwd(Date(2009, 12, 27)), Date(2011, 3, 2));
|
|
_assertPred!"=="(funcFwd(Date(2009, 12, 28)), Date(2011, 3, 3));
|
|
_assertPred!"=="(funcFwd(Date(2009, 12, 29)), Date(2011, 3, 4));
|
|
|
|
_assertPred!"=="(funcBwd(Date(2011, 2, 28)), Date(2009, 12, 25));
|
|
_assertPred!"=="(funcBwd(Date(2011, 3, 1)), Date(2009, 12, 26));
|
|
_assertPred!"=="(funcBwd(Date(2011, 3, 2)), Date(2009, 12, 27));
|
|
_assertPred!"=="(funcBwd(Date(2011, 3, 3)), Date(2009, 12, 28));
|
|
_assertPred!"=="(funcBwd(Date(2011, 3, 4)), Date(2010, 1, 1));
|
|
}
|
|
|
|
{
|
|
auto funcFwd = everyDuration!Date(1, 2, AllowDayOverflow.no, dur!"days"(3));
|
|
auto funcBwd = everyDuration!(Date, Direction.bwd)(1, 2, AllowDayOverflow.yes, dur!"days"(3));
|
|
|
|
_assertPred!"=="(funcFwd(Date(2009, 12, 25)), Date(2011, 2, 28));
|
|
_assertPred!"=="(funcFwd(Date(2009, 12, 26)), Date(2011, 3, 1));
|
|
_assertPred!"=="(funcFwd(Date(2009, 12, 27)), Date(2011, 3, 2));
|
|
_assertPred!"=="(funcFwd(Date(2009, 12, 28)), Date(2011, 3, 3));
|
|
_assertPred!"=="(funcFwd(Date(2009, 12, 29)), Date(2011, 3, 3));
|
|
|
|
_assertPred!"=="(funcBwd(Date(2011, 2, 28)), Date(2009, 12, 25));
|
|
_assertPred!"=="(funcBwd(Date(2011, 3, 1)), Date(2009, 12, 26));
|
|
_assertPred!"=="(funcBwd(Date(2011, 3, 2)), Date(2009, 12, 27));
|
|
_assertPred!"=="(funcBwd(Date(2011, 3, 3)), Date(2009, 12, 28));
|
|
_assertPred!"=="(funcBwd(Date(2011, 3, 4)), Date(2010, 1, 1));
|
|
}
|
|
|
|
static assert(__traits(compiles, everyDuration!Date(1, 2, AllowDayOverflow.yes, dur!"hnsecs"(1))));
|
|
static assert(!__traits(compiles, everyDuration!TimeOfDay(1, 2, AllowDayOverflow.yes, dur!"hnsecs"(1))));
|
|
static assert(__traits(compiles, everyDuration!DateTime(1, 2, AllowDayOverflow.yes, dur!"hnsecs"(1))));
|
|
static assert(__traits(compiles, everyDuration!SysTime(1, 2, AllowDayOverflow.yes, dur!"hnsecs"(1))));
|
|
|
|
//Verify Examples.
|
|
auto interval = Interval!Date(Date(2010, 9, 2), Date(2025, 9, 27));
|
|
auto func = everyDuration!Date(4, 1, AllowDayOverflow.yes, dur!"days"(2));
|
|
auto range = interval.fwdRange(func);
|
|
|
|
//Using PopFirst.yes would have made this Date(2014, 10, 12).
|
|
assert(range.front == Date(2010, 9, 2));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2014, 10, 4));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2018, 11, 6));
|
|
|
|
range.popFront();
|
|
assert(range.front == Date(2022, 12, 8));
|
|
|
|
range.popFront();
|
|
assert(range.empty);
|
|
}
|
|
}
|
|
|
|
|
|
//TODO Add function to create a range generating function based on a date recurrence pattern string.
|
|
// This may or may not involve creating a date recurrence pattern class of some sort - probably
|
|
// yes if we want to make it easy to build them. However, there is a standard recurrence
|
|
// pattern string format which we'd want to support with a range generator (though if we have
|
|
// the class/struct, we'd probably want a version of the range generating function which took
|
|
// that rather than a string).
|
|
|
|
|
|
//==============================================================================
|
|
// Section with ranges.
|
|
//==============================================================================
|
|
|
|
|
|
/++
|
|
A range over an $(D Interval).
|
|
|
|
$(D IntervalRange) is only ever constructed by $(D Interval). However, when
|
|
it is constructed, it is given a function, $(D func), which is used to
|
|
generate the time points which are iterated over. $(D func) takes a time
|
|
point and returns a time point of the same type. So, for instance, if you
|
|
had an $(D Interval!Date), and you wanted to iterate over all of the days in
|
|
that interval, you would pass a function to $(D Interval)'s $(D fwdRange)
|
|
where that function took a $(D Date) and returned a $(D Date) which was one
|
|
day later. That function would then be used by $(D IntervalRange)'s
|
|
$(D popFront) to iterate over the $(D Date)s in the interval.
|
|
|
|
If $(D dir == Direction.fwd), then a range iterates forward in time, whereas
|
|
if $(D dir == Direction.bwd), then it iterates backwards in time. So, if
|
|
$(D dir == Direction.fwd) then $(D front == interval.begin), whereas if
|
|
$(D dir == Direction.bwd) then $(D front == interval.end). $(D func) must
|
|
generate a time point going in the proper direction of iteration, or a
|
|
$(D DateTimeException) will be thrown. So, if you're iterating forward in
|
|
time, the time point that $(D func) generates must be later in time than the
|
|
one passed to it. If it's either identical or earlier in time, then a
|
|
$(D DateTimeException) will be thrown. If you're iterating backwards, then
|
|
the generated time point must be before the time point which was passed in.
|
|
|
|
If the generated time point is ever passed the edge of the range in the
|
|
proper direction, then the edge of that range will be used instead. So, if
|
|
iterating forward, and the generated time point is past the interval's
|
|
$(D end), then $(D front) becomes $(D end). If iterating backwards, and the
|
|
generated time point is before $(D begin), then $(D front) becomes
|
|
$(D begin). In either case, the range would then be empty.
|
|
|
|
Also note that while normally the $(D begin) of an interval is included in
|
|
it and its $(D end) is excluded from it, if $(D dir == Direction.bwd), then
|
|
$(D begin) is treated as excluded and $(D end) is treated as included. This
|
|
allows for the same behavior in both directions. This works because none of
|
|
$(D Interval)'s functions which care about whether $(D begin) or $(D end) is
|
|
included or excluded are ever called by $(D IntervalRange). $(D interval)
|
|
returns a normal interval, regardless of whether $(D dir == Direction.fwd)
|
|
or if $(D dir == Direction.bwd), so any $(D Interval) functions which are
|
|
called on it which care about whether $(D begin) or $(D end) are included or
|
|
excluded will treat $(D begin) as included and $(D end) as excluded.
|
|
+/
|
|
struct IntervalRange(TP, Direction dir)
|
|
if(isTimePoint!TP && dir != Direction.both)
|
|
{
|
|
public:
|
|
|
|
/++
|
|
Params:
|
|
rhs = The $(D IntervalRange) to assign to this one.
|
|
+/
|
|
/+ref+/ IntervalRange opAssign(ref IntervalRange rhs) pure nothrow
|
|
{
|
|
_interval = rhs._interval;
|
|
_func = rhs._func;
|
|
|
|
return this;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this $(D IntervalRange) is empty.
|
|
+/
|
|
@property bool empty() const pure nothrow
|
|
{
|
|
return _interval.empty;
|
|
}
|
|
|
|
|
|
/++
|
|
The first time point in the range.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the range is empty.
|
|
+/
|
|
@property TP front() const pure
|
|
{
|
|
_enforceNotEmpty();
|
|
|
|
static if(dir == Direction.fwd)
|
|
return _interval.begin;
|
|
else
|
|
return _interval.end;
|
|
}
|
|
|
|
|
|
/++
|
|
Pops $(D front) from the range, using $(D func) to generate the next
|
|
time point in the range. If the generated time point is beyond the edge
|
|
of the range, then $(D front) is set to that edge, and the range is then
|
|
empty. So, if iterating forwards, and the generated time point is
|
|
greater than the interval's $(D end), then $(D front) is set to
|
|
$(D end). If iterating backwards, and the generated time point is less
|
|
than the interval's $(D begin), then $(D front) is set to $(D begin).
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the range is empty or if the generated
|
|
time point is in the wrong direction (i.e. if you're iterating
|
|
forward and the generated time point is before $(D front), or if
|
|
you're iterating backwards, and the generated time point is after
|
|
$(D front)).
|
|
+/
|
|
void popFront()
|
|
{
|
|
_enforceNotEmpty();
|
|
|
|
static if(dir == Direction.fwd)
|
|
{
|
|
auto begin = _func(_interval.begin);
|
|
|
|
if(begin > _interval.end)
|
|
begin = _interval.end;
|
|
|
|
_enforceCorrectDirection(begin);
|
|
|
|
_interval.begin = begin;
|
|
}
|
|
else
|
|
{
|
|
auto end = _func(_interval.end);
|
|
|
|
if(end < _interval.begin)
|
|
end = _interval.begin;
|
|
|
|
_enforceCorrectDirection(end);
|
|
|
|
_interval.end = end;
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns a copy of $(D this).
|
|
+/
|
|
@property IntervalRange save() pure nothrow
|
|
{
|
|
return this;
|
|
}
|
|
|
|
|
|
/++
|
|
The interval that this $(D IntervalRange) currently covers.
|
|
+/
|
|
@property Interval!TP interval() const pure nothrow
|
|
{
|
|
return cast(Interval!TP)_interval;
|
|
}
|
|
|
|
|
|
/++
|
|
The function used to generate the next time point in the range.
|
|
+/
|
|
TP delegate(in TP) func() pure nothrow @property
|
|
{
|
|
return _func;
|
|
}
|
|
|
|
|
|
/++
|
|
The $(D Direction) that this range iterates in.
|
|
+/
|
|
@property Direction direction() const pure nothrow
|
|
{
|
|
return dir;
|
|
}
|
|
|
|
|
|
private:
|
|
|
|
/+
|
|
Params:
|
|
interval = The interval that this range covers.
|
|
func = The function used to generate the time points which are
|
|
iterated over.
|
|
+/
|
|
this(in Interval!TP interval, TP delegate(in TP) func) pure nothrow
|
|
{
|
|
_func = func;
|
|
_interval = interval;
|
|
}
|
|
|
|
|
|
/+
|
|
Throws:
|
|
$(D DateTimeException) if this interval is empty.
|
|
+/
|
|
void _enforceNotEmpty(size_t line = __LINE__) const pure
|
|
{
|
|
if(empty)
|
|
throw new DateTimeException("Invalid operation for an empty IntervalRange.", __FILE__, line);
|
|
}
|
|
|
|
|
|
/+
|
|
Throws:
|
|
$(D DateTimeException) if $(D_PARAM newTP) is in the wrong
|
|
direction.
|
|
+/
|
|
void _enforceCorrectDirection(in TP newTP, size_t line = __LINE__) const
|
|
{
|
|
static if(dir == Direction.fwd)
|
|
{
|
|
enforce(newTP > _interval._begin,
|
|
new DateTimeException(format("Generated time point is before previous begin: prev [%s] new [%s]",
|
|
interval._begin,
|
|
newTP),
|
|
__FILE__,
|
|
line));
|
|
}
|
|
else
|
|
{
|
|
enforce(newTP < _interval._end,
|
|
new DateTimeException(format("Generated time point is after previous end: prev [%s] new [%s]",
|
|
interval._end,
|
|
newTP),
|
|
__FILE__,
|
|
line));
|
|
}
|
|
}
|
|
|
|
|
|
Interval!TP _interval;
|
|
TP delegate(in TP) _func;
|
|
}
|
|
|
|
//Test that IntervalRange satisfies the range predicates that it's supposed to satisfy.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static assert(isInputRange!(IntervalRange!(Date, Direction.fwd)));
|
|
static assert(isForwardRange!(IntervalRange!(Date, Direction.fwd)));
|
|
|
|
//Commented out due to bug http://d.puremagic.com/issues/show_bug.cgi?id=4895
|
|
//static assert(!isOutputRange!(IntervalRange!(Date, Direction.fwd), Date));
|
|
|
|
static assert(!isBidirectionalRange!(IntervalRange!(Date, Direction.fwd)));
|
|
static assert(!isRandomAccessRange!(IntervalRange!(Date, Direction.fwd)));
|
|
static assert(!hasSwappableElements!(IntervalRange!(Date, Direction.fwd)));
|
|
static assert(!hasAssignableElements!(IntervalRange!(Date, Direction.fwd)));
|
|
static assert(!hasLength!(IntervalRange!(Date, Direction.fwd)));
|
|
static assert(!isInfinite!(IntervalRange!(Date, Direction.fwd)));
|
|
static assert(!hasSlicing!(IntervalRange!(Date, Direction.fwd)));
|
|
|
|
static assert(is(ElementType!(IntervalRange!(Date, Direction.fwd)) == Date));
|
|
static assert(is(ElementType!(IntervalRange!(TimeOfDay, Direction.fwd)) == TimeOfDay));
|
|
static assert(is(ElementType!(IntervalRange!(DateTime, Direction.fwd)) == DateTime));
|
|
static assert(is(ElementType!(IntervalRange!(SysTime, Direction.fwd)) == SysTime));
|
|
}
|
|
}
|
|
|
|
//Test construction of IntervalRange.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
{
|
|
Date dateFunc(in Date date)
|
|
{
|
|
return date;
|
|
}
|
|
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
|
|
auto ir = IntervalRange!(Date, Direction.fwd)(interval, &dateFunc);
|
|
}
|
|
|
|
{
|
|
TimeOfDay todFunc(in TimeOfDay tod)
|
|
{
|
|
return tod;
|
|
}
|
|
|
|
auto interval = Interval!TimeOfDay(TimeOfDay(12, 1, 7), TimeOfDay(14, 0, 0));
|
|
|
|
auto ir = IntervalRange!(TimeOfDay, Direction.fwd)(interval, &todFunc);
|
|
}
|
|
|
|
{
|
|
DateTime dtFunc(in DateTime dt)
|
|
{
|
|
return dt;
|
|
}
|
|
|
|
auto interval = Interval!DateTime(DateTime(2010, 7, 4, 12, 1, 7), DateTime(2012, 1, 7, 14, 0, 0));
|
|
|
|
auto ir = IntervalRange!(DateTime, Direction.fwd)(interval, &dtFunc);
|
|
}
|
|
|
|
{
|
|
SysTime stFunc(in SysTime st)
|
|
{
|
|
return cast(SysTime)st;
|
|
}
|
|
|
|
auto interval = Interval!SysTime(SysTime(DateTime(2010, 7, 4, 12, 1, 7)), SysTime(DateTime(2012, 1, 7, 14, 0, 0)));
|
|
|
|
auto ir = IntervalRange!(SysTime, Direction.fwd)(interval, &stFunc);
|
|
}
|
|
}
|
|
}
|
|
|
|
//Test IntervalRange's empty().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//fwd
|
|
{
|
|
auto range = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri));
|
|
|
|
assert(!range.empty);
|
|
range.popFront();
|
|
assert(range.empty);
|
|
|
|
const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri));
|
|
static assert(__traits(compiles, cRange.empty));
|
|
|
|
//Apparently, creating an immutable IntervalRange!Date doesn't work, so we can't test if
|
|
//empty works with it. However, since an immutable range is pretty useless, it's no great loss.
|
|
}
|
|
|
|
//bwd
|
|
{
|
|
auto range = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 21)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri));
|
|
|
|
assert(!range.empty);
|
|
range.popFront();
|
|
assert(range.empty);
|
|
|
|
const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri));
|
|
static assert(__traits(compiles, cRange.empty));
|
|
|
|
//Apparently, creating an immutable IntervalRange!Date doesn't work, so we can't test if
|
|
//empty works with it. However, since an immutable range is pretty useless, it's no great loss.
|
|
}
|
|
}
|
|
}
|
|
|
|
//Test IntervalRange's front.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//fwd
|
|
{
|
|
auto emptyRange = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 20)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes);
|
|
assertThrown!DateTimeException((in IntervalRange!(Date, Direction.fwd) range){range.front;}(emptyRange));
|
|
|
|
auto range = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed));
|
|
_assertPred!"=="(range.front, Date(2010, 7, 4));
|
|
|
|
auto poppedRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes);
|
|
_assertPred!"=="(poppedRange.front, Date(2010, 7, 7));
|
|
|
|
const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri));
|
|
static assert(__traits(compiles, cRange.front));
|
|
}
|
|
|
|
//bwd
|
|
{
|
|
auto emptyRange = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 20)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes);
|
|
assertThrown!DateTimeException((in IntervalRange!(Date, Direction.bwd) range){range.front;}(emptyRange));
|
|
|
|
auto range = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed));
|
|
_assertPred!"=="(range.front, Date(2012, 1, 7));
|
|
|
|
auto poppedRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes);
|
|
_assertPred!"=="(poppedRange.front, Date(2012, 1, 4));
|
|
|
|
const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri));
|
|
static assert(__traits(compiles, cRange.front));
|
|
}
|
|
}
|
|
}
|
|
|
|
//Test IntervalRange's popFront().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//fwd
|
|
{
|
|
auto emptyRange = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 20)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes);
|
|
assertThrown!DateTimeException((IntervalRange!(Date, Direction.fwd) range){range.popFront();}(emptyRange));
|
|
|
|
auto range = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes);
|
|
auto expected = range.front;
|
|
|
|
foreach(date; range)
|
|
{
|
|
_assertPred!"=="(date, expected);
|
|
expected += dur!"days"(7);
|
|
}
|
|
|
|
_assertPred!"=="(walkLength(range), 79);
|
|
|
|
const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri));
|
|
static assert(__traits(compiles, cRange.front));
|
|
}
|
|
|
|
//bwd
|
|
{
|
|
auto emptyRange = Interval!Date(Date(2010, 9, 19), Date(2010, 9, 20)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes);
|
|
assertThrown!DateTimeException((IntervalRange!(Date, Direction.bwd) range){range.popFront();}(emptyRange));
|
|
|
|
auto range = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes);
|
|
auto expected = range.front;
|
|
|
|
foreach(date; range)
|
|
{
|
|
_assertPred!"=="(date, expected);
|
|
expected += dur!"days"(-7);
|
|
}
|
|
|
|
_assertPred!"=="(walkLength(range), 79);
|
|
|
|
const cRange = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri));
|
|
static assert(!__traits(compiles, cRange.popFront()));
|
|
}
|
|
}
|
|
}
|
|
|
|
//Test IntervalRange's save.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//fwd
|
|
{
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
auto func = everyDayOfWeek!Date(DayOfWeek.fri);
|
|
auto range = interval.fwdRange(func);
|
|
|
|
assert(range.save == range);
|
|
}
|
|
|
|
//bwd
|
|
{
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri);
|
|
auto range = interval.bwdRange(func);
|
|
|
|
assert(range.save == range);
|
|
}
|
|
}
|
|
}
|
|
|
|
//Test IntervalRange's interval.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//fwd
|
|
{
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
auto func = everyDayOfWeek!Date(DayOfWeek.fri);
|
|
auto range = interval.fwdRange(func);
|
|
|
|
assert(range.interval == interval);
|
|
|
|
const cRange = range;
|
|
static assert(__traits(compiles, cRange.interval));
|
|
}
|
|
|
|
//bwd
|
|
{
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri);
|
|
auto range = interval.bwdRange(func);
|
|
|
|
assert(range.interval == interval);
|
|
|
|
const cRange = range;
|
|
static assert(__traits(compiles, cRange.interval));
|
|
}
|
|
}
|
|
}
|
|
|
|
//Test IntervalRange's func.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//fwd
|
|
{
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
auto func = everyDayOfWeek!Date(DayOfWeek.fri);
|
|
auto range = interval.fwdRange(func);
|
|
|
|
assert(range.func == func);
|
|
}
|
|
|
|
//bwd
|
|
{
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri);
|
|
auto range = interval.bwdRange(func);
|
|
|
|
assert(range.func == func);
|
|
}
|
|
}
|
|
}
|
|
|
|
//Test IntervalRange's direction.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//fwd
|
|
{
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
auto func = everyDayOfWeek!Date(DayOfWeek.fri);
|
|
auto range = interval.fwdRange(func);
|
|
|
|
assert(range.direction == Direction.fwd);
|
|
|
|
const cRange = range;
|
|
static assert(__traits(compiles, cRange.direction));
|
|
}
|
|
|
|
//bwd
|
|
{
|
|
auto interval = Interval!Date(Date(2010, 7, 4), Date(2012, 1, 7));
|
|
auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri);
|
|
auto range = interval.bwdRange(func);
|
|
|
|
assert(range.direction == Direction.bwd);
|
|
|
|
const cRange = range;
|
|
static assert(__traits(compiles, cRange.direction));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
A range over a $(D PosInfInterval). It is an infinite range.
|
|
|
|
$(D PosInfIntervalRange) is only ever constructed by $(D PosInfInterval).
|
|
However, when it is constructed, it is given a function, $(D func), which
|
|
is used to generate the time points which are iterated over. $(D func)
|
|
takes a time point and returns a time point of the same type. So, for
|
|
instance, if you had a $(D PosInfInterval!Date), and you wanted to iterate
|
|
over all of the days in that interval, you would pass a function to
|
|
$(D PosInfInterval)'s $(D fwdRange) where that function took a $(D Date) and
|
|
returned a $(D Date) which was one day later. That function would then be
|
|
used by $(D PosInfIntervalRange)'s $(D popFront) to iterate over the
|
|
$(D Date)s in the interval - though obviously, since the range is infinite,
|
|
you would use a function such as $(D std.range.take) with it rather than
|
|
iterating over $(I all) of the dates.
|
|
|
|
As the interval goes to positive infinity, the range is always iterated over
|
|
forwards, never backwards. $(D func) must generate a time point going in
|
|
the proper direction of iteration, or a $(D DateTimeException) will be
|
|
thrown. So, the time points that $(D func) generates must be later in time
|
|
than the one passed to it. If it's either identical or earlier in time, then
|
|
a $(D DateTimeException) will be thrown.
|
|
+/
|
|
struct PosInfIntervalRange(TP)
|
|
if(isTimePoint!TP)
|
|
{
|
|
public:
|
|
|
|
/++
|
|
Params:
|
|
rhs = The $(D PosInfIntervalRange) to assign to this one.
|
|
+/
|
|
/+ref+/ PosInfIntervalRange opAssign(ref PosInfIntervalRange rhs) pure nothrow
|
|
{
|
|
_interval = rhs._interval;
|
|
_func = rhs._func;
|
|
|
|
return this;
|
|
}
|
|
|
|
|
|
/++
|
|
This is an infinite range, so it is never empty.
|
|
+/
|
|
enum bool empty = false;
|
|
|
|
|
|
/++
|
|
The first time point in the range.
|
|
+/
|
|
@property TP front() const pure nothrow
|
|
{
|
|
return _interval.begin;
|
|
}
|
|
|
|
|
|
/++
|
|
Pops $(D front) from the range, using $(D func) to generate the next
|
|
time point in the range.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the generated time point is less than
|
|
$(D front).
|
|
+/
|
|
void popFront()
|
|
{
|
|
auto begin = _func(_interval.begin);
|
|
|
|
_enforceCorrectDirection(begin);
|
|
|
|
_interval.begin = begin;
|
|
}
|
|
|
|
|
|
/++
|
|
Returns a copy of $(D this).
|
|
+/
|
|
@property PosInfIntervalRange save() pure nothrow
|
|
{
|
|
return this;
|
|
}
|
|
|
|
|
|
/++
|
|
The interval that this range currently covers.
|
|
+/
|
|
@property PosInfInterval!TP interval() const pure nothrow
|
|
{
|
|
return cast(PosInfInterval!TP)_interval;
|
|
}
|
|
|
|
|
|
/++
|
|
The function used to generate the next time point in the range.
|
|
+/
|
|
TP delegate(in TP) func() pure nothrow @property
|
|
{
|
|
return _func;
|
|
}
|
|
|
|
|
|
private:
|
|
|
|
/+
|
|
Params:
|
|
interval = The interval that this range covers.
|
|
func = The function used to generate the time points which are
|
|
iterated over.
|
|
+/
|
|
this(in PosInfInterval!TP interval, TP delegate(in TP) func) pure nothrow
|
|
{
|
|
_func = func;
|
|
_interval = interval;
|
|
}
|
|
|
|
|
|
/+
|
|
Throws:
|
|
$(D DateTimeException) if $(D_PARAME newTP) is in the wrong
|
|
direction.
|
|
+/
|
|
void _enforceCorrectDirection(in TP newTP, size_t line = __LINE__) const
|
|
{
|
|
enforce(newTP > _interval._begin,
|
|
new DateTimeException(format("Generated time point is before previous begin: prev [%s] new [%s]",
|
|
interval._begin,
|
|
newTP),
|
|
__FILE__,
|
|
line));
|
|
}
|
|
|
|
|
|
PosInfInterval!TP _interval;
|
|
TP delegate(in TP) _func;
|
|
}
|
|
|
|
//Test that PosInfIntervalRange satisfies the range predicates that it's supposed to satisfy.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static assert(isInputRange!(PosInfIntervalRange!Date));
|
|
static assert(isForwardRange!(PosInfIntervalRange!Date));
|
|
static assert(isInfinite!(PosInfIntervalRange!Date));
|
|
|
|
//Commented out due to bug http://d.puremagic.com/issues/show_bug.cgi?id=4895
|
|
//static assert(!isOutputRange!(PosInfIntervalRange!Date, Date));
|
|
static assert(!isBidirectionalRange!(PosInfIntervalRange!Date));
|
|
static assert(!isRandomAccessRange!(PosInfIntervalRange!Date));
|
|
static assert(!hasSwappableElements!(PosInfIntervalRange!Date));
|
|
static assert(!hasAssignableElements!(PosInfIntervalRange!Date));
|
|
static assert(!hasLength!(PosInfIntervalRange!Date));
|
|
static assert(!hasSlicing!(PosInfIntervalRange!Date));
|
|
|
|
static assert(is(ElementType!(PosInfIntervalRange!Date) == Date));
|
|
static assert(is(ElementType!(PosInfIntervalRange!TimeOfDay) == TimeOfDay));
|
|
static assert(is(ElementType!(PosInfIntervalRange!DateTime) == DateTime));
|
|
static assert(is(ElementType!(PosInfIntervalRange!SysTime) == SysTime));
|
|
}
|
|
}
|
|
|
|
//Test construction of PosInfIntervalRange.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
{
|
|
Date dateFunc(in Date date)
|
|
{
|
|
return date;
|
|
}
|
|
|
|
auto posInfInterval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
|
|
auto ir = PosInfIntervalRange!Date(posInfInterval, &dateFunc);
|
|
}
|
|
|
|
{
|
|
TimeOfDay todFunc(in TimeOfDay tod)
|
|
{
|
|
return tod;
|
|
}
|
|
|
|
auto posInfInterval = PosInfInterval!TimeOfDay(TimeOfDay(12, 1, 7));
|
|
|
|
auto ir = PosInfIntervalRange!(TimeOfDay)(posInfInterval, &todFunc);
|
|
}
|
|
|
|
{
|
|
DateTime dtFunc(in DateTime dt)
|
|
{
|
|
return dt;
|
|
}
|
|
|
|
auto posInfInterval = PosInfInterval!DateTime(DateTime(2010, 7, 4, 12, 1, 7));
|
|
|
|
auto ir = PosInfIntervalRange!(DateTime)(posInfInterval, &dtFunc);
|
|
}
|
|
|
|
{
|
|
SysTime stFunc(in SysTime st)
|
|
{
|
|
return cast(SysTime)st;
|
|
}
|
|
|
|
auto posInfInterval = PosInfInterval!SysTime(SysTime(DateTime(2010, 7, 4, 12, 1, 7)));
|
|
|
|
auto ir = PosInfIntervalRange!(SysTime)(posInfInterval, &stFunc);
|
|
}
|
|
}
|
|
}
|
|
|
|
//Test PosInfIntervalRange's front.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto range = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed));
|
|
_assertPred!"=="(range.front, Date(2010, 7, 4));
|
|
|
|
auto poppedRange = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes);
|
|
_assertPred!"=="(poppedRange.front, Date(2010, 7, 7));
|
|
|
|
const cRange = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri));
|
|
static assert(__traits(compiles, cRange.front));
|
|
}
|
|
}
|
|
|
|
//Test PosInfIntervalRange's popFront().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto range = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.wed), PopFirst.yes);
|
|
auto expected = range.front;
|
|
|
|
foreach(date; take(range, 79))
|
|
{
|
|
_assertPred!"=="(date, expected);
|
|
expected += dur!"days"(7);
|
|
}
|
|
|
|
const cRange = PosInfInterval!Date(Date(2010, 7, 4)).fwdRange(everyDayOfWeek!Date(DayOfWeek.fri));
|
|
static assert(!__traits(compiles, cRange.popFront()));
|
|
}
|
|
}
|
|
|
|
//Test PosInfIntervalRange's save.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto interval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
auto func = everyDayOfWeek!Date(DayOfWeek.fri);
|
|
auto range = interval.fwdRange(func);
|
|
|
|
assert(range.save == range);
|
|
}
|
|
}
|
|
|
|
//Test PosInfIntervalRange's interval.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto interval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
auto func = everyDayOfWeek!Date(DayOfWeek.fri);
|
|
auto range = interval.fwdRange(func);
|
|
|
|
assert(range.interval == interval);
|
|
|
|
const cRange = range;
|
|
static assert(__traits(compiles, cRange.interval));
|
|
}
|
|
}
|
|
|
|
//Test PosInfIntervalRange's func.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto interval = PosInfInterval!Date(Date(2010, 7, 4));
|
|
auto func = everyDayOfWeek!Date(DayOfWeek.fri);
|
|
auto range = interval.fwdRange(func);
|
|
|
|
assert(range.func == func);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
A range over a $(D NegInfInterval). It is an infinite range.
|
|
|
|
$(D NegInfIntervalRange) is only ever constructed by $(D NegInfInterval).
|
|
However, when it is constructed, it is given a function, $(D func), which
|
|
is used to generate the time points which are iterated over. $(D func)
|
|
takes a time point and returns a time point of the same type. So, for
|
|
instance, if you had a $(D NegInfInterval!Date), and you wanted to iterate
|
|
over all of the days in that interval, you would pass a function to
|
|
$(D NegInfInterval)'s $(D bwdRange) where that function took a $(D Date) and
|
|
returned a $(D Date) which was one day earlier. That function would then be
|
|
used by $(D NegInfIntervalRange)'s $(D popFront) to iterate over the
|
|
$(D Date)s in the interval - though obviously, since the range is infinite,
|
|
you would use a function such as $(D std.range.take) with it rather than
|
|
iterating over $(I all) of the dates.
|
|
|
|
As the interval goes to negative infinity, the range is always iterated over
|
|
backwards, never forwards. $(D func) must generate a time point going in
|
|
the proper direction of iteration, or a $(D DateTimeException) will be
|
|
thrown. So, the time points that $(D func) generates must be earlier in time
|
|
than the one passed to it. If it's either identical or later in time, then a
|
|
$(D DateTimeException) will be thrown.
|
|
|
|
Also note that while normally the $(D end) of an interval is excluded from
|
|
it, $(D NegInfIntervalRange) treats it as if it were included. This allows
|
|
for the same behavior as you get with $(D PosInfIntervalRange). This works
|
|
because none of $(D NegInfInterval)'s functions which care about whether
|
|
$(D end) is included or excluded are ever called by
|
|
$(D NegInfIntervalRange). $(D interval) returns a normal interval, so any
|
|
$(D NegInfInterval) functions which are called on it which care about
|
|
whether $(D end) is included or excluded will treat $(D end) as excluded.
|
|
+/
|
|
struct NegInfIntervalRange(TP)
|
|
if(isTimePoint!TP)
|
|
{
|
|
public:
|
|
|
|
/++
|
|
Params:
|
|
rhs = The $(D NegInfIntervalRange) to assign to this one.
|
|
+/
|
|
/+ref+/ NegInfIntervalRange opAssign(ref NegInfIntervalRange rhs) pure nothrow
|
|
{
|
|
_interval = rhs._interval;
|
|
_func = rhs._func;
|
|
|
|
return this;
|
|
}
|
|
|
|
|
|
/++
|
|
This is an infinite range, so it is never empty.
|
|
+/
|
|
enum bool empty = false;
|
|
|
|
|
|
/++
|
|
The first time point in the range.
|
|
+/
|
|
@property TP front() const pure nothrow
|
|
{
|
|
return _interval.end;
|
|
}
|
|
|
|
|
|
/++
|
|
Pops $(D front) from the range, using $(D func) to generate the next
|
|
time point in the range.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the generated time point is greater than
|
|
$(D front).
|
|
+/
|
|
void popFront()
|
|
{
|
|
auto end = _func(_interval.end);
|
|
|
|
_enforceCorrectDirection(end);
|
|
|
|
_interval.end = end;
|
|
}
|
|
|
|
|
|
/++
|
|
Returns a copy of $(D this).
|
|
+/
|
|
@property NegInfIntervalRange save() pure nothrow
|
|
{
|
|
return this;
|
|
}
|
|
|
|
|
|
/++
|
|
The interval that this range currently covers.
|
|
+/
|
|
@property NegInfInterval!TP interval() const pure nothrow
|
|
{
|
|
return cast(NegInfInterval!TP)_interval;
|
|
}
|
|
|
|
|
|
/++
|
|
The function used to generate the next time point in the range.
|
|
+/
|
|
TP delegate(in TP) func() pure nothrow @property
|
|
{
|
|
return _func;
|
|
}
|
|
|
|
|
|
private:
|
|
|
|
/+
|
|
Params:
|
|
interval = The interval that this range covers.
|
|
func = The function used to generate the time points which are
|
|
iterated over.
|
|
+/
|
|
this(in NegInfInterval!TP interval, TP delegate(in TP) func) pure nothrow
|
|
{
|
|
_func = func;
|
|
_interval = interval;
|
|
}
|
|
|
|
|
|
/+
|
|
Throws:
|
|
$(D DateTimeException) if $(D_PARAM newTP) is in the wrong
|
|
direction.
|
|
+/
|
|
void _enforceCorrectDirection(in TP newTP, size_t line = __LINE__) const
|
|
{
|
|
enforce(newTP < _interval._end,
|
|
new DateTimeException(format("Generated time point is before previous end: prev [%s] new [%s]",
|
|
interval._end,
|
|
newTP),
|
|
__FILE__,
|
|
line));
|
|
}
|
|
|
|
|
|
NegInfInterval!TP _interval;
|
|
TP delegate(in TP) _func;
|
|
}
|
|
|
|
//Test that NegInfIntervalRange satisfies the range predicates that it's supposed to satisfy.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static assert(isInputRange!(NegInfIntervalRange!Date));
|
|
static assert(isForwardRange!(NegInfIntervalRange!Date));
|
|
static assert(isInfinite!(NegInfIntervalRange!Date));
|
|
|
|
//Commented out due to bug http://d.puremagic.com/issues/show_bug.cgi?id=4895
|
|
//static assert(!isOutputRange!(NegInfIntervalRange!Date, Date));
|
|
static assert(!isBidirectionalRange!(NegInfIntervalRange!Date));
|
|
static assert(!isRandomAccessRange!(NegInfIntervalRange!Date));
|
|
static assert(!hasSwappableElements!(NegInfIntervalRange!Date));
|
|
static assert(!hasAssignableElements!(NegInfIntervalRange!Date));
|
|
static assert(!hasLength!(NegInfIntervalRange!Date));
|
|
static assert(!hasSlicing!(NegInfIntervalRange!Date));
|
|
|
|
static assert(is(ElementType!(NegInfIntervalRange!Date) == Date));
|
|
static assert(is(ElementType!(NegInfIntervalRange!TimeOfDay) == TimeOfDay));
|
|
static assert(is(ElementType!(NegInfIntervalRange!DateTime) == DateTime));
|
|
}
|
|
}
|
|
|
|
//Test construction of NegInfIntervalRange.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
{
|
|
Date dateFunc(in Date date)
|
|
{
|
|
return date;
|
|
}
|
|
|
|
auto negInfInterval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
|
|
auto ir = NegInfIntervalRange!Date(negInfInterval, &dateFunc);
|
|
}
|
|
|
|
{
|
|
TimeOfDay todFunc(in TimeOfDay tod)
|
|
{
|
|
return tod;
|
|
}
|
|
|
|
auto negInfInterval = NegInfInterval!TimeOfDay(TimeOfDay(14, 0, 0));
|
|
|
|
auto ir = NegInfIntervalRange!(TimeOfDay)(negInfInterval, &todFunc);
|
|
}
|
|
|
|
{
|
|
DateTime dtFunc(in DateTime dt)
|
|
{
|
|
return dt;
|
|
}
|
|
|
|
auto negInfInterval = NegInfInterval!DateTime(DateTime(2012, 1, 7, 14, 0, 0));
|
|
|
|
auto ir = NegInfIntervalRange!(DateTime)(negInfInterval, &dtFunc);
|
|
}
|
|
|
|
{
|
|
SysTime stFunc(in SysTime st)
|
|
{
|
|
return cast(SysTime)(st);
|
|
}
|
|
|
|
auto negInfInterval = NegInfInterval!SysTime(SysTime(DateTime(2012, 1, 7, 14, 0, 0)));
|
|
|
|
auto ir = NegInfIntervalRange!(SysTime)(negInfInterval, &stFunc);
|
|
}
|
|
}
|
|
}
|
|
|
|
//Test NegInfIntervalRange's front.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto range = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed));
|
|
_assertPred!"=="(range.front, Date(2012, 1, 7));
|
|
|
|
auto poppedRange = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes);
|
|
_assertPred!"=="(poppedRange.front, Date(2012, 1, 4));
|
|
|
|
const cRange = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri));
|
|
static assert(__traits(compiles, cRange.front));
|
|
}
|
|
}
|
|
|
|
//Test NegInfIntervalRange's popFront().
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto range = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.wed), PopFirst.yes);
|
|
auto expected = range.front;
|
|
|
|
foreach(date; take(range, 79))
|
|
{
|
|
_assertPred!"=="(date, expected);
|
|
expected += dur!"days"(-7);
|
|
}
|
|
|
|
const cRange = NegInfInterval!Date(Date(2012, 1, 7)).bwdRange(everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri));
|
|
static assert(!__traits(compiles, cRange.popFront()));
|
|
}
|
|
}
|
|
|
|
//Test NegInfIntervalRange's save.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto interval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri);
|
|
auto range = interval.bwdRange(func);
|
|
|
|
assert(range.save == range);
|
|
}
|
|
}
|
|
|
|
//Test NegInfIntervalRange's interval.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto interval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri);
|
|
auto range = interval.bwdRange(func);
|
|
|
|
assert(range.interval == interval);
|
|
|
|
const cRange = range;
|
|
static assert(__traits(compiles, cRange.interval));
|
|
}
|
|
}
|
|
|
|
//Test NegInfIntervalRange's func.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto interval = NegInfInterval!Date(Date(2012, 1, 7));
|
|
auto func = everyDayOfWeek!(Date, Direction.bwd)(DayOfWeek.fri);
|
|
auto range = interval.bwdRange(func);
|
|
|
|
assert(range.func == func);
|
|
}
|
|
}
|
|
|
|
|
|
//==============================================================================
|
|
// Section with time zones.
|
|
//==============================================================================
|
|
|
|
/++
|
|
Represents a time zone. It is used with $(D SysTime) to indicate the time
|
|
zone of a $(D SysTime).
|
|
+/
|
|
abstract class TimeZone
|
|
{
|
|
public:
|
|
|
|
/++
|
|
The name of the time zone per the TZ Database. This is the name used to
|
|
get a $(D TimeZone) by name with $(D TimeZone.getTimeZone).
|
|
|
|
See_Also:
|
|
$(WEB en.wikipedia.org/wiki/Tz_database, Wikipedia entry on TZ
|
|
Database)
|
|
$(WEB en.wikipedia.org/wiki/List_of_tz_database_time_zones, List of
|
|
Time Zones)
|
|
+/
|
|
@property string name() const nothrow
|
|
{
|
|
return _name;
|
|
}
|
|
|
|
|
|
/++
|
|
Typically, the abbreviation (generally 3 or 4 letters) for the time zone
|
|
when DST is $(I not) in effect (e.g. PST). It is not necessarily unique.
|
|
|
|
However, on Windows, it may be the unabbreviated name (e.g. Pacific
|
|
Standard Time). Regardless, it is not the same as name.
|
|
+/
|
|
@property string stdName() const nothrow
|
|
{
|
|
return _stdName;
|
|
}
|
|
|
|
|
|
/++
|
|
Typically, the abbreviation (generally 3 or 4 letters) for the time zone
|
|
when DST $(I is) in effect (e.g. PDT). It is not necessarily unique.
|
|
|
|
However, on Windows, it may be the unabbreviated name (e.g. Pacific
|
|
Daylight Time). Regardless, it is not the same as name.
|
|
+/
|
|
@property string dstName() const nothrow
|
|
{
|
|
return _dstName;
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this time zone has Daylight Savings Time at any point in time.
|
|
Note that for some time zone types it may not have DST for current dates
|
|
but will still return true for $(D hasDST) because the time zone did at
|
|
some point have DST.
|
|
+/
|
|
@property abstract bool hasDST() const nothrow;
|
|
|
|
|
|
/++
|
|
Takes the number of hnsecs (100 ns) since midnight, January 1st, 1 A.D.
|
|
in UTC time (i.e. std time) and returns whether DST is effect in this
|
|
time zone at the given point in time.
|
|
|
|
Params:
|
|
stdTime = The UTC time that needs to be checked for DST in this time
|
|
zone.
|
|
+/
|
|
abstract bool dstInEffect(long stdTime) const nothrow;
|
|
|
|
|
|
/++
|
|
Takes the number of hnsecs (100 ns) since midnight, January 1st, 1 A.D.
|
|
in UTC time (i.e. std time) and converts it to this time zone's time.
|
|
|
|
Params:
|
|
stdTime = The UTC time that needs to be adjusted to this time zone's
|
|
time.
|
|
+/
|
|
abstract long utcToTZ(long stdTime) const nothrow;
|
|
|
|
|
|
/++
|
|
Takes the number of hnsecs (100 ns) since midnight, January 1st, 1 A.D.
|
|
in this time zone's time and converts it to UTC (i.e. std time).
|
|
|
|
Params:
|
|
adjTime = The time in this time zone that needs to be adjusted to
|
|
UTC time.
|
|
+/
|
|
abstract long tzToUTC(long adjTime) const nothrow;
|
|
|
|
|
|
/++
|
|
Returns a $(D TimeZone) with the give name per the TZ Database.
|
|
|
|
This returns a $(D PosixTimeZone) on Posix systems and a
|
|
$(D WindowsTimeZone) on Windows systems. If you want a
|
|
$(D PosixTimeZone) on Windows, then call $(D PosixTimeZone.getTimeZone)
|
|
directly and give it the location of the TZ Database time zone files on
|
|
disk.
|
|
|
|
On Windows, the given TZ Database name is converted to the corresponding
|
|
time zone name on Windows prior to calling
|
|
$(D WindowsTimeZone.getTimeZone). So, this function allows you to use
|
|
the same time zone names on both Windows and Posix systems.
|
|
|
|
See_Also:
|
|
$(WEB en.wikipedia.org/wiki/Tz_database, Wikipedia entry on TZ
|
|
Database)
|
|
$(WEB en.wikipedia.org/wiki/List_of_tz_database_time_zones, List of
|
|
Time Zones)
|
|
$(WEB unicode.org/repos/cldr-tmp/trunk/diff/supplemental/zone_tzid.html,
|
|
Windows <-> TZ Database Name Conversion Table)
|
|
|
|
Params:
|
|
name = The TZ Database name of the time zone that you're looking for.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given time zone could not be found.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto tz = TimeZone.getTimeZone("America/Los_Angeles");
|
|
--------------------
|
|
+/
|
|
static immutable(TimeZone) getTimeZone(string name)
|
|
{
|
|
version(Posix)
|
|
return PosixTimeZone.getTimeZone(name);
|
|
else version(Windows)
|
|
return WindowsTimeZone.getTimeZone(tzDatabaseNameToWindowsTZName(name));
|
|
}
|
|
|
|
//Since reading in the time zone files could be expensive, most unit tests
|
|
//are consolidated into this one unittest block which minimizes how often it
|
|
//reads a time zone file.
|
|
version(testStdDateTime) unittest
|
|
{
|
|
version(Posix) scope(exit) clearTZEnvVar();
|
|
|
|
static void testTZ(string tzName,
|
|
string stdName,
|
|
string dstName,
|
|
int utcOffset,
|
|
int dstOffset,
|
|
bool north = true)
|
|
{
|
|
scope(failure) writefln("Failed time zone: %s", tzName);
|
|
|
|
immutable tz = TimeZone.getTimeZone(tzName);
|
|
immutable hasDST = dstOffset != 0;
|
|
|
|
version(Posix)
|
|
_assertPred!"=="(tz.name, tzName);
|
|
else version(Windows)
|
|
_assertPred!"=="(tz.name, stdName);
|
|
|
|
_assertPred!"=="(tz.stdName, stdName);
|
|
_assertPred!"=="(tz.dstName, dstName);
|
|
_assertPred!"=="(tz.hasDST, hasDST);
|
|
|
|
immutable stdDate = DateTime(2010, north ? 1 : 7, 1, 6, 0, 0);
|
|
immutable dstDate = DateTime(2010, north ? 7 : 1, 1, 6, 0, 0);
|
|
auto std = SysTime(stdDate, tz);
|
|
auto dst = SysTime(dstDate, tz);
|
|
auto stdUTC = SysTime(stdDate - dur!"minutes"(utcOffset), UTC());
|
|
auto dstUTC = SysTime(stdDate - dur!"minutes"(utcOffset + dstOffset), UTC());
|
|
|
|
assert(!std.dstInEffect);
|
|
_assertPred!"=="(dst.dstInEffect, hasDST);
|
|
|
|
_assertPred!"=="(cast(DateTime)std, stdDate);
|
|
_assertPred!"=="(cast(DateTime)dst, dstDate);
|
|
_assertPred!"=="(std, stdUTC);
|
|
|
|
version(Posix)
|
|
{
|
|
setTZEnvVar(tzName);
|
|
|
|
static void testTM(in SysTime st)
|
|
{
|
|
time_t unixTime = st.toUnixTime();
|
|
tm* osTimeInfo = localtime(&unixTime);
|
|
tm ourTimeInfo = st.toTM();
|
|
|
|
_assertPred!"=="(ourTimeInfo.tm_sec, osTimeInfo.tm_sec);
|
|
_assertPred!"=="(ourTimeInfo.tm_min, osTimeInfo.tm_min);
|
|
_assertPred!"=="(ourTimeInfo.tm_hour, osTimeInfo.tm_hour);
|
|
_assertPred!"=="(ourTimeInfo.tm_min, osTimeInfo.tm_min);
|
|
_assertPred!"=="(ourTimeInfo.tm_mday, osTimeInfo.tm_mday);
|
|
_assertPred!"=="(ourTimeInfo.tm_mon, osTimeInfo.tm_mon);
|
|
_assertPred!"=="(ourTimeInfo.tm_year, osTimeInfo.tm_year);
|
|
_assertPred!"=="(ourTimeInfo.tm_wday, osTimeInfo.tm_wday);
|
|
_assertPred!"=="(ourTimeInfo.tm_yday, osTimeInfo.tm_yday);
|
|
_assertPred!"=="(ourTimeInfo.tm_isdst, osTimeInfo.tm_isdst);
|
|
_assertPred!"=="(ourTimeInfo.tm_gmtoff, osTimeInfo.tm_gmtoff);
|
|
_assertPred!"=="(to!string(ourTimeInfo.tm_zone),
|
|
to!string(osTimeInfo.tm_zone));
|
|
}
|
|
|
|
testTM(std);
|
|
testTM(dst);
|
|
|
|
//Apparently, right/ does not exist on Mac OS X. I don't know
|
|
//whether or not it exists on FreeBSD. It's rather pointless
|
|
//normally, since the Posix standard requires that leap seconds
|
|
//be ignored, so it does make some sense that right/ wouldn't
|
|
//be there, but since PosixTimeZone _does_ use leap seconds if
|
|
//the time zone file does, we'll test that functionality if the
|
|
//appropriate files exist.
|
|
if((PosixTimeZone.defaultTZDatabaseDir ~ "right/" ~ tzName).exists())
|
|
{
|
|
auto leapTZ = PosixTimeZone.getTimeZone("right/" ~ tzName);
|
|
|
|
assert(leapTZ.name == "right/" ~ tzName);
|
|
assert(leapTZ.stdName == stdName);
|
|
assert(leapTZ.dstName == dstName);
|
|
assert(leapTZ.hasDST == hasDST);
|
|
|
|
auto leapSTD = SysTime(std.stdTime, leapTZ);
|
|
auto leapDST = SysTime(dst.stdTime, leapTZ);
|
|
|
|
assert(!leapSTD.dstInEffect);
|
|
assert(leapDST.dstInEffect == hasDST);
|
|
|
|
_assertPred!"=="(leapSTD.stdTime, std.stdTime);
|
|
_assertPred!"=="(leapDST.stdTime, dst.stdTime);
|
|
|
|
//Whenever a leap second is added/removed,
|
|
//this will have to be adjusted.
|
|
enum leapDiff = convert!("seconds", "hnsecs")(24);
|
|
_assertPred!"=="(leapSTD.adjTime - leapDiff, std.adjTime);
|
|
_assertPred!"=="(leapDST.adjTime - leapDiff, dst.adjTime);
|
|
}
|
|
}
|
|
}
|
|
|
|
version(Posix)
|
|
{
|
|
version(FreeBSD) enum utcZone = "Etc/UTC";
|
|
version(linux) enum utcZone = "UTC";
|
|
version(OSX) enum utcZone = "UTC";
|
|
|
|
testTZ("America/Los_Angeles", "PST", "PDT", -8 * 60, 60);
|
|
testTZ("America/New_York", "EST", "EDT", -5 * 60, 60);
|
|
testTZ(utcZone, "UTC", "UTC", 0, 0);
|
|
testTZ("Europe/Paris", "CET", "CEST", 60, 60);
|
|
testTZ("Australia/Adelaide", "CST", "CST", 9 * 60 + 30, 60, false);
|
|
|
|
assertThrown!DateTimeException(PosixTimeZone.getTimeZone("hello_world"));
|
|
}
|
|
version(Windows)
|
|
{
|
|
testTZ("America/Los_Angeles", "Pacific Standard Time",
|
|
"Pacific Daylight Time", -8 * 60, 60);
|
|
testTZ("America/New_York", "Eastern Standard Time",
|
|
"Eastern Daylight Time", -5 * 60, 60);
|
|
testTZ("Atlantic/Reykjavik", "Greenwich Standard Time",
|
|
"Greenwich Daylight Time", 0, 0);
|
|
testTZ("Europe/Paris", "Romance Standard Time",
|
|
"Romance Daylight Time", 60, 60);
|
|
testTZ("Australia/Adelaide", "Cen. Australia Standard Time",
|
|
"Cen. Australia Daylight Time", 9 * 60 + 30, 60, false);
|
|
|
|
assertThrown!DateTimeException(WindowsTimeZone.getTimeZone("hello_world"));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns a list of the names of the time zones installed on the system.
|
|
|
|
You can provide a sub-name to narrow down the list of time zones (which
|
|
will likely be in the thousands if you get them all). For example,
|
|
if you pass in "America" as the sub-name, then only the time zones which
|
|
begin with "America" will be returned.
|
|
|
|
On Windows, this function will convert the Windows time zone names to
|
|
the corresponding TZ Database names with
|
|
$(D windowsTZNameToTZDatabaseName). If you want the actual Windows time
|
|
zone names, use $(D WindowsTimeZone.getInstalledTZNames) directly.
|
|
|
|
Params:
|
|
subName = The first part of the time zones that you want.
|
|
|
|
Throws:
|
|
$(D FileException) on Posix systems if it fails to read from disk.
|
|
$(D DateTimeException) on Windows systems if it fails to read the
|
|
registry.
|
|
+/
|
|
static string[] getInstalledTZNames(string subName = "")
|
|
{
|
|
version(Posix)
|
|
return PosixTimeZone.getInstalledTZNames(subName);
|
|
else version(Windows)
|
|
{
|
|
auto windowsNames = WindowsTimeZone.getInstalledTZNames();
|
|
auto retval = appender!(string[])();
|
|
|
|
foreach(winName; windowsNames)
|
|
{
|
|
auto tzName = windowsTZNameToTZDatabaseName(winName);
|
|
|
|
if(tzName.startsWith(subName))
|
|
retval.put(tzName);
|
|
}
|
|
|
|
sort(retval.data);
|
|
|
|
return retval.data;
|
|
}
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static void testPZSuccess(string tzName)
|
|
{
|
|
scope(failure) writefln("TZName which threw: %s", tzName);
|
|
|
|
TimeZone.getTimeZone(tzName);
|
|
}
|
|
|
|
auto tzNames = getInstalledTZNames();
|
|
|
|
foreach(tzName; tzNames)
|
|
assertNotThrown!DateTimeException(testPZSuccess(tzName));
|
|
}
|
|
}
|
|
|
|
|
|
private:
|
|
|
|
/+
|
|
Params:
|
|
name = The TZ Database name for the time zone.
|
|
stdName = The abbreviation for the time zone during std time.
|
|
dstName = The abbreviation for the time zone during DST.
|
|
+/
|
|
this(string name, string stdName, string dstName) immutable pure
|
|
{
|
|
_name = name;
|
|
_stdName = stdName;
|
|
_dstName = dstName;
|
|
}
|
|
|
|
|
|
immutable string _name;
|
|
immutable string _stdName;
|
|
immutable string _dstName;
|
|
}
|
|
|
|
|
|
/++
|
|
A TimeZone which represents the current local time zone on
|
|
the system running your program.
|
|
|
|
This uses the underlying C calls to adjust the time rather than using
|
|
specific D code based off of system settings to calculate the time such as
|
|
$(D PosixTimeZone) and $(D WindowsTimeZone) do. That also means that it will
|
|
use whatever the current time zone is on the system, even if the system's
|
|
time zone changes while the program is running.
|
|
+/
|
|
final class LocalTime : TimeZone
|
|
{
|
|
public:
|
|
|
|
/++
|
|
$(D LocalTime) is a singleton class. $(D LocalTime) returns its only
|
|
instance.
|
|
+/
|
|
static immutable(LocalTime) opCall() pure nothrow
|
|
{
|
|
return _localTime;
|
|
}
|
|
|
|
|
|
version(StdDdoc)
|
|
{
|
|
/++
|
|
The name of the time zone per the TZ Database. This is the name used to
|
|
get a $(D TimeZone) by name with $(D TimeZone.getTimeZone).
|
|
|
|
Note that this always returns the empty string. This is because time
|
|
zones cannot be uniquely identified by the attributes given by the
|
|
OS (such as the $(D stdName) and $(D dstName)), and neither Posix
|
|
systems nor Windows systems provide an easy way to get the TZ
|
|
Database name of the local time zone.
|
|
|
|
See_Also:
|
|
$(WEB en.wikipedia.org/wiki/Tz_database, Wikipedia entry on TZ
|
|
Database)
|
|
$(WEB en.wikipedia.org/wiki/List_of_tz_database_time_zones, List
|
|
of Time Zones)
|
|
+/
|
|
@property override string name() const nothrow;
|
|
}
|
|
|
|
|
|
/++
|
|
Typically, the abbreviation (generally 3 or 4 letters) for the time zone
|
|
when DST is $(I not) in effect (e.g. PST). It is not necessarily unique.
|
|
|
|
However, on Windows, it may be the unabbreviated name (e.g. Pacific
|
|
Standard Time). Regardless, it is not the same as name.
|
|
|
|
This property is overridden because the local time of the system could
|
|
change while the program is running and we need to determine it
|
|
dynamically rather than it being fixed like it would be with most time
|
|
zones.
|
|
+/
|
|
@property override string stdName() const nothrow
|
|
{
|
|
version(Posix)
|
|
{
|
|
try
|
|
return to!string(tzname[0]);
|
|
catch(Exception e)
|
|
assert(0, "to!string(tzname[0]) failed.");
|
|
}
|
|
else version(Windows)
|
|
{
|
|
try
|
|
{
|
|
TIME_ZONE_INFORMATION tzInfo;
|
|
GetTimeZoneInformation(&tzInfo);
|
|
|
|
//Cannot use to!string() like this should, probably due to bug http://d.puremagic.com/issues/show_bug.cgi?id=5016
|
|
//return to!string(tzInfo.StandardName);
|
|
|
|
wchar[32] str;
|
|
|
|
foreach(i, ref wchar c; str)
|
|
c = tzInfo.StandardName[i];
|
|
|
|
string retval;
|
|
|
|
foreach(dchar c; str)
|
|
{
|
|
if(c == '\0')
|
|
break;
|
|
|
|
retval ~= c;
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
catch(Exception e)
|
|
assert(0, "GetTimeZoneInformation() threw.");
|
|
}
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assert(LocalTime().stdName !is null);
|
|
|
|
version(Posix)
|
|
{
|
|
scope(exit) clearTZEnvVar();
|
|
|
|
setTZEnvVar("America/Los_Angeles");
|
|
_assertPred!"=="(LocalTime().stdName, "PST");
|
|
|
|
setTZEnvVar("America/New_York");
|
|
_assertPred!"=="(LocalTime().stdName, "EST");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Typically, the abbreviation (generally 3 or 4 letters) for the time zone
|
|
when DST $(I is) in effect (e.g. PDT). It is not necessarily unique.
|
|
|
|
However, on Windows, it may be the unabbreviated name (e.g. Pacific
|
|
Daylight Time). Regardless, it is not the same as name.
|
|
|
|
This property is overridden because the local time of the system could
|
|
change while the program is running and we need to determine it
|
|
dynamically rather than it being fixed like it would be with most time
|
|
zones.
|
|
+/
|
|
@property override string dstName() const nothrow
|
|
{
|
|
version(Posix)
|
|
{
|
|
try
|
|
return to!string(tzname[1]);
|
|
catch(Exception e)
|
|
assert(0, "to!string(tzname[1]) failed.");
|
|
}
|
|
else version(Windows)
|
|
{
|
|
try
|
|
{
|
|
TIME_ZONE_INFORMATION tzInfo;
|
|
GetTimeZoneInformation(&tzInfo);
|
|
|
|
//Cannot use to!string() like this should, probably due to bug http://d.puremagic.com/issues/show_bug.cgi?id=5016
|
|
//return to!string(tzInfo.DaylightName);
|
|
|
|
wchar[32] str;
|
|
|
|
foreach(i, ref wchar c; str)
|
|
c = tzInfo.DaylightName[i];
|
|
|
|
string retval;
|
|
|
|
foreach(dchar c; str)
|
|
{
|
|
if(c == '\0')
|
|
break;
|
|
|
|
retval ~= c;
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
catch(Exception e)
|
|
assert(0, "GetTimeZoneInformation() threw.");
|
|
}
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assert(LocalTime().dstName !is null);
|
|
|
|
version(Posix)
|
|
{
|
|
scope(exit) clearTZEnvVar();
|
|
|
|
setTZEnvVar("America/Los_Angeles");
|
|
_assertPred!"=="(LocalTime().dstName, "PDT");
|
|
|
|
setTZEnvVar("America/New_York");
|
|
_assertPred!"=="(LocalTime().dstName, "EDT");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Whether this time zone has Daylight Savings Time at any point in time.
|
|
Note that for some time zone types it may not have DST for current
|
|
dates but will still return true for $(D hasDST) because the time zone
|
|
did at some point have DST.
|
|
+/
|
|
@property override bool hasDST() const nothrow
|
|
{
|
|
version(Posix)
|
|
{
|
|
static if(is(typeof(daylight)))
|
|
return cast(bool)(daylight);
|
|
else
|
|
{
|
|
try
|
|
{
|
|
auto currYear = (cast(Date)Clock.currTime()).year;
|
|
auto janOffset = SysTime(Date(currYear, 1, 4), this).stdTime -
|
|
SysTime(Date(currYear, 1, 4), UTC()).stdTime;
|
|
auto julyOffset = SysTime(Date(currYear, 7, 4), this).stdTime -
|
|
SysTime(Date(currYear, 7, 4), UTC()).stdTime;
|
|
|
|
return janOffset != julyOffset;
|
|
}
|
|
catch(Exception e)
|
|
assert(0, "Clock.currTime() threw.");
|
|
}
|
|
}
|
|
else version(Windows)
|
|
{
|
|
try
|
|
{
|
|
TIME_ZONE_INFORMATION tzInfo;
|
|
GetTimeZoneInformation(&tzInfo);
|
|
|
|
return tzInfo.DaylightDate.wMonth != 0;
|
|
}
|
|
catch(Exception e)
|
|
assert(0, "GetTimeZoneInformation() threw.");
|
|
}
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
LocalTime().hasDST;
|
|
|
|
version(Posix)
|
|
{
|
|
scope(exit) clearTZEnvVar();
|
|
|
|
setTZEnvVar("America/Los_Angeles");
|
|
assert(LocalTime().hasDST);
|
|
|
|
setTZEnvVar("America/New_York");
|
|
assert(LocalTime().hasDST);
|
|
|
|
setTZEnvVar("UTC");
|
|
assert(!LocalTime().hasDST);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Takes the number of hnsecs (100 ns) since midnight, January 1st, 1 A.D.
|
|
in UTC time (i.e. std time) and returns whether DST is in effect in this
|
|
time zone at the given point in time.
|
|
|
|
Params:
|
|
stdTime = The UTC time that needs to be checked for DST in this time
|
|
zone.
|
|
+/
|
|
override bool dstInEffect(long stdTime) const nothrow
|
|
{
|
|
time_t unixTime = stdTimeToUnixTime(stdTime);
|
|
|
|
version(Posix)
|
|
{
|
|
tm* timeInfo = localtime(&unixTime);
|
|
|
|
return cast(bool)(timeInfo.tm_isdst);
|
|
}
|
|
else version(Windows)
|
|
{
|
|
//Apparently Windows isn't smart enough to deal with negative time_t.
|
|
if(unixTime >= 0)
|
|
{
|
|
tm* timeInfo = localtime(&unixTime);
|
|
|
|
if(timeInfo)
|
|
return cast(bool)(timeInfo.tm_isdst);
|
|
}
|
|
|
|
TIME_ZONE_INFORMATION tzInfo;
|
|
|
|
try
|
|
GetTimeZoneInformation(&tzInfo);
|
|
catch(Exception e)
|
|
assert(0, "The impossible happened. GetTimeZoneInformation() threw.");
|
|
|
|
return WindowsTimeZone._dstInEffect(&tzInfo, stdTime);
|
|
}
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto currTime = Clock.currStdTime;
|
|
LocalTime().dstInEffect(currTime);
|
|
|
|
version(Posix)
|
|
{
|
|
scope(exit) clearTZEnvVar();
|
|
auto std = SysTime(DateTime(2010, 1, 1, 12, 0, 0), LocalTime());
|
|
auto dst = SysTime(DateTime(2010, 7, 1, 12, 0, 0), LocalTime());
|
|
|
|
setTZEnvVar("America/Los_Angeles");
|
|
assert(!LocalTime().dstInEffect(std.stdTime));
|
|
assert(LocalTime().dstInEffect(dst.stdTime));
|
|
assert(!std.dstInEffect);
|
|
assert(dst.dstInEffect);
|
|
|
|
setTZEnvVar("America/New_York");
|
|
assert(!LocalTime().dstInEffect(std.stdTime));
|
|
assert(LocalTime().dstInEffect(dst.stdTime));
|
|
assert(!std.dstInEffect);
|
|
assert(dst.dstInEffect);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns hnsecs in the local time zone using the standard C function
|
|
calls on Posix systems and the standard Windows system calls on Windows
|
|
systems to adjust the time to the appropriate time zone from std time.
|
|
|
|
Params:
|
|
stdTime = The UTC time that needs to be adjusted to this time zone's
|
|
time.
|
|
|
|
See_Also:
|
|
$(D TimeZone.utcToTZ)
|
|
+/
|
|
override long utcToTZ(long stdTime) const nothrow
|
|
{
|
|
version(Posix)
|
|
{
|
|
time_t unixTime = stdTimeToUnixTime(stdTime);
|
|
tm* timeInfo = localtime(&unixTime);
|
|
|
|
return stdTime + convert!("seconds", "hnsecs")(timeInfo.tm_gmtoff);
|
|
}
|
|
else version(Windows)
|
|
{
|
|
TIME_ZONE_INFORMATION tzInfo;
|
|
|
|
try
|
|
GetTimeZoneInformation(&tzInfo);
|
|
catch(Exception e)
|
|
assert(0, "GetTimeZoneInformation() threw.");
|
|
|
|
return WindowsTimeZone._utcToTZ(&tzInfo, stdTime, hasDST);
|
|
}
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
LocalTime().utcToTZ(0);
|
|
|
|
version(Posix)
|
|
{
|
|
scope(exit) clearTZEnvVar();
|
|
|
|
{
|
|
setTZEnvVar("America/Los_Angeles");
|
|
auto std = SysTime(Date(2010, 1, 1));
|
|
auto dst = SysTime(Date(2010, 7, 1));
|
|
_assertPred!"=="(LocalTime().utcToTZ(std.stdTime), SysTime(DateTime(2009, 12, 31, 16, 0, 0)).stdTime);
|
|
_assertPred!"=="(LocalTime().utcToTZ(dst.stdTime), SysTime(DateTime(2010, 6, 30, 17, 0, 0)).stdTime);
|
|
}
|
|
|
|
{
|
|
setTZEnvVar("America/New_York");
|
|
auto std = SysTime(Date(2010, 1, 1));
|
|
auto dst = SysTime(Date(2010, 7, 1));
|
|
_assertPred!"=="(LocalTime().utcToTZ(std.stdTime), SysTime(DateTime(2009, 12, 31, 19, 0, 0)).stdTime);
|
|
_assertPred!"=="(LocalTime().utcToTZ(dst.stdTime), SysTime(DateTime(2010, 6, 30, 20, 0, 0)).stdTime);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns std time using the standard C function calls on Posix systems
|
|
and the standard Windows system calls on Windows systems to adjust the
|
|
time to UTC from the appropriate time zone.
|
|
|
|
See_Also:
|
|
$(D TimeZone.tzToUTC)
|
|
|
|
Params:
|
|
adjTime = The time in this time zone that needs to be adjusted to
|
|
UTC time.
|
|
+/
|
|
override long tzToUTC(long adjTime) const nothrow
|
|
{
|
|
version(Posix)
|
|
{
|
|
time_t unixTime = stdTimeToUnixTime(adjTime);
|
|
tm* timeInfo = localtime(&unixTime);
|
|
|
|
return adjTime - convert!("seconds", "hnsecs")(timeInfo.tm_gmtoff);
|
|
}
|
|
else version(Windows)
|
|
{
|
|
TIME_ZONE_INFORMATION tzInfo;
|
|
|
|
try
|
|
GetTimeZoneInformation(&tzInfo);
|
|
catch(Exception e)
|
|
assert(0, "GetTimeZoneInformation() threw.");
|
|
|
|
return WindowsTimeZone._tzToUTC(&tzInfo, adjTime, hasDST);
|
|
}
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
LocalTime().tzToUTC(0);
|
|
_assertPred!"=="(LocalTime().tzToUTC(LocalTime().utcToTZ(0)), 0);
|
|
_assertPred!"=="(LocalTime().utcToTZ(LocalTime().tzToUTC(0)), 0);
|
|
|
|
version(Posix)
|
|
{
|
|
scope(exit) clearTZEnvVar();
|
|
|
|
{
|
|
setTZEnvVar("America/Los_Angeles");
|
|
auto std = SysTime(DateTime(2009, 12, 31, 16, 0, 0));
|
|
auto dst = SysTime(DateTime(2010, 6, 30, 17, 0, 0));
|
|
_assertPred!"=="(LocalTime().tzToUTC(std.stdTime), SysTime(Date(2010, 1, 1)).stdTime);
|
|
_assertPred!"=="(LocalTime().tzToUTC(dst.stdTime), SysTime(Date(2010, 7, 1)).stdTime);
|
|
}
|
|
|
|
{
|
|
setTZEnvVar("America/New_York");
|
|
auto std = SysTime(DateTime(2009, 12, 31, 19, 0, 0));
|
|
auto dst = SysTime(DateTime(2010, 6, 30, 20, 0, 0));
|
|
_assertPred!"=="(LocalTime().tzToUTC(std.stdTime), SysTime(Date(2010, 1, 1)).stdTime);
|
|
_assertPred!"=="(LocalTime().tzToUTC(dst.stdTime), SysTime(Date(2010, 7, 1)).stdTime);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private:
|
|
|
|
this() immutable pure
|
|
{
|
|
super("", "", "");
|
|
}
|
|
|
|
|
|
static immutable LocalTime _localTime;
|
|
|
|
|
|
shared static this()
|
|
{
|
|
tzset();
|
|
|
|
_localTime = new immutable(LocalTime)();
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
A $(D TimeZone) which represents UTC.
|
|
+/
|
|
final class UTC : TimeZone
|
|
{
|
|
public:
|
|
|
|
/++
|
|
$(D UTC) is a singleton class. $(D UTC) returns its only instance.
|
|
+/
|
|
static immutable(UTC) opCall() pure nothrow
|
|
{
|
|
return _utc;
|
|
}
|
|
|
|
|
|
/++
|
|
Always returns false.
|
|
+/
|
|
@property override bool hasDST() const nothrow
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
/++
|
|
Always returns false.
|
|
+/
|
|
override bool dstInEffect(long stdTime) const nothrow
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the given hnsecs without changing them at all.
|
|
|
|
Params:
|
|
stdTime = The UTC time that needs to be adjusted to this time zone's
|
|
time.
|
|
|
|
See_Also:
|
|
$(D TimeZone.utcToTZ)
|
|
+/
|
|
override long utcToTZ(long stdTime) const nothrow
|
|
{
|
|
return stdTime;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(UTC().utcToTZ(0), 0);
|
|
|
|
version(Posix)
|
|
{
|
|
scope(exit) clearTZEnvVar();
|
|
|
|
setTZEnvVar("UTC");
|
|
auto std = SysTime(Date(2010, 1, 1));
|
|
auto dst = SysTime(Date(2010, 7, 1));
|
|
_assertPred!"=="(UTC().utcToTZ(std.stdTime), std.stdTime);
|
|
_assertPred!"=="(UTC().utcToTZ(dst.stdTime), dst.stdTime);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the given hnsecs without changing them at all.
|
|
|
|
See_Also:
|
|
$(D TimeZone.tzToUTC)
|
|
|
|
Params:
|
|
adjTime = The time in this time zone that needs to be adjusted to
|
|
UTC time.
|
|
+/
|
|
override long tzToUTC(long adjTime) const nothrow
|
|
{
|
|
return adjTime;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(UTC().tzToUTC(0), 0);
|
|
|
|
version(Posix)
|
|
{
|
|
scope(exit) clearTZEnvVar();
|
|
|
|
setTZEnvVar("UTC");
|
|
auto std = SysTime(Date(2010, 1, 1));
|
|
auto dst = SysTime(Date(2010, 7, 1));
|
|
_assertPred!"=="(UTC().tzToUTC(std.stdTime), std.stdTime);
|
|
_assertPred!"=="(UTC().tzToUTC(dst.stdTime), dst.stdTime);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private:
|
|
|
|
this() immutable pure
|
|
{
|
|
super("UTC", "UTC", "UTC");
|
|
}
|
|
|
|
|
|
static immutable UTC _utc;
|
|
|
|
|
|
shared static this()
|
|
{
|
|
_utc = new immutable(UTC)();
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Represents a time zone with an offset (in minutes, west is negative) from
|
|
UTC but no DST.
|
|
|
|
It's primarily used as the time zone in the result of $(D SysTime)'s
|
|
$(D fromISOString), $(D fromISOExtString), and $(D fromSimpleString).
|
|
|
|
$(D name) and $(D dstName) are always the empty string since this time zone
|
|
has no DST, and while it may be meant to represent a time zone which is in
|
|
the TZ Database, obviously it's not likely to be following the exact rules
|
|
of any of the time zones in the TZ Database, so it makes no sense to set it.
|
|
+/
|
|
final class SimpleTimeZone : TimeZone
|
|
{
|
|
public:
|
|
|
|
/++
|
|
Always returns false.
|
|
+/
|
|
@property override bool hasDST() const nothrow
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
/++
|
|
Always returns false.
|
|
+/
|
|
override bool dstInEffect(long stdTime) const nothrow
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
/++
|
|
Takes the number of hnsecs (100 ns) since midnight, January 1st, 1 A.D.
|
|
in UTC time (i.e. std time) and converts it to this time zone's time.
|
|
|
|
Params:
|
|
stdTime = The UTC time that needs to be adjusted to this time zone's
|
|
time.
|
|
+/
|
|
override long utcToTZ(long stdTime) const nothrow
|
|
{
|
|
return stdTime + convert!("minutes", "hnsecs")(utcOffset);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="((new SimpleTimeZone(-8 * 60)).utcToTZ(0), -288_000_000_000L);
|
|
_assertPred!"=="((new SimpleTimeZone(8 * 60)).utcToTZ(0), 288_000_000_000L);
|
|
_assertPred!"=="((new SimpleTimeZone(-8 * 60)).utcToTZ(54_321_234_567_890L), 54_033_234_567_890L);
|
|
auto stz = new SimpleTimeZone(-8 * 60);
|
|
const cstz = new SimpleTimeZone(-8 * 60);
|
|
static assert(__traits(compiles, stz.utcToTZ(50002)));
|
|
static assert(__traits(compiles, cstz.utcToTZ(50002)));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Takes the number of hnsecs (100 ns) since midnight, January 1st, 1 A.D.
|
|
in this time zone's time and converts it to UTC (i.e. std time).
|
|
|
|
Params:
|
|
adjTime = The time in this time zone that needs to be adjusted to
|
|
UTC time.
|
|
+/
|
|
override long tzToUTC(long adjTime) const nothrow
|
|
{
|
|
return adjTime - convert!("minutes", "hnsecs")(utcOffset);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="((new SimpleTimeZone(-8 * 60)).tzToUTC(-288_000_000_000L), 0);
|
|
_assertPred!"=="((new SimpleTimeZone(8 * 60)).tzToUTC(288_000_000_000L), 0);
|
|
_assertPred!"=="((new SimpleTimeZone(-8 * 60)).tzToUTC(54_033_234_567_890L), 54_321_234_567_890L);
|
|
|
|
auto stz = new SimpleTimeZone(-8 * 60);
|
|
const cstz = new SimpleTimeZone(-8 * 60);
|
|
static assert(__traits(compiles, stz.tzToUTC(20005)));
|
|
static assert(__traits(compiles, cstz.tzToUTC(20005)));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Params:
|
|
utcOffset = This time zone's offset from UTC in minutes with west of
|
|
UTC being negative (it is added to UTC to get the
|
|
adjusted time).
|
|
stdName = The $(D stdName) for this time zone.
|
|
+/
|
|
this(int utcOffset, string stdName = "") immutable
|
|
{
|
|
//FIXME This probably needs to be changed to something like (-12 - 13).
|
|
enforce(std.math.abs(utcOffset) < 1440, new DateTimeException("Offset from UTC must be within range (-24:00 - 24:00)."));
|
|
|
|
super("", stdName, "");
|
|
|
|
this.utcOffset = utcOffset;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto stz = new SimpleTimeZone(-8 * 60, "PST");
|
|
|
|
_assertPred!"=="(stz.name, "");
|
|
_assertPred!"=="(stz.stdName, "PST");
|
|
_assertPred!"=="(stz.dstName, "");
|
|
_assertPred!"=="(stz.utcOffset, -8 * 60);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
The number of minutes the offset from UTC is (negative is west of UTC,
|
|
positive is east).
|
|
+/
|
|
immutable int utcOffset;
|
|
|
|
private:
|
|
|
|
/+
|
|
Returns a time zone as a string with an offset from UTC.
|
|
|
|
Time zone offsets will be in the form +HH:MM or -HH:MM.
|
|
|
|
Params:
|
|
utcOffset = The number of minutes offset from UTC (negative means
|
|
west).
|
|
+/
|
|
static string toISOString(int utcOffset)
|
|
{
|
|
immutable absOffset = std.math.abs(utcOffset);
|
|
enforce(absOffset < 1440, new DateTimeException("Offset from UTC must be within range (-24:00 - 24:00)."));
|
|
|
|
immutable hours = convert!("minutes", "hours")(absOffset);
|
|
immutable minutes = absOffset - convert!("hours", "minutes")(hours);
|
|
|
|
if(utcOffset < 0)
|
|
return format("-%02d:%02d", hours, minutes);
|
|
|
|
return format("+%02d:%02d", hours, minutes);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static string testSTZInvalid(int offset)
|
|
{
|
|
return SimpleTimeZone.toISOString(offset);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testSTZInvalid(1440));
|
|
assertThrown!DateTimeException(testSTZInvalid(-1440));
|
|
|
|
_assertPred!"=="(toISOString(0), "+00:00");
|
|
_assertPred!"=="(toISOString(1), "+00:01");
|
|
_assertPred!"=="(toISOString(10), "+00:10");
|
|
_assertPred!"=="(toISOString(59), "+00:59");
|
|
_assertPred!"=="(toISOString(60), "+01:00");
|
|
_assertPred!"=="(toISOString(90), "+01:30");
|
|
_assertPred!"=="(toISOString(120), "+02:00");
|
|
_assertPred!"=="(toISOString(480), "+08:00");
|
|
_assertPred!"=="(toISOString(1439), "+23:59");
|
|
|
|
_assertPred!"=="(toISOString(-1), "-00:01");
|
|
_assertPred!"=="(toISOString(-10), "-00:10");
|
|
_assertPred!"=="(toISOString(-59), "-00:59");
|
|
_assertPred!"=="(toISOString(-60), "-01:00");
|
|
_assertPred!"=="(toISOString(-90), "-01:30");
|
|
_assertPred!"=="(toISOString(-120), "-02:00");
|
|
_assertPred!"=="(toISOString(-480), "-08:00");
|
|
_assertPred!"=="(toISOString(-1439), "-23:59");
|
|
}
|
|
}
|
|
|
|
|
|
/+
|
|
Takes a time zone as a string with an offset from UTC and returns a
|
|
$(D SimpleTimeZone) which matches.
|
|
|
|
The accepted formats for time zone offsets
|
|
are +H, -H, +HH, -HH, +H:MM, -H:MM, +HH:MM, and -HH:MM.
|
|
|
|
Params:
|
|
isoString = A string which represents a time zone in the ISO format.
|
|
+/
|
|
static immutable(SimpleTimeZone) fromISOString(S)(S isoString)
|
|
if(isSomeString!(S))
|
|
{
|
|
auto dstr = to!dstring(strip(isoString));
|
|
|
|
enforce(dstr.startsWith("-") || dstr.startsWith("+"), new DateTimeException("Invalid ISO String"));
|
|
|
|
auto sign = dstr.startsWith("-") ? -1 : 1;
|
|
|
|
dstr.popFront();
|
|
enforce(!dstr.empty, new DateTimeException("Invalid ISO String"));
|
|
|
|
immutable colon = dstr.stds_indexOf(":");
|
|
|
|
dstring hoursStr;
|
|
dstring minutesStr;
|
|
|
|
if(colon != -1)
|
|
{
|
|
hoursStr = dstr[0 .. colon];
|
|
minutesStr = dstr[colon + 1 .. $];
|
|
enforce(minutesStr.length == 2, new DateTimeException(format("Invalid ISO String: %s", dstr)));
|
|
}
|
|
else
|
|
hoursStr = dstr;
|
|
|
|
enforce(!canFind!(not!isDigit)(hoursStr), new DateTimeException(format("Invalid ISO String: %s", dstr)));
|
|
enforce(!canFind!(not!isDigit)(minutesStr), new DateTimeException(format("Invalid ISO String: %s", dstr)));
|
|
|
|
immutable hours = to!int(hoursStr);
|
|
immutable minutes = minutesStr.empty ? 0 : to!int(minutesStr);
|
|
|
|
return new SimpleTimeZone(sign * cast(int)(convert!("hours", "minutes")(hours) + minutes));
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assertThrown!DateTimeException(SimpleTimeZone.fromISOString(""));
|
|
assertThrown!DateTimeException(SimpleTimeZone.fromISOString("Z"));
|
|
assertThrown!DateTimeException(SimpleTimeZone.fromISOString("-"));
|
|
assertThrown!DateTimeException(SimpleTimeZone.fromISOString("+"));
|
|
assertThrown!DateTimeException(SimpleTimeZone.fromISOString("-:"));
|
|
assertThrown!DateTimeException(SimpleTimeZone.fromISOString("+:"));
|
|
assertThrown!DateTimeException(SimpleTimeZone.fromISOString("-1:"));
|
|
assertThrown!DateTimeException(SimpleTimeZone.fromISOString("+1:"));
|
|
assertThrown!DateTimeException(SimpleTimeZone.fromISOString("1"));
|
|
assertThrown!DateTimeException(SimpleTimeZone.fromISOString("-24:00"));
|
|
assertThrown!DateTimeException(SimpleTimeZone.fromISOString("+24:00"));
|
|
assertThrown!DateTimeException(SimpleTimeZone.fromISOString("+1:0"));
|
|
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("+00:00").utcOffset, (new SimpleTimeZone(0)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("+00:01").utcOffset, (new SimpleTimeZone(1)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("+00:10").utcOffset, (new SimpleTimeZone(10)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("+00:59").utcOffset, (new SimpleTimeZone(59)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("+01:00").utcOffset, (new SimpleTimeZone(60)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("+01:30").utcOffset, (new SimpleTimeZone(90)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("+02:00").utcOffset, (new SimpleTimeZone(120)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("+08:00").utcOffset, (new SimpleTimeZone(480)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("+23:59").utcOffset, (new SimpleTimeZone(1439)).utcOffset);
|
|
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("-00:01").utcOffset, (new SimpleTimeZone(-1)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("-00:10").utcOffset, (new SimpleTimeZone(-10)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("-00:59").utcOffset, (new SimpleTimeZone(-59)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("-01:00").utcOffset, (new SimpleTimeZone(-60)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("-01:30").utcOffset, (new SimpleTimeZone(-90)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("-02:00").utcOffset, (new SimpleTimeZone(-120)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("-08:00").utcOffset, (new SimpleTimeZone(-480)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("-23:59").utcOffset, (new SimpleTimeZone(-1439)).utcOffset);
|
|
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("+0").utcOffset, (new SimpleTimeZone(0)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("+1").utcOffset, (new SimpleTimeZone(60)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("+2").utcOffset, (new SimpleTimeZone(120)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("+23").utcOffset, (new SimpleTimeZone(1380)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("+2").utcOffset, (new SimpleTimeZone(120)).utcOffset);
|
|
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("+0").utcOffset, (new SimpleTimeZone(0)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("+1").utcOffset, (new SimpleTimeZone(60)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("+2").utcOffset, (new SimpleTimeZone(120)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("+23").utcOffset, (new SimpleTimeZone(1380)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("+1:00").utcOffset, (new SimpleTimeZone(60)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("+1:01").utcOffset, (new SimpleTimeZone(61)).utcOffset);
|
|
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("-0").utcOffset, (new SimpleTimeZone(0)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("-1").utcOffset, (new SimpleTimeZone(-60)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("-2").utcOffset, (new SimpleTimeZone(-120)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("-23").utcOffset, (new SimpleTimeZone(-1380)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("-1:00").utcOffset, (new SimpleTimeZone(-60)).utcOffset);
|
|
_assertPred!"=="(SimpleTimeZone.fromISOString("-1:01").utcOffset, (new SimpleTimeZone(-61)).utcOffset);
|
|
}
|
|
}
|
|
|
|
//Test that converting from an ISO string to a SimpleTimeZone to an ISO String works properly.
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static void testSTZ(in string isoString, int expectedOffset, size_t line = __LINE__)
|
|
{
|
|
auto stz = SimpleTimeZone.fromISOString(isoString);
|
|
_assertPred!"=="(stz.utcOffset, expectedOffset, "", __FILE__, line);
|
|
|
|
auto result = SimpleTimeZone.toISOString(stz.utcOffset);
|
|
_assertPred!"=="(result, isoString, "", __FILE__, line);
|
|
}
|
|
|
|
testSTZ("+00:00", 0);
|
|
testSTZ("+00:01", 1);
|
|
testSTZ("+00:10", 10);
|
|
testSTZ("+00:59", 59);
|
|
testSTZ("+01:00", 60);
|
|
testSTZ("+01:30", 90);
|
|
testSTZ("+02:00", 120);
|
|
testSTZ("+08:00", 480);
|
|
testSTZ("+08:00", 480);
|
|
testSTZ("+23:59", 1439);
|
|
|
|
testSTZ("-00:01", -1);
|
|
testSTZ("-00:10", -10);
|
|
testSTZ("-00:59", -59);
|
|
testSTZ("-01:00", -60);
|
|
testSTZ("-01:30", -90);
|
|
testSTZ("-02:00", -120);
|
|
testSTZ("-08:00", -480);
|
|
testSTZ("-08:00", -480);
|
|
testSTZ("-23:59", -1439);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Represents a time zone from a TZ Database time zone file. Files from the TZ
|
|
database are how Posix systems hold their time zone information.
|
|
Unfortunately, Windows does not use the TZ Database. You can, however, use
|
|
$(D PosixTimeZone) (which reads its information from the TZ Database files
|
|
on disk) on Windows if you provide the TZ Database files
|
|
( $(WEB elsie.nci.nih.gov/pub/, Repository with the TZ Database files (tzdata)) )
|
|
yourself and tell $(D PosixTimeZone.getTimeZone) where the directory holding
|
|
them is.
|
|
|
|
To get a $(D PosixTimeZone), either call $(D PosixTimeZone.getTimeZone)
|
|
(which will allow you to specify the location the time zone files) or call
|
|
$(D TimeZone.getTimeZone) (which will give you a $(D PosixTimeZone) on Posix
|
|
systems and a $(D WindowsTimeZone) on Windows systems).
|
|
|
|
Note:
|
|
Unless your system's local time zone deals with leap seconds (which is
|
|
highly unlikely), then only way that you will get a time zone which
|
|
takes leap seconds into account is if you use $(D PosixTimeZone) with a
|
|
time zone whose name starts with "right/". Those time zone files do
|
|
include leap seconds, and $(D PosixTimeZone) will take them into account
|
|
(though posix systems which use a "right/" time zone as their local time
|
|
zone will $(I not) take leap seconds into account even though they're
|
|
in the file).
|
|
|
|
See_Also:
|
|
$(WEB en.wikipedia.org/wiki/Tz_database, Wikipedia entry on TZ Database)
|
|
$(WEB en.wikipedia.org/wiki/List_of_tz_database_time_zones, List of Time
|
|
Zones)
|
|
+/
|
|
final class PosixTimeZone : TimeZone
|
|
{
|
|
public:
|
|
|
|
/++
|
|
Whether this time zone has Daylight Savings Time at any point in time.
|
|
Note that for some time zone types it may not have DST for current
|
|
dates but will still return true for $(D hasDST) because the time zone
|
|
did at some point have DST.
|
|
+/
|
|
@property override bool hasDST() const nothrow
|
|
{
|
|
return _hasDST;
|
|
}
|
|
|
|
|
|
/++
|
|
Takes the number of hnsecs (100 ns) since midnight, January 1st, 1 A.D.
|
|
in UTC time (i.e. std time) and returns whether DST is in effect in this
|
|
time zone at the given point in time.
|
|
|
|
Params:
|
|
stdTime = The UTC time that needs to be checked for DST in this time
|
|
zone.
|
|
+/
|
|
override bool dstInEffect(long stdTime) const nothrow
|
|
{
|
|
assert(!_transitions.empty);
|
|
|
|
try
|
|
{
|
|
immutable unixTime = stdTimeToUnixTime(stdTime);
|
|
|
|
if(_transitions.front.timeT >= unixTime)
|
|
return _transitions.front.ttInfo.isDST;
|
|
|
|
auto found = std.algorithm.countUntil!"b < a.timeT"(cast(Transition[])_transitions, unixTime);
|
|
|
|
if(found == -1)
|
|
return _transitions.back.ttInfo.isDST;
|
|
|
|
auto transition = found == 0 ? _transitions[0] : _transitions[found - 1];
|
|
|
|
return transition.ttInfo.isDST;
|
|
}
|
|
catch(Exception e)
|
|
assert(0, format("Nothing in calculateLeapSeconds() should be throwing. Caught Exception: %s", e));
|
|
}
|
|
|
|
|
|
/++
|
|
Takes the number of hnsecs (100 ns) since midnight, January 1st, 1 A.D.
|
|
in UTC time (i.e. std time) and converts it to this time zone's time.
|
|
|
|
Params:
|
|
stdTime = The UTC time that needs to be adjusted to this time zone's
|
|
time.
|
|
+/
|
|
override long utcToTZ(long stdTime) const nothrow
|
|
{
|
|
assert(!_transitions.empty);
|
|
|
|
try
|
|
{
|
|
immutable leapSecs = calculateLeapSeconds(stdTime);
|
|
immutable unixTime = stdTimeToUnixTime(stdTime);
|
|
|
|
if(_transitions.front.timeT >= unixTime)
|
|
return stdTime + convert!("seconds", "hnsecs")(_transitions.front.ttInfo.utcOffset + leapSecs);
|
|
|
|
auto found = std.algorithm.countUntil!"b < a.timeT"(cast(Transition[])_transitions, unixTime);
|
|
|
|
if(found == -1)
|
|
return stdTime + convert!("seconds", "hnsecs")(_transitions.back.ttInfo.utcOffset + leapSecs);
|
|
|
|
auto transition = found == 0 ? _transitions[0] : _transitions[found - 1];
|
|
|
|
return stdTime + convert!("seconds", "hnsecs")(transition.ttInfo.utcOffset + leapSecs);
|
|
}
|
|
catch(Exception e)
|
|
assert(0, format("Nothing in calculateLeapSeconds() should be throwing. Caught Exception: %s", e));
|
|
}
|
|
|
|
|
|
/++
|
|
Takes the number of hnsecs (100 ns) since midnight, January 1st, 1 A.D.
|
|
in this time zone's time and converts it to UTC (i.e. std time).
|
|
|
|
Params:
|
|
adjTime = The time in this time zone that needs to be adjusted to
|
|
UTC time.
|
|
+/
|
|
override long tzToUTC(long adjTime) const nothrow
|
|
{
|
|
assert(!_transitions.empty);
|
|
|
|
try
|
|
{
|
|
immutable leapSecs = calculateLeapSeconds(adjTime);
|
|
immutable unixTime = stdTimeToUnixTime(adjTime);
|
|
|
|
if(_transitions.front.timeT >= unixTime)
|
|
return adjTime - convert!("seconds", "hnsecs")(_transitions.front.ttInfo.utcOffset + leapSecs);
|
|
|
|
//Okay, casting is a hack, but countUntil shouldn't be changing it,
|
|
//and it would be too inefficient to have to keep duping it every
|
|
//time we have to calculate the time. Hopefully, countUntil will
|
|
//properly support immutable ranges at some point.
|
|
auto found = std.algorithm.countUntil!"b < a.timeT"(cast(Transition[])_transitions, unixTime);
|
|
|
|
if(found == -1)
|
|
return adjTime - convert!("seconds", "hnsecs")(_transitions.back.ttInfo.utcOffset + leapSecs);
|
|
|
|
auto transition = found == 0 ? _transitions[0] : _transitions[found - 1];
|
|
|
|
return adjTime - convert!("seconds", "hnsecs")(transition.ttInfo.utcOffset + leapSecs);
|
|
}
|
|
catch(Exception e)
|
|
assert(0, format("Nothing in calculateLeapSeconds() should be throwing. Caught Exception: %s", e));
|
|
}
|
|
|
|
|
|
version(Posix)
|
|
{
|
|
/++
|
|
The default directory where the TZ Database files are. It's empty
|
|
for Windows, since Windows doesn't have them.
|
|
+/
|
|
enum defaultTZDatabaseDir = "/usr/share/zoneinfo/";
|
|
}
|
|
else version(Windows)
|
|
{
|
|
/++ The default directory where the TZ Database files are. It's empty
|
|
for Windows, since Windows doesn't have them.
|
|
+/
|
|
enum defaultTZDatabaseDir = "";
|
|
}
|
|
|
|
|
|
/++
|
|
Returns a $(D TimeZone) with the give name per the TZ Database. The time
|
|
zone information is fetched from the TZ Database time zone files in the
|
|
given directory.
|
|
|
|
See_Also:
|
|
$(WEB en.wikipedia.org/wiki/Tz_database, Wikipedia entry on TZ
|
|
Database)
|
|
$(WEB en.wikipedia.org/wiki/List_of_tz_database_time_zones, List of
|
|
Time Zones)
|
|
|
|
Params:
|
|
name = The TZ Database name of the time zone that you're
|
|
looking for.
|
|
tzDatabaseDir = The directory where the TZ Database files are
|
|
located. Because these files are not located on
|
|
Windows systems, you will need to provide them
|
|
yourself and give their location here if you wish to
|
|
use $(D PosixTimeZone)s.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given time zone could not be found or
|
|
$(D FileException) if the TZ Database file could not be opened.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto tz = PosixTimeZone.getTimeZone("America/Los_Angeles");
|
|
|
|
assert(tz.name == "America/Los_Angeles");
|
|
assert(tz.stdName == "PST");
|
|
assert(tz.dstName == "PDT");
|
|
--------------------
|
|
+/
|
|
//TODO make it possible for tzDatabaseDir to be gzipped tar file rather than an uncompressed
|
|
// directory.
|
|
static immutable(PosixTimeZone) getTimeZone(string name, string tzDatabaseDir = defaultTZDatabaseDir)
|
|
{
|
|
name = strip(name);
|
|
|
|
enforce(tzDatabaseDir.exists, new DateTimeException(format("Directory %s does not exist.", tzDatabaseDir)));
|
|
enforce(tzDatabaseDir.isDir, new DateTimeException(format("%s is not a directory.", tzDatabaseDir)));
|
|
|
|
version(Posix)
|
|
auto file = tzDatabaseDir ~ name;
|
|
else version(Windows)
|
|
auto file = tzDatabaseDir ~ replace(strip(name), "/", sep);
|
|
|
|
enforce(file.exists, new DateTimeException(format("File %s does not exist.", file)));
|
|
enforce(file.isFile, new DateTimeException(format("%s is not a file.", file)));
|
|
|
|
auto tzFile = File(file);
|
|
immutable gmtZone = file.canFind("GMT");
|
|
|
|
try
|
|
{
|
|
_enforceValidTZFile(readVal!(char[])(tzFile, 4) == "TZif");
|
|
|
|
immutable char tzFileVersion = readVal!char(tzFile);
|
|
_enforceValidTZFile(tzFileVersion == '\0' || tzFileVersion == '2');
|
|
|
|
{
|
|
auto zeroBlock = readVal!(ubyte[])(tzFile, 15);
|
|
bool allZeroes = true;
|
|
|
|
foreach(val; zeroBlock)
|
|
{
|
|
if(val != 0)
|
|
{
|
|
allZeroes = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
_enforceValidTZFile(allZeroes);
|
|
}
|
|
|
|
|
|
//The number of UTC/local indicators stored in the file.
|
|
auto tzh_ttisgmtcnt = readVal!int(tzFile);
|
|
|
|
//The number of standard/wall indicators stored in the file.
|
|
auto tzh_ttisstdcnt = readVal!int(tzFile);
|
|
|
|
//The number of leap seconds for which data is stored in the file.
|
|
auto tzh_leapcnt = readVal!int(tzFile);
|
|
|
|
//The number of "transition times" for which data is stored in the file.
|
|
auto tzh_timecnt = readVal!int(tzFile);
|
|
|
|
//The number of "local time types" for which data is stored in the file (must not be zero).
|
|
auto tzh_typecnt = readVal!int(tzFile);
|
|
_enforceValidTZFile(tzh_typecnt != 0);
|
|
|
|
//The number of characters of "timezone abbreviation strings" stored in the file.
|
|
auto tzh_charcnt = readVal!int(tzFile);
|
|
|
|
//time_ts where DST transitions occur.
|
|
auto transitionTimeTs = new long[](tzh_timecnt);
|
|
foreach(ref transition; transitionTimeTs)
|
|
transition = readVal!int(tzFile);
|
|
|
|
//Indices into ttinfo structs indicating the changes
|
|
//to be made at the corresponding DST transition.
|
|
auto ttInfoIndices = new ubyte[](tzh_timecnt);
|
|
foreach(ref ttInfoIndex; ttInfoIndices)
|
|
ttInfoIndex = readVal!ubyte(tzFile);
|
|
|
|
//ttinfos which give info on DST transitions.
|
|
auto tempTTInfos = new TempTTInfo[](tzh_typecnt);
|
|
foreach(ref ttInfo; tempTTInfos)
|
|
ttInfo = readVal!TempTTInfo(tzFile);
|
|
|
|
//The array of time zone abbreviation characters.
|
|
auto tzAbbrevChars = readVal!(char[])(tzFile, tzh_charcnt);
|
|
|
|
auto leapSeconds = new LeapSecond[](tzh_leapcnt);
|
|
foreach(ref leapSecond; leapSeconds)
|
|
{
|
|
//The time_t when the leap second occurs.
|
|
auto timeT = readVal!int(tzFile);
|
|
|
|
//The total number of leap seconds to be applied after
|
|
//the corresponding leap second.
|
|
auto total = readVal!int(tzFile);
|
|
|
|
leapSecond = LeapSecond(timeT, total);
|
|
}
|
|
|
|
//Indicate whether each corresponding DST transition were specified
|
|
//in standard time or wall clock time.
|
|
auto transitionIsStd = new bool[](tzh_ttisstdcnt);
|
|
foreach(ref isStd; transitionIsStd)
|
|
isStd = readVal!bool(tzFile);
|
|
|
|
//Indicate whether each corresponding DST transition associated with
|
|
//local time types are specified in UTC or local time.
|
|
auto transitionInUTC = new bool[](tzh_ttisgmtcnt);
|
|
foreach(ref inUTC; transitionInUTC)
|
|
inUTC = readVal!bool(tzFile);
|
|
|
|
_enforceValidTZFile(!tzFile.eof());
|
|
|
|
//If version 2, the information is duplicated in 64-bit.
|
|
if(tzFileVersion == '2')
|
|
{
|
|
_enforceValidTZFile(readVal!(char[])(tzFile, 4) == "TZif");
|
|
|
|
_enforceValidTZFile(readVal!(char)(tzFile) == '2');
|
|
|
|
{
|
|
auto zeroBlock = readVal!(ubyte[])(tzFile, 15);
|
|
bool allZeroes = true;
|
|
|
|
foreach(val; zeroBlock)
|
|
{
|
|
if(val != 0)
|
|
{
|
|
allZeroes = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
_enforceValidTZFile(allZeroes);
|
|
}
|
|
|
|
|
|
//The number of UTC/local indicators stored in the file.
|
|
tzh_ttisgmtcnt = readVal!int(tzFile);
|
|
|
|
//The number of standard/wall indicators stored in the file.
|
|
tzh_ttisstdcnt = readVal!int(tzFile);
|
|
|
|
//The number of leap seconds for which data is stored in the file.
|
|
tzh_leapcnt = readVal!int(tzFile);
|
|
|
|
//The number of "transition times" for which data is stored in the file.
|
|
tzh_timecnt = readVal!int(tzFile);
|
|
|
|
//The number of "local time types" for which data is stored in the file (must not be zero).
|
|
tzh_typecnt = readVal!int(tzFile);
|
|
_enforceValidTZFile(tzh_typecnt != 0);
|
|
|
|
//The number of characters of "timezone abbreviation strings" stored in the file.
|
|
tzh_charcnt = readVal!int(tzFile);
|
|
|
|
//time_ts where DST transitions occur.
|
|
transitionTimeTs = new long[](tzh_timecnt);
|
|
foreach(ref transition; transitionTimeTs)
|
|
transition = readVal!long(tzFile);
|
|
|
|
//Indices into ttinfo structs indicating the changes
|
|
//to be made at the corresponding DST transition.
|
|
ttInfoIndices = new ubyte[](tzh_timecnt);
|
|
foreach(ref ttInfoIndex; ttInfoIndices)
|
|
ttInfoIndex = readVal!ubyte(tzFile);
|
|
|
|
//ttinfos which give info on DST transitions.
|
|
tempTTInfos = new TempTTInfo[](tzh_typecnt);
|
|
foreach(ref ttInfo; tempTTInfos)
|
|
ttInfo = readVal!TempTTInfo(tzFile);
|
|
|
|
//The array of time zone abbreviation characters.
|
|
tzAbbrevChars = readVal!(char[])(tzFile, tzh_charcnt);
|
|
|
|
leapSeconds = new LeapSecond[](tzh_leapcnt);
|
|
foreach(ref leapSecond; leapSeconds)
|
|
{
|
|
//The time_t when the leap second occurs.
|
|
auto timeT = readVal!long(tzFile);
|
|
|
|
//The total number of leap seconds to be applied after
|
|
//the corresponding leap second.
|
|
auto total = readVal!int(tzFile);
|
|
|
|
leapSecond = LeapSecond(timeT, total);
|
|
}
|
|
|
|
//Indicate whether each corresponding DST transition were specified
|
|
//in standard time or wall clock time.
|
|
transitionIsStd = new bool[](tzh_ttisstdcnt);
|
|
foreach(ref isStd; transitionIsStd)
|
|
isStd = readVal!bool(tzFile);
|
|
|
|
//Indicate whether each corresponding DST transition associated with
|
|
//local time types are specified in UTC or local time.
|
|
transitionInUTC = new bool[](tzh_ttisgmtcnt);
|
|
foreach(ref inUTC; transitionInUTC)
|
|
inUTC = readVal!bool(tzFile);
|
|
}
|
|
|
|
_enforceValidTZFile(tzFile.readln().strip().empty());
|
|
|
|
auto posixEnvStr = tzFile.readln().strip();
|
|
|
|
_enforceValidTZFile(tzFile.readln().strip().empty());
|
|
_enforceValidTZFile(tzFile.eof());
|
|
|
|
|
|
auto transitionTypes = new TransitionType*[](tempTTInfos.length);
|
|
|
|
foreach(i, ref ttype; transitionTypes)
|
|
{
|
|
bool isStd = false;
|
|
|
|
if(i < transitionIsStd.length && !transitionIsStd.empty)
|
|
isStd = transitionIsStd[i];
|
|
|
|
bool inUTC = false;
|
|
|
|
if(i < transitionInUTC.length && !transitionInUTC.empty)
|
|
inUTC = transitionInUTC[i];
|
|
|
|
ttype = new TransitionType(isStd, inUTC);
|
|
}
|
|
|
|
auto ttInfos = new immutable(TTInfo)*[](tempTTInfos.length);
|
|
foreach(i, ref ttInfo; ttInfos)
|
|
{
|
|
auto tempTTInfo = tempTTInfos[i];
|
|
|
|
if(gmtZone)
|
|
tempTTInfo.tt_gmtoff = -tempTTInfo.tt_gmtoff;
|
|
|
|
auto abbrevChars = tzAbbrevChars[tempTTInfo.tt_abbrind .. $];
|
|
string abbrev = abbrevChars[0 .. abbrevChars.stds_indexOf("\0")].idup;
|
|
|
|
ttInfo = new immutable(TTInfo)(tempTTInfos[i], abbrev);
|
|
}
|
|
|
|
auto tempTransitions = new TempTransition[](transitionTimeTs.length);
|
|
foreach(i, ref tempTransition; tempTransitions)
|
|
{
|
|
immutable ttiIndex = ttInfoIndices[i];
|
|
auto transitionTimeT = transitionTimeTs[i];
|
|
auto ttype = transitionTypes[ttiIndex];
|
|
auto ttInfo = ttInfos[ttiIndex];
|
|
|
|
tempTransition = TempTransition(transitionTimeT, ttInfo, ttype);
|
|
}
|
|
|
|
if(tempTransitions.empty)
|
|
{
|
|
_enforceValidTZFile(ttInfos.length == 1 && transitionTypes.length == 1);
|
|
tempTransitions ~= TempTransition(0, ttInfos[0], transitionTypes[0]);
|
|
}
|
|
|
|
sort!"a.timeT < b.timeT"(tempTransitions);
|
|
sort!"a.timeT < b.timeT"(leapSeconds);
|
|
|
|
auto transitions = new Transition[](tempTransitions.length);
|
|
foreach(i, ref transition; transitions)
|
|
{
|
|
auto tempTransition = tempTransitions[i];
|
|
auto transitionTimeT = tempTransition.timeT;
|
|
auto ttInfo = tempTransition.ttInfo;
|
|
auto ttype = tempTransition.ttype;
|
|
|
|
_enforceValidTZFile(i == 0 || transitionTimeT > tempTransitions[i - 1].timeT);
|
|
|
|
transition = Transition(transitionTimeT, ttInfo);
|
|
}
|
|
|
|
string stdName;
|
|
string dstName;
|
|
bool hasDST = false;
|
|
|
|
foreach(transition; retro(transitions))
|
|
{
|
|
auto ttInfo = transition.ttInfo;
|
|
|
|
if(ttInfo.isDST)
|
|
{
|
|
if(dstName.empty)
|
|
dstName = ttInfo.abbrev;
|
|
|
|
hasDST = true;
|
|
}
|
|
else
|
|
{
|
|
if(stdName.empty)
|
|
stdName = ttInfo.abbrev;
|
|
}
|
|
|
|
if(!stdName.empty && !dstName.empty)
|
|
break;
|
|
}
|
|
|
|
return new PosixTimeZone(transitions.idup, leapSeconds.idup, name, stdName, dstName, hasDST);
|
|
}
|
|
catch(DateTimeException dte)
|
|
throw dte;
|
|
catch(Exception e)
|
|
throw new DateTimeException("Not a valid TZ data file", __FILE__, __LINE__, e);
|
|
}
|
|
|
|
/++
|
|
Returns a list of the names of the time zones installed on the system.
|
|
|
|
You can provide a sub-name to narrow down the list of time zones (which
|
|
will likely be in the thousands if you get them all). For example,
|
|
if you pass in "America" as the sub-name, then only the time zones which
|
|
begin with "America" will be returned.
|
|
|
|
Params:
|
|
subName = The first part of the time zones that you want.
|
|
|
|
Throws:
|
|
$(D FileException) if it fails to read from disk.
|
|
+/
|
|
static string[] getInstalledTZNames(string subName = "", string tzDatabaseDir = defaultTZDatabaseDir)
|
|
{
|
|
version(Posix)
|
|
subName = strip(subName);
|
|
else version(Windows)
|
|
subName = replace(strip(subName), "/", sep);
|
|
|
|
if(!tzDatabaseDir.endsWith(sep))
|
|
tzDatabaseDir ~= sep;
|
|
|
|
enforce(tzDatabaseDir.exists, new DateTimeException(format("Directory %s does not exist.", tzDatabaseDir)));
|
|
enforce(tzDatabaseDir.isDir, new DateTimeException(format("%s is not a directory.", tzDatabaseDir)));
|
|
|
|
auto timezones = appender!(string[])();
|
|
|
|
foreach(DirEntry dentry; dirEntries(tzDatabaseDir, SpanMode.depth))
|
|
{
|
|
if(dentry.isFile)
|
|
{
|
|
auto tzName = dentry.name[tzDatabaseDir.length .. $];
|
|
|
|
if(!tzName.getExt().empty() ||
|
|
!tzName.startsWith(subName) ||
|
|
tzName == "+VERSION")
|
|
{
|
|
continue;
|
|
}
|
|
|
|
timezones.put(tzName);
|
|
}
|
|
}
|
|
|
|
sort(timezones.data);
|
|
|
|
return timezones.data;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
version(Posix)
|
|
{
|
|
static void testPTZSuccess(string tzName)
|
|
{
|
|
scope(failure) writefln("TZName which threw: %s", tzName);
|
|
|
|
PosixTimeZone.getTimeZone(tzName);
|
|
}
|
|
|
|
static void testPTZFailure(string tzName)
|
|
{
|
|
scope(success) writefln("TZName which was supposed to throw: %s", tzName);
|
|
|
|
PosixTimeZone.getTimeZone(tzName);
|
|
}
|
|
|
|
auto tzNames = getInstalledTZNames();
|
|
|
|
foreach(tzName; tzNames)
|
|
assertNotThrown!DateTimeException(testPTZSuccess(tzName));
|
|
|
|
foreach(DirEntry dentry; dirEntries(defaultTZDatabaseDir, SpanMode.depth))
|
|
{
|
|
if(dentry.isFile)
|
|
{
|
|
auto tzName = dentry.name[defaultTZDatabaseDir.length .. $];
|
|
|
|
if(!canFind(tzNames, tzName))
|
|
assertThrown!DateTimeException(testPTZFailure(tzName));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private:
|
|
|
|
/+
|
|
Holds information on when a time transition occures (usually a
|
|
transition to or from DST) as well as a pointer to the $(D TTInfo) which
|
|
holds information on the utc offset passed the transition.
|
|
+/
|
|
struct Transition
|
|
{
|
|
this(long timeT, immutable (TTInfo)* ttInfo)
|
|
{
|
|
this.timeT = timeT;
|
|
this.ttInfo = ttInfo;
|
|
}
|
|
|
|
long timeT;
|
|
immutable (TTInfo)* ttInfo;
|
|
}
|
|
|
|
|
|
/+
|
|
Holds information on when a leap second occurs.
|
|
+/
|
|
struct LeapSecond
|
|
{
|
|
this(long timeT, int total)
|
|
{
|
|
this.timeT = timeT;
|
|
this.total = total;
|
|
}
|
|
|
|
long timeT;
|
|
int total;
|
|
}
|
|
|
|
/+
|
|
Holds information on the utc offset after a transition as well as
|
|
whether DST is in effect after that transition.
|
|
+/
|
|
struct TTInfo
|
|
{
|
|
this(in TempTTInfo tempTTInfo, string abbrev) immutable
|
|
{
|
|
utcOffset = tempTTInfo.tt_gmtoff;
|
|
isDST = tempTTInfo.tt_isdst;
|
|
this.abbrev = abbrev;
|
|
}
|
|
|
|
immutable int utcOffset; /// Offset from UTC.
|
|
immutable bool isDST; /// Whether DST is in effect.
|
|
immutable string abbrev; /// The current abbreviation for the time zone.
|
|
}
|
|
|
|
|
|
/+
|
|
Struct used to hold information relating to $(D TTInfo) while organizing
|
|
the time zone information prior to putting it in its final form.
|
|
+/
|
|
struct TempTTInfo
|
|
{
|
|
this(int gmtOff, bool isDST, ubyte abbrInd)
|
|
{
|
|
tt_gmtoff = gmtOff;
|
|
tt_isdst = isDST;
|
|
tt_abbrind = abbrInd;
|
|
}
|
|
|
|
int tt_gmtoff;
|
|
bool tt_isdst;
|
|
ubyte tt_abbrind;
|
|
}
|
|
|
|
|
|
/+
|
|
Struct used to hold information relating to $(D Transition) while
|
|
organizing the time zone information prior to putting it in its final
|
|
form.
|
|
+/
|
|
struct TempTransition
|
|
{
|
|
this(long timeT, immutable (TTInfo)* ttInfo, TransitionType* ttype)
|
|
{
|
|
this.timeT = timeT;
|
|
this.ttInfo = ttInfo;
|
|
this.ttype = ttype;
|
|
}
|
|
|
|
long timeT;
|
|
immutable (TTInfo)* ttInfo;
|
|
TransitionType* ttype;
|
|
}
|
|
|
|
|
|
/+
|
|
Struct used to hold information relating to $(D Transition) and
|
|
$(D TTInfo) while organizing the time zone information prior to putting
|
|
it in its final form.
|
|
+/
|
|
struct TransitionType
|
|
{
|
|
this(bool isStd, bool inUTC)
|
|
{
|
|
this.isStd = isStd;
|
|
this.inUTC = inUTC;
|
|
}
|
|
|
|
/// Whether the transition is in std time (as opposed to wall clock time).
|
|
bool isStd;
|
|
|
|
/// Whether the transition is in UTC (as opposed to local time).
|
|
bool inUTC;
|
|
}
|
|
|
|
|
|
/+
|
|
Reads an int from a TZ file.
|
|
+/
|
|
static T readVal(T)(ref File tzFile)
|
|
if(is(T == int))
|
|
{
|
|
T[1] buff;
|
|
|
|
_enforceValidTZFile(!tzFile.eof());
|
|
tzFile.rawRead(buff);
|
|
|
|
return cast(int)ntohl(buff[0]);
|
|
}
|
|
|
|
|
|
/+
|
|
Reads a long from a TZ file.
|
|
+/
|
|
static T readVal(T)(ref File tzFile)
|
|
if(is(T == long))
|
|
{
|
|
T[1] buff;
|
|
|
|
_enforceValidTZFile(!tzFile.eof());
|
|
tzFile.rawRead(buff);
|
|
|
|
return cast(long)ntoh64(buff[0]);
|
|
}
|
|
|
|
/+
|
|
Reads an array of values from a TZ file.
|
|
+/
|
|
static T readVal(T)(ref File tzFile, size_t length)
|
|
if(isArray!T)
|
|
{
|
|
auto buff = new T(length);
|
|
|
|
_enforceValidTZFile(!tzFile.eof());
|
|
tzFile.rawRead(buff);
|
|
|
|
return buff;
|
|
}
|
|
|
|
|
|
/+
|
|
Reads a $(D TempTTInfo) from a TZ file.
|
|
+/
|
|
static T readVal(T)(ref File tzFile)
|
|
if(is(T == TempTTInfo))
|
|
{
|
|
return TempTTInfo(readVal!int(tzFile),
|
|
readVal!bool(tzFile),
|
|
readVal!ubyte(tzFile));
|
|
}
|
|
|
|
|
|
/+
|
|
Reads a value from a TZ file.
|
|
+/
|
|
static T readVal(T)(ref File tzFile)
|
|
if(!is(T == int) &&
|
|
!is(T == long) &&
|
|
!is(T == char[]) &&
|
|
!is(T == TempTTInfo))
|
|
{
|
|
T[1] buff;
|
|
|
|
_enforceValidTZFile(!tzFile.eof());
|
|
tzFile.rawRead(buff);
|
|
|
|
return buff[0];
|
|
}
|
|
|
|
/+
|
|
64 bit version of $(D ntoh). Unfortunately, for some reason, most
|
|
systems provide only 16 and 32 bit versions of this, so we need to
|
|
provide it ourselves. We really should declare a version of this in core
|
|
somewhere.
|
|
+/
|
|
static ulong ntoh64(ulong val)
|
|
{
|
|
static if(endian == Endian.LittleEndian)
|
|
return endianSwap64(val);
|
|
else
|
|
return val;
|
|
}
|
|
|
|
|
|
/+
|
|
Swaps the endianness of a 64-bit value. We really should declare a
|
|
version of this in core somewhere.
|
|
+/
|
|
static ulong endianSwap64(ulong val)
|
|
{
|
|
return ((val & 0xff00000000000000UL) >> 56) |
|
|
((val & 0x00ff000000000000UL) >> 40) |
|
|
((val & 0x0000ff0000000000UL) >> 24) |
|
|
((val & 0x000000ff00000000UL) >> 8) |
|
|
((val & 0x00000000ff000000UL) << 8) |
|
|
((val & 0x0000000000ff0000UL) << 24) |
|
|
((val & 0x000000000000ff00UL) << 40) |
|
|
((val & 0x00000000000000ffUL) << 56);
|
|
}
|
|
|
|
|
|
/+
|
|
Throws:
|
|
$(D DateTimeException) if $(D result) is false.
|
|
+/
|
|
static void _enforceValidTZFile(bool result, size_t line = __LINE__)
|
|
{
|
|
if(!result)
|
|
throw new DateTimeException("Not a valid tzdata file.", __FILE__, line);
|
|
}
|
|
|
|
|
|
int calculateLeapSeconds(long stdTime) const nothrow
|
|
{
|
|
try
|
|
{
|
|
if(_leapSeconds.empty)
|
|
return 0;
|
|
|
|
immutable unixTime = stdTimeToUnixTime(stdTime);
|
|
|
|
if(_leapSeconds.front.timeT >= unixTime)
|
|
return 0;
|
|
|
|
//Okay, casting is a hack, but countUntil shouldn't be changing it,
|
|
//and it would be too inefficient to have to keep duping it every
|
|
//time we have to calculate the time. Hopefully, countUntil will
|
|
//properly support immutable ranges at some point.
|
|
auto found = std.algorithm.countUntil!"b < a.timeT"(cast(LeapSecond[])_leapSeconds, unixTime);
|
|
|
|
if(found == -1)
|
|
return _leapSeconds.back.total;
|
|
|
|
auto leapSecond = found == 0 ? _leapSeconds[0] : _leapSeconds[found - 1];
|
|
|
|
return leapSecond.total;
|
|
}
|
|
catch(Exception e)
|
|
assert(0, format("Nothing in calculateLeapSeconds() should be throwing. Caught Exception: %s", e));
|
|
}
|
|
|
|
|
|
this(immutable Transition[] transitions,
|
|
immutable LeapSecond[] leapSeconds,
|
|
string name,
|
|
string stdName,
|
|
string dstName,
|
|
bool hasDST) immutable
|
|
{
|
|
if(dstName.empty && !stdName.empty)
|
|
dstName = stdName;
|
|
else if(stdName.empty && !dstName.empty)
|
|
stdName = dstName;
|
|
|
|
super(name, stdName, dstName);
|
|
|
|
if(!transitions.empty)
|
|
{
|
|
foreach(i, transition; transitions[0 .. $-1])
|
|
_enforceValidTZFile(transition.timeT < transitions[i + 1].timeT);
|
|
}
|
|
|
|
foreach(i, leapSecond; leapSeconds)
|
|
_enforceValidTZFile(i == leapSeconds.length - 1 || leapSecond.timeT < leapSeconds[i + 1].timeT);
|
|
|
|
_transitions = transitions;
|
|
_leapSeconds = leapSeconds;
|
|
_hasDST = hasDST;
|
|
}
|
|
|
|
/// List of times when the utc offset changes.
|
|
immutable Transition[] _transitions;
|
|
|
|
/// List of leap second occurrences.
|
|
immutable LeapSecond[] _leapSeconds;
|
|
|
|
/// Whether DST is in effect for this time zone at any point in time.
|
|
immutable bool _hasDST;
|
|
}
|
|
|
|
|
|
|
|
version(StdDdoc)
|
|
{
|
|
/++
|
|
$(BLUE This class is Windows-Only.)
|
|
|
|
Represents a time zone from the Windows registry. Unfortunately, Windows
|
|
does not use the TZ Database. You can, however, use $(D PosixTimeZone)
|
|
(which reads its information from the TZ Database files on disk) on
|
|
Windows if you provide the TZ Database files
|
|
( $(WEB ftp://elsie.nci.nih.gov/pub/,
|
|
Repository with the TZ Database files (tzdata)) )
|
|
yourself and tell $(D PosixTimeZone.getTimeZone) where the directory
|
|
holding them is.
|
|
|
|
The TZ Dabatase files and Windows are not likely to always match,
|
|
particularly for historical dates, so if you want complete consistency
|
|
between Posix and Windows, then you should provide the appropriate
|
|
TZ Database files on Windows and use $(D PosixTimeZone). But as
|
|
$(D WindowsTimeZone) uses the Windows functions, $(D WindowsTimeZone)
|
|
is more likely to match the behavior of other Windows programs.
|
|
$(D WindowsTimeZone) should be fine for most programs.
|
|
|
|
$(D WindowsTimeZone) does not exist on Posix systems.
|
|
|
|
To get a $(D WindowsTimeZone), either call
|
|
$(D WindowsTimeZone.getTimeZone) or call $(D TimeZone.getTimeZone)
|
|
(which will give you a $(D PosixTimeZone) on Posix systems and a
|
|
$(D WindowsTimeZone) on Windows systems).
|
|
+/
|
|
final class WindowsTimeZone : TimeZone
|
|
{
|
|
public:
|
|
|
|
/++
|
|
Whether this time zone has Daylight Savings Time at any point in
|
|
time. Note that for some time zone types it may not have DST for
|
|
current dates but will still return true for $(D hasDST) because the
|
|
time zone did at some point have DST.
|
|
+/
|
|
@property override bool hasDST() const nothrow;
|
|
|
|
|
|
/++
|
|
Takes the number of hnsecs (100 ns) since midnight, January 1st,
|
|
1 A.D. in UTC time (i.e. std time) and returns whether DST is in
|
|
effect in this time zone at the given point in time.
|
|
|
|
Params:
|
|
stdTime = The UTC time that needs to be checked for DST in this
|
|
time zone.
|
|
+/
|
|
override bool dstInEffect(long stdTime) const nothrow;
|
|
|
|
|
|
/++
|
|
Takes the number of hnsecs (100 ns) since midnight, January 1st,
|
|
1 A.D. in UTC time (i.e. std time) and converts it to this time
|
|
zone's time.
|
|
|
|
Params:
|
|
stdTime = The UTC time that needs to be adjusted to this time
|
|
zone's time.
|
|
+/
|
|
override long utcToTZ(long stdTime) const nothrow;
|
|
|
|
|
|
/++
|
|
Takes the number of hnsecs (100 ns) since midnight, January 1st,
|
|
1 A.D. in this time zone's time and converts it to UTC (i.e. std
|
|
time).
|
|
|
|
Params:
|
|
adjTime = The time in this time zone that needs to be adjusted
|
|
to UTC time.
|
|
+/
|
|
override long tzToUTC(long adjTime) const nothrow;
|
|
|
|
|
|
/++
|
|
Returns a $(D TimeZone) with the given name per the Windows time
|
|
zone names. The time zone information is fetched from the Windows
|
|
registry.
|
|
|
|
See_Also:
|
|
$(WEB en.wikipedia.org/wiki/Tz_database, Wikipedia entry on TZ
|
|
Database)
|
|
$(WEB en.wikipedia.org/wiki/List_of_tz_database_time_zones, List
|
|
of Time Zones)
|
|
|
|
Params:
|
|
name = The TZ Database name of the time zone that you're looking
|
|
for.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given time zone could not be
|
|
found.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto tz = TimeZone.getTimeZone("America/Los_Angeles");
|
|
--------------------
|
|
+/
|
|
static immutable(WindowsTimeZone) getTimeZone(string name);
|
|
|
|
|
|
/++
|
|
Returns a list of the names of the time zones installed on the
|
|
system.
|
|
+/
|
|
static string[] getInstalledTZNames();
|
|
|
|
private:
|
|
|
|
version(Windows) {}
|
|
else
|
|
alias void* TIME_ZONE_INFORMATION;
|
|
|
|
static bool _dstInEffect(const TIME_ZONE_INFORMATION* tzInfo, long stdTime) nothrow;
|
|
static long _utcToTZ(const TIME_ZONE_INFORMATION* tzInfo, long stdTime, bool hasDST) nothrow;
|
|
static long _tzToUTC(const TIME_ZONE_INFORMATION* tzInfo, long adjTime, bool hasDST) nothrow;
|
|
|
|
this() immutable pure
|
|
{
|
|
super("", "", "");
|
|
}
|
|
}
|
|
|
|
}
|
|
else version(Windows)
|
|
{
|
|
|
|
//Should be in core.sys.windows.windows, but for some reason it isn't.
|
|
extern(Windows)
|
|
{
|
|
export LONG RegQueryValueExA(HKEY hKey, LPCSTR name, LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count);
|
|
|
|
struct REG_TZI_FORMAT
|
|
{
|
|
LONG Bias;
|
|
LONG StandardBias;
|
|
LONG DaylightBias;
|
|
SYSTEMTIME StandardDate;
|
|
SYSTEMTIME DaylightDate;
|
|
}
|
|
|
|
}
|
|
|
|
final class WindowsTimeZone : TimeZone
|
|
{
|
|
public:
|
|
|
|
@property override bool hasDST() const nothrow
|
|
{
|
|
return _tzInfo.DaylightDate.wMonth != 0;
|
|
}
|
|
|
|
|
|
override bool dstInEffect(long stdTime) const nothrow
|
|
{
|
|
return _dstInEffect(&_tzInfo, stdTime);
|
|
}
|
|
|
|
|
|
override long utcToTZ(long stdTime) const nothrow
|
|
{
|
|
return _utcToTZ(&_tzInfo, stdTime, hasDST);
|
|
}
|
|
|
|
|
|
override long tzToUTC(long adjTime) const nothrow
|
|
{
|
|
return _tzToUTC(&_tzInfo, adjTime, hasDST);
|
|
}
|
|
|
|
|
|
static immutable(WindowsTimeZone) getTimeZone(string name)
|
|
{
|
|
auto keyStr = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\0";
|
|
HKEY baseKey;
|
|
|
|
{
|
|
auto result = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyStr.ptr, 0, KEY_READ, &baseKey);
|
|
if(result != ERROR_SUCCESS)
|
|
throw new DateTimeException(format("Failed to open registry. Error: %s", result));
|
|
}
|
|
scope(exit) RegCloseKey(baseKey);
|
|
|
|
char[1024] keyName;
|
|
auto nameLen = keyName.length;
|
|
int result;
|
|
for(DWORD index = 0;
|
|
(result = RegEnumKeyExA(baseKey, index, keyName.ptr, &nameLen, null, null, null, null)) != ERROR_NO_MORE_ITEMS;
|
|
++index, nameLen = keyName.length)
|
|
{
|
|
if(result == ERROR_SUCCESS)
|
|
{
|
|
HKEY tzKey;
|
|
if(RegOpenKeyExA(baseKey, keyName.ptr, 0, KEY_READ, &tzKey) == ERROR_SUCCESS)
|
|
{
|
|
scope(exit) RegCloseKey(tzKey);
|
|
char[1024] strVal;
|
|
auto strValLen = strVal.length;
|
|
|
|
bool queryStringValue(string name, size_t lineNum = __LINE__)
|
|
{
|
|
strValLen = strVal.length;
|
|
|
|
return RegQueryValueExA(tzKey, name.ptr, null, null, cast(ubyte*)strVal.ptr, &strValLen) == ERROR_SUCCESS;
|
|
}
|
|
|
|
if(to!string(keyName.ptr) == name)
|
|
{
|
|
if(queryStringValue("Std\0"))
|
|
{
|
|
//Cannot use to!wstring(char*), probably due to bug http://d.puremagic.com/issues/show_bug.cgi?id=5016
|
|
static wstring conv(char* cstr, size_t strValLen)
|
|
{
|
|
cstr[strValLen - 1] = '\0';
|
|
|
|
string retval;
|
|
|
|
for(;; ++cstr)
|
|
{
|
|
if(*cstr == '\0')
|
|
break;
|
|
|
|
retval ~= *cstr;
|
|
}
|
|
|
|
return to!wstring(retval);
|
|
}
|
|
|
|
//auto stdName = to!wstring(strVal.ptr);
|
|
auto stdName = conv(strVal.ptr, strValLen);
|
|
|
|
if(queryStringValue("Dlt\0"))
|
|
{
|
|
//auto dstName = to!wstring(strVal.ptr);
|
|
auto dstName = conv(strVal.ptr, strValLen);
|
|
|
|
enum tzi = "TZI\0";
|
|
REG_TZI_FORMAT binVal;
|
|
auto binValLen = REG_TZI_FORMAT.sizeof;
|
|
|
|
if(RegQueryValueExA(tzKey, tzi.ptr, null, null, cast(ubyte*)&binVal, &binValLen) == ERROR_SUCCESS)
|
|
{
|
|
TIME_ZONE_INFORMATION tzInfo;
|
|
|
|
auto stdNameLen = stdName.length > 32 ? 32 : stdName.length;
|
|
auto dstNameLen = dstName.length > 32 ? 32 : dstName.length;
|
|
|
|
tzInfo.Bias = binVal.Bias;
|
|
tzInfo.StandardName[0 .. stdNameLen] = stdName[0 .. stdNameLen];
|
|
tzInfo.StandardName[stdNameLen .. $] = '\0';
|
|
tzInfo.StandardDate = binVal.StandardDate;
|
|
tzInfo.StandardBias = binVal.StandardBias;
|
|
tzInfo.DaylightName[0 .. dstNameLen] = dstName[0 .. dstNameLen];
|
|
tzInfo.DaylightName[dstNameLen .. $] = '\0';
|
|
tzInfo.DaylightDate = binVal.DaylightDate;
|
|
tzInfo.DaylightBias = binVal.DaylightBias;
|
|
|
|
return new WindowsTimeZone(name, tzInfo);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
throw new DateTimeException(format("Failed to find time zone: %s", name));
|
|
}
|
|
|
|
static string[] getInstalledTZNames()
|
|
{
|
|
auto timezones = appender!(string[])();
|
|
|
|
auto keyStr = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones";
|
|
HKEY baseKey;
|
|
|
|
{
|
|
auto result = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyStr.ptr, 0, KEY_READ, &baseKey);
|
|
if(result != ERROR_SUCCESS)
|
|
throw new DateTimeException(format("Failed to open registry. Error: %s", result));
|
|
}
|
|
scope(exit) RegCloseKey(baseKey);
|
|
|
|
char[1024] keyName;
|
|
auto nameLen = keyName.length;
|
|
int result;
|
|
for(DWORD index = 0;
|
|
(result = RegEnumKeyExA(baseKey, index, keyName.ptr, &nameLen, null, null, null, null)) != ERROR_NO_MORE_ITEMS;
|
|
++index, nameLen = keyName.length)
|
|
{
|
|
if(result == ERROR_SUCCESS)
|
|
timezones.put(to!string(keyName.ptr));
|
|
}
|
|
|
|
sort(timezones.data);
|
|
|
|
return timezones.data;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static void testWTZSuccess(string tzName)
|
|
{
|
|
scope(failure) writefln("TZName which threw: %s", tzName);
|
|
|
|
WindowsTimeZone.getTimeZone(tzName);
|
|
}
|
|
|
|
auto tzNames = getInstalledTZNames();
|
|
|
|
foreach(tzName; tzNames)
|
|
assertNotThrown!DateTimeException(testWTZSuccess(tzName));
|
|
}
|
|
}
|
|
|
|
|
|
private:
|
|
|
|
static bool _dstInEffect(const TIME_ZONE_INFORMATION* tzInfo, long stdTime) nothrow
|
|
{
|
|
try
|
|
{
|
|
if(tzInfo.DaylightDate.wMonth == 0)
|
|
return false;
|
|
|
|
auto utcDateTime = cast(DateTime)SysTime(stdTime, UTC());
|
|
|
|
//The limits of what SystemTimeToTZSpecificLocalTime will accept.
|
|
if(utcDateTime.year < 1601)
|
|
{
|
|
if(utcDateTime.month == Month.feb && utcDateTime.day == 29)
|
|
utcDateTime.day = 28;
|
|
|
|
utcDateTime.year = 1601;
|
|
}
|
|
else if(utcDateTime.year > 30_827)
|
|
{
|
|
if(utcDateTime.month == Month.feb && utcDateTime.day == 29)
|
|
utcDateTime.day = 28;
|
|
|
|
utcDateTime.year = 30_827;
|
|
}
|
|
|
|
//SystemTimeToTZSpecificLocalTime doesn't act correctly at the
|
|
//beginning or end of the year (bleh). Unless some bizarre time
|
|
//zone changes DST on January 1st or December 31st, this should
|
|
//fix the problem.
|
|
if(utcDateTime.month == Month.jan)
|
|
{
|
|
if(utcDateTime.day == 1)
|
|
utcDateTime.day = 2;
|
|
}
|
|
else if(utcDateTime.month == Month.dec && utcDateTime.day == 31)
|
|
utcDateTime.day = 30;
|
|
|
|
SYSTEMTIME utcTime = void;
|
|
SYSTEMTIME otherTime = void;
|
|
|
|
utcTime.wYear = utcDateTime.year;
|
|
utcTime.wMonth = utcDateTime.month;
|
|
utcTime.wDay = utcDateTime.day;
|
|
utcTime.wHour = utcDateTime.hour;
|
|
utcTime.wMinute = utcDateTime.minute;
|
|
utcTime.wSecond = utcDateTime.second;
|
|
utcTime.wMilliseconds = 0;
|
|
|
|
immutable result = SystemTimeToTzSpecificLocalTime(cast(TIME_ZONE_INFORMATION*)tzInfo,
|
|
&utcTime,
|
|
&otherTime);
|
|
assert(result);
|
|
|
|
immutable otherDateTime = DateTime(otherTime.wYear,
|
|
otherTime.wMonth,
|
|
otherTime.wDay,
|
|
otherTime.wHour,
|
|
otherTime.wMinute,
|
|
otherTime.wSecond);
|
|
immutable diff = utcDateTime - otherDateTime;
|
|
immutable minutes = diff.total!"minutes"() - tzInfo.Bias;
|
|
|
|
if(minutes == tzInfo.DaylightBias)
|
|
return true;
|
|
|
|
assert(minutes == tzInfo.StandardBias);
|
|
|
|
return false;
|
|
}
|
|
catch(Exception e)
|
|
assert(0, "DateTime's constructor threw.");
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
TIME_ZONE_INFORMATION tzInfo;
|
|
GetTimeZoneInformation(&tzInfo);
|
|
|
|
foreach(year; [1600, 1601, 30_827, 30_828])
|
|
WindowsTimeZone._dstInEffect(&tzInfo, SysTime(DateTime(year, 1, 1)).stdTime);
|
|
}
|
|
|
|
|
|
static long _utcToTZ(const TIME_ZONE_INFORMATION* tzInfo, long stdTime, bool hasDST) nothrow
|
|
{
|
|
if(hasDST && WindowsTimeZone._dstInEffect(tzInfo, stdTime))
|
|
return stdTime - convert!("minutes", "hnsecs")(tzInfo.Bias + tzInfo.DaylightBias);
|
|
|
|
return stdTime - convert!("minutes", "hnsecs")(tzInfo.Bias + tzInfo.StandardBias);
|
|
}
|
|
|
|
|
|
static long _tzToUTC(const TIME_ZONE_INFORMATION* tzInfo, long adjTime, bool hasDST) nothrow
|
|
{
|
|
if(hasDST)
|
|
{
|
|
try
|
|
{
|
|
bool dstInEffectForLocalDateTime(DateTime localDateTime)
|
|
{
|
|
//The limits of what SystemTimeToTZSpecificLocalTime will accept.
|
|
if(localDateTime.year < 1601)
|
|
{
|
|
if(localDateTime.month == Month.feb && localDateTime.day == 29)
|
|
localDateTime.day = 28;
|
|
|
|
localDateTime.year = 1601;
|
|
}
|
|
else if(localDateTime.year > 30_827)
|
|
{
|
|
if(localDateTime.month == Month.feb && localDateTime.day == 29)
|
|
localDateTime.day = 28;
|
|
|
|
localDateTime.year = 30_827;
|
|
}
|
|
|
|
//SystemTimeToTZSpecificLocalTime doesn't act correctly at the
|
|
//beginning or end of the year (bleh). Unless some bizarre time
|
|
//zone changes DST on January 1st or December 31st, this should
|
|
//fix the problem.
|
|
if(localDateTime.month == Month.jan)
|
|
{
|
|
if(localDateTime.day == 1)
|
|
localDateTime.day = 2;
|
|
}
|
|
else if(localDateTime.month == Month.dec && localDateTime.day == 31)
|
|
localDateTime.day = 30;
|
|
|
|
SYSTEMTIME utcTime = void;
|
|
SYSTEMTIME localTime = void;
|
|
|
|
localTime.wYear = localDateTime.year;
|
|
localTime.wMonth = localDateTime.month;
|
|
localTime.wDay = localDateTime.day;
|
|
localTime.wHour = localDateTime.hour;
|
|
localTime.wMinute = localDateTime.minute;
|
|
localTime.wSecond = localDateTime.second;
|
|
localTime.wMilliseconds = 0;
|
|
|
|
immutable result = SystemTimeToTzSpecificLocalTime(cast(TIME_ZONE_INFORMATION*)tzInfo,
|
|
&localTime,
|
|
&utcTime);
|
|
assert(result);
|
|
|
|
immutable utcDateTime = DateTime(utcTime.wYear,
|
|
utcTime.wMonth,
|
|
utcTime.wDay,
|
|
utcTime.wHour,
|
|
utcTime.wMinute,
|
|
utcTime.wSecond);
|
|
|
|
immutable diff = localDateTime - utcDateTime;
|
|
immutable minutes = diff.total!"minutes"() - tzInfo.Bias;
|
|
|
|
if(minutes == tzInfo.DaylightBias)
|
|
return true;
|
|
|
|
assert(minutes == tzInfo.StandardBias);
|
|
|
|
return false;
|
|
}
|
|
|
|
auto localDateTime = cast(DateTime)SysTime(adjTime, UTC());
|
|
auto localDateTimeBefore = localDateTime - dur!"hours"(1);
|
|
auto localDateTimeAfter = localDateTime + dur!"hours"(1);
|
|
|
|
auto dstInEffectNow = dstInEffectForLocalDateTime(localDateTime);
|
|
auto dstInEffectBefore = dstInEffectForLocalDateTime(localDateTimeBefore);
|
|
auto dstInEffectAfter = dstInEffectForLocalDateTime(localDateTimeAfter);
|
|
|
|
bool isDST;
|
|
|
|
if(dstInEffectBefore && dstInEffectNow && dstInEffectAfter)
|
|
isDST = true;
|
|
else if(!dstInEffectBefore && !dstInEffectNow && !dstInEffectAfter)
|
|
isDST = false;
|
|
else if((!dstInEffectBefore && dstInEffectAfter) ||
|
|
(dstInEffectBefore && !dstInEffectAfter))
|
|
{
|
|
isDST = dstInEffectNow;
|
|
}
|
|
else
|
|
assert(0, "Bad Logic.");
|
|
|
|
if(isDST)
|
|
return adjTime + convert!("minutes", "hnsecs")(tzInfo.Bias + tzInfo.DaylightBias);
|
|
}
|
|
catch(Exception e)
|
|
assert(0, "SysTime's constructor threw.");
|
|
}
|
|
|
|
return adjTime + convert!("minutes", "hnsecs")(tzInfo.Bias + tzInfo.StandardBias);
|
|
}
|
|
|
|
|
|
this(string name, TIME_ZONE_INFORMATION tzInfo) immutable
|
|
{
|
|
//Cannot use to!string(wchar*), probably due to bug http://d.puremagic.com/issues/show_bug.cgi?id=5016
|
|
static string conv(wchar* wcstr)
|
|
{
|
|
wcstr[31] = '\0';
|
|
wstring retval;
|
|
|
|
for(;; ++wcstr)
|
|
{
|
|
if(*wcstr == '\0')
|
|
break;
|
|
|
|
retval ~= *wcstr;
|
|
}
|
|
|
|
return to!string(retval);
|
|
}
|
|
|
|
//super(name, to!string(tzInfo.StandardName.ptr), to!string(tzInfo.DaylightName.ptr));
|
|
super(name, conv(tzInfo.StandardName.ptr), conv(tzInfo.DaylightName.ptr));
|
|
|
|
_tzInfo = tzInfo;
|
|
}
|
|
|
|
|
|
TIME_ZONE_INFORMATION _tzInfo;
|
|
}
|
|
}
|
|
|
|
|
|
version(StdDdoc)
|
|
{
|
|
/++
|
|
$(BLUE This function is Posix-Only.)
|
|
|
|
Allows you to set the local time zone on Posix systems with the TZ
|
|
database name by setting the TZ environment variable.
|
|
|
|
Unfortunately, there is no way to do it on Windows using the TZ
|
|
database name, so this function only exists on Posix systems.
|
|
+/
|
|
void setTZEnvVar(string tzDatabaseName);
|
|
|
|
|
|
/++
|
|
$(BLUE This function is Posix-Only.)
|
|
|
|
Clears the TZ environment variable.
|
|
+/
|
|
void clearTZEnvVar();
|
|
}
|
|
else version(Posix)
|
|
{
|
|
void setTZEnvVar(string tzDatabaseName) nothrow
|
|
{
|
|
try
|
|
{
|
|
auto value = PosixTimeZone.defaultTZDatabaseDir ~ tzDatabaseName ~ "\0";
|
|
|
|
setenv("TZ", value.ptr, 1);
|
|
tzset();
|
|
}
|
|
catch(Exception e)
|
|
assert(0, "The impossible happened. setenv or tzset threw.");
|
|
}
|
|
|
|
|
|
void clearTZEnvVar() nothrow
|
|
{
|
|
try
|
|
{
|
|
unsetenv("TZ");
|
|
tzset();
|
|
}
|
|
catch(Exception e)
|
|
assert(0, "The impossible happened. unsetenv or tzset threw.");
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Converts the given TZ Database name to the corresponding Windows time zone
|
|
name.
|
|
|
|
Note that in a few cases, a TZ Dabatase name corresponds to two different
|
|
Windows time zone names. So, while in most cases converting from one to the
|
|
other and back again will result in the same time zone name that you started
|
|
with, in a few cases, you will get a different name.
|
|
|
|
Also, there are far more TZ Database names than Windows time zones, so some
|
|
of the more exotic TZ Database names don't have corresponding Windows time
|
|
zone names.
|
|
|
|
See_Also:
|
|
$(WEB unicode.org/repos/cldr-tmp/trunk/diff/supplemental/zone_tzid.html,
|
|
Windows <-> TZ Database Name Conversion Table)
|
|
|
|
Params:
|
|
tzName = The TZ Database name to convert.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given $(D_PARAM tzName) cannot be
|
|
converted.
|
|
+/
|
|
string tzDatabaseNameToWindowsTZName(string tzName)
|
|
{
|
|
switch(tzName)
|
|
{
|
|
case "Africa/Cairo": return "Egypt Standard Time";
|
|
case "Africa/Casablanca": return "Morocco Standard Time";
|
|
case "Africa/Johannesburg": return "South Africa Standard Time";
|
|
case "Africa/Lagos": return "W. Central Africa Standard Time";
|
|
case "Africa/Nairobi": return "E. Africa Standard Time";
|
|
case "Africa/Windhoek": return "Namibia Standard Time";
|
|
case "America/Anchorage": return "Alaskan Standard Time";
|
|
case "America/Asuncion": return "Paraguay Standard Time";
|
|
case "America/Bogota": return "SA Pacific Standard Time";
|
|
case "America/Buenos_Aires": return "Argentina Standard Time";
|
|
case "America/Caracas": return "Venezuela Standard Time";
|
|
case "America/Cayenne": return "SA Eastern Standard Time";
|
|
case "America/Chicago": return "Central Standard Time";
|
|
case "America/Chihuahua": return "Mountain Standard Time (Mexico)";
|
|
case "America/Cuiaba": return "Central Brazilian Standard Time";
|
|
case "America/Denver": return "Mountain Standard Time";
|
|
case "America/Godthab": return "Greenland Standard Time";
|
|
case "America/Guatemala": return "Central America Standard Time";
|
|
case "America/Halifax": return "Atlantic Standard Time";
|
|
case "America/La_Paz": return "SA Western Standard Time";
|
|
case "America/Los_Angeles": return "Pacific Standard Time";
|
|
case "America/Mexico_City": return "Central Standard Time (Mexico)";
|
|
case "America/Montevideo": return "Montevideo Standard Time";
|
|
case "America/New_York": return "Eastern Standard Time";
|
|
case "America/Phoenix": return "US Mountain Standard Time";
|
|
case "America/Regina": return "Canada Central Standard Time";
|
|
case "America/Santa_Isabel": return "Pacific Standard Time (Mexico)";
|
|
case "America/Santiago": return "Pacific SA Standard Time";
|
|
case "America/Sao_Paulo": return "E. South America Standard Time";
|
|
case "America/St_Johns": return "Newfoundland Standard Time";
|
|
case "Asia/Almaty": return "Central Asia Standard Time";
|
|
case "Asia/Amman": return "Jordan Standard Time";
|
|
case "Asia/Baghdad": return "Arabic Standard Time";
|
|
case "Asia/Baku": return "Azerbaijan Standard Time";
|
|
case "Asia/Bangkok": return "SE Asia Standard Time";
|
|
case "Asia/Beirut": return "Middle East Standard Time";
|
|
case "Asia/Calcutta": return "India Standard Time";
|
|
case "Asia/Colombo": return "Sri Lanka Standard Time";
|
|
case "Asia/Damascus": return "Syria Standard Time";
|
|
case "Asia/Dhaka": return "Bangladesh Standard Time";
|
|
case "Asia/Dubai": return "Arabian Standard Time";
|
|
case "Asia/Irkutsk": return "North Asia East Standard Time";
|
|
case "Asia/Jerusalem": return "Israel Standard Time";
|
|
case "Asia/Kabul": return "Afghanistan Standard Time";
|
|
case "Asia/Kamchatka": return "Kamchatka Standard Time";
|
|
case "Asia/Karachi": return "Pakistan Standard Time";
|
|
case "Asia/Katmandu": return "Nepal Standard Time";
|
|
case "Asia/Krasnoyarsk": return "North Asia Standard Time";
|
|
case "Asia/Magadan": return "Magadan Standard Time";
|
|
case "Asia/Novosibirsk": return "N. Central Asia Standard Time";
|
|
case "Asia/Rangoon": return "Myanmar Standard Time";
|
|
case "Asia/Riyadh": return "Arab Standard Time";
|
|
case "Asia/Seoul": return "Korea Standard Time";
|
|
case "Asia/Shanghai": return "China Standard Time";
|
|
case "Asia/Singapore": return "Singapore Standard Time";
|
|
case "Asia/Taipei": return "Taipei Standard Time";
|
|
case "Asia/Tashkent": return "West Asia Standard Time";
|
|
case "Asia/Tbilisi": return "Georgian Standard Time";
|
|
case "Asia/Tehran": return "Iran Standard Time";
|
|
case "Asia/Tokyo": return "Tokyo Standard Time";
|
|
case "Asia/Ulaanbaatar": return "Ulaanbaatar Standard Time";
|
|
case "Asia/Vladivostok": return "Vladivostok Standard Time";
|
|
case "Asia/Yakutsk": return "Yakutsk Standard Time";
|
|
case "Asia/Yekaterinburg": return "Ekaterinburg Standard Time";
|
|
case "Asia/Yerevan": return "Caucasus Standard Time";
|
|
case "Atlantic/Azores": return "Azores Standard Time";
|
|
case "Atlantic/Cape_Verde": return "Cape Verde Standard Time";
|
|
case "Atlantic/Reykjavik": return "Greenwich Standard Time";
|
|
case "Australia/Adelaide": return "Cen. Australia Standard Time";
|
|
case "Australia/Brisbane": return "E. Australia Standard Time";
|
|
case "Australia/Darwin": return "AUS Central Standard Time";
|
|
case "Australia/Hobart": return "Tasmania Standard Time";
|
|
case "Australia/Perth": return "W. Australia Standard Time";
|
|
case "Australia/Sydney": return "AUS Eastern Standard Time";
|
|
case "Etc/GMT-12": return "UTC+12";
|
|
case "Etc/GMT": return "UTC";
|
|
case "Etc/GMT+11": return "UTC-11";
|
|
case "Etc/GMT+12": return "Dateline Standard Time";
|
|
case "Etc/GMT+2": return "Mid-Atlantic Standard Time";
|
|
case "Etc/GMT+5": return "US Eastern Standard Time";
|
|
case "Europe/Berlin": return "W. Europe Standard Time";
|
|
case "Europe/Budapest": return "Central Europe Standard Time";
|
|
case "Europe/Istanbul": return "GTB Standard Time";
|
|
case "Europe/Kiev": return "FLE Standard Time";
|
|
case "Europe/London": return "GMT Standard Time";
|
|
case "Europe/Minsk": return "E. Europe Standard Time";
|
|
case "Europe/Moscow": return "Russian Standard Time";
|
|
case "Europe/Paris": return "Romance Standard Time";
|
|
case "Europe/Warsaw": return "Central European Standard Time";
|
|
case "Indian/Mauritius": return "Mauritius Standard Time";
|
|
case "Pacific/Apia": return "Samoa Standard Time";
|
|
case "Pacific/Auckland": return "New Zealand Standard Time";
|
|
case "Pacific/Fiji": return "Fiji Standard Time";
|
|
case "Pacific/Guadalcanal": return "Central Pacific Standard Time";
|
|
case "Pacific/Honolulu": return "Hawaiian Standard Time";
|
|
case "Pacific/Port_Moresby": return "West Pacific Standard Time";
|
|
case "Pacific/Tongatapu": return "Tonga Standard Time";
|
|
default:
|
|
throw new DateTimeException(format("Could not find Windows time zone name for: %s.", tzName));
|
|
}
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
version(Windows)
|
|
{
|
|
static void testTZSuccess(string tzName)
|
|
{
|
|
scope(failure) writefln("TZName which threw: %s", tzName);
|
|
|
|
tzDatabaseNameToWindowsTZName(tzName);
|
|
}
|
|
|
|
auto timeZones = TimeZone.getInstalledTZNames();
|
|
|
|
foreach(tzname; timeZones)
|
|
assertNotThrown!DateTimeException(testTZSuccess(tzname));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Converts the given Windows time zone name to a corresponding TZ Database
|
|
name.
|
|
|
|
See_Also:
|
|
$(WEB unicode.org/repos/cldr-tmp/trunk/diff/supplemental/zone_tzid.html,
|
|
Windows <-> TZ Database Name Conversion Table)
|
|
|
|
Params:
|
|
tzName = The TZ Database name to convert.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given $(D_PARAM tzName) cannot be
|
|
converted.
|
|
+/
|
|
string windowsTZNameToTZDatabaseName(string tzName)
|
|
{
|
|
switch(tzName)
|
|
{
|
|
case "AUS Central Standard Time": return "Australia/Darwin";
|
|
case "AUS Eastern Standard Time": return "Australia/Sydney";
|
|
case "Afghanistan Standard Time": return "Asia/Kabul";
|
|
case "Alaskan Standard Time": return "America/Anchorage";
|
|
case "Arab Standard Time": return "Asia/Riyadh";
|
|
case "Arabian Standard Time": return "Asia/Dubai";
|
|
case "Arabic Standard Time": return "Asia/Baghdad";
|
|
case "Argentina Standard Time": return "America/Buenos_Aires";
|
|
case "Armenian Standard Time": return "Asia/Yerevan";
|
|
case "Atlantic Standard Time": return "America/Halifax";
|
|
case "Azerbaijan Standard Time": return "Asia/Baku";
|
|
case "Azores Standard Time": return "Atlantic/Azores";
|
|
case "Bangladesh Standard Time": return "Asia/Dhaka";
|
|
case "Canada Central Standard Time": return "America/Regina";
|
|
case "Cape Verde Standard Time": return "Atlantic/Cape_Verde";
|
|
case "Caucasus Standard Time": return "Asia/Yerevan";
|
|
case "Cen. Australia Standard Time": return "Australia/Adelaide";
|
|
case "Central America Standard Time": return "America/Guatemala";
|
|
case "Central Asia Standard Time": return "Asia/Almaty";
|
|
case "Central Brazilian Standard Time": return "America/Cuiaba";
|
|
case "Central Europe Standard Time": return "Europe/Budapest";
|
|
case "Central European Standard Time": return "Europe/Warsaw";
|
|
case "Central Pacific Standard Time": return "Pacific/Guadalcanal";
|
|
case "Central Standard Time": return "America/Chicago";
|
|
case "Central Standard Time (Mexico)": return "America/Mexico_City";
|
|
case "China Standard Time": return "Asia/Shanghai";
|
|
case "Dateline Standard Time": return "Etc/GMT+12";
|
|
case "E. Africa Standard Time": return "Africa/Nairobi";
|
|
case "E. Australia Standard Time": return "Australia/Brisbane";
|
|
case "E. Europe Standard Time": return "Europe/Minsk";
|
|
case "E. South America Standard Time": return "America/Sao_Paulo";
|
|
case "Eastern Standard Time": return "America/New_York";
|
|
case "Egypt Standard Time": return "Africa/Cairo";
|
|
case "Ekaterinburg Standard Time": return "Asia/Yekaterinburg";
|
|
case "FLE Standard Time": return "Europe/Kiev";
|
|
case "Fiji Standard Time": return "Pacific/Fiji";
|
|
case "GMT Standard Time": return "Europe/London";
|
|
case "GTB Standard Time": return "Europe/Istanbul";
|
|
case "Georgian Standard Time": return "Asia/Tbilisi";
|
|
case "Greenland Standard Time": return "America/Godthab";
|
|
case "Greenwich Standard Time": return "Atlantic/Reykjavik";
|
|
case "Hawaiian Standard Time": return "Pacific/Honolulu";
|
|
case "India Standard Time": return "Asia/Calcutta";
|
|
case "Iran Standard Time": return "Asia/Tehran";
|
|
case "Israel Standard Time": return "Asia/Jerusalem";
|
|
case "Jordan Standard Time": return "Asia/Amman";
|
|
case "Kamchatka Standard Time": return "Asia/Kamchatka";
|
|
case "Korea Standard Time": return "Asia/Seoul";
|
|
case "Magadan Standard Time": return "Asia/Magadan";
|
|
case "Mauritius Standard Time": return "Indian/Mauritius";
|
|
case "Mexico Standard Time": return "America/Mexico_City";
|
|
case "Mexico Standard Time 2": return "America/Chihuahua";
|
|
case "Mid-Atlantic Standard Time": return "Etc/GMT+2";
|
|
case "Middle East Standard Time": return "Asia/Beirut";
|
|
case "Montevideo Standard Time": return "America/Montevideo";
|
|
case "Morocco Standard Time": return "Africa/Casablanca";
|
|
case "Mountain Standard Time": return "America/Denver";
|
|
case "Mountain Standard Time (Mexico)": return "America/Chihuahua";
|
|
case "Myanmar Standard Time": return "Asia/Rangoon";
|
|
case "N. Central Asia Standard Time": return "Asia/Novosibirsk";
|
|
case "Namibia Standard Time": return "Africa/Windhoek";
|
|
case "Nepal Standard Time": return "Asia/Katmandu";
|
|
case "New Zealand Standard Time": return "Pacific/Auckland";
|
|
case "Newfoundland Standard Time": return "America/St_Johns";
|
|
case "North Asia East Standard Time": return "Asia/Irkutsk";
|
|
case "North Asia Standard Time": return "Asia/Krasnoyarsk";
|
|
case "Pacific SA Standard Time": return "America/Santiago";
|
|
case "Pacific Standard Time": return "America/Los_Angeles";
|
|
case "Pacific Standard Time (Mexico)": return "America/Santa_Isabel";
|
|
case "Pakistan Standard Time": return "Asia/Karachi";
|
|
case "Paraguay Standard Time": return "America/Asuncion";
|
|
case "Romance Standard Time": return "Europe/Paris";
|
|
case "Russian Standard Time": return "Europe/Moscow";
|
|
case "SA Eastern Standard Time": return "America/Cayenne";
|
|
case "SA Pacific Standard Time": return "America/Bogota";
|
|
case "SA Western Standard Time": return "America/La_Paz";
|
|
case "SE Asia Standard Time": return "Asia/Bangkok";
|
|
case "Samoa Standard Time": return "Pacific/Apia";
|
|
case "Singapore Standard Time": return "Asia/Singapore";
|
|
case "South Africa Standard Time": return "Africa/Johannesburg";
|
|
case "Sri Lanka Standard Time": return "Asia/Colombo";
|
|
case "Syria Standard Time": return "Asia/Damascus";
|
|
case "Taipei Standard Time": return "Asia/Taipei";
|
|
case "Tasmania Standard Time": return "Australia/Hobart";
|
|
case "Tokyo Standard Time": return "Asia/Tokyo";
|
|
case "Tonga Standard Time": return "Pacific/Tongatapu";
|
|
case "US Eastern Standard Time": return "Etc/GMT+5";
|
|
case "US Mountain Standard Time": return "America/Phoenix";
|
|
case "UTC": return "Etc/GMT";
|
|
case "UTC+12": return "Etc/GMT-12";
|
|
case "UTC-02": return "Etc/GMT+2";
|
|
case "UTC-11": return "Etc/GMT+11";
|
|
case "Ulaanbaatar Standard Time": return "Asia/Ulaanbaatar";
|
|
case "Venezuela Standard Time": return "America/Caracas";
|
|
case "Vladivostok Standard Time": return "Asia/Vladivostok";
|
|
case "W. Australia Standard Time": return "Australia/Perth";
|
|
case "W. Central Africa Standard Time": return "Africa/Lagos";
|
|
case "W. Europe Standard Time": return "Europe/Berlin";
|
|
case "West Asia Standard Time": return "Asia/Tashkent";
|
|
case "West Pacific Standard Time": return "Pacific/Port_Moresby";
|
|
case "Yakutsk Standard Time": return "Asia/Yakutsk";
|
|
default:
|
|
throw new DateTimeException(format("Could not find TZ Database name for: %s.", tzName));
|
|
}
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
version(Windows)
|
|
{
|
|
static void testTZSuccess(string tzName)
|
|
{
|
|
scope(failure) writefln("TZName which threw: %s", tzName);
|
|
|
|
windowsTZNameToTZDatabaseName(tzName);
|
|
}
|
|
|
|
auto timeZones = WindowsTimeZone.getInstalledTZNames();
|
|
|
|
foreach(tzname; timeZones)
|
|
assertNotThrown!DateTimeException(testTZSuccess(tzname));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//==============================================================================
|
|
// Section with StopWatch and Benchmark Code.
|
|
//==============================================================================
|
|
|
|
/++
|
|
$(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.
|
|
|
|
Examples:
|
|
--------------------
|
|
void foo()
|
|
{
|
|
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;
|
|
// When you want to know the number of seconds,
|
|
// you can use properties of TickDuration.
|
|
// (seconds, mseconds, useconds, hnsecs)
|
|
foreach(t; times)
|
|
sum += t.hnsecs;
|
|
writeln("Average time: ", sum/n, " hnsecs");
|
|
}
|
|
--------------------
|
|
+/
|
|
@safe struct StopWatch
|
|
{
|
|
public:
|
|
//Verify Example
|
|
@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;
|
|
// When you want to know the number of seconds,
|
|
// you can use properties of TickDuration.
|
|
// (seconds, mseconds, useconds, hnsecs)
|
|
foreach(t; times)
|
|
sum += t.hnsecs;
|
|
writeln("Average time: ", sum/n, " hnsecs");
|
|
}
|
|
|
|
/++
|
|
Auto start with constructor.
|
|
+/
|
|
this(AutoStart autostart)
|
|
{
|
|
if(autostart)
|
|
start();
|
|
}
|
|
|
|
version(testStdDateTime) @safe unittest
|
|
{
|
|
auto sw = StopWatch(AutoStart.yes);
|
|
sw.stop();
|
|
}
|
|
|
|
|
|
///
|
|
bool opEquals(const ref StopWatch rhs) const pure nothrow
|
|
{
|
|
return _timeStart == rhs._timeStart &&
|
|
_timeMeasured == rhs._timeMeasured;
|
|
}
|
|
|
|
|
|
/++
|
|
Resets the stop watch.
|
|
+/
|
|
void reset()
|
|
{
|
|
if(_flagStarted)
|
|
{
|
|
// Set current system time if StopWatch is measuring.
|
|
_timeStart = Clock.currSystemTick;
|
|
}
|
|
else
|
|
{
|
|
// Set zero if StopWatch is not measuring.
|
|
_timeStart.length = 0;
|
|
}
|
|
|
|
_timeMeasured.length = 0;
|
|
}
|
|
|
|
version(testStdDateTime) @safe unittest
|
|
{
|
|
StopWatch sw;
|
|
sw.start();
|
|
sw.stop();
|
|
sw.reset();
|
|
assert(sw.peek().to!("seconds", real) == 0);
|
|
}
|
|
|
|
|
|
/++
|
|
Starts the stop watch.
|
|
+/
|
|
void start()
|
|
{
|
|
assert(!_flagStarted);
|
|
StopWatch sw;
|
|
_flagStarted = true;
|
|
_timeStart = Clock.currSystemTick;
|
|
}
|
|
|
|
version(testStdDateTime) @trusted 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()
|
|
{
|
|
assert(_flagStarted);
|
|
_flagStarted = false;
|
|
_timeMeasured += Clock.currSystemTick - _timeStart;
|
|
}
|
|
|
|
version(testStdDateTime) @trusted 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
|
|
{
|
|
if(_flagStarted)
|
|
return Clock.currSystemTick - _timeStart + _timeMeasured;
|
|
|
|
return _timeMeasured;
|
|
}
|
|
|
|
version(testStdDateTime) @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);
|
|
}
|
|
|
|
private:
|
|
|
|
// true if observing.
|
|
bool _flagStarted = false;
|
|
|
|
// TickDuration at the time of StopWatch starting measurement.
|
|
TickDuration _timeStart;
|
|
|
|
// Total time that StopWatch ran.
|
|
TickDuration _timeMeasured;
|
|
}
|
|
|
|
|
|
// workaround for bug4886
|
|
@safe size_t lengthof(aliases...)() pure nothrow
|
|
{
|
|
return aliases.length;
|
|
}
|
|
|
|
|
|
/++
|
|
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 $(CXREF time, TickDuration)) 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.
|
|
|
|
Examples:
|
|
--------------------
|
|
int a;
|
|
void f0() {}
|
|
void f1() {auto b = a;}
|
|
void f2() {auto b = to!(string)(a);}
|
|
auto r = benchmark!(f0, f1, f2)(10_000_000);
|
|
writefln("Milliseconds to call fun[0] n times: %s", r[0].to!("msecs", int));
|
|
--------------------
|
|
+/
|
|
@safe TickDuration[lengthof!(fun)()] benchmark(fun...)(uint n)
|
|
if(areAllSafe!fun)
|
|
{
|
|
TickDuration[lengthof!(fun)()] result;
|
|
StopWatch sw;
|
|
sw.start();
|
|
|
|
foreach(i, unused; fun)
|
|
{
|
|
sw.reset();
|
|
foreach(j; 0 .. n)
|
|
fun[i]();
|
|
result[i] = sw.peek();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/++ Ditto +/
|
|
TickDuration[lengthof!(fun)()] benchmark(fun...)(uint times)
|
|
if(!areAllSafe!fun)
|
|
{
|
|
TickDuration[lengthof!(fun)()] result;
|
|
StopWatch sw;
|
|
sw.start();
|
|
|
|
foreach(i, unused; fun)
|
|
{
|
|
sw.reset();
|
|
foreach(j; 0 .. times)
|
|
fun[i]();
|
|
|
|
result[i] = sw.peek();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//Verify Examples.
|
|
version(testStdDateTime) unittest
|
|
{
|
|
void writefln(S...)(S args){}
|
|
|
|
int a;
|
|
void f0() {}
|
|
void f1() {auto b = a;}
|
|
void f2() {auto b = to!(string)(a);}
|
|
auto r = benchmark!(f0, f1, f2)(10_000_000);
|
|
writefln("Milliseconds to call fun[0] n times: %s", r[0].to!("msecs", int));
|
|
}
|
|
|
|
version(testStdDateTime) @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;
|
|
}
|
|
|
|
|
|
/++
|
|
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.
|
|
|
|
Examples:
|
|
--------------------
|
|
void f1() {
|
|
// ...
|
|
}
|
|
void f2() {
|
|
// ...
|
|
}
|
|
|
|
void main() {
|
|
auto b = comparingBenchmark!(f1, f2, 0x80);
|
|
writeln(b.point);
|
|
}
|
|
--------------------
|
|
+/
|
|
@safe ComparingBenchmarkResult comparingBenchmark(alias baseFunc,
|
|
alias targetFunc,
|
|
int times = 0xfff)()
|
|
if(isSafe!baseFunc && isSafe!targetFunc)
|
|
{
|
|
auto t = benchmark!(baseFunc, targetFunc)(times);
|
|
return ComparingBenchmarkResult(t[0], t[1]);
|
|
}
|
|
|
|
|
|
/++ Ditto +/
|
|
ComparingBenchmarkResult comparingBenchmark(alias baseFunc,
|
|
alias targetFunc,
|
|
int times = 0xfff)()
|
|
if(!isSafe!baseFunc || !isSafe!targetFunc)
|
|
{
|
|
auto t = benchmark!(baseFunc, targetFunc)(times);
|
|
return ComparingBenchmarkResult(t[0], t[1]);
|
|
}
|
|
|
|
|
|
version(testStdDateTime) @safe unittest
|
|
{
|
|
void f1x() {}
|
|
void f2x() {}
|
|
@safe void f1o() {}
|
|
@safe void f2o() {}
|
|
auto b1 = comparingBenchmark!(f1o, f2o, 1); // OK
|
|
//static auto b2 = comparingBenchmark!(f1x, f2x, 1); // NG
|
|
}
|
|
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
void f1x() {}
|
|
void f2x() {}
|
|
@safe void f1o() {}
|
|
@safe void f2o() {}
|
|
auto b1 = comparingBenchmark!(f1o, f2o, 1); // OK
|
|
auto b2 = comparingBenchmark!(f1x, f2x, 1); // OK
|
|
}
|
|
|
|
|
|
//==============================================================================
|
|
// Section with public helper functions and templates.
|
|
//==============================================================================
|
|
|
|
/++
|
|
$(RED Scheduled for deprecation in August 2011. This is only here to help
|
|
transition code which uses std.date to using std.datetime.)
|
|
|
|
Returns a $(D d_time) for the given $(D SysTime).
|
|
+/
|
|
long sysTimeToDTime(in SysTime sysTime)
|
|
{
|
|
return convert!("hnsecs", "msecs")(sysTime.stdTime - 621355968000000000L);
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
_assertPred!"=="(sysTimeToDTime(SysTime(DateTime(1970, 1, 1), UTC())),
|
|
0);
|
|
_assertPred!"=="(sysTimeToDTime(SysTime(DateTime(1970, 1, 1), FracSec.from!"msecs"(1), UTC())),
|
|
1);
|
|
_assertPred!"=="(sysTimeToDTime(SysTime(DateTime(1969, 12, 31, 23, 59, 59), FracSec.from!"msecs"(999), UTC())),
|
|
-1);
|
|
|
|
_assertPred!"=="(sysTimeToDTime(SysTime(DateTime(1970, 1, 2), UTC())),
|
|
86_400_000);
|
|
_assertPred!"=="(sysTimeToDTime(SysTime(DateTime(1969, 12, 31), UTC())),
|
|
-86_400_000);
|
|
}
|
|
|
|
|
|
/++
|
|
$(RED Scheduled for deprecation in August 2011. This is only here to help
|
|
transition code which uses std.date to using std.datetime.)
|
|
|
|
Returns a $(D SysTime) for the given $(D d_time).
|
|
+/
|
|
SysTime dTimeToSysTime(long dTime, immutable TimeZone tz = null)
|
|
{
|
|
immutable hnsecs = convert!("msecs", "hnsecs")(dTime) + 621355968000000000L;
|
|
|
|
return SysTime(hnsecs, tz);
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
_assertPred!"=="(dTimeToSysTime(0),
|
|
SysTime(DateTime(1970, 1, 1), UTC()));
|
|
_assertPred!"=="(dTimeToSysTime(1),
|
|
SysTime(DateTime(1970, 1, 1), FracSec.from!"msecs"(1), UTC()));
|
|
_assertPred!"=="(dTimeToSysTime(-1),
|
|
SysTime(DateTime(1969, 12, 31, 23, 59, 59), FracSec.from!"msecs"(999), UTC()));
|
|
|
|
_assertPred!"=="(dTimeToSysTime(86_400_000),
|
|
SysTime(DateTime(1970, 1, 2), UTC()));
|
|
_assertPred!"=="(dTimeToSysTime(-86_400_000),
|
|
SysTime(DateTime(1969, 12, 31), UTC()));
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the absolute value of a duration.
|
|
+/
|
|
D abs(D)(D duration)
|
|
if(is(Unqual!D == Duration) ||
|
|
is(Unqual!D == TickDuration))
|
|
{
|
|
static if(is(Unqual!D == Duration))
|
|
return dur!"hnsecs"(std.math.abs(duration.total!"hnsecs"()));
|
|
else static if(is(Unqual!D == TickDuration))
|
|
return TickDuration(std.math.abs(duration.length));
|
|
else
|
|
static assert(0);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(abs(dur!"msecs"(5)), dur!"msecs"(5));
|
|
_assertPred!"=="(abs(dur!"msecs"(-5)), dur!"msecs"(5));
|
|
|
|
_assertPred!"=="(abs(TickDuration(17)), TickDuration(17));
|
|
_assertPred!"=="(abs(TickDuration(-17)), TickDuration(17));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Whether the given type defines all of the necessary functions for it to
|
|
function as a time point.
|
|
+/
|
|
template isTimePoint(T)
|
|
{
|
|
enum isTimePoint = hasMin!T &&
|
|
hasMax!T &&
|
|
hasOverloadedOpBinaryWithDuration!T &&
|
|
hasOverloadedOpAssignWithDuration!T &&
|
|
hasOverloadedOpBinaryWithSelf!T;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static assert(isTimePoint!(Date));
|
|
static assert(isTimePoint!(DateTime));
|
|
static assert(isTimePoint!(TimeOfDay));
|
|
static assert(isTimePoint!(SysTime));
|
|
static assert(isTimePoint!(const Date));
|
|
static assert(isTimePoint!(const DateTime));
|
|
static assert(isTimePoint!(const TimeOfDay));
|
|
static assert(isTimePoint!(const SysTime));
|
|
static assert(isTimePoint!(immutable Date));
|
|
static assert(isTimePoint!(immutable DateTime));
|
|
static assert(isTimePoint!(immutable TimeOfDay));
|
|
static assert(isTimePoint!(immutable SysTime));
|
|
}
|
|
}
|
|
|
|
/++
|
|
Whether the given Gregorian Year is a leap year.
|
|
|
|
Params:
|
|
year = The year to to be tested.
|
|
+/
|
|
static bool yearIsLeapYear(int year) pure nothrow
|
|
{
|
|
if(year % 400 == 0)
|
|
return true;
|
|
|
|
if(year % 100 == 0)
|
|
return false;
|
|
|
|
return year % 4 == 0;
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
foreach(year; [1, 2, 3, 5, 6, 7, 100, 200, 300, 500, 600, 700, 1998, 1999,
|
|
2001, 2002, 2003, 2005, 2006, 2007, 2009, 2010, 2011])
|
|
{
|
|
assert(!yearIsLeapYear(year), format("year: %s.", year));
|
|
assert(!yearIsLeapYear(-year), format("year: %s.", year));
|
|
}
|
|
|
|
foreach(year; [0, 4, 8, 400, 800, 1600, 1996, 2000, 2004, 2008, 2012])
|
|
{
|
|
assert(yearIsLeapYear(year), format("year: %s.", year));
|
|
assert(yearIsLeapYear(-year), format("year: %s.", year));
|
|
}
|
|
}
|
|
|
|
/++
|
|
Converts a $(D time_t) (which uses midnight, January 1st, 1970 UTC as its
|
|
epoch and seconds as its units) to std time (which uses midnight,
|
|
January 1st, 1 A.D. UTC and hnsecs as its units).
|
|
|
|
Params:
|
|
unixTime = The $(D time_t) to convert.
|
|
+/
|
|
long unixTimeToStdTime(time_t unixTime) pure nothrow
|
|
{
|
|
return 621_355_968_000_000_000L + convert!("seconds", "hnsecs")(unixTime);
|
|
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(unixTimeToStdTime(0), 621_355_968_000_000_000L); //Midnight, January 1st, 1970
|
|
_assertPred!"=="(unixTimeToStdTime(86_400), 621_355_968_000_000_000L + 864_000_000_000L); //Midnight, January 2nd, 1970
|
|
_assertPred!"=="(unixTimeToStdTime(-86_400), 621_355_968_000_000_000L - 864_000_000_000L); //Midnight, December 31st, 1969
|
|
|
|
_assertPred!"=="(unixTimeToStdTime(0), (Date(1970, 1, 1) - Date(1, 1, 1)).total!"hnsecs");
|
|
_assertPred!"=="(unixTimeToStdTime(0), (DateTime(1970, 1, 1) - DateTime(1, 1, 1)).total!"hnsecs");
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Converts std time (which uses midnight, January 1st, 1 A.D. UTC as its epoch
|
|
and hnsecs as its units) to $(D time_t) (which uses midnight, January 1st,
|
|
1970 UTC as its epoch and seconds as its units). If $(D time_t) is 32 bits,
|
|
rather than 64, and the result can't fit in a 32-bit value, then the closest
|
|
value that can be held in 32 bits will be used (so $(D time_t.max) if it
|
|
goes over and $(D time_t.min) if it goes under).
|
|
|
|
Note:
|
|
While Windows systems require that $(D time_t) be non-negative (in spite
|
|
of $(D time_t) being signed), this function still returns negative
|
|
numbers on Windows, since it's more flexible to allow negative time_t
|
|
for those who need it. So, if you're on Windows and are using the
|
|
standard C functions or Win32 API functions which take a $(D time_t),
|
|
you may want to check whether the return value of
|
|
$(D stdTimeToUnixTime) is non-negative.
|
|
|
|
Params:
|
|
stdTime = The std time to convert.
|
|
+/
|
|
time_t stdTimeToUnixTime(long stdTime) pure nothrow
|
|
{
|
|
immutable unixTime = convert!("hnsecs", "seconds")(stdTime - 621_355_968_000_000_000L);
|
|
|
|
static if(time_t.sizeof >= long.sizeof)
|
|
return cast(time_t)unixTime;
|
|
else
|
|
{
|
|
if(unixTime > 0)
|
|
{
|
|
if(unixTime > time_t.max)
|
|
return time_t.max;
|
|
return cast(time_t)unixTime;
|
|
}
|
|
|
|
if(unixTime < time_t.min)
|
|
return time_t.min;
|
|
|
|
return cast(time_t)unixTime;
|
|
}
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(stdTimeToUnixTime(621_355_968_000_000_000L), 0); //Midnight, January 1st, 1970
|
|
_assertPred!"=="(stdTimeToUnixTime(621_355_968_000_000_000L + 864_000_000_000L), 86_400); //Midnight, January 2nd, 1970
|
|
_assertPred!"=="(stdTimeToUnixTime(621_355_968_000_000_000L - 864_000_000_000L), -86_400); //Midnight, December 31st, 1969
|
|
|
|
_assertPred!"=="(stdTimeToUnixTime((Date(1970, 1, 1) - Date(1, 1, 1)).total!"hnsecs"), 0);
|
|
_assertPred!"=="(stdTimeToUnixTime((DateTime(1970, 1, 1) - DateTime(1, 1, 1)).total!"hnsecs"), 0);
|
|
}
|
|
}
|
|
|
|
|
|
version(StdDdoc)
|
|
{
|
|
version(Windows) {}
|
|
else
|
|
{
|
|
alias void* SYSTEMTIME;
|
|
alias void* FILETIME;
|
|
}
|
|
|
|
/++
|
|
$(BLUE This function is Windows-Only.)
|
|
|
|
Converts a $(D SYSTEMTIME) struct to a $(D SysTime).
|
|
|
|
Params:
|
|
st = The $(D SYSTEMTIME) struct to convert.
|
|
tz = The time zone that the time in the $(D SYSTEMTIME) struct is
|
|
assumed to be (if the $(D SYSTEMTIME) was supplied by a Windows
|
|
system call, the $(D SYSTEMTIME) will either be in local time
|
|
or UTC, depending on the call).
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given $(D SYSTEMTIME) will not fit in
|
|
a $(D SysTime), which is highly unlikely to happen given that
|
|
$(D SysTime.max) is in 29,228 A.D. and the maximum $(D SYSTEMTIME)
|
|
is in 30,827 A.D.
|
|
+/
|
|
SysTime SYSTEMTIMEToSysTime(const SYSTEMTIME* st, immutable TimeZone tz = LocalTime());
|
|
|
|
|
|
/++
|
|
$(BLUE This function is Windows-Only.)
|
|
|
|
Converts a $(D SysTime) to a $(D SYSTEMTIME) struct.
|
|
|
|
The $(D SYSTEMTIME) which is returned will be set using the given
|
|
$(D SysTime)'s time zone, so if you want the $(D SYSTEMTIME) to be in
|
|
UTC, set the $(D SysTime)'s time zone to UTC.
|
|
|
|
Params:
|
|
sysTime = The $(D SysTime) to convert.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given $(D SysTime) will not fit in a
|
|
$(D SYSTEMTIME). This will only happen if the $(D SysTime)'s date is
|
|
prior to 1601 A.D.
|
|
+/
|
|
SYSTEMTIME SysTimeToSYSTEMTIME(in SysTime sysTime);
|
|
|
|
|
|
/++
|
|
$(BLUE This function is Windows-Only.)
|
|
|
|
Converts a $(D FILETIME) struct to a $(D SysTime).
|
|
|
|
Params:
|
|
ft = The $(D FILETIME) struct to convert.
|
|
tz = The time zone that the $(D SysTime) will be in ($(D FILETIME)s
|
|
are in UTC).
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given $(D FILETIME) will not fit in a
|
|
$(D SysTime) or if the $(D FILETIME) cannot be converted to a
|
|
$(D SYSTEMTIME).
|
|
+/
|
|
SysTime FILETIMEToSysTime(const FILETIME* ft, immutable TimeZone tz = LocalTime());
|
|
|
|
|
|
/++
|
|
$(BLUE This function is Windows-Only.)
|
|
|
|
Converts a $(D SysTime) to a $(D FILETIME) struct.
|
|
|
|
$(D FILETIME)s are always in UTC.
|
|
|
|
Params:
|
|
sysTime = The $(D SysTime) to convert.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given $(D SysTime) will not fit in a
|
|
$(D FILETIME).
|
|
+/
|
|
FILETIME SysTimeToFILETIME(SysTime sysTime);
|
|
}
|
|
else version(Windows)
|
|
{
|
|
SysTime SYSTEMTIMEToSysTime(const SYSTEMTIME* st, immutable TimeZone tz = LocalTime())
|
|
{
|
|
const max = SysTime.max;
|
|
|
|
static void throwLaterThanMax()
|
|
{
|
|
throw new DateTimeException("The given SYSTEMTIME is for a date greater than SysTime.max.");
|
|
}
|
|
|
|
if(st.wYear > max.year)
|
|
throwLaterThanMax();
|
|
else if(st.wYear == max.year)
|
|
{
|
|
if(st.wMonth > max.month)
|
|
throwLaterThanMax();
|
|
else if(st.wMonth == max.month)
|
|
{
|
|
if(st.wDay > max.day)
|
|
throwLaterThanMax();
|
|
else if(st.wDay == max.day)
|
|
{
|
|
if(st.wHour > max.hour)
|
|
throwLaterThanMax();
|
|
else if(st.wHour == max.hour)
|
|
{
|
|
if(st.wMinute > max.minute)
|
|
throwLaterThanMax();
|
|
else if(st.wMinute == max.minute)
|
|
{
|
|
if(st.wSecond > max.second)
|
|
throwLaterThanMax();
|
|
else if(st.wSecond == max.second)
|
|
{
|
|
if(st.wMilliseconds > max.fracSec.msecs)
|
|
throwLaterThanMax();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
auto dt = DateTime(st.wYear, st.wMonth, st.wDay,
|
|
st.wHour, st.wMinute, st.wSecond);
|
|
|
|
return SysTime(dt, FracSec.from!"msecs"(st.wMilliseconds), tz);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto sysTime = Clock.currTime(UTC());
|
|
SYSTEMTIME st = void;
|
|
GetSystemTime(&st);
|
|
auto converted = SYSTEMTIMEToSysTime(&st, UTC());
|
|
|
|
_assertPred!"<="(abs((converted - sysTime)),
|
|
dur!"seconds"(2));
|
|
}
|
|
}
|
|
|
|
|
|
SYSTEMTIME SysTimeToSYSTEMTIME(in SysTime sysTime)
|
|
{
|
|
immutable dt = cast(DateTime)sysTime;
|
|
|
|
if(dt.year < 1601)
|
|
throw new DateTimeException("SYSTEMTIME cannot hold dates prior to the year 1601.");
|
|
|
|
SYSTEMTIME st;
|
|
|
|
st.wYear = dt.year;
|
|
st.wMonth = dt.month;
|
|
st.wDayOfWeek = dt.dayOfWeek;
|
|
st.wDay = dt.day;
|
|
st.wHour = dt.hour;
|
|
st.wMinute = dt.minute;
|
|
st.wSecond = dt.second;
|
|
st.wMilliseconds = cast(ushort)sysTime.fracSec.msecs;
|
|
|
|
return st;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
SYSTEMTIME st = void;
|
|
GetSystemTime(&st);
|
|
auto sysTime = SYSTEMTIMEToSysTime(&st, UTC());
|
|
|
|
SYSTEMTIME result = SysTimeToSYSTEMTIME(sysTime);
|
|
|
|
_assertPred!"=="(st.wYear, result.wYear);
|
|
_assertPred!"=="(st.wMonth, result.wMonth);
|
|
_assertPred!"=="(st.wDayOfWeek, result.wDayOfWeek);
|
|
_assertPred!"=="(st.wDay, result.wDay);
|
|
_assertPred!"=="(st.wHour, result.wHour);
|
|
_assertPred!"=="(st.wMinute, result.wMinute);
|
|
_assertPred!"=="(st.wSecond, result.wSecond);
|
|
_assertPred!"=="(st.wMilliseconds, result.wMilliseconds);
|
|
}
|
|
}
|
|
|
|
|
|
SysTime FILETIMEToSysTime(const FILETIME* ft, immutable TimeZone tz = LocalTime())
|
|
{
|
|
SYSTEMTIME st = void;
|
|
|
|
if(!FileTimeToSystemTime(ft, &st))
|
|
throw new DateTimeException("FileTimeToSystemTime() failed.");
|
|
|
|
auto sysTime = SYSTEMTIMEToSysTime(&st, UTC());
|
|
sysTime.timezone = tz;
|
|
|
|
return sysTime;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
auto sysTime = Clock.currTime(UTC());
|
|
SYSTEMTIME st = void;
|
|
GetSystemTime(&st);
|
|
|
|
FILETIME ft = void;
|
|
SystemTimeToFileTime(&st, &ft);
|
|
|
|
auto converted = FILETIMEToSysTime(&ft);
|
|
|
|
_assertPred!"<="(abs((converted - sysTime)),
|
|
dur!"seconds"(2));
|
|
}
|
|
}
|
|
|
|
|
|
FILETIME SysTimeToFILETIME(SysTime sysTime)
|
|
{
|
|
SYSTEMTIME st = SysTimeToSYSTEMTIME(sysTime.toUTC());
|
|
|
|
FILETIME ft = void;
|
|
SystemTimeToFileTime(&st, &ft);
|
|
|
|
return ft;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
SYSTEMTIME st = void;
|
|
GetSystemTime(&st);
|
|
|
|
FILETIME ft = void;
|
|
SystemTimeToFileTime(&st, &ft);
|
|
auto sysTime = FILETIMEToSysTime(&ft, UTC());
|
|
|
|
FILETIME result = SysTimeToFILETIME(sysTime);
|
|
|
|
_assertPred!"=="(ft.dwLowDateTime, result.dwLowDateTime);
|
|
_assertPred!"=="(ft.dwHighDateTime, result.dwHighDateTime);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Type representing the DOS file date/time format.
|
|
+/
|
|
typedef uint DosFileTime;
|
|
|
|
/++
|
|
Converts from DOS file date/time to $(D SysTime).
|
|
|
|
Params:
|
|
dft = The DOS file time to convert.
|
|
tz = The time zone which the DOS file time is assumed to be in.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the $(D DosFileTime) is invalid.
|
|
+/
|
|
SysTime DosFileTimeToSysTime(DosFileTime dft, immutable TimeZone tz = LocalTime())
|
|
{
|
|
uint dt = cast(uint)dft;
|
|
|
|
if(dt == 0)
|
|
throw new DateTimeException("Invalid DosFileTime.");
|
|
|
|
int year = ((dt >> 25) & 0x7F) + 1980;
|
|
int month = ((dt >> 21) & 0x0F); // 1..12
|
|
int dayOfMonth = ((dt >> 16) & 0x1F); // 1..31
|
|
int hour = (dt >> 11) & 0x1F; // 0..23
|
|
int minute = (dt >> 5) & 0x3F; // 0..59
|
|
int second = (dt << 1) & 0x3E; // 0..58 (in 2 second increments)
|
|
|
|
SysTime sysTime = void;
|
|
|
|
try
|
|
return SysTime(DateTime(year, month, dayOfMonth, hour, minute, second), tz);
|
|
catch(DateTimeException dte)
|
|
throw new DateTimeException("Invalid DosFileTime", __FILE__, __LINE__, dte);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(DosFileTimeToSysTime(0b00000000001000010000000000000000),
|
|
SysTime(DateTime(1980, 1, 1, 0, 0, 0)));
|
|
|
|
_assertPred!"=="(DosFileTimeToSysTime(0b11111111100111111011111101111101),
|
|
SysTime(DateTime(2107, 12, 31, 23, 59, 58)));
|
|
|
|
_assertPred!"=="(DosFileTimeToSysTime(0x3E3F8456),
|
|
SysTime(DateTime(2011, 1, 31, 16, 34, 44)));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Converts from $(D SysTime) to DOS file date/time.
|
|
|
|
Params:
|
|
sysTime = The $(D SysTime) to convert.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given $(D SysTime) cannot be converted to
|
|
a $(D DosFileTime).
|
|
+/
|
|
DosFileTime SysTimeToDosFileTime(SysTime sysTime)
|
|
{
|
|
auto dateTime = cast(DateTime)sysTime;
|
|
|
|
if(dateTime.year < 1980)
|
|
throw new DateTimeException("DOS File Times cannot hold dates prior to 1980.");
|
|
|
|
if(dateTime.year > 2107)
|
|
throw new DateTimeException("DOS File Times cannot hold dates passed 2107.");
|
|
|
|
uint retval = 0;
|
|
retval = (dateTime.year - 1980) << 25;
|
|
retval |= (dateTime.month & 0x0F) << 21;
|
|
retval |= (dateTime.day & 0x1F) << 16;
|
|
retval |= (dateTime.hour & 0x1F) << 11;
|
|
retval |= (dateTime.minute & 0x3F) << 5;
|
|
retval |= (dateTime.second >> 1) & 0x1F;
|
|
|
|
return cast(DosFileTime)retval;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(SysTimeToDosFileTime(SysTime(DateTime(1980, 1, 1, 0, 0, 0))),
|
|
0b00000000001000010000000000000000);
|
|
|
|
_assertPred!"=="(SysTimeToDosFileTime(SysTime(DateTime(2107, 12, 31, 23, 59, 58))),
|
|
0b11111111100111111011111101111101);
|
|
|
|
_assertPred!"=="(SysTimeToDosFileTime(SysTime(DateTime(2011, 1, 31, 16, 34, 44))),
|
|
0x3E3F8456);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/++
|
|
Whether all of the given strings are valid units of time.
|
|
|
|
$(D "nsecs") is not considered a valid unit of time. Nothing in std.datetime
|
|
can handle precision greater than hnsecs, and the few functions in core.time
|
|
which deal with "nsecs" deal with it explicitly.
|
|
+/
|
|
bool validTimeUnits(string[] units...)
|
|
{
|
|
foreach(str; units)
|
|
{
|
|
if(!canFind(timeStrings.dup, str))
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/++
|
|
Compares two time unit strings. $(D "years") are the largest units and
|
|
$(D "hnsecs") are the smallest.
|
|
|
|
Returns:
|
|
$(BOOKTABLE,
|
|
$(TR $(TD this < rhs) $(TD < 0))
|
|
$(TR $(TD this == rhs) $(TD 0))
|
|
$(TR $(TD this > rhs) $(TD > 0))
|
|
)
|
|
|
|
Throws:
|
|
$(D DateTimeException) if either of the given strings is not a valid
|
|
time unit string.
|
|
+/
|
|
int cmpTimeUnits(string lhs, string rhs)
|
|
{
|
|
auto tstrings = timeStrings.dup;
|
|
immutable indexOfLHS = std.algorithm.countUntil(tstrings, lhs);
|
|
immutable indexOfRHS = std.algorithm.countUntil(tstrings, rhs);
|
|
|
|
enforce(indexOfLHS != -1, format("%s is not a valid TimeString", lhs));
|
|
enforce(indexOfRHS != -1, format("%s is not a valid TimeString", rhs));
|
|
|
|
if(indexOfLHS < indexOfRHS)
|
|
return -1;
|
|
if(indexOfLHS > indexOfRHS)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
foreach(i, outerUnits; timeStrings)
|
|
{
|
|
_assertPred!"=="(cmpTimeUnits(outerUnits, outerUnits), 0);
|
|
|
|
//For some reason, $ won't compile.
|
|
foreach(innerUnits; timeStrings[i+1 .. timeStrings.length])
|
|
_assertPred!"=="(cmpTimeUnits(outerUnits, innerUnits), -1);
|
|
}
|
|
|
|
foreach(i, outerUnits; timeStrings)
|
|
{
|
|
foreach(innerUnits; timeStrings[0 .. i])
|
|
_assertPred!"=="(cmpTimeUnits(outerUnits, innerUnits), 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Compares two time unit strings at compile time. $(D "years") are the largest
|
|
units and $(D "hnsecs") are the smallest.
|
|
|
|
This template is used instead of $(D cmpTimeUnits) because exceptions
|
|
can't be thrown at compile time and $(D cmpTimeUnits) must enforce that
|
|
the strings it's given are valid time unit strings. This template uses a
|
|
template constraint instead.
|
|
|
|
Returns:
|
|
$(BOOKTABLE,
|
|
$(TR $(TD this < rhs) $(TD < 0))
|
|
$(TR $(TD this == rhs) $(TD 0))
|
|
$(TR $(TD this > rhs) $(TD > 0))
|
|
)
|
|
+/
|
|
template CmpTimeUnits(string lhs, string rhs)
|
|
if(validTimeUnits(lhs, rhs))
|
|
{
|
|
enum CmpTimeUnits = cmpTimeUnitsCTFE(lhs, rhs);
|
|
}
|
|
|
|
|
|
/+
|
|
Helper function for $(D CmpTimeUnits).
|
|
+/
|
|
private int cmpTimeUnitsCTFE(string lhs, string rhs)
|
|
{
|
|
auto tstrings = timeStrings.dup;
|
|
immutable indexOfLHS = std.algorithm.countUntil(tstrings, lhs);
|
|
immutable indexOfRHS = std.algorithm.countUntil(tstrings, rhs);
|
|
|
|
if(indexOfLHS < indexOfRHS)
|
|
return -1;
|
|
if(indexOfLHS > indexOfRHS)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static string genTest(size_t index)
|
|
{
|
|
auto currUnits = timeStrings[index];
|
|
auto test = `_assertPred!"=="(CmpTimeUnits!("` ~ currUnits ~ `", "` ~ currUnits ~ `"), 0); `;
|
|
|
|
//For some reason, $ won't compile.
|
|
foreach(units; timeStrings[index + 1 .. timeStrings.length])
|
|
test ~= `_assertPred!"=="(CmpTimeUnits!("` ~ currUnits ~ `", "` ~ units ~ `"), -1); `;
|
|
|
|
foreach(units; timeStrings[0 .. index])
|
|
test ~= `_assertPred!"=="(CmpTimeUnits!("` ~ currUnits ~ `", "` ~ units ~ `"), 1); `;
|
|
|
|
return test;
|
|
}
|
|
|
|
mixin(genTest(0));
|
|
mixin(genTest(1));
|
|
mixin(genTest(2));
|
|
mixin(genTest(3));
|
|
mixin(genTest(4));
|
|
mixin(genTest(5));
|
|
mixin(genTest(6));
|
|
mixin(genTest(7));
|
|
mixin(genTest(8));
|
|
mixin(genTest(9));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns whether the given value is valid for the given unit type when in a
|
|
time point. Naturally, a duration is not held to a particular range, but
|
|
the values in a time point are (e.g. a month must be in the range of
|
|
1 - 12 inclusive).
|
|
|
|
Params:
|
|
units = The units of time to validate.
|
|
value = The number to validate.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(valid!"hours"(12));
|
|
assert(!valid!"hours"(32));
|
|
assert(valid!"months"(12));
|
|
assert(!valid!"months"(13));
|
|
--------------------
|
|
+/
|
|
bool valid(string units)(int value) pure nothrow
|
|
if(units == "months" ||
|
|
units == "hours" ||
|
|
units == "minutes" ||
|
|
units == "seconds")
|
|
{
|
|
static if(units == "months")
|
|
return value >= Month.jan && value <= Month.dec;
|
|
else static if(units == "hours")
|
|
return value >= 0 && value <= TimeOfDay.maxHour;
|
|
else static if(units == "minutes")
|
|
return value >= 0 && value <= TimeOfDay.maxMinute;
|
|
else static if(units == "seconds")
|
|
return value >= 0 && value <= TimeOfDay.maxSecond;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Verify Examples.
|
|
assert(valid!"hours"(12));
|
|
assert(!valid!"hours"(32));
|
|
assert(valid!"months"(12));
|
|
assert(!valid!"months"(13));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns whether the given day is valid for the given year and month.
|
|
|
|
Params:
|
|
units = The units of time to validate.
|
|
year = The year of the day to validate.
|
|
month = The month of the day to validate.
|
|
day = The day to validate.
|
|
+/
|
|
bool valid(string units)(int year, int month, int day) pure nothrow
|
|
if(units == "days")
|
|
{
|
|
return day > 0 && day <= maxDay(year, month);
|
|
}
|
|
|
|
|
|
/++
|
|
Params:
|
|
units = The units of time to validate.
|
|
value = The number to validate.
|
|
file = The file that the $(D DateTimeException) will list if thrown.
|
|
line = The line number that the $(D DateTimeException) will list if
|
|
thrown.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if $(D valid!units(value)) is false.
|
|
+/
|
|
void enforceValid(string units)(int value, string file = __FILE__, size_t line = __LINE__) pure
|
|
if(units == "months" ||
|
|
units == "hours" ||
|
|
units == "minutes" ||
|
|
units == "seconds")
|
|
{
|
|
static if(units == "months")
|
|
{
|
|
if(!valid!units(value))
|
|
throw new DateTimeException(numToString(value) ~ " is not a valid month of the year.", file, line);
|
|
}
|
|
else static if(units == "hours")
|
|
{
|
|
if(!valid!units(value))
|
|
throw new DateTimeException(numToString(value) ~ " is not a valid hour of the day.", file, line);
|
|
}
|
|
else static if(units == "minutes")
|
|
{
|
|
if(!valid!units(value))
|
|
throw new DateTimeException(numToString(value) ~ " is not a valid minute of an hour.", file, line);
|
|
}
|
|
else static if(units == "seconds")
|
|
{
|
|
if(!valid!units(value))
|
|
throw new DateTimeException(numToString(value) ~ " is not a valid second of a minute.", file, line);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Params:
|
|
units = The units of time to validate.
|
|
year = The year of the day to validate.
|
|
month = The month of the day to validate.
|
|
day = The day to validate.
|
|
file = The file that the $(D DateTimeException) will list if thrown.
|
|
line = The line number that the $(D DateTimeException) will list if
|
|
thrown.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if $(D valid!"days"(year, month, day)) is false.
|
|
+/
|
|
void enforceValid(string units)(int year, Month month, int day, string file = __FILE__, size_t line = __LINE__) pure
|
|
if(units == "days")
|
|
{
|
|
if(!valid!"days"(year, month, day))
|
|
{
|
|
throw new DateTimeException(numToString(day) ~
|
|
" is not a valid day in " ~
|
|
monthToString(month) ~
|
|
" in " ~
|
|
numToString(year), file, line);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the number of months from the current months of the year to the
|
|
given month of the year. If they are the same, then the result is 0.
|
|
|
|
Params:
|
|
currMonth = The current month of the year.
|
|
month = The month of the year to get the number of months to.
|
|
+/
|
|
static int monthsToMonth(int currMonth, int month) pure
|
|
{
|
|
enforceValid!"months"(currMonth);
|
|
enforceValid!"months"(month);
|
|
|
|
if(currMonth == month)
|
|
return 0;
|
|
|
|
if(currMonth < month)
|
|
return month - currMonth;
|
|
|
|
return (Month.dec - currMonth) + month;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(monthsToMonth(Month.jan, Month.jan), 0);
|
|
_assertPred!"=="(monthsToMonth(Month.jan, Month.feb), 1);
|
|
_assertPred!"=="(monthsToMonth(Month.jan, Month.mar), 2);
|
|
_assertPred!"=="(monthsToMonth(Month.jan, Month.apr), 3);
|
|
_assertPred!"=="(monthsToMonth(Month.jan, Month.may), 4);
|
|
_assertPred!"=="(monthsToMonth(Month.jan, Month.jun), 5);
|
|
_assertPred!"=="(monthsToMonth(Month.jan, Month.jul), 6);
|
|
_assertPred!"=="(monthsToMonth(Month.jan, Month.aug), 7);
|
|
_assertPred!"=="(monthsToMonth(Month.jan, Month.sep), 8);
|
|
_assertPred!"=="(monthsToMonth(Month.jan, Month.oct), 9);
|
|
_assertPred!"=="(monthsToMonth(Month.jan, Month.nov), 10);
|
|
_assertPred!"=="(monthsToMonth(Month.jan, Month.dec), 11);
|
|
|
|
_assertPred!"=="(monthsToMonth(Month.may, Month.jan), 8);
|
|
_assertPred!"=="(monthsToMonth(Month.may, Month.feb), 9);
|
|
_assertPred!"=="(monthsToMonth(Month.may, Month.mar), 10);
|
|
_assertPred!"=="(monthsToMonth(Month.may, Month.apr), 11);
|
|
_assertPred!"=="(monthsToMonth(Month.may, Month.may), 0);
|
|
_assertPred!"=="(monthsToMonth(Month.may, Month.jun), 1);
|
|
_assertPred!"=="(monthsToMonth(Month.may, Month.jul), 2);
|
|
_assertPred!"=="(monthsToMonth(Month.may, Month.aug), 3);
|
|
_assertPred!"=="(monthsToMonth(Month.may, Month.sep), 4);
|
|
_assertPred!"=="(monthsToMonth(Month.may, Month.oct), 5);
|
|
_assertPred!"=="(monthsToMonth(Month.may, Month.nov), 6);
|
|
_assertPred!"=="(monthsToMonth(Month.may, Month.dec), 7);
|
|
|
|
_assertPred!"=="(monthsToMonth(Month.oct, Month.jan), 3);
|
|
_assertPred!"=="(monthsToMonth(Month.oct, Month.feb), 4);
|
|
_assertPred!"=="(monthsToMonth(Month.oct, Month.mar), 5);
|
|
_assertPred!"=="(monthsToMonth(Month.oct, Month.apr), 6);
|
|
_assertPred!"=="(monthsToMonth(Month.oct, Month.may), 7);
|
|
_assertPred!"=="(monthsToMonth(Month.oct, Month.jun), 8);
|
|
_assertPred!"=="(monthsToMonth(Month.oct, Month.jul), 9);
|
|
_assertPred!"=="(monthsToMonth(Month.oct, Month.aug), 10);
|
|
_assertPred!"=="(monthsToMonth(Month.oct, Month.sep), 11);
|
|
_assertPred!"=="(monthsToMonth(Month.oct, Month.oct), 0);
|
|
_assertPred!"=="(monthsToMonth(Month.oct, Month.nov), 1);
|
|
_assertPred!"=="(monthsToMonth(Month.oct, Month.dec), 2);
|
|
|
|
_assertPred!"=="(monthsToMonth(Month.dec, Month.jan), 1);
|
|
_assertPred!"=="(monthsToMonth(Month.dec, Month.feb), 2);
|
|
_assertPred!"=="(monthsToMonth(Month.dec, Month.mar), 3);
|
|
_assertPred!"=="(monthsToMonth(Month.dec, Month.apr), 4);
|
|
_assertPred!"=="(monthsToMonth(Month.dec, Month.may), 5);
|
|
_assertPred!"=="(monthsToMonth(Month.dec, Month.jun), 6);
|
|
_assertPred!"=="(monthsToMonth(Month.dec, Month.jul), 7);
|
|
_assertPred!"=="(monthsToMonth(Month.dec, Month.aug), 8);
|
|
_assertPred!"=="(monthsToMonth(Month.dec, Month.sep), 9);
|
|
_assertPred!"=="(monthsToMonth(Month.dec, Month.oct), 10);
|
|
_assertPred!"=="(monthsToMonth(Month.dec, Month.nov), 11);
|
|
_assertPred!"=="(monthsToMonth(Month.dec, Month.dec), 0);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns the number of days from the current day of the week to the given
|
|
day of the week. If they are the same, then the result is 0.
|
|
|
|
Params:
|
|
currDoW = The current day of the week.
|
|
dow = The day of the week to get the number of days to.
|
|
+/
|
|
static int daysToDayOfWeek(DayOfWeek currDoW, DayOfWeek dow) pure nothrow
|
|
{
|
|
if(currDoW == dow)
|
|
return 0;
|
|
|
|
if(currDoW < dow)
|
|
return dow - currDoW;
|
|
|
|
return (DayOfWeek.sat - currDoW) + dow + 1;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.sun, DayOfWeek.sun), 0);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.sun, DayOfWeek.mon), 1);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.sun, DayOfWeek.tue), 2);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.sun, DayOfWeek.wed), 3);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.sun, DayOfWeek.thu), 4);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.sun, DayOfWeek.fri), 5);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.sun, DayOfWeek.sat), 6);
|
|
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.sun), 6);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.mon), 0);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.tue), 1);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.wed), 2);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.thu), 3);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.fri), 4);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.sat), 5);
|
|
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.tue, DayOfWeek.sun), 5);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.tue, DayOfWeek.mon), 6);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.tue, DayOfWeek.tue), 0);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.tue, DayOfWeek.wed), 1);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.tue, DayOfWeek.thu), 2);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.tue, DayOfWeek.fri), 3);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.tue, DayOfWeek.sat), 4);
|
|
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.wed, DayOfWeek.sun), 4);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.wed, DayOfWeek.mon), 5);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.wed, DayOfWeek.tue), 6);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.wed, DayOfWeek.wed), 0);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.wed, DayOfWeek.thu), 1);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.wed, DayOfWeek.fri), 2);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.wed, DayOfWeek.sat), 3);
|
|
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.thu, DayOfWeek.sun), 3);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.thu, DayOfWeek.mon), 4);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.thu, DayOfWeek.tue), 5);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.thu, DayOfWeek.wed), 6);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.thu, DayOfWeek.thu), 0);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.thu, DayOfWeek.fri), 1);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.thu, DayOfWeek.sat), 2);
|
|
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.fri, DayOfWeek.sun), 2);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.fri, DayOfWeek.mon), 3);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.fri, DayOfWeek.tue), 4);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.fri, DayOfWeek.wed), 5);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.fri, DayOfWeek.thu), 6);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.fri, DayOfWeek.fri), 0);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.fri, DayOfWeek.sat), 1);
|
|
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.sat, DayOfWeek.sun), 1);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.sat, DayOfWeek.mon), 2);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.sat, DayOfWeek.tue), 3);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.sat, DayOfWeek.wed), 4);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.sat, DayOfWeek.thu), 5);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.sat, DayOfWeek.fri), 6);
|
|
_assertPred!"=="(daysToDayOfWeek(DayOfWeek.sat, DayOfWeek.sat), 0);
|
|
}
|
|
}
|
|
|
|
|
|
version(StdDdoc)
|
|
{
|
|
/++
|
|
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
|
|
$(CXREF TickDuration).
|
|
|
|
Examples:
|
|
--------------------
|
|
writeln("benchmark start!");
|
|
{
|
|
auto mt = measureTime!((a){assert(a.seconds);});
|
|
doSomething();
|
|
}
|
|
writeln("benchmark end!");
|
|
--------------------
|
|
+/
|
|
auto measureTime(alias func)();
|
|
}
|
|
else
|
|
{
|
|
@safe auto measureTime(alias func)()
|
|
if(isSafe!func)
|
|
{
|
|
struct Result
|
|
{
|
|
private StopWatch _sw = void;
|
|
this(AutoStart as)
|
|
{
|
|
_sw = StopWatch(as);
|
|
}
|
|
~this()
|
|
{
|
|
unaryFun!(func)(_sw.peek());
|
|
}
|
|
}
|
|
return Result(AutoStart.yes);
|
|
}
|
|
|
|
auto measureTime(alias func)()
|
|
if(!isSafe!func)
|
|
{
|
|
struct Result
|
|
{
|
|
private StopWatch _sw = void;
|
|
this(AutoStart as)
|
|
{
|
|
_sw = StopWatch(as);
|
|
}
|
|
~this()
|
|
{
|
|
unaryFun!(func)(_sw.peek());
|
|
}
|
|
}
|
|
return Result(AutoStart.yes);
|
|
}
|
|
}
|
|
|
|
version(testStdDateTime) @safe unittest
|
|
{
|
|
@safe static void func(TickDuration td)
|
|
{
|
|
assert(td.to!("seconds", real) <>= 0);
|
|
}
|
|
|
|
auto mt = measureTime!(func)();
|
|
|
|
/+
|
|
with (measureTime!((a){assert(a.seconds);}))
|
|
{
|
|
// doSomething();
|
|
// @@@BUG@@@ doesn't work yet.
|
|
}
|
|
+/
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
static void func(TickDuration td)
|
|
{
|
|
assert(td.to!("seconds", real) <>= 0);
|
|
}
|
|
|
|
auto mt = measureTime!(func)();
|
|
|
|
/+
|
|
with (measureTime!((a){assert(a.seconds);}))
|
|
{
|
|
// doSomething();
|
|
// @@@BUG@@@ doesn't work yet.
|
|
}
|
|
+/
|
|
}
|
|
|
|
//==============================================================================
|
|
// Private Section.
|
|
//==============================================================================
|
|
private:
|
|
|
|
//==============================================================================
|
|
// Section with private enums and constants.
|
|
//==============================================================================
|
|
|
|
enum daysInYear = 365; /// The number of days in a non-leap year.
|
|
enum daysInLeapYear = 366; /// The numbef or days in a leap year.
|
|
enum daysIn4Years = daysInYear * 3 + daysInLeapYear; /// Number of days in 4 years.
|
|
enum daysIn100Years = daysIn4Years * 25 - 1; /// The number of days in 100 years.
|
|
enum daysIn400Years = daysIn100Years * 4 + 1; /// The number of days in 400 years.
|
|
|
|
|
|
//==============================================================================
|
|
// Section with private helper functions and templates.
|
|
//==============================================================================
|
|
|
|
/+
|
|
Template to help with converting between time units.
|
|
+/
|
|
template hnsecsPer(string units)
|
|
if(CmpTimeUnits!(units, "months") < 0)
|
|
{
|
|
static if(units == "hnsecs")
|
|
enum hnsecsPer = 1L;
|
|
else static if(units == "usecs")
|
|
enum hnsecsPer = 10L;
|
|
else static if(units == "msecs")
|
|
enum hnsecsPer = 1000 * hnsecsPer!"usecs";
|
|
else static if(units == "seconds")
|
|
enum hnsecsPer = 1000 * hnsecsPer!"msecs";
|
|
else static if(units == "minutes")
|
|
enum hnsecsPer = 60 * hnsecsPer!"seconds";
|
|
else static if(units == "hours")
|
|
enum hnsecsPer = 60 * hnsecsPer!"minutes";
|
|
else static if(units == "days")
|
|
enum hnsecsPer = 24 * hnsecsPer!"hours";
|
|
else static if(units == "weeks")
|
|
enum hnsecsPer = 7 * hnsecsPer!"days";
|
|
}
|
|
|
|
|
|
/+
|
|
Splits out a particular unit from hnsecs and gives you the value for that
|
|
unit and the remaining hnsecs. It really shouldn't be used unless unless
|
|
all units larger than the given units have already been split out.
|
|
|
|
Params:
|
|
units = The units to split out.
|
|
hnsecs = The current total hnsecs. Upon returning, it is the hnsecs left
|
|
after splitting out the given units.
|
|
|
|
Returns:
|
|
The number of the given units from converting hnsecs to those units.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto hnsecs = 2595000000007L;
|
|
immutable days = splitUnitsFromHNSecs!"days"(hnsecs);
|
|
assert(days == 3);
|
|
assert(hnsecs == 3000000007);
|
|
|
|
immutable minutes = splitUnitsFromHNSecs!"minutes"(hnsecs);
|
|
assert(minutes == 5);
|
|
assert(hnsecs == 7);
|
|
--------------------
|
|
+/
|
|
long splitUnitsFromHNSecs(string units)(ref long hnsecs) pure nothrow
|
|
if(validTimeUnits(units) &&
|
|
CmpTimeUnits!(units, "months") < 0)
|
|
{
|
|
immutable value = convert!("hnsecs", units)(hnsecs);
|
|
hnsecs -= convert!(units, "hnsecs")(value);
|
|
|
|
return value;
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Verify Example.
|
|
auto hnsecs = 2595000000007L;
|
|
immutable days = splitUnitsFromHNSecs!"days"(hnsecs);
|
|
assert(days == 3);
|
|
assert(hnsecs == 3000000007);
|
|
|
|
immutable minutes = splitUnitsFromHNSecs!"minutes"(hnsecs);
|
|
assert(minutes == 5);
|
|
assert(hnsecs == 7);
|
|
}
|
|
}
|
|
|
|
|
|
/+
|
|
This function is used to split out the units without getting the remaining
|
|
hnsecs.
|
|
|
|
See_Also:
|
|
splitUnitsFromHNSecs()
|
|
|
|
Params:
|
|
units = The units to split out.
|
|
hnsecs = The current total hnsecs.
|
|
|
|
Returns:
|
|
The split out value.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto hnsecs = 2595000000007L;
|
|
immutable days = getUnitsFromHNSecs!"days"(hnsecs);
|
|
assert(days == 3);
|
|
assert(hnsecs == 2595000000007L);
|
|
--------------------
|
|
+/
|
|
long getUnitsFromHNSecs(string units)(long hnsecs) pure nothrow
|
|
if(validTimeUnits(units) &&
|
|
CmpTimeUnits!(units, "months") < 0)
|
|
{
|
|
return convert!("hnsecs", units)(hnsecs);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Verify Example.
|
|
auto hnsecs = 2595000000007L;
|
|
immutable days = getUnitsFromHNSecs!"days"(hnsecs);
|
|
assert(days == 3);
|
|
assert(hnsecs == 2595000000007L);
|
|
}
|
|
}
|
|
|
|
|
|
/+
|
|
This function is used to split out the units without getting the units but
|
|
just the remaining hnsecs.
|
|
|
|
See_Also:
|
|
splitUnitsFromHNSecs()
|
|
|
|
Params:
|
|
units = The units to split out.
|
|
hnsecs = The current total hnsecs.
|
|
|
|
Returns:
|
|
The remaining hnsecs.
|
|
|
|
Examples:
|
|
--------------------
|
|
auto hnsecs = 2595000000007L;
|
|
auto returned = removeUnitsFromHNSecs!"days"(hnsecs);
|
|
assert(returned == 3000000007);
|
|
assert(hnsecs == 2595000000007L);
|
|
--------------------
|
|
+/
|
|
long removeUnitsFromHNSecs(string units)(long hnsecs) pure nothrow
|
|
if(validTimeUnits(units) &&
|
|
CmpTimeUnits!(units, "months") < 0)
|
|
{
|
|
immutable value = convert!("hnsecs", units)(hnsecs);
|
|
|
|
return hnsecs - convert!(units, "hnsecs")(value);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Verify Example.
|
|
auto hnsecs = 2595000000007L;
|
|
auto returned = removeUnitsFromHNSecs!"days"(hnsecs);
|
|
assert(returned == 3000000007);
|
|
assert(hnsecs == 2595000000007L);
|
|
}
|
|
}
|
|
|
|
|
|
/+
|
|
The maximum valid Day in the given month in the given year.
|
|
|
|
Params:
|
|
year = The year to get the day for.
|
|
month = The month of the Gregorian Calendar to get the day for.
|
|
+/
|
|
static ubyte maxDay(int year, int month) pure nothrow
|
|
in
|
|
{
|
|
assert(valid!"months"(month));
|
|
}
|
|
body
|
|
{
|
|
switch(month)
|
|
{
|
|
case Month.jan, Month.mar, Month.may, Month.jul, Month.aug, Month.oct, Month.dec:
|
|
return 31;
|
|
case Month.feb:
|
|
return yearIsLeapYear(year) ? 29 : 28;
|
|
case Month.apr, Month.jun, Month.sep, Month.nov:
|
|
return 30;
|
|
default:
|
|
assert(0, "Invalid month.");
|
|
}
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
_assertPred!"=="(maxDay(1999, 1), 31);
|
|
_assertPred!"=="(maxDay(1999, 2), 28);
|
|
_assertPred!"=="(maxDay(1999, 3), 31);
|
|
_assertPred!"=="(maxDay(1999, 4), 30);
|
|
_assertPred!"=="(maxDay(1999, 5), 31);
|
|
_assertPred!"=="(maxDay(1999, 6), 30);
|
|
_assertPred!"=="(maxDay(1999, 7), 31);
|
|
_assertPred!"=="(maxDay(1999, 8), 31);
|
|
_assertPred!"=="(maxDay(1999, 9), 30);
|
|
_assertPred!"=="(maxDay(1999, 10), 31);
|
|
_assertPred!"=="(maxDay(1999, 11), 30);
|
|
_assertPred!"=="(maxDay(1999, 12), 31);
|
|
|
|
_assertPred!"=="(maxDay(2000, 1), 31);
|
|
_assertPred!"=="(maxDay(2000, 2), 29);
|
|
_assertPred!"=="(maxDay(2000, 3), 31);
|
|
_assertPred!"=="(maxDay(2000, 4), 30);
|
|
_assertPred!"=="(maxDay(2000, 5), 31);
|
|
_assertPred!"=="(maxDay(2000, 6), 30);
|
|
_assertPred!"=="(maxDay(2000, 7), 31);
|
|
_assertPred!"=="(maxDay(2000, 8), 31);
|
|
_assertPred!"=="(maxDay(2000, 9), 30);
|
|
_assertPred!"=="(maxDay(2000, 10), 31);
|
|
_assertPred!"=="(maxDay(2000, 11), 30);
|
|
_assertPred!"=="(maxDay(2000, 12), 31);
|
|
|
|
//Test B.C.
|
|
_assertPred!"=="(maxDay(-1999, 1), 31);
|
|
_assertPred!"=="(maxDay(-1999, 2), 28);
|
|
_assertPred!"=="(maxDay(-1999, 3), 31);
|
|
_assertPred!"=="(maxDay(-1999, 4), 30);
|
|
_assertPred!"=="(maxDay(-1999, 5), 31);
|
|
_assertPred!"=="(maxDay(-1999, 6), 30);
|
|
_assertPred!"=="(maxDay(-1999, 7), 31);
|
|
_assertPred!"=="(maxDay(-1999, 8), 31);
|
|
_assertPred!"=="(maxDay(-1999, 9), 30);
|
|
_assertPred!"=="(maxDay(-1999, 10), 31);
|
|
_assertPred!"=="(maxDay(-1999, 11), 30);
|
|
_assertPred!"=="(maxDay(-1999, 12), 31);
|
|
|
|
_assertPred!"=="(maxDay(-2000, 1), 31);
|
|
_assertPred!"=="(maxDay(-2000, 2), 29);
|
|
_assertPred!"=="(maxDay(-2000, 3), 31);
|
|
_assertPred!"=="(maxDay(-2000, 4), 30);
|
|
_assertPred!"=="(maxDay(-2000, 5), 31);
|
|
_assertPred!"=="(maxDay(-2000, 6), 30);
|
|
_assertPred!"=="(maxDay(-2000, 7), 31);
|
|
_assertPred!"=="(maxDay(-2000, 8), 31);
|
|
_assertPred!"=="(maxDay(-2000, 9), 30);
|
|
_assertPred!"=="(maxDay(-2000, 10), 31);
|
|
_assertPred!"=="(maxDay(-2000, 11), 30);
|
|
_assertPred!"=="(maxDay(-2000, 12), 31);
|
|
}
|
|
}
|
|
|
|
|
|
/+
|
|
Returns the day of the week for the given day of the Gregorian Calendar.
|
|
|
|
Params:
|
|
day = The day of the Gregorian Calendar for which to get the day of
|
|
the week.
|
|
+/
|
|
DayOfWeek getDayOfWeek(int day) pure nothrow
|
|
{
|
|
//January 1st, 1 A.D. was a Monday
|
|
if(day >= 0)
|
|
return cast(DayOfWeek)(day % 7);
|
|
else
|
|
{
|
|
immutable dow = cast(DayOfWeek)((day % 7) + 7);
|
|
|
|
if(dow == 7)
|
|
return DayOfWeek.sun;
|
|
else
|
|
return dow;
|
|
}
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
//Test A.D.
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(1, 1, 1)).dayOfGregorianCal), DayOfWeek.mon);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(1, 1, 2)).dayOfGregorianCal), DayOfWeek.tue);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(1, 1, 3)).dayOfGregorianCal), DayOfWeek.wed);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(1, 1, 4)).dayOfGregorianCal), DayOfWeek.thu);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(1, 1, 5)).dayOfGregorianCal), DayOfWeek.fri);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(1, 1, 6)).dayOfGregorianCal), DayOfWeek.sat);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(1, 1, 7)).dayOfGregorianCal), DayOfWeek.sun);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(1, 1, 8)).dayOfGregorianCal), DayOfWeek.mon);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(1, 1, 9)).dayOfGregorianCal), DayOfWeek.tue);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(2, 1, 1)).dayOfGregorianCal), DayOfWeek.tue);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(3, 1, 1)).dayOfGregorianCal), DayOfWeek.wed);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(4, 1, 1)).dayOfGregorianCal), DayOfWeek.thu);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(5, 1, 1)).dayOfGregorianCal), DayOfWeek.sat);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(2000, 1, 1)).dayOfGregorianCal), DayOfWeek.sat);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(2010, 8, 22)).dayOfGregorianCal), DayOfWeek.sun);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(2010, 8, 23)).dayOfGregorianCal), DayOfWeek.mon);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(2010, 8, 24)).dayOfGregorianCal), DayOfWeek.tue);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(2010, 8, 25)).dayOfGregorianCal), DayOfWeek.wed);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(2010, 8, 26)).dayOfGregorianCal), DayOfWeek.thu);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(2010, 8, 27)).dayOfGregorianCal), DayOfWeek.fri);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(2010, 8, 28)).dayOfGregorianCal), DayOfWeek.sat);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(2010, 8, 29)).dayOfGregorianCal), DayOfWeek.sun);
|
|
|
|
//Test B.C.
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(0, 12, 31)).dayOfGregorianCal), DayOfWeek.sun);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(0, 12, 30)).dayOfGregorianCal), DayOfWeek.sat);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(0, 12, 29)).dayOfGregorianCal), DayOfWeek.fri);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(0, 12, 28)).dayOfGregorianCal), DayOfWeek.thu);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(0, 12, 27)).dayOfGregorianCal), DayOfWeek.wed);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(0, 12, 26)).dayOfGregorianCal), DayOfWeek.tue);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(0, 12, 25)).dayOfGregorianCal), DayOfWeek.mon);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(0, 12, 24)).dayOfGregorianCal), DayOfWeek.sun);
|
|
_assertPred!"=="(getDayOfWeek(SysTime(Date(0, 12, 23)).dayOfGregorianCal), DayOfWeek.sat);
|
|
}
|
|
}
|
|
|
|
|
|
/+
|
|
Returns the string representation of the given month.
|
|
|
|
Params:
|
|
useLongName = Whether the long or short version of the month name should
|
|
be used.
|
|
plural = Whether the string should be plural or not.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given month is not a valid month.
|
|
+/
|
|
string monthToString(Month month, bool useLongName = true) pure
|
|
{
|
|
if(useLongName == true)
|
|
{
|
|
switch(month)
|
|
{
|
|
case Month.jan:
|
|
return "January";
|
|
case Month.feb:
|
|
return "February";
|
|
case Month.mar:
|
|
return "March";
|
|
case Month.apr:
|
|
return "April";
|
|
case Month.may:
|
|
return "May";
|
|
case Month.jun:
|
|
return "June";
|
|
case Month.jul:
|
|
return "July";
|
|
case Month.aug:
|
|
return "August";
|
|
case Month.sep:
|
|
return "September";
|
|
case Month.oct:
|
|
return "October";
|
|
case Month.nov:
|
|
return "November";
|
|
case Month.dec:
|
|
return "December";
|
|
default:
|
|
throw new DateTimeException("Invalid month: " ~ numToString(month));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch(month)
|
|
{
|
|
case Month.jan:
|
|
return "Jan";
|
|
case Month.feb:
|
|
return "Feb";
|
|
case Month.mar:
|
|
return "Mar";
|
|
case Month.apr:
|
|
return "Apr";
|
|
case Month.may:
|
|
return "May";
|
|
case Month.jun:
|
|
return "Jun";
|
|
case Month.jul:
|
|
return "Jul";
|
|
case Month.aug:
|
|
return "Aug";
|
|
case Month.sep:
|
|
return "Sep";
|
|
case Month.oct:
|
|
return "Oct";
|
|
case Month.nov:
|
|
return "Nov";
|
|
case Month.dec:
|
|
return "Dec";
|
|
default:
|
|
throw new DateTimeException("Invalid month: " ~ numToString(month));
|
|
}
|
|
}
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static void testMTSInvalid(Month month, bool useLongName)
|
|
{
|
|
monthToString(month, useLongName);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testMTSInvalid(cast(Month)0, true));
|
|
assertThrown!DateTimeException(testMTSInvalid(cast(Month)0, false));
|
|
assertThrown!DateTimeException(testMTSInvalid(cast(Month)13, true));
|
|
assertThrown!DateTimeException(testMTSInvalid(cast(Month)13, false));
|
|
|
|
_assertPred!"=="(monthToString(Month.jan), "January");
|
|
_assertPred!"=="(monthToString(Month.feb), "February");
|
|
_assertPred!"=="(monthToString(Month.mar), "March");
|
|
_assertPred!"=="(monthToString(Month.apr), "April");
|
|
_assertPred!"=="(monthToString(Month.may), "May");
|
|
_assertPred!"=="(monthToString(Month.jun), "June");
|
|
_assertPred!"=="(monthToString(Month.jul), "July");
|
|
_assertPred!"=="(monthToString(Month.aug), "August");
|
|
_assertPred!"=="(monthToString(Month.sep), "September");
|
|
_assertPred!"=="(monthToString(Month.oct), "October");
|
|
_assertPred!"=="(monthToString(Month.nov), "November");
|
|
_assertPred!"=="(monthToString(Month.dec), "December");
|
|
|
|
_assertPred!"=="(monthToString(Month.jan, false), "Jan");
|
|
_assertPred!"=="(monthToString(Month.feb, false), "Feb");
|
|
_assertPred!"=="(monthToString(Month.mar, false), "Mar");
|
|
_assertPred!"=="(monthToString(Month.apr, false), "Apr");
|
|
_assertPred!"=="(monthToString(Month.may, false), "May");
|
|
_assertPred!"=="(monthToString(Month.jun, false), "Jun");
|
|
_assertPred!"=="(monthToString(Month.jul, false), "Jul");
|
|
_assertPred!"=="(monthToString(Month.aug, false), "Aug");
|
|
_assertPred!"=="(monthToString(Month.sep, false), "Sep");
|
|
_assertPred!"=="(monthToString(Month.oct, false), "Oct");
|
|
_assertPred!"=="(monthToString(Month.nov, false), "Nov");
|
|
_assertPred!"=="(monthToString(Month.dec, false), "Dec");
|
|
}
|
|
}
|
|
|
|
|
|
/+
|
|
Returns the Month corresponding to the given string. Casing is ignored.
|
|
|
|
Params:
|
|
monthStr = The string representation of the month to get the Month for.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given month is not a valid month string.
|
|
+/
|
|
Month monthFromString(string monthStr)
|
|
{
|
|
switch(toLower(monthStr))
|
|
{
|
|
case "january":
|
|
case "jan":
|
|
return Month.jan;
|
|
case "february":
|
|
case "feb":
|
|
return Month.feb;
|
|
case "march":
|
|
case "mar":
|
|
return Month.mar;
|
|
case "april":
|
|
case "apr":
|
|
return Month.apr;
|
|
case "may":
|
|
return Month.may;
|
|
case "june":
|
|
case "jun":
|
|
return Month.jun;
|
|
case "july":
|
|
case "jul":
|
|
return Month.jul;
|
|
case "august":
|
|
case "aug":
|
|
return Month.aug;
|
|
case "september":
|
|
case "sep":
|
|
return Month.sep;
|
|
case "october":
|
|
case "oct":
|
|
return Month.oct;
|
|
case "november":
|
|
case "nov":
|
|
return Month.nov;
|
|
case "december":
|
|
case "dec":
|
|
return Month.dec;
|
|
default:
|
|
throw new DateTimeException(format("Invalid month %s", monthStr));
|
|
}
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static void testMFSInvalid(string monthStr)
|
|
{
|
|
monthFromString(monthStr);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testMFSInvalid("Ja"));
|
|
assertThrown!DateTimeException(testMFSInvalid("Janu"));
|
|
assertThrown!DateTimeException(testMFSInvalid("Januar"));
|
|
assertThrown!DateTimeException(testMFSInvalid("Januarys"));
|
|
assertThrown!DateTimeException(testMFSInvalid("JJanuary"));
|
|
|
|
_assertPred!"=="(monthFromString(monthToString(Month.jan)), Month.jan);
|
|
_assertPred!"=="(monthFromString(monthToString(Month.feb)), Month.feb);
|
|
_assertPred!"=="(monthFromString(monthToString(Month.mar)), Month.mar);
|
|
_assertPred!"=="(monthFromString(monthToString(Month.apr)), Month.apr);
|
|
_assertPred!"=="(monthFromString(monthToString(Month.may)), Month.may);
|
|
_assertPred!"=="(monthFromString(monthToString(Month.jun)), Month.jun);
|
|
_assertPred!"=="(monthFromString(monthToString(Month.jul)), Month.jul);
|
|
_assertPred!"=="(monthFromString(monthToString(Month.aug)), Month.aug);
|
|
_assertPred!"=="(monthFromString(monthToString(Month.sep)), Month.sep);
|
|
_assertPred!"=="(monthFromString(monthToString(Month.oct)), Month.oct);
|
|
_assertPred!"=="(monthFromString(monthToString(Month.nov)), Month.nov);
|
|
_assertPred!"=="(monthFromString(monthToString(Month.dec)), Month.dec);
|
|
|
|
_assertPred!"=="(monthFromString(monthToString(Month.jan, false)), Month.jan);
|
|
_assertPred!"=="(monthFromString(monthToString(Month.feb, false)), Month.feb);
|
|
_assertPred!"=="(monthFromString(monthToString(Month.mar, false)), Month.mar);
|
|
_assertPred!"=="(monthFromString(monthToString(Month.apr, false)), Month.apr);
|
|
_assertPred!"=="(monthFromString(monthToString(Month.may, false)), Month.may);
|
|
_assertPred!"=="(monthFromString(monthToString(Month.jun, false)), Month.jun);
|
|
_assertPred!"=="(monthFromString(monthToString(Month.jul, false)), Month.jul);
|
|
_assertPred!"=="(monthFromString(monthToString(Month.aug, false)), Month.aug);
|
|
_assertPred!"=="(monthFromString(monthToString(Month.sep, false)), Month.sep);
|
|
_assertPred!"=="(monthFromString(monthToString(Month.oct, false)), Month.oct);
|
|
_assertPred!"=="(monthFromString(monthToString(Month.nov, false)), Month.nov);
|
|
_assertPred!"=="(monthFromString(monthToString(Month.dec, false)), Month.dec);
|
|
|
|
_assertPred!"=="(monthFromString("JANUARY"), Month.jan);
|
|
_assertPred!"=="(monthFromString("JAN"), Month.jan);
|
|
_assertPred!"=="(monthFromString("january"), Month.jan);
|
|
_assertPred!"=="(monthFromString("jan"), Month.jan);
|
|
_assertPred!"=="(monthFromString("jaNuary"), Month.jan);
|
|
_assertPred!"=="(monthFromString("jaN"), Month.jan);
|
|
_assertPred!"=="(monthFromString("jaNuaRy"), Month.jan);
|
|
_assertPred!"=="(monthFromString("jAn"), Month.jan);
|
|
}
|
|
}
|
|
|
|
|
|
/+
|
|
The time units which are one step smaller than the given units.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(nextSmallerTimeUnits!"years" == "months");
|
|
assert(nextSmallerTimeUnits!"usecs" == "hnsecs");
|
|
--------------------
|
|
+/
|
|
template nextSmallerTimeUnits(string units)
|
|
if(validTimeUnits(units) &&
|
|
timeStrings.front != units)
|
|
{
|
|
enum nextSmallerTimeUnits = timeStrings[std.algorithm.countUntil(timeStrings.dup, units) - 1];
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(nextSmallerTimeUnits!"months", "weeks");
|
|
_assertPred!"=="(nextSmallerTimeUnits!"weeks", "days");
|
|
_assertPred!"=="(nextSmallerTimeUnits!"days", "hours");
|
|
_assertPred!"=="(nextSmallerTimeUnits!"hours", "minutes");
|
|
_assertPred!"=="(nextSmallerTimeUnits!"minutes", "seconds");
|
|
_assertPred!"=="(nextSmallerTimeUnits!"seconds", "msecs");
|
|
_assertPred!"=="(nextSmallerTimeUnits!"msecs", "usecs");
|
|
|
|
static assert(!__traits(compiles, nextSmallerTimeUnits!"hnsecs"));
|
|
|
|
//Verify Examples.
|
|
assert(nextSmallerTimeUnits!"years" == "months");
|
|
assert(nextSmallerTimeUnits!"usecs" == "hnsecs");
|
|
}
|
|
}
|
|
|
|
|
|
/+
|
|
The time units which are one step larger than the given units.
|
|
|
|
Examples:
|
|
--------------------
|
|
assert(nextLargerTimeUnits!"months" == "years");
|
|
assert(nextLargerTimeUnits!"hnsecs" == "usecs");
|
|
--------------------
|
|
+/
|
|
template nextLargerTimeUnits(string units)
|
|
if(validTimeUnits(units) &&
|
|
timeStrings.back != units)
|
|
{
|
|
enum nextLargerTimeUnits = timeStrings[std.algorithm.countUntil(timeStrings.dup, units) + 1];
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(nextLargerTimeUnits!"usecs", "msecs");
|
|
_assertPred!"=="(nextLargerTimeUnits!"msecs", "seconds");
|
|
_assertPred!"=="(nextLargerTimeUnits!"seconds", "minutes");
|
|
_assertPred!"=="(nextLargerTimeUnits!"minutes", "hours");
|
|
_assertPred!"=="(nextLargerTimeUnits!"hours", "days");
|
|
_assertPred!"=="(nextLargerTimeUnits!"days", "weeks");
|
|
_assertPred!"=="(nextLargerTimeUnits!"weeks", "months");
|
|
|
|
static assert(!__traits(compiles, nextLargerTimeUnits!"years"));
|
|
|
|
//Verify Examples.
|
|
assert(nextLargerTimeUnits!"months" == "years");
|
|
assert(nextLargerTimeUnits!"hnsecs" == "usecs");
|
|
}
|
|
}
|
|
|
|
|
|
/+
|
|
Returns the given hnsecs as an ISO string of fractional seconds.
|
|
+/
|
|
static string fracSecToISOString(int hnsecs) nothrow
|
|
in
|
|
{
|
|
assert(hnsecs >= 0);
|
|
}
|
|
body
|
|
{
|
|
try
|
|
{
|
|
string isoString = format(".%07d", hnsecs);
|
|
|
|
while(isoString.endsWith("0"))
|
|
isoString.popBack();
|
|
|
|
if(isoString.length == 1)
|
|
return "";
|
|
|
|
return isoString;
|
|
}
|
|
catch(Exception e)
|
|
assert(0, "format() threw.");
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
_assertPred!"=="(fracSecToISOString(0), "");
|
|
_assertPred!"=="(fracSecToISOString(1), ".0000001");
|
|
_assertPred!"=="(fracSecToISOString(10), ".000001");
|
|
_assertPred!"=="(fracSecToISOString(100), ".00001");
|
|
_assertPred!"=="(fracSecToISOString(1000), ".0001");
|
|
_assertPred!"=="(fracSecToISOString(10_000), ".001");
|
|
_assertPred!"=="(fracSecToISOString(100_000), ".01");
|
|
_assertPred!"=="(fracSecToISOString(1_000_000), ".1");
|
|
_assertPred!"=="(fracSecToISOString(1_000_001), ".1000001");
|
|
_assertPred!"=="(fracSecToISOString(1_001_001), ".1001001");
|
|
_assertPred!"=="(fracSecToISOString(1_071_601), ".1071601");
|
|
_assertPred!"=="(fracSecToISOString(1_271_641), ".1271641");
|
|
_assertPred!"=="(fracSecToISOString(9_999_999), ".9999999");
|
|
_assertPred!"=="(fracSecToISOString(9_999_990), ".999999");
|
|
_assertPred!"=="(fracSecToISOString(9_999_900), ".99999");
|
|
_assertPred!"=="(fracSecToISOString(9_999_000), ".9999");
|
|
_assertPred!"=="(fracSecToISOString(9_990_000), ".999");
|
|
_assertPred!"=="(fracSecToISOString(9_900_000), ".99");
|
|
_assertPred!"=="(fracSecToISOString(9_000_000), ".9");
|
|
_assertPred!"=="(fracSecToISOString(999), ".0000999");
|
|
_assertPred!"=="(fracSecToISOString(9990), ".000999");
|
|
_assertPred!"=="(fracSecToISOString(99_900), ".00999");
|
|
_assertPred!"=="(fracSecToISOString(999_000), ".0999");
|
|
}
|
|
}
|
|
|
|
|
|
/+
|
|
Returns a FracSec corresponding to to the given ISO string of
|
|
fractional seconds.
|
|
+/
|
|
static FracSec fracSecFromISOString(S)(in S isoString)
|
|
if(isSomeString!S)
|
|
{
|
|
if(isoString.empty)
|
|
return FracSec.from!"hnsecs"(0);
|
|
|
|
auto dstr = to!dstring(isoString);
|
|
|
|
enforce(dstr.startsWith("."), new DateTimeException("Invalid ISO String"));
|
|
dstr.popFront();
|
|
|
|
enforce(!dstr.empty && dstr.length <= 7, new DateTimeException("Invalid ISO String"));
|
|
enforce(!canFind!(not!isDigit)(dstr), new DateTimeException("Invalid ISO String"));
|
|
|
|
dchar[7] fullISOString;
|
|
|
|
foreach(i, ref dchar c; fullISOString)
|
|
{
|
|
if(i < dstr.length)
|
|
c = dstr[i];
|
|
else
|
|
c = '0';
|
|
}
|
|
|
|
return FracSec.from!"hnsecs"(to!int(fullISOString[]));
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static void testFSInvalid(string isoString)
|
|
{
|
|
fracSecFromISOString(isoString);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testFSInvalid("."));
|
|
assertThrown!DateTimeException(testFSInvalid("0."));
|
|
assertThrown!DateTimeException(testFSInvalid("0"));
|
|
assertThrown!DateTimeException(testFSInvalid("0000000"));
|
|
assertThrown!DateTimeException(testFSInvalid(".00000000"));
|
|
assertThrown!DateTimeException(testFSInvalid(".00000001"));
|
|
assertThrown!DateTimeException(testFSInvalid("T"));
|
|
assertThrown!DateTimeException(testFSInvalid("T."));
|
|
assertThrown!DateTimeException(testFSInvalid(".T"));
|
|
|
|
_assertPred!"=="(fracSecFromISOString(""), FracSec.from!"hnsecs"(0));
|
|
_assertPred!"=="(fracSecFromISOString(".0000001"), FracSec.from!"hnsecs"(1));
|
|
_assertPred!"=="(fracSecFromISOString(".000001"), FracSec.from!"hnsecs"(10));
|
|
_assertPred!"=="(fracSecFromISOString(".00001"), FracSec.from!"hnsecs"(100));
|
|
_assertPred!"=="(fracSecFromISOString(".0001"), FracSec.from!"hnsecs"(1000));
|
|
_assertPred!"=="(fracSecFromISOString(".001"), FracSec.from!"hnsecs"(10_000));
|
|
_assertPred!"=="(fracSecFromISOString(".01"), FracSec.from!"hnsecs"(100_000));
|
|
_assertPred!"=="(fracSecFromISOString(".1"), FracSec.from!"hnsecs"(1_000_000));
|
|
_assertPred!"=="(fracSecFromISOString(".1000001"), FracSec.from!"hnsecs"(1_000_001));
|
|
_assertPred!"=="(fracSecFromISOString(".1001001"), FracSec.from!"hnsecs"(1_001_001));
|
|
_assertPred!"=="(fracSecFromISOString(".1071601"), FracSec.from!"hnsecs"(1_071_601));
|
|
_assertPred!"=="(fracSecFromISOString(".1271641"), FracSec.from!"hnsecs"(1_271_641));
|
|
_assertPred!"=="(fracSecFromISOString(".9999999"), FracSec.from!"hnsecs"(9_999_999));
|
|
_assertPred!"=="(fracSecFromISOString(".9999990"), FracSec.from!"hnsecs"(9_999_990));
|
|
_assertPred!"=="(fracSecFromISOString(".999999"), FracSec.from!"hnsecs"(9_999_990));
|
|
_assertPred!"=="(fracSecFromISOString(".9999900"), FracSec.from!"hnsecs"(9_999_900));
|
|
_assertPred!"=="(fracSecFromISOString(".99999"), FracSec.from!"hnsecs"(9_999_900));
|
|
_assertPred!"=="(fracSecFromISOString(".9999000"), FracSec.from!"hnsecs"(9_999_000));
|
|
_assertPred!"=="(fracSecFromISOString(".9999"), FracSec.from!"hnsecs"(9_999_000));
|
|
_assertPred!"=="(fracSecFromISOString(".9990000"), FracSec.from!"hnsecs"(9_990_000));
|
|
_assertPred!"=="(fracSecFromISOString(".999"), FracSec.from!"hnsecs"(9_990_000));
|
|
_assertPred!"=="(fracSecFromISOString(".9900000"), FracSec.from!"hnsecs"(9_900_000));
|
|
_assertPred!"=="(fracSecFromISOString(".9900"), FracSec.from!"hnsecs"(9_900_000));
|
|
_assertPred!"=="(fracSecFromISOString(".99"), FracSec.from!"hnsecs"(9_900_000));
|
|
_assertPred!"=="(fracSecFromISOString(".9000000"), FracSec.from!"hnsecs"(9_000_000));
|
|
_assertPred!"=="(fracSecFromISOString(".9"), FracSec.from!"hnsecs"(9_000_000));
|
|
_assertPred!"=="(fracSecFromISOString(".0000999"), FracSec.from!"hnsecs"(999));
|
|
_assertPred!"=="(fracSecFromISOString(".0009990"), FracSec.from!"hnsecs"(9990));
|
|
_assertPred!"=="(fracSecFromISOString(".000999"), FracSec.from!"hnsecs"(9990));
|
|
_assertPred!"=="(fracSecFromISOString(".0099900"), FracSec.from!"hnsecs"(99_900));
|
|
_assertPred!"=="(fracSecFromISOString(".00999"), FracSec.from!"hnsecs"(99_900));
|
|
_assertPred!"=="(fracSecFromISOString(".0999000"), FracSec.from!"hnsecs"(999_000));
|
|
_assertPred!"=="(fracSecFromISOString(".0999"), FracSec.from!"hnsecs"(999_000));
|
|
}
|
|
}
|
|
|
|
|
|
/+
|
|
Whether the given type defines the static property min which returns the
|
|
minimum value for the type.
|
|
+/
|
|
template hasMin(T)
|
|
{
|
|
enum hasMin = __traits(hasMember, T, "min") &&
|
|
__traits(isStaticFunction, T.min) &&
|
|
is(ReturnType!(T.min) == Unqual!T) &&
|
|
(functionAttributes!(T.min) & FunctionAttribute.PROPERTY) &&
|
|
(functionAttributes!(T.min) & FunctionAttribute.NOTHROW);
|
|
//(functionAttributes!(T.min) & FunctionAttribute.PURE); //Ideally this would be the case, but SysTime's min() can't currently be pure.
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static assert(hasMin!(Date));
|
|
static assert(hasMin!(TimeOfDay));
|
|
static assert(hasMin!(DateTime));
|
|
static assert(hasMin!(SysTime));
|
|
static assert(hasMin!(const Date));
|
|
static assert(hasMin!(const TimeOfDay));
|
|
static assert(hasMin!(const DateTime));
|
|
static assert(hasMin!(const SysTime));
|
|
static assert(hasMin!(immutable Date));
|
|
static assert(hasMin!(immutable TimeOfDay));
|
|
static assert(hasMin!(immutable SysTime));
|
|
}
|
|
}
|
|
|
|
|
|
/+
|
|
Whether the given type defines the static property max which returns the
|
|
maximum value for the type.
|
|
+/
|
|
template hasMax(T)
|
|
{
|
|
enum hasMax = __traits(hasMember, T, "max") &&
|
|
__traits(isStaticFunction, T.max) &&
|
|
is(ReturnType!(T.max) == Unqual!T) &&
|
|
(functionAttributes!(T.max) & FunctionAttribute.PROPERTY) &&
|
|
(functionAttributes!(T.max) & FunctionAttribute.NOTHROW);
|
|
//(functionAttributes!(T.max) & FunctionAttribute.PURE); //Ideally this would be the case, but SysTime's max() can't currently be pure.
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static assert(hasMax!(Date));
|
|
static assert(hasMax!(TimeOfDay));
|
|
static assert(hasMax!(DateTime));
|
|
static assert(hasMax!(SysTime));
|
|
static assert(hasMax!(const Date));
|
|
static assert(hasMax!(const TimeOfDay));
|
|
static assert(hasMax!(const DateTime));
|
|
static assert(hasMax!(const SysTime));
|
|
static assert(hasMax!(immutable Date));
|
|
static assert(hasMax!(immutable TimeOfDay));
|
|
static assert(hasMax!(immutable DateTime));
|
|
static assert(hasMax!(immutable SysTime));
|
|
}
|
|
}
|
|
|
|
|
|
/+
|
|
Whether the given type defines the overloaded opBinary operators that a time
|
|
point is supposed to define which work with time durations. Namely:
|
|
|
|
$(BOOKTABLE,
|
|
$(TR $(TD TimePoint opBinary"+"(duration)))
|
|
$(TR $(TD TimePoint opBinary"-"(duration)))
|
|
)
|
|
+/
|
|
template hasOverloadedOpBinaryWithDuration(T)
|
|
{
|
|
enum hasOverloadedOpBinaryWithDuration = __traits(compiles, T.init + dur!"days"(5)) &&
|
|
is(typeof(T.init + dur!"days"(5)) == Unqual!T) &&
|
|
__traits(compiles, T.init - dur!"days"(5)) &&
|
|
is(typeof(T.init - dur!"days"(5)) == Unqual!T) &&
|
|
__traits(compiles, T.init + TickDuration.from!"hnsecs"(5)) &&
|
|
is(typeof(T.init + TickDuration.from!"hnsecs"(5)) == Unqual!T) &&
|
|
__traits(compiles, T.init - TickDuration.from!"hnsecs"(5)) &&
|
|
is(typeof(T.init - TickDuration.from!"hnsecs"(5)) == Unqual!T);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static assert(hasOverloadedOpBinaryWithDuration!(Date));
|
|
static assert(hasOverloadedOpBinaryWithDuration!(TimeOfDay));
|
|
static assert(hasOverloadedOpBinaryWithDuration!(DateTime));
|
|
static assert(hasOverloadedOpBinaryWithDuration!(SysTime));
|
|
static assert(hasOverloadedOpBinaryWithDuration!(const Date));
|
|
static assert(hasOverloadedOpBinaryWithDuration!(const TimeOfDay));
|
|
static assert(hasOverloadedOpBinaryWithDuration!(const DateTime));
|
|
static assert(hasOverloadedOpBinaryWithDuration!(const SysTime));
|
|
static assert(hasOverloadedOpBinaryWithDuration!(immutable Date));
|
|
static assert(hasOverloadedOpBinaryWithDuration!(immutable TimeOfDay));
|
|
static assert(hasOverloadedOpBinaryWithDuration!(immutable DateTime));
|
|
static assert(hasOverloadedOpBinaryWithDuration!(immutable SysTime));
|
|
}
|
|
}
|
|
|
|
|
|
/+
|
|
Whether the given type defines the overloaded opOpAssign operators that a time point is supposed
|
|
to define. Namely:
|
|
|
|
$(BOOKTABLE,
|
|
$(TR $(TD TimePoint opOpAssign"+"(duration)))
|
|
$(TR $(TD TimePoint opOpAssign"-"(duration)))
|
|
)
|
|
+/
|
|
template hasOverloadedOpAssignWithDuration(T)
|
|
{
|
|
enum hasOverloadedOpAssignWithDuration = __traits(compiles, T.init += dur!"days"(5)) &&
|
|
is(typeof(T.init += dur!"days"(5)) == Unqual!T) &&
|
|
__traits(compiles, T.init -= dur!"days"(5)) &&
|
|
is(typeof(T.init -= dur!"days"(5)) == Unqual!T) &&
|
|
__traits(compiles, T.init += TickDuration.from!"hnsecs"(5)) &&
|
|
is(typeof(T.init += TickDuration.from!"hnsecs"(5)) == Unqual!T) &&
|
|
__traits(compiles, T.init -= TickDuration.from!"hnsecs"(5)) &&
|
|
is(typeof(T.init -= TickDuration.from!"hnsecs"(5)) == Unqual!T);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static assert(hasOverloadedOpAssignWithDuration!(Date));
|
|
static assert(hasOverloadedOpAssignWithDuration!(TimeOfDay));
|
|
static assert(hasOverloadedOpAssignWithDuration!(DateTime));
|
|
static assert(hasOverloadedOpAssignWithDuration!(SysTime));
|
|
static assert(hasOverloadedOpAssignWithDuration!(const Date));
|
|
static assert(hasOverloadedOpAssignWithDuration!(const TimeOfDay));
|
|
static assert(hasOverloadedOpAssignWithDuration!(const DateTime));
|
|
static assert(hasOverloadedOpAssignWithDuration!(const SysTime));
|
|
static assert(hasOverloadedOpAssignWithDuration!(immutable Date));
|
|
static assert(hasOverloadedOpAssignWithDuration!(immutable TimeOfDay));
|
|
static assert(hasOverloadedOpAssignWithDuration!(immutable DateTime));
|
|
static assert(hasOverloadedOpAssignWithDuration!(immutable SysTime));
|
|
}
|
|
}
|
|
|
|
|
|
/+
|
|
Whether the given type defines the overloaded opBinary operator that a time point is supposed
|
|
to define which works with itself. Namely:
|
|
|
|
$(BOOKTABLE,
|
|
$(TR $(TD duration opBinary"-"(Date)))
|
|
)
|
|
+/
|
|
template hasOverloadedOpBinaryWithSelf(T)
|
|
{
|
|
enum hasOverloadedOpBinaryWithSelf = __traits(compiles, T.init - T.init) &&
|
|
is(Unqual!(typeof(T.init - T.init)) == Duration);
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
static assert(hasOverloadedOpBinaryWithSelf!(Date));
|
|
static assert(hasOverloadedOpBinaryWithSelf!(TimeOfDay));
|
|
static assert(hasOverloadedOpBinaryWithSelf!(DateTime));
|
|
static assert(hasOverloadedOpBinaryWithSelf!(SysTime));
|
|
static assert(hasOverloadedOpBinaryWithSelf!(const Date));
|
|
static assert(hasOverloadedOpBinaryWithSelf!(const TimeOfDay));
|
|
static assert(hasOverloadedOpBinaryWithSelf!(const DateTime));
|
|
static assert(hasOverloadedOpBinaryWithSelf!(const SysTime));
|
|
static assert(hasOverloadedOpBinaryWithSelf!(immutable Date));
|
|
static assert(hasOverloadedOpBinaryWithSelf!(immutable TimeOfDay));
|
|
static assert(hasOverloadedOpBinaryWithSelf!(immutable DateTime));
|
|
static assert(hasOverloadedOpBinaryWithSelf!(immutable SysTime));
|
|
}
|
|
}
|
|
|
|
/+
|
|
Unfortunately, to!string() is not pure, so here's a way to convert
|
|
a number to a string which is. Once to!string() is properly pure
|
|
(like it hopefully will be at some point), this function should
|
|
be removed in favor of using to!string().
|
|
+/
|
|
string numToString(long value) pure nothrow
|
|
{
|
|
try
|
|
{
|
|
immutable negative = value < 0;
|
|
char[25] str;
|
|
size_t i = str.length;
|
|
|
|
if(negative)
|
|
value = -value;
|
|
|
|
while(1)
|
|
{
|
|
char digit = cast(char)('0' + value % 10);
|
|
value /= 10;
|
|
|
|
str[--i] = digit;
|
|
assert(i > 0);
|
|
|
|
if(value == 0)
|
|
break;
|
|
}
|
|
|
|
if(negative)
|
|
return "-" ~ str[i .. $].idup;
|
|
else
|
|
return str[i .. $].idup;
|
|
}
|
|
catch(Exception e)
|
|
assert(0, "Something threw when nothing can throw.");
|
|
}
|
|
|
|
|
|
/+
|
|
A temporary replacement for Rebindable!() until bug http://d.puremagic.com/issues/show_bug.cgi?id=4977
|
|
is fixed.
|
|
+/
|
|
template DTRebindable(T) if (is(T == class) || is(T == interface) || isArray!(T))
|
|
{
|
|
static if(!is(T X == const(U), U) && !is(T X == immutable(U), U))
|
|
{
|
|
alias T DTRebindable;
|
|
}
|
|
else static if(isArray!(T))
|
|
{
|
|
alias const(ElementType!(T))[] DTRebindable;
|
|
}
|
|
else
|
|
{
|
|
struct DTRebindable
|
|
{
|
|
private union
|
|
{
|
|
T original;
|
|
U stripped;
|
|
}
|
|
|
|
void opAssign(T another) pure nothrow
|
|
{
|
|
stripped = cast(U) another;
|
|
}
|
|
|
|
void opAssign(DTRebindable another) pure nothrow
|
|
{
|
|
stripped = another.stripped;
|
|
}
|
|
|
|
static if(is(T == const U))
|
|
{
|
|
// safely assign immutable to const
|
|
void opAssign(DTRebindable!(immutable U) another) pure nothrow
|
|
{
|
|
stripped = another.stripped;
|
|
}
|
|
}
|
|
|
|
this(T initializer) pure nothrow
|
|
{
|
|
opAssign(initializer);
|
|
}
|
|
|
|
@property ref T get() pure nothrow
|
|
{
|
|
return original;
|
|
}
|
|
|
|
@property ref T get() const pure nothrow
|
|
{
|
|
return original;
|
|
}
|
|
|
|
alias get this;
|
|
|
|
T opDot() pure nothrow
|
|
{
|
|
return original;
|
|
}
|
|
|
|
T opDot() const pure nothrow
|
|
{
|
|
return original;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
version(unittest)
|
|
{
|
|
//Variables to help in testing.
|
|
Duration currLocalDiffFromUTC;
|
|
immutable (TimeZone)[] testTZs;
|
|
|
|
//All of these helper arrays are sorted in ascending order.
|
|
auto testYearsBC = [-1999, -1200, -600, -4, -1, 0];
|
|
auto testYearsAD = [1, 4, 1000, 1999, 2000, 2012];
|
|
|
|
//I'd use a Tuple, but I get forward reference errors if I try.
|
|
struct MonthDay
|
|
{
|
|
Month month;
|
|
short day;
|
|
|
|
this(int m, short d)
|
|
{
|
|
month = cast(Month)m;
|
|
day = d;
|
|
}
|
|
}
|
|
|
|
MonthDay[] testMonthDays = [MonthDay(1, 1),
|
|
MonthDay(1, 2),
|
|
MonthDay(3, 17),
|
|
MonthDay(7, 4),
|
|
MonthDay(10, 27),
|
|
MonthDay(12, 30),
|
|
MonthDay(12, 31)];
|
|
|
|
auto testDays = [1, 2, 9, 10, 16, 20, 25, 28, 29, 30, 31];
|
|
|
|
auto testTODs = [TimeOfDay(0, 0, 0),
|
|
TimeOfDay(0, 0, 1),
|
|
TimeOfDay(0, 1, 0),
|
|
TimeOfDay(1, 0, 0),
|
|
TimeOfDay(13, 13, 13),
|
|
TimeOfDay(23, 59, 59)];
|
|
|
|
auto testHours = [0, 1, 12, 22, 23];
|
|
auto testMinSecs = [0, 1, 30, 58, 59];
|
|
|
|
//Throwing exceptions is incredibly expensive, so we want to use a smaller
|
|
//set of values for tests using assertThrown.
|
|
auto testTODsThrown = [TimeOfDay(0, 0, 0),
|
|
TimeOfDay(13, 13, 13),
|
|
TimeOfDay(23, 59, 59)];
|
|
|
|
Date[] testDatesBC;
|
|
Date[] testDatesAD;
|
|
|
|
DateTime[] testDateTimesBC;
|
|
DateTime[] testDateTimesAD;
|
|
|
|
FracSec[] testFracSecs;
|
|
|
|
SysTime[] testSysTimesBC;
|
|
SysTime[] testSysTimesAD;
|
|
|
|
//I'd use a Tuple, but I get forward reference errors if I try.
|
|
struct GregDay { int day; Date date; }
|
|
auto testGregDaysBC = [GregDay(-1_373_427, Date(-3760, 9, 7)), //Start of the Hebrew Calendar
|
|
GregDay(-735_233, Date(-2012, 1, 1)),
|
|
GregDay(-735_202, Date(-2012, 2, 1)),
|
|
GregDay(-735_175, Date(-2012, 2, 28)),
|
|
GregDay(-735_174, Date(-2012, 2, 29)),
|
|
GregDay(-735_173, Date(-2012, 3, 1)),
|
|
GregDay(-734_502, Date(-2010, 1, 1)),
|
|
GregDay(-734_472, Date(-2010, 1, 31)),
|
|
GregDay(-734_471, Date(-2010, 2, 1)),
|
|
GregDay(-734_444, Date(-2010, 2, 28)),
|
|
GregDay(-734_443, Date(-2010, 3, 1)),
|
|
GregDay(-734_413, Date(-2010, 3, 31)),
|
|
GregDay(-734_412, Date(-2010, 4, 1)),
|
|
GregDay(-734_383, Date(-2010, 4, 30)),
|
|
GregDay(-734_382, Date(-2010, 5, 1)),
|
|
GregDay(-734_352, Date(-2010, 5, 31)),
|
|
GregDay(-734_351, Date(-2010, 6, 1)),
|
|
GregDay(-734_322, Date(-2010, 6, 30)),
|
|
GregDay(-734_321, Date(-2010, 7, 1)),
|
|
GregDay(-734_291, Date(-2010, 7, 31)),
|
|
GregDay(-734_290, Date(-2010, 8, 1)),
|
|
GregDay(-734_260, Date(-2010, 8, 31)),
|
|
GregDay(-734_259, Date(-2010, 9, 1)),
|
|
GregDay(-734_230, Date(-2010, 9, 30)),
|
|
GregDay(-734_229, Date(-2010, 10, 1)),
|
|
GregDay(-734_199, Date(-2010, 10, 31)),
|
|
GregDay(-734_198, Date(-2010, 11, 1)),
|
|
GregDay(-734_169, Date(-2010, 11, 30)),
|
|
GregDay(-734_168, Date(-2010, 12, 1)),
|
|
GregDay(-734_139, Date(-2010, 12, 30)),
|
|
GregDay(-734_138, Date(-2010, 12, 31)),
|
|
GregDay(-731_215, Date(-2001, 1, 1)),
|
|
GregDay(-730_850, Date(-2000, 1, 1)),
|
|
GregDay(-730_849, Date(-2000, 1, 2)),
|
|
GregDay(-730_486, Date(-2000, 12, 30)),
|
|
GregDay(-730_485, Date(-2000, 12, 31)),
|
|
GregDay(-730_484, Date(-1999, 1, 1)),
|
|
GregDay(-694_690, Date(-1901, 1, 1)),
|
|
GregDay(-694_325, Date(-1900, 1, 1)),
|
|
GregDay(-585_118, Date(-1601, 1, 1)),
|
|
GregDay(-584_753, Date(-1600, 1, 1)),
|
|
GregDay(-584_388, Date(-1600, 12, 31)),
|
|
GregDay(-584_387, Date(-1599, 1, 1)),
|
|
GregDay(-365_972, Date(-1001, 1, 1)),
|
|
GregDay(-365_607, Date(-1000, 1, 1)),
|
|
GregDay(-183_351, Date(-501, 1, 1)),
|
|
GregDay(-182_986, Date(-500, 1, 1)),
|
|
GregDay(-182_621, Date(-499, 1, 1)),
|
|
GregDay(-146_827, Date(-401, 1, 1)),
|
|
GregDay(-146_462, Date(-400, 1, 1)),
|
|
GregDay(-146_097, Date(-400, 12, 31)),
|
|
GregDay(-110_302, Date(-301, 1, 1)),
|
|
GregDay(-109_937, Date(-300, 1, 1)),
|
|
GregDay(-73_778, Date(-201, 1, 1)),
|
|
GregDay(-73_413, Date(-200, 1, 1)),
|
|
GregDay(-38_715, Date(-105, 1, 1)),
|
|
GregDay(-37_254, Date(-101, 1, 1)),
|
|
GregDay(-36_889, Date(-100, 1, 1)),
|
|
GregDay(-36_524, Date(-99, 1, 1)),
|
|
GregDay(-36_160, Date(-99, 12, 31)),
|
|
GregDay(-35_794, Date(-97, 1, 1)),
|
|
GregDay(-18_627, Date(-50, 1, 1)),
|
|
GregDay(-18_262, Date(-49, 1, 1)),
|
|
GregDay(-3652, Date(-9, 1, 1)),
|
|
GregDay(-2191, Date(-5, 1, 1)),
|
|
GregDay(-1827, Date(-5, 12, 31)),
|
|
GregDay(-1826, Date(-4, 1, 1)),
|
|
GregDay(-1825, Date(-4, 1, 2)),
|
|
GregDay(-1462, Date(-4, 12, 30)),
|
|
GregDay(-1461, Date(-4, 12, 31)),
|
|
GregDay(-1460, Date(-3, 1, 1)),
|
|
GregDay(-1096, Date(-3, 12, 31)),
|
|
GregDay(-1095, Date(-2, 1, 1)),
|
|
GregDay(-731, Date(-2, 12, 31)),
|
|
GregDay(-730, Date(-1, 1, 1)),
|
|
GregDay(-367, Date(-1, 12, 30)),
|
|
GregDay(-366, Date(-1, 12, 31)),
|
|
GregDay(-365, Date(0, 1, 1)),
|
|
GregDay(-31, Date(0, 11, 30)),
|
|
GregDay(-30, Date(0, 12, 1)),
|
|
GregDay(-1, Date(0, 12, 30)),
|
|
GregDay(0, Date(0, 12, 31))];
|
|
|
|
auto testGregDaysAD = [GregDay(1, Date(1, 1, 1)),
|
|
GregDay(2, Date(1, 1, 2)),
|
|
GregDay(32, Date(1, 2, 1)),
|
|
GregDay(365, Date(1, 12, 31)),
|
|
GregDay(366, Date(2, 1, 1)),
|
|
GregDay(731, Date(3, 1, 1)),
|
|
GregDay(1096, Date(4, 1, 1)),
|
|
GregDay(1097, Date(4, 1, 2)),
|
|
GregDay(1460, Date(4, 12, 30)),
|
|
GregDay(1461, Date(4, 12, 31)),
|
|
GregDay(1462, Date(5, 1, 1)),
|
|
GregDay(17_898, Date(50, 1, 1)),
|
|
GregDay(35_065, Date(97, 1, 1)),
|
|
GregDay(36_160, Date(100, 1, 1)),
|
|
GregDay(36_525, Date(101, 1, 1)),
|
|
GregDay(37_986, Date(105, 1, 1)),
|
|
GregDay(72_684, Date(200, 1, 1)),
|
|
GregDay(73_049, Date(201, 1, 1)),
|
|
GregDay(109_208, Date(300, 1, 1)),
|
|
GregDay(109_573, Date(301, 1, 1)),
|
|
GregDay(145_732, Date(400, 1, 1)),
|
|
GregDay(146_098, Date(401, 1, 1)),
|
|
GregDay(182_257, Date(500, 1, 1)),
|
|
GregDay(182_622, Date(501, 1, 1)),
|
|
GregDay(364_878, Date(1000, 1, 1)),
|
|
GregDay(365_243, Date(1001, 1, 1)),
|
|
GregDay(584_023, Date(1600, 1, 1)),
|
|
GregDay(584_389, Date(1601, 1, 1)),
|
|
GregDay(693_596, Date(1900, 1, 1)),
|
|
GregDay(693_961, Date(1901, 1, 1)),
|
|
GregDay(729_755, Date(1999, 1, 1)),
|
|
GregDay(730_120, Date(2000, 1, 1)),
|
|
GregDay(730_121, Date(2000, 1, 2)),
|
|
GregDay(730_484, Date(2000, 12, 30)),
|
|
GregDay(730_485, Date(2000, 12, 31)),
|
|
GregDay(730_486, Date(2001, 1, 1)),
|
|
GregDay(733_773, Date(2010, 1, 1)),
|
|
GregDay(733_774, Date(2010, 1, 2)),
|
|
GregDay(733_803, Date(2010, 1, 31)),
|
|
GregDay(733_804, Date(2010, 2, 1)),
|
|
GregDay(733_831, Date(2010, 2, 28)),
|
|
GregDay(733_832, Date(2010, 3, 1)),
|
|
GregDay(733_862, Date(2010, 3, 31)),
|
|
GregDay(733_863, Date(2010, 4, 1)),
|
|
GregDay(733_892, Date(2010, 4, 30)),
|
|
GregDay(733_893, Date(2010, 5, 1)),
|
|
GregDay(733_923, Date(2010, 5, 31)),
|
|
GregDay(733_924, Date(2010, 6, 1)),
|
|
GregDay(733_953, Date(2010, 6, 30)),
|
|
GregDay(733_954, Date(2010, 7, 1)),
|
|
GregDay(733_984, Date(2010, 7, 31)),
|
|
GregDay(733_985, Date(2010, 8, 1)),
|
|
GregDay(734_015, Date(2010, 8, 31)),
|
|
GregDay(734_016, Date(2010, 9, 1)),
|
|
GregDay(734_045, Date(2010, 9, 30)),
|
|
GregDay(734_046, Date(2010, 10, 1)),
|
|
GregDay(734_076, Date(2010, 10, 31)),
|
|
GregDay(734_077, Date(2010, 11, 1)),
|
|
GregDay(734_106, Date(2010, 11, 30)),
|
|
GregDay(734_107, Date(2010, 12, 1)),
|
|
GregDay(734_136, Date(2010, 12, 30)),
|
|
GregDay(734_137, Date(2010, 12, 31)),
|
|
GregDay(734_503, Date(2012, 1, 1)),
|
|
GregDay(734_534, Date(2012, 2, 1)),
|
|
GregDay(734_561, Date(2012, 2, 28)),
|
|
GregDay(734_562, Date(2012, 2, 29)),
|
|
GregDay(734_563, Date(2012, 3, 1)),
|
|
GregDay(734_858, Date(2012, 12, 21))];
|
|
|
|
//I'd use a Tuple, but I get forward reference errors if I try.
|
|
struct DayOfYear { int day; MonthDay md; }
|
|
auto testDaysOfYear = [DayOfYear(1, MonthDay(1, 1)),
|
|
DayOfYear(2, MonthDay(1, 2)),
|
|
DayOfYear(3, MonthDay(1, 3)),
|
|
DayOfYear(31, MonthDay(1, 31)),
|
|
DayOfYear(32, MonthDay(2, 1)),
|
|
DayOfYear(59, MonthDay(2, 28)),
|
|
DayOfYear(60, MonthDay(3, 1)),
|
|
DayOfYear(90, MonthDay(3, 31)),
|
|
DayOfYear(91, MonthDay(4, 1)),
|
|
DayOfYear(120, MonthDay(4, 30)),
|
|
DayOfYear(121, MonthDay(5, 1)),
|
|
DayOfYear(151, MonthDay(5, 31)),
|
|
DayOfYear(152, MonthDay(6, 1)),
|
|
DayOfYear(181, MonthDay(6, 30)),
|
|
DayOfYear(182, MonthDay(7, 1)),
|
|
DayOfYear(212, MonthDay(7, 31)),
|
|
DayOfYear(213, MonthDay(8, 1)),
|
|
DayOfYear(243, MonthDay(8, 31)),
|
|
DayOfYear(244, MonthDay(9, 1)),
|
|
DayOfYear(273, MonthDay(9, 30)),
|
|
DayOfYear(274, MonthDay(10, 1)),
|
|
DayOfYear(304, MonthDay(10, 31)),
|
|
DayOfYear(305, MonthDay(11, 1)),
|
|
DayOfYear(334, MonthDay(11, 30)),
|
|
DayOfYear(335, MonthDay(12, 1)),
|
|
DayOfYear(363, MonthDay(12, 29)),
|
|
DayOfYear(364, MonthDay(12, 30)),
|
|
DayOfYear(365, MonthDay(12, 31))];
|
|
|
|
auto testDaysOfLeapYear = [DayOfYear(1, MonthDay(1, 1)),
|
|
DayOfYear(2, MonthDay(1, 2)),
|
|
DayOfYear(3, MonthDay(1, 3)),
|
|
DayOfYear(31, MonthDay(1, 31)),
|
|
DayOfYear(32, MonthDay(2, 1)),
|
|
DayOfYear(59, MonthDay(2, 28)),
|
|
DayOfYear(60, MonthDay(2, 29)),
|
|
DayOfYear(61, MonthDay(3, 1)),
|
|
DayOfYear(91, MonthDay(3, 31)),
|
|
DayOfYear(92, MonthDay(4, 1)),
|
|
DayOfYear(121, MonthDay(4, 30)),
|
|
DayOfYear(122, MonthDay(5, 1)),
|
|
DayOfYear(152, MonthDay(5, 31)),
|
|
DayOfYear(153, MonthDay(6, 1)),
|
|
DayOfYear(182, MonthDay(6, 30)),
|
|
DayOfYear(183, MonthDay(7, 1)),
|
|
DayOfYear(213, MonthDay(7, 31)),
|
|
DayOfYear(214, MonthDay(8, 1)),
|
|
DayOfYear(244, MonthDay(8, 31)),
|
|
DayOfYear(245, MonthDay(9, 1)),
|
|
DayOfYear(274, MonthDay(9, 30)),
|
|
DayOfYear(275, MonthDay(10, 1)),
|
|
DayOfYear(305, MonthDay(10, 31)),
|
|
DayOfYear(306, MonthDay(11, 1)),
|
|
DayOfYear(335, MonthDay(11, 30)),
|
|
DayOfYear(336, MonthDay(12, 1)),
|
|
DayOfYear(364, MonthDay(12, 29)),
|
|
DayOfYear(365, MonthDay(12, 30)),
|
|
DayOfYear(366, MonthDay(12, 31))];
|
|
|
|
static this()
|
|
{
|
|
currLocalDiffFromUTC = Clock.currTime(UTC()) -
|
|
Clock.currTime(LocalTime());
|
|
|
|
immutable simpleTZ = new SimpleTimeZone(cast(int)
|
|
(currLocalDiffFromUTC + dur!"hours"(2)).total!"minutes"());
|
|
|
|
immutable lt = LocalTime().utcToTZ(0);
|
|
immutable st = simpleTZ.utcToTZ(0);
|
|
auto diffs = [0, lt, st];
|
|
auto diffAA = [0 : cast(immutable TimeZone)UTC(),
|
|
lt : cast(immutable TimeZone)LocalTime(),
|
|
st : cast(immutable TimeZone)simpleTZ];
|
|
sort(diffs);
|
|
testTZs = [diffAA[diffs[0]], diffAA[diffs[1]], diffAA[diffs[2]]];
|
|
|
|
testFracSecs = [FracSec.from!"hnsecs"(0),
|
|
FracSec.from!"hnsecs"(1),
|
|
FracSec.from!"hnsecs"(5007),
|
|
FracSec.from!"hnsecs"(9999999)];
|
|
|
|
foreach(year; testYearsBC)
|
|
{
|
|
foreach(md; testMonthDays)
|
|
testDatesBC ~= Date(year, md.month, md.day);
|
|
}
|
|
|
|
foreach(year; testYearsAD)
|
|
{
|
|
foreach(md; testMonthDays)
|
|
testDatesAD ~= Date(year, md.month, md.day);
|
|
}
|
|
|
|
foreach(dt; testDatesBC)
|
|
{
|
|
foreach(tod; testTODs)
|
|
testDateTimesBC ~= DateTime(dt, tod);
|
|
}
|
|
|
|
foreach(dt; testDatesAD)
|
|
{
|
|
foreach(tod; testTODs)
|
|
testDateTimesAD ~= DateTime(dt, tod);
|
|
}
|
|
|
|
foreach(dt; testDateTimesBC)
|
|
{
|
|
foreach(tz; testTZs)
|
|
{
|
|
foreach(fs; testFracSecs)
|
|
testSysTimesBC ~= SysTime(dt, fs, tz);
|
|
}
|
|
}
|
|
|
|
foreach(dt; testDateTimesAD)
|
|
{
|
|
foreach(tz; testTZs)
|
|
{
|
|
foreach(fs; testFracSecs)
|
|
testSysTimesAD ~= SysTime(dt, fs, tz);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//==============================================================================
|
|
// Unit testing functions.
|
|
//==============================================================================
|
|
|
|
void _assertPred(string op, L, R)
|
|
(L lhs, R rhs, lazy string msg = null, string file = __FILE__, size_t line = __LINE__)
|
|
if((op == "<" ||
|
|
op == "<=" ||
|
|
op == "==" ||
|
|
op == "!=" ||
|
|
op == ">=" ||
|
|
op == ">") &&
|
|
__traits(compiles, mixin("lhs " ~ op ~ " rhs")) &&
|
|
_isPrintable!L &&
|
|
_isPrintable!R)
|
|
{
|
|
immutable result = mixin("lhs " ~ op ~ " rhs");
|
|
|
|
if(!result)
|
|
{
|
|
if(msg.empty)
|
|
throw new AssertError(format(`_assertPred!"%s" failed: [%s] is not %s [%s].`, op, lhs, op, rhs), file, line);
|
|
else
|
|
throw new AssertError(format(`_assertPred!"%s" failed: [%s] is not %s [%s]: %s`, op, lhs, op, rhs, msg), file, line);
|
|
}
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
struct IntWrapper
|
|
{
|
|
int value;
|
|
|
|
this(int value)
|
|
{
|
|
this.value = value;
|
|
}
|
|
|
|
string toString()
|
|
{
|
|
return to!string(value);
|
|
}
|
|
}
|
|
|
|
//Test ==.
|
|
assertNotThrown!AssertError(_assertPred!"=="(6, 6));
|
|
assertNotThrown!AssertError(_assertPred!"=="(6, 6.0));
|
|
assertNotThrown!AssertError(_assertPred!"=="(IntWrapper(6), IntWrapper(6)));
|
|
|
|
assertThrown!AssertError(_assertPred!"=="(6, 7));
|
|
assertThrown!AssertError(_assertPred!"=="(6, 6.1));
|
|
assertThrown!AssertError(_assertPred!"=="(IntWrapper(6), IntWrapper(7)));
|
|
assertThrown!AssertError(_assertPred!"=="(IntWrapper(7), IntWrapper(6)));
|
|
|
|
_assertPred!"=="(collectExceptionMsg!AssertError(_assertPred!"=="(6, 7)),
|
|
`_assertPred!"==" failed: [6] is not == [7].`);
|
|
_assertPred!"=="(collectExceptionMsg!AssertError(_assertPred!"=="(6, 7, "It failed!")),
|
|
`_assertPred!"==" failed: [6] is not == [7]: It failed!`);
|
|
|
|
//Test !=.
|
|
assertNotThrown!AssertError(_assertPred!"!="(6, 7));
|
|
assertNotThrown!AssertError(_assertPred!"!="(6, 6.1));
|
|
assertNotThrown!AssertError(_assertPred!"!="(IntWrapper(6), IntWrapper(7)));
|
|
assertNotThrown!AssertError(_assertPred!"!="(IntWrapper(7), IntWrapper(6)));
|
|
|
|
assertThrown!AssertError(_assertPred!"!="(6, 6));
|
|
assertThrown!AssertError(_assertPred!"!="(6, 6.0));
|
|
assertThrown!AssertError(_assertPred!"!="(IntWrapper(6), IntWrapper(6)));
|
|
|
|
_assertPred!"=="(collectExceptionMsg!AssertError(_assertPred!"!="(6, 6)),
|
|
`_assertPred!"!=" failed: [6] is not != [6].`);
|
|
_assertPred!"=="(collectExceptionMsg!AssertError(_assertPred!"!="(6, 6, "It failed!")),
|
|
`_assertPred!"!=" failed: [6] is not != [6]: It failed!`);
|
|
|
|
//Test <, <=, >=, >.
|
|
assertNotThrown!AssertError(_assertPred!"<"(5, 7));
|
|
assertNotThrown!AssertError(_assertPred!"<="(5, 7));
|
|
assertNotThrown!AssertError(_assertPred!"<="(5, 5));
|
|
assertNotThrown!AssertError(_assertPred!">="(7, 7));
|
|
assertNotThrown!AssertError(_assertPred!">="(7, 5));
|
|
assertNotThrown!AssertError(_assertPred!">"(7, 5));
|
|
|
|
assertThrown!AssertError(_assertPred!"<"(7, 5));
|
|
assertThrown!AssertError(_assertPred!"<="(7, 5));
|
|
assertThrown!AssertError(_assertPred!">="(5, 7));
|
|
assertThrown!AssertError(_assertPred!">"(5, 7));
|
|
|
|
_assertPred!"=="(collectExceptionMsg!AssertError(_assertPred!"<"(7, 5)),
|
|
`_assertPred!"<" failed: [7] is not < [5].`);
|
|
_assertPred!"=="(collectExceptionMsg!AssertError(_assertPred!"<"(7, 5, "It failed!")),
|
|
`_assertPred!"<" failed: [7] is not < [5]: It failed!`);
|
|
|
|
//Verify Examples.
|
|
|
|
//Equivalent to assert(5 / 2 + 4 < 27);
|
|
_assertPred!"<"(5 / 2 + 4, 27);
|
|
|
|
//Equivalent to assert(4 <= 5);
|
|
_assertPred!"<="(4, 5);
|
|
|
|
//Equivalent to assert(1 * 2.1 == 2.1);
|
|
_assertPred!"=="(1 * 2.1, 2.1);
|
|
|
|
//Equivalent to assert("hello " ~ "world" != "goodbye world");
|
|
_assertPred!"!="("hello " ~ "world", "goodbye world");
|
|
|
|
//Equivalent to assert(14.2 >= 14);
|
|
_assertPred!">="(14.2, 14);
|
|
|
|
//Equivalent to assert(15 > 2 + 1);
|
|
_assertPred!">"(15, 2 + 1);
|
|
|
|
assert(collectExceptionMsg!AssertError(_assertPred!"=="("hello", "goodbye")) ==
|
|
`_assertPred!"==" failed: [hello] is not == [goodbye].`);
|
|
|
|
assert(collectExceptionMsg!AssertError(_assertPred!"<"(5, 2, "My test failed!")) ==
|
|
`_assertPred!"<" failed: [5] is not < [2]: My test failed!`);
|
|
}
|
|
}
|
|
|
|
void _assertPred(string func, string expected, L, R)
|
|
(L lhs, R rhs, lazy string msg = null, string file = __FILE__, size_t line = __LINE__)
|
|
if(func == "opCmp" &&
|
|
(expected == "<" ||
|
|
expected == "==" ||
|
|
expected == ">") &&
|
|
__traits(compiles, lhs.opCmp(rhs)) &&
|
|
_isPrintable!L &&
|
|
_isPrintable!R)
|
|
{
|
|
immutable result = lhs.opCmp(rhs);
|
|
|
|
static if(expected == "<")
|
|
{
|
|
if(result < 0)
|
|
return;
|
|
|
|
if(result == 0)
|
|
{
|
|
if(msg.empty)
|
|
throw new AssertError(format(`_assertPred!("opCmp", "<") failed: [%s] == [%s].`, lhs, rhs), file, line);
|
|
else
|
|
throw new AssertError(format(`_assertPred!("opCmp", "<") failed: [%s] == [%s]: %s`, lhs, rhs, msg), file, line);
|
|
}
|
|
else
|
|
{
|
|
if(msg.empty)
|
|
throw new AssertError(format(`_assertPred!("opCmp", "<") failed: [%s] > [%s].`, lhs, rhs), file, line);
|
|
else
|
|
throw new AssertError(format(`_assertPred!("opCmp", "<") failed: [%s] > [%s]: %s`, lhs, rhs, msg), file, line);
|
|
}
|
|
}
|
|
else static if(expected == "==")
|
|
{
|
|
if(result == 0)
|
|
return;
|
|
|
|
if(result < 0)
|
|
{
|
|
if(msg.empty)
|
|
throw new AssertError(format(`_assertPred!("opCmp", "==") failed: [%s] < [%s].`, lhs, rhs), file, line);
|
|
else
|
|
throw new AssertError(format(`_assertPred!("opCmp", "==") failed: [%s] < [%s]: %s`, lhs, rhs, msg), file, line);
|
|
}
|
|
else
|
|
{
|
|
if(msg.empty)
|
|
throw new AssertError(format(`_assertPred!("opCmp", "==") failed: [%s] > [%s].`, lhs, rhs), file, line);
|
|
else
|
|
throw new AssertError(format(`_assertPred!("opCmp", "==") failed: [%s] > [%s]: %s`, lhs, rhs, msg), file, line);
|
|
}
|
|
}
|
|
else static if(expected == ">")
|
|
{
|
|
if(result > 0)
|
|
return;
|
|
|
|
if(result < 0)
|
|
{
|
|
if(msg.empty)
|
|
throw new AssertError(format(`_assertPred!("opCmp", ">") failed: [%s] < [%s].`, lhs, rhs), file, line);
|
|
else
|
|
throw new AssertError(format(`_assertPred!("opCmp", ">") failed: [%s] < [%s]: %s`, lhs, rhs, msg), file, line);
|
|
}
|
|
else
|
|
{
|
|
if(msg.empty)
|
|
throw new AssertError(format(`_assertPred!("opCmp", ">") failed: [%s] == [%s].`, lhs, rhs), file, line);
|
|
else
|
|
throw new AssertError(format(`_assertPred!("opCmp", ">") failed: [%s] == [%s]: %s`, lhs, rhs, msg), file, line);
|
|
}
|
|
}
|
|
else
|
|
static assert(0);
|
|
}
|
|
|
|
void _assertPred(string op, L, R, E)
|
|
(L lhs, R rhs, E expected, lazy string msg = null, string file = __FILE__, size_t line = __LINE__)
|
|
if((op == "+=" ||
|
|
op == "-=" ||
|
|
op == "*=" ||
|
|
op == "/=" ||
|
|
op == "%=" ||
|
|
op == "^^=" ||
|
|
op == "&=" ||
|
|
op == "|=" ||
|
|
op == "^=" ||
|
|
op == "<<=" ||
|
|
op == ">>=" ||
|
|
op == ">>>=" ||
|
|
op == "~=") &&
|
|
__traits(compiles, mixin("lhs " ~ op ~ " rhs")) &&
|
|
__traits(compiles, mixin("(lhs " ~ op ~ " rhs) == expected")) &&
|
|
_isPrintable!L &&
|
|
_isPrintable!R)
|
|
{
|
|
immutable origLHSStr = to!string(lhs);
|
|
const result = mixin("lhs " ~ op ~ " rhs");
|
|
|
|
if(lhs != expected)
|
|
{
|
|
if(msg.empty)
|
|
{
|
|
throw new AssertError(format(`_assertPred!"%s" failed: After [%s] %s [%s], lhs was assigned to [%s] instead of [%s].`,
|
|
op,
|
|
origLHSStr,
|
|
op,
|
|
rhs,
|
|
lhs,
|
|
expected),
|
|
file,
|
|
line);
|
|
}
|
|
else
|
|
{
|
|
throw new AssertError(format(`_assertPred!"%s" failed: After [%s] %s [%s], lhs was assigned to [%s] instead of [%s]: %s`,
|
|
op,
|
|
origLHSStr,
|
|
op,
|
|
rhs,
|
|
lhs,
|
|
expected,
|
|
msg),
|
|
file,
|
|
line);
|
|
}
|
|
}
|
|
|
|
if(result != expected)
|
|
{
|
|
if(msg.empty)
|
|
{
|
|
throw new AssertError(format(`_assertPred!"%s" failed: Return value of [%s] %s [%s] was [%s] instead of [%s].`,
|
|
op,
|
|
origLHSStr,
|
|
op,
|
|
rhs,
|
|
result,
|
|
expected),
|
|
file,
|
|
line);
|
|
}
|
|
else
|
|
{
|
|
throw new AssertError(format(`_assertPred!"%s" failed: Return value of [%s] %s [%s] was [%s] instead of [%s]: %s`,
|
|
op,
|
|
origLHSStr,
|
|
op,
|
|
rhs,
|
|
result,
|
|
expected,
|
|
msg),
|
|
file,
|
|
line);
|
|
}
|
|
}
|
|
}
|
|
|
|
unittest
|
|
{
|
|
version(testStdDateTime)
|
|
{
|
|
assertNotThrown!AssertError(_assertPred!"+="(7, 5, 12));
|
|
assertNotThrown!AssertError(_assertPred!"-="(7, 5, 2));
|
|
assertNotThrown!AssertError(_assertPred!"*="(7, 5, 35));
|
|
assertNotThrown!AssertError(_assertPred!"/="(7, 5, 1));
|
|
assertNotThrown!AssertError(_assertPred!"%="(7, 5, 2));
|
|
assertNotThrown!AssertError(_assertPred!"^^="(7, 5, 16_807));
|
|
assertNotThrown!AssertError(_assertPred!"&="(7, 5, 5));
|
|
assertNotThrown!AssertError(_assertPred!"|="(7, 5, 7));
|
|
assertNotThrown!AssertError(_assertPred!"^="(7, 5, 2));
|
|
assertNotThrown!AssertError(_assertPred!"<<="(7, 1, 14));
|
|
assertNotThrown!AssertError(_assertPred!">>="(7, 1, 3));
|
|
assertNotThrown!AssertError(_assertPred!">>>="(-7, 1, 2_147_483_644));
|
|
assertNotThrown!AssertError(_assertPred!"~="("hello ", "world", "hello world"));
|
|
|
|
assertThrown!AssertError(_assertPred!"+="(7, 5, 0));
|
|
assertThrown!AssertError(_assertPred!"-="(7, 5, 0));
|
|
assertThrown!AssertError(_assertPred!"*="(7, 5, 0));
|
|
assertThrown!AssertError(_assertPred!"/="(7, 5, 0));
|
|
assertThrown!AssertError(_assertPred!"%="(7, 5, 0));
|
|
assertThrown!AssertError(_assertPred!"^^="(7, 5, 0));
|
|
assertThrown!AssertError(_assertPred!"&="(7, 5, 0));
|
|
assertThrown!AssertError(_assertPred!"|="(7, 5, 0));
|
|
assertThrown!AssertError(_assertPred!"^="(7, 5, 0));
|
|
assertThrown!AssertError(_assertPred!"<<="(7, 1, 0));
|
|
assertThrown!AssertError(_assertPred!">>="(7, 1, 0));
|
|
assertThrown!AssertError(_assertPred!">>>="(-7, 1, 0));
|
|
assertThrown!AssertError(_assertPred!"~="("hello ", "world", "goodbye world"));
|
|
|
|
_assertPred!"=="(collectExceptionMsg!AssertError(_assertPred!"+="(7, 5, 11)),
|
|
`_assertPred!"+=" failed: After [7] += [5], lhs was assigned to [12] instead of [11].`);
|
|
_assertPred!"=="(collectExceptionMsg!AssertError(_assertPred!"+="(7, 5, 11, "It failed!")),
|
|
`_assertPred!"+=" failed: After [7] += [5], lhs was assigned to [12] instead of [11]: It failed!`);
|
|
|
|
_assertPred!"=="(collectExceptionMsg!AssertError(_assertPred!"^^="(7, 5, 42)),
|
|
`_assertPred!"^^=" failed: After [7] ^^= [5], lhs was assigned to [16807] instead of [42].`);
|
|
_assertPred!"=="(collectExceptionMsg!AssertError(_assertPred!"^^="(7, 5, 42, "It failed!")),
|
|
`_assertPred!"^^=" failed: After [7] ^^= [5], lhs was assigned to [16807] instead of [42]: It failed!`);
|
|
|
|
_assertPred!"=="(collectExceptionMsg!AssertError(_assertPred!"~="("hello ", "world", "goodbye world")),
|
|
`_assertPred!"~=" failed: After [hello ] ~= [world], lhs was assigned to [hello world] instead of [goodbye world].`);
|
|
_assertPred!"=="(collectExceptionMsg!AssertError(_assertPred!"~="("hello ", "world", "goodbye world", "It failed!")),
|
|
`_assertPred!"~=" failed: After [hello ] ~= [world], lhs was assigned to [hello world] instead of [goodbye world]: It failed!`);
|
|
|
|
struct IntWrapper
|
|
{
|
|
int value;
|
|
|
|
this(int value)
|
|
{
|
|
this.value = value;
|
|
}
|
|
|
|
IntWrapper opOpAssign(string op)(IntWrapper rhs)
|
|
{
|
|
mixin("this.value " ~ op ~ "= rhs.value;");
|
|
|
|
return this;
|
|
}
|
|
|
|
string toString()
|
|
{
|
|
return to!string(value);
|
|
}
|
|
}
|
|
|
|
struct IntWrapper_BadAssign
|
|
{
|
|
int value;
|
|
|
|
this(int value)
|
|
{
|
|
this.value = value;
|
|
}
|
|
|
|
IntWrapper_BadAssign opOpAssign(string op)(IntWrapper_BadAssign rhs)
|
|
{
|
|
auto old = this.value;
|
|
|
|
mixin("this.value " ~ op ~ "= -rhs.value;");
|
|
|
|
return IntWrapper_BadAssign(mixin("old " ~ op ~ " rhs.value"));
|
|
}
|
|
|
|
string toString()
|
|
{
|
|
return to!string(value);
|
|
}
|
|
}
|
|
|
|
struct IntWrapper_BadReturn
|
|
{
|
|
int value;
|
|
|
|
this(int value)
|
|
{
|
|
this.value = value;
|
|
}
|
|
|
|
IntWrapper_BadReturn opOpAssign(string op)(IntWrapper_BadReturn rhs)
|
|
{
|
|
mixin("this.value " ~ op ~ "= rhs.value;");
|
|
|
|
return IntWrapper_BadReturn(rhs.value);
|
|
}
|
|
|
|
string toString()
|
|
{
|
|
return to!string(value);
|
|
}
|
|
}
|
|
|
|
assertNotThrown!AssertError(_assertPred!"+="(IntWrapper(5), IntWrapper(2), IntWrapper(7)));
|
|
assertNotThrown!AssertError(_assertPred!"*="(IntWrapper(5), IntWrapper(2), IntWrapper(10)));
|
|
|
|
assertThrown!AssertError(_assertPred!"+="(IntWrapper_BadAssign(5), IntWrapper_BadAssign(2), IntWrapper_BadAssign(7)));
|
|
assertThrown!AssertError(_assertPred!"+="(IntWrapper_BadReturn(5), IntWrapper_BadReturn(2), IntWrapper_BadReturn(7)));
|
|
assertThrown!AssertError(_assertPred!"*="(IntWrapper_BadAssign(5), IntWrapper_BadAssign(2), IntWrapper_BadAssign(10)));
|
|
assertThrown!AssertError(_assertPred!"*="(IntWrapper_BadReturn(5), IntWrapper_BadReturn(2), IntWrapper_BadReturn(10)));
|
|
|
|
_assertPred!"=="(collectExceptionMsg!AssertError(_assertPred!"+="(IntWrapper_BadAssign(5), IntWrapper_BadAssign(2), IntWrapper_BadAssign(7))),
|
|
`_assertPred!"+=" failed: After [5] += [2], lhs was assigned to [3] instead of [7].`);
|
|
_assertPred!"=="(collectExceptionMsg!AssertError(_assertPred!"+="(IntWrapper_BadAssign(5), IntWrapper_BadAssign(2), IntWrapper_BadAssign(7), "It failed!")),
|
|
`_assertPred!"+=" failed: After [5] += [2], lhs was assigned to [3] instead of [7]: It failed!`);
|
|
|
|
_assertPred!"=="(collectExceptionMsg!AssertError(_assertPred!"+="(IntWrapper_BadReturn(5), IntWrapper_BadReturn(2), IntWrapper_BadReturn(7))),
|
|
`_assertPred!"+=" failed: Return value of [5] += [2] was [2] instead of [7].`);
|
|
_assertPred!"=="(collectExceptionMsg!AssertError(_assertPred!"+="(IntWrapper_BadReturn(5), IntWrapper_BadReturn(2), IntWrapper_BadReturn(7), "It failed!")),
|
|
`_assertPred!"+=" failed: Return value of [5] += [2] was [2] instead of [7]: It failed!`);
|
|
|
|
_assertPred!"=="(collectExceptionMsg!AssertError(_assertPred!"*="(IntWrapper_BadAssign(5), IntWrapper_BadAssign(2), IntWrapper_BadAssign(10))),
|
|
`_assertPred!"*=" failed: After [5] *= [2], lhs was assigned to [-10] instead of [10].`);
|
|
_assertPred!"=="(collectExceptionMsg!AssertError(_assertPred!"*="(IntWrapper_BadAssign(5), IntWrapper_BadAssign(2), IntWrapper_BadAssign(10), "It failed!")),
|
|
`_assertPred!"*=" failed: After [5] *= [2], lhs was assigned to [-10] instead of [10]: It failed!`);
|
|
|
|
_assertPred!"=="(collectExceptionMsg!AssertError(_assertPred!"*="(IntWrapper_BadReturn(5), IntWrapper_BadReturn(2), IntWrapper_BadReturn(10))),
|
|
`_assertPred!"*=" failed: Return value of [5] *= [2] was [2] instead of [10].`);
|
|
_assertPred!"=="(collectExceptionMsg!AssertError(_assertPred!"*="(IntWrapper_BadReturn(5), IntWrapper_BadReturn(2), IntWrapper_BadReturn(10), "It failed!")),
|
|
`_assertPred!"*=" failed: Return value of [5] *= [2] was [2] instead of [10]: It failed!`);
|
|
}
|
|
}
|
|
|
|
|
|
template _isPrintable(T...)
|
|
{
|
|
static if(T.length == 0)
|
|
enum _isPrintable = true;
|
|
else static if(T.length == 1)
|
|
{
|
|
enum _isPrintable = (!isArray!(T[0]) && __traits(compiles, to!string(T[0].init))) ||
|
|
(isArray!(T[0]) && __traits(compiles, to!string(T[0].init[0])));
|
|
}
|
|
else
|
|
{
|
|
enum _isPrintable = _isPrintable!(T[0]) && _isPrintable!(T[1 .. $]);
|
|
}
|
|
}
|
|
|
|
|
|
template softDeprec(string vers, string date, string oldFunc, string newFunc)
|
|
{
|
|
enum softDeprec = Format!("Warning: As of Phobos %s, std.datetime.%s has been scheduled " ~
|
|
"for deprecation in %s. Please use std.datetime.%s instead.",
|
|
vers, oldFunc, date, newFunc);
|
|
}
|