d: Merge upstream dmd 47871363d, druntime, c52e28b7, phobos 99e9c1b77.
[official-gcc.git] / libphobos / src / std / datetime / systime.d
blobe80f1225155121dec57e06cf891aa02aede2a31d
1 // Written in the D programming language
3 /++
5 $(SCRIPT inhibitQuickIndex = 1;)
6 $(DIVC quickindex,
7 $(BOOKTABLE,
8 $(TR $(TH Category) $(TH Functions))
9 $(TR $(TD Types) $(TD
10 $(LREF Clock)
11 $(LREF SysTime)
12 $(LREF DosFileTime)
14 $(TR $(TD Conversion) $(TD
15 $(LREF parseRFC822DateTime)
16 $(LREF DosFileTimeToSysTime)
17 $(LREF FILETIMEToStdTime)
18 $(LREF FILETIMEToSysTime)
19 $(LREF stdTimeToFILETIME)
20 $(LREF stdTimeToUnixTime)
21 $(LREF SYSTEMTIMEToSysTime)
22 $(LREF SysTimeToDosFileTime)
23 $(LREF SysTimeToFILETIME)
24 $(LREF SysTimeToSYSTEMTIME)
25 $(LREF unixTimeToStdTime)
29 License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
30 Authors: $(HTTP jmdavisprog.com, Jonathan M Davis)
31 Source: $(PHOBOSSRC std/datetime/systime.d)
33 module std.datetime.systime;
35 version (OSX)
36 version = Darwin;
37 else version (iOS)
38 version = Darwin;
39 else version (TVOS)
40 version = Darwin;
41 else version (WatchOS)
42 version = Darwin;
44 /// Get the current time as a $(LREF SysTime)
45 @safe unittest
47 import std.datetime.timezone : LocalTime;
48 SysTime today = Clock.currTime();
49 assert(today.timezone is LocalTime());
52 /// Construct a $(LREF SysTime) from a ISO time string
53 @safe unittest
55 import std.datetime.date : DateTime;
56 import std.datetime.timezone : UTC;
58 auto st = SysTime.fromISOExtString("2018-01-01T10:30:00Z");
59 assert(st == SysTime(DateTime(2018, 1, 1, 10, 30, 0), UTC()));
62 /// Make a specific point in time in the New York timezone
63 @safe unittest
65 import core.time : hours;
66 import std.datetime.date : DateTime;
67 import std.datetime.timezone : SimpleTimeZone;
69 auto ny = SysTime(
70 DateTime(2018, 1, 1, 10, 30, 0),
71 new immutable SimpleTimeZone(-5.hours, "America/New_York")
74 // ISO standard time strings
75 assert(ny.toISOString() == "20180101T103000-05:00");
76 assert(ny.toISOExtString() == "2018-01-01T10:30:00-05:00");
79 // Note: reconsider using specific imports below after
80 // https://issues.dlang.org/show_bug.cgi?id=17630 has been fixed
81 import core.time;// : ClockType, convert, dur, Duration, seconds, TimeException;
82 import std.datetime.date;// : _monthNames, AllowDayOverflow, CmpTimeUnits, Date,
83 //DateTime, DateTimeException, DayOfWeek, enforceValid, getDayOfWeek, maxDay,
84 //Month, splitUnitsFromHNSecs, TimeOfDay, validTimeUnits, yearIsLeapYear;
85 import std.datetime.timezone;// : LocalTime, SimpleTimeZone, TimeZone, UTC;
86 import std.exception : enforce;
87 import std.format : format;
88 import std.range.primitives;
89 import std.traits : isIntegral, isSigned, isSomeString, isNarrowString;
91 version (Windows)
93 import core.stdc.time : time_t;
94 import core.sys.windows.winbase;
95 import core.sys.windows.winnt;
96 import core.sys.windows.winsock2;
98 else version (Posix)
100 import core.sys.posix.signal : timespec;
101 import core.sys.posix.sys.types : time_t;
104 version (StdUnittest)
106 import core.exception : AssertError;
107 import std.exception : assertThrown;
111 @safe unittest
113 initializeTests();
116 version (unittest) private bool clockSupported(ClockType c)
118 // Skip unsupported clocks on older linux kernels, assume that only
119 // CLOCK_MONOTONIC and CLOCK_REALTIME exist, as that is the lowest
120 // common denominator supported by all versions of Linux pre-2.6.12.
121 version (Linux_Pre_2639)
122 return c == ClockType.normal || c == ClockType.precise;
123 else
124 return true;
128 Effectively a namespace to make it clear that the methods it contains are
129 getting the time from the system clock. It cannot be instantiated.
131 final class Clock
133 public:
136 Returns the current time in the given time zone.
138 Params:
139 clockType = The $(REF ClockType, core,time) indicates which system
140 clock to use to get the current time. Very few programs
141 need to use anything other than the default.
142 tz = The time zone for the SysTime that's returned.
144 Throws:
145 $(REF DateTimeException,std,datetime,date) if it fails to get the
146 time.
148 static SysTime currTime(ClockType clockType = ClockType.normal)(immutable TimeZone tz = LocalTime()) @safe
150 return SysTime(currStdTime!clockType, tz);
153 @safe unittest
155 import std.format : format;
156 import core.time;
157 assert(currTime().timezone is LocalTime());
158 assert(currTime(UTC()).timezone is UTC());
160 // core.stdc.time.time does not always use unix time on Windows systems.
161 // In particular, dmc does not use unix time. If we can guarantee that
162 // the MS runtime uses unix time, then we may be able run this test
163 // then, but for now, we're just not going to run this test on Windows.
164 version (Posix)
166 static import core.stdc.time;
167 static import std.math;
168 immutable unixTimeD = currTime().toUnixTime();
169 immutable unixTimeC = core.stdc.time.time(null);
170 assert(std.math.abs(unixTimeC - unixTimeD) <= 2);
173 auto norm1 = Clock.currTime;
174 auto norm2 = Clock.currTime(UTC());
175 assert(norm1 <= norm2, format("%s %s", norm1, norm2));
176 assert(abs(norm1 - norm2) <= seconds(2));
178 import std.meta : AliasSeq;
179 static foreach (ct; AliasSeq!(ClockType.coarse, ClockType.precise, ClockType.second))
181 static if (clockSupported(ct))
183 auto value1 = Clock.currTime!ct;
184 auto value2 = Clock.currTime!ct(UTC());
185 assert(value1 <= value2, format("%s %s (ClockType: %s)", value1, value2, ct));
186 assert(abs(value1 - value2) <= seconds(2), format("ClockType.%s", ct));
193 Returns the number of hnsecs since midnight, January 1st, 1 A.D. for the
194 current time.
196 Params:
197 clockType = The $(REF ClockType, core,time) indicates which system
198 clock to use to get the current time. Very few programs
199 need to use anything other than the default.
201 Throws:
202 $(REF DateTimeException,std,datetime,date) if it fails to get the
203 time.
205 static @property long currStdTime(ClockType clockType = ClockType.normal)() @trusted
207 static if (clockType != ClockType.coarse &&
208 clockType != ClockType.normal &&
209 clockType != ClockType.precise &&
210 clockType != ClockType.second)
212 static assert(0, format("ClockType.%s is not supported by Clock.currTime or Clock.currStdTime", clockType));
215 version (Windows)
217 FILETIME fileTime;
218 GetSystemTimeAsFileTime(&fileTime);
219 immutable result = FILETIMEToStdTime(&fileTime);
220 static if (clockType == ClockType.second)
222 // Ideally, this would use core.std.time.time, but the C runtime
223 // has to be using unix time for that to work, and that's not
224 // guaranteed on Windows. Digital Mars does not use unix time.
225 // MS may or may not. If it does, then this can be made to use
226 // core.stdc.time for MS, but for now, we'll leave it like this.
227 return convert!("seconds", "hnsecs")(convert!("hnsecs", "seconds")(result));
229 else
230 return result;
232 else version (Posix)
234 static import core.stdc.time;
235 enum hnsecsToUnixEpoch = unixTimeToStdTime(0);
237 version (Darwin)
239 static if (clockType == ClockType.second)
240 return unixTimeToStdTime(core.stdc.time.time(null));
241 else
243 import core.sys.posix.sys.time : gettimeofday, timeval;
244 timeval tv = void;
245 // Posix gettimeofday called with a valid timeval address
246 // and a null second parameter doesn't fail.
247 gettimeofday(&tv, null);
248 return convert!("seconds", "hnsecs")(tv.tv_sec) +
249 tv.tv_usec * 10 +
250 hnsecsToUnixEpoch;
253 else version (linux)
255 static if (clockType == ClockType.second)
256 return unixTimeToStdTime(core.stdc.time.time(null));
257 else
259 import core.sys.linux.time : CLOCK_REALTIME_COARSE;
260 import core.sys.posix.time : clock_gettime, CLOCK_REALTIME;
261 static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME_COARSE;
262 else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME;
263 else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME;
264 else static assert(0, "Previous static if is wrong.");
265 timespec ts = void;
266 immutable error = clock_gettime(clockArg, &ts);
267 // Posix clock_gettime called with a valid address and valid clock_id is only
268 // permitted to fail if the number of seconds does not fit in time_t. If tv_sec
269 // is long or larger overflow won't happen before 292 billion years A.D.
270 static if (ts.tv_sec.max < long.max)
272 if (error)
273 throw new TimeException("Call to clock_gettime() failed");
275 return convert!("seconds", "hnsecs")(ts.tv_sec) +
276 ts.tv_nsec / 100 +
277 hnsecsToUnixEpoch;
280 else version (FreeBSD)
282 import core.sys.freebsd.time : clock_gettime, CLOCK_REALTIME,
283 CLOCK_REALTIME_FAST, CLOCK_REALTIME_PRECISE, CLOCK_SECOND;
284 static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME_FAST;
285 else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME;
286 else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME_PRECISE;
287 else static if (clockType == ClockType.second) alias clockArg = CLOCK_SECOND;
288 else static assert(0, "Previous static if is wrong.");
289 timespec ts = void;
290 immutable error = clock_gettime(clockArg, &ts);
291 // Posix clock_gettime called with a valid address and valid clock_id is only
292 // permitted to fail if the number of seconds does not fit in time_t. If tv_sec
293 // is long or larger overflow won't happen before 292 billion years A.D.
294 static if (ts.tv_sec.max < long.max)
296 if (error)
297 throw new TimeException("Call to clock_gettime() failed");
299 return convert!("seconds", "hnsecs")(ts.tv_sec) +
300 ts.tv_nsec / 100 +
301 hnsecsToUnixEpoch;
303 else version (NetBSD)
305 static if (clockType == ClockType.second)
306 return unixTimeToStdTime(core.stdc.time.time(null));
307 else
309 import core.sys.netbsd.time : clock_gettime, CLOCK_REALTIME;
310 timespec ts = void;
311 immutable error = clock_gettime(CLOCK_REALTIME, &ts);
312 // Posix clock_gettime called with a valid address and valid clock_id is only
313 // permitted to fail if the number of seconds does not fit in time_t. If tv_sec
314 // is long or larger overflow won't happen before 292 billion years A.D.
315 static if (ts.tv_sec.max < long.max)
317 if (error)
318 throw new TimeException("Call to clock_gettime() failed");
320 return convert!("seconds", "hnsecs")(ts.tv_sec) +
321 ts.tv_nsec / 100 +
322 hnsecsToUnixEpoch;
325 else version (OpenBSD)
327 static if (clockType == ClockType.second)
328 return unixTimeToStdTime(core.stdc.time.time(null));
329 else
331 import core.sys.openbsd.time : clock_gettime, CLOCK_REALTIME;
332 static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME;
333 else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME;
334 else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME;
335 else static assert(0, "Previous static if is wrong.");
336 timespec ts;
337 if (clock_gettime(clockArg, &ts) != 0)
338 throw new TimeException("Call to clock_gettime() failed");
339 return convert!("seconds", "hnsecs")(ts.tv_sec) +
340 ts.tv_nsec / 100 +
341 hnsecsToUnixEpoch;
344 else version (DragonFlyBSD)
346 import core.sys.dragonflybsd.time : clock_gettime, CLOCK_REALTIME,
347 CLOCK_REALTIME_FAST, CLOCK_REALTIME_PRECISE, CLOCK_SECOND;
348 static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME_FAST;
349 else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME;
350 else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME_PRECISE;
351 else static if (clockType == ClockType.second) alias clockArg = CLOCK_SECOND;
352 else static assert(0, "Previous static if is wrong.");
353 timespec ts = void;
354 immutable error = clock_gettime(clockArg, &ts);
355 // Posix clock_gettime called with a valid address and valid clock_id is only
356 // permitted to fail if the number of seconds does not fit in time_t. If tv_sec
357 // is long or larger overflow won't happen before 292 billion years A.D.
358 static if (ts.tv_sec.max < long.max)
360 if (error)
361 throw new TimeException("Call to clock_gettime() failed");
363 return convert!("seconds", "hnsecs")(ts.tv_sec) +
364 ts.tv_nsec / 100 +
365 hnsecsToUnixEpoch;
367 else version (Solaris)
369 static if (clockType == ClockType.second)
370 return unixTimeToStdTime(core.stdc.time.time(null));
371 else
373 import core.sys.solaris.time : clock_gettime, CLOCK_REALTIME;
374 static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME;
375 else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME;
376 else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME;
377 else static assert(0, "Previous static if is wrong.");
378 timespec ts = void;
379 immutable error = clock_gettime(clockArg, &ts);
380 // Posix clock_gettime called with a valid address and valid clock_id is only
381 // permitted to fail if the number of seconds does not fit in time_t. If tv_sec
382 // is long or larger overflow won't happen before 292 billion years A.D.
383 static if (ts.tv_sec.max < long.max)
385 if (error)
386 throw new TimeException("Call to clock_gettime() failed");
388 return convert!("seconds", "hnsecs")(ts.tv_sec) +
389 ts.tv_nsec / 100 +
390 hnsecsToUnixEpoch;
393 else version (Hurd)
395 static if (clockType == ClockType.second)
396 return unixTimeToStdTime(core.stdc.time.time(null));
397 else
399 import core.sys.hurd.time : CLOCK_REALTIME_COARSE;
400 import core.sys.posix.time : clock_gettime, CLOCK_REALTIME;
401 static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME_COARSE;
402 else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME;
403 else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME;
404 else static assert(0, "Previous static if is wrong.");
405 timespec ts = void;
406 immutable error = clock_gettime(clockArg, &ts);
407 // Posix clock_gettime called with a valid address and valid clock_id is only
408 // permitted to fail if the number of seconds does not fit in time_t. If tv_sec
409 // is long or larger overflow won't happen before 292 billion years A.D.
410 static if (ts.tv_sec.max < long.max)
412 if (error)
413 throw new TimeException("Call to clock_gettime() failed");
415 return convert!("seconds", "hnsecs")(ts.tv_sec) +
416 ts.tv_nsec / 100 +
417 hnsecsToUnixEpoch;
420 else static assert(0, "Unsupported OS");
422 else static assert(0, "Unsupported OS");
425 @safe unittest
427 import std.format : format;
428 import std.math.algebraic : abs;
429 import std.meta : AliasSeq;
430 enum limit = convert!("seconds", "hnsecs")(2);
432 auto norm1 = Clock.currStdTime;
433 auto norm2 = Clock.currStdTime;
434 assert(norm1 <= norm2, format("%s %s", norm1, norm2));
435 assert(abs(norm1 - norm2) <= limit);
437 static foreach (ct; AliasSeq!(ClockType.coarse, ClockType.precise, ClockType.second))
439 static if (clockSupported(ct))
441 auto value1 = Clock.currStdTime!ct;
442 auto value2 = Clock.currStdTime!ct;
443 assert(value1 <= value2, format("%s %s (ClockType: %s)", value1, value2, ct));
444 assert(abs(value1 - value2) <= limit);
450 private:
452 @disable this();
455 /// Get the current time as a $(LREF SysTime)
456 @safe unittest
458 import std.datetime.timezone : LocalTime;
459 SysTime today = Clock.currTime();
460 assert(today.timezone is LocalTime());
465 `SysTime` is the type used to get the current time from the
466 system or doing anything that involves time zones. Unlike
467 $(REF DateTime,std,datetime,date), the time zone is an integral part of
468 `SysTime` (though for local time applications, time zones can be ignored
469 and it will work, since it defaults to using the local time zone). It holds
470 its internal time in std time (hnsecs since midnight, January 1st, 1 A.D.
471 UTC), so it interfaces well with the system time. However, that means that,
472 unlike $(REF DateTime,std,datetime,date), it is not optimized for
473 calendar-based operations, and getting individual units from it such as
474 years or days is going to involve conversions and be less efficient.
476 An $(I hnsec) (hecto-nanosecond) is 100 nanoseconds. There are 10,000,000 hnsecs in a second.
478 For calendar-based operations that don't
479 care about time zones, then $(REF DateTime,std,datetime,date) would be
480 the type to use. For system time, use `SysTime`.
482 $(LREF Clock.currTime) will return the current time as a `SysTime`.
483 To convert a `SysTime` to a $(REF Date,std,datetime,date) or
484 $(REF DateTime,std,datetime,date), simply cast it. To convert a
485 $(REF Date,std,datetime,date) or $(REF DateTime,std,datetime,date) to a
486 `SysTime`, use `SysTime`'s constructor, and pass in the intended time
487 zone with it (or don't pass in a $(REF TimeZone,std,datetime,timezone), and
488 the local time zone will be used). Be aware, however, that converting from a
489 $(REF DateTime,std,datetime,date) to a `SysTime` will not necessarily
490 be 100% accurate due to DST (one hour of the year doesn't exist and another
491 occurs twice). To not risk any conversion errors, keep times as
492 `SysTime`s. Aside from DST though, there shouldn't be any conversion
493 problems.
495 For using time zones other than local time or UTC, use
496 $(REF PosixTimeZone,std,datetime,timezone) on Posix systems (or on Windows,
497 if providing the TZ Database files), and use
498 $(REF WindowsTimeZone,std,datetime,timezone) on Windows systems. The time in
499 `SysTime` is kept internally in hnsecs from midnight, January 1st, 1 A.D.
500 UTC. Conversion error cannot happen when changing the time zone of a
501 `SysTime`. $(REF LocalTime,std,datetime,timezone) is the
502 $(REF TimeZone,std,datetime,timezone) class which represents the local time,
503 and `UTC` is the $(REF TimeZone,std,datetime,timezone) class which
504 represents UTC. `SysTime` uses $(REF LocalTime,std,datetime,timezone) if
505 no $(REF TimeZone,std,datetime,timezone) is provided. For more details on
506 time zones, see the documentation for $(REF TimeZone,std,datetime,timezone),
507 $(REF PosixTimeZone,std,datetime,timezone), and
508 $(REF WindowsTimeZone,std,datetime,timezone).
510 `SysTime`'s range is from approximately 29,000 B.C. to approximately
511 29,000 A.D.
513 struct SysTime
515 import core.stdc.time : tm;
516 version (Posix) import core.sys.posix.sys.time : timeval;
517 import std.typecons : Rebindable;
519 public:
522 Params:
523 dateTime = The $(REF DateTime,std,datetime,date) to use to set
524 this $(LREF SysTime)'s internal std time. As
525 $(REF DateTime,std,datetime,date) has no concept of
526 time zone, tz is used as its time zone.
527 tz = The $(REF TimeZone,std,datetime,timezone) to use for this
528 $(LREF SysTime). If null,
529 $(REF LocalTime,std,datetime,timezone) will be used. The
530 given $(REF DateTime,std,datetime,date) is assumed to
531 be in the given time zone.
533 this(DateTime dateTime, return scope immutable TimeZone tz = null) return scope @safe nothrow
536 this(dateTime, Duration.zero, tz);
537 catch (Exception e)
538 assert(0, "SysTime's constructor threw when it shouldn't have.");
541 @safe unittest
543 static void test(DateTime dt, immutable TimeZone tz, long expected)
545 auto sysTime = SysTime(dt, tz);
546 assert(sysTime._stdTime == expected);
547 assert(sysTime._timezone is (tz is null ? LocalTime() : tz), format("Given DateTime: %s", dt));
550 test(DateTime.init, UTC(), 0);
551 test(DateTime(1, 1, 1, 12, 30, 33), UTC(), 450_330_000_000L);
552 test(DateTime(0, 12, 31, 12, 30, 33), UTC(), -413_670_000_000L);
553 test(DateTime(1, 1, 1, 0, 0, 0), UTC(), 0);
554 test(DateTime(1, 1, 1, 0, 0, 1), UTC(), 10_000_000L);
555 test(DateTime(0, 12, 31, 23, 59, 59), UTC(), -10_000_000L);
557 test(DateTime(1, 1, 1, 0, 0, 0), new immutable SimpleTimeZone(dur!"minutes"(-60)), 36_000_000_000L);
558 test(DateTime(1, 1, 1, 0, 0, 0), new immutable SimpleTimeZone(Duration.zero), 0);
559 test(DateTime(1, 1, 1, 0, 0, 0), new immutable SimpleTimeZone(dur!"minutes"(60)), -36_000_000_000L);
561 static void testScope(scope ref DateTime dt) @safe
563 auto st = SysTime(dt);
568 Params:
569 dateTime = The $(REF DateTime,std,datetime,date) to use to set
570 this $(LREF SysTime)'s internal std time. As
571 $(REF DateTime,std,datetime,date) has no concept of
572 time zone, tz is used as its time zone.
573 fracSecs = The fractional seconds portion of the time.
574 tz = The $(REF TimeZone,std,datetime,timezone) to use for this
575 $(LREF SysTime). If null,
576 $(REF LocalTime,std,datetime,timezone) will be used. The
577 given $(REF DateTime,std,datetime,date) is assumed to
578 be in the given time zone.
580 Throws:
581 $(REF DateTimeException,std,datetime,date) if `fracSecs` is negative or if it's
582 greater than or equal to one second.
584 this(DateTime dateTime, Duration fracSecs, return scope immutable TimeZone tz = null) return scope @safe
586 enforce(fracSecs >= Duration.zero, new DateTimeException("A SysTime cannot have negative fractional seconds."));
587 enforce(fracSecs < seconds(1), new DateTimeException("Fractional seconds must be less than one second."));
588 auto nonNullTZ = tz is null ? LocalTime() : tz;
590 immutable dateDiff = dateTime.date - Date.init;
591 immutable todDiff = dateTime.timeOfDay - TimeOfDay.init;
593 immutable adjustedTime = dateDiff + todDiff + fracSecs;
594 immutable standardTime = nonNullTZ.tzToUTC(adjustedTime.total!"hnsecs");
596 this(standardTime, nonNullTZ);
599 @safe unittest
601 import core.time;
602 static void test(DateTime dt, Duration fracSecs, immutable TimeZone tz, long expected)
604 auto sysTime = SysTime(dt, fracSecs, tz);
605 assert(sysTime._stdTime == expected);
606 assert(sysTime._timezone is (tz is null ? LocalTime() : tz),
607 format("Given DateTime: %s, Given Duration: %s", dt, fracSecs));
610 test(DateTime.init, Duration.zero, UTC(), 0);
611 test(DateTime(1, 1, 1, 12, 30, 33), Duration.zero, UTC(), 450_330_000_000L);
612 test(DateTime(0, 12, 31, 12, 30, 33), Duration.zero, UTC(), -413_670_000_000L);
613 test(DateTime(1, 1, 1, 0, 0, 0), msecs(1), UTC(), 10_000L);
614 test(DateTime(0, 12, 31, 23, 59, 59), msecs(999), UTC(), -10_000L);
616 test(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC(), -1);
617 test(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC(), -9_999_999);
618 test(DateTime(0, 12, 31, 23, 59, 59), Duration.zero, UTC(), -10_000_000);
620 assertThrown!DateTimeException(SysTime(DateTime.init, hnsecs(-1), UTC()));
621 assertThrown!DateTimeException(SysTime(DateTime.init, seconds(1), UTC()));
623 static void testScope(scope ref DateTime dt, scope ref Duration d) @safe
625 auto st = SysTime(dt, d);
630 Params:
631 date = The $(REF Date,std,datetime,date) to use to set this
632 $(LREF SysTime)'s internal std time. As
633 $(REF Date,std,datetime,date) has no concept of time zone, tz
634 is used as its time zone.
635 tz = The $(REF TimeZone,std,datetime,timezone) to use for this
636 $(LREF SysTime). If null,
637 $(REF LocalTime,std,datetime,timezone) will be used. The
638 given $(REF Date,std,datetime,date) is assumed to be in the
639 given time zone.
641 this(Date date, return scope immutable TimeZone tz = null) return scope @safe nothrow
643 _timezone = tz is null ? LocalTime() : tz;
647 immutable adjustedTime = (date - Date(1, 1, 1)).total!"hnsecs";
648 immutable standardTime = _timezone.tzToUTC(adjustedTime);
650 this(standardTime, _timezone);
652 catch (Exception e)
653 assert(0, "Date's constructor through when it shouldn't have.");
656 @safe unittest
658 static void test(Date d, immutable TimeZone tz, long expected)
660 auto sysTime = SysTime(d, tz);
661 assert(sysTime._stdTime == expected);
662 assert(sysTime._timezone is (tz is null ? LocalTime() : tz), format("Given Date: %s", d));
665 test(Date.init, UTC(), 0);
666 test(Date(1, 1, 1), UTC(), 0);
667 test(Date(1, 1, 2), UTC(), 864000000000);
668 test(Date(0, 12, 31), UTC(), -864000000000);
670 static void testScope(scope ref Date d) @safe
672 auto st = SysTime(d);
677 Note:
678 Whereas the other constructors take in the given date/time, assume
679 that it's in the given time zone, and convert it to hnsecs in UTC
680 since midnight, January 1st, 1 A.D. UTC - i.e. std time - this
681 constructor takes a std time, which is specifically already in UTC,
682 so no conversion takes place. Of course, the various getter
683 properties and functions will use the given time zone's conversion
684 function to convert the results to that time zone, but no conversion
685 of the arguments to this constructor takes place.
687 Params:
688 stdTime = The number of hnsecs since midnight, January 1st, 1 A.D.
689 UTC.
690 tz = The $(REF TimeZone,std,datetime,timezone) to use for this
691 $(LREF SysTime). If null,
692 $(REF LocalTime,std,datetime,timezone) will be used.
694 this(long stdTime, return scope immutable TimeZone tz = null) return scope @safe pure nothrow
696 _stdTime = stdTime;
697 _timezone = tz is null ? LocalTime() : tz;
700 @safe unittest
702 static void test(long stdTime, immutable TimeZone tz)
704 auto sysTime = SysTime(stdTime, tz);
705 assert(sysTime._stdTime == stdTime);
706 assert(sysTime._timezone is (tz is null ? LocalTime() : tz), format("Given stdTime: %s", stdTime));
709 foreach (stdTime; [-1234567890L, -250, 0, 250, 1235657390L])
711 foreach (tz; testTZs)
712 test(stdTime, tz);
718 Params:
719 rhs = The $(LREF SysTime) to assign to this one.
721 Returns: The `this` of this `SysTime`.
723 ref SysTime opAssign()(auto ref const(SysTime) rhs) scope return @safe pure nothrow
725 _stdTime = rhs._stdTime;
726 _timezone = rhs._timezone;
727 return this;
730 @safe unittest
732 SysTime st;
733 st = SysTime(DateTime(2012, 12, 21, 1, 2, 3), UTC());
734 assert(st == SysTime(DateTime(2012, 12, 21, 1, 2, 3), UTC()));
736 const other = SysTime(DateTime(19, 1, 7, 13, 14, 15), LocalTime());
737 st = other;
738 assert(st == other);
740 version (none) // https://issues.dlang.org/show_bug.cgi?id=21175
741 static void testScope(scope ref SysTime left, const scope SysTime right) @safe
743 left = right;
749 Checks for equality between this $(LREF SysTime) and the given
750 $(LREF SysTime).
752 Note that the time zone is ignored. Only the internal
753 std times (which are in UTC) are compared.
755 bool opEquals()(auto ref const(SysTime) rhs) @safe const pure nothrow scope
757 return _stdTime == rhs._stdTime;
760 @safe unittest
762 import std.range : chain;
764 assert(SysTime(DateTime.init, UTC()) == SysTime(0, UTC()));
765 assert(SysTime(DateTime.init, UTC()) == SysTime(0));
766 assert(SysTime(Date.init, UTC()) == SysTime(0));
767 assert(SysTime(0) == SysTime(0));
769 static void test(DateTime dt, immutable TimeZone tz1, immutable TimeZone tz2)
771 auto st1 = SysTime(dt);
772 st1.timezone = tz1;
774 auto st2 = SysTime(dt);
775 st2.timezone = tz2;
777 assert(st1 == st2);
780 foreach (tz1; testTZs)
782 foreach (tz2; testTZs)
784 foreach (dt; chain(testDateTimesBC, testDateTimesAD))
785 test(dt, tz1, tz2);
789 auto st = SysTime(DateTime(1999, 7, 6, 12, 33, 30));
790 const cst = SysTime(DateTime(1999, 7, 6, 12, 33, 30));
791 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 33, 30));
792 assert(st == st);
793 assert(st == cst);
794 assert(st == ist);
795 assert(cst == st);
796 assert(cst == cst);
797 assert(cst == ist);
798 assert(ist == st);
799 assert(ist == cst);
800 assert(ist == ist);
802 static void testScope(scope ref SysTime left, const scope SysTime right) @safe
804 assert(left == right);
805 assert(right == left);
811 Compares this $(LREF SysTime) with the given $(LREF SysTime).
813 Time zone is irrelevant when comparing $(LREF SysTime)s.
815 Returns:
816 $(BOOKTABLE,
817 $(TR $(TD this &lt; rhs) $(TD &lt; 0))
818 $(TR $(TD this == rhs) $(TD 0))
819 $(TR $(TD this &gt; rhs) $(TD &gt; 0))
822 int opCmp()(auto ref const(SysTime) rhs) @safe const pure nothrow scope
824 if (_stdTime < rhs._stdTime)
825 return -1;
826 if (_stdTime > rhs._stdTime)
827 return 1;
828 return 0;
831 @safe unittest
833 import std.algorithm.iteration : map;
834 import std.array : array;
835 import std.range : chain;
837 assert(SysTime(DateTime.init, UTC()).opCmp(SysTime(0, UTC())) == 0);
838 assert(SysTime(DateTime.init, UTC()).opCmp(SysTime(0)) == 0);
839 assert(SysTime(Date.init, UTC()).opCmp(SysTime(0)) == 0);
840 assert(SysTime(0).opCmp(SysTime(0)) == 0);
842 static void testEqual(SysTime st, immutable TimeZone tz1, immutable TimeZone tz2)
844 auto st1 = st;
845 st1.timezone = tz1;
847 auto st2 = st;
848 st2.timezone = tz2;
850 assert(st1.opCmp(st2) == 0);
853 auto sts = array(map!SysTime(chain(testDateTimesBC, testDateTimesAD)));
855 foreach (st; sts)
857 foreach (tz1; testTZs)
859 foreach (tz2; testTZs)
860 testEqual(st, tz1, tz2);
864 static void testCmp(SysTime st1, immutable TimeZone tz1, SysTime st2, immutable TimeZone tz2)
866 st1.timezone = tz1;
867 st2.timezone = tz2;
868 assert(st1.opCmp(st2) < 0);
869 assert(st2.opCmp(st1) > 0);
872 foreach (si, st1; sts)
874 foreach (st2; sts[si + 1 .. $])
876 foreach (tz1; testTZs)
878 foreach (tz2; testTZs)
879 testCmp(st1, tz1, st2, tz2);
884 auto st = SysTime(DateTime(1999, 7, 6, 12, 33, 30));
885 const cst = SysTime(DateTime(1999, 7, 6, 12, 33, 30));
886 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 33, 30));
887 assert(st.opCmp(st) == 0);
888 assert(st.opCmp(cst) == 0);
889 assert(st.opCmp(ist) == 0);
890 assert(cst.opCmp(st) == 0);
891 assert(cst.opCmp(cst) == 0);
892 assert(cst.opCmp(ist) == 0);
893 assert(ist.opCmp(st) == 0);
894 assert(ist.opCmp(cst) == 0);
895 assert(ist.opCmp(ist) == 0);
897 static void testScope(scope ref SysTime left, const scope SysTime right) @safe
899 assert(left < right);
900 assert(right > left);
906 Returns: A hash of the $(LREF SysTime).
908 size_t toHash() const @nogc pure nothrow @safe scope
910 static if (is(size_t == ulong))
911 return _stdTime;
912 else
914 // MurmurHash2
915 enum ulong m = 0xc6a4a7935bd1e995UL;
916 enum ulong n = m * 16;
917 enum uint r = 47;
919 ulong k = _stdTime;
920 k *= m;
921 k ^= k >> r;
922 k *= m;
924 ulong h = n;
925 h ^= k;
926 h *= m;
928 return cast(size_t) h;
932 @safe unittest
934 assert(SysTime(0).toHash == SysTime(0).toHash);
935 assert(SysTime(DateTime(2000, 1, 1)).toHash == SysTime(DateTime(2000, 1, 1)).toHash);
936 assert(SysTime(DateTime(2000, 1, 1)).toHash != SysTime(DateTime(2000, 1, 2)).toHash);
938 // test that timezones aren't taken into account
939 assert(SysTime(0, LocalTime()).toHash == SysTime(0, LocalTime()).toHash);
940 assert(SysTime(0, LocalTime()).toHash == SysTime(0, UTC()).toHash);
941 assert(SysTime(DateTime(2000, 1, 1), LocalTime()).toHash == SysTime(DateTime(2000, 1, 1), LocalTime()).toHash);
942 immutable zone = new SimpleTimeZone(dur!"minutes"(60));
943 assert(SysTime(DateTime(2000, 1, 1, 1), zone).toHash == SysTime(DateTime(2000, 1, 1), UTC()).toHash);
944 assert(SysTime(DateTime(2000, 1, 1), zone).toHash != SysTime(DateTime(2000, 1, 1), UTC()).toHash);
946 static void testScope(scope ref SysTime st) @safe
948 auto result = st.toHash();
954 Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive
955 are B.C.
957 @property short year() @safe const nothrow scope
959 return (cast(Date) this).year;
962 @safe unittest
964 import std.range : chain;
965 static void test(SysTime sysTime, long expected)
967 assert(sysTime.year == expected, format("Value given: %s", sysTime));
970 test(SysTime(0, UTC()), 1);
971 test(SysTime(1, UTC()), 1);
972 test(SysTime(-1, UTC()), 0);
974 foreach (year; chain(testYearsBC, testYearsAD))
976 foreach (md; testMonthDays)
978 foreach (tod; testTODs)
980 auto dt = DateTime(Date(year, md.month, md.day), tod);
981 foreach (tz; testTZs)
983 foreach (fs; testFracSecs)
984 test(SysTime(dt, fs, tz), year);
990 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
991 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
992 assert(cst.year == 1999);
993 assert(ist.year == 1999);
995 static void testScope(scope ref SysTime st) @safe
997 auto result = st.year;
1002 Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive
1003 are B.C.
1005 Params:
1006 year = The year to set this $(LREF SysTime)'s year to.
1008 Throws:
1009 $(REF DateTimeException,std,datetime,date) if the new year is not
1010 a leap year and the resulting date would be on February 29th.
1012 @property void year(int year) @safe scope
1014 auto hnsecs = adjTime;
1015 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
1017 if (hnsecs < 0)
1019 hnsecs += convert!("hours", "hnsecs")(24);
1020 --days;
1023 auto date = Date(cast(int) days);
1024 date.year = year;
1026 immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1);
1027 adjTime = newDaysHNSecs + hnsecs;
1031 @safe unittest
1033 import std.datetime.date : DateTime;
1035 assert(SysTime(DateTime(1999, 7, 6, 9, 7, 5)).year == 1999);
1036 assert(SysTime(DateTime(2010, 10, 4, 0, 0, 30)).year == 2010);
1037 assert(SysTime(DateTime(-7, 4, 5, 7, 45, 2)).year == -7);
1040 @safe unittest
1042 import std.range : chain;
1044 static void test(SysTime st, int year, SysTime expected)
1046 st.year = year;
1047 assert(st == expected);
1050 foreach (st; chain(testSysTimesBC, testSysTimesAD))
1052 auto dt = cast(DateTime) st;
1054 foreach (year; chain(testYearsBC, testYearsAD))
1056 auto e = SysTime(DateTime(year, dt.month, dt.day, dt.hour, dt.minute, dt.second),
1057 st.fracSecs,
1058 st.timezone);
1059 test(st, year, e);
1063 foreach (fs; testFracSecs)
1065 foreach (tz; testTZs)
1067 foreach (tod; testTODs)
1069 test(SysTime(DateTime(Date(1999, 2, 28), tod), fs, tz), 2000,
1070 SysTime(DateTime(Date(2000, 2, 28), tod), fs, tz));
1071 test(SysTime(DateTime(Date(2000, 2, 28), tod), fs, tz), 1999,
1072 SysTime(DateTime(Date(1999, 2, 28), tod), fs, tz));
1075 foreach (tod; testTODsThrown)
1077 auto st = SysTime(DateTime(Date(2000, 2, 29), tod), fs, tz);
1078 assertThrown!DateTimeException(st.year = 1999);
1083 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1084 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1085 static assert(!__traits(compiles, cst.year = 7));
1086 static assert(!__traits(compiles, ist.year = 7));
1088 static void testScope(scope ref SysTime st) @safe
1090 st.year = 42;
1095 Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C.
1097 Throws:
1098 $(REF DateTimeException,std,datetime,date) if `isAD` is true.
1100 @property ushort yearBC() @safe const scope
1102 return (cast(Date) this).yearBC;
1106 @safe unittest
1108 import std.datetime.date : DateTime;
1110 assert(SysTime(DateTime(0, 1, 1, 12, 30, 33)).yearBC == 1);
1111 assert(SysTime(DateTime(-1, 1, 1, 10, 7, 2)).yearBC == 2);
1112 assert(SysTime(DateTime(-100, 1, 1, 4, 59, 0)).yearBC == 101);
1115 @safe unittest
1117 import std.exception : assertNotThrown;
1118 foreach (st; testSysTimesBC)
1120 auto msg = format("SysTime: %s", st);
1121 assertNotThrown!DateTimeException(st.yearBC, msg);
1122 assert(st.yearBC == (st.year * -1) + 1, msg);
1125 foreach (st; [testSysTimesAD[0], testSysTimesAD[$/2], testSysTimesAD[$-1]])
1126 assertThrown!DateTimeException(st.yearBC, format("SysTime: %s", st));
1128 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1129 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1130 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1131 st.year = 12;
1132 assert(st.year == 12);
1133 static assert(!__traits(compiles, cst.year = 12));
1134 static assert(!__traits(compiles, ist.year = 12));
1136 static void testScope(scope ref SysTime st) @safe
1138 auto result = st.yearBC;
1144 Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C.
1146 Params:
1147 year = The year B.C. to set this $(LREF SysTime)'s year to.
1149 Throws:
1150 $(REF DateTimeException,std,datetime,date) if a non-positive value
1151 is given.
1153 @property void yearBC(int year) @safe scope
1155 auto hnsecs = adjTime;
1156 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
1158 if (hnsecs < 0)
1160 hnsecs += convert!("hours", "hnsecs")(24);
1161 --days;
1164 auto date = Date(cast(int) days);
1165 date.yearBC = year;
1167 immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1);
1168 adjTime = newDaysHNSecs + hnsecs;
1171 @safe unittest
1173 auto st = SysTime(DateTime(2010, 1, 1, 7, 30, 0));
1174 st.yearBC = 1;
1175 assert(st == SysTime(DateTime(0, 1, 1, 7, 30, 0)));
1177 st.yearBC = 10;
1178 assert(st == SysTime(DateTime(-9, 1, 1, 7, 30, 0)));
1181 @safe unittest
1183 import std.range : chain;
1184 static void test(SysTime st, int year, SysTime expected)
1186 st.yearBC = year;
1187 assert(st == expected, format("SysTime: %s", st));
1190 foreach (st; chain(testSysTimesBC, testSysTimesAD))
1192 auto dt = cast(DateTime) st;
1194 foreach (year; testYearsBC)
1196 auto e = SysTime(DateTime(year, dt.month, dt.day, dt.hour, dt.minute, dt.second),
1197 st.fracSecs,
1198 st.timezone);
1199 test(st, (year * -1) + 1, e);
1203 foreach (st; [testSysTimesBC[0], testSysTimesBC[$ - 1], testSysTimesAD[0], testSysTimesAD[$ - 1]])
1205 foreach (year; testYearsBC)
1206 assertThrown!DateTimeException(st.yearBC = year);
1209 foreach (fs; testFracSecs)
1211 foreach (tz; testTZs)
1213 foreach (tod; testTODs)
1215 test(SysTime(DateTime(Date(-1999, 2, 28), tod), fs, tz), 2001,
1216 SysTime(DateTime(Date(-2000, 2, 28), tod), fs, tz));
1217 test(SysTime(DateTime(Date(-2000, 2, 28), tod), fs, tz), 2000,
1218 SysTime(DateTime(Date(-1999, 2, 28), tod), fs, tz));
1221 foreach (tod; testTODsThrown)
1223 auto st = SysTime(DateTime(Date(-2000, 2, 29), tod), fs, tz);
1224 assertThrown!DateTimeException(st.year = -1999);
1229 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1230 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1231 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1232 st.yearBC = 12;
1233 assert(st.yearBC == 12);
1234 static assert(!__traits(compiles, cst.yearBC = 12));
1235 static assert(!__traits(compiles, ist.yearBC = 12));
1237 static void testScope(scope ref SysTime st) @safe
1239 st.yearBC = 42;
1245 Month of a Gregorian Year.
1247 @property Month month() @safe const nothrow scope
1249 return (cast(Date) this).month;
1253 @safe unittest
1255 import std.datetime.date : DateTime;
1257 assert(SysTime(DateTime(1999, 7, 6, 9, 7, 5)).month == 7);
1258 assert(SysTime(DateTime(2010, 10, 4, 0, 0, 30)).month == 10);
1259 assert(SysTime(DateTime(-7, 4, 5, 7, 45, 2)).month == 4);
1262 @safe unittest
1264 import std.range : chain;
1266 static void test(SysTime sysTime, Month expected)
1268 assert(sysTime.month == expected, format("Value given: %s", sysTime));
1271 test(SysTime(0, UTC()), Month.jan);
1272 test(SysTime(1, UTC()), Month.jan);
1273 test(SysTime(-1, UTC()), Month.dec);
1275 foreach (year; chain(testYearsBC, testYearsAD))
1277 foreach (md; testMonthDays)
1279 foreach (tod; testTODs)
1281 auto dt = DateTime(Date(year, md.month, md.day), tod);
1282 foreach (fs; testFracSecs)
1284 foreach (tz; testTZs)
1285 test(SysTime(dt, fs, tz), md.month);
1291 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1292 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1293 assert(cst.month == 7);
1294 assert(ist.month == 7);
1296 static void testScope(scope ref SysTime st) @safe
1298 auto result = st.month;
1304 Month of a Gregorian Year.
1306 Params:
1307 month = The month to set this $(LREF SysTime)'s month to.
1309 Throws:
1310 $(REF DateTimeException,std,datetime,date) if the given month is
1311 not a valid month.
1313 @property void month(Month month) @safe scope
1315 auto hnsecs = adjTime;
1316 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
1318 if (hnsecs < 0)
1320 hnsecs += convert!("hours", "hnsecs")(24);
1321 --days;
1324 auto date = Date(cast(int) days);
1325 date.month = month;
1327 immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1);
1328 adjTime = newDaysHNSecs + hnsecs;
1331 @safe unittest
1333 import std.algorithm.iteration : filter;
1334 import std.range : chain;
1336 static void test(SysTime st, Month month, SysTime expected)
1338 st.month = cast(Month) month;
1339 assert(st == expected);
1342 foreach (st; chain(testSysTimesBC, testSysTimesAD))
1344 auto dt = cast(DateTime) st;
1346 foreach (md; testMonthDays)
1348 if (st.day > maxDay(dt.year, md.month))
1349 continue;
1350 auto e = SysTime(DateTime(dt.year, md.month, dt.day, dt.hour, dt.minute, dt.second),
1351 st.fracSecs,
1352 st.timezone);
1353 test(st, md.month, e);
1357 foreach (fs; testFracSecs)
1359 foreach (tz; testTZs)
1361 foreach (tod; testTODs)
1363 foreach (year; filter!((a){return yearIsLeapYear(a);}) (chain(testYearsBC, testYearsAD)))
1365 test(SysTime(DateTime(Date(year, 1, 29), tod), fs, tz),
1366 Month.feb,
1367 SysTime(DateTime(Date(year, 2, 29), tod), fs, tz));
1370 foreach (year; chain(testYearsBC, testYearsAD))
1372 test(SysTime(DateTime(Date(year, 1, 28), tod), fs, tz),
1373 Month.feb,
1374 SysTime(DateTime(Date(year, 2, 28), tod), fs, tz));
1375 test(SysTime(DateTime(Date(year, 7, 30), tod), fs, tz),
1376 Month.jun,
1377 SysTime(DateTime(Date(year, 6, 30), tod), fs, tz));
1383 foreach (fs; [testFracSecs[0], testFracSecs[$-1]])
1385 foreach (tz; testTZs)
1387 foreach (tod; testTODsThrown)
1389 foreach (year; [testYearsBC[$-3], testYearsBC[$-2],
1390 testYearsBC[$-2], testYearsAD[0],
1391 testYearsAD[$-2], testYearsAD[$-1]])
1393 auto day = yearIsLeapYear(year) ? 30 : 29;
1394 auto st1 = SysTime(DateTime(Date(year, 1, day), tod), fs, tz);
1395 assertThrown!DateTimeException(st1.month = Month.feb);
1397 auto st2 = SysTime(DateTime(Date(year, 7, 31), tod), fs, tz);
1398 assertThrown!DateTimeException(st2.month = Month.jun);
1404 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1405 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1406 static assert(!__traits(compiles, cst.month = Month.dec));
1407 static assert(!__traits(compiles, ist.month = Month.dec));
1409 static void testScope(scope ref SysTime st) @safe
1411 st.month = Month.dec;
1416 Day of a Gregorian Month.
1418 @property ubyte day() @safe const nothrow scope
1420 return (cast(Date) this).day;
1424 @safe unittest
1426 import std.datetime.date : DateTime;
1428 assert(SysTime(DateTime(1999, 7, 6, 9, 7, 5)).day == 6);
1429 assert(SysTime(DateTime(2010, 10, 4, 0, 0, 30)).day == 4);
1430 assert(SysTime(DateTime(-7, 4, 5, 7, 45, 2)).day == 5);
1433 @safe unittest
1435 import std.range : chain;
1437 static void test(SysTime sysTime, int expected)
1439 assert(sysTime.day == expected, format("Value given: %s", sysTime));
1442 test(SysTime(0, UTC()), 1);
1443 test(SysTime(1, UTC()), 1);
1444 test(SysTime(-1, UTC()), 31);
1446 foreach (year; chain(testYearsBC, testYearsAD))
1448 foreach (md; testMonthDays)
1450 foreach (tod; testTODs)
1452 auto dt = DateTime(Date(year, md.month, md.day), tod);
1454 foreach (tz; testTZs)
1456 foreach (fs; testFracSecs)
1457 test(SysTime(dt, fs, tz), md.day);
1463 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1464 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1465 assert(cst.day == 6);
1466 assert(ist.day == 6);
1468 static void testScope(scope ref SysTime st) @safe
1470 auto result = st.day;
1476 Day of a Gregorian Month.
1478 Params:
1479 day = The day of the month to set this $(LREF SysTime)'s day to.
1481 Throws:
1482 $(REF DateTimeException,std,datetime,date) if the given day is not
1483 a valid day of the current month.
1485 @property void day(int day) @safe scope
1487 auto hnsecs = adjTime;
1488 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
1490 if (hnsecs < 0)
1492 hnsecs += convert!("hours", "hnsecs")(24);
1493 --days;
1496 auto date = Date(cast(int) days);
1497 date.day = day;
1499 immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1);
1500 adjTime = newDaysHNSecs + hnsecs;
1503 @safe unittest
1505 import std.range : chain;
1506 import std.traits : EnumMembers;
1508 foreach (day; chain(testDays))
1510 foreach (st; chain(testSysTimesBC, testSysTimesAD))
1512 auto dt = cast(DateTime) st;
1514 if (day > maxDay(dt.year, dt.month))
1515 continue;
1516 auto expected = SysTime(DateTime(dt.year, dt.month, day, dt.hour, dt.minute, dt.second),
1517 st.fracSecs,
1518 st.timezone);
1519 st.day = day;
1520 assert(st == expected, format("[%s] [%s]", st, expected));
1524 foreach (tz; testTZs)
1526 foreach (tod; testTODs)
1528 foreach (fs; testFracSecs)
1530 foreach (year; chain(testYearsBC, testYearsAD))
1532 foreach (month; EnumMembers!Month)
1534 auto st = SysTime(DateTime(Date(year, month, 1), tod), fs, tz);
1535 immutable max = maxDay(year, month);
1536 auto expected = SysTime(DateTime(Date(year, month, max), tod), fs, tz);
1538 st.day = max;
1539 assert(st == expected, format("[%s] [%s]", st, expected));
1546 foreach (tz; testTZs)
1548 foreach (tod; testTODsThrown)
1550 foreach (fs; [testFracSecs[0], testFracSecs[$-1]])
1552 foreach (year; [testYearsBC[$-3], testYearsBC[$-2],
1553 testYearsBC[$-2], testYearsAD[0],
1554 testYearsAD[$-2], testYearsAD[$-1]])
1556 foreach (month; EnumMembers!Month)
1558 auto st = SysTime(DateTime(Date(year, month, 1), tod), fs, tz);
1559 immutable max = maxDay(year, month);
1561 assertThrown!DateTimeException(st.day = max + 1);
1568 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1569 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1570 static assert(!__traits(compiles, cst.day = 27));
1571 static assert(!__traits(compiles, ist.day = 27));
1573 static void testScope(scope ref SysTime st) @safe
1575 st.day = 12;
1581 Hours past midnight.
1583 @property ubyte hour() @safe const nothrow scope
1585 auto hnsecs = adjTime;
1586 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
1588 if (hnsecs < 0)
1590 hnsecs += convert!("hours", "hnsecs")(24);
1591 --days;
1594 return cast(ubyte) getUnitsFromHNSecs!"hours"(hnsecs);
1597 @safe unittest
1599 import std.range : chain;
1601 static void test(SysTime sysTime, int expected)
1603 assert(sysTime.hour == expected, format("Value given: %s", sysTime));
1606 test(SysTime(0, UTC()), 0);
1607 test(SysTime(1, UTC()), 0);
1608 test(SysTime(-1, UTC()), 23);
1610 foreach (tz; testTZs)
1612 foreach (year; chain(testYearsBC, testYearsAD))
1614 foreach (md; testMonthDays)
1616 foreach (hour; testHours)
1618 foreach (minute; testMinSecs)
1620 foreach (second; testMinSecs)
1622 auto dt = DateTime(Date(year, md.month, md.day), TimeOfDay(hour, minute, second));
1623 foreach (fs; testFracSecs)
1624 test(SysTime(dt, fs, tz), hour);
1632 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1633 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1634 assert(cst.hour == 12);
1635 assert(ist.hour == 12);
1637 static void testScope(scope ref SysTime st) @safe
1639 auto result = st.hour;
1645 Hours past midnight.
1647 Params:
1648 hour = The hours to set this $(LREF SysTime)'s hour to.
1650 Throws:
1651 $(REF DateTimeException,std,datetime,date) if the given hour are
1652 not a valid hour of the day.
1654 @property void hour(int hour) @safe scope
1656 enforceValid!"hours"(hour);
1658 auto hnsecs = adjTime;
1659 auto days = splitUnitsFromHNSecs!"days"(hnsecs);
1660 immutable daysHNSecs = convert!("days", "hnsecs")(days);
1661 immutable negative = hnsecs < 0;
1663 if (negative)
1664 hnsecs += convert!("hours", "hnsecs")(24);
1666 hnsecs = removeUnitsFromHNSecs!"hours"(hnsecs);
1667 hnsecs += convert!("hours", "hnsecs")(hour);
1669 if (negative)
1670 hnsecs -= convert!("hours", "hnsecs")(24);
1672 adjTime = daysHNSecs + hnsecs;
1675 @safe unittest
1677 import std.range : chain;
1679 foreach (hour; chain(testHours))
1681 foreach (st; chain(testSysTimesBC, testSysTimesAD))
1683 auto dt = cast(DateTime) st;
1684 auto expected = SysTime(DateTime(dt.year, dt.month, dt.day, hour, dt.minute, dt.second),
1685 st.fracSecs,
1686 st.timezone);
1687 st.hour = hour;
1688 assert(st == expected, format("[%s] [%s]", st, expected));
1692 auto st = testSysTimesAD[0];
1693 assertThrown!DateTimeException(st.hour = -1);
1694 assertThrown!DateTimeException(st.hour = 60);
1696 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1697 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1698 static assert(!__traits(compiles, cst.hour = 27));
1699 static assert(!__traits(compiles, ist.hour = 27));
1701 static void testScope(scope ref SysTime st) @safe
1703 st.hour = 12;
1709 Minutes past the current hour.
1711 @property ubyte minute() @safe const nothrow scope
1713 auto hnsecs = adjTime;
1714 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
1716 if (hnsecs < 0)
1718 hnsecs += convert!("hours", "hnsecs")(24);
1719 --days;
1722 hnsecs = removeUnitsFromHNSecs!"hours"(hnsecs);
1724 return cast(ubyte) getUnitsFromHNSecs!"minutes"(hnsecs);
1727 @safe unittest
1729 import std.range : chain;
1731 static void test(SysTime sysTime, int expected)
1733 assert(sysTime.minute == expected, format("Value given: %s", sysTime));
1736 test(SysTime(0, UTC()), 0);
1737 test(SysTime(1, UTC()), 0);
1738 test(SysTime(-1, UTC()), 59);
1740 foreach (tz; testTZs)
1742 foreach (year; chain(testYearsBC, testYearsAD))
1744 foreach (md; testMonthDays)
1746 foreach (hour; testHours)
1748 foreach (minute; testMinSecs)
1750 foreach (second; testMinSecs)
1752 auto dt = DateTime(Date(year, md.month, md.day), TimeOfDay(hour, minute, second));
1753 foreach (fs; testFracSecs)
1754 test(SysTime(dt, fs, tz), minute);
1762 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1763 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1764 assert(cst.minute == 30);
1765 assert(ist.minute == 30);
1767 static void testScope(scope ref SysTime st) @safe
1769 auto result = st.minute;
1775 Minutes past the current hour.
1777 Params:
1778 minute = The minute to set this $(LREF SysTime)'s minute to.
1780 Throws:
1781 $(REF DateTimeException,std,datetime,date) if the given minute are
1782 not a valid minute of an hour.
1784 @property void minute(int minute) @safe scope
1786 enforceValid!"minutes"(minute);
1788 auto hnsecs = adjTime;
1789 auto days = splitUnitsFromHNSecs!"days"(hnsecs);
1790 immutable daysHNSecs = convert!("days", "hnsecs")(days);
1791 immutable negative = hnsecs < 0;
1793 if (negative)
1794 hnsecs += convert!("hours", "hnsecs")(24);
1796 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs);
1797 hnsecs = removeUnitsFromHNSecs!"minutes"(hnsecs);
1799 hnsecs += convert!("hours", "hnsecs")(hour);
1800 hnsecs += convert!("minutes", "hnsecs")(minute);
1802 if (negative)
1803 hnsecs -= convert!("hours", "hnsecs")(24);
1805 adjTime = daysHNSecs + hnsecs;
1808 @safe unittest
1810 import std.range : chain;
1812 foreach (minute; testMinSecs)
1814 foreach (st; chain(testSysTimesBC, testSysTimesAD))
1816 auto dt = cast(DateTime) st;
1817 auto expected = SysTime(DateTime(dt.year, dt.month, dt.day, dt.hour, minute, dt.second),
1818 st.fracSecs,
1819 st.timezone);
1820 st.minute = minute;
1821 assert(st == expected, format("[%s] [%s]", st, expected));
1825 auto st = testSysTimesAD[0];
1826 assertThrown!DateTimeException(st.minute = -1);
1827 assertThrown!DateTimeException(st.minute = 60);
1829 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1830 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1831 static assert(!__traits(compiles, cst.minute = 27));
1832 static assert(!__traits(compiles, ist.minute = 27));
1834 static void testScope(scope ref SysTime st) @safe
1836 st.minute = 12;
1842 Seconds past the current minute.
1844 @property ubyte second() @safe const nothrow scope
1846 auto hnsecs = adjTime;
1847 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
1849 if (hnsecs < 0)
1851 hnsecs += convert!("hours", "hnsecs")(24);
1852 --days;
1855 hnsecs = removeUnitsFromHNSecs!"hours"(hnsecs);
1856 hnsecs = removeUnitsFromHNSecs!"minutes"(hnsecs);
1858 return cast(ubyte) getUnitsFromHNSecs!"seconds"(hnsecs);
1861 @safe unittest
1863 import std.range : chain;
1865 static void test(SysTime sysTime, int expected)
1867 assert(sysTime.second == expected, format("Value given: %s", sysTime));
1870 test(SysTime(0, UTC()), 0);
1871 test(SysTime(1, UTC()), 0);
1872 test(SysTime(-1, UTC()), 59);
1874 foreach (tz; testTZs)
1876 foreach (year; chain(testYearsBC, testYearsAD))
1878 foreach (md; testMonthDays)
1880 foreach (hour; testHours)
1882 foreach (minute; testMinSecs)
1884 foreach (second; testMinSecs)
1886 auto dt = DateTime(Date(year, md.month, md.day), TimeOfDay(hour, minute, second));
1887 foreach (fs; testFracSecs)
1888 test(SysTime(dt, fs, tz), second);
1896 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1897 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1898 assert(cst.second == 33);
1899 assert(ist.second == 33);
1901 static void testScope(scope ref SysTime st) @safe
1903 auto result = st.second;
1909 Seconds past the current minute.
1911 Params:
1912 second = The second to set this $(LREF SysTime)'s second to.
1914 Throws:
1915 $(REF DateTimeException,std,datetime,date) if the given second are
1916 not a valid second of a minute.
1918 @property void second(int second) @safe scope
1920 enforceValid!"seconds"(second);
1922 auto hnsecs = adjTime;
1923 auto days = splitUnitsFromHNSecs!"days"(hnsecs);
1924 immutable daysHNSecs = convert!("days", "hnsecs")(days);
1925 immutable negative = hnsecs < 0;
1927 if (negative)
1928 hnsecs += convert!("hours", "hnsecs")(24);
1930 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs);
1931 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs);
1932 hnsecs = removeUnitsFromHNSecs!"seconds"(hnsecs);
1934 hnsecs += convert!("hours", "hnsecs")(hour);
1935 hnsecs += convert!("minutes", "hnsecs")(minute);
1936 hnsecs += convert!("seconds", "hnsecs")(second);
1938 if (negative)
1939 hnsecs -= convert!("hours", "hnsecs")(24);
1941 adjTime = daysHNSecs + hnsecs;
1944 @safe unittest
1946 import std.range : chain;
1948 foreach (second; testMinSecs)
1950 foreach (st; chain(testSysTimesBC, testSysTimesAD))
1952 auto dt = cast(DateTime) st;
1953 auto expected = SysTime(DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, second),
1954 st.fracSecs,
1955 st.timezone);
1956 st.second = second;
1957 assert(st == expected, format("[%s] [%s]", st, expected));
1961 auto st = testSysTimesAD[0];
1962 assertThrown!DateTimeException(st.second = -1);
1963 assertThrown!DateTimeException(st.second = 60);
1965 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1966 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
1967 static assert(!__traits(compiles, cst.seconds = 27));
1968 static assert(!__traits(compiles, ist.seconds = 27));
1970 static void testScope(scope ref SysTime st) @safe
1972 st.second = 12;
1978 Fractional seconds past the second (i.e. the portion of a
1979 $(LREF SysTime) which is less than a second).
1981 @property Duration fracSecs() @safe const nothrow scope
1983 auto hnsecs = removeUnitsFromHNSecs!"days"(adjTime);
1985 if (hnsecs < 0)
1986 hnsecs += convert!("hours", "hnsecs")(24);
1988 return dur!"hnsecs"(removeUnitsFromHNSecs!"seconds"(hnsecs));
1992 @safe unittest
1994 import core.time : msecs, usecs, hnsecs, nsecs;
1995 import std.datetime.date : DateTime;
1997 auto dt = DateTime(1982, 4, 1, 20, 59, 22);
1998 assert(SysTime(dt, msecs(213)).fracSecs == msecs(213));
1999 assert(SysTime(dt, usecs(5202)).fracSecs == usecs(5202));
2000 assert(SysTime(dt, hnsecs(1234567)).fracSecs == hnsecs(1234567));
2002 // SysTime and Duration both have a precision of hnsecs (100 ns),
2003 // so nsecs are going to be truncated.
2004 assert(SysTime(dt, nsecs(123456789)).fracSecs == nsecs(123456700));
2007 @safe unittest
2009 import std.range : chain;
2010 import core.time;
2012 assert(SysTime(0, UTC()).fracSecs == Duration.zero);
2013 assert(SysTime(1, UTC()).fracSecs == hnsecs(1));
2014 assert(SysTime(-1, UTC()).fracSecs == hnsecs(9_999_999));
2016 foreach (tz; testTZs)
2018 foreach (year; chain(testYearsBC, testYearsAD))
2020 foreach (md; testMonthDays)
2022 foreach (hour; testHours)
2024 foreach (minute; testMinSecs)
2026 foreach (second; testMinSecs)
2028 auto dt = DateTime(Date(year, md.month, md.day), TimeOfDay(hour, minute, second));
2029 foreach (fs; testFracSecs)
2030 assert(SysTime(dt, fs, tz).fracSecs == fs);
2038 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
2039 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
2040 assert(cst.fracSecs == Duration.zero);
2041 assert(ist.fracSecs == Duration.zero);
2043 static void testScope(scope ref SysTime st) @safe
2045 auto result = st.fracSecs;
2051 Fractional seconds past the second (i.e. the portion of a
2052 $(LREF SysTime) which is less than a second).
2054 Params:
2055 fracSecs = The duration to set this $(LREF SysTime)'s fractional
2056 seconds to.
2058 Throws:
2059 $(REF DateTimeException,std,datetime,date) if the given duration
2060 is negative or if it's greater than or equal to one second.
2062 @property void fracSecs(Duration fracSecs) @safe scope
2064 enforce(fracSecs >= Duration.zero, new DateTimeException("A SysTime cannot have negative fractional seconds."));
2065 enforce(fracSecs < seconds(1), new DateTimeException("Fractional seconds must be less than one second."));
2067 auto oldHNSecs = adjTime;
2068 auto days = splitUnitsFromHNSecs!"days"(oldHNSecs);
2069 immutable daysHNSecs = convert!("days", "hnsecs")(days);
2070 immutable negative = oldHNSecs < 0;
2072 if (negative)
2073 oldHNSecs += convert!("hours", "hnsecs")(24);
2075 immutable seconds = splitUnitsFromHNSecs!"seconds"(oldHNSecs);
2076 immutable secondsHNSecs = convert!("seconds", "hnsecs")(seconds);
2077 auto newHNSecs = fracSecs.total!"hnsecs" + secondsHNSecs;
2079 if (negative)
2080 newHNSecs -= convert!("hours", "hnsecs")(24);
2082 adjTime = daysHNSecs + newHNSecs;
2086 @safe unittest
2088 import core.time : Duration, msecs, hnsecs, nsecs;
2089 import std.datetime.date : DateTime;
2091 auto st = SysTime(DateTime(1982, 4, 1, 20, 59, 22));
2092 assert(st.fracSecs == Duration.zero);
2094 st.fracSecs = msecs(213);
2095 assert(st.fracSecs == msecs(213));
2097 st.fracSecs = hnsecs(1234567);
2098 assert(st.fracSecs == hnsecs(1234567));
2100 // SysTime has a precision of hnsecs (100 ns), so nsecs are
2101 // going to be truncated.
2102 st.fracSecs = nsecs(123456789);
2103 assert(st.fracSecs == hnsecs(1234567));
2106 @safe unittest
2108 import std.range : chain;
2109 import core.time;
2111 foreach (fracSec; testFracSecs)
2113 foreach (st; chain(testSysTimesBC, testSysTimesAD))
2115 auto dt = cast(DateTime) st;
2116 auto expected = SysTime(dt, fracSec, st.timezone);
2117 st.fracSecs = fracSec;
2118 assert(st == expected, format("[%s] [%s]", st, expected));
2122 auto st = testSysTimesAD[0];
2123 assertThrown!DateTimeException(st.fracSecs = hnsecs(-1));
2124 assertThrown!DateTimeException(st.fracSecs = seconds(1));
2126 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
2127 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
2128 static assert(!__traits(compiles, cst.fracSecs = msecs(7)));
2129 static assert(!__traits(compiles, ist.fracSecs = msecs(7)));
2131 static void testScope(scope ref SysTime st) @safe
2133 st.fracSecs = Duration.zero;
2139 The total hnsecs from midnight, January 1st, 1 A.D. UTC. This is the
2140 internal representation of $(LREF SysTime).
2142 @property long stdTime() @safe const pure nothrow scope @nogc
2144 return _stdTime;
2147 @safe unittest
2149 import core.time;
2150 assert(SysTime(0).stdTime == 0);
2151 assert(SysTime(1).stdTime == 1);
2152 assert(SysTime(-1).stdTime == -1);
2153 assert(SysTime(DateTime(1, 1, 1, 0, 0, 33), hnsecs(502), UTC()).stdTime == 330_000_502L);
2154 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 0), UTC()).stdTime == 621_355_968_000_000_000L);
2156 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
2157 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
2158 assert(cst.stdTime > 0);
2159 assert(ist.stdTime > 0);
2161 static void testScope(scope ref SysTime st) @safe
2163 auto result = st.stdTime;
2169 The total hnsecs from midnight, January 1st, 1 A.D. UTC. This is the
2170 internal representation of $(LREF SysTime).
2172 Params:
2173 stdTime = The number of hnsecs since January 1st, 1 A.D. UTC.
2175 @property void stdTime(long stdTime) @safe pure nothrow scope
2177 _stdTime = stdTime;
2180 @safe unittest
2182 import core.time;
2183 static void test(long stdTime, SysTime expected, size_t line = __LINE__)
2185 auto st = SysTime(0, UTC());
2186 st.stdTime = stdTime;
2187 assert(st == expected);
2190 test(0, SysTime(Date(1, 1, 1), UTC()));
2191 test(1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC()));
2192 test(-1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()));
2193 test(330_000_502L, SysTime(DateTime(1, 1, 1, 0, 0, 33), hnsecs(502), UTC()));
2194 test(621_355_968_000_000_000L, SysTime(DateTime(1970, 1, 1, 0, 0, 0), UTC()));
2196 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
2197 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
2198 static assert(!__traits(compiles, cst.stdTime = 27));
2199 static assert(!__traits(compiles, ist.stdTime = 27));
2201 static void testScope(scope ref SysTime st) @safe
2203 st.stdTime = 42;
2209 The current time zone of this $(LREF SysTime). Its internal time is
2210 always kept in UTC, so there are no conversion issues between time zones
2211 due to DST. Functions which return all or part of the time - such as
2212 hours - adjust the time to this $(LREF SysTime)'s time zone before
2213 returning.
2215 @property immutable(TimeZone) timezone() @safe const pure nothrow return scope
2217 return _timezone;
2220 @safe unittest
2222 assert(SysTime.init.timezone is InitTimeZone());
2223 assert(SysTime(DateTime.init, UTC()).timezone is UTC());
2225 static void testScope(scope ref SysTime st) @safe
2227 auto result = st.timezone;
2233 The current time zone of this $(LREF SysTime). It's internal time is
2234 always kept in UTC, so there are no conversion issues between time zones
2235 due to DST. Functions which return all or part of the time - such as
2236 hours - adjust the time to this $(LREF SysTime)'s time zone before
2237 returning.
2239 Params:
2240 timezone = The $(REF _TimeZone,std,datetime,_timezone) to set this
2241 $(LREF SysTime)'s time zone to.
2243 @property void timezone(immutable TimeZone timezone) @safe pure nothrow scope
2245 if (timezone is null)
2246 _timezone = LocalTime();
2247 else
2248 _timezone = timezone;
2251 @safe unittest
2253 SysTime st;
2254 st.timezone = null;
2255 assert(st.timezone is LocalTime());
2256 st.timezone = UTC();
2257 assert(st.timezone is UTC());
2259 static void testScope(scope ref SysTime st) @safe
2261 st.timezone = UTC();
2267 Returns whether DST is in effect for this $(LREF SysTime).
2269 @property bool dstInEffect() @safe const nothrow return scope
2271 return _timezone.dstInEffect(_stdTime);
2274 // This function's full unit testing is done in the time zone classes, but
2275 // this verifies that SysTime.init works correctly, since historically, it
2276 // has segfaulted due to a null _timezone.
2277 @safe unittest
2279 assert(!SysTime.init.dstInEffect);
2281 static void testScope(scope ref SysTime st) @safe
2283 auto result = st.dstInEffect;
2289 Returns what the offset from UTC is for this $(LREF SysTime).
2290 It includes the DST offset in effect at that time (if any).
2292 @property Duration utcOffset() @safe const nothrow return scope
2294 return _timezone.utcOffsetAt(_stdTime);
2297 // This function's full unit testing is done in the time zone classes, but
2298 // this verifies that SysTime.init works correctly, since historically, it
2299 // has segfaulted due to a null _timezone.
2300 @safe unittest
2302 assert(SysTime.init.utcOffset == Duration.zero);
2304 static void testScope(scope ref SysTime st) @safe
2306 auto result = st.utcOffset;
2312 Returns a $(LREF SysTime) with the same std time as this one, but with
2313 $(REF LocalTime,std,datetime,timezone) as its time zone.
2315 SysTime toLocalTime() @safe const pure nothrow scope
2317 return SysTime(_stdTime, LocalTime());
2320 @safe unittest
2322 import core.time;
2324 auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), hnsecs(27));
2325 assert(sysTime == sysTime.toLocalTime());
2326 assert(sysTime._stdTime == sysTime.toLocalTime()._stdTime);
2327 assert(sysTime.toLocalTime().timezone is LocalTime());
2328 assert(sysTime.toLocalTime().timezone is sysTime.timezone);
2329 assert(sysTime.toLocalTime().timezone !is UTC());
2333 auto stz = new immutable SimpleTimeZone(dur!"minutes"(-3 * 60));
2334 auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), hnsecs(27), stz);
2335 assert(sysTime == sysTime.toLocalTime());
2336 assert(sysTime._stdTime == sysTime.toLocalTime()._stdTime);
2337 assert(sysTime.toLocalTime().timezone is LocalTime());
2338 assert(sysTime.toLocalTime().timezone !is UTC());
2339 assert(sysTime.toLocalTime().timezone !is stz);
2342 static void testScope(scope ref SysTime st) @safe
2344 auto result = st.toLocalTime();
2350 Returns a $(LREF SysTime) with the same std time as this one, but with
2351 `UTC` as its time zone.
2353 SysTime toUTC() @safe const pure nothrow scope
2355 return SysTime(_stdTime, UTC());
2358 @safe unittest
2360 import core.time;
2361 auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), hnsecs(27));
2362 assert(sysTime == sysTime.toUTC());
2363 assert(sysTime._stdTime == sysTime.toUTC()._stdTime);
2364 assert(sysTime.toUTC().timezone is UTC());
2365 assert(sysTime.toUTC().timezone !is LocalTime());
2366 assert(sysTime.toUTC().timezone !is sysTime.timezone);
2368 static void testScope(scope ref SysTime st) @safe
2370 auto result = st.toUTC();
2376 Returns a $(LREF SysTime) with the same std time as this one, but with
2377 given time zone as its time zone.
2379 SysTime toOtherTZ(immutable TimeZone tz) @safe const pure nothrow scope
2381 if (tz is null)
2382 return SysTime(_stdTime, LocalTime());
2383 else
2384 return SysTime(_stdTime, tz);
2387 @safe unittest
2389 import core.time;
2390 auto stz = new immutable SimpleTimeZone(dur!"minutes"(11 * 60));
2391 auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), hnsecs(27));
2392 assert(sysTime == sysTime.toOtherTZ(stz));
2393 assert(sysTime._stdTime == sysTime.toOtherTZ(stz)._stdTime);
2394 assert(sysTime.toOtherTZ(stz).timezone is stz);
2395 assert(sysTime.toOtherTZ(stz).timezone !is LocalTime());
2396 assert(sysTime.toOtherTZ(stz).timezone !is UTC());
2397 assert(sysTime.toOtherTZ(null).timezone is LocalTime());
2399 static void testScope(scope ref SysTime st) @safe
2401 auto result = st.toOtherTZ(null);
2407 Converts this $(LREF SysTime) to unix time (i.e. seconds from midnight,
2408 January 1st, 1970 in UTC).
2410 The C standard does not specify the representation of time_t, so it is
2411 implementation defined. On POSIX systems, unix time is equivalent to
2412 time_t, but that's not necessarily true on other systems (e.g. it is
2413 not true for the Digital Mars C runtime). So, be careful when using unix
2414 time with C functions on non-POSIX systems.
2416 By default, the return type is time_t (which is normally an alias for
2417 int on 32-bit systems and long on 64-bit systems), but if a different
2418 size is required than either int or long can be passed as a template
2419 argument to get the desired size.
2421 If the return type is int, and the result can't fit in an int, then the
2422 closest value that can be held in 32 bits will be used (so `int.max`
2423 if it goes over and `int.min` if it goes under). However, no attempt
2424 is made to deal with integer overflow if the return type is long.
2426 Params:
2427 T = The return type (int or long). It defaults to time_t, which is
2428 normally 32 bits on a 32-bit system and 64 bits on a 64-bit
2429 system.
2431 Returns:
2432 A signed integer representing the unix time which is equivalent to
2433 this SysTime.
2435 T toUnixTime(T = time_t)() @safe const pure nothrow scope
2436 if (is(T == int) || is(T == long))
2438 return stdTimeToUnixTime!T(_stdTime);
2442 @safe unittest
2444 import core.time : hours;
2445 import std.datetime.date : DateTime;
2446 import std.datetime.timezone : SimpleTimeZone, UTC;
2448 assert(SysTime(DateTime(1970, 1, 1), UTC()).toUnixTime() == 0);
2450 auto pst = new immutable SimpleTimeZone(hours(-8));
2451 assert(SysTime(DateTime(1970, 1, 1), pst).toUnixTime() == 28800);
2453 auto utc = SysTime(DateTime(2007, 12, 22, 8, 14, 45), UTC());
2454 assert(utc.toUnixTime() == 1_198_311_285);
2456 auto ca = SysTime(DateTime(2007, 12, 22, 8, 14, 45), pst);
2457 assert(ca.toUnixTime() == 1_198_340_085);
2459 static void testScope(scope ref SysTime st) @safe
2461 auto result = st.toUnixTime();
2465 @safe unittest
2467 import std.meta : AliasSeq;
2468 import core.time;
2469 assert(SysTime(DateTime(1970, 1, 1), UTC()).toUnixTime() == 0);
2470 static foreach (units; ["hnsecs", "usecs", "msecs"])
2471 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 0), dur!units(1), UTC()).toUnixTime() == 0);
2472 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), UTC()).toUnixTime() == 1);
2473 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toUnixTime() == 0);
2474 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999_999), UTC()).toUnixTime() == 0);
2475 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), msecs(999), UTC()).toUnixTime() == 0);
2476 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), UTC()).toUnixTime() == -1);
2481 Converts from unix time (i.e. seconds from midnight, January 1st, 1970
2482 in UTC) to a $(LREF SysTime).
2484 The C standard does not specify the representation of time_t, so it is
2485 implementation defined. On POSIX systems, unix time is equivalent to
2486 time_t, but that's not necessarily true on other systems (e.g. it is
2487 not true for the Digital Mars C runtime). So, be careful when using unix
2488 time with C functions on non-POSIX systems.
2490 Params:
2491 unixTime = Seconds from midnight, January 1st, 1970 in UTC.
2492 tz = The time zone for the SysTime that's returned.
2494 static SysTime fromUnixTime(long unixTime, immutable TimeZone tz = LocalTime()) @safe pure nothrow
2496 return SysTime(unixTimeToStdTime(unixTime), tz);
2500 @safe unittest
2502 import core.time : hours;
2503 import std.datetime.date : DateTime;
2504 import std.datetime.timezone : SimpleTimeZone, UTC;
2506 assert(SysTime.fromUnixTime(0) ==
2507 SysTime(DateTime(1970, 1, 1), UTC()));
2509 auto pst = new immutable SimpleTimeZone(hours(-8));
2510 assert(SysTime.fromUnixTime(28800) ==
2511 SysTime(DateTime(1970, 1, 1), pst));
2513 auto st1 = SysTime.fromUnixTime(1_198_311_285, UTC());
2514 assert(st1 == SysTime(DateTime(2007, 12, 22, 8, 14, 45), UTC()));
2515 assert(st1.timezone is UTC());
2516 assert(st1 == SysTime(DateTime(2007, 12, 22, 0, 14, 45), pst));
2518 auto st2 = SysTime.fromUnixTime(1_198_311_285, pst);
2519 assert(st2 == SysTime(DateTime(2007, 12, 22, 8, 14, 45), UTC()));
2520 assert(st2.timezone is pst);
2521 assert(st2 == SysTime(DateTime(2007, 12, 22, 0, 14, 45), pst));
2524 @safe unittest
2526 import core.time;
2527 assert(SysTime.fromUnixTime(0) == SysTime(DateTime(1970, 1, 1), UTC()));
2528 assert(SysTime.fromUnixTime(1) == SysTime(DateTime(1970, 1, 1, 0, 0, 1), UTC()));
2529 assert(SysTime.fromUnixTime(-1) == SysTime(DateTime(1969, 12, 31, 23, 59, 59), UTC()));
2531 auto st = SysTime.fromUnixTime(0);
2532 auto dt = cast(DateTime) st;
2533 assert(dt <= DateTime(1970, 2, 1) && dt >= DateTime(1969, 12, 31));
2534 assert(st.timezone is LocalTime());
2536 auto aest = new immutable SimpleTimeZone(hours(10));
2537 assert(SysTime.fromUnixTime(-36000) == SysTime(DateTime(1970, 1, 1), aest));
2542 Returns a `timeval` which represents this $(LREF SysTime).
2544 Note that like all conversions in std.datetime, this is a truncating
2545 conversion.
2547 If `timeval.tv_sec` is int, and the result can't fit in an int, then
2548 the closest value that can be held in 32 bits will be used for
2549 `tv_sec`. (so `int.max` if it goes over and `int.min` if it
2550 goes under).
2552 timeval toTimeVal() @safe const pure nothrow scope
2554 immutable tv_sec = toUnixTime!(typeof(timeval.tv_sec))();
2555 immutable fracHNSecs = removeUnitsFromHNSecs!"seconds"(_stdTime - 621_355_968_000_000_000L);
2556 immutable tv_usec = cast(typeof(timeval.tv_usec))convert!("hnsecs", "usecs")(fracHNSecs);
2557 return timeval(tv_sec, tv_usec);
2560 @safe unittest
2562 import core.time;
2563 assert(SysTime(DateTime(1970, 1, 1), UTC()).toTimeVal() == timeval(0, 0));
2564 assert(SysTime(DateTime(1970, 1, 1), hnsecs(9), UTC()).toTimeVal() == timeval(0, 0));
2565 assert(SysTime(DateTime(1970, 1, 1), hnsecs(10), UTC()).toTimeVal() == timeval(0, 1));
2566 assert(SysTime(DateTime(1970, 1, 1), usecs(7), UTC()).toTimeVal() == timeval(0, 7));
2568 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), UTC()).toTimeVal() == timeval(1, 0));
2569 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), hnsecs(9), UTC()).toTimeVal() == timeval(1, 0));
2570 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), hnsecs(10), UTC()).toTimeVal() == timeval(1, 1));
2571 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), usecs(7), UTC()).toTimeVal() == timeval(1, 7));
2573 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toTimeVal() == timeval(0, 0));
2574 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_990), UTC()).toTimeVal() == timeval(0, -1));
2576 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999_999), UTC()).toTimeVal() == timeval(0, -1));
2577 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999), UTC()).toTimeVal() == timeval(0, -999_001));
2578 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), msecs(999), UTC()).toTimeVal() == timeval(0, -1000));
2579 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), UTC()).toTimeVal() == timeval(-1, 0));
2580 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 58), usecs(17), UTC()).toTimeVal() == timeval(-1, -999_983));
2582 static void testScope(scope ref SysTime st) @safe
2584 auto result = st.toTimeVal();
2589 version (StdDdoc)
2591 version (Windows) private struct timespec {}
2593 Returns a `timespec` which represents this $(LREF SysTime).
2595 $(BLUE This function is Posix-Only.)
2597 timespec toTimeSpec() @safe const pure nothrow scope;
2599 else version (Posix)
2601 timespec toTimeSpec() @safe const pure nothrow scope
2603 immutable tv_sec = toUnixTime!(typeof(timespec.tv_sec))();
2604 immutable fracHNSecs = removeUnitsFromHNSecs!"seconds"(_stdTime - 621_355_968_000_000_000L);
2605 immutable tv_nsec = cast(typeof(timespec.tv_nsec))convert!("hnsecs", "nsecs")(fracHNSecs);
2606 return timespec(tv_sec, tv_nsec);
2609 @safe unittest
2611 import core.time;
2612 assert(SysTime(DateTime(1970, 1, 1), UTC()).toTimeSpec() == timespec(0, 0));
2613 assert(SysTime(DateTime(1970, 1, 1), hnsecs(9), UTC()).toTimeSpec() == timespec(0, 900));
2614 assert(SysTime(DateTime(1970, 1, 1), hnsecs(10), UTC()).toTimeSpec() == timespec(0, 1000));
2615 assert(SysTime(DateTime(1970, 1, 1), usecs(7), UTC()).toTimeSpec() == timespec(0, 7000));
2617 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), UTC()).toTimeSpec() == timespec(1, 0));
2618 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), hnsecs(9), UTC()).toTimeSpec() == timespec(1, 900));
2619 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), hnsecs(10), UTC()).toTimeSpec() == timespec(1, 1000));
2620 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), usecs(7), UTC()).toTimeSpec() == timespec(1, 7000));
2622 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toTimeSpec() ==
2623 timespec(0, -100));
2624 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_990), UTC()).toTimeSpec() ==
2625 timespec(0, -1000));
2627 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999_999), UTC()).toTimeSpec() ==
2628 timespec(0, -1_000));
2629 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999), UTC()).toTimeSpec() ==
2630 timespec(0, -999_001_000));
2631 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), msecs(999), UTC()).toTimeSpec() ==
2632 timespec(0, -1_000_000));
2633 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), UTC()).toTimeSpec() ==
2634 timespec(-1, 0));
2635 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 58), usecs(17), UTC()).toTimeSpec() ==
2636 timespec(-1, -999_983_000));
2638 static void testScope(scope ref SysTime st) @safe
2640 auto result = st.toTimeSpec();
2646 Returns a `tm` which represents this $(LREF SysTime).
2648 tm toTM() @safe const nothrow scope
2650 auto dateTime = cast(DateTime) this;
2651 tm timeInfo;
2653 timeInfo.tm_sec = dateTime.second;
2654 timeInfo.tm_min = dateTime.minute;
2655 timeInfo.tm_hour = dateTime.hour;
2656 timeInfo.tm_mday = dateTime.day;
2657 timeInfo.tm_mon = dateTime.month - 1;
2658 timeInfo.tm_year = dateTime.year - 1900;
2659 timeInfo.tm_wday = dateTime.dayOfWeek;
2660 timeInfo.tm_yday = dateTime.dayOfYear - 1;
2661 timeInfo.tm_isdst = _timezone.dstInEffect(_stdTime);
2663 version (Posix)
2665 import std.utf : toUTFz;
2666 timeInfo.tm_gmtoff = cast(int) convert!("hnsecs", "seconds")(adjTime - _stdTime);
2667 auto zone = timeInfo.tm_isdst ? _timezone.dstName : _timezone.stdName;
2668 timeInfo.tm_zone = zone.toUTFz!(char*)();
2671 return timeInfo;
2674 @system unittest
2676 import std.conv : to;
2677 import core.time;
2679 version (Posix)
2681 import std.datetime.timezone : clearTZEnvVar, setTZEnvVar;
2682 setTZEnvVar("America/Los_Angeles");
2683 scope(exit) clearTZEnvVar();
2687 auto timeInfo = SysTime(DateTime(1970, 1, 1)).toTM();
2689 assert(timeInfo.tm_sec == 0);
2690 assert(timeInfo.tm_min == 0);
2691 assert(timeInfo.tm_hour == 0);
2692 assert(timeInfo.tm_mday == 1);
2693 assert(timeInfo.tm_mon == 0);
2694 assert(timeInfo.tm_year == 70);
2695 assert(timeInfo.tm_wday == 4);
2696 assert(timeInfo.tm_yday == 0);
2698 version (Posix)
2699 assert(timeInfo.tm_isdst == 0);
2700 else version (Windows)
2701 assert(timeInfo.tm_isdst == 0 || timeInfo.tm_isdst == 1);
2703 version (Posix)
2705 assert(timeInfo.tm_gmtoff == -8 * 60 * 60);
2706 assert(to!string(timeInfo.tm_zone) == "PST");
2711 auto timeInfo = SysTime(DateTime(2010, 7, 4, 12, 15, 7), hnsecs(15)).toTM();
2713 assert(timeInfo.tm_sec == 7);
2714 assert(timeInfo.tm_min == 15);
2715 assert(timeInfo.tm_hour == 12);
2716 assert(timeInfo.tm_mday == 4);
2717 assert(timeInfo.tm_mon == 6);
2718 assert(timeInfo.tm_year == 110);
2719 assert(timeInfo.tm_wday == 0);
2720 assert(timeInfo.tm_yday == 184);
2722 version (Posix)
2723 assert(timeInfo.tm_isdst == 1);
2724 else version (Windows)
2725 assert(timeInfo.tm_isdst == 0 || timeInfo.tm_isdst == 1);
2727 version (Posix)
2729 assert(timeInfo.tm_gmtoff == -7 * 60 * 60);
2730 assert(to!string(timeInfo.tm_zone) == "PDT");
2734 // This is more to verify that SysTime.init.toTM() doesn't segfault and
2735 // does something sane rather than that the value is anything
2736 // particularly useful.
2738 auto timeInfo = SysTime.init.toTM();
2740 assert(timeInfo.tm_sec == 0);
2741 assert(timeInfo.tm_min == 0);
2742 assert(timeInfo.tm_hour == 0);
2743 assert(timeInfo.tm_mday == 1);
2744 assert(timeInfo.tm_mon == 0);
2745 assert(timeInfo.tm_year == -1899);
2746 assert(timeInfo.tm_wday == 1);
2747 assert(timeInfo.tm_yday == 0);
2748 assert(timeInfo.tm_isdst == 0);
2750 version (Posix)
2752 assert(timeInfo.tm_gmtoff == 0);
2753 assert(to!string(timeInfo.tm_zone) == "SysTime.init's timezone");
2757 static void testScope(scope ref SysTime st) @safe
2759 auto result = st.toTM();
2765 Adds the given number of years or months to this $(LREF SysTime). A
2766 negative number will subtract.
2768 Note that if day overflow is allowed, and the date with the adjusted
2769 year/month overflows the number of days in the new month, then the month
2770 will be incremented by one, and the day set to the number of days
2771 overflowed. (e.g. if the day were 31 and the new month were June, then
2772 the month would be incremented to July, and the new day would be 1). If
2773 day overflow is not allowed, then the day will be set to the last valid
2774 day in the month (e.g. June 31st would become June 30th).
2776 Params:
2777 units = The type of units to add ("years" or "months").
2778 value = The number of months or years to add to this
2779 $(LREF SysTime).
2780 allowOverflow = Whether the days should be allowed to overflow,
2781 causing the month to increment.
2783 ref SysTime add(string units)(long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe nothrow scope
2784 if (units == "years" || units == "months")
2786 auto hnsecs = adjTime;
2787 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
2789 if (hnsecs < 0)
2791 hnsecs += convert!("hours", "hnsecs")(24);
2792 --days;
2795 auto date = Date(cast(int) days);
2796 date.add!units(value, allowOverflow);
2797 days = date.dayOfGregorianCal - 1;
2799 if (days < 0)
2801 hnsecs -= convert!("hours", "hnsecs")(24);
2802 ++days;
2805 immutable newDaysHNSecs = convert!("days", "hnsecs")(days);
2807 adjTime = newDaysHNSecs + hnsecs;
2809 return this;
2812 @safe unittest
2814 auto st1 = SysTime(DateTime(2010, 1, 1, 12, 30, 33));
2815 st1.add!"months"(11);
2816 assert(st1 == SysTime(DateTime(2010, 12, 1, 12, 30, 33)));
2818 auto st2 = SysTime(DateTime(2010, 1, 1, 12, 30, 33));
2819 st2.add!"months"(-11);
2820 assert(st2 == SysTime(DateTime(2009, 2, 1, 12, 30, 33)));
2822 auto st3 = SysTime(DateTime(2000, 2, 29, 12, 30, 33));
2823 st3.add!"years"(1);
2824 assert(st3 == SysTime(DateTime(2001, 3, 1, 12, 30, 33)));
2826 auto st4 = SysTime(DateTime(2000, 2, 29, 12, 30, 33));
2827 st4.add!"years"(1, AllowDayOverflow.no);
2828 assert(st4 == SysTime(DateTime(2001, 2, 28, 12, 30, 33)));
2831 // Test add!"years"() with AllowDayOverflow.yes
2832 @safe unittest
2834 import core.time;
2835 // Test A.D.
2837 auto sysTime = SysTime(Date(1999, 7, 6));
2838 sysTime.add!"years"(7);
2839 assert(sysTime == SysTime(Date(2006, 7, 6)));
2840 sysTime.add!"years"(-9);
2841 assert(sysTime == SysTime(Date(1997, 7, 6)));
2845 auto sysTime = SysTime(Date(1999, 2, 28));
2846 sysTime.add!"years"(1);
2847 assert(sysTime == SysTime(Date(2000, 2, 28)));
2851 auto sysTime = SysTime(Date(2000, 2, 29));
2852 sysTime.add!"years"(-1);
2853 assert(sysTime == SysTime(Date(1999, 3, 1)));
2857 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 7, 3), msecs(234));
2858 sysTime.add!"years"(7);
2859 assert(sysTime == SysTime(DateTime(2006, 7, 6, 12, 7, 3), msecs(234)));
2860 sysTime.add!"years"(-9);
2861 assert(sysTime == SysTime(DateTime(1997, 7, 6, 12, 7, 3), msecs(234)));
2865 auto sysTime = SysTime(DateTime(1999, 2, 28, 0, 7, 2), usecs(1207));
2866 sysTime.add!"years"(1);
2867 assert(sysTime == SysTime(DateTime(2000, 2, 28, 0, 7, 2), usecs(1207)));
2871 auto sysTime = SysTime(DateTime(2000, 2, 29, 0, 7, 2), usecs(1207));
2872 sysTime.add!"years"(-1);
2873 assert(sysTime == SysTime(DateTime(1999, 3, 1, 0, 7, 2), usecs(1207)));
2876 // Test B.C.
2878 auto sysTime = SysTime(Date(-1999, 7, 6));
2879 sysTime.add!"years"(-7);
2880 assert(sysTime == SysTime(Date(-2006, 7, 6)));
2881 sysTime.add!"years"(9);
2882 assert(sysTime == SysTime(Date(-1997, 7, 6)));
2886 auto sysTime = SysTime(Date(-1999, 2, 28));
2887 sysTime.add!"years"(-1);
2888 assert(sysTime == SysTime(Date(-2000, 2, 28)));
2892 auto sysTime = SysTime(Date(-2000, 2, 29));
2893 sysTime.add!"years"(1);
2894 assert(sysTime == SysTime(Date(-1999, 3, 1)));
2898 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 7, 3), msecs(234));
2899 sysTime.add!"years"(-7);
2900 assert(sysTime == SysTime(DateTime(-2006, 7, 6, 12, 7, 3), msecs(234)));
2901 sysTime.add!"years"(9);
2902 assert(sysTime == SysTime(DateTime(-1997, 7, 6, 12, 7, 3), msecs(234)));
2906 auto sysTime = SysTime(DateTime(-1999, 2, 28, 3, 3, 3), hnsecs(3));
2907 sysTime.add!"years"(-1);
2908 assert(sysTime == SysTime(DateTime(-2000, 2, 28, 3, 3, 3), hnsecs(3)));
2912 auto sysTime = SysTime(DateTime(-2000, 2, 29, 3, 3, 3), hnsecs(3));
2913 sysTime.add!"years"(1);
2914 assert(sysTime == SysTime(DateTime(-1999, 3, 1, 3, 3, 3), hnsecs(3)));
2917 // Test Both
2919 auto sysTime = SysTime(Date(4, 7, 6));
2920 sysTime.add!"years"(-5);
2921 assert(sysTime == SysTime(Date(-1, 7, 6)));
2922 sysTime.add!"years"(5);
2923 assert(sysTime == SysTime(Date(4, 7, 6)));
2927 auto sysTime = SysTime(Date(-4, 7, 6));
2928 sysTime.add!"years"(5);
2929 assert(sysTime == SysTime(Date(1, 7, 6)));
2930 sysTime.add!"years"(-5);
2931 assert(sysTime == SysTime(Date(-4, 7, 6)));
2935 auto sysTime = SysTime(Date(4, 7, 6));
2936 sysTime.add!"years"(-8);
2937 assert(sysTime == SysTime(Date(-4, 7, 6)));
2938 sysTime.add!"years"(8);
2939 assert(sysTime == SysTime(Date(4, 7, 6)));
2943 auto sysTime = SysTime(Date(-4, 7, 6));
2944 sysTime.add!"years"(8);
2945 assert(sysTime == SysTime(Date(4, 7, 6)));
2946 sysTime.add!"years"(-8);
2947 assert(sysTime == SysTime(Date(-4, 7, 6)));
2951 auto sysTime = SysTime(Date(-4, 2, 29));
2952 sysTime.add!"years"(5);
2953 assert(sysTime == SysTime(Date(1, 3, 1)));
2957 auto sysTime = SysTime(Date(4, 2, 29));
2958 sysTime.add!"years"(-5);
2959 assert(sysTime == SysTime(Date(-1, 3, 1)));
2963 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0));
2964 sysTime.add!"years"(-1);
2965 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0)));
2966 sysTime.add!"years"(1);
2967 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));
2971 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999));
2972 sysTime.add!"years"(-1);
2973 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)));
2974 sysTime.add!"years"(1);
2975 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));
2979 auto sysTime = SysTime(DateTime(0, 1, 1, 0, 0, 0));
2980 sysTime.add!"years"(1);
2981 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));
2982 sysTime.add!"years"(-1);
2983 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0)));
2987 auto sysTime = SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999));
2988 sysTime.add!"years"(1);
2989 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));
2990 sysTime.add!"years"(-1);
2991 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)));
2995 auto sysTime = SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329));
2996 sysTime.add!"years"(-5);
2997 assert(sysTime == SysTime(DateTime(-1, 7, 6, 14, 7, 1), usecs(54329)));
2998 sysTime.add!"years"(5);
2999 assert(sysTime == SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329)));
3003 auto sysTime = SysTime(DateTime(-4, 7, 6, 14, 7, 1), usecs(54329));
3004 sysTime.add!"years"(5);
3005 assert(sysTime == SysTime(DateTime(1, 7, 6, 14, 7, 1), usecs(54329)));
3006 sysTime.add!"years"(-5);
3007 assert(sysTime == SysTime(DateTime(-4, 7, 6, 14, 7, 1), usecs(54329)));
3011 auto sysTime = SysTime(DateTime(-4, 2, 29, 5, 5, 5), msecs(555));
3012 sysTime.add!"years"(5);
3013 assert(sysTime == SysTime(DateTime(1, 3, 1, 5, 5, 5), msecs(555)));
3017 auto sysTime = SysTime(DateTime(4, 2, 29, 5, 5, 5), msecs(555));
3018 sysTime.add!"years"(-5);
3019 assert(sysTime == SysTime(DateTime(-1, 3, 1, 5, 5, 5), msecs(555)));
3023 auto sysTime = SysTime(DateTime(4, 2, 29, 5, 5, 5), msecs(555));
3024 sysTime.add!"years"(-5).add!"years"(7);
3025 assert(sysTime == SysTime(DateTime(6, 3, 1, 5, 5, 5), msecs(555)));
3028 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
3029 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
3030 static assert(!__traits(compiles, cst.add!"years"(4)));
3031 static assert(!__traits(compiles, ist.add!"years"(4)));
3033 static void testScope(scope ref SysTime st) @safe
3035 auto result = st.add!"years"(42);
3039 // Test add!"years"() with AllowDayOverflow.no
3040 @safe unittest
3042 import core.time;
3043 // Test A.D.
3045 auto sysTime = SysTime(Date(1999, 7, 6));
3046 sysTime.add!"years"(7, AllowDayOverflow.no);
3047 assert(sysTime == SysTime(Date(2006, 7, 6)));
3048 sysTime.add!"years"(-9, AllowDayOverflow.no);
3049 assert(sysTime == SysTime(Date(1997, 7, 6)));
3053 auto sysTime = SysTime(Date(1999, 2, 28));
3054 sysTime.add!"years"(1, AllowDayOverflow.no);
3055 assert(sysTime == SysTime(Date(2000, 2, 28)));
3059 auto sysTime = SysTime(Date(2000, 2, 29));
3060 sysTime.add!"years"(-1, AllowDayOverflow.no);
3061 assert(sysTime == SysTime(Date(1999, 2, 28)));
3065 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 7, 3), msecs(234));
3066 sysTime.add!"years"(7, AllowDayOverflow.no);
3067 assert(sysTime == SysTime(DateTime(2006, 7, 6, 12, 7, 3), msecs(234)));
3068 sysTime.add!"years"(-9, AllowDayOverflow.no);
3069 assert(sysTime == SysTime(DateTime(1997, 7, 6, 12, 7, 3), msecs(234)));
3073 auto sysTime = SysTime(DateTime(1999, 2, 28, 0, 7, 2), usecs(1207));
3074 sysTime.add!"years"(1, AllowDayOverflow.no);
3075 assert(sysTime == SysTime(DateTime(2000, 2, 28, 0, 7, 2), usecs(1207)));
3079 auto sysTime = SysTime(DateTime(2000, 2, 29, 0, 7, 2), usecs(1207));
3080 sysTime.add!"years"(-1, AllowDayOverflow.no);
3081 assert(sysTime == SysTime(DateTime(1999, 2, 28, 0, 7, 2), usecs(1207)));
3084 // Test B.C.
3086 auto sysTime = SysTime(Date(-1999, 7, 6));
3087 sysTime.add!"years"(-7, AllowDayOverflow.no);
3088 assert(sysTime == SysTime(Date(-2006, 7, 6)));
3089 sysTime.add!"years"(9, AllowDayOverflow.no);
3090 assert(sysTime == SysTime(Date(-1997, 7, 6)));
3094 auto sysTime = SysTime(Date(-1999, 2, 28));
3095 sysTime.add!"years"(-1, AllowDayOverflow.no);
3096 assert(sysTime == SysTime(Date(-2000, 2, 28)));
3100 auto sysTime = SysTime(Date(-2000, 2, 29));
3101 sysTime.add!"years"(1, AllowDayOverflow.no);
3102 assert(sysTime == SysTime(Date(-1999, 2, 28)));
3106 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 7, 3), msecs(234));
3107 sysTime.add!"years"(-7, AllowDayOverflow.no);
3108 assert(sysTime == SysTime(DateTime(-2006, 7, 6, 12, 7, 3), msecs(234)));
3109 sysTime.add!"years"(9, AllowDayOverflow.no);
3110 assert(sysTime == SysTime(DateTime(-1997, 7, 6, 12, 7, 3), msecs(234)));
3114 auto sysTime = SysTime(DateTime(-1999, 2, 28, 3, 3, 3), hnsecs(3));
3115 sysTime.add!"years"(-1, AllowDayOverflow.no);
3116 assert(sysTime == SysTime(DateTime(-2000, 2, 28, 3, 3, 3), hnsecs(3)));
3120 auto sysTime = SysTime(DateTime(-2000, 2, 29, 3, 3, 3), hnsecs(3));
3121 sysTime.add!"years"(1, AllowDayOverflow.no);
3122 assert(sysTime == SysTime(DateTime(-1999, 2, 28, 3, 3, 3), hnsecs(3)));
3125 // Test Both
3127 auto sysTime = SysTime(Date(4, 7, 6));
3128 sysTime.add!"years"(-5, AllowDayOverflow.no);
3129 assert(sysTime == SysTime(Date(-1, 7, 6)));
3130 sysTime.add!"years"(5, AllowDayOverflow.no);
3131 assert(sysTime == SysTime(Date(4, 7, 6)));
3135 auto sysTime = SysTime(Date(-4, 7, 6));
3136 sysTime.add!"years"(5, AllowDayOverflow.no);
3137 assert(sysTime == SysTime(Date(1, 7, 6)));
3138 sysTime.add!"years"(-5, AllowDayOverflow.no);
3139 assert(sysTime == SysTime(Date(-4, 7, 6)));
3143 auto sysTime = SysTime(Date(4, 7, 6));
3144 sysTime.add!"years"(-8, AllowDayOverflow.no);
3145 assert(sysTime == SysTime(Date(-4, 7, 6)));
3146 sysTime.add!"years"(8, AllowDayOverflow.no);
3147 assert(sysTime == SysTime(Date(4, 7, 6)));
3151 auto sysTime = SysTime(Date(-4, 7, 6));
3152 sysTime.add!"years"(8, AllowDayOverflow.no);
3153 assert(sysTime == SysTime(Date(4, 7, 6)));
3154 sysTime.add!"years"(-8, AllowDayOverflow.no);
3155 assert(sysTime == SysTime(Date(-4, 7, 6)));
3159 auto sysTime = SysTime(Date(-4, 2, 29));
3160 sysTime.add!"years"(5, AllowDayOverflow.no);
3161 assert(sysTime == SysTime(Date(1, 2, 28)));
3165 auto sysTime = SysTime(Date(4, 2, 29));
3166 sysTime.add!"years"(-5, AllowDayOverflow.no);
3167 assert(sysTime == SysTime(Date(-1, 2, 28)));
3171 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0));
3172 sysTime.add!"years"(-1, AllowDayOverflow.no);
3173 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0)));
3174 sysTime.add!"years"(1, AllowDayOverflow.no);
3175 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));
3179 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999));
3180 sysTime.add!"years"(-1, AllowDayOverflow.no);
3181 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)));
3182 sysTime.add!"years"(1, AllowDayOverflow.no);
3183 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));
3187 auto sysTime = SysTime(DateTime(0, 1, 1, 0, 0, 0));
3188 sysTime.add!"years"(1, AllowDayOverflow.no);
3189 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));
3190 sysTime.add!"years"(-1, AllowDayOverflow.no);
3191 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0)));
3195 auto sysTime = SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999));
3196 sysTime.add!"years"(1, AllowDayOverflow.no);
3197 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));
3198 sysTime.add!"years"(-1, AllowDayOverflow.no);
3199 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)));
3203 auto sysTime = SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329));
3204 sysTime.add!"years"(-5);
3205 assert(sysTime == SysTime(DateTime(-1, 7, 6, 14, 7, 1), usecs(54329)));
3206 sysTime.add!"years"(5);
3207 assert(sysTime == SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329)));
3211 auto sysTime = SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329));
3212 sysTime.add!"years"(-5, AllowDayOverflow.no);
3213 assert(sysTime == SysTime(DateTime(-1, 7, 6, 14, 7, 1), usecs(54329)));
3214 sysTime.add!"years"(5, AllowDayOverflow.no);
3215 assert(sysTime == SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329)));
3219 auto sysTime = SysTime(DateTime(-4, 7, 6, 14, 7, 1), usecs(54329));
3220 sysTime.add!"years"(5, AllowDayOverflow.no);
3221 assert(sysTime == SysTime(DateTime(1, 7, 6, 14, 7, 1), usecs(54329)));
3222 sysTime.add!"years"(-5, AllowDayOverflow.no);
3223 assert(sysTime == SysTime(DateTime(-4, 7, 6, 14, 7, 1), usecs(54329)));
3227 auto sysTime = SysTime(DateTime(-4, 2, 29, 5, 5, 5), msecs(555));
3228 sysTime.add!"years"(5, AllowDayOverflow.no);
3229 assert(sysTime == SysTime(DateTime(1, 2, 28, 5, 5, 5), msecs(555)));
3233 auto sysTime = SysTime(DateTime(4, 2, 29, 5, 5, 5), msecs(555));
3234 sysTime.add!"years"(-5, AllowDayOverflow.no);
3235 assert(sysTime == SysTime(DateTime(-1, 2, 28, 5, 5, 5), msecs(555)));
3239 auto sysTime = SysTime(DateTime(4, 2, 29, 5, 5, 5), msecs(555));
3240 sysTime.add!"years"(-5, AllowDayOverflow.no).add!"years"(7, AllowDayOverflow.no);
3241 assert(sysTime == SysTime(DateTime(6, 2, 28, 5, 5, 5), msecs(555)));
3245 // Test add!"months"() with AllowDayOverflow.yes
3246 @safe unittest
3248 import core.time;
3249 // Test A.D.
3251 auto sysTime = SysTime(Date(1999, 7, 6));
3252 sysTime.add!"months"(3);
3253 assert(sysTime == SysTime(Date(1999, 10, 6)));
3254 sysTime.add!"months"(-4);
3255 assert(sysTime == SysTime(Date(1999, 6, 6)));
3259 auto sysTime = SysTime(Date(1999, 7, 6));
3260 sysTime.add!"months"(6);
3261 assert(sysTime == SysTime(Date(2000, 1, 6)));
3262 sysTime.add!"months"(-6);
3263 assert(sysTime == SysTime(Date(1999, 7, 6)));
3267 auto sysTime = SysTime(Date(1999, 7, 6));
3268 sysTime.add!"months"(27);
3269 assert(sysTime == SysTime(Date(2001, 10, 6)));
3270 sysTime.add!"months"(-28);
3271 assert(sysTime == SysTime(Date(1999, 6, 6)));
3275 auto sysTime = SysTime(Date(1999, 5, 31));
3276 sysTime.add!"months"(1);
3277 assert(sysTime == SysTime(Date(1999, 7, 1)));
3281 auto sysTime = SysTime(Date(1999, 5, 31));
3282 sysTime.add!"months"(-1);
3283 assert(sysTime == SysTime(Date(1999, 5, 1)));
3287 auto sysTime = SysTime(Date(1999, 2, 28));
3288 sysTime.add!"months"(12);
3289 assert(sysTime == SysTime(Date(2000, 2, 28)));
3293 auto sysTime = SysTime(Date(2000, 2, 29));
3294 sysTime.add!"months"(12);
3295 assert(sysTime == SysTime(Date(2001, 3, 1)));
3299 auto sysTime = SysTime(Date(1999, 7, 31));
3300 sysTime.add!"months"(1);
3301 assert(sysTime == SysTime(Date(1999, 8, 31)));
3302 sysTime.add!"months"(1);
3303 assert(sysTime == SysTime(Date(1999, 10, 1)));
3307 auto sysTime = SysTime(Date(1998, 8, 31));
3308 sysTime.add!"months"(13);
3309 assert(sysTime == SysTime(Date(1999, 10, 1)));
3310 sysTime.add!"months"(-13);
3311 assert(sysTime == SysTime(Date(1998, 9, 1)));
3315 auto sysTime = SysTime(Date(1997, 12, 31));
3316 sysTime.add!"months"(13);
3317 assert(sysTime == SysTime(Date(1999, 1, 31)));
3318 sysTime.add!"months"(-13);
3319 assert(sysTime == SysTime(Date(1997, 12, 31)));
3323 auto sysTime = SysTime(Date(1997, 12, 31));
3324 sysTime.add!"months"(14);
3325 assert(sysTime == SysTime(Date(1999, 3, 3)));
3326 sysTime.add!"months"(-14);
3327 assert(sysTime == SysTime(Date(1998, 1, 3)));
3331 auto sysTime = SysTime(Date(1998, 12, 31));
3332 sysTime.add!"months"(14);
3333 assert(sysTime == SysTime(Date(2000, 3, 2)));
3334 sysTime.add!"months"(-14);
3335 assert(sysTime == SysTime(Date(1999, 1, 2)));
3339 auto sysTime = SysTime(Date(1999, 12, 31));
3340 sysTime.add!"months"(14);
3341 assert(sysTime == SysTime(Date(2001, 3, 3)));
3342 sysTime.add!"months"(-14);
3343 assert(sysTime == SysTime(Date(2000, 1, 3)));
3347 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), usecs(5007));
3348 sysTime.add!"months"(3);
3349 assert(sysTime == SysTime(DateTime(1999, 10, 6, 12, 2, 7), usecs(5007)));
3350 sysTime.add!"months"(-4);
3351 assert(sysTime == SysTime(DateTime(1999, 6, 6, 12, 2, 7), usecs(5007)));
3355 auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), hnsecs(422202));
3356 sysTime.add!"months"(14);
3357 assert(sysTime == SysTime(DateTime(2000, 3, 2, 7, 7, 7), hnsecs(422202)));
3358 sysTime.add!"months"(-14);
3359 assert(sysTime == SysTime(DateTime(1999, 1, 2, 7, 7, 7), hnsecs(422202)));
3363 auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), hnsecs(422202));
3364 sysTime.add!"months"(14);
3365 assert(sysTime == SysTime(DateTime(2001, 3, 3, 7, 7, 7), hnsecs(422202)));
3366 sysTime.add!"months"(-14);
3367 assert(sysTime == SysTime(DateTime(2000, 1, 3, 7, 7, 7), hnsecs(422202)));
3370 // Test B.C.
3372 auto sysTime = SysTime(Date(-1999, 7, 6));
3373 sysTime.add!"months"(3);
3374 assert(sysTime == SysTime(Date(-1999, 10, 6)));
3375 sysTime.add!"months"(-4);
3376 assert(sysTime == SysTime(Date(-1999, 6, 6)));
3380 auto sysTime = SysTime(Date(-1999, 7, 6));
3381 sysTime.add!"months"(6);
3382 assert(sysTime == SysTime(Date(-1998, 1, 6)));
3383 sysTime.add!"months"(-6);
3384 assert(sysTime == SysTime(Date(-1999, 7, 6)));
3388 auto sysTime = SysTime(Date(-1999, 7, 6));
3389 sysTime.add!"months"(-27);
3390 assert(sysTime == SysTime(Date(-2001, 4, 6)));
3391 sysTime.add!"months"(28);
3392 assert(sysTime == SysTime(Date(-1999, 8, 6)));
3396 auto sysTime = SysTime(Date(-1999, 5, 31));
3397 sysTime.add!"months"(1);
3398 assert(sysTime == SysTime(Date(-1999, 7, 1)));
3402 auto sysTime = SysTime(Date(-1999, 5, 31));
3403 sysTime.add!"months"(-1);
3404 assert(sysTime == SysTime(Date(-1999, 5, 1)));
3408 auto sysTime = SysTime(Date(-1999, 2, 28));
3409 sysTime.add!"months"(-12);
3410 assert(sysTime == SysTime(Date(-2000, 2, 28)));
3414 auto sysTime = SysTime(Date(-2000, 2, 29));
3415 sysTime.add!"months"(-12);
3416 assert(sysTime == SysTime(Date(-2001, 3, 1)));
3420 auto sysTime = SysTime(Date(-1999, 7, 31));
3421 sysTime.add!"months"(1);
3422 assert(sysTime == SysTime(Date(-1999, 8, 31)));
3423 sysTime.add!"months"(1);
3424 assert(sysTime == SysTime(Date(-1999, 10, 1)));
3428 auto sysTime = SysTime(Date(-1998, 8, 31));
3429 sysTime.add!"months"(13);
3430 assert(sysTime == SysTime(Date(-1997, 10, 1)));
3431 sysTime.add!"months"(-13);
3432 assert(sysTime == SysTime(Date(-1998, 9, 1)));
3436 auto sysTime = SysTime(Date(-1997, 12, 31));
3437 sysTime.add!"months"(13);
3438 assert(sysTime == SysTime(Date(-1995, 1, 31)));
3439 sysTime.add!"months"(-13);
3440 assert(sysTime == SysTime(Date(-1997, 12, 31)));
3444 auto sysTime = SysTime(Date(-1997, 12, 31));
3445 sysTime.add!"months"(14);
3446 assert(sysTime == SysTime(Date(-1995, 3, 3)));
3447 sysTime.add!"months"(-14);
3448 assert(sysTime == SysTime(Date(-1996, 1, 3)));
3452 auto sysTime = SysTime(Date(-2002, 12, 31));
3453 sysTime.add!"months"(14);
3454 assert(sysTime == SysTime(Date(-2000, 3, 2)));
3455 sysTime.add!"months"(-14);
3456 assert(sysTime == SysTime(Date(-2001, 1, 2)));
3460 auto sysTime = SysTime(Date(-2001, 12, 31));
3461 sysTime.add!"months"(14);
3462 assert(sysTime == SysTime(Date(-1999, 3, 3)));
3463 sysTime.add!"months"(-14);
3464 assert(sysTime == SysTime(Date(-2000, 1, 3)));
3468 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), usecs(5007));
3469 sysTime.add!"months"(3);
3470 assert(sysTime == SysTime(DateTime(-1999, 10, 6, 12, 2, 7), usecs(5007)));
3471 sysTime.add!"months"(-4);
3472 assert(sysTime == SysTime(DateTime(-1999, 6, 6, 12, 2, 7), usecs(5007)));
3476 auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), hnsecs(422202));
3477 sysTime.add!"months"(14);
3478 assert(sysTime == SysTime(DateTime(-2000, 3, 2, 7, 7, 7), hnsecs(422202)));
3479 sysTime.add!"months"(-14);
3480 assert(sysTime == SysTime(DateTime(-2001, 1, 2, 7, 7, 7), hnsecs(422202)));
3484 auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), hnsecs(422202));
3485 sysTime.add!"months"(14);
3486 assert(sysTime == SysTime(DateTime(-1999, 3, 3, 7, 7, 7), hnsecs(422202)));
3487 sysTime.add!"months"(-14);
3488 assert(sysTime == SysTime(DateTime(-2000, 1, 3, 7, 7, 7), hnsecs(422202)));
3491 // Test Both
3493 auto sysTime = SysTime(Date(1, 1, 1));
3494 sysTime.add!"months"(-1);
3495 assert(sysTime == SysTime(Date(0, 12, 1)));
3496 sysTime.add!"months"(1);
3497 assert(sysTime == SysTime(Date(1, 1, 1)));
3501 auto sysTime = SysTime(Date(4, 1, 1));
3502 sysTime.add!"months"(-48);
3503 assert(sysTime == SysTime(Date(0, 1, 1)));
3504 sysTime.add!"months"(48);
3505 assert(sysTime == SysTime(Date(4, 1, 1)));
3509 auto sysTime = SysTime(Date(4, 3, 31));
3510 sysTime.add!"months"(-49);
3511 assert(sysTime == SysTime(Date(0, 3, 2)));
3512 sysTime.add!"months"(49);
3513 assert(sysTime == SysTime(Date(4, 4, 2)));
3517 auto sysTime = SysTime(Date(4, 3, 31));
3518 sysTime.add!"months"(-85);
3519 assert(sysTime == SysTime(Date(-3, 3, 3)));
3520 sysTime.add!"months"(85);
3521 assert(sysTime == SysTime(Date(4, 4, 3)));
3525 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0));
3526 sysTime.add!"months"(-1);
3527 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0)));
3528 sysTime.add!"months"(1);
3529 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));
3533 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999));
3534 sysTime.add!"months"(-1);
3535 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)));
3536 sysTime.add!"months"(1);
3537 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));
3541 auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0));
3542 sysTime.add!"months"(1);
3543 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));
3544 sysTime.add!"months"(-1);
3545 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0)));
3549 auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999));
3550 sysTime.add!"months"(1);
3551 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));
3552 sysTime.add!"months"(-1);
3553 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)));
3557 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17));
3558 sysTime.add!"months"(-1);
3559 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 7, 9), hnsecs(17)));
3560 sysTime.add!"months"(1);
3561 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17)));
3565 auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), msecs(9));
3566 sysTime.add!"months"(-85);
3567 assert(sysTime == SysTime(DateTime(-3, 3, 3, 12, 11, 10), msecs(9)));
3568 sysTime.add!"months"(85);
3569 assert(sysTime == SysTime(DateTime(4, 4, 3, 12, 11, 10), msecs(9)));
3573 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9));
3574 sysTime.add!"months"(85);
3575 assert(sysTime == SysTime(DateTime(4, 5, 1, 12, 11, 10), msecs(9)));
3576 sysTime.add!"months"(-85);
3577 assert(sysTime == SysTime(DateTime(-3, 4, 1, 12, 11, 10), msecs(9)));
3581 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9));
3582 sysTime.add!"months"(85).add!"months"(-83);
3583 assert(sysTime == SysTime(DateTime(-3, 6, 1, 12, 11, 10), msecs(9)));
3586 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
3587 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
3588 static assert(!__traits(compiles, cst.add!"months"(4)));
3589 static assert(!__traits(compiles, ist.add!"months"(4)));
3591 static void testScope(scope ref SysTime st) @safe
3593 auto result = st.add!"months"(42);
3597 // Test add!"months"() with AllowDayOverflow.no
3598 @safe unittest
3600 import core.time;
3601 // Test A.D.
3603 auto sysTime = SysTime(Date(1999, 7, 6));
3604 sysTime.add!"months"(3, AllowDayOverflow.no);
3605 assert(sysTime == SysTime(Date(1999, 10, 6)));
3606 sysTime.add!"months"(-4, AllowDayOverflow.no);
3607 assert(sysTime == SysTime(Date(1999, 6, 6)));
3611 auto sysTime = SysTime(Date(1999, 7, 6));
3612 sysTime.add!"months"(6, AllowDayOverflow.no);
3613 assert(sysTime == SysTime(Date(2000, 1, 6)));
3614 sysTime.add!"months"(-6, AllowDayOverflow.no);
3615 assert(sysTime == SysTime(Date(1999, 7, 6)));
3619 auto sysTime = SysTime(Date(1999, 7, 6));
3620 sysTime.add!"months"(27, AllowDayOverflow.no);
3621 assert(sysTime == SysTime(Date(2001, 10, 6)));
3622 sysTime.add!"months"(-28, AllowDayOverflow.no);
3623 assert(sysTime == SysTime(Date(1999, 6, 6)));
3627 auto sysTime = SysTime(Date(1999, 5, 31));
3628 sysTime.add!"months"(1, AllowDayOverflow.no);
3629 assert(sysTime == SysTime(Date(1999, 6, 30)));
3633 auto sysTime = SysTime(Date(1999, 5, 31));
3634 sysTime.add!"months"(-1, AllowDayOverflow.no);
3635 assert(sysTime == SysTime(Date(1999, 4, 30)));
3639 auto sysTime = SysTime(Date(1999, 2, 28));
3640 sysTime.add!"months"(12, AllowDayOverflow.no);
3641 assert(sysTime == SysTime(Date(2000, 2, 28)));
3645 auto sysTime = SysTime(Date(2000, 2, 29));
3646 sysTime.add!"months"(12, AllowDayOverflow.no);
3647 assert(sysTime == SysTime(Date(2001, 2, 28)));
3651 auto sysTime = SysTime(Date(1999, 7, 31));
3652 sysTime.add!"months"(1, AllowDayOverflow.no);
3653 assert(sysTime == SysTime(Date(1999, 8, 31)));
3654 sysTime.add!"months"(1, AllowDayOverflow.no);
3655 assert(sysTime == SysTime(Date(1999, 9, 30)));
3659 auto sysTime = SysTime(Date(1998, 8, 31));
3660 sysTime.add!"months"(13, AllowDayOverflow.no);
3661 assert(sysTime == SysTime(Date(1999, 9, 30)));
3662 sysTime.add!"months"(-13, AllowDayOverflow.no);
3663 assert(sysTime == SysTime(Date(1998, 8, 30)));
3667 auto sysTime = SysTime(Date(1997, 12, 31));
3668 sysTime.add!"months"(13, AllowDayOverflow.no);
3669 assert(sysTime == SysTime(Date(1999, 1, 31)));
3670 sysTime.add!"months"(-13, AllowDayOverflow.no);
3671 assert(sysTime == SysTime(Date(1997, 12, 31)));
3675 auto sysTime = SysTime(Date(1997, 12, 31));
3676 sysTime.add!"months"(14, AllowDayOverflow.no);
3677 assert(sysTime == SysTime(Date(1999, 2, 28)));
3678 sysTime.add!"months"(-14, AllowDayOverflow.no);
3679 assert(sysTime == SysTime(Date(1997, 12, 28)));
3683 auto sysTime = SysTime(Date(1998, 12, 31));
3684 sysTime.add!"months"(14, AllowDayOverflow.no);
3685 assert(sysTime == SysTime(Date(2000, 2, 29)));
3686 sysTime.add!"months"(-14, AllowDayOverflow.no);
3687 assert(sysTime == SysTime(Date(1998, 12, 29)));
3691 auto sysTime = SysTime(Date(1999, 12, 31));
3692 sysTime.add!"months"(14, AllowDayOverflow.no);
3693 assert(sysTime == SysTime(Date(2001, 2, 28)));
3694 sysTime.add!"months"(-14, AllowDayOverflow.no);
3695 assert(sysTime == SysTime(Date(1999, 12, 28)));
3699 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), usecs(5007));
3700 sysTime.add!"months"(3, AllowDayOverflow.no);
3701 assert(sysTime == SysTime(DateTime(1999, 10, 6, 12, 2, 7), usecs(5007)));
3702 sysTime.add!"months"(-4, AllowDayOverflow.no);
3703 assert(sysTime == SysTime(DateTime(1999, 6, 6, 12, 2, 7), usecs(5007)));
3707 auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), hnsecs(422202));
3708 sysTime.add!"months"(14, AllowDayOverflow.no);
3709 assert(sysTime == SysTime(DateTime(2000, 2, 29, 7, 7, 7), hnsecs(422202)));
3710 sysTime.add!"months"(-14, AllowDayOverflow.no);
3711 assert(sysTime == SysTime(DateTime(1998, 12, 29, 7, 7, 7), hnsecs(422202)));
3715 auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), hnsecs(422202));
3716 sysTime.add!"months"(14, AllowDayOverflow.no);
3717 assert(sysTime == SysTime(DateTime(2001, 2, 28, 7, 7, 7), hnsecs(422202)));
3718 sysTime.add!"months"(-14, AllowDayOverflow.no);
3719 assert(sysTime == SysTime(DateTime(1999, 12, 28, 7, 7, 7), hnsecs(422202)));
3722 // Test B.C.
3724 auto sysTime = SysTime(Date(-1999, 7, 6));
3725 sysTime.add!"months"(3, AllowDayOverflow.no);
3726 assert(sysTime == SysTime(Date(-1999, 10, 6)));
3727 sysTime.add!"months"(-4, AllowDayOverflow.no);
3728 assert(sysTime == SysTime(Date(-1999, 6, 6)));
3732 auto sysTime = SysTime(Date(-1999, 7, 6));
3733 sysTime.add!"months"(6, AllowDayOverflow.no);
3734 assert(sysTime == SysTime(Date(-1998, 1, 6)));
3735 sysTime.add!"months"(-6, AllowDayOverflow.no);
3736 assert(sysTime == SysTime(Date(-1999, 7, 6)));
3740 auto sysTime = SysTime(Date(-1999, 7, 6));
3741 sysTime.add!"months"(-27, AllowDayOverflow.no);
3742 assert(sysTime == SysTime(Date(-2001, 4, 6)));
3743 sysTime.add!"months"(28, AllowDayOverflow.no);
3744 assert(sysTime == SysTime(Date(-1999, 8, 6)));
3748 auto sysTime = SysTime(Date(-1999, 5, 31));
3749 sysTime.add!"months"(1, AllowDayOverflow.no);
3750 assert(sysTime == SysTime(Date(-1999, 6, 30)));
3754 auto sysTime = SysTime(Date(-1999, 5, 31));
3755 sysTime.add!"months"(-1, AllowDayOverflow.no);
3756 assert(sysTime == SysTime(Date(-1999, 4, 30)));
3760 auto sysTime = SysTime(Date(-1999, 2, 28));
3761 sysTime.add!"months"(-12, AllowDayOverflow.no);
3762 assert(sysTime == SysTime(Date(-2000, 2, 28)));
3766 auto sysTime = SysTime(Date(-2000, 2, 29));
3767 sysTime.add!"months"(-12, AllowDayOverflow.no);
3768 assert(sysTime == SysTime(Date(-2001, 2, 28)));
3772 auto sysTime = SysTime(Date(-1999, 7, 31));
3773 sysTime.add!"months"(1, AllowDayOverflow.no);
3774 assert(sysTime == SysTime(Date(-1999, 8, 31)));
3775 sysTime.add!"months"(1, AllowDayOverflow.no);
3776 assert(sysTime == SysTime(Date(-1999, 9, 30)));
3780 auto sysTime = SysTime(Date(-1998, 8, 31));
3781 sysTime.add!"months"(13, AllowDayOverflow.no);
3782 assert(sysTime == SysTime(Date(-1997, 9, 30)));
3783 sysTime.add!"months"(-13, AllowDayOverflow.no);
3784 assert(sysTime == SysTime(Date(-1998, 8, 30)));
3788 auto sysTime = SysTime(Date(-1997, 12, 31));
3789 sysTime.add!"months"(13, AllowDayOverflow.no);
3790 assert(sysTime == SysTime(Date(-1995, 1, 31)));
3791 sysTime.add!"months"(-13, AllowDayOverflow.no);
3792 assert(sysTime == SysTime(Date(-1997, 12, 31)));
3796 auto sysTime = SysTime(Date(-1997, 12, 31));
3797 sysTime.add!"months"(14, AllowDayOverflow.no);
3798 assert(sysTime == SysTime(Date(-1995, 2, 28)));
3799 sysTime.add!"months"(-14, AllowDayOverflow.no);
3800 assert(sysTime == SysTime(Date(-1997, 12, 28)));
3804 auto sysTime = SysTime(Date(-2002, 12, 31));
3805 sysTime.add!"months"(14, AllowDayOverflow.no);
3806 assert(sysTime == SysTime(Date(-2000, 2, 29)));
3807 sysTime.add!"months"(-14, AllowDayOverflow.no);
3808 assert(sysTime == SysTime(Date(-2002, 12, 29)));
3812 auto sysTime = SysTime(Date(-2001, 12, 31));
3813 sysTime.add!"months"(14, AllowDayOverflow.no);
3814 assert(sysTime == SysTime(Date(-1999, 2, 28)));
3815 sysTime.add!"months"(-14, AllowDayOverflow.no);
3816 assert(sysTime == SysTime(Date(-2001, 12, 28)));
3820 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), usecs(5007));
3821 sysTime.add!"months"(3, AllowDayOverflow.no);
3822 assert(sysTime == SysTime(DateTime(-1999, 10, 6, 12, 2, 7), usecs(5007)));
3823 sysTime.add!"months"(-4, AllowDayOverflow.no);
3824 assert(sysTime == SysTime(DateTime(-1999, 6, 6, 12, 2, 7), usecs(5007)));
3828 auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), hnsecs(422202));
3829 sysTime.add!"months"(14, AllowDayOverflow.no);
3830 assert(sysTime == SysTime(DateTime(-2000, 2, 29, 7, 7, 7), hnsecs(422202)));
3831 sysTime.add!"months"(-14, AllowDayOverflow.no);
3832 assert(sysTime == SysTime(DateTime(-2002, 12, 29, 7, 7, 7), hnsecs(422202)));
3836 auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), hnsecs(422202));
3837 sysTime.add!"months"(14, AllowDayOverflow.no);
3838 assert(sysTime == SysTime(DateTime(-1999, 2, 28, 7, 7, 7), hnsecs(422202)));
3839 sysTime.add!"months"(-14, AllowDayOverflow.no);
3840 assert(sysTime == SysTime(DateTime(-2001, 12, 28, 7, 7, 7), hnsecs(422202)));
3843 // Test Both
3845 auto sysTime = SysTime(Date(1, 1, 1));
3846 sysTime.add!"months"(-1, AllowDayOverflow.no);
3847 assert(sysTime == SysTime(Date(0, 12, 1)));
3848 sysTime.add!"months"(1, AllowDayOverflow.no);
3849 assert(sysTime == SysTime(Date(1, 1, 1)));
3853 auto sysTime = SysTime(Date(4, 1, 1));
3854 sysTime.add!"months"(-48, AllowDayOverflow.no);
3855 assert(sysTime == SysTime(Date(0, 1, 1)));
3856 sysTime.add!"months"(48, AllowDayOverflow.no);
3857 assert(sysTime == SysTime(Date(4, 1, 1)));
3861 auto sysTime = SysTime(Date(4, 3, 31));
3862 sysTime.add!"months"(-49, AllowDayOverflow.no);
3863 assert(sysTime == SysTime(Date(0, 2, 29)));
3864 sysTime.add!"months"(49, AllowDayOverflow.no);
3865 assert(sysTime == SysTime(Date(4, 3, 29)));
3869 auto sysTime = SysTime(Date(4, 3, 31));
3870 sysTime.add!"months"(-85, AllowDayOverflow.no);
3871 assert(sysTime == SysTime(Date(-3, 2, 28)));
3872 sysTime.add!"months"(85, AllowDayOverflow.no);
3873 assert(sysTime == SysTime(Date(4, 3, 28)));
3877 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0));
3878 sysTime.add!"months"(-1, AllowDayOverflow.no);
3879 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0)));
3880 sysTime.add!"months"(1, AllowDayOverflow.no);
3881 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));
3885 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999));
3886 sysTime.add!"months"(-1, AllowDayOverflow.no);
3887 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)));
3888 sysTime.add!"months"(1, AllowDayOverflow.no);
3889 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));
3893 auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0));
3894 sysTime.add!"months"(1, AllowDayOverflow.no);
3895 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));
3896 sysTime.add!"months"(-1, AllowDayOverflow.no);
3897 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0)));
3901 auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999));
3902 sysTime.add!"months"(1, AllowDayOverflow.no);
3903 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));
3904 sysTime.add!"months"(-1, AllowDayOverflow.no);
3905 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)));
3909 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17));
3910 sysTime.add!"months"(-1, AllowDayOverflow.no);
3911 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 7, 9), hnsecs(17)));
3912 sysTime.add!"months"(1, AllowDayOverflow.no);
3913 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17)));
3917 auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), msecs(9));
3918 sysTime.add!"months"(-85, AllowDayOverflow.no);
3919 assert(sysTime == SysTime(DateTime(-3, 2, 28, 12, 11, 10), msecs(9)));
3920 sysTime.add!"months"(85, AllowDayOverflow.no);
3921 assert(sysTime == SysTime(DateTime(4, 3, 28, 12, 11, 10), msecs(9)));
3925 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9));
3926 sysTime.add!"months"(85, AllowDayOverflow.no);
3927 assert(sysTime == SysTime(DateTime(4, 4, 30, 12, 11, 10), msecs(9)));
3928 sysTime.add!"months"(-85, AllowDayOverflow.no);
3929 assert(sysTime == SysTime(DateTime(-3, 3, 30, 12, 11, 10), msecs(9)));
3933 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9));
3934 sysTime.add!"months"(85, AllowDayOverflow.no).add!"months"(-83, AllowDayOverflow.no);
3935 assert(sysTime == SysTime(DateTime(-3, 5, 30, 12, 11, 10), msecs(9)));
3941 Adds the given number of years or months to this $(LREF SysTime). A
3942 negative number will subtract.
3944 The difference between rolling and adding is that rolling does not
3945 affect larger units. Rolling a $(LREF SysTime) 12 months
3946 gets the exact same $(LREF SysTime). However, the days can still be
3947 affected due to the differing number of days in each month.
3949 Because there are no units larger than years, there is no difference
3950 between adding and rolling years.
3952 Params:
3953 units = The type of units to add ("years" or "months").
3954 value = The number of months or years to add to this
3955 $(LREF SysTime).
3956 allowOverflow = Whether the days should be allowed to overflow,
3957 causing the month to increment.
3959 ref SysTime roll(string units)
3960 (long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe nothrow scope
3961 if (units == "years")
3963 return add!"years"(value, allowOverflow);
3967 @safe unittest
3969 import std.datetime.date : AllowDayOverflow, DateTime;
3971 auto st1 = SysTime(DateTime(2010, 1, 1, 12, 33, 33));
3972 st1.roll!"months"(1);
3973 assert(st1 == SysTime(DateTime(2010, 2, 1, 12, 33, 33)));
3975 auto st2 = SysTime(DateTime(2010, 1, 1, 12, 33, 33));
3976 st2.roll!"months"(-1);
3977 assert(st2 == SysTime(DateTime(2010, 12, 1, 12, 33, 33)));
3979 auto st3 = SysTime(DateTime(1999, 1, 29, 12, 33, 33));
3980 st3.roll!"months"(1);
3981 assert(st3 == SysTime(DateTime(1999, 3, 1, 12, 33, 33)));
3983 auto st4 = SysTime(DateTime(1999, 1, 29, 12, 33, 33));
3984 st4.roll!"months"(1, AllowDayOverflow.no);
3985 assert(st4 == SysTime(DateTime(1999, 2, 28, 12, 33, 33)));
3987 auto st5 = SysTime(DateTime(2000, 2, 29, 12, 30, 33));
3988 st5.roll!"years"(1);
3989 assert(st5 == SysTime(DateTime(2001, 3, 1, 12, 30, 33)));
3991 auto st6 = SysTime(DateTime(2000, 2, 29, 12, 30, 33));
3992 st6.roll!"years"(1, AllowDayOverflow.no);
3993 assert(st6 == SysTime(DateTime(2001, 2, 28, 12, 30, 33)));
3996 @safe unittest
3998 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
3999 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
4000 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
4001 st.roll!"years"(4);
4002 static assert(!__traits(compiles, cst.roll!"years"(4)));
4003 static assert(!__traits(compiles, ist.roll!"years"(4)));
4005 static void testScope(scope ref SysTime st) @safe
4007 auto result = st.roll!"years"(42);
4012 // Shares documentation with "years" overload.
4013 ref SysTime roll(string units)
4014 (long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe nothrow scope
4015 if (units == "months")
4017 auto hnsecs = adjTime;
4018 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
4020 if (hnsecs < 0)
4022 hnsecs += convert!("hours", "hnsecs")(24);
4023 --days;
4026 auto date = Date(cast(int) days);
4027 date.roll!"months"(value, allowOverflow);
4028 days = date.dayOfGregorianCal - 1;
4030 if (days < 0)
4032 hnsecs -= convert!("hours", "hnsecs")(24);
4033 ++days;
4036 immutable newDaysHNSecs = convert!("days", "hnsecs")(days);
4037 adjTime = newDaysHNSecs + hnsecs;
4038 return this;
4041 // Test roll!"months"() with AllowDayOverflow.yes
4042 @safe unittest
4044 import core.time;
4045 // Test A.D.
4047 auto sysTime = SysTime(Date(1999, 7, 6));
4048 sysTime.roll!"months"(3);
4049 assert(sysTime == SysTime(Date(1999, 10, 6)));
4050 sysTime.roll!"months"(-4);
4051 assert(sysTime == SysTime(Date(1999, 6, 6)));
4055 auto sysTime = SysTime(Date(1999, 7, 6));
4056 sysTime.roll!"months"(6);
4057 assert(sysTime == SysTime(Date(1999, 1, 6)));
4058 sysTime.roll!"months"(-6);
4059 assert(sysTime == SysTime(Date(1999, 7, 6)));
4063 auto sysTime = SysTime(Date(1999, 7, 6));
4064 sysTime.roll!"months"(27);
4065 assert(sysTime == SysTime(Date(1999, 10, 6)));
4066 sysTime.roll!"months"(-28);
4067 assert(sysTime == SysTime(Date(1999, 6, 6)));
4071 auto sysTime = SysTime(Date(1999, 5, 31));
4072 sysTime.roll!"months"(1);
4073 assert(sysTime == SysTime(Date(1999, 7, 1)));
4077 auto sysTime = SysTime(Date(1999, 5, 31));
4078 sysTime.roll!"months"(-1);
4079 assert(sysTime == SysTime(Date(1999, 5, 1)));
4083 auto sysTime = SysTime(Date(1999, 2, 28));
4084 sysTime.roll!"months"(12);
4085 assert(sysTime == SysTime(Date(1999, 2, 28)));
4089 auto sysTime = SysTime(Date(2000, 2, 29));
4090 sysTime.roll!"months"(12);
4091 assert(sysTime == SysTime(Date(2000, 2, 29)));
4095 auto sysTime = SysTime(Date(1999, 7, 31));
4096 sysTime.roll!"months"(1);
4097 assert(sysTime == SysTime(Date(1999, 8, 31)));
4098 sysTime.roll!"months"(1);
4099 assert(sysTime == SysTime(Date(1999, 10, 1)));
4103 auto sysTime = SysTime(Date(1998, 8, 31));
4104 sysTime.roll!"months"(13);
4105 assert(sysTime == SysTime(Date(1998, 10, 1)));
4106 sysTime.roll!"months"(-13);
4107 assert(sysTime == SysTime(Date(1998, 9, 1)));
4111 auto sysTime = SysTime(Date(1997, 12, 31));
4112 sysTime.roll!"months"(13);
4113 assert(sysTime == SysTime(Date(1997, 1, 31)));
4114 sysTime.roll!"months"(-13);
4115 assert(sysTime == SysTime(Date(1997, 12, 31)));
4119 auto sysTime = SysTime(Date(1997, 12, 31));
4120 sysTime.roll!"months"(14);
4121 assert(sysTime == SysTime(Date(1997, 3, 3)));
4122 sysTime.roll!"months"(-14);
4123 assert(sysTime == SysTime(Date(1997, 1, 3)));
4127 auto sysTime = SysTime(Date(1998, 12, 31));
4128 sysTime.roll!"months"(14);
4129 assert(sysTime == SysTime(Date(1998, 3, 3)));
4130 sysTime.roll!"months"(-14);
4131 assert(sysTime == SysTime(Date(1998, 1, 3)));
4135 auto sysTime = SysTime(Date(1999, 12, 31));
4136 sysTime.roll!"months"(14);
4137 assert(sysTime == SysTime(Date(1999, 3, 3)));
4138 sysTime.roll!"months"(-14);
4139 assert(sysTime == SysTime(Date(1999, 1, 3)));
4143 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), usecs(5007));
4144 sysTime.roll!"months"(3);
4145 assert(sysTime == SysTime(DateTime(1999, 10, 6, 12, 2, 7), usecs(5007)));
4146 sysTime.roll!"months"(-4);
4147 assert(sysTime == SysTime(DateTime(1999, 6, 6, 12, 2, 7), usecs(5007)));
4151 auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), hnsecs(422202));
4152 sysTime.roll!"months"(14);
4153 assert(sysTime == SysTime(DateTime(1998, 3, 3, 7, 7, 7), hnsecs(422202)));
4154 sysTime.roll!"months"(-14);
4155 assert(sysTime == SysTime(DateTime(1998, 1, 3, 7, 7, 7), hnsecs(422202)));
4159 auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), hnsecs(422202));
4160 sysTime.roll!"months"(14);
4161 assert(sysTime == SysTime(DateTime(1999, 3, 3, 7, 7, 7), hnsecs(422202)));
4162 sysTime.roll!"months"(-14);
4163 assert(sysTime == SysTime(DateTime(1999, 1, 3, 7, 7, 7), hnsecs(422202)));
4166 // Test B.C.
4168 auto sysTime = SysTime(Date(-1999, 7, 6));
4169 sysTime.roll!"months"(3);
4170 assert(sysTime == SysTime(Date(-1999, 10, 6)));
4171 sysTime.roll!"months"(-4);
4172 assert(sysTime == SysTime(Date(-1999, 6, 6)));
4176 auto sysTime = SysTime(Date(-1999, 7, 6));
4177 sysTime.roll!"months"(6);
4178 assert(sysTime == SysTime(Date(-1999, 1, 6)));
4179 sysTime.roll!"months"(-6);
4180 assert(sysTime == SysTime(Date(-1999, 7, 6)));
4184 auto sysTime = SysTime(Date(-1999, 7, 6));
4185 sysTime.roll!"months"(-27);
4186 assert(sysTime == SysTime(Date(-1999, 4, 6)));
4187 sysTime.roll!"months"(28);
4188 assert(sysTime == SysTime(Date(-1999, 8, 6)));
4192 auto sysTime = SysTime(Date(-1999, 5, 31));
4193 sysTime.roll!"months"(1);
4194 assert(sysTime == SysTime(Date(-1999, 7, 1)));
4198 auto sysTime = SysTime(Date(-1999, 5, 31));
4199 sysTime.roll!"months"(-1);
4200 assert(sysTime == SysTime(Date(-1999, 5, 1)));
4204 auto sysTime = SysTime(Date(-1999, 2, 28));
4205 sysTime.roll!"months"(-12);
4206 assert(sysTime == SysTime(Date(-1999, 2, 28)));
4210 auto sysTime = SysTime(Date(-2000, 2, 29));
4211 sysTime.roll!"months"(-12);
4212 assert(sysTime == SysTime(Date(-2000, 2, 29)));
4216 auto sysTime = SysTime(Date(-1999, 7, 31));
4217 sysTime.roll!"months"(1);
4218 assert(sysTime == SysTime(Date(-1999, 8, 31)));
4219 sysTime.roll!"months"(1);
4220 assert(sysTime == SysTime(Date(-1999, 10, 1)));
4224 auto sysTime = SysTime(Date(-1998, 8, 31));
4225 sysTime.roll!"months"(13);
4226 assert(sysTime == SysTime(Date(-1998, 10, 1)));
4227 sysTime.roll!"months"(-13);
4228 assert(sysTime == SysTime(Date(-1998, 9, 1)));
4232 auto sysTime = SysTime(Date(-1997, 12, 31));
4233 sysTime.roll!"months"(13);
4234 assert(sysTime == SysTime(Date(-1997, 1, 31)));
4235 sysTime.roll!"months"(-13);
4236 assert(sysTime == SysTime(Date(-1997, 12, 31)));
4240 auto sysTime = SysTime(Date(-1997, 12, 31));
4241 sysTime.roll!"months"(14);
4242 assert(sysTime == SysTime(Date(-1997, 3, 3)));
4243 sysTime.roll!"months"(-14);
4244 assert(sysTime == SysTime(Date(-1997, 1, 3)));
4248 auto sysTime = SysTime(Date(-2002, 12, 31));
4249 sysTime.roll!"months"(14);
4250 assert(sysTime == SysTime(Date(-2002, 3, 3)));
4251 sysTime.roll!"months"(-14);
4252 assert(sysTime == SysTime(Date(-2002, 1, 3)));
4256 auto sysTime = SysTime(Date(-2001, 12, 31));
4257 sysTime.roll!"months"(14);
4258 assert(sysTime == SysTime(Date(-2001, 3, 3)));
4259 sysTime.roll!"months"(-14);
4260 assert(sysTime == SysTime(Date(-2001, 1, 3)));
4264 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0));
4265 sysTime.roll!"months"(-1);
4266 assert(sysTime == SysTime(DateTime(1, 12, 1, 0, 0, 0)));
4267 sysTime.roll!"months"(1);
4268 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));
4272 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999));
4273 sysTime.roll!"months"(-1);
4274 assert(sysTime == SysTime(DateTime(1, 12, 1, 23, 59, 59), hnsecs(9_999_999)));
4275 sysTime.roll!"months"(1);
4276 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));
4280 auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0));
4281 sysTime.roll!"months"(1);
4282 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0)));
4283 sysTime.roll!"months"(-1);
4284 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0)));
4288 auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999));
4289 sysTime.roll!"months"(1);
4290 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)));
4291 sysTime.roll!"months"(-1);
4292 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)));
4296 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), hnsecs(5007));
4297 sysTime.roll!"months"(3);
4298 assert(sysTime == SysTime(DateTime(-1999, 10, 6, 12, 2, 7), hnsecs(5007)));
4299 sysTime.roll!"months"(-4);
4300 assert(sysTime == SysTime(DateTime(-1999, 6, 6, 12, 2, 7), hnsecs(5007)));
4304 auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), hnsecs(422202));
4305 sysTime.roll!"months"(14);
4306 assert(sysTime == SysTime(DateTime(-2002, 3, 3, 7, 7, 7), hnsecs(422202)));
4307 sysTime.roll!"months"(-14);
4308 assert(sysTime == SysTime(DateTime(-2002, 1, 3, 7, 7, 7), hnsecs(422202)));
4312 auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), hnsecs(422202));
4313 sysTime.roll!"months"(14);
4314 assert(sysTime == SysTime(DateTime(-2001, 3, 3, 7, 7, 7), hnsecs(422202)));
4315 sysTime.roll!"months"(-14);
4316 assert(sysTime == SysTime(DateTime(-2001, 1, 3, 7, 7, 7), hnsecs(422202)));
4319 // Test Both
4321 auto sysTime = SysTime(Date(1, 1, 1));
4322 sysTime.roll!"months"(-1);
4323 assert(sysTime == SysTime(Date(1, 12, 1)));
4324 sysTime.roll!"months"(1);
4325 assert(sysTime == SysTime(Date(1, 1, 1)));
4329 auto sysTime = SysTime(Date(4, 1, 1));
4330 sysTime.roll!"months"(-48);
4331 assert(sysTime == SysTime(Date(4, 1, 1)));
4332 sysTime.roll!"months"(48);
4333 assert(sysTime == SysTime(Date(4, 1, 1)));
4337 auto sysTime = SysTime(Date(4, 3, 31));
4338 sysTime.roll!"months"(-49);
4339 assert(sysTime == SysTime(Date(4, 3, 2)));
4340 sysTime.roll!"months"(49);
4341 assert(sysTime == SysTime(Date(4, 4, 2)));
4345 auto sysTime = SysTime(Date(4, 3, 31));
4346 sysTime.roll!"months"(-85);
4347 assert(sysTime == SysTime(Date(4, 3, 2)));
4348 sysTime.roll!"months"(85);
4349 assert(sysTime == SysTime(Date(4, 4, 2)));
4353 auto sysTime = SysTime(Date(-1, 1, 1));
4354 sysTime.roll!"months"(-1);
4355 assert(sysTime == SysTime(Date(-1, 12, 1)));
4356 sysTime.roll!"months"(1);
4357 assert(sysTime == SysTime(Date(-1, 1, 1)));
4361 auto sysTime = SysTime(Date(-4, 1, 1));
4362 sysTime.roll!"months"(-48);
4363 assert(sysTime == SysTime(Date(-4, 1, 1)));
4364 sysTime.roll!"months"(48);
4365 assert(sysTime == SysTime(Date(-4, 1, 1)));
4369 auto sysTime = SysTime(Date(-4, 3, 31));
4370 sysTime.roll!"months"(-49);
4371 assert(sysTime == SysTime(Date(-4, 3, 2)));
4372 sysTime.roll!"months"(49);
4373 assert(sysTime == SysTime(Date(-4, 4, 2)));
4377 auto sysTime = SysTime(Date(-4, 3, 31));
4378 sysTime.roll!"months"(-85);
4379 assert(sysTime == SysTime(Date(-4, 3, 2)));
4380 sysTime.roll!"months"(85);
4381 assert(sysTime == SysTime(Date(-4, 4, 2)));
4385 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17));
4386 sysTime.roll!"months"(-1);
4387 assert(sysTime == SysTime(DateTime(1, 12, 1, 0, 7, 9), hnsecs(17)));
4388 sysTime.roll!"months"(1);
4389 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17)));
4393 auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), msecs(9));
4394 sysTime.roll!"months"(-85);
4395 assert(sysTime == SysTime(DateTime(4, 3, 2, 12, 11, 10), msecs(9)));
4396 sysTime.roll!"months"(85);
4397 assert(sysTime == SysTime(DateTime(4, 4, 2, 12, 11, 10), msecs(9)));
4401 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9));
4402 sysTime.roll!"months"(85);
4403 assert(sysTime == SysTime(DateTime(-3, 5, 1, 12, 11, 10), msecs(9)));
4404 sysTime.roll!"months"(-85);
4405 assert(sysTime == SysTime(DateTime(-3, 4, 1, 12, 11, 10), msecs(9)));
4409 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9));
4410 sysTime.roll!"months"(85).roll!"months"(-83);
4411 assert(sysTime == SysTime(DateTime(-3, 6, 1, 12, 11, 10), msecs(9)));
4414 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
4415 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
4416 static assert(!__traits(compiles, cst.roll!"months"(4)));
4417 static assert(!__traits(compiles, ist.roll!"months"(4)));
4419 static void testScope(scope ref SysTime st) @safe
4421 auto result = st.roll!"months"(42);
4425 // Test roll!"months"() with AllowDayOverflow.no
4426 @safe unittest
4428 import core.time;
4429 // Test A.D.
4431 auto sysTime = SysTime(Date(1999, 7, 6));
4432 sysTime.roll!"months"(3, AllowDayOverflow.no);
4433 assert(sysTime == SysTime(Date(1999, 10, 6)));
4434 sysTime.roll!"months"(-4, AllowDayOverflow.no);
4435 assert(sysTime == SysTime(Date(1999, 6, 6)));
4439 auto sysTime = SysTime(Date(1999, 7, 6));
4440 sysTime.roll!"months"(6, AllowDayOverflow.no);
4441 assert(sysTime == SysTime(Date(1999, 1, 6)));
4442 sysTime.roll!"months"(-6, AllowDayOverflow.no);
4443 assert(sysTime == SysTime(Date(1999, 7, 6)));
4447 auto sysTime = SysTime(Date(1999, 7, 6));
4448 sysTime.roll!"months"(27, AllowDayOverflow.no);
4449 assert(sysTime == SysTime(Date(1999, 10, 6)));
4450 sysTime.roll!"months"(-28, AllowDayOverflow.no);
4451 assert(sysTime == SysTime(Date(1999, 6, 6)));
4455 auto sysTime = SysTime(Date(1999, 5, 31));
4456 sysTime.roll!"months"(1, AllowDayOverflow.no);
4457 assert(sysTime == SysTime(Date(1999, 6, 30)));
4461 auto sysTime = SysTime(Date(1999, 5, 31));
4462 sysTime.roll!"months"(-1, AllowDayOverflow.no);
4463 assert(sysTime == SysTime(Date(1999, 4, 30)));
4467 auto sysTime = SysTime(Date(1999, 2, 28));
4468 sysTime.roll!"months"(12, AllowDayOverflow.no);
4469 assert(sysTime == SysTime(Date(1999, 2, 28)));
4473 auto sysTime = SysTime(Date(2000, 2, 29));
4474 sysTime.roll!"months"(12, AllowDayOverflow.no);
4475 assert(sysTime == SysTime(Date(2000, 2, 29)));
4479 auto sysTime = SysTime(Date(1999, 7, 31));
4480 sysTime.roll!"months"(1, AllowDayOverflow.no);
4481 assert(sysTime == SysTime(Date(1999, 8, 31)));
4482 sysTime.roll!"months"(1, AllowDayOverflow.no);
4483 assert(sysTime == SysTime(Date(1999, 9, 30)));
4487 auto sysTime = SysTime(Date(1998, 8, 31));
4488 sysTime.roll!"months"(13, AllowDayOverflow.no);
4489 assert(sysTime == SysTime(Date(1998, 9, 30)));
4490 sysTime.roll!"months"(-13, AllowDayOverflow.no);
4491 assert(sysTime == SysTime(Date(1998, 8, 30)));
4495 auto sysTime = SysTime(Date(1997, 12, 31));
4496 sysTime.roll!"months"(13, AllowDayOverflow.no);
4497 assert(sysTime == SysTime(Date(1997, 1, 31)));
4498 sysTime.roll!"months"(-13, AllowDayOverflow.no);
4499 assert(sysTime == SysTime(Date(1997, 12, 31)));
4503 auto sysTime = SysTime(Date(1997, 12, 31));
4504 sysTime.roll!"months"(14, AllowDayOverflow.no);
4505 assert(sysTime == SysTime(Date(1997, 2, 28)));
4506 sysTime.roll!"months"(-14, AllowDayOverflow.no);
4507 assert(sysTime == SysTime(Date(1997, 12, 28)));
4511 auto sysTime = SysTime(Date(1998, 12, 31));
4512 sysTime.roll!"months"(14, AllowDayOverflow.no);
4513 assert(sysTime == SysTime(Date(1998, 2, 28)));
4514 sysTime.roll!"months"(-14, AllowDayOverflow.no);
4515 assert(sysTime == SysTime(Date(1998, 12, 28)));
4519 auto sysTime = SysTime(Date(1999, 12, 31));
4520 sysTime.roll!"months"(14, AllowDayOverflow.no);
4521 assert(sysTime == SysTime(Date(1999, 2, 28)));
4522 sysTime.roll!"months"(-14, AllowDayOverflow.no);
4523 assert(sysTime == SysTime(Date(1999, 12, 28)));
4527 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), usecs(5007));
4528 sysTime.roll!"months"(3, AllowDayOverflow.no);
4529 assert(sysTime == SysTime(DateTime(1999, 10, 6, 12, 2, 7), usecs(5007)));
4530 sysTime.roll!"months"(-4, AllowDayOverflow.no);
4531 assert(sysTime == SysTime(DateTime(1999, 6, 6, 12, 2, 7), usecs(5007)));
4535 auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), hnsecs(422202));
4536 sysTime.roll!"months"(14, AllowDayOverflow.no);
4537 assert(sysTime == SysTime(DateTime(1998, 2, 28, 7, 7, 7), hnsecs(422202)));
4538 sysTime.roll!"months"(-14, AllowDayOverflow.no);
4539 assert(sysTime == SysTime(DateTime(1998, 12, 28, 7, 7, 7), hnsecs(422202)));
4543 auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), hnsecs(422202));
4544 sysTime.roll!"months"(14, AllowDayOverflow.no);
4545 assert(sysTime == SysTime(DateTime(1999, 2, 28, 7, 7, 7), hnsecs(422202)));
4546 sysTime.roll!"months"(-14, AllowDayOverflow.no);
4547 assert(sysTime == SysTime(DateTime(1999, 12, 28, 7, 7, 7), hnsecs(422202)));
4550 // Test B.C.
4552 auto sysTime = SysTime(Date(-1999, 7, 6));
4553 sysTime.roll!"months"(3, AllowDayOverflow.no);
4554 assert(sysTime == SysTime(Date(-1999, 10, 6)));
4555 sysTime.roll!"months"(-4, AllowDayOverflow.no);
4556 assert(sysTime == SysTime(Date(-1999, 6, 6)));
4560 auto sysTime = SysTime(Date(-1999, 7, 6));
4561 sysTime.roll!"months"(6, AllowDayOverflow.no);
4562 assert(sysTime == SysTime(Date(-1999, 1, 6)));
4563 sysTime.roll!"months"(-6, AllowDayOverflow.no);
4564 assert(sysTime == SysTime(Date(-1999, 7, 6)));
4568 auto sysTime = SysTime(Date(-1999, 7, 6));
4569 sysTime.roll!"months"(-27, AllowDayOverflow.no);
4570 assert(sysTime == SysTime(Date(-1999, 4, 6)));
4571 sysTime.roll!"months"(28, AllowDayOverflow.no);
4572 assert(sysTime == SysTime(Date(-1999, 8, 6)));
4576 auto sysTime = SysTime(Date(-1999, 5, 31));
4577 sysTime.roll!"months"(1, AllowDayOverflow.no);
4578 assert(sysTime == SysTime(Date(-1999, 6, 30)));
4582 auto sysTime = SysTime(Date(-1999, 5, 31));
4583 sysTime.roll!"months"(-1, AllowDayOverflow.no);
4584 assert(sysTime == SysTime(Date(-1999, 4, 30)));
4588 auto sysTime = SysTime(Date(-1999, 2, 28));
4589 sysTime.roll!"months"(-12, AllowDayOverflow.no);
4590 assert(sysTime == SysTime(Date(-1999, 2, 28)));
4594 auto sysTime = SysTime(Date(-2000, 2, 29));
4595 sysTime.roll!"months"(-12, AllowDayOverflow.no);
4596 assert(sysTime == SysTime(Date(-2000, 2, 29)));
4600 auto sysTime = SysTime(Date(-1999, 7, 31));
4601 sysTime.roll!"months"(1, AllowDayOverflow.no);
4602 assert(sysTime == SysTime(Date(-1999, 8, 31)));
4603 sysTime.roll!"months"(1, AllowDayOverflow.no);
4604 assert(sysTime == SysTime(Date(-1999, 9, 30)));
4608 auto sysTime = SysTime(Date(-1998, 8, 31));
4609 sysTime.roll!"months"(13, AllowDayOverflow.no);
4610 assert(sysTime == SysTime(Date(-1998, 9, 30)));
4611 sysTime.roll!"months"(-13, AllowDayOverflow.no);
4612 assert(sysTime == SysTime(Date(-1998, 8, 30)));
4616 auto sysTime = SysTime(Date(-1997, 12, 31));
4617 sysTime.roll!"months"(13, AllowDayOverflow.no);
4618 assert(sysTime == SysTime(Date(-1997, 1, 31)));
4619 sysTime.roll!"months"(-13, AllowDayOverflow.no);
4620 assert(sysTime == SysTime(Date(-1997, 12, 31)));
4624 auto sysTime = SysTime(Date(-1997, 12, 31));
4625 sysTime.roll!"months"(14, AllowDayOverflow.no);
4626 assert(sysTime == SysTime(Date(-1997, 2, 28)));
4627 sysTime.roll!"months"(-14, AllowDayOverflow.no);
4628 assert(sysTime == SysTime(Date(-1997, 12, 28)));
4632 auto sysTime = SysTime(Date(-2002, 12, 31));
4633 sysTime.roll!"months"(14, AllowDayOverflow.no);
4634 assert(sysTime == SysTime(Date(-2002, 2, 28)));
4635 sysTime.roll!"months"(-14, AllowDayOverflow.no);
4636 assert(sysTime == SysTime(Date(-2002, 12, 28)));
4640 auto sysTime = SysTime(Date(-2001, 12, 31));
4641 sysTime.roll!"months"(14, AllowDayOverflow.no);
4642 assert(sysTime == SysTime(Date(-2001, 2, 28)));
4643 sysTime.roll!"months"(-14, AllowDayOverflow.no);
4644 assert(sysTime == SysTime(Date(-2001, 12, 28)));
4648 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), usecs(5007));
4649 sysTime.roll!"months"(3, AllowDayOverflow.no);
4650 assert(sysTime == SysTime(DateTime(-1999, 10, 6, 12, 2, 7), usecs(5007)));
4651 sysTime.roll!"months"(-4, AllowDayOverflow.no);
4652 assert(sysTime == SysTime(DateTime(-1999, 6, 6, 12, 2, 7), usecs(5007)));
4656 auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), hnsecs(422202));
4657 sysTime.roll!"months"(14, AllowDayOverflow.no);
4658 assert(sysTime == SysTime(DateTime(-2002, 2, 28, 7, 7, 7), hnsecs(422202)));
4659 sysTime.roll!"months"(-14, AllowDayOverflow.no);
4660 assert(sysTime == SysTime(DateTime(-2002, 12, 28, 7, 7, 7), hnsecs(422202)));
4664 auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), hnsecs(422202));
4665 sysTime.roll!"months"(14, AllowDayOverflow.no);
4666 assert(sysTime == SysTime(DateTime(-2001, 2, 28, 7, 7, 7), hnsecs(422202)));
4667 sysTime.roll!"months"(-14, AllowDayOverflow.no);
4668 assert(sysTime == SysTime(DateTime(-2001, 12, 28, 7, 7, 7), hnsecs(422202)));
4671 // Test Both
4673 auto sysTime = SysTime(Date(1, 1, 1));
4674 sysTime.roll!"months"(-1, AllowDayOverflow.no);
4675 assert(sysTime == SysTime(Date(1, 12, 1)));
4676 sysTime.roll!"months"(1, AllowDayOverflow.no);
4677 assert(sysTime == SysTime(Date(1, 1, 1)));
4681 auto sysTime = SysTime(Date(4, 1, 1));
4682 sysTime.roll!"months"(-48, AllowDayOverflow.no);
4683 assert(sysTime == SysTime(Date(4, 1, 1)));
4684 sysTime.roll!"months"(48, AllowDayOverflow.no);
4685 assert(sysTime == SysTime(Date(4, 1, 1)));
4689 auto sysTime = SysTime(Date(4, 3, 31));
4690 sysTime.roll!"months"(-49, AllowDayOverflow.no);
4691 assert(sysTime == SysTime(Date(4, 2, 29)));
4692 sysTime.roll!"months"(49, AllowDayOverflow.no);
4693 assert(sysTime == SysTime(Date(4, 3, 29)));
4697 auto sysTime = SysTime(Date(4, 3, 31));
4698 sysTime.roll!"months"(-85, AllowDayOverflow.no);
4699 assert(sysTime == SysTime(Date(4, 2, 29)));
4700 sysTime.roll!"months"(85, AllowDayOverflow.no);
4701 assert(sysTime == SysTime(Date(4, 3, 29)));
4705 auto sysTime = SysTime(Date(-1, 1, 1));
4706 sysTime.roll!"months"(-1, AllowDayOverflow.no);
4707 assert(sysTime == SysTime(Date(-1, 12, 1)));
4708 sysTime.roll!"months"(1, AllowDayOverflow.no);
4709 assert(sysTime == SysTime(Date(-1, 1, 1)));
4713 auto sysTime = SysTime(Date(-4, 1, 1));
4714 sysTime.roll!"months"(-48, AllowDayOverflow.no);
4715 assert(sysTime == SysTime(Date(-4, 1, 1)));
4716 sysTime.roll!"months"(48, AllowDayOverflow.no);
4717 assert(sysTime == SysTime(Date(-4, 1, 1)));
4721 auto sysTime = SysTime(Date(-4, 3, 31));
4722 sysTime.roll!"months"(-49, AllowDayOverflow.no);
4723 assert(sysTime == SysTime(Date(-4, 2, 29)));
4724 sysTime.roll!"months"(49, AllowDayOverflow.no);
4725 assert(sysTime == SysTime(Date(-4, 3, 29)));
4729 auto sysTime = SysTime(Date(-4, 3, 31));
4730 sysTime.roll!"months"(-85, AllowDayOverflow.no);
4731 assert(sysTime == SysTime(Date(-4, 2, 29)));
4732 sysTime.roll!"months"(85, AllowDayOverflow.no);
4733 assert(sysTime == SysTime(Date(-4, 3, 29)));
4737 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0));
4738 sysTime.roll!"months"(-1, AllowDayOverflow.no);
4739 assert(sysTime == SysTime(DateTime(1, 12, 1, 0, 0, 0)));
4740 sysTime.roll!"months"(1, AllowDayOverflow.no);
4741 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));
4745 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999));
4746 sysTime.roll!"months"(-1, AllowDayOverflow.no);
4747 assert(sysTime == SysTime(DateTime(1, 12, 1, 23, 59, 59), hnsecs(9_999_999)));
4748 sysTime.roll!"months"(1, AllowDayOverflow.no);
4749 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));
4753 auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0));
4754 sysTime.roll!"months"(1, AllowDayOverflow.no);
4755 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0)));
4756 sysTime.roll!"months"(-1, AllowDayOverflow.no);
4757 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0)));
4761 auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999));
4762 sysTime.roll!"months"(1, AllowDayOverflow.no);
4763 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)));
4764 sysTime.roll!"months"(-1, AllowDayOverflow.no);
4765 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)));
4769 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17));
4770 sysTime.roll!"months"(-1, AllowDayOverflow.no);
4771 assert(sysTime == SysTime(DateTime(1, 12, 1, 0, 7, 9), hnsecs(17)));
4772 sysTime.roll!"months"(1, AllowDayOverflow.no);
4773 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17)));
4777 auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), msecs(9));
4778 sysTime.roll!"months"(-85, AllowDayOverflow.no);
4779 assert(sysTime == SysTime(DateTime(4, 2, 29, 12, 11, 10), msecs(9)));
4780 sysTime.roll!"months"(85, AllowDayOverflow.no);
4781 assert(sysTime == SysTime(DateTime(4, 3, 29, 12, 11, 10), msecs(9)));
4785 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9));
4786 sysTime.roll!"months"(85, AllowDayOverflow.no);
4787 assert(sysTime == SysTime(DateTime(-3, 4, 30, 12, 11, 10), msecs(9)));
4788 sysTime.roll!"months"(-85, AllowDayOverflow.no);
4789 assert(sysTime == SysTime(DateTime(-3, 3, 30, 12, 11, 10), msecs(9)));
4793 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9));
4794 sysTime.roll!"months"(85, AllowDayOverflow.no).roll!"months"(-83, AllowDayOverflow.no);
4795 assert(sysTime == SysTime(DateTime(-3, 5, 30, 12, 11, 10), msecs(9)));
4801 Adds the given number of units to this $(LREF SysTime). A negative number
4802 will subtract.
4804 The difference between rolling and adding is that rolling does not
4805 affect larger units. For instance, rolling a $(LREF SysTime) one
4806 year's worth of days gets the exact same $(LREF SysTime).
4808 Accepted units are `"days"`, `"minutes"`, `"hours"`,
4809 `"minutes"`, `"seconds"`, `"msecs"`, `"usecs"`, and
4810 `"hnsecs"`.
4812 Note that when rolling msecs, usecs or hnsecs, they all add up to a
4813 second. So, for example, rolling 1000 msecs is exactly the same as
4814 rolling 100,000 usecs.
4816 Params:
4817 units = The units to add.
4818 value = The number of $(D_PARAM units) to add to this
4819 $(LREF SysTime).
4821 ref SysTime roll(string units)(long value) @safe nothrow scope
4822 if (units == "days")
4824 auto hnsecs = adjTime;
4825 auto gdays = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
4827 if (hnsecs < 0)
4829 hnsecs += convert!("hours", "hnsecs")(24);
4830 --gdays;
4833 auto date = Date(cast(int) gdays);
4834 date.roll!"days"(value);
4835 gdays = date.dayOfGregorianCal - 1;
4837 if (gdays < 0)
4839 hnsecs -= convert!("hours", "hnsecs")(24);
4840 ++gdays;
4843 immutable newDaysHNSecs = convert!("days", "hnsecs")(gdays);
4844 adjTime = newDaysHNSecs + hnsecs;
4845 return this;
4849 @safe unittest
4851 import core.time : msecs, hnsecs;
4852 import std.datetime.date : DateTime;
4854 auto st1 = SysTime(DateTime(2010, 1, 1, 11, 23, 12));
4855 st1.roll!"days"(1);
4856 assert(st1 == SysTime(DateTime(2010, 1, 2, 11, 23, 12)));
4857 st1.roll!"days"(365);
4858 assert(st1 == SysTime(DateTime(2010, 1, 26, 11, 23, 12)));
4859 st1.roll!"days"(-32);
4860 assert(st1 == SysTime(DateTime(2010, 1, 25, 11, 23, 12)));
4862 auto st2 = SysTime(DateTime(2010, 7, 4, 12, 0, 0));
4863 st2.roll!"hours"(1);
4864 assert(st2 == SysTime(DateTime(2010, 7, 4, 13, 0, 0)));
4866 auto st3 = SysTime(DateTime(2010, 2, 12, 12, 0, 0));
4867 st3.roll!"hours"(-1);
4868 assert(st3 == SysTime(DateTime(2010, 2, 12, 11, 0, 0)));
4870 auto st4 = SysTime(DateTime(2009, 12, 31, 0, 0, 0));
4871 st4.roll!"minutes"(1);
4872 assert(st4 == SysTime(DateTime(2009, 12, 31, 0, 1, 0)));
4874 auto st5 = SysTime(DateTime(2010, 1, 1, 0, 0, 0));
4875 st5.roll!"minutes"(-1);
4876 assert(st5 == SysTime(DateTime(2010, 1, 1, 0, 59, 0)));
4878 auto st6 = SysTime(DateTime(2009, 12, 31, 0, 0, 0));
4879 st6.roll!"seconds"(1);
4880 assert(st6 == SysTime(DateTime(2009, 12, 31, 0, 0, 1)));
4882 auto st7 = SysTime(DateTime(2010, 1, 1, 0, 0, 0));
4883 st7.roll!"seconds"(-1);
4884 assert(st7 == SysTime(DateTime(2010, 1, 1, 0, 0, 59)));
4886 auto dt = DateTime(2010, 1, 1, 0, 0, 0);
4887 auto st8 = SysTime(dt);
4888 st8.roll!"msecs"(1);
4889 assert(st8 == SysTime(dt, msecs(1)));
4891 auto st9 = SysTime(dt);
4892 st9.roll!"msecs"(-1);
4893 assert(st9 == SysTime(dt, msecs(999)));
4895 auto st10 = SysTime(dt);
4896 st10.roll!"hnsecs"(1);
4897 assert(st10 == SysTime(dt, hnsecs(1)));
4899 auto st11 = SysTime(dt);
4900 st11.roll!"hnsecs"(-1);
4901 assert(st11 == SysTime(dt, hnsecs(9_999_999)));
4904 @safe unittest
4906 import core.time;
4907 // Test A.D.
4909 auto sysTime = SysTime(Date(1999, 2, 28));
4910 sysTime.roll!"days"(1);
4911 assert(sysTime == SysTime(Date(1999, 2, 1)));
4912 sysTime.roll!"days"(-1);
4913 assert(sysTime == SysTime(Date(1999, 2, 28)));
4917 auto sysTime = SysTime(Date(2000, 2, 28));
4918 sysTime.roll!"days"(1);
4919 assert(sysTime == SysTime(Date(2000, 2, 29)));
4920 sysTime.roll!"days"(1);
4921 assert(sysTime == SysTime(Date(2000, 2, 1)));
4922 sysTime.roll!"days"(-1);
4923 assert(sysTime == SysTime(Date(2000, 2, 29)));
4927 auto sysTime = SysTime(Date(1999, 6, 30));
4928 sysTime.roll!"days"(1);
4929 assert(sysTime == SysTime(Date(1999, 6, 1)));
4930 sysTime.roll!"days"(-1);
4931 assert(sysTime == SysTime(Date(1999, 6, 30)));
4935 auto sysTime = SysTime(Date(1999, 7, 31));
4936 sysTime.roll!"days"(1);
4937 assert(sysTime == SysTime(Date(1999, 7, 1)));
4938 sysTime.roll!"days"(-1);
4939 assert(sysTime == SysTime(Date(1999, 7, 31)));
4943 auto sysTime = SysTime(Date(1999, 1, 1));
4944 sysTime.roll!"days"(-1);
4945 assert(sysTime == SysTime(Date(1999, 1, 31)));
4946 sysTime.roll!"days"(1);
4947 assert(sysTime == SysTime(Date(1999, 1, 1)));
4951 auto sysTime = SysTime(Date(1999, 7, 6));
4952 sysTime.roll!"days"(9);
4953 assert(sysTime == SysTime(Date(1999, 7, 15)));
4954 sysTime.roll!"days"(-11);
4955 assert(sysTime == SysTime(Date(1999, 7, 4)));
4956 sysTime.roll!"days"(30);
4957 assert(sysTime == SysTime(Date(1999, 7, 3)));
4958 sysTime.roll!"days"(-3);
4959 assert(sysTime == SysTime(Date(1999, 7, 31)));
4963 auto sysTime = SysTime(Date(1999, 7, 6));
4964 sysTime.roll!"days"(365);
4965 assert(sysTime == SysTime(Date(1999, 7, 30)));
4966 sysTime.roll!"days"(-365);
4967 assert(sysTime == SysTime(Date(1999, 7, 6)));
4968 sysTime.roll!"days"(366);
4969 assert(sysTime == SysTime(Date(1999, 7, 31)));
4970 sysTime.roll!"days"(730);
4971 assert(sysTime == SysTime(Date(1999, 7, 17)));
4972 sysTime.roll!"days"(-1096);
4973 assert(sysTime == SysTime(Date(1999, 7, 6)));
4977 auto sysTime = SysTime(Date(1999, 2, 6));
4978 sysTime.roll!"days"(365);
4979 assert(sysTime == SysTime(Date(1999, 2, 7)));
4980 sysTime.roll!"days"(-365);
4981 assert(sysTime == SysTime(Date(1999, 2, 6)));
4982 sysTime.roll!"days"(366);
4983 assert(sysTime == SysTime(Date(1999, 2, 8)));
4984 sysTime.roll!"days"(730);
4985 assert(sysTime == SysTime(Date(1999, 2, 10)));
4986 sysTime.roll!"days"(-1096);
4987 assert(sysTime == SysTime(Date(1999, 2, 6)));
4991 auto sysTime = SysTime(DateTime(1999, 2, 28, 7, 9, 2), usecs(234578));
4992 sysTime.roll!"days"(1);
4993 assert(sysTime == SysTime(DateTime(1999, 2, 1, 7, 9, 2), usecs(234578)));
4994 sysTime.roll!"days"(-1);
4995 assert(sysTime == SysTime(DateTime(1999, 2, 28, 7, 9, 2), usecs(234578)));
4999 auto sysTime = SysTime(DateTime(1999, 7, 6, 7, 9, 2), usecs(234578));
5000 sysTime.roll!"days"(9);
5001 assert(sysTime == SysTime(DateTime(1999, 7, 15, 7, 9, 2), usecs(234578)));
5002 sysTime.roll!"days"(-11);
5003 assert(sysTime == SysTime(DateTime(1999, 7, 4, 7, 9, 2), usecs(234578)));
5004 sysTime.roll!"days"(30);
5005 assert(sysTime == SysTime(DateTime(1999, 7, 3, 7, 9, 2), usecs(234578)));
5006 sysTime.roll!"days"(-3);
5007 assert(sysTime == SysTime(DateTime(1999, 7, 31, 7, 9, 2), usecs(234578)));
5010 // Test B.C.
5012 auto sysTime = SysTime(Date(-1999, 2, 28));
5013 sysTime.roll!"days"(1);
5014 assert(sysTime == SysTime(Date(-1999, 2, 1)));
5015 sysTime.roll!"days"(-1);
5016 assert(sysTime == SysTime(Date(-1999, 2, 28)));
5020 auto sysTime = SysTime(Date(-2000, 2, 28));
5021 sysTime.roll!"days"(1);
5022 assert(sysTime == SysTime(Date(-2000, 2, 29)));
5023 sysTime.roll!"days"(1);
5024 assert(sysTime == SysTime(Date(-2000, 2, 1)));
5025 sysTime.roll!"days"(-1);
5026 assert(sysTime == SysTime(Date(-2000, 2, 29)));
5030 auto sysTime = SysTime(Date(-1999, 6, 30));
5031 sysTime.roll!"days"(1);
5032 assert(sysTime == SysTime(Date(-1999, 6, 1)));
5033 sysTime.roll!"days"(-1);
5034 assert(sysTime == SysTime(Date(-1999, 6, 30)));
5038 auto sysTime = SysTime(Date(-1999, 7, 31));
5039 sysTime.roll!"days"(1);
5040 assert(sysTime == SysTime(Date(-1999, 7, 1)));
5041 sysTime.roll!"days"(-1);
5042 assert(sysTime == SysTime(Date(-1999, 7, 31)));
5046 auto sysTime = SysTime(Date(-1999, 1, 1));
5047 sysTime.roll!"days"(-1);
5048 assert(sysTime == SysTime(Date(-1999, 1, 31)));
5049 sysTime.roll!"days"(1);
5050 assert(sysTime == SysTime(Date(-1999, 1, 1)));
5054 auto sysTime = SysTime(Date(-1999, 7, 6));
5055 sysTime.roll!"days"(9);
5056 assert(sysTime == SysTime(Date(-1999, 7, 15)));
5057 sysTime.roll!"days"(-11);
5058 assert(sysTime == SysTime(Date(-1999, 7, 4)));
5059 sysTime.roll!"days"(30);
5060 assert(sysTime == SysTime(Date(-1999, 7, 3)));
5061 sysTime.roll!"days"(-3);
5062 assert(sysTime == SysTime(Date(-1999, 7, 31)));
5066 auto sysTime = SysTime(Date(-1999, 7, 6));
5067 sysTime.roll!"days"(365);
5068 assert(sysTime == SysTime(Date(-1999, 7, 30)));
5069 sysTime.roll!"days"(-365);
5070 assert(sysTime == SysTime(Date(-1999, 7, 6)));
5071 sysTime.roll!"days"(366);
5072 assert(sysTime == SysTime(Date(-1999, 7, 31)));
5073 sysTime.roll!"days"(730);
5074 assert(sysTime == SysTime(Date(-1999, 7, 17)));
5075 sysTime.roll!"days"(-1096);
5076 assert(sysTime == SysTime(Date(-1999, 7, 6)));
5080 auto sysTime = SysTime(DateTime(-1999, 2, 28, 7, 9, 2), usecs(234578));
5081 sysTime.roll!"days"(1);
5082 assert(sysTime == SysTime(DateTime(-1999, 2, 1, 7, 9, 2), usecs(234578)));
5083 sysTime.roll!"days"(-1);
5084 assert(sysTime == SysTime(DateTime(-1999, 2, 28, 7, 9, 2), usecs(234578)));
5088 auto sysTime = SysTime(DateTime(-1999, 7, 6, 7, 9, 2), usecs(234578));
5089 sysTime.roll!"days"(9);
5090 assert(sysTime == SysTime(DateTime(-1999, 7, 15, 7, 9, 2), usecs(234578)));
5091 sysTime.roll!"days"(-11);
5092 assert(sysTime == SysTime(DateTime(-1999, 7, 4, 7, 9, 2), usecs(234578)));
5093 sysTime.roll!"days"(30);
5094 assert(sysTime == SysTime(DateTime(-1999, 7, 3, 7, 9, 2), usecs(234578)));
5095 sysTime.roll!"days"(-3);
5098 // Test Both
5100 auto sysTime = SysTime(Date(1, 7, 6));
5101 sysTime.roll!"days"(-365);
5102 assert(sysTime == SysTime(Date(1, 7, 13)));
5103 sysTime.roll!"days"(365);
5104 assert(sysTime == SysTime(Date(1, 7, 6)));
5105 sysTime.roll!"days"(-731);
5106 assert(sysTime == SysTime(Date(1, 7, 19)));
5107 sysTime.roll!"days"(730);
5108 assert(sysTime == SysTime(Date(1, 7, 5)));
5112 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0));
5113 sysTime.roll!"days"(-1);
5114 assert(sysTime == SysTime(DateTime(1, 1, 31, 0, 0, 0)));
5115 sysTime.roll!"days"(1);
5116 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));
5120 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999));
5121 sysTime.roll!"days"(-1);
5122 assert(sysTime == SysTime(DateTime(1, 1, 31, 23, 59, 59), hnsecs(9_999_999)));
5123 sysTime.roll!"days"(1);
5124 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));
5128 auto sysTime = SysTime(DateTime(0, 12, 31, 0, 0, 0));
5129 sysTime.roll!"days"(1);
5130 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0)));
5131 sysTime.roll!"days"(-1);
5132 assert(sysTime == SysTime(DateTime(0, 12, 31, 0, 0, 0)));
5136 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));
5137 sysTime.roll!"days"(1);
5138 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)));
5139 sysTime.roll!"days"(-1);
5140 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));
5144 auto sysTime = SysTime(DateTime(1, 7, 6, 13, 13, 9), msecs(22));
5145 sysTime.roll!"days"(-365);
5146 assert(sysTime == SysTime(DateTime(1, 7, 13, 13, 13, 9), msecs(22)));
5147 sysTime.roll!"days"(365);
5148 assert(sysTime == SysTime(DateTime(1, 7, 6, 13, 13, 9), msecs(22)));
5149 sysTime.roll!"days"(-731);
5150 assert(sysTime == SysTime(DateTime(1, 7, 19, 13, 13, 9), msecs(22)));
5151 sysTime.roll!"days"(730);
5152 assert(sysTime == SysTime(DateTime(1, 7, 5, 13, 13, 9), msecs(22)));
5156 auto sysTime = SysTime(DateTime(0, 7, 6, 13, 13, 9), msecs(22));
5157 sysTime.roll!"days"(-365);
5158 assert(sysTime == SysTime(DateTime(0, 7, 13, 13, 13, 9), msecs(22)));
5159 sysTime.roll!"days"(365);
5160 assert(sysTime == SysTime(DateTime(0, 7, 6, 13, 13, 9), msecs(22)));
5161 sysTime.roll!"days"(-731);
5162 assert(sysTime == SysTime(DateTime(0, 7, 19, 13, 13, 9), msecs(22)));
5163 sysTime.roll!"days"(730);
5164 assert(sysTime == SysTime(DateTime(0, 7, 5, 13, 13, 9), msecs(22)));
5168 auto sysTime = SysTime(DateTime(0, 7, 6, 13, 13, 9), msecs(22));
5169 sysTime.roll!"days"(-365).roll!"days"(362).roll!"days"(-12).roll!"days"(730);
5170 assert(sysTime == SysTime(DateTime(0, 7, 8, 13, 13, 9), msecs(22)));
5173 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
5174 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
5175 static assert(!__traits(compiles, cst.roll!"days"(4)));
5176 static assert(!__traits(compiles, ist.roll!"days"(4)));
5178 static void testScope(scope ref SysTime st) @safe
5180 auto result = st.roll!"days"(42);
5185 // Shares documentation with "days" version.
5186 ref SysTime roll(string units)(long value) @safe nothrow scope
5187 if (units == "hours" || units == "minutes" || units == "seconds")
5191 auto hnsecs = adjTime;
5192 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
5194 if (hnsecs < 0)
5196 hnsecs += convert!("hours", "hnsecs")(24);
5197 --days;
5200 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs);
5201 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs);
5202 immutable second = splitUnitsFromHNSecs!"seconds"(hnsecs);
5204 auto dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour,
5205 cast(int) minute, cast(int) second));
5206 dateTime.roll!units(value);
5207 --days;
5209 hnsecs += convert!("hours", "hnsecs")(dateTime.hour);
5210 hnsecs += convert!("minutes", "hnsecs")(dateTime.minute);
5211 hnsecs += convert!("seconds", "hnsecs")(dateTime.second);
5213 if (days < 0)
5215 hnsecs -= convert!("hours", "hnsecs")(24);
5216 ++days;
5219 immutable newDaysHNSecs = convert!("days", "hnsecs")(days);
5220 adjTime = newDaysHNSecs + hnsecs;
5221 return this;
5223 catch (Exception e)
5224 assert(0, "Either DateTime's constructor or TimeOfDay's constructor threw.");
5227 // Test roll!"hours"().
5228 @safe unittest
5230 import core.time;
5231 static void testST(SysTime orig, int hours, SysTime expected, size_t line = __LINE__) @safe
5233 orig.roll!"hours"(hours);
5234 if (orig != expected)
5235 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line);
5238 // Test A.D.
5239 immutable d = msecs(45);
5240 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), d);
5241 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));
5242 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 13, 30, 33), d));
5243 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 14, 30, 33), d));
5244 testST(beforeAD, 3, SysTime(DateTime(1999, 7, 6, 15, 30, 33), d));
5245 testST(beforeAD, 4, SysTime(DateTime(1999, 7, 6, 16, 30, 33), d));
5246 testST(beforeAD, 5, SysTime(DateTime(1999, 7, 6, 17, 30, 33), d));
5247 testST(beforeAD, 6, SysTime(DateTime(1999, 7, 6, 18, 30, 33), d));
5248 testST(beforeAD, 7, SysTime(DateTime(1999, 7, 6, 19, 30, 33), d));
5249 testST(beforeAD, 8, SysTime(DateTime(1999, 7, 6, 20, 30, 33), d));
5250 testST(beforeAD, 9, SysTime(DateTime(1999, 7, 6, 21, 30, 33), d));
5251 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 22, 30, 33), d));
5252 testST(beforeAD, 11, SysTime(DateTime(1999, 7, 6, 23, 30, 33), d));
5253 testST(beforeAD, 12, SysTime(DateTime(1999, 7, 6, 0, 30, 33), d));
5254 testST(beforeAD, 13, SysTime(DateTime(1999, 7, 6, 1, 30, 33), d));
5255 testST(beforeAD, 14, SysTime(DateTime(1999, 7, 6, 2, 30, 33), d));
5256 testST(beforeAD, 15, SysTime(DateTime(1999, 7, 6, 3, 30, 33), d));
5257 testST(beforeAD, 16, SysTime(DateTime(1999, 7, 6, 4, 30, 33), d));
5258 testST(beforeAD, 17, SysTime(DateTime(1999, 7, 6, 5, 30, 33), d));
5259 testST(beforeAD, 18, SysTime(DateTime(1999, 7, 6, 6, 30, 33), d));
5260 testST(beforeAD, 19, SysTime(DateTime(1999, 7, 6, 7, 30, 33), d));
5261 testST(beforeAD, 20, SysTime(DateTime(1999, 7, 6, 8, 30, 33), d));
5262 testST(beforeAD, 21, SysTime(DateTime(1999, 7, 6, 9, 30, 33), d));
5263 testST(beforeAD, 22, SysTime(DateTime(1999, 7, 6, 10, 30, 33), d));
5264 testST(beforeAD, 23, SysTime(DateTime(1999, 7, 6, 11, 30, 33), d));
5265 testST(beforeAD, 24, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));
5266 testST(beforeAD, 25, SysTime(DateTime(1999, 7, 6, 13, 30, 33), d));
5267 testST(beforeAD, 50, SysTime(DateTime(1999, 7, 6, 14, 30, 33), d));
5268 testST(beforeAD, 10_000, SysTime(DateTime(1999, 7, 6, 4, 30, 33), d));
5270 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 11, 30, 33), d));
5271 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 10, 30, 33), d));
5272 testST(beforeAD, -3, SysTime(DateTime(1999, 7, 6, 9, 30, 33), d));
5273 testST(beforeAD, -4, SysTime(DateTime(1999, 7, 6, 8, 30, 33), d));
5274 testST(beforeAD, -5, SysTime(DateTime(1999, 7, 6, 7, 30, 33), d));
5275 testST(beforeAD, -6, SysTime(DateTime(1999, 7, 6, 6, 30, 33), d));
5276 testST(beforeAD, -7, SysTime(DateTime(1999, 7, 6, 5, 30, 33), d));
5277 testST(beforeAD, -8, SysTime(DateTime(1999, 7, 6, 4, 30, 33), d));
5278 testST(beforeAD, -9, SysTime(DateTime(1999, 7, 6, 3, 30, 33), d));
5279 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 2, 30, 33), d));
5280 testST(beforeAD, -11, SysTime(DateTime(1999, 7, 6, 1, 30, 33), d));
5281 testST(beforeAD, -12, SysTime(DateTime(1999, 7, 6, 0, 30, 33), d));
5282 testST(beforeAD, -13, SysTime(DateTime(1999, 7, 6, 23, 30, 33), d));
5283 testST(beforeAD, -14, SysTime(DateTime(1999, 7, 6, 22, 30, 33), d));
5284 testST(beforeAD, -15, SysTime(DateTime(1999, 7, 6, 21, 30, 33), d));
5285 testST(beforeAD, -16, SysTime(DateTime(1999, 7, 6, 20, 30, 33), d));
5286 testST(beforeAD, -17, SysTime(DateTime(1999, 7, 6, 19, 30, 33), d));
5287 testST(beforeAD, -18, SysTime(DateTime(1999, 7, 6, 18, 30, 33), d));
5288 testST(beforeAD, -19, SysTime(DateTime(1999, 7, 6, 17, 30, 33), d));
5289 testST(beforeAD, -20, SysTime(DateTime(1999, 7, 6, 16, 30, 33), d));
5290 testST(beforeAD, -21, SysTime(DateTime(1999, 7, 6, 15, 30, 33), d));
5291 testST(beforeAD, -22, SysTime(DateTime(1999, 7, 6, 14, 30, 33), d));
5292 testST(beforeAD, -23, SysTime(DateTime(1999, 7, 6, 13, 30, 33), d));
5293 testST(beforeAD, -24, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));
5294 testST(beforeAD, -25, SysTime(DateTime(1999, 7, 6, 11, 30, 33), d));
5295 testST(beforeAD, -50, SysTime(DateTime(1999, 7, 6, 10, 30, 33), d));
5296 testST(beforeAD, -10_000, SysTime(DateTime(1999, 7, 6, 20, 30, 33), d));
5298 testST(SysTime(DateTime(1999, 7, 6, 0, 30, 33), d), 1, SysTime(DateTime(1999, 7, 6, 1, 30, 33), d));
5299 testST(SysTime(DateTime(1999, 7, 6, 0, 30, 33), d), 0, SysTime(DateTime(1999, 7, 6, 0, 30, 33), d));
5300 testST(SysTime(DateTime(1999, 7, 6, 0, 30, 33), d), -1, SysTime(DateTime(1999, 7, 6, 23, 30, 33), d));
5302 testST(SysTime(DateTime(1999, 7, 6, 23, 30, 33), d), 1, SysTime(DateTime(1999, 7, 6, 0, 30, 33), d));
5303 testST(SysTime(DateTime(1999, 7, 6, 23, 30, 33), d), 0, SysTime(DateTime(1999, 7, 6, 23, 30, 33), d));
5304 testST(SysTime(DateTime(1999, 7, 6, 23, 30, 33), d), -1, SysTime(DateTime(1999, 7, 6, 22, 30, 33), d));
5306 testST(SysTime(DateTime(1999, 7, 31, 23, 30, 33), d), 1, SysTime(DateTime(1999, 7, 31, 0, 30, 33), d));
5307 testST(SysTime(DateTime(1999, 8, 1, 0, 30, 33), d), -1, SysTime(DateTime(1999, 8, 1, 23, 30, 33), d));
5309 testST(SysTime(DateTime(1999, 12, 31, 23, 30, 33), d), 1, SysTime(DateTime(1999, 12, 31, 0, 30, 33), d));
5310 testST(SysTime(DateTime(2000, 1, 1, 0, 30, 33), d), -1, SysTime(DateTime(2000, 1, 1, 23, 30, 33), d));
5312 testST(SysTime(DateTime(1999, 2, 28, 23, 30, 33), d), 25, SysTime(DateTime(1999, 2, 28, 0, 30, 33), d));
5313 testST(SysTime(DateTime(1999, 3, 2, 0, 30, 33), d), -25, SysTime(DateTime(1999, 3, 2, 23, 30, 33), d));
5315 testST(SysTime(DateTime(2000, 2, 28, 23, 30, 33), d), 25, SysTime(DateTime(2000, 2, 28, 0, 30, 33), d));
5316 testST(SysTime(DateTime(2000, 3, 1, 0, 30, 33), d), -25, SysTime(DateTime(2000, 3, 1, 23, 30, 33), d));
5318 // Test B.C.
5319 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d);
5320 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));
5321 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), d));
5322 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 14, 30, 33), d));
5323 testST(beforeBC, 3, SysTime(DateTime(-1999, 7, 6, 15, 30, 33), d));
5324 testST(beforeBC, 4, SysTime(DateTime(-1999, 7, 6, 16, 30, 33), d));
5325 testST(beforeBC, 5, SysTime(DateTime(-1999, 7, 6, 17, 30, 33), d));
5326 testST(beforeBC, 6, SysTime(DateTime(-1999, 7, 6, 18, 30, 33), d));
5327 testST(beforeBC, 7, SysTime(DateTime(-1999, 7, 6, 19, 30, 33), d));
5328 testST(beforeBC, 8, SysTime(DateTime(-1999, 7, 6, 20, 30, 33), d));
5329 testST(beforeBC, 9, SysTime(DateTime(-1999, 7, 6, 21, 30, 33), d));
5330 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 22, 30, 33), d));
5331 testST(beforeBC, 11, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d));
5332 testST(beforeBC, 12, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d));
5333 testST(beforeBC, 13, SysTime(DateTime(-1999, 7, 6, 1, 30, 33), d));
5334 testST(beforeBC, 14, SysTime(DateTime(-1999, 7, 6, 2, 30, 33), d));
5335 testST(beforeBC, 15, SysTime(DateTime(-1999, 7, 6, 3, 30, 33), d));
5336 testST(beforeBC, 16, SysTime(DateTime(-1999, 7, 6, 4, 30, 33), d));
5337 testST(beforeBC, 17, SysTime(DateTime(-1999, 7, 6, 5, 30, 33), d));
5338 testST(beforeBC, 18, SysTime(DateTime(-1999, 7, 6, 6, 30, 33), d));
5339 testST(beforeBC, 19, SysTime(DateTime(-1999, 7, 6, 7, 30, 33), d));
5340 testST(beforeBC, 20, SysTime(DateTime(-1999, 7, 6, 8, 30, 33), d));
5341 testST(beforeBC, 21, SysTime(DateTime(-1999, 7, 6, 9, 30, 33), d));
5342 testST(beforeBC, 22, SysTime(DateTime(-1999, 7, 6, 10, 30, 33), d));
5343 testST(beforeBC, 23, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), d));
5344 testST(beforeBC, 24, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));
5345 testST(beforeBC, 25, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), d));
5346 testST(beforeBC, 50, SysTime(DateTime(-1999, 7, 6, 14, 30, 33), d));
5347 testST(beforeBC, 10_000, SysTime(DateTime(-1999, 7, 6, 4, 30, 33), d));
5349 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), d));
5350 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 10, 30, 33), d));
5351 testST(beforeBC, -3, SysTime(DateTime(-1999, 7, 6, 9, 30, 33), d));
5352 testST(beforeBC, -4, SysTime(DateTime(-1999, 7, 6, 8, 30, 33), d));
5353 testST(beforeBC, -5, SysTime(DateTime(-1999, 7, 6, 7, 30, 33), d));
5354 testST(beforeBC, -6, SysTime(DateTime(-1999, 7, 6, 6, 30, 33), d));
5355 testST(beforeBC, -7, SysTime(DateTime(-1999, 7, 6, 5, 30, 33), d));
5356 testST(beforeBC, -8, SysTime(DateTime(-1999, 7, 6, 4, 30, 33), d));
5357 testST(beforeBC, -9, SysTime(DateTime(-1999, 7, 6, 3, 30, 33), d));
5358 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 2, 30, 33), d));
5359 testST(beforeBC, -11, SysTime(DateTime(-1999, 7, 6, 1, 30, 33), d));
5360 testST(beforeBC, -12, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d));
5361 testST(beforeBC, -13, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d));
5362 testST(beforeBC, -14, SysTime(DateTime(-1999, 7, 6, 22, 30, 33), d));
5363 testST(beforeBC, -15, SysTime(DateTime(-1999, 7, 6, 21, 30, 33), d));
5364 testST(beforeBC, -16, SysTime(DateTime(-1999, 7, 6, 20, 30, 33), d));
5365 testST(beforeBC, -17, SysTime(DateTime(-1999, 7, 6, 19, 30, 33), d));
5366 testST(beforeBC, -18, SysTime(DateTime(-1999, 7, 6, 18, 30, 33), d));
5367 testST(beforeBC, -19, SysTime(DateTime(-1999, 7, 6, 17, 30, 33), d));
5368 testST(beforeBC, -20, SysTime(DateTime(-1999, 7, 6, 16, 30, 33), d));
5369 testST(beforeBC, -21, SysTime(DateTime(-1999, 7, 6, 15, 30, 33), d));
5370 testST(beforeBC, -22, SysTime(DateTime(-1999, 7, 6, 14, 30, 33), d));
5371 testST(beforeBC, -23, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), d));
5372 testST(beforeBC, -24, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));
5373 testST(beforeBC, -25, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), d));
5374 testST(beforeBC, -50, SysTime(DateTime(-1999, 7, 6, 10, 30, 33), d));
5375 testST(beforeBC, -10_000, SysTime(DateTime(-1999, 7, 6, 20, 30, 33), d));
5377 testST(SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 1, 30, 33), d));
5378 testST(SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d));
5379 testST(SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d));
5381 testST(SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d));
5382 testST(SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d));
5383 testST(SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 22, 30, 33), d));
5385 testST(SysTime(DateTime(-1999, 7, 31, 23, 30, 33), d), 1, SysTime(DateTime(-1999, 7, 31, 0, 30, 33), d));
5386 testST(SysTime(DateTime(-1999, 8, 1, 0, 30, 33), d), -1, SysTime(DateTime(-1999, 8, 1, 23, 30, 33), d));
5388 testST(SysTime(DateTime(-2001, 12, 31, 23, 30, 33), d), 1, SysTime(DateTime(-2001, 12, 31, 0, 30, 33), d));
5389 testST(SysTime(DateTime(-2000, 1, 1, 0, 30, 33), d), -1, SysTime(DateTime(-2000, 1, 1, 23, 30, 33), d));
5391 testST(SysTime(DateTime(-2001, 2, 28, 23, 30, 33), d), 25, SysTime(DateTime(-2001, 2, 28, 0, 30, 33), d));
5392 testST(SysTime(DateTime(-2001, 3, 2, 0, 30, 33), d), -25, SysTime(DateTime(-2001, 3, 2, 23, 30, 33), d));
5394 testST(SysTime(DateTime(-2000, 2, 28, 23, 30, 33), d), 25, SysTime(DateTime(-2000, 2, 28, 0, 30, 33), d));
5395 testST(SysTime(DateTime(-2000, 3, 1, 0, 30, 33), d), -25, SysTime(DateTime(-2000, 3, 1, 23, 30, 33), d));
5397 // Test Both
5398 testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 17_546, SysTime(DateTime(-1, 1, 1, 13, 30, 33), d));
5399 testST(SysTime(DateTime(1, 1, 1, 13, 30, 33), d), -17_546, SysTime(DateTime(1, 1, 1, 11, 30, 33), d));
5402 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0));
5403 sysTime.roll!"hours"(-1);
5404 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 0, 0)));
5405 sysTime.roll!"hours"(1);
5406 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));
5410 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 59, 59), hnsecs(9_999_999));
5411 sysTime.roll!"hours"(-1);
5412 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));
5413 sysTime.roll!"hours"(1);
5414 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 59, 59), hnsecs(9_999_999)));
5418 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 0, 0));
5419 sysTime.roll!"hours"(1);
5420 assert(sysTime == SysTime(DateTime(0, 12, 31, 0, 0, 0)));
5421 sysTime.roll!"hours"(-1);
5422 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 0, 0)));
5426 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));
5427 sysTime.roll!"hours"(1);
5428 assert(sysTime == SysTime(DateTime(0, 12, 31, 0, 59, 59), hnsecs(9_999_999)));
5429 sysTime.roll!"hours"(-1);
5430 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));
5434 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));
5435 sysTime.roll!"hours"(1).roll!"hours"(-67);
5436 assert(sysTime == SysTime(DateTime(0, 12, 31, 5, 59, 59), hnsecs(9_999_999)));
5439 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
5440 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
5441 static assert(!__traits(compiles, cst.roll!"hours"(4)));
5442 static assert(!__traits(compiles, ist.roll!"hours"(4)));
5444 static void testScope(scope ref SysTime st) @safe
5446 auto result = st.roll!"hours"(42);
5450 // Test roll!"minutes"().
5451 @safe unittest
5453 import core.time;
5454 static void testST(SysTime orig, int minutes, SysTime expected, size_t line = __LINE__) @safe
5456 orig.roll!"minutes"(minutes);
5457 if (orig != expected)
5458 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line);
5461 // Test A.D.
5462 immutable d = usecs(7203);
5463 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), d);
5464 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));
5465 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 31, 33), d));
5466 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 32, 33), d));
5467 testST(beforeAD, 3, SysTime(DateTime(1999, 7, 6, 12, 33, 33), d));
5468 testST(beforeAD, 4, SysTime(DateTime(1999, 7, 6, 12, 34, 33), d));
5469 testST(beforeAD, 5, SysTime(DateTime(1999, 7, 6, 12, 35, 33), d));
5470 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 40, 33), d));
5471 testST(beforeAD, 15, SysTime(DateTime(1999, 7, 6, 12, 45, 33), d));
5472 testST(beforeAD, 29, SysTime(DateTime(1999, 7, 6, 12, 59, 33), d));
5473 testST(beforeAD, 30, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d));
5474 testST(beforeAD, 45, SysTime(DateTime(1999, 7, 6, 12, 15, 33), d));
5475 testST(beforeAD, 60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));
5476 testST(beforeAD, 75, SysTime(DateTime(1999, 7, 6, 12, 45, 33), d));
5477 testST(beforeAD, 90, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d));
5478 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 10, 33), d));
5480 testST(beforeAD, 689, SysTime(DateTime(1999, 7, 6, 12, 59, 33), d));
5481 testST(beforeAD, 690, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d));
5482 testST(beforeAD, 691, SysTime(DateTime(1999, 7, 6, 12, 1, 33), d));
5483 testST(beforeAD, 960, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));
5484 testST(beforeAD, 1439, SysTime(DateTime(1999, 7, 6, 12, 29, 33), d));
5485 testST(beforeAD, 1440, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));
5486 testST(beforeAD, 1441, SysTime(DateTime(1999, 7, 6, 12, 31, 33), d));
5487 testST(beforeAD, 2880, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));
5489 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 29, 33), d));
5490 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 28, 33), d));
5491 testST(beforeAD, -3, SysTime(DateTime(1999, 7, 6, 12, 27, 33), d));
5492 testST(beforeAD, -4, SysTime(DateTime(1999, 7, 6, 12, 26, 33), d));
5493 testST(beforeAD, -5, SysTime(DateTime(1999, 7, 6, 12, 25, 33), d));
5494 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 20, 33), d));
5495 testST(beforeAD, -15, SysTime(DateTime(1999, 7, 6, 12, 15, 33), d));
5496 testST(beforeAD, -29, SysTime(DateTime(1999, 7, 6, 12, 1, 33), d));
5497 testST(beforeAD, -30, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d));
5498 testST(beforeAD, -45, SysTime(DateTime(1999, 7, 6, 12, 45, 33), d));
5499 testST(beforeAD, -60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));
5500 testST(beforeAD, -75, SysTime(DateTime(1999, 7, 6, 12, 15, 33), d));
5501 testST(beforeAD, -90, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d));
5502 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 50, 33), d));
5504 testST(beforeAD, -749, SysTime(DateTime(1999, 7, 6, 12, 1, 33), d));
5505 testST(beforeAD, -750, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d));
5506 testST(beforeAD, -751, SysTime(DateTime(1999, 7, 6, 12, 59, 33), d));
5507 testST(beforeAD, -960, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));
5508 testST(beforeAD, -1439, SysTime(DateTime(1999, 7, 6, 12, 31, 33), d));
5509 testST(beforeAD, -1440, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));
5510 testST(beforeAD, -1441, SysTime(DateTime(1999, 7, 6, 12, 29, 33), d));
5511 testST(beforeAD, -2880, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));
5513 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 33), d), 1, SysTime(DateTime(1999, 7, 6, 12, 1, 33), d));
5514 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 33), d), 0, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d));
5515 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 33), d), -1, SysTime(DateTime(1999, 7, 6, 12, 59, 33), d));
5517 testST(SysTime(DateTime(1999, 7, 6, 11, 59, 33), d), 1, SysTime(DateTime(1999, 7, 6, 11, 0, 33), d));
5518 testST(SysTime(DateTime(1999, 7, 6, 11, 59, 33), d), 0, SysTime(DateTime(1999, 7, 6, 11, 59, 33), d));
5519 testST(SysTime(DateTime(1999, 7, 6, 11, 59, 33), d), -1, SysTime(DateTime(1999, 7, 6, 11, 58, 33), d));
5521 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 33), d), 1, SysTime(DateTime(1999, 7, 6, 0, 1, 33), d));
5522 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 33), d), 0, SysTime(DateTime(1999, 7, 6, 0, 0, 33), d));
5523 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 33), d), -1, SysTime(DateTime(1999, 7, 6, 0, 59, 33), d));
5525 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 33), d), 1, SysTime(DateTime(1999, 7, 5, 23, 0, 33), d));
5526 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 33), d), 0, SysTime(DateTime(1999, 7, 5, 23, 59, 33), d));
5527 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 33), d), -1, SysTime(DateTime(1999, 7, 5, 23, 58, 33), d));
5529 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 33), d), 1, SysTime(DateTime(1998, 12, 31, 23, 0, 33), d));
5530 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 33), d), 0, SysTime(DateTime(1998, 12, 31, 23, 59, 33), d));
5531 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 33), d), -1, SysTime(DateTime(1998, 12, 31, 23, 58, 33), d));
5533 // Test B.C.
5534 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d);
5535 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));
5536 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), d));
5537 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 32, 33), d));
5538 testST(beforeBC, 3, SysTime(DateTime(-1999, 7, 6, 12, 33, 33), d));
5539 testST(beforeBC, 4, SysTime(DateTime(-1999, 7, 6, 12, 34, 33), d));
5540 testST(beforeBC, 5, SysTime(DateTime(-1999, 7, 6, 12, 35, 33), d));
5541 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 40, 33), d));
5542 testST(beforeBC, 15, SysTime(DateTime(-1999, 7, 6, 12, 45, 33), d));
5543 testST(beforeBC, 29, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), d));
5544 testST(beforeBC, 30, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d));
5545 testST(beforeBC, 45, SysTime(DateTime(-1999, 7, 6, 12, 15, 33), d));
5546 testST(beforeBC, 60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));
5547 testST(beforeBC, 75, SysTime(DateTime(-1999, 7, 6, 12, 45, 33), d));
5548 testST(beforeBC, 90, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d));
5549 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 10, 33), d));
5551 testST(beforeBC, 689, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), d));
5552 testST(beforeBC, 690, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d));
5553 testST(beforeBC, 691, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), d));
5554 testST(beforeBC, 960, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));
5555 testST(beforeBC, 1439, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), d));
5556 testST(beforeBC, 1440, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));
5557 testST(beforeBC, 1441, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), d));
5558 testST(beforeBC, 2880, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));
5560 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), d));
5561 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 28, 33), d));
5562 testST(beforeBC, -3, SysTime(DateTime(-1999, 7, 6, 12, 27, 33), d));
5563 testST(beforeBC, -4, SysTime(DateTime(-1999, 7, 6, 12, 26, 33), d));
5564 testST(beforeBC, -5, SysTime(DateTime(-1999, 7, 6, 12, 25, 33), d));
5565 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 20, 33), d));
5566 testST(beforeBC, -15, SysTime(DateTime(-1999, 7, 6, 12, 15, 33), d));
5567 testST(beforeBC, -29, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), d));
5568 testST(beforeBC, -30, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d));
5569 testST(beforeBC, -45, SysTime(DateTime(-1999, 7, 6, 12, 45, 33), d));
5570 testST(beforeBC, -60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));
5571 testST(beforeBC, -75, SysTime(DateTime(-1999, 7, 6, 12, 15, 33), d));
5572 testST(beforeBC, -90, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d));
5573 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 50, 33), d));
5575 testST(beforeBC, -749, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), d));
5576 testST(beforeBC, -750, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d));
5577 testST(beforeBC, -751, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), d));
5578 testST(beforeBC, -960, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));
5579 testST(beforeBC, -1439, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), d));
5580 testST(beforeBC, -1440, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));
5581 testST(beforeBC, -1441, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), d));
5582 testST(beforeBC, -2880, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));
5584 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), d));
5585 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d));
5586 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), d));
5588 testST(SysTime(DateTime(-1999, 7, 6, 11, 59, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 11, 0, 33), d));
5589 testST(SysTime(DateTime(-1999, 7, 6, 11, 59, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 11, 59, 33), d));
5590 testST(SysTime(DateTime(-1999, 7, 6, 11, 59, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 11, 58, 33), d));
5592 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 0, 1, 33), d));
5593 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 0, 0, 33), d));
5594 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 0, 59, 33), d));
5596 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 33), d), 1, SysTime(DateTime(-1999, 7, 5, 23, 0, 33), d));
5597 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 33), d), 0, SysTime(DateTime(-1999, 7, 5, 23, 59, 33), d));
5598 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 33), d), -1, SysTime(DateTime(-1999, 7, 5, 23, 58, 33), d));
5600 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 33), d), 1, SysTime(DateTime(-2000, 12, 31, 23, 0, 33), d));
5601 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 33), d), 0, SysTime(DateTime(-2000, 12, 31, 23, 59, 33), d));
5602 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 33), d), -1, SysTime(DateTime(-2000, 12, 31, 23, 58, 33), d));
5604 // Test Both
5605 testST(SysTime(DateTime(1, 1, 1, 0, 0, 0)), -1, SysTime(DateTime(1, 1, 1, 0, 59, 0)));
5606 testST(SysTime(DateTime(0, 12, 31, 23, 59, 0)), 1, SysTime(DateTime(0, 12, 31, 23, 0, 0)));
5608 testST(SysTime(DateTime(0, 1, 1, 0, 0, 0)), -1, SysTime(DateTime(0, 1, 1, 0, 59, 0)));
5609 testST(SysTime(DateTime(-1, 12, 31, 23, 59, 0)), 1, SysTime(DateTime(-1, 12, 31, 23, 0, 0)));
5611 testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 1_052_760, SysTime(DateTime(-1, 1, 1, 11, 30, 33), d));
5612 testST(SysTime(DateTime(1, 1, 1, 13, 30, 33), d), -1_052_760, SysTime(DateTime(1, 1, 1, 13, 30, 33), d));
5614 testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 1_052_782, SysTime(DateTime(-1, 1, 1, 11, 52, 33), d));
5615 testST(SysTime(DateTime(1, 1, 1, 13, 52, 33), d), -1_052_782, SysTime(DateTime(1, 1, 1, 13, 30, 33), d));
5618 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0));
5619 sysTime.roll!"minutes"(-1);
5620 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 59, 0)));
5621 sysTime.roll!"minutes"(1);
5622 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));
5626 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 59), hnsecs(9_999_999));
5627 sysTime.roll!"minutes"(-1);
5628 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 59, 59), hnsecs(9_999_999)));
5629 sysTime.roll!"minutes"(1);
5630 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 59), hnsecs(9_999_999)));
5634 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 0));
5635 sysTime.roll!"minutes"(1);
5636 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 0, 0)));
5637 sysTime.roll!"minutes"(-1);
5638 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 0)));
5642 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));
5643 sysTime.roll!"minutes"(1);
5644 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 0, 59), hnsecs(9_999_999)));
5645 sysTime.roll!"minutes"(-1);
5646 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));
5650 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));
5651 sysTime.roll!"minutes"(1).roll!"minutes"(-79);
5652 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 41, 59), hnsecs(9_999_999)));
5655 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
5656 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
5657 static assert(!__traits(compiles, cst.roll!"minutes"(4)));
5658 static assert(!__traits(compiles, ist.roll!"minutes"(4)));
5660 static void testScope(scope ref SysTime st) @safe
5662 auto result = st.roll!"minutes"(42);
5666 // Test roll!"seconds"().
5667 @safe unittest
5669 import core.time;
5670 static void testST(SysTime orig, int seconds, SysTime expected, size_t line = __LINE__) @safe
5672 orig.roll!"seconds"(seconds);
5673 if (orig != expected)
5674 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line);
5677 // Test A.D.
5678 immutable d = msecs(274);
5679 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), d);
5680 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));
5681 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 34), d));
5682 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 35), d));
5683 testST(beforeAD, 3, SysTime(DateTime(1999, 7, 6, 12, 30, 36), d));
5684 testST(beforeAD, 4, SysTime(DateTime(1999, 7, 6, 12, 30, 37), d));
5685 testST(beforeAD, 5, SysTime(DateTime(1999, 7, 6, 12, 30, 38), d));
5686 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 43), d));
5687 testST(beforeAD, 15, SysTime(DateTime(1999, 7, 6, 12, 30, 48), d));
5688 testST(beforeAD, 26, SysTime(DateTime(1999, 7, 6, 12, 30, 59), d));
5689 testST(beforeAD, 27, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d));
5690 testST(beforeAD, 30, SysTime(DateTime(1999, 7, 6, 12, 30, 3), d));
5691 testST(beforeAD, 59, SysTime(DateTime(1999, 7, 6, 12, 30, 32), d));
5692 testST(beforeAD, 60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));
5693 testST(beforeAD, 61, SysTime(DateTime(1999, 7, 6, 12, 30, 34), d));
5695 testST(beforeAD, 1766, SysTime(DateTime(1999, 7, 6, 12, 30, 59), d));
5696 testST(beforeAD, 1767, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d));
5697 testST(beforeAD, 1768, SysTime(DateTime(1999, 7, 6, 12, 30, 1), d));
5698 testST(beforeAD, 2007, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d));
5699 testST(beforeAD, 3599, SysTime(DateTime(1999, 7, 6, 12, 30, 32), d));
5700 testST(beforeAD, 3600, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));
5701 testST(beforeAD, 3601, SysTime(DateTime(1999, 7, 6, 12, 30, 34), d));
5702 testST(beforeAD, 7200, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));
5704 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 32), d));
5705 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 31), d));
5706 testST(beforeAD, -3, SysTime(DateTime(1999, 7, 6, 12, 30, 30), d));
5707 testST(beforeAD, -4, SysTime(DateTime(1999, 7, 6, 12, 30, 29), d));
5708 testST(beforeAD, -5, SysTime(DateTime(1999, 7, 6, 12, 30, 28), d));
5709 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 23), d));
5710 testST(beforeAD, -15, SysTime(DateTime(1999, 7, 6, 12, 30, 18), d));
5711 testST(beforeAD, -33, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d));
5712 testST(beforeAD, -34, SysTime(DateTime(1999, 7, 6, 12, 30, 59), d));
5713 testST(beforeAD, -35, SysTime(DateTime(1999, 7, 6, 12, 30, 58), d));
5714 testST(beforeAD, -59, SysTime(DateTime(1999, 7, 6, 12, 30, 34), d));
5715 testST(beforeAD, -60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d));
5716 testST(beforeAD, -61, SysTime(DateTime(1999, 7, 6, 12, 30, 32), d));
5718 testST(SysTime(DateTime(1999, 7, 6, 12, 30, 0), d), 1, SysTime(DateTime(1999, 7, 6, 12, 30, 1), d));
5719 testST(SysTime(DateTime(1999, 7, 6, 12, 30, 0), d), 0, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d));
5720 testST(SysTime(DateTime(1999, 7, 6, 12, 30, 0), d), -1, SysTime(DateTime(1999, 7, 6, 12, 30, 59), d));
5722 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 0), d), 1, SysTime(DateTime(1999, 7, 6, 12, 0, 1), d));
5723 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 0), d), 0, SysTime(DateTime(1999, 7, 6, 12, 0, 0), d));
5724 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 0), d), -1, SysTime(DateTime(1999, 7, 6, 12, 0, 59), d));
5726 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 0), d), 1, SysTime(DateTime(1999, 7, 6, 0, 0, 1), d));
5727 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 0), d), 0, SysTime(DateTime(1999, 7, 6, 0, 0, 0), d));
5728 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 0), d), -1, SysTime(DateTime(1999, 7, 6, 0, 0, 59), d));
5730 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 59), d), 1, SysTime(DateTime(1999, 7, 5, 23, 59, 0), d));
5731 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 59), d), 0, SysTime(DateTime(1999, 7, 5, 23, 59, 59), d));
5732 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 59), d), -1, SysTime(DateTime(1999, 7, 5, 23, 59, 58), d));
5734 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 59), d), 1, SysTime(DateTime(1998, 12, 31, 23, 59, 0), d));
5735 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 59), d), 0, SysTime(DateTime(1998, 12, 31, 23, 59, 59), d));
5736 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 59), d), -1, SysTime(DateTime(1998, 12, 31, 23, 59, 58), d));
5738 // Test B.C.
5739 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d);
5740 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));
5741 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), d));
5742 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 35), d));
5743 testST(beforeBC, 3, SysTime(DateTime(-1999, 7, 6, 12, 30, 36), d));
5744 testST(beforeBC, 4, SysTime(DateTime(-1999, 7, 6, 12, 30, 37), d));
5745 testST(beforeBC, 5, SysTime(DateTime(-1999, 7, 6, 12, 30, 38), d));
5746 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 43), d));
5747 testST(beforeBC, 15, SysTime(DateTime(-1999, 7, 6, 12, 30, 48), d));
5748 testST(beforeBC, 26, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), d));
5749 testST(beforeBC, 27, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d));
5750 testST(beforeBC, 30, SysTime(DateTime(-1999, 7, 6, 12, 30, 3), d));
5751 testST(beforeBC, 59, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), d));
5752 testST(beforeBC, 60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));
5753 testST(beforeBC, 61, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), d));
5755 testST(beforeBC, 1766, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), d));
5756 testST(beforeBC, 1767, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d));
5757 testST(beforeBC, 1768, SysTime(DateTime(-1999, 7, 6, 12, 30, 1), d));
5758 testST(beforeBC, 2007, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d));
5759 testST(beforeBC, 3599, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), d));
5760 testST(beforeBC, 3600, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));
5761 testST(beforeBC, 3601, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), d));
5762 testST(beforeBC, 7200, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));
5764 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), d));
5765 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 31), d));
5766 testST(beforeBC, -3, SysTime(DateTime(-1999, 7, 6, 12, 30, 30), d));
5767 testST(beforeBC, -4, SysTime(DateTime(-1999, 7, 6, 12, 30, 29), d));
5768 testST(beforeBC, -5, SysTime(DateTime(-1999, 7, 6, 12, 30, 28), d));
5769 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 23), d));
5770 testST(beforeBC, -15, SysTime(DateTime(-1999, 7, 6, 12, 30, 18), d));
5771 testST(beforeBC, -33, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d));
5772 testST(beforeBC, -34, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), d));
5773 testST(beforeBC, -35, SysTime(DateTime(-1999, 7, 6, 12, 30, 58), d));
5774 testST(beforeBC, -59, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), d));
5775 testST(beforeBC, -60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d));
5776 testST(beforeBC, -61, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), d));
5778 testST(SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d), 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 1), d));
5779 testST(SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d), 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d));
5780 testST(SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d), -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), d));
5782 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 0), d), 1, SysTime(DateTime(-1999, 7, 6, 12, 0, 1), d));
5783 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 0), d), 0, SysTime(DateTime(-1999, 7, 6, 12, 0, 0), d));
5784 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 0), d), -1, SysTime(DateTime(-1999, 7, 6, 12, 0, 59), d));
5786 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 0), d), 1, SysTime(DateTime(-1999, 7, 6, 0, 0, 1), d));
5787 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 0), d), 0, SysTime(DateTime(-1999, 7, 6, 0, 0, 0), d));
5788 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 0), d), -1, SysTime(DateTime(-1999, 7, 6, 0, 0, 59), d));
5790 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 59), d), 1, SysTime(DateTime(-1999, 7, 5, 23, 59, 0), d));
5791 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 59), d), 0, SysTime(DateTime(-1999, 7, 5, 23, 59, 59), d));
5792 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 59), d), -1, SysTime(DateTime(-1999, 7, 5, 23, 59, 58), d));
5794 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 59), d), 1, SysTime(DateTime(-2000, 12, 31, 23, 59, 0), d));
5795 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 59), d), 0, SysTime(DateTime(-2000, 12, 31, 23, 59, 59), d));
5796 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 59), d), -1, SysTime(DateTime(-2000, 12, 31, 23, 59, 58), d));
5798 // Test Both
5799 testST(SysTime(DateTime(1, 1, 1, 0, 0, 0), d), -1, SysTime(DateTime(1, 1, 1, 0, 0, 59), d));
5800 testST(SysTime(DateTime(0, 12, 31, 23, 59, 59), d), 1, SysTime(DateTime(0, 12, 31, 23, 59, 0), d));
5802 testST(SysTime(DateTime(0, 1, 1, 0, 0, 0), d), -1, SysTime(DateTime(0, 1, 1, 0, 0, 59), d));
5803 testST(SysTime(DateTime(-1, 12, 31, 23, 59, 59), d), 1, SysTime(DateTime(-1, 12, 31, 23, 59, 0), d));
5805 testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 63_165_600L, SysTime(DateTime(-1, 1, 1, 11, 30, 33), d));
5806 testST(SysTime(DateTime(1, 1, 1, 13, 30, 33), d), -63_165_600L, SysTime(DateTime(1, 1, 1, 13, 30, 33), d));
5808 testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 63_165_617L, SysTime(DateTime(-1, 1, 1, 11, 30, 50), d));
5809 testST(SysTime(DateTime(1, 1, 1, 13, 30, 50), d), -63_165_617L, SysTime(DateTime(1, 1, 1, 13, 30, 33), d));
5812 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0));
5813 sysTime.roll!"seconds"(-1);
5814 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 59)));
5815 sysTime.roll!"seconds"(1);
5816 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0)));
5820 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(9_999_999));
5821 sysTime.roll!"seconds"(-1);
5822 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 59), hnsecs(9_999_999)));
5823 sysTime.roll!"seconds"(1);
5824 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(9_999_999)));
5828 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59));
5829 sysTime.roll!"seconds"(1);
5830 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 0)));
5831 sysTime.roll!"seconds"(-1);
5832 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59)));
5836 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));
5837 sysTime.roll!"seconds"(1);
5838 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 0), hnsecs(9_999_999)));
5839 sysTime.roll!"seconds"(-1);
5840 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));
5844 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));
5845 sysTime.roll!"seconds"(1).roll!"seconds"(-102);
5846 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 18), hnsecs(9_999_999)));
5849 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
5850 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
5851 static assert(!__traits(compiles, cst.roll!"seconds"(4)));
5852 static assert(!__traits(compiles, ist.roll!"seconds"(4)));
5854 static void testScope(scope ref SysTime st) @safe
5856 auto result = st.roll!"seconds"(42);
5861 // Shares documentation with "days" version.
5862 ref SysTime roll(string units)(long value) @safe nothrow scope
5863 if (units == "msecs" || units == "usecs" || units == "hnsecs")
5865 auto hnsecs = adjTime;
5866 immutable days = splitUnitsFromHNSecs!"days"(hnsecs);
5867 immutable negative = hnsecs < 0;
5869 if (negative)
5870 hnsecs += convert!("hours", "hnsecs")(24);
5872 immutable seconds = splitUnitsFromHNSecs!"seconds"(hnsecs);
5873 hnsecs += convert!(units, "hnsecs")(value);
5874 hnsecs %= convert!("seconds", "hnsecs")(1);
5876 if (hnsecs < 0)
5877 hnsecs += convert!("seconds", "hnsecs")(1);
5878 hnsecs += convert!("seconds", "hnsecs")(seconds);
5880 if (negative)
5881 hnsecs -= convert!("hours", "hnsecs")(24);
5883 immutable newDaysHNSecs = convert!("days", "hnsecs")(days);
5884 adjTime = newDaysHNSecs + hnsecs;
5885 return this;
5889 // Test roll!"msecs"().
5890 @safe unittest
5892 import core.time;
5893 static void testST(SysTime orig, int milliseconds, SysTime expected, size_t line = __LINE__) @safe
5895 orig.roll!"msecs"(milliseconds);
5896 if (orig != expected)
5897 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line);
5900 // Test A.D.
5901 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274));
5902 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274)));
5903 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(275)));
5904 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(276)));
5905 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(284)));
5906 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(374)));
5907 testST(beforeAD, 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999)));
5908 testST(beforeAD, 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
5909 testST(beforeAD, 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274)));
5910 testST(beforeAD, 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(275)));
5911 testST(beforeAD, 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274)));
5912 testST(beforeAD, 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999)));
5913 testST(beforeAD, 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
5914 testST(beforeAD, 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(1)));
5915 testST(beforeAD, 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999)));
5916 testST(beforeAD, 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
5918 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(273)));
5919 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(272)));
5920 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(264)));
5921 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(174)));
5922 testST(beforeAD, -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
5923 testST(beforeAD, -275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999)));
5924 testST(beforeAD, -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274)));
5925 testST(beforeAD, -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(273)));
5926 testST(beforeAD, -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274)));
5927 testST(beforeAD, -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
5928 testST(beforeAD, -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999)));
5929 testST(beforeAD, -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
5930 testST(beforeAD, -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999)));
5932 // Test B.C.
5933 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274));
5934 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274)));
5935 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(275)));
5936 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(276)));
5937 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(284)));
5938 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(374)));
5939 testST(beforeBC, 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999)));
5940 testST(beforeBC, 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));
5941 testST(beforeBC, 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274)));
5942 testST(beforeBC, 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(275)));
5943 testST(beforeBC, 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274)));
5944 testST(beforeBC, 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999)));
5945 testST(beforeBC, 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));
5946 testST(beforeBC, 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(1)));
5947 testST(beforeBC, 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999)));
5948 testST(beforeBC, 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));
5950 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(273)));
5951 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(272)));
5952 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(264)));
5953 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(174)));
5954 testST(beforeBC, -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));
5955 testST(beforeBC, -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999)));
5956 testST(beforeBC, -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274)));
5957 testST(beforeBC, -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(273)));
5958 testST(beforeBC, -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274)));
5959 testST(beforeBC, -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));
5960 testST(beforeBC, -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999)));
5961 testST(beforeBC, -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));
5962 testST(beforeBC, -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999)));
5964 // Test Both
5965 auto beforeBoth1 = SysTime(DateTime(1, 1, 1, 0, 0, 0));
5966 testST(beforeBoth1, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), msecs(1)));
5967 testST(beforeBoth1, 0, SysTime(DateTime(1, 1, 1, 0, 0, 0)));
5968 testST(beforeBoth1, -1, SysTime(DateTime(1, 1, 1, 0, 0, 0), msecs(999)));
5969 testST(beforeBoth1, -2, SysTime(DateTime(1, 1, 1, 0, 0, 0), msecs(998)));
5970 testST(beforeBoth1, -1000, SysTime(DateTime(1, 1, 1, 0, 0, 0)));
5971 testST(beforeBoth1, -2000, SysTime(DateTime(1, 1, 1, 0, 0, 0)));
5972 testST(beforeBoth1, -2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), msecs(445)));
5974 auto beforeBoth2 = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));
5975 testST(beforeBoth2, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_989_999)));
5976 testST(beforeBoth2, 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));
5977 testST(beforeBoth2, 1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9999)));
5978 testST(beforeBoth2, 2, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(19_999)));
5979 testST(beforeBoth2, 1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));
5980 testST(beforeBoth2, 2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));
5981 testST(beforeBoth2, 2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(5_549_999)));
5984 auto st = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));
5985 st.roll!"msecs"(1202).roll!"msecs"(-703);
5986 assert(st == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(4_989_999)));
5989 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
5990 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
5991 static assert(!__traits(compiles, cst.roll!"msecs"(4)));
5992 static assert(!__traits(compiles, ist.roll!"msecs"(4)));
5994 static void testScope(scope ref SysTime st) @safe
5996 auto result = st.roll!"msecs"(42);
6000 // Test roll!"usecs"().
6001 @safe unittest
6003 import core.time;
6004 static void testST(SysTime orig, long microseconds, SysTime expected, size_t line = __LINE__) @safe
6006 orig.roll!"usecs"(microseconds);
6007 if (orig != expected)
6008 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line);
6011 // Test A.D.
6012 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274));
6013 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274)));
6014 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(275)));
6015 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(276)));
6016 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(284)));
6017 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(374)));
6018 testST(beforeAD, 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(999)));
6019 testST(beforeAD, 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(1000)));
6020 testST(beforeAD, 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(1274)));
6021 testST(beforeAD, 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(1275)));
6022 testST(beforeAD, 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(2274)));
6023 testST(beforeAD, 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(26_999)));
6024 testST(beforeAD, 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(27_000)));
6025 testST(beforeAD, 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(27_001)));
6026 testST(beforeAD, 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(766_999)));
6027 testST(beforeAD, 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(767_000)));
6028 testST(beforeAD, 1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274)));
6029 testST(beforeAD, 60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274)));
6030 testST(beforeAD, 3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274)));
6032 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(273)));
6033 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(272)));
6034 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(264)));
6035 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(174)));
6036 testST(beforeAD, -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
6037 testST(beforeAD, -275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(999_999)));
6038 testST(beforeAD, -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(999_274)));
6039 testST(beforeAD, -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(999_273)));
6040 testST(beforeAD, -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(998_274)));
6041 testST(beforeAD, -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(967_000)));
6042 testST(beforeAD, -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(966_999)));
6043 testST(beforeAD, -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(167_000)));
6044 testST(beforeAD, -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(166_999)));
6045 testST(beforeAD, -1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274)));
6046 testST(beforeAD, -60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274)));
6047 testST(beforeAD, -3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274)));
6049 // Test B.C.
6050 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274));
6051 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274)));
6052 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(275)));
6053 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(276)));
6054 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(284)));
6055 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(374)));
6056 testST(beforeBC, 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(999)));
6057 testST(beforeBC, 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(1000)));
6058 testST(beforeBC, 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(1274)));
6059 testST(beforeBC, 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(1275)));
6060 testST(beforeBC, 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(2274)));
6061 testST(beforeBC, 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(26_999)));
6062 testST(beforeBC, 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(27_000)));
6063 testST(beforeBC, 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(27_001)));
6064 testST(beforeBC, 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(766_999)));
6065 testST(beforeBC, 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(767_000)));
6066 testST(beforeBC, 1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274)));
6067 testST(beforeBC, 60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274)));
6068 testST(beforeBC, 3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274)));
6070 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(273)));
6071 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(272)));
6072 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(264)));
6073 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(174)));
6074 testST(beforeBC, -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));
6075 testST(beforeBC, -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(999_999)));
6076 testST(beforeBC, -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(999_274)));
6077 testST(beforeBC, -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(999_273)));
6078 testST(beforeBC, -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(998_274)));
6079 testST(beforeBC, -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(967_000)));
6080 testST(beforeBC, -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(966_999)));
6081 testST(beforeBC, -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(167_000)));
6082 testST(beforeBC, -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(166_999)));
6083 testST(beforeBC, -1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274)));
6084 testST(beforeBC, -60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274)));
6085 testST(beforeBC, -3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274)));
6087 // Test Both
6088 auto beforeBoth1 = SysTime(DateTime(1, 1, 1, 0, 0, 0));
6089 testST(beforeBoth1, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(1)));
6090 testST(beforeBoth1, 0, SysTime(DateTime(1, 1, 1, 0, 0, 0)));
6091 testST(beforeBoth1, -1, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(999_999)));
6092 testST(beforeBoth1, -2, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(999_998)));
6093 testST(beforeBoth1, -1000, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(999_000)));
6094 testST(beforeBoth1, -2000, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(998_000)));
6095 testST(beforeBoth1, -2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(997_445)));
6096 testST(beforeBoth1, -1_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0)));
6097 testST(beforeBoth1, -2_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0)));
6098 testST(beforeBoth1, -2_333_333, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(666_667)));
6100 auto beforeBoth2 = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));
6101 testST(beforeBoth2, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_989)));
6102 testST(beforeBoth2, 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));
6103 testST(beforeBoth2, 1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9)));
6104 testST(beforeBoth2, 2, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(19)));
6105 testST(beforeBoth2, 1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9999)));
6106 testST(beforeBoth2, 2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(19_999)));
6107 testST(beforeBoth2, 2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(25_549)));
6108 testST(beforeBoth2, 1_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));
6109 testST(beforeBoth2, 2_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));
6110 testST(beforeBoth2, 2_333_333, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(3_333_329)));
6113 auto st = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));
6114 st.roll!"usecs"(9_020_027);
6115 assert(st == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(200_269)));
6119 auto st = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));
6120 st.roll!"usecs"(9_020_027).roll!"usecs"(-70_034);
6121 assert(st == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_499_929)));
6124 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
6125 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
6126 static assert(!__traits(compiles, cst.roll!"usecs"(4)));
6127 static assert(!__traits(compiles, ist.roll!"usecs"(4)));
6129 static void testScope(scope ref SysTime st) @safe
6131 auto result = st.roll!"usecs"(42);
6135 // Test roll!"hnsecs"().
6136 @safe unittest
6138 import core.time;
6139 static void testST(SysTime orig, long hnsecs, SysTime expected, size_t line = __LINE__) @safe
6141 orig.roll!"hnsecs"(hnsecs);
6142 if (orig != expected)
6143 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line);
6146 // Test A.D.
6147 auto dtAD = DateTime(1999, 7, 6, 12, 30, 33);
6148 auto beforeAD = SysTime(dtAD, hnsecs(274));
6149 testST(beforeAD, 0, SysTime(dtAD, hnsecs(274)));
6150 testST(beforeAD, 1, SysTime(dtAD, hnsecs(275)));
6151 testST(beforeAD, 2, SysTime(dtAD, hnsecs(276)));
6152 testST(beforeAD, 10, SysTime(dtAD, hnsecs(284)));
6153 testST(beforeAD, 100, SysTime(dtAD, hnsecs(374)));
6154 testST(beforeAD, 725, SysTime(dtAD, hnsecs(999)));
6155 testST(beforeAD, 726, SysTime(dtAD, hnsecs(1000)));
6156 testST(beforeAD, 1000, SysTime(dtAD, hnsecs(1274)));
6157 testST(beforeAD, 1001, SysTime(dtAD, hnsecs(1275)));
6158 testST(beforeAD, 2000, SysTime(dtAD, hnsecs(2274)));
6159 testST(beforeAD, 26_725, SysTime(dtAD, hnsecs(26_999)));
6160 testST(beforeAD, 26_726, SysTime(dtAD, hnsecs(27_000)));
6161 testST(beforeAD, 26_727, SysTime(dtAD, hnsecs(27_001)));
6162 testST(beforeAD, 1_766_725, SysTime(dtAD, hnsecs(1_766_999)));
6163 testST(beforeAD, 1_766_726, SysTime(dtAD, hnsecs(1_767_000)));
6164 testST(beforeAD, 1_000_000, SysTime(dtAD, hnsecs(1_000_274)));
6165 testST(beforeAD, 60_000_000L, SysTime(dtAD, hnsecs(274)));
6166 testST(beforeAD, 3_600_000_000L, SysTime(dtAD, hnsecs(274)));
6167 testST(beforeAD, 600_000_000L, SysTime(dtAD, hnsecs(274)));
6168 testST(beforeAD, 36_000_000_000L, SysTime(dtAD, hnsecs(274)));
6170 testST(beforeAD, -1, SysTime(dtAD, hnsecs(273)));
6171 testST(beforeAD, -2, SysTime(dtAD, hnsecs(272)));
6172 testST(beforeAD, -10, SysTime(dtAD, hnsecs(264)));
6173 testST(beforeAD, -100, SysTime(dtAD, hnsecs(174)));
6174 testST(beforeAD, -274, SysTime(dtAD));
6175 testST(beforeAD, -275, SysTime(dtAD, hnsecs(9_999_999)));
6176 testST(beforeAD, -1000, SysTime(dtAD, hnsecs(9_999_274)));
6177 testST(beforeAD, -1001, SysTime(dtAD, hnsecs(9_999_273)));
6178 testST(beforeAD, -2000, SysTime(dtAD, hnsecs(9_998_274)));
6179 testST(beforeAD, -33_274, SysTime(dtAD, hnsecs(9_967_000)));
6180 testST(beforeAD, -33_275, SysTime(dtAD, hnsecs(9_966_999)));
6181 testST(beforeAD, -1_833_274, SysTime(dtAD, hnsecs(8_167_000)));
6182 testST(beforeAD, -1_833_275, SysTime(dtAD, hnsecs(8_166_999)));
6183 testST(beforeAD, -1_000_000, SysTime(dtAD, hnsecs(9_000_274)));
6184 testST(beforeAD, -60_000_000L, SysTime(dtAD, hnsecs(274)));
6185 testST(beforeAD, -3_600_000_000L, SysTime(dtAD, hnsecs(274)));
6186 testST(beforeAD, -600_000_000L, SysTime(dtAD, hnsecs(274)));
6187 testST(beforeAD, -36_000_000_000L, SysTime(dtAD, hnsecs(274)));
6189 // Test B.C.
6190 auto dtBC = DateTime(-1999, 7, 6, 12, 30, 33);
6191 auto beforeBC = SysTime(dtBC, hnsecs(274));
6192 testST(beforeBC, 0, SysTime(dtBC, hnsecs(274)));
6193 testST(beforeBC, 1, SysTime(dtBC, hnsecs(275)));
6194 testST(beforeBC, 2, SysTime(dtBC, hnsecs(276)));
6195 testST(beforeBC, 10, SysTime(dtBC, hnsecs(284)));
6196 testST(beforeBC, 100, SysTime(dtBC, hnsecs(374)));
6197 testST(beforeBC, 725, SysTime(dtBC, hnsecs(999)));
6198 testST(beforeBC, 726, SysTime(dtBC, hnsecs(1000)));
6199 testST(beforeBC, 1000, SysTime(dtBC, hnsecs(1274)));
6200 testST(beforeBC, 1001, SysTime(dtBC, hnsecs(1275)));
6201 testST(beforeBC, 2000, SysTime(dtBC, hnsecs(2274)));
6202 testST(beforeBC, 26_725, SysTime(dtBC, hnsecs(26_999)));
6203 testST(beforeBC, 26_726, SysTime(dtBC, hnsecs(27_000)));
6204 testST(beforeBC, 26_727, SysTime(dtBC, hnsecs(27_001)));
6205 testST(beforeBC, 1_766_725, SysTime(dtBC, hnsecs(1_766_999)));
6206 testST(beforeBC, 1_766_726, SysTime(dtBC, hnsecs(1_767_000)));
6207 testST(beforeBC, 1_000_000, SysTime(dtBC, hnsecs(1_000_274)));
6208 testST(beforeBC, 60_000_000L, SysTime(dtBC, hnsecs(274)));
6209 testST(beforeBC, 3_600_000_000L, SysTime(dtBC, hnsecs(274)));
6210 testST(beforeBC, 600_000_000L, SysTime(dtBC, hnsecs(274)));
6211 testST(beforeBC, 36_000_000_000L, SysTime(dtBC, hnsecs(274)));
6213 testST(beforeBC, -1, SysTime(dtBC, hnsecs(273)));
6214 testST(beforeBC, -2, SysTime(dtBC, hnsecs(272)));
6215 testST(beforeBC, -10, SysTime(dtBC, hnsecs(264)));
6216 testST(beforeBC, -100, SysTime(dtBC, hnsecs(174)));
6217 testST(beforeBC, -274, SysTime(dtBC));
6218 testST(beforeBC, -275, SysTime(dtBC, hnsecs(9_999_999)));
6219 testST(beforeBC, -1000, SysTime(dtBC, hnsecs(9_999_274)));
6220 testST(beforeBC, -1001, SysTime(dtBC, hnsecs(9_999_273)));
6221 testST(beforeBC, -2000, SysTime(dtBC, hnsecs(9_998_274)));
6222 testST(beforeBC, -33_274, SysTime(dtBC, hnsecs(9_967_000)));
6223 testST(beforeBC, -33_275, SysTime(dtBC, hnsecs(9_966_999)));
6224 testST(beforeBC, -1_833_274, SysTime(dtBC, hnsecs(8_167_000)));
6225 testST(beforeBC, -1_833_275, SysTime(dtBC, hnsecs(8_166_999)));
6226 testST(beforeBC, -1_000_000, SysTime(dtBC, hnsecs(9_000_274)));
6227 testST(beforeBC, -60_000_000L, SysTime(dtBC, hnsecs(274)));
6228 testST(beforeBC, -3_600_000_000L, SysTime(dtBC, hnsecs(274)));
6229 testST(beforeBC, -600_000_000L, SysTime(dtBC, hnsecs(274)));
6230 testST(beforeBC, -36_000_000_000L, SysTime(dtBC, hnsecs(274)));
6232 // Test Both
6233 auto dtBoth1 = DateTime(1, 1, 1, 0, 0, 0);
6234 auto beforeBoth1 = SysTime(dtBoth1);
6235 testST(beforeBoth1, 1, SysTime(dtBoth1, hnsecs(1)));
6236 testST(beforeBoth1, 0, SysTime(dtBoth1));
6237 testST(beforeBoth1, -1, SysTime(dtBoth1, hnsecs(9_999_999)));
6238 testST(beforeBoth1, -2, SysTime(dtBoth1, hnsecs(9_999_998)));
6239 testST(beforeBoth1, -1000, SysTime(dtBoth1, hnsecs(9_999_000)));
6240 testST(beforeBoth1, -2000, SysTime(dtBoth1, hnsecs(9_998_000)));
6241 testST(beforeBoth1, -2555, SysTime(dtBoth1, hnsecs(9_997_445)));
6242 testST(beforeBoth1, -1_000_000, SysTime(dtBoth1, hnsecs(9_000_000)));
6243 testST(beforeBoth1, -2_000_000, SysTime(dtBoth1, hnsecs(8_000_000)));
6244 testST(beforeBoth1, -2_333_333, SysTime(dtBoth1, hnsecs(7_666_667)));
6245 testST(beforeBoth1, -10_000_000, SysTime(dtBoth1));
6246 testST(beforeBoth1, -20_000_000, SysTime(dtBoth1));
6247 testST(beforeBoth1, -20_888_888, SysTime(dtBoth1, hnsecs(9_111_112)));
6249 auto dtBoth2 = DateTime(0, 12, 31, 23, 59, 59);
6250 auto beforeBoth2 = SysTime(dtBoth2, hnsecs(9_999_999));
6251 testST(beforeBoth2, -1, SysTime(dtBoth2, hnsecs(9_999_998)));
6252 testST(beforeBoth2, 0, SysTime(dtBoth2, hnsecs(9_999_999)));
6253 testST(beforeBoth2, 1, SysTime(dtBoth2));
6254 testST(beforeBoth2, 2, SysTime(dtBoth2, hnsecs(1)));
6255 testST(beforeBoth2, 1000, SysTime(dtBoth2, hnsecs(999)));
6256 testST(beforeBoth2, 2000, SysTime(dtBoth2, hnsecs(1999)));
6257 testST(beforeBoth2, 2555, SysTime(dtBoth2, hnsecs(2554)));
6258 testST(beforeBoth2, 1_000_000, SysTime(dtBoth2, hnsecs(999_999)));
6259 testST(beforeBoth2, 2_000_000, SysTime(dtBoth2, hnsecs(1_999_999)));
6260 testST(beforeBoth2, 2_333_333, SysTime(dtBoth2, hnsecs(2_333_332)));
6261 testST(beforeBoth2, 10_000_000, SysTime(dtBoth2, hnsecs(9_999_999)));
6262 testST(beforeBoth2, 20_000_000, SysTime(dtBoth2, hnsecs(9_999_999)));
6263 testST(beforeBoth2, 20_888_888, SysTime(dtBoth2, hnsecs(888_887)));
6266 auto st = SysTime(dtBoth2, hnsecs(9_999_999));
6267 st.roll!"hnsecs"(70_777_222).roll!"hnsecs"(-222_555_292);
6268 assert(st == SysTime(dtBoth2, hnsecs(8_221_929)));
6271 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
6272 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
6273 static assert(!__traits(compiles, cst.roll!"hnsecs"(4)));
6274 static assert(!__traits(compiles, ist.roll!"hnsecs"(4)));
6276 static void testScope(scope ref SysTime st) @safe
6278 auto result = st.roll!"hnsecs"(42);
6284 Gives the result of adding or subtracting a $(REF Duration, core,time)
6285 from this $(LREF SysTime).
6287 The legal types of arithmetic for $(LREF SysTime) using this operator
6290 $(BOOKTABLE,
6291 $(TR $(TD SysTime) $(TD +) $(TD Duration) $(TD -->) $(TD SysTime))
6292 $(TR $(TD SysTime) $(TD -) $(TD Duration) $(TD -->) $(TD SysTime))
6295 Params:
6296 duration = The $(REF Duration, core,time) to add to or subtract from
6297 this $(LREF SysTime).
6299 SysTime opBinary(string op)(Duration duration) @safe const pure nothrow return scope
6300 if (op == "+" || op == "-")
6302 SysTime retval = SysTime(this._stdTime, this._timezone);
6303 immutable hnsecs = duration.total!"hnsecs";
6304 mixin("retval._stdTime " ~ op ~ "= hnsecs;");
6305 return retval;
6309 @safe unittest
6311 import core.time : hours, seconds;
6312 import std.datetime.date : DateTime;
6314 assert(SysTime(DateTime(2015, 12, 31, 23, 59, 59)) + seconds(1) ==
6315 SysTime(DateTime(2016, 1, 1, 0, 0, 0)));
6317 assert(SysTime(DateTime(2015, 12, 31, 23, 59, 59)) + hours(1) ==
6318 SysTime(DateTime(2016, 1, 1, 0, 59, 59)));
6320 assert(SysTime(DateTime(2016, 1, 1, 0, 0, 0)) - seconds(1) ==
6321 SysTime(DateTime(2015, 12, 31, 23, 59, 59)));
6323 assert(SysTime(DateTime(2016, 1, 1, 0, 59, 59)) - hours(1) ==
6324 SysTime(DateTime(2015, 12, 31, 23, 59, 59)));
6327 @safe unittest
6329 import core.time;
6330 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_678));
6332 assert(st + dur!"weeks"(7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33), hnsecs(2_345_678)));
6333 assert(st + dur!"weeks"(-7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33), hnsecs(2_345_678)));
6334 assert(st + dur!"days"(7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33), hnsecs(2_345_678)));
6335 assert(st + dur!"days"(-7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33), hnsecs(2_345_678)));
6336 assert(st + dur!"hours"(7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33), hnsecs(2_345_678)));
6337 assert(st + dur!"hours"(-7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33), hnsecs(2_345_678)));
6338 assert(st + dur!"minutes"(7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33), hnsecs(2_345_678)));
6339 assert(st + dur!"minutes"(-7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33), hnsecs(2_345_678)));
6340 assert(st + dur!"seconds"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40), hnsecs(2_345_678)));
6341 assert(st + dur!"seconds"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26), hnsecs(2_345_678)));
6342 assert(st + dur!"msecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_415_678)));
6343 assert(st + dur!"msecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_275_678)));
6344 assert(st + dur!"usecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_748)));
6345 assert(st + dur!"usecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_608)));
6346 assert(st + dur!"hnsecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_685)));
6347 assert(st + dur!"hnsecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_671)));
6349 assert(st - dur!"weeks"(-7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33), hnsecs(2_345_678)));
6350 assert(st - dur!"weeks"(7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33), hnsecs(2_345_678)));
6351 assert(st - dur!"days"(-7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33), hnsecs(2_345_678)));
6352 assert(st - dur!"days"(7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33), hnsecs(2_345_678)));
6353 assert(st - dur!"hours"(-7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33), hnsecs(2_345_678)));
6354 assert(st - dur!"hours"(7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33), hnsecs(2_345_678)));
6355 assert(st - dur!"minutes"(-7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33), hnsecs(2_345_678)));
6356 assert(st - dur!"minutes"(7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33), hnsecs(2_345_678)));
6357 assert(st - dur!"seconds"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40), hnsecs(2_345_678)));
6358 assert(st - dur!"seconds"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26), hnsecs(2_345_678)));
6359 assert(st - dur!"msecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_415_678)));
6360 assert(st - dur!"msecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_275_678)));
6361 assert(st - dur!"usecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_748)));
6362 assert(st - dur!"usecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_608)));
6363 assert(st - dur!"hnsecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_685)));
6364 assert(st - dur!"hnsecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_671)));
6366 static void testST(SysTime orig, long hnsecs, SysTime expected, size_t line = __LINE__) @safe
6368 auto result = orig + dur!"hnsecs"(hnsecs);
6369 if (result != expected)
6370 throw new AssertError(format("Failed. actual [%s] != expected [%s]", result, expected), __FILE__, line);
6373 // Test A.D.
6374 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274));
6375 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274)));
6376 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(275)));
6377 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(276)));
6378 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(284)));
6379 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(374)));
6380 testST(beforeAD, 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(999)));
6381 testST(beforeAD, 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1000)));
6382 testST(beforeAD, 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1274)));
6383 testST(beforeAD, 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1275)));
6384 testST(beforeAD, 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2274)));
6385 testST(beforeAD, 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(26_999)));
6386 testST(beforeAD, 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_000)));
6387 testST(beforeAD, 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_001)));
6388 testST(beforeAD, 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_766_999)));
6389 testST(beforeAD, 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_767_000)));
6390 testST(beforeAD, 1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_000_274)));
6391 testST(beforeAD, 60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 39), hnsecs(274)));
6392 testST(beforeAD, 3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 36, 33), hnsecs(274)));
6393 testST(beforeAD, 600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 31, 33), hnsecs(274)));
6394 testST(beforeAD, 36_000_000_000L, SysTime(DateTime(1999, 7, 6, 13, 30, 33), hnsecs(274)));
6396 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(273)));
6397 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(272)));
6398 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(264)));
6399 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(174)));
6400 testST(beforeAD, -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
6401 testST(beforeAD, -275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_999)));
6402 testST(beforeAD, -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_274)));
6403 testST(beforeAD, -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_273)));
6404 testST(beforeAD, -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_998_274)));
6405 testST(beforeAD, -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_967_000)));
6406 testST(beforeAD, -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_966_999)));
6407 testST(beforeAD, -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_167_000)));
6408 testST(beforeAD, -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_166_999)));
6409 testST(beforeAD, -1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_000_274)));
6410 testST(beforeAD, -60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 27), hnsecs(274)));
6411 testST(beforeAD, -3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 24, 33), hnsecs(274)));
6412 testST(beforeAD, -600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 29, 33), hnsecs(274)));
6413 testST(beforeAD, -36_000_000_000L, SysTime(DateTime(1999, 7, 6, 11, 30, 33), hnsecs(274)));
6415 // Test B.C.
6416 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274));
6417 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274)));
6418 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(275)));
6419 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(276)));
6420 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(284)));
6421 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(374)));
6422 testST(beforeBC, 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(999)));
6423 testST(beforeBC, 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1000)));
6424 testST(beforeBC, 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1274)));
6425 testST(beforeBC, 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1275)));
6426 testST(beforeBC, 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(2274)));
6427 testST(beforeBC, 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(26_999)));
6428 testST(beforeBC, 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_000)));
6429 testST(beforeBC, 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_001)));
6430 testST(beforeBC, 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_766_999)));
6431 testST(beforeBC, 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_767_000)));
6432 testST(beforeBC, 1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_000_274)));
6433 testST(beforeBC, 60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 39), hnsecs(274)));
6434 testST(beforeBC, 3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 36, 33), hnsecs(274)));
6435 testST(beforeBC, 600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), hnsecs(274)));
6436 testST(beforeBC, 36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), hnsecs(274)));
6438 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(273)));
6439 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(272)));
6440 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(264)));
6441 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(174)));
6442 testST(beforeBC, -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));
6443 testST(beforeBC, -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_999)));
6444 testST(beforeBC, -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_274)));
6445 testST(beforeBC, -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_273)));
6446 testST(beforeBC, -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_998_274)));
6447 testST(beforeBC, -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_967_000)));
6448 testST(beforeBC, -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_966_999)));
6449 testST(beforeBC, -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_167_000)));
6450 testST(beforeBC, -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_166_999)));
6451 testST(beforeBC, -1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_000_274)));
6452 testST(beforeBC, -60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 27), hnsecs(274)));
6453 testST(beforeBC, -3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 24, 33), hnsecs(274)));
6454 testST(beforeBC, -600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), hnsecs(274)));
6455 testST(beforeBC, -36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), hnsecs(274)));
6457 // Test Both
6458 auto beforeBoth1 = SysTime(DateTime(1, 1, 1, 0, 0, 0));
6459 testST(beforeBoth1, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1)));
6460 testST(beforeBoth1, 0, SysTime(DateTime(1, 1, 1, 0, 0, 0)));
6461 testST(beforeBoth1, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));
6462 testST(beforeBoth1, -2, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998)));
6463 testST(beforeBoth1, -1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_000)));
6464 testST(beforeBoth1, -2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_998_000)));
6465 testST(beforeBoth1, -2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_997_445)));
6466 testST(beforeBoth1, -1_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_000_000)));
6467 testST(beforeBoth1, -2_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(8_000_000)));
6468 testST(beforeBoth1, -2_333_333, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(7_666_667)));
6469 testST(beforeBoth1, -10_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59)));
6470 testST(beforeBoth1, -20_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 58)));
6471 testST(beforeBoth1, -20_888_888, SysTime(DateTime(0, 12, 31, 23, 59, 57), hnsecs(9_111_112)));
6473 auto beforeBoth2 = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));
6474 testST(beforeBoth2, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998)));
6475 testST(beforeBoth2, 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));
6476 testST(beforeBoth2, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0)));
6477 testST(beforeBoth2, 2, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1)));
6478 testST(beforeBoth2, 1000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999)));
6479 testST(beforeBoth2, 2000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1999)));
6480 testST(beforeBoth2, 2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2554)));
6481 testST(beforeBoth2, 1_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999_999)));
6482 testST(beforeBoth2, 2_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1_999_999)));
6483 testST(beforeBoth2, 2_333_333, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2_333_332)));
6484 testST(beforeBoth2, 10_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(9_999_999)));
6485 testST(beforeBoth2, 20_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 1), hnsecs(9_999_999)));
6486 testST(beforeBoth2, 20_888_888, SysTime(DateTime(1, 1, 1, 0, 0, 2), hnsecs(888_887)));
6488 auto duration = dur!"seconds"(12);
6489 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
6490 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
6491 assert(cst + duration == SysTime(DateTime(1999, 7, 6, 12, 30, 45)));
6492 assert(ist + duration == SysTime(DateTime(1999, 7, 6, 12, 30, 45)));
6493 assert(cst - duration == SysTime(DateTime(1999, 7, 6, 12, 30, 21)));
6494 assert(ist - duration == SysTime(DateTime(1999, 7, 6, 12, 30, 21)));
6496 static void testScope(scope ref SysTime st, scope ref Duration d) @safe
6498 auto result = st + d;
6504 Gives the result of adding or subtracting a $(REF Duration, core,time) from
6505 this $(LREF SysTime), as well as assigning the result to this
6506 $(LREF SysTime).
6508 The legal types of arithmetic for $(LREF SysTime) using this operator are
6510 $(BOOKTABLE,
6511 $(TR $(TD SysTime) $(TD +) $(TD Duration) $(TD -->) $(TD SysTime))
6512 $(TR $(TD SysTime) $(TD -) $(TD Duration) $(TD -->) $(TD SysTime))
6515 Params:
6516 duration = The $(REF Duration, core,time) to add to or subtract from
6517 this $(LREF SysTime).
6519 ref SysTime opOpAssign(string op)(Duration duration) @safe pure nothrow scope
6520 if (op == "+" || op == "-")
6522 immutable hnsecs = duration.total!"hnsecs";
6523 mixin("_stdTime " ~ op ~ "= hnsecs;");
6524 return this;
6527 @safe unittest
6529 import core.time;
6530 auto before = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
6531 assert(before + dur!"weeks"(7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33)));
6532 assert(before + dur!"weeks"(-7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33)));
6533 assert(before + dur!"days"(7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33)));
6534 assert(before + dur!"days"(-7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33)));
6536 assert(before + dur!"hours"(7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33)));
6537 assert(before + dur!"hours"(-7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33)));
6538 assert(before + dur!"minutes"(7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33)));
6539 assert(before + dur!"minutes"(-7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33)));
6540 assert(before + dur!"seconds"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40)));
6541 assert(before + dur!"seconds"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26)));
6542 assert(before + dur!"msecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(7)));
6543 assert(before + dur!"msecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), msecs(993)));
6544 assert(before + dur!"usecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(7)));
6545 assert(before + dur!"usecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), usecs(999_993)));
6546 assert(before + dur!"hnsecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(7)));
6547 assert(before + dur!"hnsecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_993)));
6549 assert(before - dur!"weeks"(-7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33)));
6550 assert(before - dur!"weeks"(7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33)));
6551 assert(before - dur!"days"(-7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33)));
6552 assert(before - dur!"days"(7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33)));
6554 assert(before - dur!"hours"(-7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33)));
6555 assert(before - dur!"hours"(7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33)));
6556 assert(before - dur!"minutes"(-7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33)));
6557 assert(before - dur!"minutes"(7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33)));
6558 assert(before - dur!"seconds"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40)));
6559 assert(before - dur!"seconds"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26)));
6560 assert(before - dur!"msecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(7)));
6561 assert(before - dur!"msecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), msecs(993)));
6562 assert(before - dur!"usecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(7)));
6563 assert(before - dur!"usecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), usecs(999_993)));
6564 assert(before - dur!"hnsecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(7)));
6565 assert(before - dur!"hnsecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_993)));
6567 static void testST(SysTime orig, long hnsecs, SysTime expected, size_t line = __LINE__) @safe
6569 auto r = orig += dur!"hnsecs"(hnsecs);
6570 if (orig != expected)
6571 throw new AssertError(format("Failed 1. actual [%s] != expected [%s]", orig, expected), __FILE__, line);
6572 if (r != expected)
6573 throw new AssertError(format("Failed 2. actual [%s] != expected [%s]", r, expected), __FILE__, line);
6576 // Test A.D.
6577 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274));
6578 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274)));
6579 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(275)));
6580 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(276)));
6581 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(284)));
6582 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(374)));
6583 testST(beforeAD, 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(999)));
6584 testST(beforeAD, 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1000)));
6585 testST(beforeAD, 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1274)));
6586 testST(beforeAD, 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1275)));
6587 testST(beforeAD, 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2274)));
6588 testST(beforeAD, 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(26_999)));
6589 testST(beforeAD, 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_000)));
6590 testST(beforeAD, 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_001)));
6591 testST(beforeAD, 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_766_999)));
6592 testST(beforeAD, 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_767_000)));
6593 testST(beforeAD, 1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_000_274)));
6594 testST(beforeAD, 60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 39), hnsecs(274)));
6595 testST(beforeAD, 3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 36, 33), hnsecs(274)));
6596 testST(beforeAD, 600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 31, 33), hnsecs(274)));
6597 testST(beforeAD, 36_000_000_000L, SysTime(DateTime(1999, 7, 6, 13, 30, 33), hnsecs(274)));
6599 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(273)));
6600 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(272)));
6601 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(264)));
6602 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(174)));
6603 testST(beforeAD, -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
6604 testST(beforeAD, -275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_999)));
6605 testST(beforeAD, -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_274)));
6606 testST(beforeAD, -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_273)));
6607 testST(beforeAD, -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_998_274)));
6608 testST(beforeAD, -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_967_000)));
6609 testST(beforeAD, -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_966_999)));
6610 testST(beforeAD, -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_167_000)));
6611 testST(beforeAD, -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_166_999)));
6612 testST(beforeAD, -1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_000_274)));
6613 testST(beforeAD, -60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 27), hnsecs(274)));
6614 testST(beforeAD, -3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 24, 33), hnsecs(274)));
6615 testST(beforeAD, -600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 29, 33), hnsecs(274)));
6616 testST(beforeAD, -36_000_000_000L, SysTime(DateTime(1999, 7, 6, 11, 30, 33), hnsecs(274)));
6618 // Test B.C.
6619 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274));
6620 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274)));
6621 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(275)));
6622 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(276)));
6623 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(284)));
6624 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(374)));
6625 testST(beforeBC, 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(999)));
6626 testST(beforeBC, 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1000)));
6627 testST(beforeBC, 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1274)));
6628 testST(beforeBC, 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1275)));
6629 testST(beforeBC, 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(2274)));
6630 testST(beforeBC, 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(26_999)));
6631 testST(beforeBC, 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_000)));
6632 testST(beforeBC, 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_001)));
6633 testST(beforeBC, 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_766_999)));
6634 testST(beforeBC, 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_767_000)));
6635 testST(beforeBC, 1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_000_274)));
6636 testST(beforeBC, 60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 39), hnsecs(274)));
6637 testST(beforeBC, 3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 36, 33), hnsecs(274)));
6638 testST(beforeBC, 600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), hnsecs(274)));
6639 testST(beforeBC, 36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), hnsecs(274)));
6641 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(273)));
6642 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(272)));
6643 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(264)));
6644 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(174)));
6645 testST(beforeBC, -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));
6646 testST(beforeBC, -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_999)));
6647 testST(beforeBC, -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_274)));
6648 testST(beforeBC, -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_273)));
6649 testST(beforeBC, -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_998_274)));
6650 testST(beforeBC, -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_967_000)));
6651 testST(beforeBC, -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_966_999)));
6652 testST(beforeBC, -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_167_000)));
6653 testST(beforeBC, -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_166_999)));
6654 testST(beforeBC, -1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_000_274)));
6655 testST(beforeBC, -60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 27), hnsecs(274)));
6656 testST(beforeBC, -3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 24, 33), hnsecs(274)));
6657 testST(beforeBC, -600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), hnsecs(274)));
6658 testST(beforeBC, -36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), hnsecs(274)));
6660 // Test Both
6661 auto beforeBoth1 = SysTime(DateTime(1, 1, 1, 0, 0, 0));
6662 testST(beforeBoth1, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1)));
6663 testST(beforeBoth1, 0, SysTime(DateTime(1, 1, 1, 0, 0, 0)));
6664 testST(beforeBoth1, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));
6665 testST(beforeBoth1, -2, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998)));
6666 testST(beforeBoth1, -1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_000)));
6667 testST(beforeBoth1, -2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_998_000)));
6668 testST(beforeBoth1, -2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_997_445)));
6669 testST(beforeBoth1, -1_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_000_000)));
6670 testST(beforeBoth1, -2_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(8_000_000)));
6671 testST(beforeBoth1, -2_333_333, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(7_666_667)));
6672 testST(beforeBoth1, -10_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59)));
6673 testST(beforeBoth1, -20_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 58)));
6674 testST(beforeBoth1, -20_888_888, SysTime(DateTime(0, 12, 31, 23, 59, 57), hnsecs(9_111_112)));
6676 auto beforeBoth2 = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));
6677 testST(beforeBoth2, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998)));
6678 testST(beforeBoth2, 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));
6679 testST(beforeBoth2, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0)));
6680 testST(beforeBoth2, 2, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1)));
6681 testST(beforeBoth2, 1000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999)));
6682 testST(beforeBoth2, 2000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1999)));
6683 testST(beforeBoth2, 2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2554)));
6684 testST(beforeBoth2, 1_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999_999)));
6685 testST(beforeBoth2, 2_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1_999_999)));
6686 testST(beforeBoth2, 2_333_333, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2_333_332)));
6687 testST(beforeBoth2, 10_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(9_999_999)));
6688 testST(beforeBoth2, 20_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 1), hnsecs(9_999_999)));
6689 testST(beforeBoth2, 20_888_888, SysTime(DateTime(1, 1, 1, 0, 0, 2), hnsecs(888_887)));
6692 auto st = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999));
6693 (st += dur!"hnsecs"(52)) += dur!"seconds"(-907);
6694 assert(st == SysTime(DateTime(0, 12, 31, 23, 44, 53), hnsecs(51)));
6697 auto duration = dur!"seconds"(12);
6698 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
6699 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
6700 static assert(!__traits(compiles, cst += duration));
6701 static assert(!__traits(compiles, ist += duration));
6702 static assert(!__traits(compiles, cst -= duration));
6703 static assert(!__traits(compiles, ist -= duration));
6705 static void testScope(scope ref SysTime st, scope ref Duration d) @safe
6707 auto result1 = st += d;
6708 auto result2 = st -= d;
6714 Gives the difference between two $(LREF SysTime)s.
6716 The legal types of arithmetic for $(LREF SysTime) using this operator
6719 $(BOOKTABLE,
6720 $(TR $(TD SysTime) $(TD -) $(TD SysTime) $(TD -->) $(TD duration))
6723 Duration opBinary(string op)(SysTime rhs) @safe const pure nothrow scope
6724 if (op == "-")
6726 return dur!"hnsecs"(_stdTime - rhs._stdTime);
6729 @safe unittest
6731 import core.time;
6732 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1998, 7, 6, 12, 30, 33)) ==
6733 dur!"seconds"(31_536_000));
6734 assert(SysTime(DateTime(1998, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) ==
6735 dur!"seconds"(-31_536_000));
6737 assert(SysTime(DateTime(1999, 8, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) ==
6738 dur!"seconds"(26_78_400));
6739 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 8, 6, 12, 30, 33)) ==
6740 dur!"seconds"(-26_78_400));
6742 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 5, 12, 30, 33)) ==
6743 dur!"seconds"(86_400));
6744 assert(SysTime(DateTime(1999, 7, 5, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) ==
6745 dur!"seconds"(-86_400));
6747 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 11, 30, 33)) ==
6748 dur!"seconds"(3600));
6749 assert(SysTime(DateTime(1999, 7, 6, 11, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) ==
6750 dur!"seconds"(-3600));
6752 assert(SysTime(DateTime(1999, 7, 6, 12, 31, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) ==
6753 dur!"seconds"(60));
6754 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 31, 33)) ==
6755 dur!"seconds"(-60));
6757 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 34)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) ==
6758 dur!"seconds"(1));
6759 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 34)) ==
6760 dur!"seconds"(-1));
6763 auto dt = DateTime(1999, 7, 6, 12, 30, 33);
6764 assert(SysTime(dt, msecs(532)) - SysTime(dt) == msecs(532));
6765 assert(SysTime(dt) - SysTime(dt, msecs(532)) == msecs(-532));
6767 assert(SysTime(dt, usecs(333_347)) - SysTime(dt) == usecs(333_347));
6768 assert(SysTime(dt) - SysTime(dt, usecs(333_347)) == usecs(-333_347));
6770 assert(SysTime(dt, hnsecs(1_234_567)) - SysTime(dt) == hnsecs(1_234_567));
6771 assert(SysTime(dt) - SysTime(dt, hnsecs(1_234_567)) == hnsecs(-1_234_567));
6774 assert(SysTime(DateTime(1, 1, 1, 12, 30, 33)) - SysTime(DateTime(1, 1, 1, 0, 0, 0)) == dur!"seconds"(45033));
6775 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)) - SysTime(DateTime(1, 1, 1, 12, 30, 33)) == dur!"seconds"(-45033));
6776 assert(SysTime(DateTime(0, 12, 31, 12, 30, 33)) - SysTime(DateTime(1, 1, 1, 0, 0, 0)) == dur!"seconds"(-41367));
6777 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)) - SysTime(DateTime(0, 12, 31, 12, 30, 33)) == dur!"seconds"(41367));
6779 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)) - SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)) ==
6780 dur!"hnsecs"(1));
6781 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)) - SysTime(DateTime(1, 1, 1, 0, 0, 0)) ==
6782 dur!"hnsecs"(-1));
6784 version (Posix)
6786 import std.datetime.timezone : PosixTimeZone;
6787 immutable tz = PosixTimeZone.getTimeZone("America/Los_Angeles");
6789 else version (Windows)
6791 import std.datetime.timezone : WindowsTimeZone;
6792 immutable tz = WindowsTimeZone.getTimeZone("Pacific Standard Time");
6796 auto dt = DateTime(2011, 1, 13, 8, 17, 2);
6797 auto d = msecs(296);
6798 assert(SysTime(dt, d, tz) - SysTime(dt, d, tz) == Duration.zero);
6799 assert(SysTime(dt, d, tz) - SysTime(dt, d, UTC()) == hours(8));
6800 assert(SysTime(dt, d, UTC()) - SysTime(dt, d, tz) == hours(-8));
6803 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
6804 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
6805 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
6806 assert(st - st == Duration.zero);
6807 assert(cst - st == Duration.zero);
6808 assert(ist - st == Duration.zero);
6810 assert(st - cst == Duration.zero);
6811 assert(cst - cst == Duration.zero);
6812 assert(ist - cst == Duration.zero);
6814 assert(st - ist == Duration.zero);
6815 assert(cst - ist == Duration.zero);
6816 assert(ist - ist == Duration.zero);
6818 static void testScope(scope ref SysTime left, scope ref SysTime right) @safe
6820 auto result = left - right;
6826 Returns the difference between the two $(LREF SysTime)s in months.
6828 To get the difference in years, subtract the year property
6829 of two $(LREF SysTime)s. To get the difference in days or weeks,
6830 subtract the $(LREF SysTime)s themselves and use the
6831 $(REF Duration, core,time) that results. Because converting between
6832 months and smaller units requires a specific date (which
6833 $(REF Duration, core,time)s don't have), getting the difference in
6834 months requires some math using both the year and month properties, so
6835 this is a convenience function for getting the difference in months.
6837 Note that the number of days in the months or how far into the month
6838 either date is is irrelevant. It is the difference in the month property
6839 combined with the difference in years * 12. So, for instance,
6840 December 31st and January 1st are one month apart just as December 1st
6841 and January 31st are one month apart.
6843 Params:
6844 rhs = The $(LREF SysTime) to subtract from this one.
6846 int diffMonths(scope SysTime rhs) @safe const nothrow scope
6848 return (cast(Date) this).diffMonths(cast(Date) rhs);
6852 @safe unittest
6854 import core.time;
6855 import std.datetime.date : Date;
6857 assert(SysTime(Date(1999, 2, 1)).diffMonths(
6858 SysTime(Date(1999, 1, 31))) == 1);
6860 assert(SysTime(Date(1999, 1, 31)).diffMonths(
6861 SysTime(Date(1999, 2, 1))) == -1);
6863 assert(SysTime(Date(1999, 3, 1)).diffMonths(
6864 SysTime(Date(1999, 1, 1))) == 2);
6866 assert(SysTime(Date(1999, 1, 1)).diffMonths(
6867 SysTime(Date(1999, 3, 31))) == -2);
6870 @safe unittest
6872 import core.time;
6873 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
6874 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
6875 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
6876 assert(st.diffMonths(st) == 0);
6877 assert(cst.diffMonths(st) == 0);
6878 assert(ist.diffMonths(st) == 0);
6880 assert(st.diffMonths(cst) == 0);
6881 assert(cst.diffMonths(cst) == 0);
6882 assert(ist.diffMonths(cst) == 0);
6884 assert(st.diffMonths(ist) == 0);
6885 assert(cst.diffMonths(ist) == 0);
6886 assert(ist.diffMonths(ist) == 0);
6888 static void testScope(scope ref SysTime left, scope ref SysTime right) @safe
6890 auto result = left.diffMonths(right);
6896 Whether this $(LREF SysTime) is in a leap year.
6898 @property bool isLeapYear() @safe const nothrow scope
6900 return (cast(Date) this).isLeapYear;
6903 @safe unittest
6905 import core.time;
6906 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
6907 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
6908 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
6909 assert(!st.isLeapYear);
6910 assert(!cst.isLeapYear);
6911 assert(!ist.isLeapYear);
6913 static void testScope(scope ref SysTime st) @safe
6915 auto result = st.isLeapYear;
6921 Day of the week this $(LREF SysTime) is on.
6923 @property DayOfWeek dayOfWeek() @safe const nothrow scope
6925 return getDayOfWeek(dayOfGregorianCal);
6928 @safe unittest
6930 import core.time;
6931 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
6932 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
6933 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
6934 assert(st.dayOfWeek == DayOfWeek.tue);
6935 assert(cst.dayOfWeek == DayOfWeek.tue);
6936 assert(ist.dayOfWeek == DayOfWeek.tue);
6938 static void testScope(scope ref SysTime st) @safe
6940 auto result = st.dayOfWeek;
6946 Day of the year this $(LREF SysTime) is on.
6948 @property ushort dayOfYear() @safe const nothrow scope
6950 return (cast(Date) this).dayOfYear;
6954 @safe unittest
6956 import core.time;
6957 import std.datetime.date : DateTime;
6959 assert(SysTime(DateTime(1999, 1, 1, 12, 22, 7)).dayOfYear == 1);
6960 assert(SysTime(DateTime(1999, 12, 31, 7, 2, 59)).dayOfYear == 365);
6961 assert(SysTime(DateTime(2000, 12, 31, 21, 20, 0)).dayOfYear == 366);
6964 @safe unittest
6966 import core.time;
6967 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
6968 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
6969 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
6970 assert(st.dayOfYear == 187);
6971 assert(cst.dayOfYear == 187);
6972 assert(ist.dayOfYear == 187);
6974 static void testScope(scope ref SysTime st) @safe
6976 auto result = st.dayOfYear;
6982 Day of the year.
6984 Params:
6985 day = The day of the year to set which day of the year this
6986 $(LREF SysTime) is on.
6988 @property void dayOfYear(int day) @safe scope
6990 immutable hnsecs = adjTime;
6991 immutable days = convert!("hnsecs", "days")(hnsecs);
6992 immutable theRest = hnsecs - convert!("days", "hnsecs")(days);
6994 auto date = Date(cast(int) days);
6995 date.dayOfYear = day;
6997 immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1);
6999 adjTime = newDaysHNSecs + theRest;
7002 @safe unittest
7004 import core.time;
7005 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
7006 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
7007 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
7008 st.dayOfYear = 12;
7009 assert(st.dayOfYear == 12);
7010 static assert(!__traits(compiles, cst.dayOfYear = 12));
7011 static assert(!__traits(compiles, ist.dayOfYear = 12));
7013 static void testScope(scope ref SysTime st) @safe
7015 st.dayOfYear = 42;
7021 The Xth day of the Gregorian Calendar that this $(LREF SysTime) is on.
7023 @property int dayOfGregorianCal() @safe const nothrow scope
7025 immutable adjustedTime = adjTime;
7027 // We have to add one because 0 would be midnight, January 1st, 1 A.D.,
7028 // which would be the 1st day of the Gregorian Calendar, not the 0th. So,
7029 // simply casting to days is one day off.
7030 if (adjustedTime > 0)
7031 return cast(int) getUnitsFromHNSecs!"days"(adjustedTime) + 1;
7033 long hnsecs = adjustedTime;
7034 immutable days = cast(int) splitUnitsFromHNSecs!"days"(hnsecs);
7036 return hnsecs == 0 ? days + 1 : days;
7040 @safe unittest
7042 import core.time;
7043 import std.datetime.date : DateTime;
7045 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).dayOfGregorianCal == 1);
7046 assert(SysTime(DateTime(1, 12, 31, 23, 59, 59)).dayOfGregorianCal == 365);
7047 assert(SysTime(DateTime(2, 1, 1, 2, 2, 2)).dayOfGregorianCal == 366);
7049 assert(SysTime(DateTime(0, 12, 31, 7, 7, 7)).dayOfGregorianCal == 0);
7050 assert(SysTime(DateTime(0, 1, 1, 19, 30, 0)).dayOfGregorianCal == -365);
7051 assert(SysTime(DateTime(-1, 12, 31, 4, 7, 0)).dayOfGregorianCal == -366);
7053 assert(SysTime(DateTime(2000, 1, 1, 9, 30, 20)).dayOfGregorianCal == 730_120);
7054 assert(SysTime(DateTime(2010, 12, 31, 15, 45, 50)).dayOfGregorianCal == 734_137);
7057 @safe unittest
7059 import core.time;
7060 // Test A.D.
7061 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).dayOfGregorianCal == 1);
7062 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1)).dayOfGregorianCal == 1);
7063 assert(SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)).dayOfGregorianCal == 1);
7065 assert(SysTime(DateTime(1, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 1);
7066 assert(SysTime(DateTime(1, 1, 2, 12, 2, 9), msecs(212)).dayOfGregorianCal == 2);
7067 assert(SysTime(DateTime(1, 2, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 32);
7068 assert(SysTime(DateTime(2, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 366);
7069 assert(SysTime(DateTime(3, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 731);
7070 assert(SysTime(DateTime(4, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 1096);
7071 assert(SysTime(DateTime(5, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 1462);
7072 assert(SysTime(DateTime(50, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 17_898);
7073 assert(SysTime(DateTime(97, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 35_065);
7074 assert(SysTime(DateTime(100, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 36_160);
7075 assert(SysTime(DateTime(101, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 36_525);
7076 assert(SysTime(DateTime(105, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 37_986);
7077 assert(SysTime(DateTime(200, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 72_684);
7078 assert(SysTime(DateTime(201, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 73_049);
7079 assert(SysTime(DateTime(300, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 109_208);
7080 assert(SysTime(DateTime(301, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 109_573);
7081 assert(SysTime(DateTime(400, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 145_732);
7082 assert(SysTime(DateTime(401, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 146_098);
7083 assert(SysTime(DateTime(500, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 182_257);
7084 assert(SysTime(DateTime(501, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 182_622);
7085 assert(SysTime(DateTime(1000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 364_878);
7086 assert(SysTime(DateTime(1001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 365_243);
7087 assert(SysTime(DateTime(1600, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 584_023);
7088 assert(SysTime(DateTime(1601, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 584_389);
7089 assert(SysTime(DateTime(1900, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 693_596);
7090 assert(SysTime(DateTime(1901, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 693_961);
7091 assert(SysTime(DateTime(1945, 11, 12, 12, 2, 9), msecs(212)).dayOfGregorianCal == 710_347);
7092 assert(SysTime(DateTime(1999, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 729_755);
7093 assert(SysTime(DateTime(2000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 730_120);
7094 assert(SysTime(DateTime(2001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 730_486);
7096 assert(SysTime(DateTime(2010, 1, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_773);
7097 assert(SysTime(DateTime(2010, 1, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_803);
7098 assert(SysTime(DateTime(2010, 2, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_804);
7099 assert(SysTime(DateTime(2010, 2, 28, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_831);
7100 assert(SysTime(DateTime(2010, 3, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_832);
7101 assert(SysTime(DateTime(2010, 3, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_862);
7102 assert(SysTime(DateTime(2010, 4, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_863);
7103 assert(SysTime(DateTime(2010, 4, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_892);
7104 assert(SysTime(DateTime(2010, 5, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_893);
7105 assert(SysTime(DateTime(2010, 5, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_923);
7106 assert(SysTime(DateTime(2010, 6, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_924);
7107 assert(SysTime(DateTime(2010, 6, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_953);
7108 assert(SysTime(DateTime(2010, 7, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_954);
7109 assert(SysTime(DateTime(2010, 7, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_984);
7110 assert(SysTime(DateTime(2010, 8, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_985);
7111 assert(SysTime(DateTime(2010, 8, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_015);
7112 assert(SysTime(DateTime(2010, 9, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_016);
7113 assert(SysTime(DateTime(2010, 9, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_045);
7114 assert(SysTime(DateTime(2010, 10, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_046);
7115 assert(SysTime(DateTime(2010, 10, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_076);
7116 assert(SysTime(DateTime(2010, 11, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_077);
7117 assert(SysTime(DateTime(2010, 11, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_106);
7118 assert(SysTime(DateTime(2010, 12, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_107);
7119 assert(SysTime(DateTime(2010, 12, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_137);
7121 assert(SysTime(DateTime(2012, 2, 1, 0, 0, 0)).dayOfGregorianCal == 734_534);
7122 assert(SysTime(DateTime(2012, 2, 28, 0, 0, 0)).dayOfGregorianCal == 734_561);
7123 assert(SysTime(DateTime(2012, 2, 29, 0, 0, 0)).dayOfGregorianCal == 734_562);
7124 assert(SysTime(DateTime(2012, 3, 1, 0, 0, 0)).dayOfGregorianCal == 734_563);
7126 // Test B.C.
7127 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)).dayOfGregorianCal == 0);
7128 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998)).dayOfGregorianCal == 0);
7129 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59)).dayOfGregorianCal == 0);
7130 assert(SysTime(DateTime(0, 12, 31, 0, 0, 0), hnsecs(1)).dayOfGregorianCal == 0);
7131 assert(SysTime(DateTime(0, 12, 31, 0, 0, 0)).dayOfGregorianCal == 0);
7133 assert(SysTime(DateTime(-1, 12, 31, 23, 59, 59), hnsecs(9_999_999)).dayOfGregorianCal == -366);
7134 assert(SysTime(DateTime(-1, 12, 31, 23, 59, 59), hnsecs(9_999_998)).dayOfGregorianCal == -366);
7135 assert(SysTime(DateTime(-1, 12, 31, 23, 59, 59)).dayOfGregorianCal == -366);
7136 assert(SysTime(DateTime(-1, 12, 31, 0, 0, 0)).dayOfGregorianCal == -366);
7138 assert(SysTime(DateTime(0, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == 0);
7139 assert(SysTime(DateTime(0, 12, 30, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1);
7140 assert(SysTime(DateTime(0, 12, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -30);
7141 assert(SysTime(DateTime(0, 11, 30, 12, 2, 9), msecs(212)).dayOfGregorianCal == -31);
7143 assert(SysTime(DateTime(-1, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -366);
7144 assert(SysTime(DateTime(-1, 12, 30, 12, 2, 9), msecs(212)).dayOfGregorianCal == -367);
7145 assert(SysTime(DateTime(-1, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730);
7146 assert(SysTime(DateTime(-2, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -731);
7147 assert(SysTime(DateTime(-2, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1095);
7148 assert(SysTime(DateTime(-3, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1096);
7149 assert(SysTime(DateTime(-3, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1460);
7150 assert(SysTime(DateTime(-4, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1461);
7151 assert(SysTime(DateTime(-4, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1826);
7152 assert(SysTime(DateTime(-5, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1827);
7153 assert(SysTime(DateTime(-5, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -2191);
7154 assert(SysTime(DateTime(-9, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -3652);
7156 assert(SysTime(DateTime(-49, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -18_262);
7157 assert(SysTime(DateTime(-50, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -18_627);
7158 assert(SysTime(DateTime(-97, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -35_794);
7159 assert(SysTime(DateTime(-99, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -36_160);
7160 assert(SysTime(DateTime(-99, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -36_524);
7161 assert(SysTime(DateTime(-100, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -36_889);
7162 assert(SysTime(DateTime(-101, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -37_254);
7163 assert(SysTime(DateTime(-105, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -38_715);
7164 assert(SysTime(DateTime(-200, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -73_413);
7165 assert(SysTime(DateTime(-201, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -73_778);
7166 assert(SysTime(DateTime(-300, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -109_937);
7167 assert(SysTime(DateTime(-301, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -110_302);
7168 assert(SysTime(DateTime(-400, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -146_097);
7169 assert(SysTime(DateTime(-400, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -146_462);
7170 assert(SysTime(DateTime(-401, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -146_827);
7171 assert(SysTime(DateTime(-499, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -182_621);
7172 assert(SysTime(DateTime(-500, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -182_986);
7173 assert(SysTime(DateTime(-501, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -183_351);
7174 assert(SysTime(DateTime(-1000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -365_607);
7175 assert(SysTime(DateTime(-1001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -365_972);
7176 assert(SysTime(DateTime(-1599, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -584_387);
7177 assert(SysTime(DateTime(-1600, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -584_388);
7178 assert(SysTime(DateTime(-1600, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -584_753);
7179 assert(SysTime(DateTime(-1601, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -585_118);
7180 assert(SysTime(DateTime(-1900, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -694_325);
7181 assert(SysTime(DateTime(-1901, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -694_690);
7182 assert(SysTime(DateTime(-1999, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730_484);
7183 assert(SysTime(DateTime(-2000, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730_485);
7184 assert(SysTime(DateTime(-2000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730_850);
7185 assert(SysTime(DateTime(-2001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -731_215);
7187 assert(SysTime(DateTime(-2010, 1, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_502);
7188 assert(SysTime(DateTime(-2010, 1, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_472);
7189 assert(SysTime(DateTime(-2010, 2, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_471);
7190 assert(SysTime(DateTime(-2010, 2, 28, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_444);
7191 assert(SysTime(DateTime(-2010, 3, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_443);
7192 assert(SysTime(DateTime(-2010, 3, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_413);
7193 assert(SysTime(DateTime(-2010, 4, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_412);
7194 assert(SysTime(DateTime(-2010, 4, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_383);
7195 assert(SysTime(DateTime(-2010, 5, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_382);
7196 assert(SysTime(DateTime(-2010, 5, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_352);
7197 assert(SysTime(DateTime(-2010, 6, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_351);
7198 assert(SysTime(DateTime(-2010, 6, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_322);
7199 assert(SysTime(DateTime(-2010, 7, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_321);
7200 assert(SysTime(DateTime(-2010, 7, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_291);
7201 assert(SysTime(DateTime(-2010, 8, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_290);
7202 assert(SysTime(DateTime(-2010, 8, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_260);
7203 assert(SysTime(DateTime(-2010, 9, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_259);
7204 assert(SysTime(DateTime(-2010, 9, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_230);
7205 assert(SysTime(DateTime(-2010, 10, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_229);
7206 assert(SysTime(DateTime(-2010, 10, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_199);
7207 assert(SysTime(DateTime(-2010, 11, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_198);
7208 assert(SysTime(DateTime(-2010, 11, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_169);
7209 assert(SysTime(DateTime(-2010, 12, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_168);
7210 assert(SysTime(DateTime(-2010, 12, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_138);
7212 assert(SysTime(DateTime(-2012, 2, 1, 0, 0, 0)).dayOfGregorianCal == -735_202);
7213 assert(SysTime(DateTime(-2012, 2, 28, 0, 0, 0)).dayOfGregorianCal == -735_175);
7214 assert(SysTime(DateTime(-2012, 2, 29, 0, 0, 0)).dayOfGregorianCal == -735_174);
7215 assert(SysTime(DateTime(-2012, 3, 1, 0, 0, 0)).dayOfGregorianCal == -735_173);
7217 // Start of Hebrew Calendar
7218 assert(SysTime(DateTime(-3760, 9, 7, 0, 0, 0)).dayOfGregorianCal == -1_373_427);
7220 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
7221 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
7222 assert(cst.dayOfGregorianCal == 729_941);
7223 assert(ist.dayOfGregorianCal == 729_941);
7225 static void testScope(scope ref SysTime st) @safe
7227 auto result = st.dayOfGregorianCal;
7232 // Test that the logic for the day of the Gregorian Calendar is consistent
7233 // between Date and SysTime.
7234 @safe unittest
7236 import core.time;
7237 void test(Date date, SysTime st, size_t line = __LINE__)
7239 if (date.dayOfGregorianCal != st.dayOfGregorianCal)
7241 throw new AssertError(format("Date [%s] SysTime [%s]", date.dayOfGregorianCal, st.dayOfGregorianCal),
7242 __FILE__, line);
7246 // Test A.D.
7247 test(Date(1, 1, 1), SysTime(DateTime(1, 1, 1, 0, 0, 0)));
7248 test(Date(1, 1, 2), SysTime(DateTime(1, 1, 2, 0, 0, 0), hnsecs(500)));
7249 test(Date(1, 2, 1), SysTime(DateTime(1, 2, 1, 0, 0, 0), hnsecs(50_000)));
7250 test(Date(2, 1, 1), SysTime(DateTime(2, 1, 1, 0, 0, 0), hnsecs(9_999_999)));
7251 test(Date(3, 1, 1), SysTime(DateTime(3, 1, 1, 12, 13, 14)));
7252 test(Date(4, 1, 1), SysTime(DateTime(4, 1, 1, 12, 13, 14), hnsecs(500)));
7253 test(Date(5, 1, 1), SysTime(DateTime(5, 1, 1, 12, 13, 14), hnsecs(50_000)));
7254 test(Date(50, 1, 1), SysTime(DateTime(50, 1, 1, 12, 13, 14), hnsecs(9_999_999)));
7255 test(Date(97, 1, 1), SysTime(DateTime(97, 1, 1, 23, 59, 59)));
7256 test(Date(100, 1, 1), SysTime(DateTime(100, 1, 1, 23, 59, 59), hnsecs(500)));
7257 test(Date(101, 1, 1), SysTime(DateTime(101, 1, 1, 23, 59, 59), hnsecs(50_000)));
7258 test(Date(105, 1, 1), SysTime(DateTime(105, 1, 1, 23, 59, 59), hnsecs(9_999_999)));
7259 test(Date(200, 1, 1), SysTime(DateTime(200, 1, 1, 0, 0, 0)));
7260 test(Date(201, 1, 1), SysTime(DateTime(201, 1, 1, 0, 0, 0), hnsecs(500)));
7261 test(Date(300, 1, 1), SysTime(DateTime(300, 1, 1, 0, 0, 0), hnsecs(50_000)));
7262 test(Date(301, 1, 1), SysTime(DateTime(301, 1, 1, 0, 0, 0), hnsecs(9_999_999)));
7263 test(Date(400, 1, 1), SysTime(DateTime(400, 1, 1, 12, 13, 14)));
7264 test(Date(401, 1, 1), SysTime(DateTime(401, 1, 1, 12, 13, 14), hnsecs(500)));
7265 test(Date(500, 1, 1), SysTime(DateTime(500, 1, 1, 12, 13, 14), hnsecs(50_000)));
7266 test(Date(501, 1, 1), SysTime(DateTime(501, 1, 1, 12, 13, 14), hnsecs(9_999_999)));
7267 test(Date(1000, 1, 1), SysTime(DateTime(1000, 1, 1, 23, 59, 59)));
7268 test(Date(1001, 1, 1), SysTime(DateTime(1001, 1, 1, 23, 59, 59), hnsecs(500)));
7269 test(Date(1600, 1, 1), SysTime(DateTime(1600, 1, 1, 23, 59, 59), hnsecs(50_000)));
7270 test(Date(1601, 1, 1), SysTime(DateTime(1601, 1, 1, 23, 59, 59), hnsecs(9_999_999)));
7271 test(Date(1900, 1, 1), SysTime(DateTime(1900, 1, 1, 0, 0, 0)));
7272 test(Date(1901, 1, 1), SysTime(DateTime(1901, 1, 1, 0, 0, 0), hnsecs(500)));
7273 test(Date(1945, 11, 12), SysTime(DateTime(1945, 11, 12, 0, 0, 0), hnsecs(50_000)));
7274 test(Date(1999, 1, 1), SysTime(DateTime(1999, 1, 1, 0, 0, 0), hnsecs(9_999_999)));
7275 test(Date(1999, 7, 6), SysTime(DateTime(1999, 7, 6, 12, 13, 14)));
7276 test(Date(2000, 1, 1), SysTime(DateTime(2000, 1, 1, 12, 13, 14), hnsecs(500)));
7277 test(Date(2001, 1, 1), SysTime(DateTime(2001, 1, 1, 12, 13, 14), hnsecs(50_000)));
7279 test(Date(2010, 1, 1), SysTime(DateTime(2010, 1, 1, 12, 13, 14), hnsecs(9_999_999)));
7280 test(Date(2010, 1, 31), SysTime(DateTime(2010, 1, 31, 23, 0, 0)));
7281 test(Date(2010, 2, 1), SysTime(DateTime(2010, 2, 1, 23, 59, 59), hnsecs(500)));
7282 test(Date(2010, 2, 28), SysTime(DateTime(2010, 2, 28, 23, 59, 59), hnsecs(50_000)));
7283 test(Date(2010, 3, 1), SysTime(DateTime(2010, 3, 1, 23, 59, 59), hnsecs(9_999_999)));
7284 test(Date(2010, 3, 31), SysTime(DateTime(2010, 3, 31, 0, 0, 0)));
7285 test(Date(2010, 4, 1), SysTime(DateTime(2010, 4, 1, 0, 0, 0), hnsecs(500)));
7286 test(Date(2010, 4, 30), SysTime(DateTime(2010, 4, 30, 0, 0, 0), hnsecs(50_000)));
7287 test(Date(2010, 5, 1), SysTime(DateTime(2010, 5, 1, 0, 0, 0), hnsecs(9_999_999)));
7288 test(Date(2010, 5, 31), SysTime(DateTime(2010, 5, 31, 12, 13, 14)));
7289 test(Date(2010, 6, 1), SysTime(DateTime(2010, 6, 1, 12, 13, 14), hnsecs(500)));
7290 test(Date(2010, 6, 30), SysTime(DateTime(2010, 6, 30, 12, 13, 14), hnsecs(50_000)));
7291 test(Date(2010, 7, 1), SysTime(DateTime(2010, 7, 1, 12, 13, 14), hnsecs(9_999_999)));
7292 test(Date(2010, 7, 31), SysTime(DateTime(2010, 7, 31, 23, 59, 59)));
7293 test(Date(2010, 8, 1), SysTime(DateTime(2010, 8, 1, 23, 59, 59), hnsecs(500)));
7294 test(Date(2010, 8, 31), SysTime(DateTime(2010, 8, 31, 23, 59, 59), hnsecs(50_000)));
7295 test(Date(2010, 9, 1), SysTime(DateTime(2010, 9, 1, 23, 59, 59), hnsecs(9_999_999)));
7296 test(Date(2010, 9, 30), SysTime(DateTime(2010, 9, 30, 12, 0, 0)));
7297 test(Date(2010, 10, 1), SysTime(DateTime(2010, 10, 1, 0, 12, 0), hnsecs(500)));
7298 test(Date(2010, 10, 31), SysTime(DateTime(2010, 10, 31, 0, 0, 12), hnsecs(50_000)));
7299 test(Date(2010, 11, 1), SysTime(DateTime(2010, 11, 1, 23, 0, 0), hnsecs(9_999_999)));
7300 test(Date(2010, 11, 30), SysTime(DateTime(2010, 11, 30, 0, 59, 0)));
7301 test(Date(2010, 12, 1), SysTime(DateTime(2010, 12, 1, 0, 0, 59), hnsecs(500)));
7302 test(Date(2010, 12, 31), SysTime(DateTime(2010, 12, 31, 0, 59, 59), hnsecs(50_000)));
7304 test(Date(2012, 2, 1), SysTime(DateTime(2012, 2, 1, 23, 0, 59), hnsecs(9_999_999)));
7305 test(Date(2012, 2, 28), SysTime(DateTime(2012, 2, 28, 23, 59, 0)));
7306 test(Date(2012, 2, 29), SysTime(DateTime(2012, 2, 29, 7, 7, 7), hnsecs(7)));
7307 test(Date(2012, 3, 1), SysTime(DateTime(2012, 3, 1, 7, 7, 7), hnsecs(7)));
7309 // Test B.C.
7310 test(Date(0, 12, 31), SysTime(DateTime(0, 12, 31, 0, 0, 0)));
7311 test(Date(0, 12, 30), SysTime(DateTime(0, 12, 30, 0, 0, 0), hnsecs(500)));
7312 test(Date(0, 12, 1), SysTime(DateTime(0, 12, 1, 0, 0, 0), hnsecs(50_000)));
7313 test(Date(0, 11, 30), SysTime(DateTime(0, 11, 30, 0, 0, 0), hnsecs(9_999_999)));
7315 test(Date(-1, 12, 31), SysTime(DateTime(-1, 12, 31, 12, 13, 14)));
7316 test(Date(-1, 12, 30), SysTime(DateTime(-1, 12, 30, 12, 13, 14), hnsecs(500)));
7317 test(Date(-1, 1, 1), SysTime(DateTime(-1, 1, 1, 12, 13, 14), hnsecs(50_000)));
7318 test(Date(-2, 12, 31), SysTime(DateTime(-2, 12, 31, 12, 13, 14), hnsecs(9_999_999)));
7319 test(Date(-2, 1, 1), SysTime(DateTime(-2, 1, 1, 23, 59, 59)));
7320 test(Date(-3, 12, 31), SysTime(DateTime(-3, 12, 31, 23, 59, 59), hnsecs(500)));
7321 test(Date(-3, 1, 1), SysTime(DateTime(-3, 1, 1, 23, 59, 59), hnsecs(50_000)));
7322 test(Date(-4, 12, 31), SysTime(DateTime(-4, 12, 31, 23, 59, 59), hnsecs(9_999_999)));
7323 test(Date(-4, 1, 1), SysTime(DateTime(-4, 1, 1, 0, 0, 0)));
7324 test(Date(-5, 12, 31), SysTime(DateTime(-5, 12, 31, 0, 0, 0), hnsecs(500)));
7325 test(Date(-5, 1, 1), SysTime(DateTime(-5, 1, 1, 0, 0, 0), hnsecs(50_000)));
7326 test(Date(-9, 1, 1), SysTime(DateTime(-9, 1, 1, 0, 0, 0), hnsecs(9_999_999)));
7328 test(Date(-49, 1, 1), SysTime(DateTime(-49, 1, 1, 12, 13, 14)));
7329 test(Date(-50, 1, 1), SysTime(DateTime(-50, 1, 1, 12, 13, 14), hnsecs(500)));
7330 test(Date(-97, 1, 1), SysTime(DateTime(-97, 1, 1, 12, 13, 14), hnsecs(50_000)));
7331 test(Date(-99, 12, 31), SysTime(DateTime(-99, 12, 31, 12, 13, 14), hnsecs(9_999_999)));
7332 test(Date(-99, 1, 1), SysTime(DateTime(-99, 1, 1, 23, 59, 59)));
7333 test(Date(-100, 1, 1), SysTime(DateTime(-100, 1, 1, 23, 59, 59), hnsecs(500)));
7334 test(Date(-101, 1, 1), SysTime(DateTime(-101, 1, 1, 23, 59, 59), hnsecs(50_000)));
7335 test(Date(-105, 1, 1), SysTime(DateTime(-105, 1, 1, 23, 59, 59), hnsecs(9_999_999)));
7336 test(Date(-200, 1, 1), SysTime(DateTime(-200, 1, 1, 0, 0, 0)));
7337 test(Date(-201, 1, 1), SysTime(DateTime(-201, 1, 1, 0, 0, 0), hnsecs(500)));
7338 test(Date(-300, 1, 1), SysTime(DateTime(-300, 1, 1, 0, 0, 0), hnsecs(50_000)));
7339 test(Date(-301, 1, 1), SysTime(DateTime(-301, 1, 1, 0, 0, 0), hnsecs(9_999_999)));
7340 test(Date(-400, 12, 31), SysTime(DateTime(-400, 12, 31, 12, 13, 14)));
7341 test(Date(-400, 1, 1), SysTime(DateTime(-400, 1, 1, 12, 13, 14), hnsecs(500)));
7342 test(Date(-401, 1, 1), SysTime(DateTime(-401, 1, 1, 12, 13, 14), hnsecs(50_000)));
7343 test(Date(-499, 1, 1), SysTime(DateTime(-499, 1, 1, 12, 13, 14), hnsecs(9_999_999)));
7344 test(Date(-500, 1, 1), SysTime(DateTime(-500, 1, 1, 23, 59, 59)));
7345 test(Date(-501, 1, 1), SysTime(DateTime(-501, 1, 1, 23, 59, 59), hnsecs(500)));
7346 test(Date(-1000, 1, 1), SysTime(DateTime(-1000, 1, 1, 23, 59, 59), hnsecs(50_000)));
7347 test(Date(-1001, 1, 1), SysTime(DateTime(-1001, 1, 1, 23, 59, 59), hnsecs(9_999_999)));
7348 test(Date(-1599, 1, 1), SysTime(DateTime(-1599, 1, 1, 0, 0, 0)));
7349 test(Date(-1600, 12, 31), SysTime(DateTime(-1600, 12, 31, 0, 0, 0), hnsecs(500)));
7350 test(Date(-1600, 1, 1), SysTime(DateTime(-1600, 1, 1, 0, 0, 0), hnsecs(50_000)));
7351 test(Date(-1601, 1, 1), SysTime(DateTime(-1601, 1, 1, 0, 0, 0), hnsecs(9_999_999)));
7352 test(Date(-1900, 1, 1), SysTime(DateTime(-1900, 1, 1, 12, 13, 14)));
7353 test(Date(-1901, 1, 1), SysTime(DateTime(-1901, 1, 1, 12, 13, 14), hnsecs(500)));
7354 test(Date(-1999, 1, 1), SysTime(DateTime(-1999, 1, 1, 12, 13, 14), hnsecs(50_000)));
7355 test(Date(-1999, 7, 6), SysTime(DateTime(-1999, 7, 6, 12, 13, 14), hnsecs(9_999_999)));
7356 test(Date(-2000, 12, 31), SysTime(DateTime(-2000, 12, 31, 23, 59, 59)));
7357 test(Date(-2000, 1, 1), SysTime(DateTime(-2000, 1, 1, 23, 59, 59), hnsecs(500)));
7358 test(Date(-2001, 1, 1), SysTime(DateTime(-2001, 1, 1, 23, 59, 59), hnsecs(50_000)));
7360 test(Date(-2010, 1, 1), SysTime(DateTime(-2010, 1, 1, 23, 59, 59), hnsecs(9_999_999)));
7361 test(Date(-2010, 1, 31), SysTime(DateTime(-2010, 1, 31, 0, 0, 0)));
7362 test(Date(-2010, 2, 1), SysTime(DateTime(-2010, 2, 1, 0, 0, 0), hnsecs(500)));
7363 test(Date(-2010, 2, 28), SysTime(DateTime(-2010, 2, 28, 0, 0, 0), hnsecs(50_000)));
7364 test(Date(-2010, 3, 1), SysTime(DateTime(-2010, 3, 1, 0, 0, 0), hnsecs(9_999_999)));
7365 test(Date(-2010, 3, 31), SysTime(DateTime(-2010, 3, 31, 12, 13, 14)));
7366 test(Date(-2010, 4, 1), SysTime(DateTime(-2010, 4, 1, 12, 13, 14), hnsecs(500)));
7367 test(Date(-2010, 4, 30), SysTime(DateTime(-2010, 4, 30, 12, 13, 14), hnsecs(50_000)));
7368 test(Date(-2010, 5, 1), SysTime(DateTime(-2010, 5, 1, 12, 13, 14), hnsecs(9_999_999)));
7369 test(Date(-2010, 5, 31), SysTime(DateTime(-2010, 5, 31, 23, 59, 59)));
7370 test(Date(-2010, 6, 1), SysTime(DateTime(-2010, 6, 1, 23, 59, 59), hnsecs(500)));
7371 test(Date(-2010, 6, 30), SysTime(DateTime(-2010, 6, 30, 23, 59, 59), hnsecs(50_000)));
7372 test(Date(-2010, 7, 1), SysTime(DateTime(-2010, 7, 1, 23, 59, 59), hnsecs(9_999_999)));
7373 test(Date(-2010, 7, 31), SysTime(DateTime(-2010, 7, 31, 0, 0, 0)));
7374 test(Date(-2010, 8, 1), SysTime(DateTime(-2010, 8, 1, 0, 0, 0), hnsecs(500)));
7375 test(Date(-2010, 8, 31), SysTime(DateTime(-2010, 8, 31, 0, 0, 0), hnsecs(50_000)));
7376 test(Date(-2010, 9, 1), SysTime(DateTime(-2010, 9, 1, 0, 0, 0), hnsecs(9_999_999)));
7377 test(Date(-2010, 9, 30), SysTime(DateTime(-2010, 9, 30, 12, 0, 0)));
7378 test(Date(-2010, 10, 1), SysTime(DateTime(-2010, 10, 1, 0, 12, 0), hnsecs(500)));
7379 test(Date(-2010, 10, 31), SysTime(DateTime(-2010, 10, 31, 0, 0, 12), hnsecs(50_000)));
7380 test(Date(-2010, 11, 1), SysTime(DateTime(-2010, 11, 1, 23, 0, 0), hnsecs(9_999_999)));
7381 test(Date(-2010, 11, 30), SysTime(DateTime(-2010, 11, 30, 0, 59, 0)));
7382 test(Date(-2010, 12, 1), SysTime(DateTime(-2010, 12, 1, 0, 0, 59), hnsecs(500)));
7383 test(Date(-2010, 12, 31), SysTime(DateTime(-2010, 12, 31, 0, 59, 59), hnsecs(50_000)));
7385 test(Date(-2012, 2, 1), SysTime(DateTime(-2012, 2, 1, 23, 0, 59), hnsecs(9_999_999)));
7386 test(Date(-2012, 2, 28), SysTime(DateTime(-2012, 2, 28, 23, 59, 0)));
7387 test(Date(-2012, 2, 29), SysTime(DateTime(-2012, 2, 29, 7, 7, 7), hnsecs(7)));
7388 test(Date(-2012, 3, 1), SysTime(DateTime(-2012, 3, 1, 7, 7, 7), hnsecs(7)));
7390 test(Date(-3760, 9, 7), SysTime(DateTime(-3760, 9, 7, 0, 0, 0)));
7395 The Xth day of the Gregorian Calendar that this $(LREF SysTime) is on.
7396 Setting this property does not affect the time portion of $(LREF SysTime).
7398 Params:
7399 days = The day of the Gregorian Calendar to set this $(LREF SysTime)
7402 @property void dayOfGregorianCal(int days) @safe nothrow scope
7404 auto hnsecs = adjTime;
7405 hnsecs = removeUnitsFromHNSecs!"days"(hnsecs);
7407 if (hnsecs < 0)
7408 hnsecs += convert!("hours", "hnsecs")(24);
7410 if (--days < 0)
7412 hnsecs -= convert!("hours", "hnsecs")(24);
7413 ++days;
7416 immutable newDaysHNSecs = convert!("days", "hnsecs")(days);
7418 adjTime = newDaysHNSecs + hnsecs;
7422 @safe unittest
7424 import core.time;
7425 import std.datetime.date : DateTime;
7427 auto st = SysTime(DateTime(0, 1, 1, 12, 0, 0));
7428 st.dayOfGregorianCal = 1;
7429 assert(st == SysTime(DateTime(1, 1, 1, 12, 0, 0)));
7431 st.dayOfGregorianCal = 365;
7432 assert(st == SysTime(DateTime(1, 12, 31, 12, 0, 0)));
7434 st.dayOfGregorianCal = 366;
7435 assert(st == SysTime(DateTime(2, 1, 1, 12, 0, 0)));
7437 st.dayOfGregorianCal = 0;
7438 assert(st == SysTime(DateTime(0, 12, 31, 12, 0, 0)));
7440 st.dayOfGregorianCal = -365;
7441 assert(st == SysTime(DateTime(-0, 1, 1, 12, 0, 0)));
7443 st.dayOfGregorianCal = -366;
7444 assert(st == SysTime(DateTime(-1, 12, 31, 12, 0, 0)));
7446 st.dayOfGregorianCal = 730_120;
7447 assert(st == SysTime(DateTime(2000, 1, 1, 12, 0, 0)));
7449 st.dayOfGregorianCal = 734_137;
7450 assert(st == SysTime(DateTime(2010, 12, 31, 12, 0, 0)));
7453 @safe unittest
7455 import core.time;
7456 void testST(SysTime orig, int day, SysTime expected, size_t line = __LINE__) @safe
7458 orig.dayOfGregorianCal = day;
7459 if (orig != expected)
7460 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line);
7463 // Test A.D.
7464 testST(SysTime(DateTime(1, 1, 1, 0, 0, 0)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0)));
7465 testST(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1)));
7466 testST(SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)), 1,
7467 SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));
7469 // Test B.C.
7470 testST(SysTime(DateTime(0, 1, 1, 0, 0, 0)), 0, SysTime(DateTime(0, 12, 31, 0, 0, 0)));
7471 testST(SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)), 0,
7472 SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));
7473 testST(SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(1)), 0,
7474 SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1)));
7475 testST(SysTime(DateTime(0, 1, 1, 23, 59, 59)), 0, SysTime(DateTime(0, 12, 31, 23, 59, 59)));
7477 // Test Both.
7478 testST(SysTime(DateTime(-512, 7, 20, 0, 0, 0)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0)));
7479 testST(SysTime(DateTime(-513, 6, 6, 0, 0, 0), hnsecs(1)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1)));
7480 testST(SysTime(DateTime(-511, 5, 7, 23, 59, 59), hnsecs(9_999_999)), 1,
7481 SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)));
7483 testST(SysTime(DateTime(1607, 4, 8, 0, 0, 0)), 0, SysTime(DateTime(0, 12, 31, 0, 0, 0)));
7484 testST(SysTime(DateTime(1500, 3, 9, 23, 59, 59), hnsecs(9_999_999)), 0,
7485 SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)));
7486 testST(SysTime(DateTime(999, 2, 10, 23, 59, 59), hnsecs(1)), 0,
7487 SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1)));
7488 testST(SysTime(DateTime(2007, 12, 11, 23, 59, 59)), 0, SysTime(DateTime(0, 12, 31, 23, 59, 59)));
7491 auto st = SysTime(DateTime(1, 1, 1, 12, 2, 9), msecs(212));
7493 void testST2(int day, SysTime expected, size_t line = __LINE__) @safe
7495 st.dayOfGregorianCal = day;
7496 if (st != expected)
7497 throw new AssertError(format("Failed. actual [%s] != expected [%s]", st, expected), __FILE__, line);
7500 // Test A.D.
7501 testST2(1, SysTime(DateTime(1, 1, 1, 12, 2, 9), msecs(212)));
7502 testST2(2, SysTime(DateTime(1, 1, 2, 12, 2, 9), msecs(212)));
7503 testST2(32, SysTime(DateTime(1, 2, 1, 12, 2, 9), msecs(212)));
7504 testST2(366, SysTime(DateTime(2, 1, 1, 12, 2, 9), msecs(212)));
7505 testST2(731, SysTime(DateTime(3, 1, 1, 12, 2, 9), msecs(212)));
7506 testST2(1096, SysTime(DateTime(4, 1, 1, 12, 2, 9), msecs(212)));
7507 testST2(1462, SysTime(DateTime(5, 1, 1, 12, 2, 9), msecs(212)));
7508 testST2(17_898, SysTime(DateTime(50, 1, 1, 12, 2, 9), msecs(212)));
7509 testST2(35_065, SysTime(DateTime(97, 1, 1, 12, 2, 9), msecs(212)));
7510 testST2(36_160, SysTime(DateTime(100, 1, 1, 12, 2, 9), msecs(212)));
7511 testST2(36_525, SysTime(DateTime(101, 1, 1, 12, 2, 9), msecs(212)));
7512 testST2(37_986, SysTime(DateTime(105, 1, 1, 12, 2, 9), msecs(212)));
7513 testST2(72_684, SysTime(DateTime(200, 1, 1, 12, 2, 9), msecs(212)));
7514 testST2(73_049, SysTime(DateTime(201, 1, 1, 12, 2, 9), msecs(212)));
7515 testST2(109_208, SysTime(DateTime(300, 1, 1, 12, 2, 9), msecs(212)));
7516 testST2(109_573, SysTime(DateTime(301, 1, 1, 12, 2, 9), msecs(212)));
7517 testST2(145_732, SysTime(DateTime(400, 1, 1, 12, 2, 9), msecs(212)));
7518 testST2(146_098, SysTime(DateTime(401, 1, 1, 12, 2, 9), msecs(212)));
7519 testST2(182_257, SysTime(DateTime(500, 1, 1, 12, 2, 9), msecs(212)));
7520 testST2(182_622, SysTime(DateTime(501, 1, 1, 12, 2, 9), msecs(212)));
7521 testST2(364_878, SysTime(DateTime(1000, 1, 1, 12, 2, 9), msecs(212)));
7522 testST2(365_243, SysTime(DateTime(1001, 1, 1, 12, 2, 9), msecs(212)));
7523 testST2(584_023, SysTime(DateTime(1600, 1, 1, 12, 2, 9), msecs(212)));
7524 testST2(584_389, SysTime(DateTime(1601, 1, 1, 12, 2, 9), msecs(212)));
7525 testST2(693_596, SysTime(DateTime(1900, 1, 1, 12, 2, 9), msecs(212)));
7526 testST2(693_961, SysTime(DateTime(1901, 1, 1, 12, 2, 9), msecs(212)));
7527 testST2(729_755, SysTime(DateTime(1999, 1, 1, 12, 2, 9), msecs(212)));
7528 testST2(730_120, SysTime(DateTime(2000, 1, 1, 12, 2, 9), msecs(212)));
7529 testST2(730_486, SysTime(DateTime(2001, 1, 1, 12, 2, 9), msecs(212)));
7531 testST2(733_773, SysTime(DateTime(2010, 1, 1, 12, 2, 9), msecs(212)));
7532 testST2(733_803, SysTime(DateTime(2010, 1, 31, 12, 2, 9), msecs(212)));
7533 testST2(733_804, SysTime(DateTime(2010, 2, 1, 12, 2, 9), msecs(212)));
7534 testST2(733_831, SysTime(DateTime(2010, 2, 28, 12, 2, 9), msecs(212)));
7535 testST2(733_832, SysTime(DateTime(2010, 3, 1, 12, 2, 9), msecs(212)));
7536 testST2(733_862, SysTime(DateTime(2010, 3, 31, 12, 2, 9), msecs(212)));
7537 testST2(733_863, SysTime(DateTime(2010, 4, 1, 12, 2, 9), msecs(212)));
7538 testST2(733_892, SysTime(DateTime(2010, 4, 30, 12, 2, 9), msecs(212)));
7539 testST2(733_893, SysTime(DateTime(2010, 5, 1, 12, 2, 9), msecs(212)));
7540 testST2(733_923, SysTime(DateTime(2010, 5, 31, 12, 2, 9), msecs(212)));
7541 testST2(733_924, SysTime(DateTime(2010, 6, 1, 12, 2, 9), msecs(212)));
7542 testST2(733_953, SysTime(DateTime(2010, 6, 30, 12, 2, 9), msecs(212)));
7543 testST2(733_954, SysTime(DateTime(2010, 7, 1, 12, 2, 9), msecs(212)));
7544 testST2(733_984, SysTime(DateTime(2010, 7, 31, 12, 2, 9), msecs(212)));
7545 testST2(733_985, SysTime(DateTime(2010, 8, 1, 12, 2, 9), msecs(212)));
7546 testST2(734_015, SysTime(DateTime(2010, 8, 31, 12, 2, 9), msecs(212)));
7547 testST2(734_016, SysTime(DateTime(2010, 9, 1, 12, 2, 9), msecs(212)));
7548 testST2(734_045, SysTime(DateTime(2010, 9, 30, 12, 2, 9), msecs(212)));
7549 testST2(734_046, SysTime(DateTime(2010, 10, 1, 12, 2, 9), msecs(212)));
7550 testST2(734_076, SysTime(DateTime(2010, 10, 31, 12, 2, 9), msecs(212)));
7551 testST2(734_077, SysTime(DateTime(2010, 11, 1, 12, 2, 9), msecs(212)));
7552 testST2(734_106, SysTime(DateTime(2010, 11, 30, 12, 2, 9), msecs(212)));
7553 testST2(734_107, SysTime(DateTime(2010, 12, 1, 12, 2, 9), msecs(212)));
7554 testST2(734_137, SysTime(DateTime(2010, 12, 31, 12, 2, 9), msecs(212)));
7556 testST2(734_534, SysTime(DateTime(2012, 2, 1, 12, 2, 9), msecs(212)));
7557 testST2(734_561, SysTime(DateTime(2012, 2, 28, 12, 2, 9), msecs(212)));
7558 testST2(734_562, SysTime(DateTime(2012, 2, 29, 12, 2, 9), msecs(212)));
7559 testST2(734_563, SysTime(DateTime(2012, 3, 1, 12, 2, 9), msecs(212)));
7561 testST2(734_534, SysTime(DateTime(2012, 2, 1, 12, 2, 9), msecs(212)));
7563 testST2(734_561, SysTime(DateTime(2012, 2, 28, 12, 2, 9), msecs(212)));
7564 testST2(734_562, SysTime(DateTime(2012, 2, 29, 12, 2, 9), msecs(212)));
7565 testST2(734_563, SysTime(DateTime(2012, 3, 1, 12, 2, 9), msecs(212)));
7567 // Test B.C.
7568 testST2(0, SysTime(DateTime(0, 12, 31, 12, 2, 9), msecs(212)));
7569 testST2(-1, SysTime(DateTime(0, 12, 30, 12, 2, 9), msecs(212)));
7570 testST2(-30, SysTime(DateTime(0, 12, 1, 12, 2, 9), msecs(212)));
7571 testST2(-31, SysTime(DateTime(0, 11, 30, 12, 2, 9), msecs(212)));
7573 testST2(-366, SysTime(DateTime(-1, 12, 31, 12, 2, 9), msecs(212)));
7574 testST2(-367, SysTime(DateTime(-1, 12, 30, 12, 2, 9), msecs(212)));
7575 testST2(-730, SysTime(DateTime(-1, 1, 1, 12, 2, 9), msecs(212)));
7576 testST2(-731, SysTime(DateTime(-2, 12, 31, 12, 2, 9), msecs(212)));
7577 testST2(-1095, SysTime(DateTime(-2, 1, 1, 12, 2, 9), msecs(212)));
7578 testST2(-1096, SysTime(DateTime(-3, 12, 31, 12, 2, 9), msecs(212)));
7579 testST2(-1460, SysTime(DateTime(-3, 1, 1, 12, 2, 9), msecs(212)));
7580 testST2(-1461, SysTime(DateTime(-4, 12, 31, 12, 2, 9), msecs(212)));
7581 testST2(-1826, SysTime(DateTime(-4, 1, 1, 12, 2, 9), msecs(212)));
7582 testST2(-1827, SysTime(DateTime(-5, 12, 31, 12, 2, 9), msecs(212)));
7583 testST2(-2191, SysTime(DateTime(-5, 1, 1, 12, 2, 9), msecs(212)));
7584 testST2(-3652, SysTime(DateTime(-9, 1, 1, 12, 2, 9), msecs(212)));
7586 testST2(-18_262, SysTime(DateTime(-49, 1, 1, 12, 2, 9), msecs(212)));
7587 testST2(-18_627, SysTime(DateTime(-50, 1, 1, 12, 2, 9), msecs(212)));
7588 testST2(-35_794, SysTime(DateTime(-97, 1, 1, 12, 2, 9), msecs(212)));
7589 testST2(-36_160, SysTime(DateTime(-99, 12, 31, 12, 2, 9), msecs(212)));
7590 testST2(-36_524, SysTime(DateTime(-99, 1, 1, 12, 2, 9), msecs(212)));
7591 testST2(-36_889, SysTime(DateTime(-100, 1, 1, 12, 2, 9), msecs(212)));
7592 testST2(-37_254, SysTime(DateTime(-101, 1, 1, 12, 2, 9), msecs(212)));
7593 testST2(-38_715, SysTime(DateTime(-105, 1, 1, 12, 2, 9), msecs(212)));
7594 testST2(-73_413, SysTime(DateTime(-200, 1, 1, 12, 2, 9), msecs(212)));
7595 testST2(-73_778, SysTime(DateTime(-201, 1, 1, 12, 2, 9), msecs(212)));
7596 testST2(-109_937, SysTime(DateTime(-300, 1, 1, 12, 2, 9), msecs(212)));
7597 testST2(-110_302, SysTime(DateTime(-301, 1, 1, 12, 2, 9), msecs(212)));
7598 testST2(-146_097, SysTime(DateTime(-400, 12, 31, 12, 2, 9), msecs(212)));
7599 testST2(-146_462, SysTime(DateTime(-400, 1, 1, 12, 2, 9), msecs(212)));
7600 testST2(-146_827, SysTime(DateTime(-401, 1, 1, 12, 2, 9), msecs(212)));
7601 testST2(-182_621, SysTime(DateTime(-499, 1, 1, 12, 2, 9), msecs(212)));
7602 testST2(-182_986, SysTime(DateTime(-500, 1, 1, 12, 2, 9), msecs(212)));
7603 testST2(-183_351, SysTime(DateTime(-501, 1, 1, 12, 2, 9), msecs(212)));
7604 testST2(-365_607, SysTime(DateTime(-1000, 1, 1, 12, 2, 9), msecs(212)));
7605 testST2(-365_972, SysTime(DateTime(-1001, 1, 1, 12, 2, 9), msecs(212)));
7606 testST2(-584_387, SysTime(DateTime(-1599, 1, 1, 12, 2, 9), msecs(212)));
7607 testST2(-584_388, SysTime(DateTime(-1600, 12, 31, 12, 2, 9), msecs(212)));
7608 testST2(-584_753, SysTime(DateTime(-1600, 1, 1, 12, 2, 9), msecs(212)));
7609 testST2(-585_118, SysTime(DateTime(-1601, 1, 1, 12, 2, 9), msecs(212)));
7610 testST2(-694_325, SysTime(DateTime(-1900, 1, 1, 12, 2, 9), msecs(212)));
7611 testST2(-694_690, SysTime(DateTime(-1901, 1, 1, 12, 2, 9), msecs(212)));
7612 testST2(-730_484, SysTime(DateTime(-1999, 1, 1, 12, 2, 9), msecs(212)));
7613 testST2(-730_485, SysTime(DateTime(-2000, 12, 31, 12, 2, 9), msecs(212)));
7614 testST2(-730_850, SysTime(DateTime(-2000, 1, 1, 12, 2, 9), msecs(212)));
7615 testST2(-731_215, SysTime(DateTime(-2001, 1, 1, 12, 2, 9), msecs(212)));
7617 testST2(-734_502, SysTime(DateTime(-2010, 1, 1, 12, 2, 9), msecs(212)));
7618 testST2(-734_472, SysTime(DateTime(-2010, 1, 31, 12, 2, 9), msecs(212)));
7619 testST2(-734_471, SysTime(DateTime(-2010, 2, 1, 12, 2, 9), msecs(212)));
7620 testST2(-734_444, SysTime(DateTime(-2010, 2, 28, 12, 2, 9), msecs(212)));
7621 testST2(-734_443, SysTime(DateTime(-2010, 3, 1, 12, 2, 9), msecs(212)));
7622 testST2(-734_413, SysTime(DateTime(-2010, 3, 31, 12, 2, 9), msecs(212)));
7623 testST2(-734_412, SysTime(DateTime(-2010, 4, 1, 12, 2, 9), msecs(212)));
7624 testST2(-734_383, SysTime(DateTime(-2010, 4, 30, 12, 2, 9), msecs(212)));
7625 testST2(-734_382, SysTime(DateTime(-2010, 5, 1, 12, 2, 9), msecs(212)));
7626 testST2(-734_352, SysTime(DateTime(-2010, 5, 31, 12, 2, 9), msecs(212)));
7627 testST2(-734_351, SysTime(DateTime(-2010, 6, 1, 12, 2, 9), msecs(212)));
7628 testST2(-734_322, SysTime(DateTime(-2010, 6, 30, 12, 2, 9), msecs(212)));
7629 testST2(-734_321, SysTime(DateTime(-2010, 7, 1, 12, 2, 9), msecs(212)));
7630 testST2(-734_291, SysTime(DateTime(-2010, 7, 31, 12, 2, 9), msecs(212)));
7631 testST2(-734_290, SysTime(DateTime(-2010, 8, 1, 12, 2, 9), msecs(212)));
7632 testST2(-734_260, SysTime(DateTime(-2010, 8, 31, 12, 2, 9), msecs(212)));
7633 testST2(-734_259, SysTime(DateTime(-2010, 9, 1, 12, 2, 9), msecs(212)));
7634 testST2(-734_230, SysTime(DateTime(-2010, 9, 30, 12, 2, 9), msecs(212)));
7635 testST2(-734_229, SysTime(DateTime(-2010, 10, 1, 12, 2, 9), msecs(212)));
7636 testST2(-734_199, SysTime(DateTime(-2010, 10, 31, 12, 2, 9), msecs(212)));
7637 testST2(-734_198, SysTime(DateTime(-2010, 11, 1, 12, 2, 9), msecs(212)));
7638 testST2(-734_169, SysTime(DateTime(-2010, 11, 30, 12, 2, 9), msecs(212)));
7639 testST2(-734_168, SysTime(DateTime(-2010, 12, 1, 12, 2, 9), msecs(212)));
7640 testST2(-734_138, SysTime(DateTime(-2010, 12, 31, 12, 2, 9), msecs(212)));
7642 testST2(-735_202, SysTime(DateTime(-2012, 2, 1, 12, 2, 9), msecs(212)));
7643 testST2(-735_175, SysTime(DateTime(-2012, 2, 28, 12, 2, 9), msecs(212)));
7644 testST2(-735_174, SysTime(DateTime(-2012, 2, 29, 12, 2, 9), msecs(212)));
7645 testST2(-735_173, SysTime(DateTime(-2012, 3, 1, 12, 2, 9), msecs(212)));
7647 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
7648 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
7649 static assert(!__traits(compiles, cst.dayOfGregorianCal = 7));
7650 static assert(!__traits(compiles, ist.dayOfGregorianCal = 7));
7652 static void testScope(scope ref SysTime st) @safe
7654 st.dayOfGregorianCal = 42;
7660 The ISO 8601 week of the year that this $(LREF SysTime) is in.
7662 See_Also:
7663 $(HTTP en.wikipedia.org/wiki/ISO_week_date, ISO Week Date).
7665 @property ubyte isoWeek() @safe const nothrow scope
7667 return (cast(Date) this).isoWeek;
7671 @safe unittest
7673 import core.time;
7674 import std.datetime.date : Date;
7676 auto st = SysTime(Date(1999, 7, 6));
7677 const cst = SysTime(Date(2010, 5, 1));
7678 immutable ist = SysTime(Date(2015, 10, 10));
7680 assert(st.isoWeek == 27);
7681 assert(cst.isoWeek == 17);
7682 assert(ist.isoWeek == 41);
7685 @safe unittest
7687 static void testScope(scope ref SysTime st) @safe
7689 auto result = st.isoWeek;
7695 $(LREF SysTime) for the last day in the month that this Date is in.
7696 The time portion of endOfMonth is always 23:59:59.9999999.
7698 @property SysTime endOfMonth() @safe const nothrow return scope
7700 immutable hnsecs = adjTime;
7701 immutable days = getUnitsFromHNSecs!"days"(hnsecs);
7703 auto date = Date(cast(int) days + 1).endOfMonth;
7704 auto newDays = date.dayOfGregorianCal - 1;
7705 long theTimeHNSecs;
7707 if (newDays < 0)
7709 theTimeHNSecs = -1;
7710 ++newDays;
7712 else
7713 theTimeHNSecs = convert!("days", "hnsecs")(1) - 1;
7715 immutable newDaysHNSecs = convert!("days", "hnsecs")(newDays);
7717 auto retval = SysTime(this._stdTime, this._timezone);
7718 retval.adjTime = newDaysHNSecs + theTimeHNSecs;
7720 return retval;
7724 @safe unittest
7726 import core.time : msecs, usecs, hnsecs;
7727 import std.datetime.date : DateTime;
7729 assert(SysTime(DateTime(1999, 1, 6, 0, 0, 0)).endOfMonth ==
7730 SysTime(DateTime(1999, 1, 31, 23, 59, 59), hnsecs(9_999_999)));
7732 assert(SysTime(DateTime(1999, 2, 7, 19, 30, 0), msecs(24)).endOfMonth ==
7733 SysTime(DateTime(1999, 2, 28, 23, 59, 59), hnsecs(9_999_999)));
7735 assert(SysTime(DateTime(2000, 2, 7, 5, 12, 27), usecs(5203)).endOfMonth ==
7736 SysTime(DateTime(2000, 2, 29, 23, 59, 59), hnsecs(9_999_999)));
7738 assert(SysTime(DateTime(2000, 6, 4, 12, 22, 9), hnsecs(12345)).endOfMonth ==
7739 SysTime(DateTime(2000, 6, 30, 23, 59, 59), hnsecs(9_999_999)));
7742 @safe unittest
7744 import core.time;
7745 // Test A.D.
7746 assert(SysTime(Date(1999, 1, 1)).endOfMonth == SysTime(DateTime(1999, 1, 31, 23, 59, 59), hnsecs(9_999_999)));
7747 assert(SysTime(Date(1999, 2, 1)).endOfMonth == SysTime(DateTime(1999, 2, 28, 23, 59, 59), hnsecs(9_999_999)));
7748 assert(SysTime(Date(2000, 2, 1)).endOfMonth == SysTime(DateTime(2000, 2, 29, 23, 59, 59), hnsecs(9_999_999)));
7749 assert(SysTime(Date(1999, 3, 1)).endOfMonth == SysTime(DateTime(1999, 3, 31, 23, 59, 59), hnsecs(9_999_999)));
7750 assert(SysTime(Date(1999, 4, 1)).endOfMonth == SysTime(DateTime(1999, 4, 30, 23, 59, 59), hnsecs(9_999_999)));
7751 assert(SysTime(Date(1999, 5, 1)).endOfMonth == SysTime(DateTime(1999, 5, 31, 23, 59, 59), hnsecs(9_999_999)));
7752 assert(SysTime(Date(1999, 6, 1)).endOfMonth == SysTime(DateTime(1999, 6, 30, 23, 59, 59), hnsecs(9_999_999)));
7753 assert(SysTime(Date(1999, 7, 1)).endOfMonth == SysTime(DateTime(1999, 7, 31, 23, 59, 59), hnsecs(9_999_999)));
7754 assert(SysTime(Date(1999, 8, 1)).endOfMonth == SysTime(DateTime(1999, 8, 31, 23, 59, 59), hnsecs(9_999_999)));
7755 assert(SysTime(Date(1999, 9, 1)).endOfMonth == SysTime(DateTime(1999, 9, 30, 23, 59, 59), hnsecs(9_999_999)));
7756 assert(SysTime(Date(1999, 10, 1)).endOfMonth == SysTime(DateTime(1999, 10, 31, 23, 59, 59), hnsecs(9_999_999)));
7757 assert(SysTime(Date(1999, 11, 1)).endOfMonth == SysTime(DateTime(1999, 11, 30, 23, 59, 59), hnsecs(9_999_999)));
7758 assert(SysTime(Date(1999, 12, 1)).endOfMonth == SysTime(DateTime(1999, 12, 31, 23, 59, 59), hnsecs(9_999_999)));
7760 // Test B.C.
7761 assert(SysTime(Date(-1999, 1, 1)).endOfMonth == SysTime(DateTime(-1999, 1, 31, 23, 59, 59), hnsecs(9_999_999)));
7762 assert(SysTime(Date(-1999, 2, 1)).endOfMonth == SysTime(DateTime(-1999, 2, 28, 23, 59, 59), hnsecs(9_999_999)));
7763 assert(SysTime(Date(-2000, 2, 1)).endOfMonth == SysTime(DateTime(-2000, 2, 29, 23, 59, 59), hnsecs(9_999_999)));
7764 assert(SysTime(Date(-1999, 3, 1)).endOfMonth == SysTime(DateTime(-1999, 3, 31, 23, 59, 59), hnsecs(9_999_999)));
7765 assert(SysTime(Date(-1999, 4, 1)).endOfMonth == SysTime(DateTime(-1999, 4, 30, 23, 59, 59), hnsecs(9_999_999)));
7766 assert(SysTime(Date(-1999, 5, 1)).endOfMonth == SysTime(DateTime(-1999, 5, 31, 23, 59, 59), hnsecs(9_999_999)));
7767 assert(SysTime(Date(-1999, 6, 1)).endOfMonth == SysTime(DateTime(-1999, 6, 30, 23, 59, 59), hnsecs(9_999_999)));
7768 assert(SysTime(Date(-1999, 7, 1)).endOfMonth == SysTime(DateTime(-1999, 7, 31, 23, 59, 59), hnsecs(9_999_999)));
7769 assert(SysTime(Date(-1999, 8, 1)).endOfMonth == SysTime(DateTime(-1999, 8, 31, 23, 59, 59), hnsecs(9_999_999)));
7770 assert(SysTime(Date(-1999, 9, 1)).endOfMonth == SysTime(DateTime(-1999, 9, 30, 23, 59, 59), hnsecs(9_999_999)));
7771 assert(SysTime(Date(-1999, 10, 1)).endOfMonth ==
7772 SysTime(DateTime(-1999, 10, 31, 23, 59, 59), hnsecs(9_999_999)));
7773 assert(SysTime(Date(-1999, 11, 1)).endOfMonth ==
7774 SysTime(DateTime(-1999, 11, 30, 23, 59, 59), hnsecs(9_999_999)));
7775 assert(SysTime(Date(-1999, 12, 1)).endOfMonth ==
7776 SysTime(DateTime(-1999, 12, 31, 23, 59, 59), hnsecs(9_999_999)));
7778 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
7779 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
7780 assert(cst.endOfMonth == SysTime(DateTime(1999, 7, 31, 23, 59, 59), hnsecs(9_999_999)));
7781 assert(ist.endOfMonth == SysTime(DateTime(1999, 7, 31, 23, 59, 59), hnsecs(9_999_999)));
7783 static void testScope(scope ref SysTime st) @safe
7785 auto result = st.endOfMonth;
7791 The last day in the month that this $(LREF SysTime) is in.
7793 @property ubyte daysInMonth() @safe const nothrow scope
7795 return Date(dayOfGregorianCal).daysInMonth;
7799 @safe unittest
7801 import core.time;
7802 import std.datetime.date : DateTime;
7804 assert(SysTime(DateTime(1999, 1, 6, 0, 0, 0)).daysInMonth == 31);
7805 assert(SysTime(DateTime(1999, 2, 7, 19, 30, 0)).daysInMonth == 28);
7806 assert(SysTime(DateTime(2000, 2, 7, 5, 12, 27)).daysInMonth == 29);
7807 assert(SysTime(DateTime(2000, 6, 4, 12, 22, 9)).daysInMonth == 30);
7810 @safe unittest
7812 import core.time;
7813 // Test A.D.
7814 assert(SysTime(DateTime(1999, 1, 1, 12, 1, 13)).daysInMonth == 31);
7815 assert(SysTime(DateTime(1999, 2, 1, 17, 13, 12)).daysInMonth == 28);
7816 assert(SysTime(DateTime(2000, 2, 1, 13, 2, 12)).daysInMonth == 29);
7817 assert(SysTime(DateTime(1999, 3, 1, 12, 13, 12)).daysInMonth == 31);
7818 assert(SysTime(DateTime(1999, 4, 1, 12, 6, 13)).daysInMonth == 30);
7819 assert(SysTime(DateTime(1999, 5, 1, 15, 13, 12)).daysInMonth == 31);
7820 assert(SysTime(DateTime(1999, 6, 1, 13, 7, 12)).daysInMonth == 30);
7821 assert(SysTime(DateTime(1999, 7, 1, 12, 13, 17)).daysInMonth == 31);
7822 assert(SysTime(DateTime(1999, 8, 1, 12, 3, 13)).daysInMonth == 31);
7823 assert(SysTime(DateTime(1999, 9, 1, 12, 13, 12)).daysInMonth == 30);
7824 assert(SysTime(DateTime(1999, 10, 1, 13, 19, 12)).daysInMonth == 31);
7825 assert(SysTime(DateTime(1999, 11, 1, 12, 13, 17)).daysInMonth == 30);
7826 assert(SysTime(DateTime(1999, 12, 1, 12, 52, 13)).daysInMonth == 31);
7828 // Test B.C.
7829 assert(SysTime(DateTime(-1999, 1, 1, 12, 1, 13)).daysInMonth == 31);
7830 assert(SysTime(DateTime(-1999, 2, 1, 7, 13, 12)).daysInMonth == 28);
7831 assert(SysTime(DateTime(-2000, 2, 1, 13, 2, 12)).daysInMonth == 29);
7832 assert(SysTime(DateTime(-1999, 3, 1, 12, 13, 12)).daysInMonth == 31);
7833 assert(SysTime(DateTime(-1999, 4, 1, 12, 6, 13)).daysInMonth == 30);
7834 assert(SysTime(DateTime(-1999, 5, 1, 5, 13, 12)).daysInMonth == 31);
7835 assert(SysTime(DateTime(-1999, 6, 1, 13, 7, 12)).daysInMonth == 30);
7836 assert(SysTime(DateTime(-1999, 7, 1, 12, 13, 17)).daysInMonth == 31);
7837 assert(SysTime(DateTime(-1999, 8, 1, 12, 3, 13)).daysInMonth == 31);
7838 assert(SysTime(DateTime(-1999, 9, 1, 12, 13, 12)).daysInMonth == 30);
7839 assert(SysTime(DateTime(-1999, 10, 1, 13, 19, 12)).daysInMonth == 31);
7840 assert(SysTime(DateTime(-1999, 11, 1, 12, 13, 17)).daysInMonth == 30);
7841 assert(SysTime(DateTime(-1999, 12, 1, 12, 52, 13)).daysInMonth == 31);
7843 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
7844 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
7845 assert(cst.daysInMonth == 31);
7846 assert(ist.daysInMonth == 31);
7848 static void testScope(scope ref SysTime st) @safe
7850 auto result = st.daysInMonth;
7856 Whether the current year is a date in A.D.
7858 @property bool isAD() @safe const nothrow scope
7860 return adjTime >= 0;
7864 @safe unittest
7866 import core.time;
7867 import std.datetime.date : DateTime;
7869 assert(SysTime(DateTime(1, 1, 1, 12, 7, 0)).isAD);
7870 assert(SysTime(DateTime(2010, 12, 31, 0, 0, 0)).isAD);
7871 assert(!SysTime(DateTime(0, 12, 31, 23, 59, 59)).isAD);
7872 assert(!SysTime(DateTime(-2010, 1, 1, 2, 2, 2)).isAD);
7875 @safe unittest
7877 import core.time;
7878 assert(SysTime(DateTime(2010, 7, 4, 12, 0, 9)).isAD);
7879 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).isAD);
7880 assert(!SysTime(DateTime(0, 12, 31, 23, 59, 59)).isAD);
7881 assert(!SysTime(DateTime(0, 1, 1, 23, 59, 59)).isAD);
7882 assert(!SysTime(DateTime(-1, 1, 1, 23 ,59 ,59)).isAD);
7883 assert(!SysTime(DateTime(-2010, 7, 4, 12, 2, 2)).isAD);
7885 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
7886 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
7887 assert(cst.isAD);
7888 assert(ist.isAD);
7890 static void testScope(scope ref SysTime st) @safe
7892 auto result = st.isAD;
7898 The $(HTTP en.wikipedia.org/wiki/Julian_day, Julian day)
7899 for this $(LREF SysTime) at the given time. For example,
7900 prior to noon, 1996-03-31 would be the Julian day number 2_450_173, so
7901 this function returns 2_450_173, while from noon onward, the Julian
7902 day number would be 2_450_174, so this function returns 2_450_174.
7904 @property long julianDay() @safe const nothrow scope
7906 immutable jd = dayOfGregorianCal + 1_721_425;
7907 return hour < 12 ? jd - 1 : jd;
7910 @safe unittest
7912 import core.time;
7913 assert(SysTime(DateTime(-4713, 11, 24, 0, 0, 0)).julianDay == -1);
7914 assert(SysTime(DateTime(-4713, 11, 24, 12, 0, 0)).julianDay == 0);
7916 assert(SysTime(DateTime(0, 12, 31, 0, 0, 0)).julianDay == 1_721_424);
7917 assert(SysTime(DateTime(0, 12, 31, 12, 0, 0)).julianDay == 1_721_425);
7919 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).julianDay == 1_721_425);
7920 assert(SysTime(DateTime(1, 1, 1, 12, 0, 0)).julianDay == 1_721_426);
7922 assert(SysTime(DateTime(1582, 10, 15, 0, 0, 0)).julianDay == 2_299_160);
7923 assert(SysTime(DateTime(1582, 10, 15, 12, 0, 0)).julianDay == 2_299_161);
7925 assert(SysTime(DateTime(1858, 11, 17, 0, 0, 0)).julianDay == 2_400_000);
7926 assert(SysTime(DateTime(1858, 11, 17, 12, 0, 0)).julianDay == 2_400_001);
7928 assert(SysTime(DateTime(1982, 1, 4, 0, 0, 0)).julianDay == 2_444_973);
7929 assert(SysTime(DateTime(1982, 1, 4, 12, 0, 0)).julianDay == 2_444_974);
7931 assert(SysTime(DateTime(1996, 3, 31, 0, 0, 0)).julianDay == 2_450_173);
7932 assert(SysTime(DateTime(1996, 3, 31, 12, 0, 0)).julianDay == 2_450_174);
7934 assert(SysTime(DateTime(2010, 8, 24, 0, 0, 0)).julianDay == 2_455_432);
7935 assert(SysTime(DateTime(2010, 8, 24, 12, 0, 0)).julianDay == 2_455_433);
7937 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
7938 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
7939 assert(cst.julianDay == 2_451_366);
7940 assert(ist.julianDay == 2_451_366);
7942 static void testScope(scope ref SysTime st) @safe
7944 auto result = st.julianDay;
7950 The modified $(HTTP en.wikipedia.org/wiki/Julian_day, Julian day) for
7951 any time on this date (since, the modified Julian day changes at
7952 midnight).
7954 @property long modJulianDay() @safe const nothrow scope
7956 return dayOfGregorianCal + 1_721_425 - 2_400_001;
7959 @safe unittest
7961 import core.time;
7962 assert(SysTime(DateTime(1858, 11, 17, 0, 0, 0)).modJulianDay == 0);
7963 assert(SysTime(DateTime(1858, 11, 17, 12, 0, 0)).modJulianDay == 0);
7965 assert(SysTime(DateTime(2010, 8, 24, 0, 0, 0)).modJulianDay == 55_432);
7966 assert(SysTime(DateTime(2010, 8, 24, 12, 0, 0)).modJulianDay == 55_432);
7968 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
7969 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
7970 assert(cst.modJulianDay == 51_365);
7971 assert(ist.modJulianDay == 51_365);
7973 static void testScope(scope ref SysTime st) @safe
7975 auto result = st.modJulianDay;
7981 Returns a $(REF Date,std,datetime,date) equivalent to this $(LREF SysTime).
7983 Date opCast(T)() @safe const nothrow scope
7984 if (is(immutable T == immutable Date))
7986 return Date(dayOfGregorianCal);
7989 @safe unittest
7991 import core.time;
7992 assert(cast(Date) SysTime(Date(1999, 7, 6)) == Date(1999, 7, 6));
7993 assert(cast(Date) SysTime(Date(2000, 12, 31)) == Date(2000, 12, 31));
7994 assert(cast(Date) SysTime(Date(2001, 1, 1)) == Date(2001, 1, 1));
7996 assert(cast(Date) SysTime(DateTime(1999, 7, 6, 12, 10, 9)) == Date(1999, 7, 6));
7997 assert(cast(Date) SysTime(DateTime(2000, 12, 31, 13, 11, 10)) == Date(2000, 12, 31));
7998 assert(cast(Date) SysTime(DateTime(2001, 1, 1, 14, 12, 11)) == Date(2001, 1, 1));
8000 assert(cast(Date) SysTime(Date(-1999, 7, 6)) == Date(-1999, 7, 6));
8001 assert(cast(Date) SysTime(Date(-2000, 12, 31)) == Date(-2000, 12, 31));
8002 assert(cast(Date) SysTime(Date(-2001, 1, 1)) == Date(-2001, 1, 1));
8004 assert(cast(Date) SysTime(DateTime(-1999, 7, 6, 12, 10, 9)) == Date(-1999, 7, 6));
8005 assert(cast(Date) SysTime(DateTime(-2000, 12, 31, 13, 11, 10)) == Date(-2000, 12, 31));
8006 assert(cast(Date) SysTime(DateTime(-2001, 1, 1, 14, 12, 11)) == Date(-2001, 1, 1));
8008 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
8009 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
8010 assert(cast(Date) cst != Date.init);
8011 assert(cast(Date) ist != Date.init);
8013 static void testScope(scope ref SysTime st) @safe
8015 auto result = cast(Date) st;
8021 Returns a $(REF DateTime,std,datetime,date) equivalent to this
8022 $(LREF SysTime).
8024 DateTime opCast(T)() @safe const nothrow scope
8025 if (is(immutable T == immutable DateTime))
8029 auto hnsecs = adjTime;
8030 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
8032 if (hnsecs < 0)
8034 hnsecs += convert!("hours", "hnsecs")(24);
8035 --days;
8038 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs);
8039 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs);
8040 immutable second = getUnitsFromHNSecs!"seconds"(hnsecs);
8042 return DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour, cast(int) minute, cast(int) second));
8044 catch (Exception e)
8045 assert(0, "Either DateTime's constructor or TimeOfDay's constructor threw.");
8048 @safe unittest
8050 import core.time;
8051 assert(cast(DateTime) SysTime(DateTime(1, 1, 6, 7, 12, 22)) == DateTime(1, 1, 6, 7, 12, 22));
8052 assert(cast(DateTime) SysTime(DateTime(1, 1, 6, 7, 12, 22), msecs(22)) == DateTime(1, 1, 6, 7, 12, 22));
8053 assert(cast(DateTime) SysTime(Date(1999, 7, 6)) == DateTime(1999, 7, 6, 0, 0, 0));
8054 assert(cast(DateTime) SysTime(Date(2000, 12, 31)) == DateTime(2000, 12, 31, 0, 0, 0));
8055 assert(cast(DateTime) SysTime(Date(2001, 1, 1)) == DateTime(2001, 1, 1, 0, 0, 0));
8057 assert(cast(DateTime) SysTime(DateTime(1999, 7, 6, 12, 10, 9)) == DateTime(1999, 7, 6, 12, 10, 9));
8058 assert(cast(DateTime) SysTime(DateTime(2000, 12, 31, 13, 11, 10)) == DateTime(2000, 12, 31, 13, 11, 10));
8059 assert(cast(DateTime) SysTime(DateTime(2001, 1, 1, 14, 12, 11)) == DateTime(2001, 1, 1, 14, 12, 11));
8061 assert(cast(DateTime) SysTime(DateTime(-1, 1, 6, 7, 12, 22)) == DateTime(-1, 1, 6, 7, 12, 22));
8062 assert(cast(DateTime) SysTime(DateTime(-1, 1, 6, 7, 12, 22), msecs(22)) == DateTime(-1, 1, 6, 7, 12, 22));
8063 assert(cast(DateTime) SysTime(Date(-1999, 7, 6)) == DateTime(-1999, 7, 6, 0, 0, 0));
8064 assert(cast(DateTime) SysTime(Date(-2000, 12, 31)) == DateTime(-2000, 12, 31, 0, 0, 0));
8065 assert(cast(DateTime) SysTime(Date(-2001, 1, 1)) == DateTime(-2001, 1, 1, 0, 0, 0));
8067 assert(cast(DateTime) SysTime(DateTime(-1999, 7, 6, 12, 10, 9)) == DateTime(-1999, 7, 6, 12, 10, 9));
8068 assert(cast(DateTime) SysTime(DateTime(-2000, 12, 31, 13, 11, 10)) == DateTime(-2000, 12, 31, 13, 11, 10));
8069 assert(cast(DateTime) SysTime(DateTime(-2001, 1, 1, 14, 12, 11)) == DateTime(-2001, 1, 1, 14, 12, 11));
8071 assert(cast(DateTime) SysTime(DateTime(2011, 1, 13, 8, 17, 2), msecs(296), LocalTime()) ==
8072 DateTime(2011, 1, 13, 8, 17, 2));
8074 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
8075 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
8076 assert(cast(DateTime) cst != DateTime.init);
8077 assert(cast(DateTime) ist != DateTime.init);
8079 static void testScope(scope ref SysTime st) @safe
8081 auto result = cast(DateTime) st;
8087 Returns a $(REF TimeOfDay,std,datetime,date) equivalent to this
8088 $(LREF SysTime).
8090 TimeOfDay opCast(T)() @safe const nothrow scope
8091 if (is(immutable T == immutable TimeOfDay))
8095 auto hnsecs = adjTime;
8096 hnsecs = removeUnitsFromHNSecs!"days"(hnsecs);
8098 if (hnsecs < 0)
8099 hnsecs += convert!("hours", "hnsecs")(24);
8101 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs);
8102 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs);
8103 immutable second = getUnitsFromHNSecs!"seconds"(hnsecs);
8105 return TimeOfDay(cast(int) hour, cast(int) minute, cast(int) second);
8107 catch (Exception e)
8108 assert(0, "TimeOfDay's constructor threw.");
8111 @safe unittest
8113 import core.time;
8114 assert(cast(TimeOfDay) SysTime(Date(1999, 7, 6)) == TimeOfDay(0, 0, 0));
8115 assert(cast(TimeOfDay) SysTime(Date(2000, 12, 31)) == TimeOfDay(0, 0, 0));
8116 assert(cast(TimeOfDay) SysTime(Date(2001, 1, 1)) == TimeOfDay(0, 0, 0));
8118 assert(cast(TimeOfDay) SysTime(DateTime(1999, 7, 6, 12, 10, 9)) == TimeOfDay(12, 10, 9));
8119 assert(cast(TimeOfDay) SysTime(DateTime(2000, 12, 31, 13, 11, 10)) == TimeOfDay(13, 11, 10));
8120 assert(cast(TimeOfDay) SysTime(DateTime(2001, 1, 1, 14, 12, 11)) == TimeOfDay(14, 12, 11));
8122 assert(cast(TimeOfDay) SysTime(Date(-1999, 7, 6)) == TimeOfDay(0, 0, 0));
8123 assert(cast(TimeOfDay) SysTime(Date(-2000, 12, 31)) == TimeOfDay(0, 0, 0));
8124 assert(cast(TimeOfDay) SysTime(Date(-2001, 1, 1)) == TimeOfDay(0, 0, 0));
8126 assert(cast(TimeOfDay) SysTime(DateTime(-1999, 7, 6, 12, 10, 9)) == TimeOfDay(12, 10, 9));
8127 assert(cast(TimeOfDay) SysTime(DateTime(-2000, 12, 31, 13, 11, 10)) == TimeOfDay(13, 11, 10));
8128 assert(cast(TimeOfDay) SysTime(DateTime(-2001, 1, 1, 14, 12, 11)) == TimeOfDay(14, 12, 11));
8130 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
8131 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
8132 assert(cast(TimeOfDay) cst != TimeOfDay.init);
8133 assert(cast(TimeOfDay) ist != TimeOfDay.init);
8135 static void testScope(scope ref SysTime st) @safe
8137 auto result = cast(TimeOfDay) st;
8142 // Temporary hack until bug https://issues.dlang.org/show_bug.cgi?id=4867 is fixed.
8143 // This allows assignment from const(SysTime) to SysTime.
8144 // It may be a good idea to keep it though, since casting from a type to itself
8145 // should be allowed, and it doesn't work without this opCast() since opCast()
8146 // has already been defined for other types.
8147 SysTime opCast(T)() @safe const pure nothrow scope
8148 if (is(immutable T == immutable SysTime))
8150 return SysTime(_stdTime, _timezone);
8153 @safe unittest
8155 static void testScope(scope ref SysTime st) @safe
8157 auto result = cast(SysTime) st;
8163 Converts this $(LREF SysTime) to a string with the format
8164 YYYYMMDDTHHMMSS.FFFFFFFTZ (where F is fractional seconds and TZ is time
8165 zone).
8167 Note that the number of digits in the fractional seconds varies with the
8168 number of fractional seconds. It's a maximum of 7 (which would be
8169 hnsecs), but only has as many as are necessary to hold the correct value
8170 (so no trailing zeroes), and if there are no fractional seconds, then
8171 there is no decimal point.
8173 If this $(LREF SysTime)'s time zone is
8174 $(REF LocalTime,std,datetime,timezone), then TZ is empty. If its time
8175 zone is `UTC`, then it is "Z". Otherwise, it is the offset from UTC
8176 (e.g. +0100 or -0700). Note that the offset from UTC is $(I not) enough
8177 to uniquely identify the time zone.
8179 Time zone offsets will be in the form +HHMM or -HHMM.
8181 $(RED Warning:
8182 Previously, toISOString did the same as $(LREF toISOExtString) and
8183 generated +HH:MM or -HH:MM for the time zone when it was not
8184 $(REF LocalTime,std,datetime,timezone) or
8185 $(REF UTC,std,datetime,timezone), which is not in conformance with
8186 ISO 8601 for the non-extended string format. This has now been
8187 fixed. However, for now, fromISOString will continue to accept the
8188 extended format for the time zone so that any code which has been
8189 writing out the result of toISOString to read in later will continue
8190 to work. The current behavior will be kept until July 2019 at which
8191 point, fromISOString will be fixed to be standards compliant.)
8193 Params:
8194 writer = A `char` accepting
8195 $(REF_ALTTEXT output range, isOutputRange, std, range, primitives)
8196 Returns:
8197 A `string` when not using an output range; `void` otherwise.
8199 string toISOString() @safe const nothrow scope
8201 import std.array : appender;
8202 auto app = appender!string();
8203 app.reserve(30);
8205 toISOString(app);
8206 catch (Exception e)
8207 assert(0, "toISOString() threw.");
8208 return app.data;
8211 /// ditto
8212 void toISOString(W)(ref W writer) const scope
8213 if (isOutputRange!(W, char))
8215 immutable adjustedTime = adjTime;
8216 long hnsecs = adjustedTime;
8218 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
8220 if (hnsecs < 0)
8222 hnsecs += convert!("hours", "hnsecs")(24);
8223 --days;
8226 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs);
8227 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs);
8228 immutable second = splitUnitsFromHNSecs!"seconds"(hnsecs);
8230 auto dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour,
8231 cast(int) minute, cast(int) second));
8233 if (_timezone is LocalTime())
8235 dateTime.toISOString(writer);
8236 fracSecsToISOString(writer, cast(int) hnsecs);
8237 return;
8240 if (_timezone is UTC())
8242 dateTime.toISOString(writer);
8243 fracSecsToISOString(writer, cast(int) hnsecs);
8244 put(writer, 'Z');
8245 return;
8248 immutable utcOffset = dur!"hnsecs"(adjustedTime - stdTime);
8250 dateTime.toISOString(writer);
8251 fracSecsToISOString(writer, cast(int) hnsecs);
8252 SimpleTimeZone.toISOExtString(writer, utcOffset);
8256 @safe unittest
8258 import core.time : msecs, hnsecs;
8259 import std.datetime.date : DateTime;
8261 assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toISOString() ==
8262 "20100704T070612");
8264 assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(24)).toISOString() ==
8265 "19981225T021500.024");
8267 assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toISOString() ==
8268 "00000105T230959");
8270 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toISOString() ==
8271 "-00040105T000002.052092");
8274 @safe unittest
8276 import core.time;
8277 // Test A.D.
8278 assert(SysTime(DateTime.init, UTC()).toISOString() == "00010101T000000Z");
8279 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC()).toISOString() == "00010101T000000.0000001Z");
8281 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0)).toISOString() == "00091204T000000");
8282 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12)).toISOString() == "00991204T050612");
8283 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59)).toISOString() == "09991204T134459");
8284 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59)).toISOString() == "99990704T235959");
8285 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1)).toISOString() == "+100001020T010101");
8287 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0), msecs(42)).toISOString() == "00091204T000000.042");
8288 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12), msecs(100)).toISOString() == "00991204T050612.1");
8289 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59), usecs(45020)).toISOString() == "09991204T134459.04502");
8290 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOString() == "99990704T235959.0000012");
8291 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOString() == "+100001020T010101.050789");
8293 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12),
8294 new immutable SimpleTimeZone(dur!"minutes"(-360))).toISOString() ==
8295 "20121221T121212-06:00");
8297 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12),
8298 new immutable SimpleTimeZone(dur!"minutes"(420))).toISOString() ==
8299 "20121221T121212+07:00");
8301 // Test B.C.
8302 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toISOString() ==
8303 "00001231T235959.9999999Z");
8304 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC()).toISOString() == "00001231T235959.0000001Z");
8305 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), UTC()).toISOString() == "00001231T235959Z");
8307 assert(SysTime(DateTime(0, 12, 4, 0, 12, 4)).toISOString() == "00001204T001204");
8308 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0)).toISOString() == "-00091204T000000");
8309 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12)).toISOString() == "-00991204T050612");
8310 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59)).toISOString() == "-09991204T134459");
8311 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59)).toISOString() == "-99990704T235959");
8312 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1)).toISOString() == "-100001020T010101");
8314 assert(SysTime(DateTime(0, 12, 4, 0, 0, 0), msecs(7)).toISOString() == "00001204T000000.007");
8315 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0), msecs(42)).toISOString() == "-00091204T000000.042");
8316 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12), msecs(100)).toISOString() == "-00991204T050612.1");
8317 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59), usecs(45020)).toISOString() == "-09991204T134459.04502");
8318 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOString() == "-99990704T235959.0000012");
8319 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOString() == "-100001020T010101.050789");
8321 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
8322 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
8323 assert(cst.toISOString() == "19990706T123033");
8324 assert(ist.toISOString() == "19990706T123033");
8326 static void testScope(scope ref SysTime st) @safe
8328 auto result = st.toISOString();
8335 Converts this $(LREF SysTime) to a string with the format
8336 YYYY-MM-DDTHH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ
8337 is the time zone).
8339 Default behaviour:
8340 Note that the number of digits in the fractional seconds varies with the
8341 number of fractional seconds. It's a maximum of 7 (which would be
8342 hnsecs), but only has as many as are necessary to hold the correct value
8343 (so no trailing zeroes), and if there are no fractional seconds, then
8344 there is no decimal point.
8346 The optional parameter "prec" allows to change the default behavior by
8347 specifying the precision of the fractional seconds. The accepted values
8348 are in the range [-1, 7], where -1 represents the default behavior.
8350 If this $(LREF SysTime)'s time zone is
8351 $(REF LocalTime,std,datetime,timezone), then TZ is empty. If its time
8352 zone is `UTC`, then it is "Z". Otherwise, it is the offset from UTC
8353 (e.g. +01:00 or -07:00). Note that the offset from UTC is $(I not)
8354 enough to uniquely identify the time zone.
8356 Time zone offsets will be in the form +HH:MM or -HH:MM.
8358 Params:
8359 writer = A `char` accepting
8360 $(REF_ALTTEXT output range, isOutputRange, std, range, primitives)
8361 prec = An `int` representing the desired precision. Acceptable values range from -1 to 7, where -1 represents the default behavior.
8362 Returns:
8363 A `string` when not using an output range; `void` otherwise.
8365 string toISOExtString(int prec = -1) @safe const nothrow scope
8367 assert(prec >= -1 && prec <= 7, "Precision must be in the range [-1, 7]");
8369 import std.array : appender;
8370 auto app = appender!string();
8371 app.reserve(35);
8373 toISOExtString(app, prec);
8374 catch (Exception e)
8375 assert(0, "toISOExtString() threw.");
8376 return app.data;
8379 /// ditto
8380 void toISOExtString(W)(ref W writer, int prec = -1) const scope
8381 if (isOutputRange!(W, char))
8383 assert(prec >= -1 && prec <= 7, "Precision must be in the range [-1, 7]");
8385 immutable adjustedTime = adjTime;
8386 long hnsecs = adjustedTime;
8388 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
8390 if (hnsecs < 0)
8392 hnsecs += convert!("hours", "hnsecs")(24);
8393 --days;
8396 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs);
8397 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs);
8398 immutable second = splitUnitsFromHNSecs!"seconds"(hnsecs);
8400 immutable dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour,
8401 cast(int) minute, cast(int) second));
8403 if (_timezone is LocalTime())
8405 dateTime.toISOExtString(writer);
8406 fracSecsToISOString(writer, cast(int) hnsecs, prec);
8407 return;
8410 if (_timezone is UTC())
8412 dateTime.toISOExtString(writer);
8413 fracSecsToISOString(writer, cast(int) hnsecs, prec);
8414 put(writer, 'Z');
8415 return;
8418 immutable utcOffset = dur!"hnsecs"(adjustedTime - stdTime);
8420 dateTime.toISOExtString(writer);
8421 fracSecsToISOString(writer, cast(int) hnsecs, prec);
8422 SimpleTimeZone.toISOExtString(writer, utcOffset);
8426 @safe unittest
8428 import core.time : msecs, hnsecs;
8429 import std.datetime.date : DateTime;
8431 assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toISOExtString() ==
8432 "2010-07-04T07:06:12");
8434 assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(24)).toISOExtString() ==
8435 "1998-12-25T02:15:00.024");
8437 assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toISOExtString() ==
8438 "0000-01-05T23:09:59");
8440 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toISOExtString() ==
8441 "-0004-01-05T00:00:02.052092");
8443 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toISOExtString(4) ==
8444 "-0004-01-05T00:00:02.0520");
8446 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toISOExtString(2) ==
8447 "-0004-01-05T00:00:02.05");
8449 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toISOExtString(7) ==
8450 "-0004-01-05T00:00:02.0520920");
8453 @safe unittest
8455 import core.time;
8456 // Test A.D.
8457 assert(SysTime(DateTime.init, UTC()).toISOExtString() == "0001-01-01T00:00:00Z");
8458 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC()).toISOExtString() ==
8459 "0001-01-01T00:00:00.0000001Z");
8461 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0)).toISOExtString() == "0009-12-04T00:00:00");
8462 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12)).toISOExtString() == "0099-12-04T05:06:12");
8463 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59)).toISOExtString() == "0999-12-04T13:44:59");
8464 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59)).toISOExtString() == "9999-07-04T23:59:59");
8465 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1)).toISOExtString() == "+10000-10-20T01:01:01");
8467 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0), msecs(42)).toISOExtString() == "0009-12-04T00:00:00.042");
8468 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12), msecs(100)).toISOExtString() == "0099-12-04T05:06:12.1");
8469 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59), usecs(45020)).toISOExtString() == "0999-12-04T13:44:59.04502");
8470 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOExtString() == "9999-07-04T23:59:59.0000012");
8471 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOExtString() ==
8472 "+10000-10-20T01:01:01.050789");
8474 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12),
8475 new immutable SimpleTimeZone(dur!"minutes"(-360))).toISOExtString() ==
8476 "2012-12-21T12:12:12-06:00");
8478 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12),
8479 new immutable SimpleTimeZone(dur!"minutes"(420))).toISOExtString() ==
8480 "2012-12-21T12:12:12+07:00");
8482 // Test B.C.
8483 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toISOExtString() ==
8484 "0000-12-31T23:59:59.9999999Z");
8485 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC()).toISOExtString() ==
8486 "0000-12-31T23:59:59.0000001Z");
8487 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), UTC()).toISOExtString() == "0000-12-31T23:59:59Z");
8489 assert(SysTime(DateTime(0, 12, 4, 0, 12, 4)).toISOExtString() == "0000-12-04T00:12:04");
8490 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0)).toISOExtString() == "-0009-12-04T00:00:00");
8491 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12)).toISOExtString() == "-0099-12-04T05:06:12");
8492 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59)).toISOExtString() == "-0999-12-04T13:44:59");
8493 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59)).toISOExtString() == "-9999-07-04T23:59:59");
8494 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1)).toISOExtString() == "-10000-10-20T01:01:01");
8496 assert(SysTime(DateTime(0, 12, 4, 0, 0, 0), msecs(7)).toISOExtString() == "0000-12-04T00:00:00.007");
8497 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0), msecs(42)).toISOExtString() == "-0009-12-04T00:00:00.042");
8498 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12), msecs(100)).toISOExtString() == "-0099-12-04T05:06:12.1");
8499 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59), usecs(45020)).toISOExtString() ==
8500 "-0999-12-04T13:44:59.04502");
8501 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOExtString() ==
8502 "-9999-07-04T23:59:59.0000012");
8503 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOExtString() ==
8504 "-10000-10-20T01:01:01.050789");
8506 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
8507 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
8508 assert(cst.toISOExtString() == "1999-07-06T12:30:33");
8509 assert(ist.toISOExtString() == "1999-07-06T12:30:33");
8511 static void testScope(scope ref SysTime st) @safe
8513 auto result = st.toISOExtString();
8518 Converts this $(LREF SysTime) to a string with the format
8519 YYYY-Mon-DD HH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ
8520 is the time zone).
8522 Note that the number of digits in the fractional seconds varies with the
8523 number of fractional seconds. It's a maximum of 7 (which would be
8524 hnsecs), but only has as many as are necessary to hold the correct value
8525 (so no trailing zeroes), and if there are no fractional seconds, then
8526 there is no decimal point.
8528 If this $(LREF SysTime)'s time zone is
8529 $(REF LocalTime,std,datetime,timezone), then TZ is empty. If its time
8530 zone is `UTC`, then it is "Z". Otherwise, it is the offset from UTC
8531 (e.g. +01:00 or -07:00). Note that the offset from UTC is $(I not)
8532 enough to uniquely identify the time zone.
8534 Time zone offsets will be in the form +HH:MM or -HH:MM.
8536 Params:
8537 writer = A `char` accepting
8538 $(REF_ALTTEXT output range, isOutputRange, std, range, primitives)
8539 Returns:
8540 A `string` when not using an output range; `void` otherwise.
8542 string toSimpleString() @safe const nothrow scope
8544 import std.array : appender;
8545 auto app = appender!string();
8546 app.reserve(35);
8548 toSimpleString(app);
8549 catch (Exception e)
8550 assert(0, "toSimpleString() threw.");
8551 return app.data;
8554 /// ditto
8555 void toSimpleString(W)(ref W writer) const scope
8556 if (isOutputRange!(W, char))
8558 immutable adjustedTime = adjTime;
8559 long hnsecs = adjustedTime;
8561 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1;
8563 if (hnsecs < 0)
8565 hnsecs += convert!("hours", "hnsecs")(24);
8566 --days;
8569 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs);
8570 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs);
8571 immutable second = splitUnitsFromHNSecs!"seconds"(hnsecs);
8573 immutable dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour,
8574 cast(int) minute, cast(int) second));
8576 if (_timezone is LocalTime())
8578 dateTime.toSimpleString(writer);
8579 fracSecsToISOString(writer, cast(int) hnsecs);
8580 return;
8583 if (_timezone is UTC())
8585 dateTime.toSimpleString(writer);
8586 fracSecsToISOString(writer, cast(int) hnsecs);
8587 put(writer, 'Z');
8588 return;
8591 immutable utcOffset = dur!"hnsecs"(adjustedTime - stdTime);
8593 dateTime.toSimpleString(writer);
8594 fracSecsToISOString(writer, cast(int) hnsecs);
8595 SimpleTimeZone.toISOExtString(writer, utcOffset);
8599 @safe unittest
8601 import core.time : msecs, hnsecs;
8602 import std.datetime.date : DateTime;
8604 assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toSimpleString() ==
8605 "2010-Jul-04 07:06:12");
8607 assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(24)).toSimpleString() ==
8608 "1998-Dec-25 02:15:00.024");
8610 assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toSimpleString() ==
8611 "0000-Jan-05 23:09:59");
8613 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toSimpleString() ==
8614 "-0004-Jan-05 00:00:02.052092");
8617 @safe unittest
8619 import core.time;
8620 // Test A.D.
8621 assert(SysTime(DateTime.init, UTC()).toString() == "0001-Jan-01 00:00:00Z");
8622 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC()).toString() == "0001-Jan-01 00:00:00.0000001Z");
8624 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0)).toSimpleString() == "0009-Dec-04 00:00:00");
8625 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12)).toSimpleString() == "0099-Dec-04 05:06:12");
8626 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59)).toSimpleString() == "0999-Dec-04 13:44:59");
8627 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59)).toSimpleString() == "9999-Jul-04 23:59:59");
8628 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1)).toSimpleString() == "+10000-Oct-20 01:01:01");
8630 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0), msecs(42)).toSimpleString() == "0009-Dec-04 00:00:00.042");
8631 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12), msecs(100)).toSimpleString() == "0099-Dec-04 05:06:12.1");
8632 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59), usecs(45020)).toSimpleString() ==
8633 "0999-Dec-04 13:44:59.04502");
8634 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59), hnsecs(12)).toSimpleString() ==
8635 "9999-Jul-04 23:59:59.0000012");
8636 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1), hnsecs(507890)).toSimpleString() ==
8637 "+10000-Oct-20 01:01:01.050789");
8639 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12),
8640 new immutable SimpleTimeZone(dur!"minutes"(-360))).toSimpleString() ==
8641 "2012-Dec-21 12:12:12-06:00");
8643 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12),
8644 new immutable SimpleTimeZone(dur!"minutes"(420))).toSimpleString() ==
8645 "2012-Dec-21 12:12:12+07:00");
8647 // Test B.C.
8648 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toSimpleString() ==
8649 "0000-Dec-31 23:59:59.9999999Z");
8650 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC()).toSimpleString() ==
8651 "0000-Dec-31 23:59:59.0000001Z");
8652 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), UTC()).toSimpleString() == "0000-Dec-31 23:59:59Z");
8654 assert(SysTime(DateTime(0, 12, 4, 0, 12, 4)).toSimpleString() == "0000-Dec-04 00:12:04");
8655 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0)).toSimpleString() == "-0009-Dec-04 00:00:00");
8656 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12)).toSimpleString() == "-0099-Dec-04 05:06:12");
8657 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59)).toSimpleString() == "-0999-Dec-04 13:44:59");
8658 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59)).toSimpleString() == "-9999-Jul-04 23:59:59");
8659 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1)).toSimpleString() == "-10000-Oct-20 01:01:01");
8661 assert(SysTime(DateTime(0, 12, 4, 0, 0, 0), msecs(7)).toSimpleString() == "0000-Dec-04 00:00:00.007");
8662 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0), msecs(42)).toSimpleString() == "-0009-Dec-04 00:00:00.042");
8663 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12), msecs(100)).toSimpleString() == "-0099-Dec-04 05:06:12.1");
8664 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59), usecs(45020)).toSimpleString() ==
8665 "-0999-Dec-04 13:44:59.04502");
8666 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59), hnsecs(12)).toSimpleString() ==
8667 "-9999-Jul-04 23:59:59.0000012");
8668 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1), hnsecs(507890)).toSimpleString() ==
8669 "-10000-Oct-20 01:01:01.050789");
8671 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
8672 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
8673 assert(cst.toSimpleString() == "1999-Jul-06 12:30:33");
8674 assert(ist.toSimpleString() == "1999-Jul-06 12:30:33");
8676 static void testScope(scope ref SysTime st) @safe
8678 auto result = st.toSimpleString();
8684 Converts this $(LREF SysTime) to a string.
8686 This function exists to make it easy to convert a $(LREF SysTime) to a
8687 string for code that does not care what the exact format is - just that
8688 it presents the information in a clear manner. It also makes it easy to
8689 simply convert a $(LREF SysTime) to a string when using functions such
8690 as `to!string`, `format`, or `writeln` which use toString to convert
8691 user-defined types. So, it is unlikely that much code will call
8692 toString directly.
8694 The format of the string is purposefully unspecified, and code that
8695 cares about the format of the string should use `toISOString`,
8696 `toISOExtString`, `toSimpleString`, or some other custom formatting
8697 function that explicitly generates the format that the code needs. The
8698 reason is that the code is then clear about what format it's using,
8699 making it less error-prone to maintain the code and interact with other
8700 software that consumes the generated strings. It's for this same reason
8701 that $(LREF SysTime) has no `fromString` function, whereas it does have
8702 `fromISOString`, `fromISOExtString`, and `fromSimpleString`.
8704 The format returned by toString may or may not change in the future.
8706 Params:
8707 writer = A `char` accepting
8708 $(REF_ALTTEXT output range, isOutputRange, std, range, primitives)
8709 Returns:
8710 A `string` when not using an output range; `void` otherwise.
8712 string toString() @safe const nothrow scope
8714 return toSimpleString();
8717 /// ditto
8718 void toString(W)(ref W writer) const scope
8719 if (isOutputRange!(W, char))
8721 toSimpleString(writer);
8724 @safe unittest
8726 import core.time;
8727 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
8728 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
8729 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33));
8730 static assert(__traits(compiles, st.toString()));
8731 static assert(__traits(compiles, cst.toString()));
8732 static assert(__traits(compiles, ist.toString()));
8734 static void testScope(scope ref SysTime st) @safe
8736 auto result = st.toString();
8742 Creates a $(LREF SysTime) from a string with the format
8743 YYYYMMDDTHHMMSS.FFFFFFFTZ (where F is fractional seconds and TZ
8744 is the time zone). Whitespace is stripped from the given string.
8746 The exact format is exactly as described in $(LREF toISOString) except
8747 that trailing zeroes are permitted - including having fractional seconds
8748 with all zeroes. The time zone and fractional seconds are optional,
8749 however, a decimal point with nothing following it is invalid.
8750 Also, while $(LREF toISOString) will never generate a string
8751 with more than 7 digits in the fractional seconds (because that's the
8752 limit with hecto-nanosecond precision), it will allow more than 7 digits
8753 in order to read strings from other sources that have higher precision
8754 (however, any digits beyond 7 will be truncated).
8756 If there is no time zone in the string, then
8757 $(REF LocalTime,std,datetime,timezone) is used. If the time zone is "Z",
8758 then `UTC` is used. Otherwise, a
8759 $(REF SimpleTimeZone,std,datetime,timezone) which corresponds to the
8760 given offset from UTC is used. To get the returned $(LREF SysTime) to be
8761 a particular time zone, pass in that time zone and the $(LREF SysTime)
8762 to be returned will be converted to that time zone (though it will still
8763 be read in as whatever time zone is in its string).
8765 The accepted formats for time zone offsets are +HH, -HH, +HHMM, and
8766 -HHMM.
8768 $(RED Warning:
8769 Previously, $(LREF toISOString) did the same as
8770 $(LREF toISOExtString) and generated +HH:MM or -HH:MM for the time
8771 zone when it was not $(REF LocalTime,std,datetime,timezone) or
8772 $(REF UTC,std,datetime,timezone), which is not in conformance with
8773 ISO 8601 for the non-extended string format. This has now been
8774 fixed. However, for now, fromISOString will continue to accept the
8775 extended format for the time zone so that any code which has been
8776 writing out the result of toISOString to read in later will continue
8777 to work. The current behavior will be kept until July 2019 at which
8778 point, fromISOString will be fixed to be standards compliant.)
8780 Params:
8781 isoString = A string formatted in the ISO format for dates and times.
8782 tz = The time zone to convert the given time to (no
8783 conversion occurs if null).
8785 Throws:
8786 $(REF DateTimeException,std,datetime,date) if the given string is
8787 not in the ISO format or if the resulting $(LREF SysTime) would not
8788 be valid.
8790 static SysTime fromISOString(S)(scope const S isoString, immutable TimeZone tz = null) @safe
8791 if (isSomeString!S)
8793 import std.algorithm.searching : startsWith, find;
8794 import std.conv : to;
8795 import std.string : strip;
8796 import std.utf : byCodeUnit;
8798 auto str = strip(isoString);
8799 immutable skipFirst = str.startsWith('+', '-');
8801 auto found = (skipFirst ? str[1..$] : str).byCodeUnit.find('.', 'Z', '+', '-');
8802 auto dateTimeStr = str[0 .. $ - found[0].length];
8804 typeof(str.byCodeUnit) foundTZ; // needs to have longer lifetime than zoneStr
8805 typeof(str) fracSecStr;
8806 typeof(str) zoneStr;
8808 if (found[1] != 0)
8810 if (found[1] == 1)
8812 foundTZ = found[0].find('Z', '+', '-')[0];
8814 if (foundTZ.length != 0)
8816 static if (isNarrowString!S)
8818 fracSecStr = found[0][0 .. $ - foundTZ.length].source;
8819 zoneStr = foundTZ.source;
8821 else
8823 fracSecStr = found[0][0 .. $ - foundTZ.length];
8824 zoneStr = foundTZ;
8827 else
8829 static if (isNarrowString!S)
8830 fracSecStr = found[0].source;
8831 else
8832 fracSecStr = found[0];
8835 else
8837 static if (isNarrowString!S)
8838 zoneStr = found[0].source;
8839 else
8840 zoneStr = found[0];
8846 auto dateTime = DateTime.fromISOString(dateTimeStr);
8847 auto fracSec = fracSecsFromISOString(fracSecStr);
8849 Rebindable!(immutable TimeZone) parsedZone;
8851 if (zoneStr.empty)
8852 parsedZone = LocalTime();
8853 else if (zoneStr == "Z")
8854 parsedZone = UTC();
8855 else
8858 parsedZone = SimpleTimeZone.fromISOString(zoneStr);
8859 catch (DateTimeException dte)
8860 parsedZone = SimpleTimeZone.fromISOExtString(zoneStr);
8863 auto retval = SysTime(dateTime, fracSec, parsedZone);
8865 if (tz !is null)
8866 retval.timezone = tz;
8868 return retval;
8870 catch (DateTimeException dte)
8871 throw new DateTimeException(format("Invalid ISO String: %s", isoString));
8875 @safe unittest
8877 import core.time : hours, msecs, usecs, hnsecs;
8878 import std.datetime.date : DateTime;
8879 import std.datetime.timezone : SimpleTimeZone, UTC;
8881 assert(SysTime.fromISOString("20100704T070612") ==
8882 SysTime(DateTime(2010, 7, 4, 7, 6, 12)));
8884 assert(SysTime.fromISOString("19981225T021500.007") ==
8885 SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(7)));
8887 assert(SysTime.fromISOString("00000105T230959.00002") ==
8888 SysTime(DateTime(0, 1, 5, 23, 9, 59), usecs(20)));
8890 assert(SysTime.fromISOString("20130207T043937.000050392") ==
8891 SysTime(DateTime(2013, 2, 7, 4, 39, 37), hnsecs(503)));
8893 assert(SysTime.fromISOString("-00040105T000002") ==
8894 SysTime(DateTime(-4, 1, 5, 0, 0, 2)));
8896 assert(SysTime.fromISOString(" 20100704T070612 ") ==
8897 SysTime(DateTime(2010, 7, 4, 7, 6, 12)));
8899 assert(SysTime.fromISOString("20100704T070612Z") ==
8900 SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC()));
8902 assert(SysTime.fromISOString("20100704T070612-0800") ==
8903 SysTime(DateTime(2010, 7, 4, 7, 6, 12),
8904 new immutable SimpleTimeZone(hours(-8))));
8906 assert(SysTime.fromISOString("20100704T070612+0800") ==
8907 SysTime(DateTime(2010, 7, 4, 7, 6, 12),
8908 new immutable SimpleTimeZone(hours(8))));
8911 @safe unittest
8913 import core.time;
8914 foreach (str; ["", "20100704000000", "20100704 000000", "20100704t000000",
8915 "20100704T000000.", "20100704T000000.A", "20100704T000000.Z",
8916 "20100704T000000.0000000A", "20100704T000000.00000000A",
8917 "20100704T000000+", "20100704T000000-", "20100704T000000:",
8918 "20100704T000000-:", "20100704T000000+:", "20100704T000000-1:",
8919 "20100704T000000+1:", "20100704T000000+1:0",
8920 "20100704T000000-12.00", "20100704T000000+12.00",
8921 "20100704T000000-8", "20100704T000000+8",
8922 "20100704T000000-800", "20100704T000000+800",
8923 "20100704T000000-080", "20100704T000000+080",
8924 "20100704T000000-2400", "20100704T000000+2400",
8925 "20100704T000000-1260", "20100704T000000+1260",
8926 "20100704T000000.0-8", "20100704T000000.0+8",
8927 "20100704T000000.0-800", "20100704T000000.0+800",
8928 "20100704T000000.0-080", "20100704T000000.0+080",
8929 "20100704T000000.0-2400", "20100704T000000.0+2400",
8930 "20100704T000000.0-1260", "20100704T000000.0+1260",
8931 "20100704T000000-8:00", "20100704T000000+8:00",
8932 "20100704T000000-08:0", "20100704T000000+08:0",
8933 "20100704T000000-24:00", "20100704T000000+24:00",
8934 "20100704T000000-12:60", "20100704T000000+12:60",
8935 "20100704T000000.0-8:00", "20100704T000000.0+8:00",
8936 "20100704T000000.0-08:0", "20100704T000000.0+08:0",
8937 "20100704T000000.0-24:00", "20100704T000000.0+24:00",
8938 "20100704T000000.0-12:60", "20100704T000000.0+12:60",
8939 "2010-07-0400:00:00", "2010-07-04 00:00:00",
8940 "2010-07-04t00:00:00", "2010-07-04T00:00:00.",
8941 "2010-Jul-0400:00:00", "2010-Jul-04 00:00:00", "2010-Jul-04t00:00:00",
8942 "2010-Jul-04T00:00:00", "2010-Jul-04 00:00:00.",
8943 "2010-12-22T172201", "2010-Dec-22 17:22:01"])
8945 assertThrown!DateTimeException(SysTime.fromISOString(str), format("[%s]", str));
8948 static void test(string str, SysTime st, size_t line = __LINE__)
8950 if (SysTime.fromISOString(str) != st)
8951 throw new AssertError("unittest failure", __FILE__, line);
8954 test("20101222T172201", SysTime(DateTime(2010, 12, 22, 17, 22, 1)));
8955 test("19990706T123033", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
8956 test("-19990706T123033", SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));
8957 test("+019990706T123033", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
8958 test("19990706T123033 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
8959 test(" 19990706T123033", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
8960 test(" 19990706T123033 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
8962 test("19070707T121212.0", SysTime(DateTime(1907, 7, 7, 12, 12, 12)));
8963 test("19070707T121212.0000000", SysTime(DateTime(1907, 7, 7, 12, 12, 12)));
8964 test("19070707T121212.0000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), hnsecs(1)));
8965 test("20100704T000000.00000000", SysTime(Date(2010, 7, 4)));
8966 test("20100704T000000.00000009", SysTime(Date(2010, 7, 4)));
8967 test("20100704T000000.00000019", SysTime(DateTime(2010, 7, 4), hnsecs(1)));
8968 test("19070707T121212.000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1)));
8969 test("19070707T121212.0000010", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1)));
8970 test("19070707T121212.001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1)));
8971 test("19070707T121212.0010000", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1)));
8973 auto west60 = new immutable SimpleTimeZone(hours(-1));
8974 auto west90 = new immutable SimpleTimeZone(minutes(-90));
8975 auto west480 = new immutable SimpleTimeZone(hours(-8));
8976 auto east60 = new immutable SimpleTimeZone(hours(1));
8977 auto east90 = new immutable SimpleTimeZone(minutes(90));
8978 auto east480 = new immutable SimpleTimeZone(hours(8));
8980 test("20101222T172201Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), UTC()));
8981 test("20101222T172201-0100", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60));
8982 test("20101222T172201-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60));
8983 test("20101222T172201-0130", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west90));
8984 test("20101222T172201-0800", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west480));
8985 test("20101222T172201+0100", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60));
8986 test("20101222T172201+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60));
8987 test("20101222T172201+0130", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90));
8988 test("20101222T172201+0800", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east480));
8990 test("20101103T065106.57159Z", SysTime(DateTime(2010, 11, 3, 6, 51, 6), hnsecs(5715900), UTC()));
8991 test("20101222T172201.23412Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_341_200), UTC()));
8992 test("20101222T172201.23112-0100", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_311_200), west60));
8993 test("20101222T172201.45-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), west60));
8994 test("20101222T172201.1-0130", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_000_000), west90));
8995 test("20101222T172201.55-0800", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(5_500_000), west480));
8996 test("20101222T172201.1234567+0100", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_234_567), east60));
8997 test("20101222T172201.0+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60));
8998 test("20101222T172201.0000000+0130", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90));
8999 test("20101222T172201.45+0800", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), east480));
9001 // for dstring coverage
9002 assert(SysTime.fromISOString("20101222T172201.23112-0100"d) == SysTime(
9003 DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_311_200), west60));
9004 assert(SysTime.fromISOString("19070707T121212.0010000"d) == SysTime(
9005 DateTime(1907, 7, 7, 12, 12, 12), msecs(1)));
9007 // @@@DEPRECATED_2019-07@@@
9008 // This isn't deprecated per se, but that text will make it so that it
9009 // pops up when deprecations are moved along around July 2019. At that
9010 // time, we will update fromISOString so that it is conformant with ISO
9011 // 8601, and it will no longer accept ISO extended time zones (it does
9012 // currently because of https://issues.dlang.org/show_bug.cgi?id=15654
9013 // toISOString used to incorrectly use the ISO extended time zone format).
9014 // These tests will then start failing will need to be updated accordingly.
9015 // Also, the notes about this issue in toISOString and fromISOString's
9016 // documentation will need to be removed.
9017 test("20101222T172201-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60));
9018 test("20101222T172201-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west90));
9019 test("20101222T172201-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west480));
9020 test("20101222T172201+01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60));
9021 test("20101222T172201+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90));
9022 test("20101222T172201+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east480));
9024 test("20101222T172201.23112-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_311_200), west60));
9025 test("20101222T172201.1-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_000_000), west90));
9026 test("20101222T172201.55-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(5_500_000), west480));
9027 test("20101222T172201.1234567+01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_234_567), east60));
9028 test("20101222T172201.0000000+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90));
9029 test("20101222T172201.45+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), east480));
9031 static void testScope(scope ref string str) @safe
9033 auto result = SysTime.fromISOString(str);
9037 // https://issues.dlang.org/show_bug.cgi?id=17801
9038 @safe unittest
9040 import std.conv : to;
9041 import std.meta : AliasSeq;
9042 static foreach (C; AliasSeq!(char, wchar, dchar))
9044 static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[]))
9046 assert(SysTime.fromISOString(to!S("20121221T141516Z")) ==
9047 SysTime(DateTime(2012, 12, 21, 14, 15, 16), UTC()));
9054 Creates a $(LREF SysTime) from a string with the format
9055 YYYY-MM-DDTHH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ
9056 is the time zone). Whitespace is stripped from the given string.
9058 The exact format is exactly as described in $(LREF toISOExtString)
9059 except that trailing zeroes are permitted - including having fractional
9060 seconds with all zeroes. The time zone and fractional seconds are
9061 optional, however, a decimal point with nothing following it is invalid.
9062 Also, while $(LREF toISOExtString) will never generate a
9063 string with more than 7 digits in the fractional seconds (because that's
9064 the limit with hecto-nanosecond precision), it will allow more than 7
9065 digits in order to read strings from other sources that have higher
9066 precision (however, any digits beyond 7 will be truncated).
9068 If there is no time zone in the string, then
9069 $(REF LocalTime,std,datetime,timezone) is used. If the time zone is "Z",
9070 then `UTC` is used. Otherwise, a
9071 $(REF SimpleTimeZone,std,datetime,timezone) which corresponds to the
9072 given offset from UTC is used. To get the returned $(LREF SysTime) to be
9073 a particular time zone, pass in that time zone and the $(LREF SysTime)
9074 to be returned will be converted to that time zone (though it will still
9075 be read in as whatever time zone is in its string).
9077 The accepted formats for time zone offsets are +HH, -HH, +HH:MM, and
9078 -HH:MM.
9080 Params:
9081 isoExtString = A string formatted in the ISO Extended format for
9082 dates and times.
9083 tz = The time zone to convert the given time to (no
9084 conversion occurs if null).
9086 Throws:
9087 $(REF DateTimeException,std,datetime,date) if the given string is
9088 not in the ISO format or if the resulting $(LREF SysTime) would not
9089 be valid.
9091 static SysTime fromISOExtString(S)(scope const S isoExtString, immutable TimeZone tz = null) @safe
9092 if (isSomeString!(S))
9094 import std.algorithm.searching : countUntil, find;
9095 import std.conv : to;
9096 import std.string : strip, indexOf;
9098 auto str = strip(isoExtString);
9100 auto tIndex = str.indexOf('T');
9101 enforce(tIndex != -1, new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
9103 auto found = str[tIndex + 1 .. $].find('.', 'Z', '+', '-');
9104 auto dateTimeStr = str[0 .. $ - found[0].length];
9106 typeof(str) foundTZ; // needs to have longer lifetime than zoneStr
9107 typeof(str) fracSecStr;
9108 typeof(str) zoneStr;
9110 if (found[1] != 0)
9112 if (found[1] == 1)
9114 foundTZ = found[0].find('Z', '+', '-')[0];
9116 if (foundTZ.length != 0)
9118 fracSecStr = found[0][0 .. $ - foundTZ.length];
9119 zoneStr = foundTZ;
9121 else
9122 fracSecStr = found[0];
9124 else
9125 zoneStr = found[0];
9130 auto dateTime = DateTime.fromISOExtString(dateTimeStr);
9131 auto fracSec = fracSecsFromISOString(fracSecStr);
9132 Rebindable!(immutable TimeZone) parsedZone;
9134 if (zoneStr.empty)
9135 parsedZone = LocalTime();
9136 else if (zoneStr == "Z")
9137 parsedZone = UTC();
9138 else
9139 parsedZone = SimpleTimeZone.fromISOExtString(zoneStr);
9141 auto retval = SysTime(dateTime, fracSec, parsedZone);
9143 if (tz !is null)
9144 retval.timezone = tz;
9146 return retval;
9148 catch (DateTimeException dte)
9149 throw new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString));
9153 @safe unittest
9155 import core.time : hours, msecs, usecs, hnsecs;
9156 import std.datetime.date : DateTime;
9157 import std.datetime.timezone : SimpleTimeZone, UTC;
9159 assert(SysTime.fromISOExtString("2010-07-04T07:06:12") ==
9160 SysTime(DateTime(2010, 7, 4, 7, 6, 12)));
9162 assert(SysTime.fromISOExtString("1998-12-25T02:15:00.007") ==
9163 SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(7)));
9165 assert(SysTime.fromISOExtString("0000-01-05T23:09:59.00002") ==
9166 SysTime(DateTime(0, 1, 5, 23, 9, 59), usecs(20)));
9168 assert(SysTime.fromISOExtString("2013-02-07T04:39:37.000050392") ==
9169 SysTime(DateTime(2013, 2, 7, 4, 39, 37), hnsecs(503)));
9171 assert(SysTime.fromISOExtString("-0004-01-05T00:00:02") ==
9172 SysTime(DateTime(-4, 1, 5, 0, 0, 2)));
9174 assert(SysTime.fromISOExtString(" 2010-07-04T07:06:12 ") ==
9175 SysTime(DateTime(2010, 7, 4, 7, 6, 12)));
9177 assert(SysTime.fromISOExtString("2010-07-04T07:06:12Z") ==
9178 SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC()));
9180 assert(SysTime.fromISOExtString("2010-07-04T07:06:12-08:00") ==
9181 SysTime(DateTime(2010, 7, 4, 7, 6, 12),
9182 new immutable SimpleTimeZone(hours(-8))));
9183 assert(SysTime.fromISOExtString("2010-07-04T07:06:12+08:00") ==
9184 SysTime(DateTime(2010, 7, 4, 7, 6, 12),
9185 new immutable SimpleTimeZone(hours(8))));
9188 @safe unittest
9190 import core.time;
9191 foreach (str; ["", "20100704000000", "20100704 000000",
9192 "20100704t000000", "20100704T000000.", "20100704T000000.0",
9193 "2010-07:0400:00:00", "2010-07-04 00:00:00",
9194 "2010-07-04 00:00:00", "2010-07-04t00:00:00",
9195 "2010-07-04T00:00:00.", "2010-07-04T00:00:00.A", "2010-07-04T00:00:00.Z",
9196 "2010-07-04T00:00:00.0000000A", "2010-07-04T00:00:00.00000000A",
9197 "2010-07-04T00:00:00+", "2010-07-04T00:00:00-",
9198 "2010-07-04T00:00:00:", "2010-07-04T00:00:00-:", "2010-07-04T00:00:00+:",
9199 "2010-07-04T00:00:00-1:", "2010-07-04T00:00:00+1:", "2010-07-04T00:00:00+1:0",
9200 "2010-07-04T00:00:00-12.00", "2010-07-04T00:00:00+12.00",
9201 "2010-07-04T00:00:00-8", "2010-07-04T00:00:00+8",
9202 "20100704T000000-800", "20100704T000000+800",
9203 "20100704T000000-080", "20100704T000000+080",
9204 "20100704T000000-2400", "20100704T000000+2400",
9205 "20100704T000000-1260", "20100704T000000+1260",
9206 "20100704T000000.0-800", "20100704T000000.0+800",
9207 "20100704T000000.0-8", "20100704T000000.0+8",
9208 "20100704T000000.0-080", "20100704T000000.0+080",
9209 "20100704T000000.0-2400", "20100704T000000.0+2400",
9210 "20100704T000000.0-1260", "20100704T000000.0+1260",
9211 "2010-07-04T00:00:00-8:00", "2010-07-04T00:00:00+8:00",
9212 "2010-07-04T00:00:00-24:00", "2010-07-04T00:00:00+24:00",
9213 "2010-07-04T00:00:00-12:60", "2010-07-04T00:00:00+12:60",
9214 "2010-07-04T00:00:00.0-8:00", "2010-07-04T00:00:00.0+8:00",
9215 "2010-07-04T00:00:00.0-8", "2010-07-04T00:00:00.0+8",
9216 "2010-07-04T00:00:00.0-24:00", "2010-07-04T00:00:00.0+24:00",
9217 "2010-07-04T00:00:00.0-12:60", "2010-07-04T00:00:00.0+12:60",
9218 "2010-Jul-0400:00:00", "2010-Jul-04t00:00:00",
9219 "2010-Jul-04 00:00:00.", "2010-Jul-04 00:00:00.0",
9220 "20101222T172201", "2010-Dec-22 17:22:01"])
9222 assertThrown!DateTimeException(SysTime.fromISOExtString(str), format("[%s]", str));
9225 static void test(string str, SysTime st, size_t line = __LINE__)
9227 if (SysTime.fromISOExtString(str) != st)
9228 throw new AssertError("unittest failure", __FILE__, line);
9231 test("2010-12-22T17:22:01", SysTime(DateTime(2010, 12, 22, 17, 22, 1)));
9232 test("1999-07-06T12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
9233 test("-1999-07-06T12:30:33", SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));
9234 test("+01999-07-06T12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
9235 test("1999-07-06T12:30:33 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
9236 test(" 1999-07-06T12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
9237 test(" 1999-07-06T12:30:33 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
9239 test("1907-07-07T12:12:12.0", SysTime(DateTime(1907, 7, 7, 12, 12, 12)));
9240 test("1907-07-07T12:12:12.0000000", SysTime(DateTime(1907, 7, 7, 12, 12, 12)));
9241 test("1907-07-07T12:12:12.0000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), hnsecs(1)));
9242 test("2010-07-04T00:00:00.00000000", SysTime(Date(2010, 7, 4)));
9243 test("2010-07-04T00:00:00.00000009", SysTime(Date(2010, 7, 4)));
9244 test("2010-07-04T00:00:00.00000019", SysTime(DateTime(2010, 7, 4), hnsecs(1)));
9245 test("1907-07-07T12:12:12.000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1)));
9246 test("1907-07-07T12:12:12.0000010", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1)));
9247 test("1907-07-07T12:12:12.001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1)));
9248 test("1907-07-07T12:12:12.0010000", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1)));
9250 auto west60 = new immutable SimpleTimeZone(hours(-1));
9251 auto west90 = new immutable SimpleTimeZone(minutes(-90));
9252 auto west480 = new immutable SimpleTimeZone(hours(-8));
9253 auto east60 = new immutable SimpleTimeZone(hours(1));
9254 auto east90 = new immutable SimpleTimeZone(minutes(90));
9255 auto east480 = new immutable SimpleTimeZone(hours(8));
9257 test("2010-12-22T17:22:01Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), UTC()));
9258 test("2010-12-22T17:22:01-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60));
9259 test("2010-12-22T17:22:01-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60));
9260 test("2010-12-22T17:22:01-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west90));
9261 test("2010-12-22T17:22:01-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west480));
9262 test("2010-12-22T17:22:01+01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60));
9263 test("2010-12-22T17:22:01+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60));
9264 test("2010-12-22T17:22:01+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90));
9265 test("2010-12-22T17:22:01+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east480));
9267 test("2010-11-03T06:51:06.57159Z", SysTime(DateTime(2010, 11, 3, 6, 51, 6), hnsecs(5715900), UTC()));
9268 test("2010-12-22T17:22:01.23412Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_341_200), UTC()));
9269 test("2010-12-22T17:22:01.23112-01:00",
9270 SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_311_200), west60));
9271 test("2010-12-22T17:22:01.45-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), west60));
9272 test("2010-12-22T17:22:01.1-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_000_000), west90));
9273 test("2010-12-22T17:22:01.55-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(5_500_000), west480));
9274 test("2010-12-22T17:22:01.1234567+01:00",
9275 SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_234_567), east60));
9276 test("2010-12-22T17:22:01.0+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60));
9277 test("2010-12-22T17:22:01.0000000+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90));
9278 test("2010-12-22T17:22:01.45+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), east480));
9280 static void testScope(scope ref string str) @safe
9282 auto result = SysTime.fromISOExtString(str);
9286 // https://issues.dlang.org/show_bug.cgi?id=17801
9287 @safe unittest
9289 import core.time;
9290 import std.conv : to;
9291 import std.meta : AliasSeq;
9292 static foreach (C; AliasSeq!(char, wchar, dchar))
9294 static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[]))
9296 assert(SysTime.fromISOExtString(to!S("2012-12-21T14:15:16Z")) ==
9297 SysTime(DateTime(2012, 12, 21, 14, 15, 16), UTC()));
9304 Creates a $(LREF SysTime) from a string with the format
9305 YYYY-Mon-DD HH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ
9306 is the time zone). Whitespace is stripped from the given string.
9308 The exact format is exactly as described in $(LREF toSimpleString) except
9309 that trailing zeroes are permitted - including having fractional seconds
9310 with all zeroes. The time zone and fractional seconds are optional,
9311 however, a decimal point with nothing following it is invalid.
9312 Also, while $(LREF toSimpleString) will never generate a
9313 string with more than 7 digits in the fractional seconds (because that's
9314 the limit with hecto-nanosecond precision), it will allow more than 7
9315 digits in order to read strings from other sources that have higher
9316 precision (however, any digits beyond 7 will be truncated).
9318 If there is no time zone in the string, then
9319 $(REF LocalTime,std,datetime,timezone) is used. If the time zone is "Z",
9320 then `UTC` is used. Otherwise, a
9321 $(REF SimpleTimeZone,std,datetime,timezone) which corresponds to the
9322 given offset from UTC is used. To get the returned $(LREF SysTime) to be
9323 a particular time zone, pass in that time zone and the $(LREF SysTime)
9324 to be returned will be converted to that time zone (though it will still
9325 be read in as whatever time zone is in its string).
9327 The accepted formats for time zone offsets are +HH, -HH, +HH:MM, and
9328 -HH:MM.
9330 Params:
9331 simpleString = A string formatted in the way that
9332 `toSimpleString` formats dates and times.
9333 tz = The time zone to convert the given time to (no
9334 conversion occurs if null).
9336 Throws:
9337 $(REF DateTimeException,std,datetime,date) if the given string is
9338 not in the ISO format or if the resulting $(LREF SysTime) would not
9339 be valid.
9341 static SysTime fromSimpleString(S)(scope const S simpleString, immutable TimeZone tz = null) @safe
9342 if (isSomeString!(S))
9344 import std.algorithm.searching : find;
9345 import std.conv : to;
9346 import std.string : strip, indexOf;
9348 auto str = strip(simpleString);
9350 auto spaceIndex = str.indexOf(' ');
9351 enforce(spaceIndex != -1, new DateTimeException(format("Invalid Simple String: %s", simpleString)));
9353 auto found = str[spaceIndex + 1 .. $].find('.', 'Z', '+', '-');
9354 auto dateTimeStr = str[0 .. $ - found[0].length];
9356 typeof(str) foundTZ; // needs to have longer lifetime than zoneStr
9357 typeof(str) fracSecStr;
9358 typeof(str) zoneStr;
9360 if (found[1] != 0)
9362 if (found[1] == 1)
9364 foundTZ = found[0].find('Z', '+', '-')[0];
9366 if (foundTZ.length != 0)
9368 fracSecStr = found[0][0 .. $ - foundTZ.length];
9369 zoneStr = foundTZ;
9371 else
9372 fracSecStr = found[0];
9374 else
9375 zoneStr = found[0];
9380 auto dateTime = DateTime.fromSimpleString(dateTimeStr);
9381 auto fracSec = fracSecsFromISOString(fracSecStr);
9382 Rebindable!(immutable TimeZone) parsedZone;
9384 if (zoneStr.empty)
9385 parsedZone = LocalTime();
9386 else if (zoneStr == "Z")
9387 parsedZone = UTC();
9388 else
9389 parsedZone = SimpleTimeZone.fromISOExtString(zoneStr);
9391 auto retval = SysTime(dateTime, fracSec, parsedZone);
9393 if (tz !is null)
9394 retval.timezone = tz;
9396 return retval;
9398 catch (DateTimeException dte)
9399 throw new DateTimeException(format("Invalid Simple String: %s", simpleString));
9403 @safe unittest
9405 import core.time : hours, msecs, usecs, hnsecs;
9406 import std.datetime.date : DateTime;
9407 import std.datetime.timezone : SimpleTimeZone, UTC;
9409 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12") ==
9410 SysTime(DateTime(2010, 7, 4, 7, 6, 12)));
9412 assert(SysTime.fromSimpleString("1998-Dec-25 02:15:00.007") ==
9413 SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(7)));
9415 assert(SysTime.fromSimpleString("0000-Jan-05 23:09:59.00002") ==
9416 SysTime(DateTime(0, 1, 5, 23, 9, 59), usecs(20)));
9418 assert(SysTime.fromSimpleString("2013-Feb-07 04:39:37.000050392") ==
9419 SysTime(DateTime(2013, 2, 7, 4, 39, 37), hnsecs(503)));
9421 assert(SysTime.fromSimpleString("-0004-Jan-05 00:00:02") ==
9422 SysTime(DateTime(-4, 1, 5, 0, 0, 2)));
9424 assert(SysTime.fromSimpleString(" 2010-Jul-04 07:06:12 ") ==
9425 SysTime(DateTime(2010, 7, 4, 7, 6, 12)));
9427 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12Z") ==
9428 SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC()));
9430 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12-08:00") ==
9431 SysTime(DateTime(2010, 7, 4, 7, 6, 12),
9432 new immutable SimpleTimeZone(hours(-8))));
9434 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12+08:00") ==
9435 SysTime(DateTime(2010, 7, 4, 7, 6, 12),
9436 new immutable SimpleTimeZone(hours(8))));
9439 @safe unittest
9441 import core.time;
9442 foreach (str; ["", "20100704000000", "20100704 000000",
9443 "20100704t000000", "20100704T000000.", "20100704T000000.0",
9444 "2010-07-0400:00:00", "2010-07-04 00:00:00", "2010-07-04t00:00:00",
9445 "2010-07-04T00:00:00.", "2010-07-04T00:00:00.0",
9446 "2010-Jul-0400:00:00", "2010-Jul-04t00:00:00", "2010-Jul-04T00:00:00",
9447 "2010-Jul-04 00:00:00.", "2010-Jul-04 00:00:00.A", "2010-Jul-04 00:00:00.Z",
9448 "2010-Jul-04 00:00:00.0000000A", "2010-Jul-04 00:00:00.00000000A",
9449 "2010-Jul-04 00:00:00+", "2010-Jul-04 00:00:00-",
9450 "2010-Jul-04 00:00:00:", "2010-Jul-04 00:00:00-:",
9451 "2010-Jul-04 00:00:00+:", "2010-Jul-04 00:00:00-1:",
9452 "2010-Jul-04 00:00:00+1:", "2010-Jul-04 00:00:00+1:0",
9453 "2010-Jul-04 00:00:00-12.00", "2010-Jul-04 00:00:00+12.00",
9454 "2010-Jul-04 00:00:00-8", "2010-Jul-04 00:00:00+8",
9455 "20100704T000000-800", "20100704T000000+800",
9456 "20100704T000000-080", "20100704T000000+080",
9457 "20100704T000000-2400", "20100704T000000+2400",
9458 "20100704T000000-1260", "20100704T000000+1260",
9459 "20100704T000000.0-800", "20100704T000000.0+800",
9460 "20100704T000000.0-8", "20100704T000000.0+8",
9461 "20100704T000000.0-080", "20100704T000000.0+080",
9462 "20100704T000000.0-2400", "20100704T000000.0+2400",
9463 "20100704T000000.0-1260", "20100704T000000.0+1260",
9464 "2010-Jul-04 00:00:00-8:00", "2010-Jul-04 00:00:00+8:00",
9465 "2010-Jul-04 00:00:00-08:0", "2010-Jul-04 00:00:00+08:0",
9466 "2010-Jul-04 00:00:00-24:00", "2010-Jul-04 00:00:00+24:00",
9467 "2010-Jul-04 00:00:00-12:60", "2010-Jul-04 00:00:00+24:60",
9468 "2010-Jul-04 00:00:00.0-8:00", "2010-Jul-04 00:00:00+8:00",
9469 "2010-Jul-04 00:00:00.0-8", "2010-Jul-04 00:00:00.0+8",
9470 "2010-Jul-04 00:00:00.0-08:0", "2010-Jul-04 00:00:00.0+08:0",
9471 "2010-Jul-04 00:00:00.0-24:00", "2010-Jul-04 00:00:00.0+24:00",
9472 "2010-Jul-04 00:00:00.0-12:60", "2010-Jul-04 00:00:00.0+24:60",
9473 "20101222T172201", "2010-12-22T172201"])
9475 assertThrown!DateTimeException(SysTime.fromSimpleString(str), format("[%s]", str));
9478 static void test(string str, SysTime st, size_t line = __LINE__)
9480 if (SysTime.fromSimpleString(str) != st)
9481 throw new AssertError("unittest failure", __FILE__, line);
9484 test("2010-Dec-22 17:22:01", SysTime(DateTime(2010, 12, 22, 17, 22, 1)));
9485 test("1999-Jul-06 12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
9486 test("-1999-Jul-06 12:30:33", SysTime(DateTime(-1999, 7, 6, 12, 30, 33)));
9487 test("+01999-Jul-06 12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
9488 test("1999-Jul-06 12:30:33 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
9489 test(" 1999-Jul-06 12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
9490 test(" 1999-Jul-06 12:30:33 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33)));
9492 test("1907-Jul-07 12:12:12.0", SysTime(DateTime(1907, 7, 7, 12, 12, 12)));
9493 test("1907-Jul-07 12:12:12.0000000", SysTime(DateTime(1907, 7, 7, 12, 12, 12)));
9494 test("2010-Jul-04 00:00:00.00000000", SysTime(Date(2010, 7, 4)));
9495 test("2010-Jul-04 00:00:00.00000009", SysTime(Date(2010, 7, 4)));
9496 test("2010-Jul-04 00:00:00.00000019", SysTime(DateTime(2010, 7, 4), hnsecs(1)));
9497 test("1907-Jul-07 12:12:12.0000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), hnsecs(1)));
9498 test("1907-Jul-07 12:12:12.000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1)));
9499 test("1907-Jul-07 12:12:12.0000010", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1)));
9500 test("1907-Jul-07 12:12:12.001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1)));
9501 test("1907-Jul-07 12:12:12.0010000", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1)));
9503 auto west60 = new immutable SimpleTimeZone(hours(-1));
9504 auto west90 = new immutable SimpleTimeZone(minutes(-90));
9505 auto west480 = new immutable SimpleTimeZone(hours(-8));
9506 auto east60 = new immutable SimpleTimeZone(hours(1));
9507 auto east90 = new immutable SimpleTimeZone(minutes(90));
9508 auto east480 = new immutable SimpleTimeZone(hours(8));
9510 test("2010-Dec-22 17:22:01Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), UTC()));
9511 test("2010-Dec-22 17:22:01-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60));
9512 test("2010-Dec-22 17:22:01-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60));
9513 test("2010-Dec-22 17:22:01-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west90));
9514 test("2010-Dec-22 17:22:01-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west480));
9515 test("2010-Dec-22 17:22:01+01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60));
9516 test("2010-Dec-22 17:22:01+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60));
9517 test("2010-Dec-22 17:22:01+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90));
9518 test("2010-Dec-22 17:22:01+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east480));
9520 test("2010-Nov-03 06:51:06.57159Z", SysTime(DateTime(2010, 11, 3, 6, 51, 6), hnsecs(5715900), UTC()));
9521 test("2010-Dec-22 17:22:01.23412Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_341_200), UTC()));
9522 test("2010-Dec-22 17:22:01.23112-01:00",
9523 SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_311_200), west60));
9524 test("2010-Dec-22 17:22:01.45-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), west60));
9525 test("2010-Dec-22 17:22:01.1-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_000_000), west90));
9526 test("2010-Dec-22 17:22:01.55-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(5_500_000), west480));
9527 test("2010-Dec-22 17:22:01.1234567+01:00",
9528 SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_234_567), east60));
9529 test("2010-Dec-22 17:22:01.0+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60));
9530 test("2010-Dec-22 17:22:01.0000000+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90));
9531 test("2010-Dec-22 17:22:01.45+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), east480));
9533 static void testScope(scope ref string str) @safe
9535 auto result = SysTime.fromSimpleString(str);
9539 // https://issues.dlang.org/show_bug.cgi?id=17801
9540 @safe unittest
9542 import core.time;
9543 import std.conv : to;
9544 import std.meta : AliasSeq;
9545 static foreach (C; AliasSeq!(char, wchar, dchar))
9547 static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[]))
9549 assert(SysTime.fromSimpleString(to!S("2012-Dec-21 14:15:16Z")) ==
9550 SysTime(DateTime(2012, 12, 21, 14, 15, 16), UTC()));
9557 Returns the $(LREF SysTime) farthest in the past which is representable
9558 by $(LREF SysTime).
9560 The $(LREF SysTime) which is returned is in UTC.
9562 @property static SysTime min() @safe pure nothrow
9564 return SysTime(long.min, UTC());
9567 @safe unittest
9569 assert(SysTime.min.year < 0);
9570 assert(SysTime.min < SysTime.max);
9575 Returns the $(LREF SysTime) farthest in the future which is representable
9576 by $(LREF SysTime).
9578 The $(LREF SysTime) which is returned is in UTC.
9580 @property static SysTime max() @safe pure nothrow
9582 return SysTime(long.max, UTC());
9585 @safe unittest
9587 assert(SysTime.max.year > 0);
9588 assert(SysTime.max > SysTime.min);
9592 private:
9595 Returns `stdTime` converted to $(LREF SysTime)'s time zone.
9597 @property long adjTime() @safe const nothrow scope
9599 return _timezone.utcToTZ(_stdTime);
9604 Converts the given hnsecs from $(LREF SysTime)'s time zone to std time.
9606 @property void adjTime(long adjTime) @safe nothrow scope
9608 _stdTime = _timezone.tzToUTC(adjTime);
9612 final class InitTimeZone : TimeZone
9614 public:
9616 static immutable(InitTimeZone) opCall() @safe pure nothrow @nogc { return _initTimeZone; }
9618 @property override bool hasDST() @safe const nothrow @nogc { return false; }
9620 override bool dstInEffect(long stdTime) @safe const scope nothrow @nogc { return false; }
9622 override long utcToTZ(long stdTime) @safe const scope nothrow @nogc { return 0; }
9624 override long tzToUTC(long adjTime) @safe const scope nothrow @nogc { return 0; }
9626 override Duration utcOffsetAt(long stdTime) @safe const scope nothrow @nogc { return Duration.zero; }
9628 private:
9630 this() @safe immutable pure
9632 super("SysTime.init's timezone", "SysTime.init's timezone", "SysTime.init's timezone");
9635 static immutable InitTimeZone _initTimeZone = new immutable(InitTimeZone);
9638 // https://issues.dlang.org/show_bug.cgi?id=17732
9639 @safe unittest
9641 assert(SysTime.init.timezone is InitTimeZone());
9642 assert(SysTime.init.toISOString() == "00010101T000000+00:00");
9643 assert(SysTime.init.toISOExtString() == "0001-01-01T00:00:00+00:00");
9644 assert(SysTime.init.toSimpleString() == "0001-Jan-01 00:00:00+00:00");
9645 assert(SysTime.init.toString() == "0001-Jan-01 00:00:00+00:00");
9648 // Assigning a value to _timezone in SysTime.init currently doesn't work due
9649 // to https://issues.dlang.org/show_bug.cgi?id=17740. So, to hack around
9650 // that problem, these accessors have been added so that we can insert a
9651 // runtime check for null and then use InitTimeZone for SysTime.init (which
9652 // which is the only case where _timezone would be null). This thus fixes
9653 // the problem with segfaulting when using SysTime.init but at the cost of
9654 // what should be an unnecessary null check. Once 17740 has finally been
9655 // fixed, _timezoneStorage should be removed, these accessors should be
9656 // removed, and the _timezone variable declaration should be restored.
9657 pragma(inline, true) @property _timezone() @safe const pure nothrow @nogc
9659 return _timezoneStorage is null ? InitTimeZone() : _timezoneStorage;
9662 pragma(inline, true) @property void _timezone(return scope immutable TimeZone tz) @safe pure nothrow @nogc scope
9664 _timezoneStorage = tz;
9668 long _stdTime;
9669 Rebindable!(immutable TimeZone) _timezoneStorage;
9670 //Rebindable!(immutable TimeZone) _timezone = InitTimeZone();
9674 @safe unittest
9676 import core.time : days, hours, seconds;
9677 import std.datetime.date : DateTime;
9678 import std.datetime.timezone : SimpleTimeZone, UTC;
9680 // make a specific point in time in the UTC timezone
9681 auto st = SysTime(DateTime(2018, 1, 1, 10, 30, 0), UTC());
9682 // make a specific point in time in the New York timezone
9683 auto ny = SysTime(
9684 DateTime(2018, 1, 1, 10, 30, 0),
9685 new immutable SimpleTimeZone(-5.hours, "America/New_York")
9688 // ISO standard time strings
9689 assert(st.toISOString() == "20180101T103000Z");
9690 assert(st.toISOExtString() == "2018-01-01T10:30:00Z");
9692 // add two days and 30 seconds
9693 st += 2.days + 30.seconds;
9694 assert(st.toISOExtString() == "2018-01-03T10:30:30Z");
9699 Converts from unix time (which uses midnight, January 1st, 1970 UTC as its
9700 epoch and seconds as its units) to "std time" (which uses midnight,
9701 January 1st, 1 A.D. UTC and hnsecs as its units).
9703 The C standard does not specify the representation of time_t, so it is
9704 implementation defined. On POSIX systems, unix time is equivalent to
9705 time_t, but that's not necessarily true on other systems (e.g. it is
9706 not true for the Digital Mars C runtime). So, be careful when using unix
9707 time with C functions on non-POSIX systems.
9709 "std time"'s epoch is based on the Proleptic Gregorian Calendar per ISO
9710 8601 and is what $(LREF SysTime) uses internally. However, holding the time
9711 as an integer in hnsecs since that epoch technically isn't actually part of
9712 the standard, much as it's based on it, so the name "std time" isn't
9713 particularly good, but there isn't an official name for it. C# uses "ticks"
9714 for the same thing, but they aren't actually clock ticks, and the term
9715 "ticks" $(I is) used for actual clock ticks for $(REF MonoTime, core,time),
9716 so it didn't make sense to use the term ticks here. So, for better or worse,
9717 std.datetime uses the term "std time" for this.
9719 Params:
9720 unixTime = The unix time to convert.
9722 See_Also:
9723 SysTime.fromUnixTime
9725 long unixTimeToStdTime(long unixTime) @safe pure nothrow @nogc
9727 return 621_355_968_000_000_000L + convert!("seconds", "hnsecs")(unixTime);
9731 @safe unittest
9733 import std.datetime.date : DateTime;
9734 import std.datetime.timezone : UTC;
9736 // Midnight, January 1st, 1970
9737 assert(unixTimeToStdTime(0) == 621_355_968_000_000_000L);
9738 assert(SysTime(unixTimeToStdTime(0)) ==
9739 SysTime(DateTime(1970, 1, 1), UTC()));
9741 assert(unixTimeToStdTime(int.max) == 642_830_804_470_000_000L);
9742 assert(SysTime(unixTimeToStdTime(int.max)) ==
9743 SysTime(DateTime(2038, 1, 19, 3, 14, 7), UTC()));
9745 assert(unixTimeToStdTime(-127_127) == 621_354_696_730_000_000L);
9746 assert(SysTime(unixTimeToStdTime(-127_127)) ==
9747 SysTime(DateTime(1969, 12, 30, 12, 41, 13), UTC()));
9750 @safe unittest
9752 // Midnight, January 2nd, 1970
9753 assert(unixTimeToStdTime(86_400) == 621_355_968_000_000_000L + 864_000_000_000L);
9754 // Midnight, December 31st, 1969
9755 assert(unixTimeToStdTime(-86_400) == 621_355_968_000_000_000L - 864_000_000_000L);
9757 assert(unixTimeToStdTime(0) == (Date(1970, 1, 1) - Date(1, 1, 1)).total!"hnsecs");
9758 assert(unixTimeToStdTime(0) == (DateTime(1970, 1, 1) - DateTime(1, 1, 1)).total!"hnsecs");
9760 foreach (dt; [DateTime(2010, 11, 1, 19, 5, 22), DateTime(1952, 7, 6, 2, 17, 9)])
9761 assert(unixTimeToStdTime((dt - DateTime(1970, 1, 1)).total!"seconds") == (dt - DateTime.init).total!"hnsecs");
9766 Converts std time (which uses midnight, January 1st, 1 A.D. UTC as its epoch
9767 and hnsecs as its units) to unix time (which uses midnight, January 1st,
9768 1970 UTC as its epoch and seconds as its units).
9770 The C standard does not specify the representation of time_t, so it is
9771 implementation defined. On POSIX systems, unix time is equivalent to
9772 time_t, but that's not necessarily true on other systems (e.g. it is
9773 not true for the Digital Mars C runtime). So, be careful when using unix
9774 time with C functions on non-POSIX systems.
9776 "std time"'s epoch is based on the Proleptic Gregorian Calendar per ISO
9777 8601 and is what $(LREF SysTime) uses internally. However, holding the time
9778 as an integer in hnescs since that epoch technically isn't actually part of
9779 the standard, much as it's based on it, so the name "std time" isn't
9780 particularly good, but there isn't an official name for it. C# uses "ticks"
9781 for the same thing, but they aren't actually clock ticks, and the term
9782 "ticks" $(I is) used for actual clock ticks for $(REF MonoTime, core,time),
9783 so it didn't make sense to use the term ticks here. So, for better or worse,
9784 std.datetime uses the term "std time" for this.
9786 By default, the return type is time_t (which is normally an alias for
9787 int on 32-bit systems and long on 64-bit systems), but if a different
9788 size is required than either int or long can be passed as a template
9789 argument to get the desired size.
9791 If the return type is int, and the result can't fit in an int, then the
9792 closest value that can be held in 32 bits will be used (so `int.max`
9793 if it goes over and `int.min` if it goes under). However, no attempt
9794 is made to deal with integer overflow if the return type is long.
9796 Params:
9797 T = The return type (int or long). It defaults to time_t, which is
9798 normally 32 bits on a 32-bit system and 64 bits on a 64-bit
9799 system.
9800 stdTime = The std time to convert.
9802 Returns:
9803 A signed integer representing the unix time which is equivalent to
9804 the given std time.
9806 See_Also:
9807 SysTime.toUnixTime
9809 T stdTimeToUnixTime(T = time_t)(long stdTime) @safe pure nothrow
9810 if (is(T == int) || is(T == long))
9812 immutable unixTime = convert!("hnsecs", "seconds")(stdTime - 621_355_968_000_000_000L);
9814 static assert(is(time_t == int) || is(time_t == long),
9815 "Currently, std.datetime only supports systems where time_t is int or long");
9817 static if (is(T == long))
9818 return unixTime;
9819 else static if (is(T == int))
9821 if (unixTime > int.max)
9822 return int.max;
9823 return unixTime < int.min ? int.min : cast(int) unixTime;
9825 else
9826 static assert(0, "Bug in template constraint. Only int and long allowed.");
9830 @safe unittest
9832 // Midnight, January 1st, 1970 UTC
9833 assert(stdTimeToUnixTime(621_355_968_000_000_000L) == 0);
9835 // 2038-01-19 03:14:07 UTC
9836 assert(stdTimeToUnixTime(642_830_804_470_000_000L) == int.max);
9839 @safe unittest
9841 enum unixEpochAsStdTime = (Date(1970, 1, 1) - Date.init).total!"hnsecs";
9843 assert(stdTimeToUnixTime(unixEpochAsStdTime) == 0); // Midnight, January 1st, 1970
9844 assert(stdTimeToUnixTime(unixEpochAsStdTime + 864_000_000_000L) == 86_400); // Midnight, January 2nd, 1970
9845 assert(stdTimeToUnixTime(unixEpochAsStdTime - 864_000_000_000L) == -86_400); // Midnight, December 31st, 1969
9847 assert(stdTimeToUnixTime((Date(1970, 1, 1) - Date(1, 1, 1)).total!"hnsecs") == 0);
9848 assert(stdTimeToUnixTime((DateTime(1970, 1, 1) - DateTime(1, 1, 1)).total!"hnsecs") == 0);
9850 foreach (dt; [DateTime(2010, 11, 1, 19, 5, 22), DateTime(1952, 7, 6, 2, 17, 9)])
9851 assert(stdTimeToUnixTime((dt - DateTime.init).total!"hnsecs") == (dt - DateTime(1970, 1, 1)).total!"seconds");
9853 enum max = convert!("seconds", "hnsecs")(int.max);
9854 enum min = convert!("seconds", "hnsecs")(int.min);
9855 enum one = convert!("seconds", "hnsecs")(1);
9857 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + max) == int.max);
9858 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + max) == int.max);
9860 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + max + one) == int.max + 1L);
9861 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + max + one) == int.max);
9862 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + max + 9_999_999) == int.max);
9863 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + max + 9_999_999) == int.max);
9865 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + min) == int.min);
9866 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + min) == int.min);
9868 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + min - one) == int.min - 1L);
9869 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + min - one) == int.min);
9870 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + min - 9_999_999) == int.min);
9871 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + min - 9_999_999) == int.min);
9875 version (StdDdoc)
9877 version (Windows)
9879 else
9881 alias SYSTEMTIME = void*;
9882 alias FILETIME = void*;
9886 $(BLUE This function is Windows-Only.)
9888 Converts a `SYSTEMTIME` struct to a $(LREF SysTime).
9890 Params:
9891 st = The `SYSTEMTIME` struct to convert.
9892 tz = The time zone that the time in the `SYSTEMTIME` struct is
9893 assumed to be (if the `SYSTEMTIME` was supplied by a Windows
9894 system call, the `SYSTEMTIME` will either be in local time
9895 or UTC, depending on the call).
9897 Throws:
9898 $(REF DateTimeException,std,datetime,date) if the given
9899 `SYSTEMTIME` will not fit in a $(LREF SysTime), which is highly
9900 unlikely to happen given that `SysTime.max` is in 29,228 A.D. and
9901 the maximum `SYSTEMTIME` is in 30,827 A.D.
9903 SysTime SYSTEMTIMEToSysTime(const scope SYSTEMTIME* st, immutable TimeZone tz = LocalTime()) @safe;
9907 $(BLUE This function is Windows-Only.)
9909 Converts a $(LREF SysTime) to a `SYSTEMTIME` struct.
9911 The `SYSTEMTIME` which is returned will be set using the given
9912 $(LREF SysTime)'s time zone, so to get the `SYSTEMTIME` in
9913 UTC, set the $(LREF SysTime)'s time zone to UTC.
9915 Params:
9916 sysTime = The $(LREF SysTime) to convert.
9918 Throws:
9919 $(REF DateTimeException,std,datetime,date) if the given
9920 $(LREF SysTime) will not fit in a `SYSTEMTIME`. This will only
9921 happen if the $(LREF SysTime)'s date is prior to 1601 A.D.
9923 SYSTEMTIME SysTimeToSYSTEMTIME(scope SysTime sysTime) @safe;
9927 $(BLUE This function is Windows-Only.)
9929 Converts a `FILETIME` struct to the number of hnsecs since midnight,
9930 January 1st, 1 A.D.
9932 Params:
9933 ft = The `FILETIME` struct to convert.
9935 Throws:
9936 $(REF DateTimeException,std,datetime,date) if the given
9937 `FILETIME` cannot be represented as the return value.
9939 long FILETIMEToStdTime(scope const FILETIME* ft) @safe;
9943 $(BLUE This function is Windows-Only.)
9945 Converts a `FILETIME` struct to a $(LREF SysTime).
9947 Params:
9948 ft = The `FILETIME` struct to convert.
9949 tz = The time zone that the $(LREF SysTime) will be in
9950 (`FILETIME`s are in UTC).
9952 Throws:
9953 $(REF DateTimeException,std,datetime,date) if the given
9954 `FILETIME` will not fit in a $(LREF SysTime).
9956 SysTime FILETIMEToSysTime(scope const FILETIME* ft, immutable TimeZone tz = LocalTime()) @safe;
9960 $(BLUE This function is Windows-Only.)
9962 Converts a number of hnsecs since midnight, January 1st, 1 A.D. to a
9963 `FILETIME` struct.
9965 Params:
9966 stdTime = The number of hnsecs since midnight, January 1st, 1 A.D.
9967 UTC.
9969 Throws:
9970 $(REF DateTimeException,std,datetime,date) if the given value will
9971 not fit in a `FILETIME`.
9973 FILETIME stdTimeToFILETIME(long stdTime) @safe;
9977 $(BLUE This function is Windows-Only.)
9979 Converts a $(LREF SysTime) to a `FILETIME` struct.
9981 `FILETIME`s are always in UTC.
9983 Params:
9984 sysTime = The $(LREF SysTime) to convert.
9986 Throws:
9987 $(REF DateTimeException,std,datetime,date) if the given
9988 $(LREF SysTime) will not fit in a `FILETIME`.
9990 FILETIME SysTimeToFILETIME(scope SysTime sysTime) @safe;
9992 else version (Windows)
9994 SysTime SYSTEMTIMEToSysTime(const scope SYSTEMTIME* st, immutable TimeZone tz = LocalTime()) @safe
9996 const max = SysTime.max;
9998 static void throwLaterThanMax()
10000 throw new DateTimeException("The given SYSTEMTIME is for a date greater than SysTime.max.");
10003 if (st.wYear > max.year)
10004 throwLaterThanMax();
10005 else if (st.wYear == max.year)
10007 if (st.wMonth > max.month)
10008 throwLaterThanMax();
10009 else if (st.wMonth == max.month)
10011 if (st.wDay > max.day)
10012 throwLaterThanMax();
10013 else if (st.wDay == max.day)
10015 if (st.wHour > max.hour)
10016 throwLaterThanMax();
10017 else if (st.wHour == max.hour)
10019 if (st.wMinute > max.minute)
10020 throwLaterThanMax();
10021 else if (st.wMinute == max.minute)
10023 if (st.wSecond > max.second)
10024 throwLaterThanMax();
10025 else if (st.wSecond == max.second)
10027 if (st.wMilliseconds > max.fracSecs.total!"msecs")
10028 throwLaterThanMax();
10036 auto dt = DateTime(st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
10038 import core.time : msecs;
10039 return SysTime(dt, msecs(st.wMilliseconds), tz);
10042 @system unittest
10044 auto sysTime = Clock.currTime(UTC());
10045 SYSTEMTIME st = void;
10046 GetSystemTime(&st);
10047 auto converted = SYSTEMTIMEToSysTime(&st, UTC());
10048 import core.time : abs;
10049 assert(abs((converted - sysTime)) <= dur!"seconds"(2));
10051 static void testScope(scope SYSTEMTIME* st) @safe
10053 auto result = SYSTEMTIMEToSysTime(st);
10058 SYSTEMTIME SysTimeToSYSTEMTIME(scope SysTime sysTime) @safe
10060 immutable dt = cast(DateTime) sysTime;
10062 if (dt.year < 1601)
10063 throw new DateTimeException("SYSTEMTIME cannot hold dates prior to the year 1601.");
10065 SYSTEMTIME st;
10067 st.wYear = dt.year;
10068 st.wMonth = dt.month;
10069 st.wDayOfWeek = dt.dayOfWeek;
10070 st.wDay = dt.day;
10071 st.wHour = dt.hour;
10072 st.wMinute = dt.minute;
10073 st.wSecond = dt.second;
10074 st.wMilliseconds = cast(ushort) sysTime.fracSecs.total!"msecs";
10076 return st;
10079 @system unittest
10081 SYSTEMTIME st = void;
10082 GetSystemTime(&st);
10083 auto sysTime = SYSTEMTIMEToSysTime(&st, UTC());
10085 SYSTEMTIME result = SysTimeToSYSTEMTIME(sysTime);
10087 assert(st.wYear == result.wYear);
10088 assert(st.wMonth == result.wMonth);
10089 assert(st.wDayOfWeek == result.wDayOfWeek);
10090 assert(st.wDay == result.wDay);
10091 assert(st.wHour == result.wHour);
10092 assert(st.wMinute == result.wMinute);
10093 assert(st.wSecond == result.wSecond);
10094 assert(st.wMilliseconds == result.wMilliseconds);
10096 static void testScope(scope ref SysTime st) @safe
10098 auto result = SysTimeToSYSTEMTIME(st);
10102 private enum hnsecsFrom1601 = 504_911_232_000_000_000L;
10104 long FILETIMEToStdTime(scope const FILETIME* ft) @safe
10106 ULARGE_INTEGER ul;
10107 ul.HighPart = ft.dwHighDateTime;
10108 ul.LowPart = ft.dwLowDateTime;
10109 ulong tempHNSecs = ul.QuadPart;
10111 if (tempHNSecs > long.max - hnsecsFrom1601)
10112 throw new DateTimeException("The given FILETIME cannot be represented as a stdTime value.");
10114 return cast(long) tempHNSecs + hnsecsFrom1601;
10117 SysTime FILETIMEToSysTime(scope const FILETIME* ft, immutable TimeZone tz = LocalTime()) @safe
10119 auto sysTime = SysTime(FILETIMEToStdTime(ft), UTC());
10120 sysTime.timezone = tz;
10121 return sysTime;
10124 @system unittest
10126 auto sysTime = Clock.currTime(UTC());
10127 SYSTEMTIME st = void;
10128 GetSystemTime(&st);
10130 FILETIME ft = void;
10131 SystemTimeToFileTime(&st, &ft);
10133 auto converted = FILETIMEToSysTime(&ft);
10135 import core.time : abs;
10136 assert(abs((converted - sysTime)) <= dur!"seconds"(2));
10138 static void testScope(scope FILETIME* ft) @safe
10140 auto result = FILETIMEToSysTime(ft);
10145 FILETIME stdTimeToFILETIME(long stdTime) @safe
10147 if (stdTime < hnsecsFrom1601)
10148 throw new DateTimeException("The given stdTime value cannot be represented as a FILETIME.");
10150 ULARGE_INTEGER ul;
10151 ul.QuadPart = cast(ulong) stdTime - hnsecsFrom1601;
10153 FILETIME ft;
10154 ft.dwHighDateTime = ul.HighPart;
10155 ft.dwLowDateTime = ul.LowPart;
10157 return ft;
10160 FILETIME SysTimeToFILETIME(scope SysTime sysTime) @safe
10162 return stdTimeToFILETIME(sysTime.stdTime);
10165 @system unittest
10167 SYSTEMTIME st = void;
10168 GetSystemTime(&st);
10170 FILETIME ft = void;
10171 SystemTimeToFileTime(&st, &ft);
10172 auto sysTime = FILETIMEToSysTime(&ft, UTC());
10174 FILETIME result = SysTimeToFILETIME(sysTime);
10176 assert(ft.dwLowDateTime == result.dwLowDateTime);
10177 assert(ft.dwHighDateTime == result.dwHighDateTime);
10179 static void testScope(scope ref SysTime st) @safe
10181 auto result = SysTimeToFILETIME(st);
10188 Type representing the DOS file date/time format.
10190 alias DosFileTime = uint;
10193 Converts from DOS file date/time to $(LREF SysTime).
10195 Params:
10196 dft = The DOS file time to convert.
10197 tz = The time zone which the DOS file time is assumed to be in.
10199 Throws:
10200 $(REF DateTimeException,std,datetime,date) if the `DosFileTime` is
10201 invalid.
10203 SysTime DosFileTimeToSysTime(DosFileTime dft, immutable TimeZone tz = LocalTime()) @safe
10205 uint dt = cast(uint) dft;
10207 if (dt == 0)
10208 throw new DateTimeException("Invalid DosFileTime.");
10210 int year = ((dt >> 25) & 0x7F) + 1980;
10211 int month = ((dt >> 21) & 0x0F); // 1 .. 12
10212 int dayOfMonth = ((dt >> 16) & 0x1F); // 1 .. 31
10213 int hour = (dt >> 11) & 0x1F; // 0 .. 23
10214 int minute = (dt >> 5) & 0x3F; // 0 .. 59
10215 int second = (dt << 1) & 0x3E; // 0 .. 58 (in 2 second increments)
10218 return SysTime(DateTime(year, month, dayOfMonth, hour, minute, second), tz);
10219 catch (DateTimeException dte)
10220 throw new DateTimeException("Invalid DosFileTime", __FILE__, __LINE__, dte);
10224 @safe unittest
10226 import std.datetime.date : DateTime;
10228 assert(DosFileTimeToSysTime(0b00000000001000010000000000000000) == SysTime(DateTime(1980, 1, 1, 0, 0, 0)));
10229 assert(DosFileTimeToSysTime(0b11111111100111111011111101111101) == SysTime(DateTime(2107, 12, 31, 23, 59, 58)));
10230 assert(DosFileTimeToSysTime(0x3E3F8456) == SysTime(DateTime(2011, 1, 31, 16, 34, 44)));
10233 @safe unittest
10235 static void testScope(scope ref DosFileTime dft) @safe
10237 auto result = DosFileTimeToSysTime(dft);
10243 Converts from $(LREF SysTime) to DOS file date/time.
10245 Params:
10246 sysTime = The $(LREF SysTime) to convert.
10248 Throws:
10249 $(REF DateTimeException,std,datetime,date) if the given
10250 $(LREF SysTime) cannot be converted to a `DosFileTime`.
10252 DosFileTime SysTimeToDosFileTime(scope SysTime sysTime) @safe
10254 auto dateTime = cast(DateTime) sysTime;
10256 if (dateTime.year < 1980)
10257 throw new DateTimeException("DOS File Times cannot hold dates prior to 1980.");
10259 if (dateTime.year > 2107)
10260 throw new DateTimeException("DOS File Times cannot hold dates past 2107.");
10262 uint retval = 0;
10263 retval = (dateTime.year - 1980) << 25;
10264 retval |= (dateTime.month & 0x0F) << 21;
10265 retval |= (dateTime.day & 0x1F) << 16;
10266 retval |= (dateTime.hour & 0x1F) << 11;
10267 retval |= (dateTime.minute & 0x3F) << 5;
10268 retval |= (dateTime.second >> 1) & 0x1F;
10270 return cast(DosFileTime) retval;
10274 @safe unittest
10276 import std.datetime.date : DateTime;
10278 assert(SysTimeToDosFileTime(SysTime(DateTime(1980, 1, 1, 0, 0, 0))) == 0b00000000001000010000000000000000);
10279 assert(SysTimeToDosFileTime(SysTime(DateTime(2107, 12, 31, 23, 59, 58))) == 0b11111111100111111011111101111101);
10280 assert(SysTimeToDosFileTime(SysTime(DateTime(2011, 1, 31, 16, 34, 44))) == 0x3E3F8456);
10283 @safe unittest
10285 static void testScope(scope ref SysTime st) @safe
10287 auto result = SysTimeToDosFileTime(st);
10293 The given array of `char` or random-access range of `char` or
10294 `ubyte` is expected to be in the format specified in
10295 $(HTTP tools.ietf.org/html/rfc5322, RFC 5322) section 3.3 with the
10296 grammar rule $(I date-time). It is the date-time format commonly used in
10297 internet messages such as e-mail and HTTP. The corresponding
10298 $(LREF SysTime) will be returned.
10300 RFC 822 was the original spec (hence the function's name), whereas RFC 5322
10301 is the current spec.
10303 The day of the week is ignored beyond verifying that it's a valid day of the
10304 week, as the day of the week can be inferred from the date. It is not
10305 checked whether the given day of the week matches the actual day of the week
10306 of the given date (though it is technically invalid per the spec if the
10307 day of the week doesn't match the actual day of the week of the given date).
10309 If the time zone is `"-0000"` (or considered to be equivalent to
10310 `"-0000"` by section 4.3 of the spec), a
10311 $(REF SimpleTimeZone,std,datetime,timezone) with a utc offset of `0` is
10312 used rather than $(REF UTC,std,datetime,timezone), whereas `"+0000"` uses
10313 $(REF UTC,std,datetime,timezone).
10315 Note that because $(LREF SysTime) does not currently support having a second
10316 value of 60 (as is sometimes done for leap seconds), if the date-time value
10317 does have a value of 60 for the seconds, it is treated as 59.
10319 The one area in which this function violates RFC 5322 is that it accepts
10320 `"\n"` in folding whitespace in the place of `"\r\n"`, because the
10321 HTTP spec requires it.
10323 Throws:
10324 $(REF DateTimeException,std,datetime,date) if the given string doesn't
10325 follow the grammar for a date-time field or if the resulting
10326 $(LREF SysTime) is invalid.
10328 SysTime parseRFC822DateTime()(scope const char[] value) @safe
10330 import std.string : representation;
10331 return parseRFC822DateTime(value.representation);
10334 /++ Ditto +/
10335 SysTime parseRFC822DateTime(R)(scope R value)
10336 if (isRandomAccessRange!R && hasSlicing!R && hasLength!R &&
10337 (is(immutable ElementType!R == immutable char) || is(immutable ElementType!R == immutable ubyte)))
10339 import std.algorithm.searching : find, all;
10340 import std.ascii : isDigit, isAlpha, isPrintable;
10341 import std.conv : to;
10342 import std.functional : not;
10343 import std.string : capitalize, format;
10344 import std.traits : EnumMembers, isArray;
10345 import std.typecons : Rebindable;
10347 void stripAndCheckLen(R valueBefore, size_t minLen, size_t line = __LINE__)
10349 value = _stripCFWS(valueBefore);
10350 if (value.length < minLen)
10351 throw new DateTimeException("date-time value too short", __FILE__, line);
10353 stripAndCheckLen(value, "7Dec1200:00A".length);
10355 static if (isArray!R && (is(ElementEncodingType!R == char) || is(ElementEncodingType!R == ubyte)))
10357 static string sliceAsString(R str) @trusted
10359 return cast(string) str;
10362 else
10364 char[4] temp;
10365 char[] sliceAsString(R str) @trusted
10367 size_t i = 0;
10368 foreach (c; str)
10369 temp[i++] = cast(char) c;
10370 return temp[0 .. str.length];
10374 // day-of-week
10375 if (isAlpha(value[0]))
10377 auto dowStr = sliceAsString(value[0 .. 3]);
10378 switch (dowStr)
10380 foreach (dow; EnumMembers!DayOfWeek)
10382 enum dowC = capitalize(to!string(dow));
10383 case dowC:
10384 goto afterDoW;
10386 default: throw new DateTimeException(format("Invalid day-of-week: %s", dowStr));
10388 afterDoW: stripAndCheckLen(value[3 .. value.length], ",7Dec1200:00A".length);
10389 if (value[0] != ',')
10390 throw new DateTimeException("day-of-week missing comma");
10391 stripAndCheckLen(value[1 .. value.length], "7Dec1200:00A".length);
10394 // day
10395 immutable digits = isDigit(value[1]) ? 2 : 1;
10396 immutable day = _convDigits!short(value[0 .. digits]);
10397 if (day == -1)
10398 throw new DateTimeException("Invalid day");
10399 stripAndCheckLen(value[digits .. value.length], "Dec1200:00A".length);
10401 // month
10402 Month month;
10404 auto monStr = sliceAsString(value[0 .. 3]);
10405 switch (monStr)
10407 foreach (mon; EnumMembers!Month)
10409 enum monC = capitalize(to!string(mon));
10410 case monC:
10412 month = mon;
10413 goto afterMon;
10416 default: throw new DateTimeException(format("Invalid month: %s", monStr));
10418 afterMon: stripAndCheckLen(value[3 .. value.length], "1200:00A".length);
10421 // year
10422 auto found = value[2 .. value.length].find!(not!(isDigit))();
10423 size_t yearLen = value.length - found.length;
10424 if (found.length == 0)
10425 throw new DateTimeException("Invalid year");
10426 if (found[0] == ':')
10427 yearLen -= 2;
10428 auto year = _convDigits!short(value[0 .. yearLen]);
10429 if (year < 1900)
10431 if (year == -1)
10432 throw new DateTimeException("Invalid year");
10433 if (yearLen < 4)
10435 if (yearLen == 3)
10436 year += 1900;
10437 else if (yearLen == 2)
10438 year += year < 50 ? 2000 : 1900;
10439 else
10440 throw new DateTimeException("Invalid year. Too few digits.");
10442 else
10443 throw new DateTimeException("Invalid year. Cannot be earlier than 1900.");
10445 stripAndCheckLen(value[yearLen .. value.length], "00:00A".length);
10447 // hour
10448 immutable hour = _convDigits!short(value[0 .. 2]);
10449 stripAndCheckLen(value[2 .. value.length], ":00A".length);
10450 if (value[0] != ':')
10451 throw new DateTimeException("Invalid hour");
10452 stripAndCheckLen(value[1 .. value.length], "00A".length);
10454 // minute
10455 immutable minute = _convDigits!short(value[0 .. 2]);
10456 stripAndCheckLen(value[2 .. value.length], "A".length);
10458 // second
10459 short second;
10460 if (value[0] == ':')
10462 stripAndCheckLen(value[1 .. value.length], "00A".length);
10463 second = _convDigits!short(value[0 .. 2]);
10464 // this is just if/until SysTime is sorted out to fully support leap seconds
10465 if (second == 60)
10466 second = 59;
10467 stripAndCheckLen(value[2 .. value.length], "A".length);
10470 immutable(TimeZone) parseTZ(int sign)
10472 if (value.length < 5)
10473 throw new DateTimeException("Invalid timezone");
10474 immutable zoneHours = _convDigits!short(value[1 .. 3]);
10475 immutable zoneMinutes = _convDigits!short(value[3 .. 5]);
10476 if (zoneHours == -1 || zoneMinutes == -1 || zoneMinutes > 59)
10477 throw new DateTimeException("Invalid timezone");
10478 value = value[5 .. value.length];
10479 immutable utcOffset = (dur!"hours"(zoneHours) + dur!"minutes"(zoneMinutes)) * sign;
10480 if (utcOffset == Duration.zero)
10482 return sign == 1 ? cast(immutable(TimeZone))UTC()
10483 : cast(immutable(TimeZone))new immutable SimpleTimeZone(Duration.zero);
10485 return new immutable(SimpleTimeZone)(utcOffset);
10488 // zone
10489 Rebindable!(immutable TimeZone) tz;
10490 if (value[0] == '-')
10491 tz = parseTZ(-1);
10492 else if (value[0] == '+')
10493 tz = parseTZ(1);
10494 else
10496 // obs-zone
10497 immutable tzLen = value.length - find(value, ' ', '\t', '(')[0].length;
10498 switch (sliceAsString(value[0 .. tzLen <= 4 ? tzLen : 4]))
10500 case "UT": case "GMT": tz = UTC(); break;
10501 case "EST": tz = new immutable SimpleTimeZone(dur!"hours"(-5)); break;
10502 case "EDT": tz = new immutable SimpleTimeZone(dur!"hours"(-4)); break;
10503 case "CST": tz = new immutable SimpleTimeZone(dur!"hours"(-6)); break;
10504 case "CDT": tz = new immutable SimpleTimeZone(dur!"hours"(-5)); break;
10505 case "MST": tz = new immutable SimpleTimeZone(dur!"hours"(-7)); break;
10506 case "MDT": tz = new immutable SimpleTimeZone(dur!"hours"(-6)); break;
10507 case "PST": tz = new immutable SimpleTimeZone(dur!"hours"(-8)); break;
10508 case "PDT": tz = new immutable SimpleTimeZone(dur!"hours"(-7)); break;
10509 case "J": case "j": throw new DateTimeException("Invalid timezone");
10510 default:
10512 if (all!(isAlpha)(value[0 .. tzLen]))
10514 tz = new immutable SimpleTimeZone(Duration.zero);
10515 break;
10517 throw new DateTimeException("Invalid timezone");
10520 value = value[tzLen .. value.length];
10523 // This is kind of arbitrary. Technically, nothing but CFWS is legal past
10524 // the end of the timezone, but we don't want to be picky about that in a
10525 // function that's just parsing rather than validating. So, the idea here is
10526 // that if the next character is printable (and not part of CFWS), then it
10527 // might be part of the timezone and thus affect what the timezone was
10528 // supposed to be, so we'll throw, but otherwise, we'll just ignore it.
10529 if (!value.empty && isPrintable(value[0]) && value[0] != ' ' && value[0] != '(')
10530 throw new DateTimeException("Invalid timezone");
10533 return SysTime(DateTime(year, month, day, hour, minute, second), tz);
10534 catch (DateTimeException dte)
10535 throw new DateTimeException("date-time format is correct, but the resulting SysTime is invalid.", dte);
10539 @safe unittest
10541 import core.time : hours;
10542 import std.datetime.date : DateTime, DateTimeException;
10543 import std.datetime.timezone : SimpleTimeZone, UTC;
10544 import std.exception : assertThrown;
10546 auto tz = new immutable SimpleTimeZone(hours(-8));
10547 assert(parseRFC822DateTime("Sat, 6 Jan 1990 12:14:19 -0800") ==
10548 SysTime(DateTime(1990, 1, 6, 12, 14, 19), tz));
10550 assert(parseRFC822DateTime("9 Jul 2002 13:11 +0000") ==
10551 SysTime(DateTime(2002, 7, 9, 13, 11, 0), UTC()));
10553 auto badStr = "29 Feb 2001 12:17:16 +0200";
10554 assertThrown!DateTimeException(parseRFC822DateTime(badStr));
10557 version (StdUnittest) private void testParse822(alias cr)(string str, SysTime expected, size_t line = __LINE__)
10559 import std.format : format;
10560 auto value = cr(str);
10561 auto result = parseRFC822DateTime(value);
10562 if (result != expected)
10563 throw new AssertError(format("wrong result. expected [%s], actual[%s]", expected, result), __FILE__, line);
10566 version (StdUnittest) private void testBadParse822(alias cr)(string str, size_t line = __LINE__)
10569 parseRFC822DateTime(cr(str));
10570 catch (DateTimeException)
10571 return;
10572 throw new AssertError("No DateTimeException was thrown", __FILE__, line);
10575 @system unittest
10577 import core.time;
10578 import std.algorithm.iteration : filter, map;
10579 import std.algorithm.searching : canFind;
10580 import std.array : array;
10581 import std.ascii : letters;
10582 import std.format : format;
10583 import std.meta : AliasSeq;
10584 import std.range : chain, iota, take;
10585 import std.stdio : writefln, writeln;
10586 import std.string : representation;
10588 static struct Rand3Letters
10590 enum empty = false;
10591 @property auto front() { return _mon; }
10592 void popFront()
10594 import std.exception : assumeUnique;
10595 import std.random : rndGen;
10596 _mon = rndGen.map!(a => letters[a % letters.length])().take(3).array().assumeUnique();
10598 string _mon;
10599 static auto start() { Rand3Letters retval; retval.popFront(); return retval; }
10602 static foreach (cr; AliasSeq!(function(string a){return cast(char[]) a;},
10603 function(string a){return cast(ubyte[]) a;},
10604 function(string a){return a;},
10605 function(string a){return map!(b => cast(char) b)(a.representation);}))
10606 {(){ // workaround slow optimizations for large functions
10607 // https://issues.dlang.org/show_bug.cgi?id=2396
10608 scope(failure) writeln(typeof(cr).stringof);
10609 alias test = testParse822!cr;
10610 alias testBad = testBadParse822!cr;
10612 immutable std1 = DateTime(2012, 12, 21, 13, 14, 15);
10613 immutable std2 = DateTime(2012, 12, 21, 13, 14, 0);
10614 immutable dst1 = DateTime(1976, 7, 4, 5, 4, 22);
10615 immutable dst2 = DateTime(1976, 7, 4, 5, 4, 0);
10617 test("21 Dec 2012 13:14:15 +0000", SysTime(std1, UTC()));
10618 test("21 Dec 2012 13:14 +0000", SysTime(std2, UTC()));
10619 test("Fri, 21 Dec 2012 13:14 +0000", SysTime(std2, UTC()));
10620 test("Fri, 21 Dec 2012 13:14:15 +0000", SysTime(std1, UTC()));
10622 test("04 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC()));
10623 test("04 Jul 1976 05:04 +0000", SysTime(dst2, UTC()));
10624 test("Sun, 04 Jul 1976 05:04 +0000", SysTime(dst2, UTC()));
10625 test("Sun, 04 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC()));
10627 test("4 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC()));
10628 test("4 Jul 1976 05:04 +0000", SysTime(dst2, UTC()));
10629 test("Sun, 4 Jul 1976 05:04 +0000", SysTime(dst2, UTC()));
10630 test("Sun, 4 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC()));
10632 auto badTZ = new immutable SimpleTimeZone(Duration.zero);
10633 test("21 Dec 2012 13:14:15 -0000", SysTime(std1, badTZ));
10634 test("21 Dec 2012 13:14 -0000", SysTime(std2, badTZ));
10635 test("Fri, 21 Dec 2012 13:14 -0000", SysTime(std2, badTZ));
10636 test("Fri, 21 Dec 2012 13:14:15 -0000", SysTime(std1, badTZ));
10638 test("04 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ));
10639 test("04 Jul 1976 05:04 -0000", SysTime(dst2, badTZ));
10640 test("Sun, 04 Jul 1976 05:04 -0000", SysTime(dst2, badTZ));
10641 test("Sun, 04 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ));
10643 test("4 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ));
10644 test("4 Jul 1976 05:04 -0000", SysTime(dst2, badTZ));
10645 test("Sun, 4 Jul 1976 05:04 -0000", SysTime(dst2, badTZ));
10646 test("Sun, 4 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ));
10648 auto pst = new immutable SimpleTimeZone(dur!"hours"(-8));
10649 auto pdt = new immutable SimpleTimeZone(dur!"hours"(-7));
10650 test("21 Dec 2012 13:14:15 -0800", SysTime(std1, pst));
10651 test("21 Dec 2012 13:14 -0800", SysTime(std2, pst));
10652 test("Fri, 21 Dec 2012 13:14 -0800", SysTime(std2, pst));
10653 test("Fri, 21 Dec 2012 13:14:15 -0800", SysTime(std1, pst));
10655 test("04 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt));
10656 test("04 Jul 1976 05:04 -0700", SysTime(dst2, pdt));
10657 test("Sun, 04 Jul 1976 05:04 -0700", SysTime(dst2, pdt));
10658 test("Sun, 04 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt));
10660 test("4 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt));
10661 test("4 Jul 1976 05:04 -0700", SysTime(dst2, pdt));
10662 test("Sun, 4 Jul 1976 05:04 -0700", SysTime(dst2, pdt));
10663 test("Sun, 4 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt));
10665 auto cet = new immutable SimpleTimeZone(dur!"hours"(1));
10666 auto cest = new immutable SimpleTimeZone(dur!"hours"(2));
10667 test("21 Dec 2012 13:14:15 +0100", SysTime(std1, cet));
10668 test("21 Dec 2012 13:14 +0100", SysTime(std2, cet));
10669 test("Fri, 21 Dec 2012 13:14 +0100", SysTime(std2, cet));
10670 test("Fri, 21 Dec 2012 13:14:15 +0100", SysTime(std1, cet));
10672 test("04 Jul 1976 05:04:22 +0200", SysTime(dst1, cest));
10673 test("04 Jul 1976 05:04 +0200", SysTime(dst2, cest));
10674 test("Sun, 04 Jul 1976 05:04 +0200", SysTime(dst2, cest));
10675 test("Sun, 04 Jul 1976 05:04:22 +0200", SysTime(dst1, cest));
10677 test("4 Jul 1976 05:04:22 +0200", SysTime(dst1, cest));
10678 test("4 Jul 1976 05:04 +0200", SysTime(dst2, cest));
10679 test("Sun, 4 Jul 1976 05:04 +0200", SysTime(dst2, cest));
10680 test("Sun, 4 Jul 1976 05:04:22 +0200", SysTime(dst1, cest));
10682 // dst and std times are switched in the Southern Hemisphere which is why the
10683 // time zone names and DateTime variables don't match.
10684 auto cstStd = new immutable SimpleTimeZone(dur!"hours"(9) + dur!"minutes"(30));
10685 auto cstDST = new immutable SimpleTimeZone(dur!"hours"(10) + dur!"minutes"(30));
10686 test("21 Dec 2012 13:14:15 +1030", SysTime(std1, cstDST));
10687 test("21 Dec 2012 13:14 +1030", SysTime(std2, cstDST));
10688 test("Fri, 21 Dec 2012 13:14 +1030", SysTime(std2, cstDST));
10689 test("Fri, 21 Dec 2012 13:14:15 +1030", SysTime(std1, cstDST));
10691 test("04 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd));
10692 test("04 Jul 1976 05:04 +0930", SysTime(dst2, cstStd));
10693 test("Sun, 04 Jul 1976 05:04 +0930", SysTime(dst2, cstStd));
10694 test("Sun, 04 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd));
10696 test("4 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd));
10697 test("4 Jul 1976 05:04 +0930", SysTime(dst2, cstStd));
10698 test("Sun, 4 Jul 1976 05:04 +0930", SysTime(dst2, cstStd));
10699 test("Sun, 4 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd));
10701 foreach (int i, mon; _monthNames)
10703 test(format("17 %s 2012 00:05:02 +0000", mon), SysTime(DateTime(2012, i + 1, 17, 0, 5, 2), UTC()));
10704 test(format("17 %s 2012 00:05 +0000", mon), SysTime(DateTime(2012, i + 1, 17, 0, 5, 0), UTC()));
10707 import std.uni : toLower, toUpper;
10708 foreach (mon; chain(_monthNames[].map!(a => toLower(a))(),
10709 _monthNames[].map!(a => toUpper(a))(),
10710 ["Jam", "Jen", "Fec", "Fdb", "Mas", "Mbr", "Aps", "Aqr", "Mai", "Miy",
10711 "Jum", "Jbn", "Jup", "Jal", "Aur", "Apg", "Sem", "Sap", "Ocm", "Odt",
10712 "Nom", "Nav", "Dem", "Dac"],
10713 Rand3Letters.start().filter!(a => !_monthNames[].canFind(a)).take(20)))
10715 scope(failure) writefln("Month: %s", mon);
10716 testBad(format("17 %s 2012 00:05:02 +0000", mon));
10717 testBad(format("17 %s 2012 00:05 +0000", mon));
10720 immutable string[7] daysOfWeekNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
10723 auto start = SysTime(DateTime(2012, 11, 11, 9, 42, 0), UTC());
10724 int day = 11;
10726 foreach (int i, dow; daysOfWeekNames)
10728 auto curr = start + dur!"days"(i);
10729 test(format("%s, %s Nov 2012 09:42:00 +0000", dow, day), curr);
10730 test(format("%s, %s Nov 2012 09:42 +0000", dow, day++), curr);
10732 // Whether the day of the week matches the date is ignored.
10733 test(format("%s, 11 Nov 2012 09:42:00 +0000", dow), start);
10734 test(format("%s, 11 Nov 2012 09:42 +0000", dow), start);
10738 foreach (dow; chain(daysOfWeekNames[].map!(a => toLower(a))(),
10739 daysOfWeekNames[].map!(a => toUpper(a))(),
10740 ["Sum", "Spn", "Mom", "Man", "Tuf", "Tae", "Wem", "Wdd", "The", "Tur",
10741 "Fro", "Fai", "San", "Sut"],
10742 Rand3Letters.start().filter!(a => !daysOfWeekNames[].canFind(a)).take(20)))
10744 scope(failure) writefln("Day of Week: %s", dow);
10745 testBad(format("%s, 11 Nov 2012 09:42:00 +0000", dow));
10746 testBad(format("%s, 11 Nov 2012 09:42 +0000", dow));
10749 testBad("31 Dec 1899 23:59:59 +0000");
10750 test("01 Jan 1900 00:00:00 +0000", SysTime(Date(1900, 1, 1), UTC()));
10751 test("01 Jan 1900 00:00:00 -0000", SysTime(Date(1900, 1, 1),
10752 new immutable SimpleTimeZone(Duration.zero)));
10753 test("01 Jan 1900 00:00:00 -0700", SysTime(Date(1900, 1, 1),
10754 new immutable SimpleTimeZone(dur!"hours"(-7))));
10757 auto st1 = SysTime(Date(1900, 1, 1), UTC());
10758 auto st2 = SysTime(Date(1900, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-11)));
10759 foreach (i; 1900 .. 2102)
10761 test(format("1 Jan %05d 00:00 +0000", i), st1);
10762 test(format("1 Jan %05d 00:00 -1100", i), st2);
10763 st1.add!"years"(1);
10764 st2.add!"years"(1);
10766 st1.year = 9998;
10767 st2.year = 9998;
10768 foreach (i; 9998 .. 11_002)
10770 test(format("1 Jan %05d 00:00 +0000", i), st1);
10771 test(format("1 Jan %05d 00:00 -1100", i), st2);
10772 st1.add!"years"(1);
10773 st2.add!"years"(1);
10777 testBad("12 Feb 1907 23:17:09 0000");
10778 testBad("12 Feb 1907 23:17:09 +000");
10779 testBad("12 Feb 1907 23:17:09 -000");
10780 testBad("12 Feb 1907 23:17:09 +00000");
10781 testBad("12 Feb 1907 23:17:09 -00000");
10782 testBad("12 Feb 1907 23:17:09 +A");
10783 testBad("12 Feb 1907 23:17:09 +PST");
10784 testBad("12 Feb 1907 23:17:09 -A");
10785 testBad("12 Feb 1907 23:17:09 -PST");
10787 // test trailing stuff that gets ignored
10789 foreach (c; chain(iota(0, 33), ['('], iota(127, ubyte.max + 1)))
10791 scope(failure) writefln("c: %d", c);
10792 test(format("21 Dec 2012 13:14:15 +0000%c", cast(char) c), SysTime(std1, UTC()));
10793 test(format("21 Dec 2012 13:14:15 +0000%c ", cast(char) c), SysTime(std1, UTC()));
10794 test(format("21 Dec 2012 13:14:15 +0000%chello", cast(char) c), SysTime(std1, UTC()));
10798 // test trailing stuff that doesn't get ignored
10800 foreach (c; chain(iota(33, '('), iota('(' + 1, 127)))
10802 scope(failure) writefln("c: %d", c);
10803 testBad(format("21 Dec 2012 13:14:15 +0000%c", cast(char) c));
10804 testBad(format("21 Dec 2012 13:14:15 +0000%c ", cast(char) c));
10805 testBad(format("21 Dec 2012 13:14:15 +0000%chello", cast(char) c));
10809 testBad("32 Jan 2012 12:13:14 -0800");
10810 testBad("31 Jan 2012 24:13:14 -0800");
10811 testBad("31 Jan 2012 12:60:14 -0800");
10812 testBad("31 Jan 2012 12:13:61 -0800");
10813 testBad("31 Jan 2012 12:13:14 -0860");
10814 test("31 Jan 2012 12:13:14 -0859",
10815 SysTime(DateTime(2012, 1, 31, 12, 13, 14),
10816 new immutable SimpleTimeZone(dur!"hours"(-8) + dur!"minutes"(-59))));
10818 // leap-seconds
10819 test("21 Dec 2012 15:59:60 -0800", SysTime(DateTime(2012, 12, 21, 15, 59, 59), pst));
10821 // FWS
10822 test("Sun,4 Jul 1976 05:04 +0930", SysTime(dst2, cstStd));
10823 test("Sun,4 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd));
10824 test("Sun,4 Jul 1976 05:04 +0930 (foo)", SysTime(dst2, cstStd));
10825 test("Sun,4 Jul 1976 05:04:22 +0930 (foo)", SysTime(dst1, cstStd));
10826 test("Sun,4 \r\n Jul \r\n 1976 \r\n 05:04 \r\n +0930 \r\n (foo)", SysTime(dst2, cstStd));
10827 test("Sun,4 \r\n Jul \r\n 1976 \r\n 05:04:22 \r\n +0930 \r\n (foo)", SysTime(dst1, cstStd));
10829 auto str = "01 Jan 2012 12:13:14 -0800 ";
10830 test(str, SysTime(DateTime(2012, 1, 1, 12, 13, 14), new immutable SimpleTimeZone(hours(-8))));
10831 foreach (i; 0 .. str.length)
10833 auto currStr = str.dup;
10834 currStr[i] = 'x';
10835 scope(failure) writefln("failed: %s", currStr);
10836 testBad(cast(string) currStr);
10838 foreach (i; 2 .. str.length)
10840 auto currStr = str[0 .. $ - i];
10841 scope(failure) writefln("failed: %s", currStr);
10842 testBad(cast(string) currStr);
10843 testBad((cast(string) currStr) ~ " ");
10845 }();}
10847 static void testScope(scope ref string str) @safe
10849 auto result = parseRFC822DateTime(str);
10853 // Obsolete Format per section 4.3 of RFC 5322.
10854 @system unittest
10856 import std.algorithm.iteration : filter, map;
10857 import std.ascii : letters;
10858 import std.exception : collectExceptionMsg;
10859 import std.format : format;
10860 import std.meta : AliasSeq;
10861 import std.range : chain, iota;
10862 import std.stdio : writefln, writeln;
10863 import std.string : representation;
10865 auto std1 = SysTime(DateTime(2012, 12, 21, 13, 14, 15), UTC());
10866 auto std2 = SysTime(DateTime(2012, 12, 21, 13, 14, 0), UTC());
10867 auto std3 = SysTime(DateTime(1912, 12, 21, 13, 14, 15), UTC());
10868 auto std4 = SysTime(DateTime(1912, 12, 21, 13, 14, 0), UTC());
10869 auto dst1 = SysTime(DateTime(1976, 7, 4, 5, 4, 22), UTC());
10870 auto dst2 = SysTime(DateTime(1976, 7, 4, 5, 4, 0), UTC());
10871 auto tooLate1 = SysTime(Date(10_000, 1, 1), UTC());
10872 auto tooLate2 = SysTime(DateTime(12_007, 12, 31, 12, 22, 19), UTC());
10874 static foreach (cr; AliasSeq!(function(string a){return cast(char[]) a;},
10875 function(string a){return cast(ubyte[]) a;},
10876 function(string a){return a;},
10877 function(string a){return map!(b => cast(char) b)(a.representation);}))
10878 {(){ // workaround slow optimizations for large functions
10879 // https://issues.dlang.org/show_bug.cgi?id=2396
10880 scope(failure) writeln(typeof(cr).stringof);
10881 alias test = testParse822!cr;
10883 auto list = ["", " ", " \r\n\t", "\t\r\n (hello world( frien(dog)) silly \r\n ) \t\t \r\n ()",
10884 " \n ", "\t\n\t", " \n\t (foo) \n (bar) \r\n (baz) \n "];
10886 foreach (i, cfws; list)
10888 scope(failure) writefln("i: %s", i);
10890 test(format("%1$s21%1$sDec%1$s2012%1$s13:14:15%1$s+0000%1$s", cfws), std1);
10891 test(format("%1$s21%1$sDec%1$s2012%1$s13:14%1$s+0000%1$s", cfws), std2);
10892 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s2012%1$s13:14%1$s+0000%1$s", cfws), std2);
10893 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s2012%1$s13:14:15%1$s+0000%1$s", cfws), std1);
10895 test(format("%1$s04%1$sJul%1$s1976%1$s05:04:22%1$s+0000%1$s", cfws), dst1);
10896 test(format("%1$s04%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2);
10897 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2);
10898 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s1976%1$s05:04:22 +0000%1$s", cfws), dst1);
10900 test(format("%1$s4%1$sJul%1$s1976%1$s05:04:22%1$s+0000%1$s", cfws), dst1);
10901 test(format("%1$s4%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2);
10902 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2);
10903 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s1976%1$s05:04:22%1$s+0000%1$s", cfws), dst1);
10905 test(format("%1$s21%1$sDec%1$s12%1$s13:14:15%1$s+0000%1$s", cfws), std1);
10906 test(format("%1$s21%1$sDec%1$s12%1$s13:14%1$s+0000%1$s", cfws), std2);
10907 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s12%1$s13:14%1$s+0000%1$s", cfws), std2);
10908 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s12%1$s13:14:15%1$s+0000%1$s", cfws), std1);
10910 test(format("%1$s04%1$sJul%1$s76%1$s05:04:22%1$s+0000%1$s", cfws), dst1);
10911 test(format("%1$s04%1$sJul%1$s76%1$s05:04%1$s+0000%1$s", cfws), dst2);
10912 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s76%1$s05:04%1$s+0000%1$s", cfws), dst2);
10913 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s76%1$s05:04:22%1$s+0000%1$s", cfws), dst1);
10915 test(format("%1$s4%1$sJul%1$s76 05:04:22%1$s+0000%1$s", cfws), dst1);
10916 test(format("%1$s4%1$sJul%1$s76 05:04%1$s+0000%1$s", cfws), dst2);
10917 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s76%1$s05:04%1$s+0000%1$s", cfws), dst2);
10918 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s76%1$s05:04:22%1$s+0000%1$s", cfws), dst1);
10920 test(format("%1$s21%1$sDec%1$s012%1$s13:14:15%1$s+0000%1$s", cfws), std3);
10921 test(format("%1$s21%1$sDec%1$s012%1$s13:14%1$s+0000%1$s", cfws), std4);
10922 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s012%1$s13:14%1$s+0000%1$s", cfws), std4);
10923 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s012%1$s13:14:15%1$s+0000%1$s", cfws), std3);
10925 test(format("%1$s04%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1);
10926 test(format("%1$s04%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2);
10927 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2);
10928 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1);
10930 test(format("%1$s4%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1);
10931 test(format("%1$s4%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2);
10932 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2);
10933 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1);
10935 test(format("%1$s1%1$sJan%1$s10000%1$s00:00:00%1$s+0000%1$s", cfws), tooLate1);
10936 test(format("%1$s31%1$sDec%1$s12007%1$s12:22:19%1$s+0000%1$s", cfws), tooLate2);
10937 test(format("%1$sSat%1$s,%1$s1%1$sJan%1$s10000%1$s00:00:00%1$s+0000%1$s", cfws), tooLate1);
10938 test(format("%1$sSun%1$s,%1$s31%1$sDec%1$s12007%1$s12:22:19%1$s+0000%1$s", cfws), tooLate2);
10942 // test years of 1, 2, and 3 digits.
10944 auto st1 = SysTime(Date(2000, 1, 1), UTC());
10945 auto st2 = SysTime(Date(2000, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-12)));
10946 foreach (i; 0 .. 50)
10948 test(format("1 Jan %02d 00:00 GMT", i), st1);
10949 test(format("1 Jan %02d 00:00 -1200", i), st2);
10950 st1.add!"years"(1);
10951 st2.add!"years"(1);
10956 auto st1 = SysTime(Date(1950, 1, 1), UTC());
10957 auto st2 = SysTime(Date(1950, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-12)));
10958 foreach (i; 50 .. 100)
10960 test(format("1 Jan %02d 00:00 GMT", i), st1);
10961 test(format("1 Jan %02d 00:00 -1200", i), st2);
10962 st1.add!"years"(1);
10963 st2.add!"years"(1);
10968 auto st1 = SysTime(Date(1900, 1, 1), UTC());
10969 auto st2 = SysTime(Date(1900, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-11)));
10970 foreach (i; 0 .. 1000)
10972 test(format("1 Jan %03d 00:00 GMT", i), st1);
10973 test(format("1 Jan %03d 00:00 -1100", i), st2);
10974 st1.add!"years"(1);
10975 st2.add!"years"(1);
10979 foreach (i; 0 .. 10)
10981 auto str1 = cr(format("1 Jan %d 00:00 GMT", i));
10982 auto str2 = cr(format("1 Jan %d 00:00 -1200", i));
10983 assertThrown!DateTimeException(parseRFC822DateTime(str1));
10984 assertThrown!DateTimeException(parseRFC822DateTime(str1));
10987 // test time zones
10989 auto dt = DateTime(1982, 5, 3, 12, 22, 4);
10990 test("Wed, 03 May 1982 12:22:04 UT", SysTime(dt, UTC()));
10991 test("Wed, 03 May 1982 12:22:04 GMT", SysTime(dt, UTC()));
10992 test("Wed, 03 May 1982 12:22:04 EST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-5))));
10993 test("Wed, 03 May 1982 12:22:04 EDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-4))));
10994 test("Wed, 03 May 1982 12:22:04 CST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-6))));
10995 test("Wed, 03 May 1982 12:22:04 CDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-5))));
10996 test("Wed, 03 May 1982 12:22:04 MST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-7))));
10997 test("Wed, 03 May 1982 12:22:04 MDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-6))));
10998 test("Wed, 03 May 1982 12:22:04 PST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-8))));
10999 test("Wed, 03 May 1982 12:22:04 PDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-7))));
11001 auto badTZ = new immutable SimpleTimeZone(Duration.zero);
11002 foreach (dchar c; filter!(a => a != 'j' && a != 'J')(letters))
11004 scope(failure) writefln("c: %s", c);
11005 test(format("Wed, 03 May 1982 12:22:04 %s", c), SysTime(dt, badTZ));
11006 test(format("Wed, 03 May 1982 12:22:04%s", c), SysTime(dt, badTZ));
11009 foreach (dchar c; ['j', 'J'])
11011 scope(failure) writefln("c: %s", c);
11012 assertThrown!DateTimeException(parseRFC822DateTime(cr(format("Wed, 03 May 1982 12:22:04 %s", c))));
11013 assertThrown!DateTimeException(parseRFC822DateTime(cr(format("Wed, 03 May 1982 12:22:04%s", c))));
11016 foreach (string s; ["AAA", "GQW", "DDT", "PDA", "GT", "GM"])
11018 scope(failure) writefln("s: %s", s);
11019 test(format("Wed, 03 May 1982 12:22:04 %s", s), SysTime(dt, badTZ));
11022 // test trailing stuff that gets ignored
11024 foreach (c; chain(iota(0, 33), ['('], iota(127, ubyte.max + 1)))
11026 scope(failure) writefln("c: %d", c);
11027 test(format("21Dec1213:14:15+0000%c", cast(char) c), std1);
11028 test(format("21Dec1213:14:15+0000%c ", cast(char) c), std1);
11029 test(format("21Dec1213:14:15+0000%chello", cast(char) c), std1);
11033 // test trailing stuff that doesn't get ignored
11035 foreach (c; chain(iota(33, '('), iota('(' + 1, 127)))
11037 scope(failure) writefln("c: %d", c);
11038 assertThrown!DateTimeException(
11039 parseRFC822DateTime(cr(format("21Dec1213:14:15+0000%c", cast(char) c))));
11040 assertThrown!DateTimeException(
11041 parseRFC822DateTime(cr(format("21Dec1213:14:15+0000%c ", cast(char) c))));
11042 assertThrown!DateTimeException(
11043 parseRFC822DateTime(cr(format("21Dec1213:14:15+0000%chello", cast(char) c))));
11048 // test that the checks for minimum length work correctly and avoid
11049 // any RangeErrors.
11050 test("7Dec1200:00A", SysTime(DateTime(2012, 12, 7, 0, 0, 0),
11051 new immutable SimpleTimeZone(Duration.zero)));
11052 test("Fri,7Dec1200:00A", SysTime(DateTime(2012, 12, 7, 0, 0, 0),
11053 new immutable SimpleTimeZone(Duration.zero)));
11054 test("7Dec1200:00:00A", SysTime(DateTime(2012, 12, 7, 0, 0, 0),
11055 new immutable SimpleTimeZone(Duration.zero)));
11056 test("Fri,7Dec1200:00:00A", SysTime(DateTime(2012, 12, 7, 0, 0, 0),
11057 new immutable SimpleTimeZone(Duration.zero)));
11059 auto tooShortMsg = collectExceptionMsg!DateTimeException(parseRFC822DateTime(""));
11060 foreach (str; ["Fri,7Dec1200:00:00", "7Dec1200:00:00"])
11062 foreach (i; 0 .. str.length)
11064 auto value = str[0 .. $ - i];
11065 scope(failure) writeln(value);
11066 assert(collectExceptionMsg!DateTimeException(parseRFC822DateTime(value)) == tooShortMsg);
11069 }();}
11073 private:
11076 Returns the given hnsecs as an ISO string of fractional seconds.
11078 string fracSecsToISOString(int hnsecs, int prec = -1) @safe pure nothrow
11080 import std.array : appender;
11081 auto w = appender!string();
11083 fracSecsToISOString(w, hnsecs, prec);
11084 catch (Exception e)
11085 assert(0, "fracSecsToISOString() threw.");
11086 return w.data;
11089 void fracSecsToISOString(W)(ref W writer, int hnsecs, int prec = -1)
11091 import std.conv : toChars;
11092 import std.range : padLeft;
11094 assert(hnsecs >= 0);
11096 if (prec == 0)
11097 return;
11099 if (hnsecs == 0)
11100 return;
11102 put(writer, '.');
11103 auto chars = hnsecs.toChars.padLeft('0', 7);
11105 if (prec == -1)
11107 while (chars.back == '0')
11108 chars.popBack();
11109 put(writer, chars);
11111 else
11112 put(writer, chars[0 .. prec]);
11115 @safe unittest
11117 assert(fracSecsToISOString(0) == "");
11118 assert(fracSecsToISOString(1) == ".0000001");
11119 assert(fracSecsToISOString(10) == ".000001");
11120 assert(fracSecsToISOString(100) == ".00001");
11121 assert(fracSecsToISOString(1000) == ".0001");
11122 assert(fracSecsToISOString(10_000) == ".001");
11123 assert(fracSecsToISOString(100_000) == ".01");
11124 assert(fracSecsToISOString(1_000_000) == ".1");
11125 assert(fracSecsToISOString(1_000_001) == ".1000001");
11126 assert(fracSecsToISOString(1_001_001) == ".1001001");
11127 assert(fracSecsToISOString(1_071_601) == ".1071601");
11128 assert(fracSecsToISOString(1_271_641) == ".1271641");
11129 assert(fracSecsToISOString(9_999_999) == ".9999999");
11130 assert(fracSecsToISOString(9_999_990) == ".999999");
11131 assert(fracSecsToISOString(9_999_900) == ".99999");
11132 assert(fracSecsToISOString(9_999_000) == ".9999");
11133 assert(fracSecsToISOString(9_990_000) == ".999");
11134 assert(fracSecsToISOString(9_900_000) == ".99");
11135 assert(fracSecsToISOString(9_000_000) == ".9");
11136 assert(fracSecsToISOString(999) == ".0000999");
11137 assert(fracSecsToISOString(9990) == ".000999");
11138 assert(fracSecsToISOString(99_900) == ".00999");
11139 assert(fracSecsToISOString(999_000) == ".0999");
11144 Returns a Duration corresponding to to the given ISO string of
11145 fractional seconds.
11147 static Duration fracSecsFromISOString(S)(scope const S isoString) @safe pure
11148 if (isSomeString!S)
11150 import std.algorithm.searching : all;
11151 import std.ascii : isDigit;
11152 import std.conv : to;
11153 import std.string : representation;
11155 if (isoString.empty)
11156 return Duration.zero;
11158 auto str = isoString.representation;
11160 enforce(str[0] == '.', new DateTimeException("Invalid ISO String"));
11161 str.popFront();
11163 enforce(!str.empty && all!isDigit(str), new DateTimeException("Invalid ISO String"));
11165 dchar[7] fullISOString = void;
11166 foreach (i, ref dchar c; fullISOString)
11168 if (i < str.length)
11169 c = str[i];
11170 else
11171 c = '0';
11174 return hnsecs(to!int(fullISOString[]));
11177 @safe unittest
11179 import core.time;
11180 static void testFSInvalid(string isoString)
11182 fracSecsFromISOString(isoString);
11185 assertThrown!DateTimeException(testFSInvalid("."));
11186 assertThrown!DateTimeException(testFSInvalid("0."));
11187 assertThrown!DateTimeException(testFSInvalid("0"));
11188 assertThrown!DateTimeException(testFSInvalid("0000000"));
11189 assertThrown!DateTimeException(testFSInvalid("T"));
11190 assertThrown!DateTimeException(testFSInvalid("T."));
11191 assertThrown!DateTimeException(testFSInvalid(".T"));
11192 assertThrown!DateTimeException(testFSInvalid(".00000Q0"));
11193 assertThrown!DateTimeException(testFSInvalid(".000000Q"));
11194 assertThrown!DateTimeException(testFSInvalid(".0000000Q"));
11195 assertThrown!DateTimeException(testFSInvalid(".0000000000Q"));
11197 assert(fracSecsFromISOString("") == Duration.zero);
11198 assert(fracSecsFromISOString(".0000001") == hnsecs(1));
11199 assert(fracSecsFromISOString(".000001") == hnsecs(10));
11200 assert(fracSecsFromISOString(".00001") == hnsecs(100));
11201 assert(fracSecsFromISOString(".0001") == hnsecs(1000));
11202 assert(fracSecsFromISOString(".001") == hnsecs(10_000));
11203 assert(fracSecsFromISOString(".01") == hnsecs(100_000));
11204 assert(fracSecsFromISOString(".1") == hnsecs(1_000_000));
11205 assert(fracSecsFromISOString(".1000001") == hnsecs(1_000_001));
11206 assert(fracSecsFromISOString(".1001001") == hnsecs(1_001_001));
11207 assert(fracSecsFromISOString(".1071601") == hnsecs(1_071_601));
11208 assert(fracSecsFromISOString(".1271641") == hnsecs(1_271_641));
11209 assert(fracSecsFromISOString(".9999999") == hnsecs(9_999_999));
11210 assert(fracSecsFromISOString(".9999990") == hnsecs(9_999_990));
11211 assert(fracSecsFromISOString(".999999") == hnsecs(9_999_990));
11212 assert(fracSecsFromISOString(".9999900") == hnsecs(9_999_900));
11213 assert(fracSecsFromISOString(".99999") == hnsecs(9_999_900));
11214 assert(fracSecsFromISOString(".9999000") == hnsecs(9_999_000));
11215 assert(fracSecsFromISOString(".9999") == hnsecs(9_999_000));
11216 assert(fracSecsFromISOString(".9990000") == hnsecs(9_990_000));
11217 assert(fracSecsFromISOString(".999") == hnsecs(9_990_000));
11218 assert(fracSecsFromISOString(".9900000") == hnsecs(9_900_000));
11219 assert(fracSecsFromISOString(".9900") == hnsecs(9_900_000));
11220 assert(fracSecsFromISOString(".99") == hnsecs(9_900_000));
11221 assert(fracSecsFromISOString(".9000000") == hnsecs(9_000_000));
11222 assert(fracSecsFromISOString(".9") == hnsecs(9_000_000));
11223 assert(fracSecsFromISOString(".0000999") == hnsecs(999));
11224 assert(fracSecsFromISOString(".0009990") == hnsecs(9990));
11225 assert(fracSecsFromISOString(".000999") == hnsecs(9990));
11226 assert(fracSecsFromISOString(".0099900") == hnsecs(99_900));
11227 assert(fracSecsFromISOString(".00999") == hnsecs(99_900));
11228 assert(fracSecsFromISOString(".0999000") == hnsecs(999_000));
11229 assert(fracSecsFromISOString(".0999") == hnsecs(999_000));
11230 assert(fracSecsFromISOString(".00000000") == Duration.zero);
11231 assert(fracSecsFromISOString(".00000001") == Duration.zero);
11232 assert(fracSecsFromISOString(".00000009") == Duration.zero);
11233 assert(fracSecsFromISOString(".1234567890") == hnsecs(1_234_567));
11234 assert(fracSecsFromISOString(".12345678901234567890") == hnsecs(1_234_567));
11239 This function is used to split out the units without getting the remaining
11240 hnsecs.
11242 Params:
11243 units = The units to split out.
11244 hnsecs = The current total hnsecs.
11246 Returns:
11247 The split out value.
11249 long getUnitsFromHNSecs(string units)(long hnsecs) @safe pure nothrow
11250 if (validTimeUnits(units) &&
11251 CmpTimeUnits!(units, "months") < 0)
11253 return convert!("hnsecs", units)(hnsecs);
11256 @safe unittest
11258 auto hnsecs = 2595000000007L;
11259 immutable days = getUnitsFromHNSecs!"days"(hnsecs);
11260 assert(days == 3);
11261 assert(hnsecs == 2595000000007L);
11266 This function is used to split out the units without getting the units but
11267 just the remaining hnsecs.
11269 Params:
11270 units = The units to split out.
11271 hnsecs = The current total hnsecs.
11273 Returns:
11274 The remaining hnsecs.
11276 long removeUnitsFromHNSecs(string units)(long hnsecs) @safe pure nothrow
11277 if (validTimeUnits(units) &&
11278 CmpTimeUnits!(units, "months") < 0)
11280 immutable value = convert!("hnsecs", units)(hnsecs);
11281 return hnsecs - convert!(units, "hnsecs")(value);
11284 @safe unittest
11286 auto hnsecs = 2595000000007L;
11287 auto returned = removeUnitsFromHNSecs!"days"(hnsecs);
11288 assert(returned == 3000000007);
11289 assert(hnsecs == 2595000000007L);
11294 Strips what RFC 5322, section 3.2.2 refers to as CFWS from the left-hand
11295 side of the given range (it strips comments delimited by $(D '(') and
11296 `'`') as well as folding whitespace).
11298 It is assumed that the given range contains the value of a header field and
11299 no terminating CRLF for the line (though the CRLF for folding whitespace is
11300 of course expected and stripped) and thus that the only case of CR or LF is
11301 in folding whitespace.
11303 If a comment does not terminate correctly (e.g. mismatched parens) or if the
11304 the FWS is malformed, then the range will be empty when stripCWFS is done.
11305 However, only minimal validation of the content is done (e.g. quoted pairs
11306 within a comment aren't validated beyond \$LPAREN or \$RPAREN, because
11307 they're inside a comment, and thus their value doesn't matter anyway). It's
11308 only when the content does not conform to the grammar rules for FWS and thus
11309 literally cannot be parsed that content is considered invalid, and an empty
11310 range is returned.
11312 Note that _stripCFWS is eager, not lazy. It does not create a new range.
11313 Rather, it pops off the CFWS from the range and returns it.
11315 R _stripCFWS(R)(R range)
11316 if (isRandomAccessRange!R && hasSlicing!R && hasLength!R &&
11317 (is(immutable ElementType!R == immutable char) || is(immutable ElementType!R == immutable ubyte)))
11319 immutable e = range.length;
11320 outer: for (size_t i = 0; i < e; )
11322 switch (range[i])
11324 case ' ': case '\t':
11326 ++i;
11327 break;
11329 case '\r':
11331 if (i + 2 < e && range[i + 1] == '\n' && (range[i + 2] == ' ' || range[i + 2] == '\t'))
11333 i += 3;
11334 break;
11336 break outer;
11338 case '\n':
11340 if (i + 1 < e && (range[i + 1] == ' ' || range[i + 1] == '\t'))
11342 i += 2;
11343 break;
11345 break outer;
11347 case '(':
11349 ++i;
11350 size_t commentLevel = 1;
11351 while (i < e)
11353 if (range[i] == '(')
11354 ++commentLevel;
11355 else if (range[i] == ')')
11357 ++i;
11358 if (--commentLevel == 0)
11359 continue outer;
11360 continue;
11362 else if (range[i] == '\\')
11364 if (++i == e)
11365 break outer;
11367 ++i;
11369 break outer;
11371 default: return range[i .. e];
11374 return range[e .. e];
11377 @system unittest
11379 import std.algorithm.comparison : equal;
11380 import std.algorithm.iteration : map;
11381 import std.meta : AliasSeq;
11382 import std.stdio : writeln;
11383 import std.string : representation;
11385 static foreach (cr; AliasSeq!(function(string a){return cast(ubyte[]) a;},
11386 function(string a){return map!(b => cast(char) b)(a.representation);}))
11388 scope(failure) writeln(typeof(cr).stringof);
11390 assert(_stripCFWS(cr("")).empty);
11391 assert(_stripCFWS(cr("\r")).empty);
11392 assert(_stripCFWS(cr("\r\n")).empty);
11393 assert(_stripCFWS(cr("\r\n ")).empty);
11394 assert(_stripCFWS(cr(" \t\r\n")).empty);
11395 assert(equal(_stripCFWS(cr(" \t\r\n hello")), cr("hello")));
11396 assert(_stripCFWS(cr(" \t\r\nhello")).empty);
11397 assert(_stripCFWS(cr(" \t\r\n\v")).empty);
11398 assert(equal(_stripCFWS(cr("\v \t\r\n\v")), cr("\v \t\r\n\v")));
11399 assert(_stripCFWS(cr("()")).empty);
11400 assert(_stripCFWS(cr("(hello world)")).empty);
11401 assert(_stripCFWS(cr("(hello world)(hello world)")).empty);
11402 assert(_stripCFWS(cr("(hello world\r\n foo\r where's\nwaldo)")).empty);
11403 assert(_stripCFWS(cr(" \t (hello \tworld\r\n foo\r where's\nwaldo)\t\t ")).empty);
11404 assert(_stripCFWS(cr(" ")).empty);
11405 assert(_stripCFWS(cr("\t\t\t")).empty);
11406 assert(_stripCFWS(cr("\t \r\n\r \n")).empty);
11407 assert(_stripCFWS(cr("(hello world) (can't find waldo) (he's lost)")).empty);
11408 assert(_stripCFWS(cr("(hello\\) world) (can't \\(find waldo) (he's \\(\\)lost)")).empty);
11409 assert(_stripCFWS(cr("(((((")).empty);
11410 assert(_stripCFWS(cr("(((()))")).empty);
11411 assert(_stripCFWS(cr("(((())))")).empty);
11412 assert(equal(_stripCFWS(cr("(((()))))")), cr(")")));
11413 assert(equal(_stripCFWS(cr(")))))")), cr(")))))")));
11414 assert(equal(_stripCFWS(cr("()))))")), cr("))))")));
11415 assert(equal(_stripCFWS(cr(" hello hello ")), cr("hello hello ")));
11416 assert(equal(_stripCFWS(cr("\thello (world)")), cr("hello (world)")));
11417 assert(equal(_stripCFWS(cr(" \r\n \\((\\)) foo")), cr("\\((\\)) foo")));
11418 assert(equal(_stripCFWS(cr(" \r\n (\\((\\))) foo")), cr("foo")));
11419 assert(equal(_stripCFWS(cr(" \r\n (\\(())) foo")), cr(") foo")));
11420 assert(_stripCFWS(cr(" \r\n (((\\))) foo")).empty);
11422 assert(_stripCFWS(cr("(hello)(hello)")).empty);
11423 assert(_stripCFWS(cr(" \r\n (hello)\r\n (hello)")).empty);
11424 assert(_stripCFWS(cr(" \r\n (hello) \r\n (hello) \r\n ")).empty);
11425 assert(_stripCFWS(cr("\t\t\t\t(hello)\t\t\t\t(hello)\t\t\t\t")).empty);
11426 assert(equal(_stripCFWS(cr(" \r\n (hello)\r\n (hello) \r\n hello")), cr("hello")));
11427 assert(equal(_stripCFWS(cr(" \r\n (hello) \r\n (hello) \r\n hello")), cr("hello")));
11428 assert(equal(_stripCFWS(cr("\t\r\n\t(hello)\r\n\t(hello)\t\r\n hello")), cr("hello")));
11429 assert(equal(_stripCFWS(cr("\t\r\n\t(hello)\t\r\n\t(hello)\t\r\n hello")), cr("hello")));
11430 assert(equal(_stripCFWS(cr(" \r\n (hello) \r\n \r\n (hello) \r\n hello")), cr("hello")));
11431 assert(equal(_stripCFWS(cr(" \r\n (hello) \r\n (hello) \r\n \r\n hello")), cr("hello")));
11432 assert(equal(_stripCFWS(cr(" \r\n \r\n (hello)\t\r\n (hello) \r\n hello")), cr("hello")));
11433 assert(equal(_stripCFWS(cr(" \r\n\t\r\n\t(hello)\t\r\n (hello) \r\n hello")), cr("hello")));
11435 assert(equal(_stripCFWS(cr(" (\r\n ( \r\n ) \r\n ) foo")), cr("foo")));
11436 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n ) foo")), cr("foo")));
11437 assert(equal(_stripCFWS(cr(" (\t\r\n ( \r\n ) \r\n ) foo")), cr("foo")));
11438 assert(equal(_stripCFWS(cr(" (\r\n\t( \r\n ) \r\n ) foo")), cr("foo")));
11439 assert(equal(_stripCFWS(cr(" ( \r\n (\t\r\n ) \r\n ) foo")), cr("foo")));
11440 assert(equal(_stripCFWS(cr(" ( \r\n (\r\n ) \r\n ) foo")), cr("foo")));
11441 assert(equal(_stripCFWS(cr(" ( \r\n (\r\n\t) \r\n ) foo")), cr("foo")));
11442 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n) \r\n ) foo")), cr("foo")));
11443 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n )\t\r\n ) foo")), cr("foo")));
11444 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n )\r\n ) foo")), cr("foo")));
11445 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n) foo")), cr("foo")));
11446 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n\t) foo")), cr("foo")));
11447 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n ) \r\n foo")), cr("foo")));
11448 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n )\t\r\n foo")), cr("foo")));
11449 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n )\r\n foo")), cr("foo")));
11451 assert(equal(_stripCFWS(cr(" ( \r\n \r\n ( \r\n \r\n ) \r\n ) foo")), cr("foo")));
11452 assert(equal(_stripCFWS(cr(" ( \r\n \r\n ( \r\n \r\n ) \r\n ) foo")), cr("foo")));
11453 assert(equal(_stripCFWS(cr(" (\t\r\n \r\n ( \r\n \r\n ) \r\n ) foo")), cr("foo")));
11454 assert(equal(_stripCFWS(cr(" (\r\n \r\n\t( \r\n \r\n ) \r\n ) foo")), cr("foo")));
11455 assert(equal(_stripCFWS(cr(" (\r\n \r\n( \r\n \r\n ) \r\n ) foo")), cr("foo")));
11456 assert(equal(_stripCFWS(cr(" (\r\n \r\n ( \r\n \r\n\t) \r\n ) foo")), cr("foo")));
11457 assert(equal(_stripCFWS(cr(" (\r\n \r\n ( \r\n \r\n )\t\r\n ) foo")), cr("foo")));
11458 assert(equal(_stripCFWS(cr(" (\r\n \r\n ( \r\n \r\n )\r\n ) foo")), cr("foo")));
11460 assert(equal(_stripCFWS(cr(" ( \r\n bar \r\n ( \r\n bar \r\n ) \r\n ) foo")), cr("foo")));
11461 assert(equal(_stripCFWS(cr(" ( \r\n () \r\n ( \r\n () \r\n ) \r\n ) foo")), cr("foo")));
11462 assert(equal(_stripCFWS(cr(" ( \r\n \\\\ \r\n ( \r\n \\\\ \r\n ) \r\n ) foo")), cr("foo")));
11464 assert(_stripCFWS(cr("(hello)(hello)")).empty);
11465 assert(_stripCFWS(cr(" \n (hello)\n (hello) \n ")).empty);
11466 assert(_stripCFWS(cr(" \n (hello) \n (hello) \n ")).empty);
11467 assert(equal(_stripCFWS(cr(" \n (hello)\n (hello) \n hello")), cr("hello")));
11468 assert(equal(_stripCFWS(cr(" \n (hello) \n (hello) \n hello")), cr("hello")));
11469 assert(equal(_stripCFWS(cr("\t\n\t(hello)\n\t(hello)\t\n hello")), cr("hello")));
11470 assert(equal(_stripCFWS(cr("\t\n\t(hello)\t\n\t(hello)\t\n hello")), cr("hello")));
11471 assert(equal(_stripCFWS(cr(" \n (hello) \n \n (hello) \n hello")), cr("hello")));
11472 assert(equal(_stripCFWS(cr(" \n (hello) \n (hello) \n \n hello")), cr("hello")));
11473 assert(equal(_stripCFWS(cr(" \n \n (hello)\t\n (hello) \n hello")), cr("hello")));
11474 assert(equal(_stripCFWS(cr(" \n\t\n\t(hello)\t\n (hello) \n hello")), cr("hello")));
11478 // This is so that we don't have to worry about std.conv.to throwing. It also
11479 // doesn't have to worry about quite as many cases as std.conv.to, since it
11480 // doesn't have to worry about a sign on the value or about whether it fits.
11481 T _convDigits(T, R)(R str)
11482 if (isIntegral!T && isSigned!T) // The constraints on R were already covered by parseRFC822DateTime.
11484 import std.ascii : isDigit;
11486 assert(!str.empty);
11487 T num = 0;
11488 foreach (i; 0 .. str.length)
11490 if (i != 0)
11491 num *= 10;
11492 if (!isDigit(str[i]))
11493 return -1;
11494 num += str[i] - '0';
11496 return num;
11499 @safe unittest
11501 import std.conv : to;
11502 import std.range : chain, iota;
11503 foreach (i; chain(iota(0, 101), [250, 999, 1000, 1001, 2345, 9999]))
11505 assert(_convDigits!int(to!string(i)) == i, i.to!string);
11507 foreach (str; ["-42", "+42", "1a", "1 ", " ", " 42 "])
11509 assert(_convDigits!int(str) == -1, str);
11514 // NOTE: all the non-simple array literals are wrapped in functions, because
11515 // otherwise importing causes re-evaluation of the static initializers using
11516 // CTFE with unittests enabled
11517 version (StdUnittest)
11519 private @safe:
11520 // Variables to help in testing.
11521 Duration currLocalDiffFromUTC;
11522 immutable (TimeZone)[] testTZs;
11524 // All of these helper arrays are sorted in ascending order.
11525 auto testYearsBC = [-1999, -1200, -600, -4, -1, 0];
11526 auto testYearsAD = [1, 4, 1000, 1999, 2000, 2012];
11528 // I'd use a Tuple, but I get forward reference errors if I try.
11529 struct MonthDay
11531 Month month;
11532 short day;
11534 this(int m, short d)
11536 month = cast(Month) m;
11537 day = d;
11541 MonthDay[] testMonthDays()
11543 static result = [MonthDay(1, 1),
11544 MonthDay(1, 2),
11545 MonthDay(3, 17),
11546 MonthDay(7, 4),
11547 MonthDay(10, 27),
11548 MonthDay(12, 30),
11549 MonthDay(12, 31)];
11550 return result;
11553 auto testDays = [1, 2, 9, 10, 16, 20, 25, 28, 29, 30, 31];
11555 TimeOfDay[] testTODs()
11557 static result = [TimeOfDay(0, 0, 0),
11558 TimeOfDay(0, 0, 1),
11559 TimeOfDay(0, 1, 0),
11560 TimeOfDay(1, 0, 0),
11561 TimeOfDay(13, 13, 13),
11562 TimeOfDay(23, 59, 59)];
11563 return result;
11566 auto testHours = [0, 1, 12, 22, 23];
11567 auto testMinSecs = [0, 1, 30, 58, 59];
11569 // Throwing exceptions is incredibly expensive, so we want to use a smaller
11570 // set of values for tests using assertThrown.
11571 TimeOfDay[] testTODsThrown()
11573 static result = [TimeOfDay(0, 0, 0),
11574 TimeOfDay(13, 13, 13),
11575 TimeOfDay(23, 59, 59)];
11576 return result;
11579 Date[] testDatesBC;
11580 Date[] testDatesAD;
11582 DateTime[] testDateTimesBC;
11583 DateTime[] testDateTimesAD;
11585 Duration[] testFracSecs;
11587 SysTime[] testSysTimesBC;
11588 SysTime[] testSysTimesAD;
11590 // I'd use a Tuple, but I get forward reference errors if I try.
11591 struct GregDay { int day; Date date; }
11592 GregDay[] testGregDaysBC()
11594 static result = [GregDay(-1_373_427, Date(-3760, 9, 7)), // Start of the Hebrew Calendar
11595 GregDay(-735_233, Date(-2012, 1, 1)),
11596 GregDay(-735_202, Date(-2012, 2, 1)),
11597 GregDay(-735_175, Date(-2012, 2, 28)),
11598 GregDay(-735_174, Date(-2012, 2, 29)),
11599 GregDay(-735_173, Date(-2012, 3, 1)),
11600 GregDay(-734_502, Date(-2010, 1, 1)),
11601 GregDay(-734_472, Date(-2010, 1, 31)),
11602 GregDay(-734_471, Date(-2010, 2, 1)),
11603 GregDay(-734_444, Date(-2010, 2, 28)),
11604 GregDay(-734_443, Date(-2010, 3, 1)),
11605 GregDay(-734_413, Date(-2010, 3, 31)),
11606 GregDay(-734_412, Date(-2010, 4, 1)),
11607 GregDay(-734_383, Date(-2010, 4, 30)),
11608 GregDay(-734_382, Date(-2010, 5, 1)),
11609 GregDay(-734_352, Date(-2010, 5, 31)),
11610 GregDay(-734_351, Date(-2010, 6, 1)),
11611 GregDay(-734_322, Date(-2010, 6, 30)),
11612 GregDay(-734_321, Date(-2010, 7, 1)),
11613 GregDay(-734_291, Date(-2010, 7, 31)),
11614 GregDay(-734_290, Date(-2010, 8, 1)),
11615 GregDay(-734_260, Date(-2010, 8, 31)),
11616 GregDay(-734_259, Date(-2010, 9, 1)),
11617 GregDay(-734_230, Date(-2010, 9, 30)),
11618 GregDay(-734_229, Date(-2010, 10, 1)),
11619 GregDay(-734_199, Date(-2010, 10, 31)),
11620 GregDay(-734_198, Date(-2010, 11, 1)),
11621 GregDay(-734_169, Date(-2010, 11, 30)),
11622 GregDay(-734_168, Date(-2010, 12, 1)),
11623 GregDay(-734_139, Date(-2010, 12, 30)),
11624 GregDay(-734_138, Date(-2010, 12, 31)),
11625 GregDay(-731_215, Date(-2001, 1, 1)),
11626 GregDay(-730_850, Date(-2000, 1, 1)),
11627 GregDay(-730_849, Date(-2000, 1, 2)),
11628 GregDay(-730_486, Date(-2000, 12, 30)),
11629 GregDay(-730_485, Date(-2000, 12, 31)),
11630 GregDay(-730_484, Date(-1999, 1, 1)),
11631 GregDay(-694_690, Date(-1901, 1, 1)),
11632 GregDay(-694_325, Date(-1900, 1, 1)),
11633 GregDay(-585_118, Date(-1601, 1, 1)),
11634 GregDay(-584_753, Date(-1600, 1, 1)),
11635 GregDay(-584_388, Date(-1600, 12, 31)),
11636 GregDay(-584_387, Date(-1599, 1, 1)),
11637 GregDay(-365_972, Date(-1001, 1, 1)),
11638 GregDay(-365_607, Date(-1000, 1, 1)),
11639 GregDay(-183_351, Date(-501, 1, 1)),
11640 GregDay(-182_986, Date(-500, 1, 1)),
11641 GregDay(-182_621, Date(-499, 1, 1)),
11642 GregDay(-146_827, Date(-401, 1, 1)),
11643 GregDay(-146_462, Date(-400, 1, 1)),
11644 GregDay(-146_097, Date(-400, 12, 31)),
11645 GregDay(-110_302, Date(-301, 1, 1)),
11646 GregDay(-109_937, Date(-300, 1, 1)),
11647 GregDay(-73_778, Date(-201, 1, 1)),
11648 GregDay(-73_413, Date(-200, 1, 1)),
11649 GregDay(-38_715, Date(-105, 1, 1)),
11650 GregDay(-37_254, Date(-101, 1, 1)),
11651 GregDay(-36_889, Date(-100, 1, 1)),
11652 GregDay(-36_524, Date(-99, 1, 1)),
11653 GregDay(-36_160, Date(-99, 12, 31)),
11654 GregDay(-35_794, Date(-97, 1, 1)),
11655 GregDay(-18_627, Date(-50, 1, 1)),
11656 GregDay(-18_262, Date(-49, 1, 1)),
11657 GregDay(-3652, Date(-9, 1, 1)),
11658 GregDay(-2191, Date(-5, 1, 1)),
11659 GregDay(-1827, Date(-5, 12, 31)),
11660 GregDay(-1826, Date(-4, 1, 1)),
11661 GregDay(-1825, Date(-4, 1, 2)),
11662 GregDay(-1462, Date(-4, 12, 30)),
11663 GregDay(-1461, Date(-4, 12, 31)),
11664 GregDay(-1460, Date(-3, 1, 1)),
11665 GregDay(-1096, Date(-3, 12, 31)),
11666 GregDay(-1095, Date(-2, 1, 1)),
11667 GregDay(-731, Date(-2, 12, 31)),
11668 GregDay(-730, Date(-1, 1, 1)),
11669 GregDay(-367, Date(-1, 12, 30)),
11670 GregDay(-366, Date(-1, 12, 31)),
11671 GregDay(-365, Date(0, 1, 1)),
11672 GregDay(-31, Date(0, 11, 30)),
11673 GregDay(-30, Date(0, 12, 1)),
11674 GregDay(-1, Date(0, 12, 30)),
11675 GregDay(0, Date(0, 12, 31))];
11676 return result;
11679 GregDay[] testGregDaysAD()
11681 static result = [GregDay(1, Date(1, 1, 1)),
11682 GregDay(2, Date(1, 1, 2)),
11683 GregDay(32, Date(1, 2, 1)),
11684 GregDay(365, Date(1, 12, 31)),
11685 GregDay(366, Date(2, 1, 1)),
11686 GregDay(731, Date(3, 1, 1)),
11687 GregDay(1096, Date(4, 1, 1)),
11688 GregDay(1097, Date(4, 1, 2)),
11689 GregDay(1460, Date(4, 12, 30)),
11690 GregDay(1461, Date(4, 12, 31)),
11691 GregDay(1462, Date(5, 1, 1)),
11692 GregDay(17_898, Date(50, 1, 1)),
11693 GregDay(35_065, Date(97, 1, 1)),
11694 GregDay(36_160, Date(100, 1, 1)),
11695 GregDay(36_525, Date(101, 1, 1)),
11696 GregDay(37_986, Date(105, 1, 1)),
11697 GregDay(72_684, Date(200, 1, 1)),
11698 GregDay(73_049, Date(201, 1, 1)),
11699 GregDay(109_208, Date(300, 1, 1)),
11700 GregDay(109_573, Date(301, 1, 1)),
11701 GregDay(145_732, Date(400, 1, 1)),
11702 GregDay(146_098, Date(401, 1, 1)),
11703 GregDay(182_257, Date(500, 1, 1)),
11704 GregDay(182_622, Date(501, 1, 1)),
11705 GregDay(364_878, Date(1000, 1, 1)),
11706 GregDay(365_243, Date(1001, 1, 1)),
11707 GregDay(584_023, Date(1600, 1, 1)),
11708 GregDay(584_389, Date(1601, 1, 1)),
11709 GregDay(693_596, Date(1900, 1, 1)),
11710 GregDay(693_961, Date(1901, 1, 1)),
11711 GregDay(729_755, Date(1999, 1, 1)),
11712 GregDay(730_120, Date(2000, 1, 1)),
11713 GregDay(730_121, Date(2000, 1, 2)),
11714 GregDay(730_484, Date(2000, 12, 30)),
11715 GregDay(730_485, Date(2000, 12, 31)),
11716 GregDay(730_486, Date(2001, 1, 1)),
11717 GregDay(733_773, Date(2010, 1, 1)),
11718 GregDay(733_774, Date(2010, 1, 2)),
11719 GregDay(733_803, Date(2010, 1, 31)),
11720 GregDay(733_804, Date(2010, 2, 1)),
11721 GregDay(733_831, Date(2010, 2, 28)),
11722 GregDay(733_832, Date(2010, 3, 1)),
11723 GregDay(733_862, Date(2010, 3, 31)),
11724 GregDay(733_863, Date(2010, 4, 1)),
11725 GregDay(733_892, Date(2010, 4, 30)),
11726 GregDay(733_893, Date(2010, 5, 1)),
11727 GregDay(733_923, Date(2010, 5, 31)),
11728 GregDay(733_924, Date(2010, 6, 1)),
11729 GregDay(733_953, Date(2010, 6, 30)),
11730 GregDay(733_954, Date(2010, 7, 1)),
11731 GregDay(733_984, Date(2010, 7, 31)),
11732 GregDay(733_985, Date(2010, 8, 1)),
11733 GregDay(734_015, Date(2010, 8, 31)),
11734 GregDay(734_016, Date(2010, 9, 1)),
11735 GregDay(734_045, Date(2010, 9, 30)),
11736 GregDay(734_046, Date(2010, 10, 1)),
11737 GregDay(734_076, Date(2010, 10, 31)),
11738 GregDay(734_077, Date(2010, 11, 1)),
11739 GregDay(734_106, Date(2010, 11, 30)),
11740 GregDay(734_107, Date(2010, 12, 1)),
11741 GregDay(734_136, Date(2010, 12, 30)),
11742 GregDay(734_137, Date(2010, 12, 31)),
11743 GregDay(734_503, Date(2012, 1, 1)),
11744 GregDay(734_534, Date(2012, 2, 1)),
11745 GregDay(734_561, Date(2012, 2, 28)),
11746 GregDay(734_562, Date(2012, 2, 29)),
11747 GregDay(734_563, Date(2012, 3, 1)),
11748 GregDay(734_858, Date(2012, 12, 21))];
11749 return result;
11752 // I'd use a Tuple, but I get forward reference errors if I try.
11753 struct DayOfYear { int day; MonthDay md; }
11754 DayOfYear[] testDaysOfYear()
11756 static result = [DayOfYear(1, MonthDay(1, 1)),
11757 DayOfYear(2, MonthDay(1, 2)),
11758 DayOfYear(3, MonthDay(1, 3)),
11759 DayOfYear(31, MonthDay(1, 31)),
11760 DayOfYear(32, MonthDay(2, 1)),
11761 DayOfYear(59, MonthDay(2, 28)),
11762 DayOfYear(60, MonthDay(3, 1)),
11763 DayOfYear(90, MonthDay(3, 31)),
11764 DayOfYear(91, MonthDay(4, 1)),
11765 DayOfYear(120, MonthDay(4, 30)),
11766 DayOfYear(121, MonthDay(5, 1)),
11767 DayOfYear(151, MonthDay(5, 31)),
11768 DayOfYear(152, MonthDay(6, 1)),
11769 DayOfYear(181, MonthDay(6, 30)),
11770 DayOfYear(182, MonthDay(7, 1)),
11771 DayOfYear(212, MonthDay(7, 31)),
11772 DayOfYear(213, MonthDay(8, 1)),
11773 DayOfYear(243, MonthDay(8, 31)),
11774 DayOfYear(244, MonthDay(9, 1)),
11775 DayOfYear(273, MonthDay(9, 30)),
11776 DayOfYear(274, MonthDay(10, 1)),
11777 DayOfYear(304, MonthDay(10, 31)),
11778 DayOfYear(305, MonthDay(11, 1)),
11779 DayOfYear(334, MonthDay(11, 30)),
11780 DayOfYear(335, MonthDay(12, 1)),
11781 DayOfYear(363, MonthDay(12, 29)),
11782 DayOfYear(364, MonthDay(12, 30)),
11783 DayOfYear(365, MonthDay(12, 31))];
11784 return result;
11787 DayOfYear[] testDaysOfLeapYear()
11789 static result = [DayOfYear(1, MonthDay(1, 1)),
11790 DayOfYear(2, MonthDay(1, 2)),
11791 DayOfYear(3, MonthDay(1, 3)),
11792 DayOfYear(31, MonthDay(1, 31)),
11793 DayOfYear(32, MonthDay(2, 1)),
11794 DayOfYear(59, MonthDay(2, 28)),
11795 DayOfYear(60, MonthDay(2, 29)),
11796 DayOfYear(61, MonthDay(3, 1)),
11797 DayOfYear(91, MonthDay(3, 31)),
11798 DayOfYear(92, MonthDay(4, 1)),
11799 DayOfYear(121, MonthDay(4, 30)),
11800 DayOfYear(122, MonthDay(5, 1)),
11801 DayOfYear(152, MonthDay(5, 31)),
11802 DayOfYear(153, MonthDay(6, 1)),
11803 DayOfYear(182, MonthDay(6, 30)),
11804 DayOfYear(183, MonthDay(7, 1)),
11805 DayOfYear(213, MonthDay(7, 31)),
11806 DayOfYear(214, MonthDay(8, 1)),
11807 DayOfYear(244, MonthDay(8, 31)),
11808 DayOfYear(245, MonthDay(9, 1)),
11809 DayOfYear(274, MonthDay(9, 30)),
11810 DayOfYear(275, MonthDay(10, 1)),
11811 DayOfYear(305, MonthDay(10, 31)),
11812 DayOfYear(306, MonthDay(11, 1)),
11813 DayOfYear(335, MonthDay(11, 30)),
11814 DayOfYear(336, MonthDay(12, 1)),
11815 DayOfYear(364, MonthDay(12, 29)),
11816 DayOfYear(365, MonthDay(12, 30)),
11817 DayOfYear(366, MonthDay(12, 31))];
11818 return result;
11821 void initializeTests()
11823 import std.algorithm.sorting : sort;
11824 import std.typecons : Rebindable;
11825 immutable lt = LocalTime().utcToTZ(0);
11826 currLocalDiffFromUTC = dur!"hnsecs"(lt);
11828 version (Posix)
11830 import std.datetime.timezone : PosixTimeZone;
11831 immutable otherTZ = lt < 0 ? PosixTimeZone.getTimeZone("Australia/Sydney")
11832 : PosixTimeZone.getTimeZone("America/Denver");
11834 else version (Windows)
11836 import std.datetime.timezone : WindowsTimeZone;
11837 immutable otherTZ = lt < 0 ? WindowsTimeZone.getTimeZone("AUS Eastern Standard Time")
11838 : WindowsTimeZone.getTimeZone("Mountain Standard Time");
11841 immutable ot = otherTZ.utcToTZ(0);
11843 auto diffs = [0L, lt, ot];
11844 auto diffAA = [0L : Rebindable!(immutable TimeZone)(UTC())];
11845 diffAA[lt] = Rebindable!(immutable TimeZone)(LocalTime());
11846 diffAA[ot] = Rebindable!(immutable TimeZone)(otherTZ);
11848 sort(diffs);
11849 testTZs = [diffAA[diffs[0]], diffAA[diffs[1]], diffAA[diffs[2]]];
11851 testFracSecs = [Duration.zero, hnsecs(1), hnsecs(5007), hnsecs(9_999_999)];
11853 foreach (year; testYearsBC)
11855 foreach (md; testMonthDays)
11856 testDatesBC ~= Date(year, md.month, md.day);
11859 foreach (year; testYearsAD)
11861 foreach (md; testMonthDays)
11862 testDatesAD ~= Date(year, md.month, md.day);
11865 foreach (dt; testDatesBC)
11867 foreach (tod; testTODs)
11868 testDateTimesBC ~= DateTime(dt, tod);
11871 foreach (dt; testDatesAD)
11873 foreach (tod; testTODs)
11874 testDateTimesAD ~= DateTime(dt, tod);
11877 foreach (dt; testDateTimesBC)
11879 foreach (tz; testTZs)
11881 foreach (fs; testFracSecs)
11882 testSysTimesBC ~= SysTime(dt, fs, tz);
11886 foreach (dt; testDateTimesAD)
11888 foreach (tz; testTZs)
11890 foreach (fs; testFracSecs)
11891 testSysTimesAD ~= SysTime(dt, fs, tz);