mirror of
https://github.com/dlang/phobos.git
synced 2025-04-27 13:40:20 +03:00

I don't think that it makes any sense for core.time.TickDuration.to to be a property, since it's a conversion function, not an abstraction for a variable. However, it _does_ make sense for the example to use one of TickDuration's property functions instead (it makes the code cleaner too). So, I've done that. And if the property debate results in non-property functions being allowed to be called without parens (as currently seems likely), then anyone wanting to use the to function without the extra parens can do so then.
34070 lines
1.5 MiB
34070 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).
|
|
core.time is publically imported into std.datetime, it isn't necessary
|
|
to import it separately.
|
|
|
|
Three of the main concepts used in this module are time points, time
|
|
durations, and time intervals.
|
|
|
|
A time point is a specific point in time. e.g. January 5th, 2010
|
|
or 5:00.
|
|
|
|
A time duration is a length of time with units. e.g. 5 days or 231 seconds.
|
|
|
|
A time interval indicates a period of time associated with a fixed point in
|
|
time. It is either two time points associated with each other,
|
|
indicating the time starting at the first point up to, but not including,
|
|
the second point - e.g. [January 5th, 2010 - March 10th, 2010$(RPAREN) - or
|
|
it is a time point and a time duration associated with one another. e.g.
|
|
January 5th, 2010 and 5 days, indicating [January 5th, 2010 -
|
|
January 10th, 2010$(RPAREN).
|
|
|
|
Various arithmetic operations are supported between time points and
|
|
durations (e.g. the difference between two time points is a time duration),
|
|
and ranges can be gotten from time intervals, so range-based operations may
|
|
be done on a series of time points.
|
|
|
|
The types that the typical user is most likely to be interested in are
|
|
$(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). To print it, $(D toString) is
|
|
sufficient, but if using $(D toISOString), $(D toISOExtString), or
|
|
$(D toSimpleString), use the corresponding $(D fromISOString),
|
|
$(D fromISOExtString), or $(D 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").
|
|
To remember which units are abbreviated and which aren't,
|
|
all units seconds and greater use their full names, and all
|
|
sub-second units are abbreviated (since they'd be rather long if they
|
|
weren't).
|
|
|
|
Note:
|
|
$(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:
|
|
<a href="../intro-to-datetime.html">Introduction to std._datetime </a><br>
|
|
$(WEB en.wikipedia.org/wiki/ISO_8601, ISO 8601)<br>
|
|
$(WEB en.wikipedia.org/wiki/Tz_database,
|
|
Wikipedia entry on TZ Database)<br>
|
|
$(WEB en.wikipedia.org/wiki/List_of_tz_database_time_zones,
|
|
List of Time Zones)<br>
|
|
|
|
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;
|
|
import std.typecons;
|
|
import std.utf;
|
|
|
|
version(Windows)
|
|
{
|
|
import core.sys.windows.windows;
|
|
import std.c.windows.winsock;
|
|
import std.windows.registry;
|
|
}
|
|
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;
|
|
}
|
|
|
|
//Comment this out to disable std.datetime's unit tests.
|
|
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;
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
initializeTests();
|
|
}
|
|
|
|
//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.
|
|
version(testStdDateTime) 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. To get the first time point
|
|
in the range to match what the function generates, then 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. Using
|
|
$(D PopFirst.yes) would tell the function which returned the
|
|
range that $(D popFront) was to be called so that front would then be
|
|
an Easter - the next one generated by the function (which when
|
|
iterating forward would be the Easter following the original $(D front),
|
|
while when 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 is desired -
|
|
e.g. if 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 private constants.
|
|
//==============================================================================
|
|
|
|
/++
|
|
Array of integers representing the last days of each month in a year.
|
|
+/
|
|
private immutable int[13] lastDayNonLeap = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];
|
|
|
|
/++
|
|
Array of integers representing the last days of each month in a leap year.
|
|
+/
|
|
private immutable int[13] lastDayLeap = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366];
|
|
|
|
/++
|
|
Array of the long names of each month.
|
|
+/
|
|
private immutable string[12] longMonthNames = [
|
|
"January",
|
|
"February",
|
|
"March",
|
|
"April",
|
|
"May",
|
|
"June",
|
|
"July",
|
|
"August",
|
|
"September",
|
|
"October",
|
|
"November",
|
|
"December"
|
|
];
|
|
|
|
/++
|
|
Array of the short (three letter) names of each month.
|
|
+/
|
|
private immutable string[12] shortMonthNames = [
|
|
"Jan",
|
|
"Feb",
|
|
"Mar",
|
|
"Apr",
|
|
"May",
|
|
"Jun",
|
|
"Jul",
|
|
"Aug",
|
|
"Sep",
|
|
"Oct",
|
|
"Nov",
|
|
"Dec"
|
|
];
|
|
|
|
//==============================================================================
|
|
// Section with other types.
|
|
//==============================================================================
|
|
|
|
/++
|
|
Exception type used by std.datetime. It's an alias to TimeException, which
|
|
is what core.time uses. Either can be caught without concern 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 fileTime;
|
|
GetSystemTimeAsFileTime(&fileTime);
|
|
|
|
return FILETIMEToStdTime(&fileTime);
|
|
}
|
|
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 to get the current time from the
|
|
system or doing anything that involves time zones. Unlike
|
|
$(D DateTime), the time zone is an integral part of $(D SysTime) (though for
|
|
local time applications, time zones can be ignored 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.
|
|
|
|
For calendar-based operations that don't
|
|
care about time zones, then $(D DateTime) would be the type to
|
|
use. For system time, use $(D SysTime).
|
|
|
|
$(D Clock.currTime) will return the current time as a $(D SysTime).
|
|
To convert a $(D SysTime) to a $(D Date) or $(D DateTime), simply cast
|
|
it. To convert a $(D Date) or $(D DateTime) to a
|
|
$(D SysTime), use $(D SysTime)'s constructor, and 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).
|
|
To not risk any conversion errors, keep times as
|
|
$(D SysTime)s. Aside from DST though, there shouldn't be any conversion
|
|
problems.
|
|
|
|
For using time zones other than local time or UTC, use
|
|
$(D PosixTimeZone) on Posix systems (or on Windows, if providing the TZ
|
|
Database files), and use $(D WindowsTimeZone) on Windows systems.
|
|
The time in $(D SysTime) is kept internally in hnsecs from midnight,
|
|
January 1st, 1 A.D. UTC. Conversion error cannot happen 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, see 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(dur!"minutes"(-60)), 36_000_000_000L);
|
|
test(DateTime(1, 1, 1, 0, 0, 0), new SimpleTimeZone(Duration.zero), 0);
|
|
test(DateTime(1, 1, 1, 0, 0, 0), new SimpleTimeZone(dur!"minutes"(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);
|
|
}
|
|
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);
|
|
}
|
|
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;
|
|
|
|
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;
|
|
|
|
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 SysTime rhs) const pure nothrow
|
|
{
|
|
return opEquals(rhs);
|
|
}
|
|
|
|
/// ditto
|
|
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(SysTime st,
|
|
immutable TimeZone tz1,
|
|
immutable TimeZone tz2)
|
|
{
|
|
auto st1 = st;
|
|
st1.timezone = tz1;
|
|
|
|
auto st2 = st;
|
|
st2.timezone = tz2;
|
|
|
|
_assertPred!("opCmp", "==")(st1, st2);
|
|
}
|
|
|
|
auto sts = array(map!SysTime(chain(testDateTimesBC, testDateTimesAD)));
|
|
|
|
foreach(st; sts)
|
|
foreach(tz1; testTZs)
|
|
foreach(tz2; testTZs)
|
|
testEqual(st, tz1, tz2);
|
|
|
|
static void testCmp(SysTime st1,
|
|
immutable TimeZone tz1,
|
|
SysTime st2,
|
|
immutable TimeZone tz2)
|
|
{
|
|
st1.timezone = tz1;
|
|
st2.timezone = tz2;
|
|
_assertPred!("opCmp", "<")(st1, st2);
|
|
_assertPred!("opCmp", ">")(st2, st1);
|
|
}
|
|
|
|
foreach(si, st1; sts)
|
|
foreach(st2; sts[si+1 .. $])
|
|
foreach(tz1; testTZs)
|
|
foreach(tz2; testTZs)
|
|
testCmp(st1, tz1, st2, 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
|
|
{
|
|
foreach(day; chain(testDays))
|
|
{
|
|
foreach(st; chain(testSysTimesBC, testSysTimesAD))
|
|
{
|
|
auto dt = cast(DateTime)st;
|
|
|
|
if(day > maxDay(dt.year, dt.month))
|
|
continue;
|
|
|
|
auto expected = SysTime(DateTime(dt.year, dt.month, day, dt.hour, dt.minute, dt.second),
|
|
st.fracSec,
|
|
st.timezone);
|
|
|
|
st.day = day;
|
|
assert(st == expected, format("[%s] [%s]", st, expected));
|
|
}
|
|
}
|
|
|
|
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);
|
|
auto expected = SysTime(DateTime(Date(year, month, max), tod), fs, tz);
|
|
|
|
st.day = max;
|
|
assert(st == expected, format("[%s] [%s]", st, expected));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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
|
|
{
|
|
foreach(hour; chain(testHours))
|
|
{
|
|
foreach(st; chain(testSysTimesBC, testSysTimesAD))
|
|
{
|
|
auto dt = cast(DateTime)st;
|
|
auto expected = SysTime(DateTime(dt.year, dt.month, dt.day, hour, dt.minute, dt.second),
|
|
st.fracSec,
|
|
st.timezone);
|
|
|
|
st.hour = hour;
|
|
assert(st == expected, format("[%s] [%s]", st, expected));
|
|
}
|
|
}
|
|
|
|
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
|
|
{
|
|
foreach(minute; testMinSecs)
|
|
{
|
|
foreach(st; chain(testSysTimesBC, testSysTimesAD))
|
|
{
|
|
auto dt = cast(DateTime)st;
|
|
auto expected = SysTime(DateTime(dt.year, dt.month, dt.day, dt.hour, minute, dt.second),
|
|
st.fracSec,
|
|
st.timezone);
|
|
|
|
st.minute = minute;
|
|
assert(st == expected, format("[%s] [%s]", st, expected));
|
|
}
|
|
}
|
|
|
|
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
|
|
{
|
|
foreach(second; testMinSecs)
|
|
{
|
|
foreach(st; chain(testSysTimesBC, testSysTimesAD))
|
|
{
|
|
auto dt = cast(DateTime)st;
|
|
auto expected = SysTime(DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, second),
|
|
st.fracSec,
|
|
st.timezone);
|
|
|
|
st.second = second;
|
|
assert(st == expected, format("[%s] [%s]", st, expected));
|
|
}
|
|
}
|
|
|
|
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
|
|
{
|
|
foreach(fracSec; testFracSecs)
|
|
{
|
|
foreach(st; chain(testSysTimesBC, testSysTimesAD))
|
|
{
|
|
auto dt = cast(DateTime)st;
|
|
auto expected = SysTime(DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second),
|
|
fracSec,
|
|
st.timezone);
|
|
|
|
st.fracSec = fracSec;
|
|
assert(st == expected, format("[%s] [%s]", st, expected));
|
|
}
|
|
}
|
|
|
|
auto st = testSysTimesAD[0];
|
|
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;
|
|
}
|
|
|
|
|
|
/++
|
|
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 what the offset from UTC is for this $(D SysTime).
|
|
It includes the DST offset in effect at that time (if any).
|
|
+/
|
|
@property Duration utcOffset() const nothrow
|
|
{
|
|
return _timezone.utcOffsetAt(_stdTime);
|
|
}
|
|
|
|
|
|
/++
|
|
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(dur!"minutes"(-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(dur!"minutes"(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. Rolling a $(D SysTime) 12 months
|
|
gets 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. For instance, rolling a $(D SysTime) one
|
|
year's worth of days gets 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);
|
|
|
|
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.
|
|
|
|
To get the difference in years, subtract the year property
|
|
of two $(D SysTime)s. To get the difference in days or weeks,
|
|
subtract the $(D SysTime)s themselves and use the $(D Duration)
|
|
that results. Because converting between months and smaller
|
|
units requires a specific date (which $(D Duration)s don't have),
|
|
getting the difference in months requires 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;
|
|
|
|
long 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);
|
|
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;
|
|
}
|
|
|
|
//Explicitly undocumented. Do not use. To be removed in March 2013.
|
|
deprecated("Please use daysInMonth instead.") @property ubyte endOfMonthDay() const nothrow
|
|
{
|
|
return Date(dayOfGregorianCal).daysInMonth;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
|
|
/++
|
|
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 is LocalTime())
|
|
return dateTime.toISOString() ~ fracSecToISOString(cast(int)hnsecs);
|
|
|
|
if(_timezone is UTC())
|
|
return dateTime.toISOString() ~ fracSecToISOString(cast(int)hnsecs) ~ "Z";
|
|
|
|
immutable utcOffset = dur!"hnsecs"(adjustedTime - stdTime);
|
|
|
|
return format("%s%s%s",
|
|
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(dur!"minutes"(-360))).toISOString(),
|
|
"20121221T121212-06:00");
|
|
|
|
_assertPred!"=="(SysTime(DateTime(2012, 12, 21, 12, 12, 12),
|
|
new SimpleTimeZone(dur!"minutes"(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 is LocalTime())
|
|
return dateTime.toISOExtString() ~ fracSecToISOString(cast(int)hnsecs);
|
|
|
|
if(_timezone is UTC())
|
|
return dateTime.toISOExtString() ~ fracSecToISOString(cast(int)hnsecs) ~ "Z";
|
|
|
|
immutable utcOffset = dur!"hnsecs"(adjustedTime - stdTime);
|
|
|
|
return format("%s%s%s",
|
|
dateTime.toISOExtString(),
|
|
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()).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(dur!"minutes"(-360))).toISOExtString(),
|
|
"2012-12-21T12:12:12-06:00");
|
|
|
|
_assertPred!"=="(SysTime(DateTime(2012, 12, 21, 12, 12, 12),
|
|
new SimpleTimeZone(dur!"minutes"(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 is LocalTime())
|
|
return dateTime.toSimpleString() ~ fracSecToISOString(cast(int)hnsecs);
|
|
|
|
if(_timezone is UTC())
|
|
return dateTime.toSimpleString() ~ fracSecToISOString(cast(int)hnsecs) ~ "Z";
|
|
|
|
immutable utcOffset = dur!"hnsecs"(adjustedTime - stdTime);
|
|
|
|
return format("%s%s%s",
|
|
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(dur!"minutes"(-360))).toSimpleString(),
|
|
"2012-Dec-21 12:12:12-06:00");
|
|
|
|
_assertPred!"=="(SysTime(DateTime(2012, 12, 21, 12, 12, 12),
|
|
new SimpleTimeZone(dur!"minutes"(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
|
|
$(LREF SimpleTimeZone) which corresponds to the given offset from UTC is
|
|
used. To get the returned $(D SysTime) to be a particular time
|
|
zone, 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(dur!"hours"(-8))));
|
|
assert(SysTime.fromISOString("20100704T070612+8:00") ==
|
|
SysTime(DateTime(2010, 7, 4, 7, 6, 12),
|
|
new SimpleTimeZone(dur!"hours"(8))));
|
|
--------------------
|
|
+/
|
|
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);
|
|
Rebindable!(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);
|
|
|
|
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(dur!"minutes"(-60))));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201-1"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(dur!"minutes"(-60))));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201-1:30"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(dur!"minutes"(-90))));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201-8:00"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(dur!"minutes"(-480))));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201+1:00"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(dur!"minutes"(60))));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201+1"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(dur!"minutes"(60))));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201+1:30"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(dur!"minutes"(90))));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201+8:00"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(dur!"minutes"(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(dur!"minutes"(-60))));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201.45-1"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(4_500_000),
|
|
new SimpleTimeZone(dur!"minutes"(-60))));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201.1-1:30"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(1_000_000),
|
|
new SimpleTimeZone(dur!"minutes"(-90))));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201.55-8:00"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(5_500_000),
|
|
new SimpleTimeZone(dur!"minutes"(-480))));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201.1234567+1:00"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(1_234_567),
|
|
new SimpleTimeZone(dur!"minutes"(60))));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201.0+1"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(0),
|
|
new SimpleTimeZone(dur!"minutes"(60))));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201.0000000+1:30"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(0),
|
|
new SimpleTimeZone(dur!"minutes"(90))));
|
|
_assertPred!"=="(SysTime.fromISOString("20101222T172201.45+8:00"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), FracSec.from!"hnsecs"(4_500_000),
|
|
new SimpleTimeZone(dur!"minutes"(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(dur!"hours"(-8))));
|
|
assert(SysTime.fromISOString("20100704T070612+8:00") ==
|
|
SysTime(DateTime(2010, 7, 4, 7, 6, 12), new SimpleTimeZone(dur!"hours"(8))));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
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
|
|
$(LREF SimpleTimeZone) which corresponds to the given offset from UTC is
|
|
used. To get the returned $(D SysTime) to be a particular time
|
|
zone, 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(dur!"hours"(-8))));
|
|
assert(SysTime.fromISOExtString("2010-07-04T07:06:12+8:00") ==
|
|
SysTime(DateTime(2010, 7, 4, 7, 6, 12),
|
|
new SimpleTimeZone(dur!"hours"(8))));
|
|
--------------------
|
|
+/
|
|
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);
|
|
Rebindable!(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);
|
|
|
|
if(tz !is null)
|
|
retval.timezone = tz;
|
|
|
|
return retval;
|
|
}
|
|
catch(DateTimeException dte)
|
|
throw new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString));
|
|
}
|
|
|
|
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(dur!"minutes"(-60))));
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-12-22T17:22:01-1"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(dur!"minutes"(-60))));
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-12-22T17:22:01-1:30"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(dur!"minutes"(-90))));
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-12-22T17:22:01-8:00"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(dur!"minutes"(-480))));
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-12-22T17:22:01+1:00"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(dur!"minutes"(60))));
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-12-22T17:22:01+1"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(dur!"minutes"(60))));
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-12-22T17:22:01+1:30"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(dur!"minutes"(90))));
|
|
_assertPred!"=="(SysTime.fromISOExtString("2010-12-22T17:22:01+8:00"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(dur!"minutes"(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(dur!"minutes"(-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(dur!"minutes"(-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(dur!"minutes"(-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(dur!"minutes"(-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(dur!"minutes"(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(dur!"minutes"(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(dur!"minutes"(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(dur!"minutes"(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(dur!"hours"(-8))));
|
|
assert(SysTime.fromISOExtString("2010-07-04T07:06:12+8:00") ==
|
|
SysTime(DateTime(2010, 7, 4, 7, 6, 12), new SimpleTimeZone(dur!"hours"(8))));
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
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
|
|
$(LREF SimpleTimeZone) which corresponds to the given offset from UTC is
|
|
used. To get the returned $(D SysTime) to be a particular time
|
|
zone, 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(dur!"hours"(-8))));
|
|
assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12+8:00") ==
|
|
SysTime(DateTime(2010, 7, 4, 7, 6, 12),
|
|
new SimpleTimeZone(dur!"hours"(8))));
|
|
--------------------
|
|
+/
|
|
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);
|
|
Rebindable!(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);
|
|
|
|
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(dur!"minutes"(-60))));
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Dec-22 17:22:01-1"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(dur!"minutes"(-60))));
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Dec-22 17:22:01-1:30"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(dur!"minutes"(-90))));
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Dec-22 17:22:01-8:00"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(dur!"minutes"(-480))));
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Dec-22 17:22:01+1:00"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(dur!"minutes"(60))));
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Dec-22 17:22:01+1"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(dur!"minutes"(60))));
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Dec-22 17:22:01+1:30"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(dur!"minutes"(90))));
|
|
_assertPred!"=="(SysTime.fromSimpleString("2010-Dec-22 17:22:01+8:00"),
|
|
SysTime(DateTime(2010, 12, 22, 17, 22, 01), new SimpleTimeZone(dur!"minutes"(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(dur!"minutes"(-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(dur!"minutes"(-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(dur!"minutes"(-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(dur!"minutes"(-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(dur!"minutes"(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(dur!"minutes"(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(dur!"minutes"(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(dur!"minutes"(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(dur!"hours"(-8))));
|
|
assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12+8:00") ==
|
|
SysTime(DateTime(2010, 7, 4, 7, 6, 12), new SimpleTimeZone(dur!"hours"(8))));
|
|
}
|
|
}
|
|
|
|
|
|
//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 !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;
|
|
Rebindable!(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. Rolling a $(D Date) 12 months gets
|
|
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. For instance, rolling a $(D Date) one
|
|
year's worth of days gets 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.
|
|
|
|
To get the difference in years, subtract the year property
|
|
of two $(D SysTime)s. To get the difference in days or weeks,
|
|
subtract the $(D SysTime)s themselves and use the $(D Duration)
|
|
that results. Because converting between months and smaller
|
|
units requires a specific date (which $(D Duration)s don't have),
|
|
getting the difference in months requires 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
|
|
{
|
|
if (_month >= Month.jan && _month <= Month.dec)
|
|
{
|
|
immutable int[] lastDay = isLeapYear ? lastDayLeap : lastDayNonLeap;
|
|
auto monthIndex = _month - Month.jan;
|
|
|
|
return cast(ushort)(lastDay[monthIndex] + _day);
|
|
}
|
|
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
|
|
{
|
|
immutable int[] lastDay = isLeapYear ? lastDayLeap : lastDayNonLeap;
|
|
|
|
if(day <= 0 || day > (isLeapYear ? daysInLeapYear : daysInYear) )
|
|
throw new DateTimeException("Invalid day of the year.");
|
|
|
|
foreach (i; 1..lastDay.length)
|
|
{
|
|
if (day <= lastDay[i])
|
|
{
|
|
_month = cast(Month)(cast(int)Month.jan + i - 1);
|
|
_day = cast(ubyte)(day - lastDay[i - 1]);
|
|
return;
|
|
}
|
|
}
|
|
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);
|
|
}
|
|
|
|
//Explicitly undocumented. Do not use. To be removed in March 2013.
|
|
deprecated("Please use daysInMonth instead.") @property ubyte endOfMonthDay() const nothrow
|
|
{
|
|
return maxDay(_year, _month);
|
|
}
|
|
|
|
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.");
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
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. For instance, rolling a $(D TimeOfDay)
|
|
one hours's worth of minutes gets 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.");
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
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 an object
|
|
which holds both the date and the time. It is optimized for calendar-based
|
|
operations and has no concept of time zone. For an object which is
|
|
optimized for time operations based on the system time, 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. Rolling a $(D DateTime) 12 months
|
|
gets 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. For instance, rolling a $(D DateTime) one
|
|
year's worth of days gets 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.
|
|
|
|
To get the difference in years, subtract the year property
|
|
of two $(D SysTime)s. To get the difference in days or weeks,
|
|
subtract the $(D SysTime)s themselves and use the $(D Duration)
|
|
that results. Because converting between months and smaller
|
|
units requires a specific date (which $(D Duration)s don't have),
|
|
getting the difference in months requires 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;
|
|
}
|
|
|
|
//Explicitly undocumented. Do not use. To be removed in March 2013.
|
|
deprecated("Please use daysInMonth instead.") @property ubyte endOfMonthDay() const nothrow
|
|
{
|
|
return _date.daysInMonth;
|
|
}
|
|
|
|
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.");
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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 iteration 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," making them easily searchable.
|
|
|
|
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.
|
|
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 when creating a custom 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," making them easily searchable.
|
|
|
|
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.
|
|
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 for custom delegates.
|
|
|
|
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 = delegate (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 = delegate (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), because an interval
|
|
going from negative infinity to positive infinity
|
|
is not possible.
|
|
|
|
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), because an interval
|
|
going from negative infinity to positive infinity
|
|
is not possible.
|
|
|
|
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), because an interval
|
|
going from negative infinity to positive infinity
|
|
is not possible.
|
|
|
|
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), because an interval
|
|
going from negative infinity to positive infinity
|
|
is not possible.
|
|
|
|
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," to make them easily searchable.
|
|
|
|
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.
|
|
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 for custom delegates.
|
|
|
|
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 = delegate (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.
|
|
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), because an interval
|
|
going from negative infinity to positive infinity
|
|
is not possible.
|
|
|
|
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), because an interval
|
|
going from negative infinity to positive infinity
|
|
is not possible.
|
|
|
|
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), because an interval
|
|
going from negative infinity to positive infinity
|
|
is not possible.
|
|
|
|
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), because an interval
|
|
going from negative infinity to positive infinity
|
|
is not possible.
|
|
|
|
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," to make them easily searchable.
|
|
|
|
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.
|
|
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 for custom delegates.
|
|
|
|
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 = delegate (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 iteration 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 iteration over successive time points
|
|
which are in the same month but different years. For example,
|
|
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 iteration 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 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. For instance,
|
|
to iterate over all of the days in
|
|
the interval $(D Interval!Date), 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, to iterate 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. To iterate 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 iterating
|
|
forward and the generated time point is before $(D front), or if
|
|
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. For
|
|
instance, to iterate
|
|
over all of the days in the interval $(D PosInfInterval!Date), 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,
|
|
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. For
|
|
instance, to iterate
|
|
over all of the days in the interval $(D NegInfInterval!Date), 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,
|
|
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 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)<br>
|
|
$(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 what the offset from UTC is at the given std time.
|
|
It includes the DST offset in effect at that time (if any).
|
|
|
|
Params:
|
|
stdTime = The UTC time for which to get the offset from UTC for this
|
|
time zone.
|
|
+/
|
|
Duration utcOffsetAt(long stdTime) const nothrow
|
|
{
|
|
return dur!"hnsecs"(utcToTZ(stdTime) - stdTime);
|
|
}
|
|
|
|
|
|
/++
|
|
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. For
|
|
$(D PosixTimeZone) on Windows, 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). This function allows for
|
|
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)<br>
|
|
$(WEB en.wikipedia.org/wiki/List_of_tz_database_time_zones, List of
|
|
Time Zones)<br>
|
|
$(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 desired time zone
|
|
|
|
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 immutable(TimeZone) testTZ(string tzName,
|
|
string stdName,
|
|
string dstName,
|
|
Duration utcOffset,
|
|
Duration dstOffset,
|
|
bool north = true)
|
|
{
|
|
scope(failure) writefln("Failed time zone: %s", tzName);
|
|
|
|
immutable tz = TimeZone.getTimeZone(tzName);
|
|
immutable hasDST = dstOffset != dur!"hnsecs"(0);
|
|
|
|
version(Posix)
|
|
_assertPred!"=="(tz.name, tzName);
|
|
else version(Windows)
|
|
_assertPred!"=="(tz.name, stdName);
|
|
|
|
//_assertPred!"=="(tz.stdName, stdName); //Locale-dependent
|
|
//_assertPred!"=="(tz.dstName, dstName); //Locale-dependent
|
|
_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 - utcOffset, UTC());
|
|
auto dstUTC = SysTime(stdDate - utcOffset + dstOffset, UTC());
|
|
|
|
assert(!std.dstInEffect);
|
|
_assertPred!"=="(dst.dstInEffect, hasDST);
|
|
_assertPred!"=="(tz.utcOffsetAt(std.stdTime), utcOffset);
|
|
_assertPred!"=="(tz.utcOffsetAt(dst.stdTime), utcOffset + dstOffset);
|
|
|
|
_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_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); //Locale-dependent
|
|
//assert(leapTZ.dstName == dstName); //Locale-dependent
|
|
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")(25);
|
|
//_assertPred!"=="(leapSTD.adjTime - leapDiff, std.adjTime);
|
|
//_assertPred!"=="(leapDST.adjTime - leapDiff, dst.adjTime);
|
|
}
|
|
}
|
|
|
|
return tz;
|
|
}
|
|
|
|
auto dstSwitches = [/+America/Los_Angeles+/ tuple(DateTime(2012, 3, 11), DateTime(2012, 11, 4), 2, 2),
|
|
/+America/New_York+/ tuple(DateTime(2012, 3, 11), DateTime(2012, 11, 4), 2, 2),
|
|
///+America/Santiago+/ tuple(DateTime(2011, 8, 21), DateTime(2011, 5, 8), 0, 0),
|
|
/+Europe/London+/ tuple(DateTime(2012, 3, 25), DateTime(2012, 10, 28), 1, 2),
|
|
/+Europe/Paris+/ tuple(DateTime(2012, 3, 25), DateTime(2012, 10, 28), 2, 3),
|
|
/+Australia/Adelaide+/ tuple(DateTime(2012, 10, 7), DateTime(2012, 4, 1), 2, 3)];
|
|
|
|
version(Posix)
|
|
{
|
|
version(FreeBSD) enum utcZone = "Etc/UTC";
|
|
version(linux) enum utcZone = "UTC";
|
|
version(OSX) enum utcZone = "UTC";
|
|
|
|
auto tzs = [testTZ("America/Los_Angeles", "PST", "PDT", dur!"hours"(-8), dur!"hours"(1)),
|
|
testTZ("America/New_York", "EST", "EDT", dur!"hours"(-5), dur!"hours"(1)),
|
|
//testTZ("America/Santiago", "CLT", "CLST", dur!"hours"(-4), dur!"hours"(1), false),
|
|
testTZ("Europe/London", "GMT", "BST", dur!"hours"(0), dur!"hours"(1)),
|
|
testTZ("Europe/Paris", "CET", "CEST", dur!"hours"(1), dur!"hours"(1)),
|
|
//Per www.timeanddate.com, it should be "CST" and "CDT",
|
|
//but the OS insists that it's "CST" for both. We should
|
|
//probably figure out how to report an error in the TZ
|
|
//database and report it.
|
|
testTZ("Australia/Adelaide", "CST", "CST",
|
|
dur!"hours"(9) + dur!"minutes"(30), dur!"hours"(1), false)];
|
|
|
|
testTZ(utcZone, "UTC", "UTC", dur!"hours"(0), dur!"hours"(0));
|
|
assertThrown!DateTimeException(PosixTimeZone.getTimeZone("hello_world"));
|
|
}
|
|
else version(Windows)
|
|
{
|
|
auto tzs = [testTZ("America/Los_Angeles", "Pacific Standard Time",
|
|
"Pacific Daylight Time", dur!"hours"(-8), dur!"hours"(1)),
|
|
testTZ("America/New_York", "Eastern Standard Time",
|
|
"Eastern Daylight Time", dur!"hours"(-5), dur!"hours"(1)),
|
|
//testTZ("America/Santiago", "Pacific SA Standard Time",
|
|
//"Pacific SA Daylight Time", dur!"hours"(-4), dur!"hours"(1), false),
|
|
testTZ("Europe/London", "GMT Standard Time",
|
|
"GMT Daylight Time", dur!"hours"(0), dur!"hours"(1)),
|
|
testTZ("Europe/Paris", "Romance Standard Time",
|
|
"Romance Daylight Time", dur!"hours"(1), dur!"hours"(1)),
|
|
testTZ("Australia/Adelaide", "Cen. Australia Standard Time",
|
|
"Cen. Australia Daylight Time",
|
|
dur!"hours"(9) + dur!"minutes"(30), dur!"hours"(1), false)];
|
|
|
|
testTZ("Atlantic/Reykjavik", "Greenwich Standard Time",
|
|
"Greenwich Daylight Time", dur!"hours"(0), dur!"hours"(0));
|
|
assertThrown!DateTimeException(WindowsTimeZone.getTimeZone("hello_world"));
|
|
}
|
|
else
|
|
assert(0, "OS not supported.");
|
|
|
|
foreach(i; 0 .. tzs.length)
|
|
{
|
|
auto tz = tzs[i];
|
|
immutable spring = dstSwitches[i][2];
|
|
immutable fall = dstSwitches[i][3];
|
|
auto stdOffset = SysTime(dstSwitches[i][0] + dur!"days"(-1), tz).utcOffset;
|
|
auto dstOffset = stdOffset + dur!"hours"(1);
|
|
|
|
//Verify that creating a SysTime in the given time zone results
|
|
//in a SysTime with the correct std time during and surrounding
|
|
//a DST switch.
|
|
foreach(hour; -12 .. 13)
|
|
{
|
|
auto st = SysTime(dstSwitches[i][0] + dur!"hours"(hour), tz);
|
|
immutable targetHour = hour < 0 ? hour + 24 : hour;
|
|
|
|
static void testHour(SysTime st, int hour, string tzName, size_t line = __LINE__)
|
|
{
|
|
enforce(st.hour == hour,
|
|
new AssertError(format("[%s] [%s]: [%s] [%s]", st, tzName, st.hour, hour),
|
|
__FILE__, line));
|
|
}
|
|
|
|
void testOffset1(Duration offset, bool dstInEffect, size_t line = __LINE__)
|
|
{
|
|
AssertError msg(string tag)
|
|
{
|
|
return new AssertError(format("%s [%s] [%s]: [%s] [%s] [%s]",
|
|
tag, st, tz.name, st.utcOffset, stdOffset, dstOffset),
|
|
__FILE__, line);
|
|
}
|
|
|
|
enforce(st.dstInEffect == dstInEffect, msg("1"));
|
|
enforce(st.utcOffset == offset, msg("2"));
|
|
enforce((st + dur!"minutes"(1)).utcOffset == offset, msg("3"));
|
|
}
|
|
|
|
if(hour == spring)
|
|
{
|
|
testHour(st, spring + 1, tz.name);
|
|
testHour(st + dur!"minutes"(1), spring + 1, tz.name);
|
|
}
|
|
else
|
|
{
|
|
testHour(st, targetHour, tz.name);
|
|
testHour(st + dur!"minutes"(1), targetHour, tz.name);
|
|
}
|
|
|
|
if(hour < spring)
|
|
testOffset1(stdOffset, false);
|
|
else
|
|
testOffset1(dstOffset, true);
|
|
|
|
st = SysTime(dstSwitches[i][1] + dur!"hours"(hour), tz);
|
|
testHour(st, targetHour, tz.name);
|
|
|
|
//Verify that 01:00 is the first 01:00 (or whatever hour before the switch is).
|
|
if(hour == fall - 1)
|
|
testHour(st + dur!"hours"(1), targetHour, tz.name);
|
|
|
|
if(hour < fall)
|
|
testOffset1(dstOffset, true);
|
|
else
|
|
testOffset1(stdOffset, false);
|
|
}
|
|
|
|
//Verify that converting a time in UTC to a time in another
|
|
//time zone results in the correct time during and surrounding
|
|
//a DST switch.
|
|
bool first = true;
|
|
auto springSwitch = SysTime(dstSwitches[i][0] + dur!"hours"(spring), UTC()) - stdOffset;
|
|
auto fallSwitch = SysTime(dstSwitches[i][1] + dur!"hours"(fall), UTC()) - dstOffset;
|
|
//@@@BUG@@@ 3659 makes this necessary.
|
|
auto fallSwitchMinus1 = fallSwitch - dur!"hours"(1);
|
|
|
|
foreach(hour; -24 .. 25)
|
|
{
|
|
auto utc = SysTime(dstSwitches[i][0] + dur!"hours"(hour), UTC());
|
|
auto local = utc.toOtherTZ(tz);
|
|
|
|
void testOffset2(Duration offset, size_t line = __LINE__)
|
|
{
|
|
AssertError msg(string tag)
|
|
{
|
|
return new AssertError(format("%s [%s] [%s]: [%s] [%s]", tag, hour, tz.name, utc, local),
|
|
__FILE__, line);
|
|
}
|
|
|
|
enforce((utc + offset).hour == local.hour, msg("1"));
|
|
enforce((utc + offset + dur!"minutes"(1)).hour == local.hour, msg("2"));
|
|
}
|
|
|
|
if(utc < springSwitch)
|
|
testOffset2(stdOffset);
|
|
else
|
|
testOffset2(dstOffset);
|
|
|
|
utc = SysTime(dstSwitches[i][1] + dur!"hours"(hour), UTC());
|
|
local = utc.toOtherTZ(tz);
|
|
|
|
if(utc == fallSwitch || utc == fallSwitchMinus1)
|
|
{
|
|
if(first)
|
|
{
|
|
testOffset2(dstOffset);
|
|
first = false;
|
|
}
|
|
else
|
|
testOffset2(stdOffset);
|
|
}
|
|
else if(utc > fallSwitch)
|
|
testOffset2(stdOffset);
|
|
else
|
|
testOffset2(dstOffset);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns a list of the names of the time zones installed on the system.
|
|
|
|
Providing a sub-name narrows down the list of time zones (which
|
|
can number in the thousands). For example,
|
|
passing in "America" as the sub-name returns only the time zones which
|
|
begin with "America".
|
|
|
|
On Windows, this function will convert the Windows time zone names to
|
|
the corresponding TZ Database names with
|
|
$(D windowsTZNameToTZDatabaseName). To get the actual Windows time
|
|
zone names, use $(D WindowsTimeZone.getInstalledTZNames) directly.
|
|
|
|
Params:
|
|
subName = The first part of the time zones desired.
|
|
|
|
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
|
|
{
|
|
alias pure nothrow immutable(LocalTime) function() FuncType;
|
|
return (cast(FuncType)&singleton)();
|
|
}
|
|
|
|
|
|
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)<br>
|
|
$(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);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
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);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
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);
|
|
|
|
immutable past = unixTime - cast(time_t)convert!("days", "seconds")(1);
|
|
tm* timeInfo = localtime(past < unixTime ? &past : &unixTime);
|
|
immutable pastOffset = timeInfo.tm_gmtoff;
|
|
|
|
immutable future = unixTime + cast(time_t)convert!("days", "seconds")(1);
|
|
timeInfo = localtime(future > unixTime ? &future : &unixTime);
|
|
immutable futureOffset = timeInfo.tm_gmtoff;
|
|
|
|
if(pastOffset == futureOffset)
|
|
return adjTime - convert!("seconds", "hnsecs")(pastOffset);
|
|
|
|
if(pastOffset < futureOffset)
|
|
unixTime -= cast(time_t)convert!("hours", "seconds")(1);
|
|
|
|
unixTime -= pastOffset;
|
|
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)
|
|
{
|
|
assert(LocalTime().tzToUTC(LocalTime().utcToTZ(0)) == 0);
|
|
assert(LocalTime().utcToTZ(LocalTime().tzToUTC(0)) == 0);
|
|
|
|
_assertPred!"=="(LocalTime().tzToUTC(LocalTime().utcToTZ(0)), 0);
|
|
_assertPred!"=="(LocalTime().utcToTZ(LocalTime().tzToUTC(0)), 0);
|
|
|
|
version(Posix)
|
|
{
|
|
scope(exit) clearTZEnvVar();
|
|
|
|
auto tzInfos = [tuple("America/Los_Angeles", DateTime(2012, 3, 11), DateTime(2012, 11, 4), 2, 2),
|
|
tuple("America/New_York", DateTime(2012, 3, 11), DateTime(2012, 11, 4), 2, 2),
|
|
//tuple("America/Santiago", DateTime(2011, 8, 21), DateTime(2011, 5, 8), 0, 0),
|
|
tuple("Atlantic/Azores", DateTime(2011, 3, 27), DateTime(2011, 10, 30), 0, 1),
|
|
tuple("Europe/London", DateTime(2012, 3, 25), DateTime(2012, 10, 28), 1, 2),
|
|
tuple("Europe/Paris", DateTime(2012, 3, 25), DateTime(2012, 10, 28), 2, 3),
|
|
tuple("Australia/Adelaide", DateTime(2012, 10, 7), DateTime(2012, 4, 1), 2, 3)];
|
|
|
|
foreach(i; 0 .. tzInfos.length)
|
|
{
|
|
auto tzName = tzInfos[i][0];
|
|
setTZEnvVar(tzName);
|
|
immutable spring = tzInfos[i][3];
|
|
immutable fall = tzInfos[i][4];
|
|
auto stdOffset = SysTime(tzInfos[i][1] + dur!"hours"(-12)).utcOffset;
|
|
auto dstOffset = stdOffset + dur!"hours"(1);
|
|
|
|
//Verify that creating a SysTime in the given time zone results
|
|
//in a SysTime with the correct std time during and surrounding
|
|
//a DST switch.
|
|
foreach(hour; -12 .. 13)
|
|
{
|
|
auto st = SysTime(tzInfos[i][1] + dur!"hours"(hour));
|
|
immutable targetHour = hour < 0 ? hour + 24 : hour;
|
|
|
|
static void testHour(SysTime st, int hour, string tzName, size_t line = __LINE__)
|
|
{
|
|
enforce(st.hour == hour,
|
|
new AssertError(format("[%s] [%s]: [%s] [%s]", st, tzName, st.hour, hour),
|
|
__FILE__, line));
|
|
}
|
|
|
|
void testOffset1(Duration offset, bool dstInEffect, size_t line = __LINE__)
|
|
{
|
|
AssertError msg(string tag)
|
|
{
|
|
return new AssertError(format("%s [%s] [%s]: [%s] [%s] [%s]",
|
|
tag, st, tzName, st.utcOffset, stdOffset, dstOffset),
|
|
__FILE__, line);
|
|
}
|
|
|
|
enforce(st.dstInEffect == dstInEffect, msg("1"));
|
|
enforce(st.utcOffset == offset, msg("2"));
|
|
enforce((st + dur!"minutes"(1)).utcOffset == offset, msg("3"));
|
|
}
|
|
|
|
if(hour == spring)
|
|
{
|
|
testHour(st, spring + 1, tzName);
|
|
testHour(st + dur!"minutes"(1), spring + 1, tzName);
|
|
}
|
|
else
|
|
{
|
|
testHour(st, targetHour, tzName);
|
|
testHour(st + dur!"minutes"(1), targetHour, tzName);
|
|
}
|
|
|
|
if(hour < spring)
|
|
testOffset1(stdOffset, false);
|
|
else
|
|
testOffset1(dstOffset, true);
|
|
|
|
st = SysTime(tzInfos[i][2] + dur!"hours"(hour));
|
|
testHour(st, targetHour, tzName);
|
|
|
|
//Verify that 01:00 is the first 01:00 (or whatever hour before the switch is).
|
|
if(hour == fall - 1)
|
|
testHour(st + dur!"hours"(1), targetHour, tzName);
|
|
|
|
if(hour < fall)
|
|
testOffset1(dstOffset, true);
|
|
else
|
|
testOffset1(stdOffset, false);
|
|
}
|
|
|
|
//Verify that converting a time in UTC to a time in another
|
|
//time zone results in the correct time during and surrounding
|
|
//a DST switch.
|
|
bool first = true;
|
|
auto springSwitch = SysTime(tzInfos[i][1] + dur!"hours"(spring), UTC()) - stdOffset;
|
|
auto fallSwitch = SysTime(tzInfos[i][2] + dur!"hours"(fall), UTC()) - dstOffset;
|
|
//@@@BUG@@@ 3659 makes this necessary.
|
|
auto fallSwitchMinus1 = fallSwitch - dur!"hours"(1);
|
|
|
|
foreach(hour; -24 .. 25)
|
|
{
|
|
auto utc = SysTime(tzInfos[i][1] + dur!"hours"(hour), UTC());
|
|
auto local = utc.toLocalTime();
|
|
|
|
void testOffset2(Duration offset, size_t line = __LINE__)
|
|
{
|
|
AssertError msg(string tag)
|
|
{
|
|
return new AssertError(format("%s [%s] [%s]: [%s] [%s]", tag, hour, tzName, utc, local),
|
|
__FILE__, line);
|
|
}
|
|
|
|
enforce((utc + offset).hour == local.hour, msg("1"));
|
|
enforce((utc + offset + dur!"minutes"(1)).hour == local.hour, msg("2"));
|
|
}
|
|
|
|
if(utc < springSwitch)
|
|
testOffset2(stdOffset);
|
|
else
|
|
testOffset2(dstOffset);
|
|
|
|
utc = SysTime(tzInfos[i][2] + dur!"hours"(hour), UTC());
|
|
local = utc.toLocalTime();
|
|
|
|
if(utc == fallSwitch || utc == fallSwitchMinus1)
|
|
{
|
|
if(first)
|
|
{
|
|
testOffset2(dstOffset);
|
|
first = false;
|
|
}
|
|
else
|
|
testOffset2(stdOffset);
|
|
}
|
|
else if(utc > fallSwitch)
|
|
testOffset2(stdOffset);
|
|
else
|
|
testOffset2(dstOffset);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private:
|
|
|
|
this() immutable
|
|
{
|
|
super("", "", "");
|
|
tzset();
|
|
}
|
|
|
|
|
|
static shared LocalTime _localTime;
|
|
static bool _initialized;
|
|
|
|
|
|
static immutable(LocalTime) singleton()
|
|
{
|
|
//TODO Make this use double-checked locking once shared has been fixed
|
|
//to use memory fences properly.
|
|
if(!_initialized)
|
|
{
|
|
synchronized
|
|
{
|
|
if(!_localTime)
|
|
_localTime = cast(shared LocalTime)new immutable(LocalTime)();
|
|
}
|
|
|
|
_initialized = true;
|
|
}
|
|
|
|
return cast(immutable LocalTime)_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
|
|
{
|
|
alias pure nothrow immutable(UTC) function() FuncType;
|
|
return (cast(FuncType)&singleton)();
|
|
}
|
|
|
|
|
|
/++
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
Returns a $(CXREF time, Duration) of 0.
|
|
|
|
Params:
|
|
stdTime = The UTC time for which to get the offset from UTC for this
|
|
time zone.
|
|
+/
|
|
override Duration utcOffsetAt(long stdTime) const nothrow
|
|
{
|
|
return dur!"hnsecs"(0);
|
|
}
|
|
|
|
|
|
private:
|
|
|
|
this() immutable pure
|
|
{
|
|
super("UTC", "UTC", "UTC");
|
|
}
|
|
|
|
|
|
static shared UTC _utc;
|
|
static bool _initialized;
|
|
|
|
|
|
static immutable(UTC) singleton()
|
|
{
|
|
//TODO Make this use double-checked locking once shared has been fixed
|
|
//to use memory fences properly.
|
|
if(!_initialized)
|
|
{
|
|
synchronized
|
|
{
|
|
if(!_utc)
|
|
_utc = cast(shared UTC)new immutable(UTC)();
|
|
}
|
|
|
|
_initialized = true;
|
|
}
|
|
|
|
return cast(immutable UTC)_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 + _utcOffset.total!"hnsecs";
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
auto west = new SimpleTimeZone(dur!"hours"(-8));
|
|
auto east = new SimpleTimeZone(dur!"hours"(8));
|
|
|
|
assert(west.utcToTZ(0) == -288_000_000_000L);
|
|
assert(east.utcToTZ(0) == 288_000_000_000L);
|
|
assert(west.utcToTZ(54_321_234_567_890L) == 54_033_234_567_890L);
|
|
|
|
const cstz = west;
|
|
static assert(__traits(compiles, west.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 - _utcOffset.total!"hnsecs";
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
auto west = new SimpleTimeZone(dur!"hours"(-8));
|
|
auto east = new SimpleTimeZone(dur!"hours"(8));
|
|
|
|
assert(west.tzToUTC(-288_000_000_000L) == 0);
|
|
assert(east.tzToUTC(288_000_000_000L) == 0);
|
|
assert(west.tzToUTC(54_033_234_567_890L) == 54_321_234_567_890L);
|
|
|
|
const cstz = west;
|
|
static assert(__traits(compiles, west.tzToUTC(20005)));
|
|
static assert(__traits(compiles, cstz.tzToUTC(20005)));
|
|
}
|
|
|
|
|
|
/++
|
|
Returns utcOffset as a $(CXREF time, Duration).
|
|
|
|
Params:
|
|
stdTime = The UTC time for which to get the offset from UTC for this
|
|
time zone.
|
|
+/
|
|
override Duration utcOffsetAt(long stdTime) const nothrow
|
|
{
|
|
return _utcOffset;
|
|
}
|
|
|
|
|
|
/++
|
|
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(Duration utcOffset, string stdName = "") immutable
|
|
{
|
|
//FIXME This probably needs to be changed to something like (-12 - 13).
|
|
enforceEx!DateTimeException(abs(utcOffset) < dur!"minutes"(1440),
|
|
"Offset from UTC must be within range (-24:00 - 24:00).");
|
|
|
|
super("", stdName, "");
|
|
this._utcOffset = utcOffset;
|
|
}
|
|
|
|
/++ Ditto +/
|
|
this(int utcOffset, string stdName = "") immutable
|
|
{
|
|
this(dur!"minutes"(utcOffset), stdName);
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
foreach(stz; [new SimpleTimeZone(dur!"hours"(-8), "PST"),
|
|
new SimpleTimeZone(-8 * 60, "PST")])
|
|
|
|
{
|
|
assert(stz.name == "");
|
|
assert(stz.stdName == "PST");
|
|
assert(stz.dstName == "");
|
|
assert(stz.utcOffset == -8 * 60);
|
|
}
|
|
}
|
|
|
|
|
|
/++
|
|
The number of minutes the offset from UTC is (negative is west of UTC,
|
|
positive is east).
|
|
+/
|
|
@property int utcOffset() @safe const pure nothrow
|
|
{
|
|
return cast(int)_utcOffset.total!"minutes";
|
|
}
|
|
|
|
|
|
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(Duration utcOffset)
|
|
{
|
|
immutable absOffset = abs(utcOffset);
|
|
enforceEx!DateTimeException(absOffset < dur!"minutes"(1440),
|
|
"Offset from UTC must be within range (-24:00 - 24:00).");
|
|
|
|
if(utcOffset < Duration.zero)
|
|
return format("-%02d:%02d", absOffset.hours, absOffset.minutes);
|
|
|
|
return format("+%02d:%02d", absOffset.hours, absOffset.minutes);
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
static string testSTZInvalid(Duration offset)
|
|
{
|
|
return SimpleTimeZone.toISOString(offset);
|
|
}
|
|
|
|
assertThrown!DateTimeException(testSTZInvalid(dur!"minutes"(1440)));
|
|
assertThrown!DateTimeException(testSTZInvalid(dur!"minutes"(-1440)));
|
|
|
|
assert(toISOString(dur!"minutes"(0)) == "+00:00");
|
|
assert(toISOString(dur!"minutes"(1)) == "+00:01");
|
|
assert(toISOString(dur!"minutes"(10)) == "+00:10");
|
|
assert(toISOString(dur!"minutes"(59)) == "+00:59");
|
|
assert(toISOString(dur!"minutes"(60)) == "+01:00");
|
|
assert(toISOString(dur!"minutes"(90)) == "+01:30");
|
|
assert(toISOString(dur!"minutes"(120)) == "+02:00");
|
|
assert(toISOString(dur!"minutes"(480)) == "+08:00");
|
|
assert(toISOString(dur!"minutes"(1439)) == "+23:59");
|
|
|
|
assert(toISOString(dur!"minutes"(-1)) == "-00:01");
|
|
assert(toISOString(dur!"minutes"(-10)) == "-00:10");
|
|
assert(toISOString(dur!"minutes"(-59)) == "-00:59");
|
|
assert(toISOString(dur!"minutes"(-60)) == "-01:00");
|
|
assert(toISOString(dur!"minutes"(-90)) == "-01:30");
|
|
assert(toISOString(dur!"minutes"(-120)) == "-02:00");
|
|
assert(toISOString(dur!"minutes"(-480)) == "-08:00");
|
|
assert(toISOString(dur!"minutes"(-1439)) == "-23:59");
|
|
}
|
|
|
|
|
|
/+
|
|
Takes a time zone as a string with an offset from UTC and returns a
|
|
$(LREF 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 * (dur!"hours"(hours) + dur!"minutes"(minutes)));
|
|
}
|
|
|
|
version(testStdDateTime) unittest
|
|
{
|
|
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"));
|
|
|
|
assert(SimpleTimeZone.fromISOString("+00:00").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(0))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("+00:01").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(1))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("+00:10").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(10))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("+00:59").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(59))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("+01:00").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(60))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("+01:30").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(90))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("+02:00").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(120))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("+08:00").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(480))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("+23:59").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(1439))).utcOffset);
|
|
|
|
assert(SimpleTimeZone.fromISOString("-00:01").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(-1))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("-00:10").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(-10))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("-00:59").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(-59))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("-01:00").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(-60))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("-01:30").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(-90))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("-02:00").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(-120))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("-08:00").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(-480))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("-23:59").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(-1439))).utcOffset);
|
|
|
|
assert(SimpleTimeZone.fromISOString("+0").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(0))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("+1").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(60))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("+2").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(120))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("+23").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(1380))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("+2").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(120))).utcOffset);
|
|
|
|
assert(SimpleTimeZone.fromISOString("+0").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(0))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("+1").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(60))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("+2").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(120))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("+23").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(1380))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("+1:00").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(60))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("+1:01").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(61))).utcOffset);
|
|
|
|
assert(SimpleTimeZone.fromISOString("-0").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(0))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("-1").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(-60))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("-2").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(-120))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("-23").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(-1380))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("-1:00").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(-60))).utcOffset);
|
|
assert(SimpleTimeZone.fromISOString("-1:01").utcOffset ==
|
|
(new SimpleTimeZone(dur!"minutes"(-61))).utcOffset);
|
|
}
|
|
|
|
//Test that converting from an ISO string to a SimpleTimeZone to an ISO String works properly.
|
|
version(testStdDateTime) unittest
|
|
{
|
|
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(dur!"minutes"(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);
|
|
}
|
|
|
|
|
|
immutable Duration _utcOffset;
|
|
}
|
|
|
|
|
|
/++
|
|
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. To use the TZ Database,
|
|
use $(LREF PosixTimeZone) (which reads its information from the TZ Database
|
|
files on disk) on Windows by providing the TZ Database files and telling
|
|
$(D PosixTimeZone.getTimeZone) where the directory holding them is.
|
|
|
|
To get a $(D PosixTimeZone), either call $(D PosixTimeZone.getTimeZone)
|
|
(which allows specifying the location the time zone files) or call
|
|
$(D TimeZone.getTimeZone) (which will give 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 the only way to get a time zone which
|
|
takes leap seconds into account is to 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 www.iana.org/time-zones, Home of the TZ Database files)<br>
|
|
$(WEB en.wikipedia.org/wiki/Tz_database, Wikipedia entry on TZ Database)<br>
|
|
$(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);
|
|
immutable found = countUntil!"b < a.timeT"(cast(Transition[])_transitions, unixTime);
|
|
|
|
if(found == -1)
|
|
return _transitions.back.ttInfo.isDST;
|
|
|
|
immutable transition = found == 0 ? _transitions[0] : _transitions[found - 1];
|
|
|
|
return transition.ttInfo.isDST;
|
|
}
|
|
catch(Exception e)
|
|
assert(0, format("Unexpected 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);
|
|
immutable found = countUntil!"b < a.timeT"(cast(Transition[])_transitions, unixTime);
|
|
|
|
if(found == -1)
|
|
return stdTime + convert!("seconds", "hnsecs")(_transitions.back.ttInfo.utcOffset + leapSecs);
|
|
|
|
immutable transition = found == 0 ? _transitions[0] : _transitions[found - 1];
|
|
|
|
return stdTime + convert!("seconds", "hnsecs")(transition.ttInfo.utcOffset + leapSecs);
|
|
}
|
|
catch(Exception e)
|
|
assert(0, format("Unexpected 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);
|
|
time_t unixTime = stdTimeToUnixTime(adjTime);
|
|
immutable past = unixTime - convert!("days", "seconds")(1);
|
|
immutable future = unixTime + convert!("days", "seconds")(1);
|
|
|
|
immutable pastFound = countUntil!"b < a.timeT"(cast(Transition[])_transitions, past);
|
|
|
|
if(pastFound == -1)
|
|
return adjTime - convert!("seconds", "hnsecs")(_transitions.back.ttInfo.utcOffset + leapSecs);
|
|
|
|
immutable futureFound = countUntil!"b < a.timeT"(cast(Transition[])_transitions[pastFound .. $], future);
|
|
immutable pastTrans = pastFound == 0 ? _transitions[0] : _transitions[pastFound - 1];
|
|
|
|
if(futureFound == 0)
|
|
return adjTime - convert!("seconds", "hnsecs")(pastTrans.ttInfo.utcOffset + leapSecs);
|
|
|
|
immutable futureTrans = futureFound == -1 ? _transitions.back
|
|
: _transitions[pastFound + futureFound - 1];
|
|
immutable pastOffset = pastTrans.ttInfo.utcOffset;
|
|
|
|
if(pastOffset < futureTrans.ttInfo.utcOffset)
|
|
unixTime -= convert!("hours", "seconds")(1);
|
|
|
|
immutable found = countUntil!"b < a.timeT"(cast(Transition[])_transitions[pastFound .. $],
|
|
unixTime - pastOffset);
|
|
|
|
if(found == -1)
|
|
return adjTime - convert!("seconds", "hnsecs")(_transitions.back.ttInfo.utcOffset + leapSecs);
|
|
|
|
immutable transition = found == 0 ? pastTrans : _transitions[pastFound + found - 1];
|
|
|
|
return adjTime - convert!("seconds", "hnsecs")(transition.ttInfo.utcOffset + leapSecs);
|
|
}
|
|
catch(Exception e)
|
|
assert(0, format("Unexpected 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)<br>
|
|
$(WEB en.wikipedia.org/wiki/List_of_tz_database_time_zones, List of
|
|
Time Zones)
|
|
|
|
Params:
|
|
name = The TZ Database name of the desired time zone
|
|
tzDatabaseDir = The directory where the TZ Database files are
|
|
located. Because these files are not located on
|
|
Windows systems, provide them
|
|
and give their location here 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), "/", dirSeparator);
|
|
|
|
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.
|
|
|
|
Providing a sub-name narrows down the list of time zones (which
|
|
can number in the thousands). For example,
|
|
passing in "America" as the sub-name returns only the time zones which
|
|
begin with "America".
|
|
|
|
Params:
|
|
subName = The first part of the desired time zones.
|
|
|
|
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), "/", dirSeparator);
|
|
|
|
if(!tzDatabaseDir.endsWith(dirSeparator))
|
|
tzDatabaseDir ~= dirSeparator;
|
|
|
|
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.extension().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((isIntegral!T || isSomeChar!T) || is(Unqual!T == bool))
|
|
{
|
|
import std.bitmanip;
|
|
T[1] buff;
|
|
|
|
_enforceValidTZFile(!tzFile.eof);
|
|
tzFile.rawRead(buff);
|
|
|
|
return bigEndianToNative!T(cast(ubyte[T.sizeof])buff);
|
|
}
|
|
|
|
/+
|
|
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));
|
|
}
|
|
|
|
|
|
/+
|
|
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;
|
|
|
|
immutable found = countUntil!"b < a.timeT"(cast(LeapSecond[])_leapSeconds, unixTime);
|
|
|
|
if(found == -1)
|
|
return _leapSeconds.back.total;
|
|
|
|
immutable 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. To use the TZ Database, use
|
|
$(LREF PosixTimeZone) (which reads its information from the TZ Database
|
|
files on disk) on Windows by providing the TZ Database files and telling
|
|
$(D PosixTimeZone.getTimeZone) where the directory holding them is.
|
|
|
|
The TZ Database files and Windows' time zone information frequently
|
|
do not match. Windows has many errors with regards to when DST switches
|
|
occur (especially for historical dates). Also, the TZ Database files
|
|
include far more time zones than Windows does. So, for accurate
|
|
time zone information, use the TZ Database files with
|
|
$(LREF PosixTimeZone) rather than $(D WindowsTimeZone). However, because
|
|
$(D WindowsTimeZone) uses Windows system calls to deal with the time,
|
|
it's far more likely to match the behavior of other Windows programs.
|
|
Be aware of the differences when selecting a method.
|
|
|
|
$(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 a $(LREF PosixTimeZone) on Posix systems and a
|
|
$(D WindowsTimeZone) on Windows systems).
|
|
|
|
See_Also:
|
|
$(WEB www.iana.org/time-zones, Home of the TZ Database files)
|
|
+/
|
|
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)<br>
|
|
$(WEB en.wikipedia.org/wiki/List_of_tz_database_time_zones, List
|
|
of Time Zones)
|
|
|
|
Params:
|
|
name = The TZ Database name of the desired time zone.
|
|
|
|
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)
|
|
{
|
|
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)
|
|
{
|
|
scope baseKey = Registry.localMachine.getKey(`Software\Microsoft\Windows NT\CurrentVersion\Time Zones`);
|
|
|
|
foreach (tzKeyName; baseKey.keyNames)
|
|
{
|
|
if (tzKeyName != name)
|
|
continue;
|
|
|
|
scope tzKey = baseKey.getKey(tzKeyName);
|
|
|
|
scope stdVal = tzKey.getValue("Std");
|
|
auto stdName = stdVal.value_SZ;
|
|
|
|
scope dstVal = tzKey.getValue("Dlt");
|
|
auto dstName = dstVal.value_SZ;
|
|
|
|
scope tziVal = tzKey.getValue("TZI");
|
|
auto binVal = tziVal.value_BINARY;
|
|
assert(binVal.length == REG_TZI_FORMAT.sizeof);
|
|
auto tziFmt = cast(REG_TZI_FORMAT*)binVal.ptr;
|
|
|
|
TIME_ZONE_INFORMATION tzInfo;
|
|
|
|
auto wstdName = toUTF16(stdName);
|
|
auto wdstName = toUTF16(dstName);
|
|
auto wstdNameLen = wstdName.length > 32 ? 32 : wstdName.length;
|
|
auto wdstNameLen = wdstName.length > 32 ? 32 : wdstName.length;
|
|
|
|
tzInfo.Bias = tziFmt.Bias;
|
|
tzInfo.StandardName[0 .. wstdNameLen] = wstdName[0 .. wstdNameLen];
|
|
tzInfo.StandardName[wstdNameLen .. $] = '\0';
|
|
tzInfo.StandardDate = tziFmt.StandardDate;
|
|
tzInfo.StandardBias = tziFmt.StandardBias;
|
|
tzInfo.DaylightName[0 .. wdstNameLen] = wdstName[0 .. wdstNameLen];
|
|
tzInfo.DaylightName[wdstNameLen .. $] = '\0';
|
|
tzInfo.DaylightDate = tziFmt.DaylightDate;
|
|
tzInfo.DaylightBias = tziFmt.DaylightBias;
|
|
|
|
return new WindowsTimeZone(name, tzInfo);
|
|
}
|
|
throw new DateTimeException(format("Failed to find time zone: %s", name));
|
|
}
|
|
|
|
static string[] getInstalledTZNames()
|
|
{
|
|
auto timezones = appender!(string[])();
|
|
|
|
scope baseKey = Registry.localMachine.getKey(`Software\Microsoft\Windows NT\CurrentVersion\Time Zones`);
|
|
|
|
foreach (tzKeyName; baseKey.keyNames)
|
|
{
|
|
timezones.put(tzKeyName);
|
|
}
|
|
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 = TzSpecificLocalTimeToSystemTime(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 = -tzInfo.Bias - diff.total!"minutes";
|
|
|
|
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)
|
|
isDST = false;
|
|
else if(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.)
|
|
|
|
Sets 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 started
|
|
with, in a few case, it'll 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)
|
|
{
|
|
//Most of these come from the link in the documentation, but a few have
|
|
//been added because they were found in the Windows registry.
|
|
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/Bahia": return "Bahia 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";
|
|
//This should probably be Turkey Standard Time, but GTB Standard Time
|
|
//has been around longer and therefore will work on more systems.
|
|
case "Europe/Istanbul": return "GTB Standard Time";
|
|
case "Europe/Kaliningrad": return "Kaliningrad 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)
|
|
{
|
|
//Most of these come from the link in the documentation, but a few have
|
|
//been added because they were found in the Windows registry.
|
|
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 "Bahia Standard Time": return "America/Bahia";
|
|
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 "Kaliningrad Standard Time": return "Europe/Kaliningrad";
|
|
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 "Turkey Standard Time": return "Europe/Istanbul";
|
|
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;
|
|
// To know the number of seconds,
|
|
// use properties of TickDuration.
|
|
// (seconds, msecs, usecs, 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;
|
|
// To get the number of seconds,
|
|
// use properties of TickDuration.
|
|
// (seconds, msecs, usecs, hnsecs)
|
|
foreach(t; times)
|
|
sum += t.hnsecs;
|
|
writeln("Average time: ", sum/n, " hnsecs");
|
|
}
|
|
|
|
/++
|
|
Auto start with constructor.
|
|
+/
|
|
this(AutoStart autostart)
|
|
{
|
|
if(autostart)
|
|
start();
|
|
}
|
|
|
|
version(testStdDateTime) @safe unittest
|
|
{
|
|
auto sw = StopWatch(AutoStart.yes);
|
|
sw.stop();
|
|
}
|
|
|
|
|
|
///
|
|
bool opEquals(const StopWatch rhs) const pure nothrow
|
|
{
|
|
return opEquals(rhs);
|
|
}
|
|
|
|
/// ditto
|
|
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);
|
|
_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);
|
|
}
|
|
|
|
|
|
/++
|
|
Set the amount of time which has been measured since the stop watch was
|
|
started.
|
|
+/
|
|
void setMeasured(TickDuration d)
|
|
{
|
|
reset();
|
|
_timeMeasured = d;
|
|
}
|
|
|
|
version(testStdDateTime) @safe unittest
|
|
{
|
|
StopWatch sw;
|
|
TickDuration t0;
|
|
t0.length = 100;
|
|
sw.setMeasured(t0);
|
|
auto t1 = sw.peek();
|
|
assert(t0 == t1);
|
|
}
|
|
|
|
|
|
/++
|
|
Confirm whether this stopwatch is measuring time.
|
|
+/
|
|
bool running() @property const pure nothrow
|
|
{
|
|
return _flagStarted;
|
|
}
|
|
|
|
version(testStdDateTime) @safe unittest
|
|
{
|
|
StopWatch sw1;
|
|
assert(!sw1.running);
|
|
sw1.start();
|
|
assert(sw1.running);
|
|
sw1.stop();
|
|
assert(!sw1.running);
|
|
StopWatch sw2 = AutoStart.yes;
|
|
assert(sw2.running);
|
|
sw2.stop();
|
|
assert(!sw2.running);
|
|
sw2.start();
|
|
assert(sw2.running);
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
// true if observing.
|
|
bool _flagStarted = false;
|
|
|
|
// TickDuration at the time of StopWatch starting measurement.
|
|
TickDuration _timeStart;
|
|
|
|
// Total time that StopWatch ran.
|
|
TickDuration _timeMeasured;
|
|
}
|
|
|
|
|
|
// 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);
|
|
writefln("Milliseconds to call fun[0] n times: %s", r[0].msecs);
|
|
--------------------
|
|
+/
|
|
TickDuration[lengthof!(fun)()] benchmark(fun...)(uint n)
|
|
{
|
|
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;
|
|
}
|
|
|
|
//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);
|
|
writefln("Milliseconds to call fun[0] n times: %s", r[0].msecs);
|
|
}
|
|
|
|
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);
|
|
}
|
|
--------------------
|
|
+/
|
|
ComparingBenchmarkResult comparingBenchmark(alias baseFunc,
|
|
alias targetFunc,
|
|
int times = 0xfff)()
|
|
{
|
|
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
|
|
}
|
|
|
|
//Bug# 8450
|
|
version(testStdDateTime) unittest
|
|
{
|
|
@safe void safeFunc() {}
|
|
@trusted void trustFunc() {}
|
|
@system void sysFunc() {}
|
|
auto safeResult = comparingBenchmark!((){safeFunc();}, (){safeFunc();})();
|
|
auto trustResult = comparingBenchmark!((){trustFunc();}, (){trustFunc();})();
|
|
auto sysResult = comparingBenchmark!((){sysFunc();}, (){sysFunc();})();
|
|
auto mixedResult1 = comparingBenchmark!((){safeFunc();}, (){trustFunc();})();
|
|
auto mixedResult2 = comparingBenchmark!((){trustFunc();}, (){sysFunc();})();
|
|
auto mixedResult3 = comparingBenchmark!((){safeFunc();}, (){sysFunc();})();
|
|
}
|
|
|
|
|
|
//==============================================================================
|
|
// Section with public helper functions and templates.
|
|
//==============================================================================
|
|
|
|
|
|
/++
|
|
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. If on Windows and using the
|
|
standard C functions or Win32 API functions which take a $(D time_t),
|
|
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 to get the $(D SYSTEMTIME) 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 the number of hnsecs since midnight,
|
|
January 1st, 1 A.D.
|
|
|
|
Params:
|
|
ft = The $(D FILETIME) struct to convert.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given $(D FILETIME) cannot be
|
|
represented as the return value.
|
|
+/
|
|
long FILETIMEToStdTime(const FILETIME* ft);
|
|
|
|
|
|
/++
|
|
$(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).
|
|
+/
|
|
SysTime FILETIMEToSysTime(const FILETIME* ft, immutable TimeZone tz = LocalTime());
|
|
|
|
|
|
/++
|
|
$(BLUE This function is Windows-Only.)
|
|
|
|
Converts a number of hnsecs since midnight, January 1st, 1 A.D. to a
|
|
$(D FILETIME) struct.
|
|
|
|
Params:
|
|
sysTime = The $(D SysTime) to convert.
|
|
|
|
Throws:
|
|
$(D DateTimeException) if the given value will not fit in a
|
|
$(D FILETIME).
|
|
+/
|
|
FILETIME stdTimeToFILETIME(long stdTime);
|
|
|
|
|
|
/++
|
|
$(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);
|
|
}
|
|
}
|
|
|
|
private enum hnsecsFrom1601 = 504_911_232_000_000_000L;
|
|
|
|
long FILETIMEToStdTime(const FILETIME* ft)
|
|
{
|
|
ULARGE_INTEGER ul;
|
|
ul.HighPart = ft.dwHighDateTime;
|
|
ul.LowPart = ft.dwLowDateTime;
|
|
ulong tempHNSecs = ul.QuadPart;
|
|
|
|
if(tempHNSecs > long.max - hnsecsFrom1601)
|
|
throw new DateTimeException("The given FILETIME cannot be represented as a stdTime value.");
|
|
|
|
return cast(long)tempHNSecs + hnsecsFrom1601;
|
|
}
|
|
|
|
SysTime FILETIMEToSysTime(const FILETIME* ft, immutable TimeZone tz = LocalTime())
|
|
{
|
|
auto sysTime = SysTime(FILETIMEToStdTime(ft), 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 stdTimeToFILETIME(long stdTime)
|
|
{
|
|
if(stdTime < hnsecsFrom1601)
|
|
throw new DateTimeException("The given stdTime value cannot be represented as a FILETIME.");
|
|
|
|
ULARGE_INTEGER ul;
|
|
ul.QuadPart = cast(ulong)stdTime - hnsecsFrom1601;
|
|
|
|
FILETIME ft;
|
|
ft.dwHighDateTime = ul.HighPart;
|
|
ft.dwLowDateTime = ul.LowPart;
|
|
|
|
return ft;
|
|
}
|
|
|
|
FILETIME SysTimeToFILETIME(SysTime sysTime)
|
|
{
|
|
return stdTimeToFILETIME(sysTime.stdTime);
|
|
}
|
|
|
|
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.
|
|
+/
|
|
alias 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 = countUntil(tstrings, lhs);
|
|
immutable indexOfRHS = 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 = countUntil(tstrings, lhs);
|
|
immutable indexOfRHS = 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 time, 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!((){StopWatch sw; unaryFun!func(sw.peek());}))
|
|
{
|
|
struct Result
|
|
{
|
|
private StopWatch _sw = void;
|
|
this(AutoStart as)
|
|
{
|
|
_sw = StopWatch(as);
|
|
}
|
|
~this()
|
|
{
|
|
unaryFun!(func)(_sw.peek());
|
|
}
|
|
}
|
|
return Result(AutoStart.yes);
|
|
}
|
|
|
|
auto measureTime(alias func)()
|
|
if(!isSafe!((){StopWatch sw; unaryFun!func(sw.peek());}))
|
|
{
|
|
struct Result
|
|
{
|
|
private StopWatch _sw = void;
|
|
this(AutoStart as)
|
|
{
|
|
_sw = StopWatch(as);
|
|
}
|
|
~this()
|
|
{
|
|
unaryFun!(func)(_sw.peek());
|
|
}
|
|
}
|
|
return Result(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.
|
|
}
|
|
+/
|
|
}
|
|
|
|
//Bug# 8450
|
|
version(testStdDateTime) unittest
|
|
{
|
|
@safe void safeFunc() {}
|
|
@trusted void trustFunc() {}
|
|
@system void sysFunc() {}
|
|
auto safeResult = measureTime!((a){safeFunc();})();
|
|
auto trustResult = measureTime!((a){trustFunc();})();
|
|
auto sysResult = measureTime!((a){sysFunc();})();
|
|
}
|
|
|
|
//==============================================================================
|
|
// 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 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:
|
|
$(LREF 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:
|
|
$(LREF 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 (month < Month.jan || month > Month.dec)
|
|
{
|
|
throw new DateTimeException("Invalid month: " ~ numToString(month));
|
|
}
|
|
|
|
if(useLongName == true)
|
|
{
|
|
return longMonthNames[month - Month.jan];
|
|
}
|
|
else
|
|
{
|
|
return shortMonthNames[month - Month.jan];
|
|
}
|
|
}
|
|
|
|
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[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[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 = is(typeof(
|
|
{
|
|
auto d = dur!"days"(5);
|
|
auto td = TickDuration.from!"hnsecs"(5);
|
|
alias U = Unqual!T;
|
|
static assert(is(typeof(U.init += d) == U));
|
|
static assert(is(typeof(U.init -= d) == U));
|
|
static assert(is(typeof(U.init += td) == U));
|
|
static assert(is(typeof(U.init -= td) == U));
|
|
}));
|
|
}
|
|
|
|
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.");
|
|
}
|
|
|
|
|
|
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))];
|
|
|
|
void initializeTests()
|
|
{
|
|
immutable lt = LocalTime().utcToTZ(0);
|
|
currLocalDiffFromUTC = dur!"hnsecs"(lt);
|
|
|
|
immutable otherTZ = lt < 0 ? TimeZone.getTimeZone("Australia/Sydney")
|
|
: TimeZone.getTimeZone("America/Denver");
|
|
immutable ot = otherTZ.utcToTZ(0);
|
|
|
|
auto diffs = [0, lt, ot];
|
|
auto diffAA = [0 : Rebindable!(immutable TimeZone)(UTC()),
|
|
lt : Rebindable!(immutable TimeZone)(LocalTime()),
|
|
ot : Rebindable!(immutable TimeZone)(otherTZ)];
|
|
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() const
|
|
{
|
|
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() const
|
|
{
|
|
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() const
|
|
{
|
|
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() const
|
|
{
|
|
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!`);
|
|
}
|
|
}
|
|
|
|
unittest
|
|
{
|
|
/* Issue 6642 */
|
|
static assert(!hasUnsharedAliasing!Date);
|
|
static assert(!hasUnsharedAliasing!TimeOfDay);
|
|
static assert(!hasUnsharedAliasing!DateTime);
|
|
static assert(!hasUnsharedAliasing!SysTime);
|
|
}
|
|
|
|
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 .. $]);
|
|
}
|
|
}
|