Fix build on sparc64-linux-gnu.
[official-gcc.git] / libphobos / src / std / datetime / date.d
blob38a87661b4fd1b2a402df64073e8abd930917670
1 // Written in the D programming language
3 /++
4 License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
5 Authors: Jonathan M Davis
6 Source: $(PHOBOSSRC std/datetime/_date.d)
7 +/
8 module std.datetime.date;
10 import core.time;
11 import std.traits : isSomeString, Unqual;
12 import std.typecons : Flag;
14 version (unittest) import std.exception : assertThrown;
17 @safe unittest
19 initializeTests();
23 /++
24 Exception type used by std.datetime. It's an alias to
25 $(REF TimeException,core,time). Either can be caught without concern about
26 which module it came from.
28 alias DateTimeException = TimeException;
31 /++
32 Represents the 12 months of the Gregorian year (January is 1).
34 enum Month : ubyte
36 jan = 1, ///
37 feb, ///
38 mar, ///
39 apr, ///
40 may, ///
41 jun, ///
42 jul, ///
43 aug, ///
44 sep, ///
45 oct, ///
46 nov, ///
47 dec ///
51 /++
52 Represents the 7 days of the Gregorian week (Sunday is 0).
54 enum DayOfWeek : ubyte
56 sun = 0, ///
57 mon, ///
58 tue, ///
59 wed, ///
60 thu, ///
61 fri, ///
62 sat ///
66 /++
67 In some date calculations, adding months or years can cause the date to fall
68 on a day of the month which is not valid (e.g. February 29th 2001 or
69 June 31st 2000). If overflow is allowed (as is the default), then the month
70 will be incremented accordingly (so, February 29th 2001 would become
71 March 1st 2001, and June 31st 2000 would become July 1st 2000). If overflow
72 is not allowed, then the day will be adjusted to the last valid day in that
73 month (so, February 29th 2001 would become February 28th 2001 and
74 June 31st 2000 would become June 30th 2000).
76 AllowDayOverflow only applies to calculations involving months or years.
78 If set to $(D AllowDayOverflow.no), then day overflow is not allowed.
80 Otherwise, if set to $(D AllowDayOverflow.yes), then day overflow is
81 allowed.
83 alias AllowDayOverflow = Flag!"allowDayOverflow";
86 /++
87 Array of the strings representing time units, starting with the smallest
88 unit and going to the largest. It does not include $(D "nsecs").
90 Includes $(D "hnsecs") (hecto-nanoseconds (100 ns)),
91 $(D "usecs") (microseconds), $(D "msecs") (milliseconds), $(D "seconds"),
92 $(D "minutes"), $(D "hours"), $(D "days"), $(D "weeks"), $(D "months"), and
93 $(D "years")
95 immutable string[] timeStrings = ["hnsecs", "usecs", "msecs", "seconds", "minutes",
96 "hours", "days", "weeks", "months", "years"];
99 /++
100 Combines the $(REF Date,std,datetime,date) and
101 $(REF TimeOfDay,std,datetime,date) structs to give an object which holds
102 both the date and the time. It is optimized for calendar-based operations and
103 has no concept of time zone. For an object which is optimized for time
104 operations based on the system time, use $(REF SysTime,std,datetime,systime).
105 $(REF SysTime,std,datetime,systime) has a concept of time zone and has much
106 higher precision (hnsecs). $(D DateTime) is intended primarily for
107 calendar-based uses rather than precise time operations.
109 struct DateTime
111 public:
114 Params:
115 date = The date portion of $(LREF DateTime).
116 tod = The time portion of $(LREF DateTime).
118 this(in Date date, in TimeOfDay tod = TimeOfDay.init) @safe pure nothrow @nogc
120 _date = date;
121 _tod = tod;
124 @safe unittest
127 auto dt = DateTime.init;
128 assert(dt._date == Date.init);
129 assert(dt._tod == TimeOfDay.init);
133 auto dt = DateTime(Date(1999, 7 ,6));
134 assert(dt._date == Date(1999, 7, 6));
135 assert(dt._tod == TimeOfDay.init);
139 auto dt = DateTime(Date(1999, 7 ,6), TimeOfDay(12, 30, 33));
140 assert(dt._date == Date(1999, 7, 6));
141 assert(dt._tod == TimeOfDay(12, 30, 33));
147 Params:
148 year = The year portion of the date.
149 month = The month portion of the date (January is 1).
150 day = The day portion of the date.
151 hour = The hour portion of the time;
152 minute = The minute portion of the time;
153 second = The second portion of the time;
155 this(int year, int month, int day, int hour = 0, int minute = 0, int second = 0) @safe pure
157 _date = Date(year, month, day);
158 _tod = TimeOfDay(hour, minute, second);
161 @safe unittest
164 auto dt = DateTime(1999, 7 ,6);
165 assert(dt._date == Date(1999, 7, 6));
166 assert(dt._tod == TimeOfDay.init);
170 auto dt = DateTime(1999, 7 ,6, 12, 30, 33);
171 assert(dt._date == Date(1999, 7, 6));
172 assert(dt._tod == TimeOfDay(12, 30, 33));
178 Compares this $(LREF DateTime) with the given $(D DateTime.).
180 Returns:
181 $(BOOKTABLE,
182 $(TR $(TD this < rhs) $(TD < 0))
183 $(TR $(TD this == rhs) $(TD 0))
184 $(TR $(TD this > rhs) $(TD > 0))
187 int opCmp(in DateTime rhs) const @safe pure nothrow @nogc
189 immutable dateResult = _date.opCmp(rhs._date);
191 if (dateResult != 0)
192 return dateResult;
194 return _tod.opCmp(rhs._tod);
197 @safe unittest
199 // Test A.D.
200 assert(DateTime(Date.init, TimeOfDay.init).opCmp(DateTime.init) == 0);
202 assert(DateTime(Date(1999, 1, 1)).opCmp(DateTime(Date(1999, 1, 1))) == 0);
203 assert(DateTime(Date(1, 7, 1)).opCmp(DateTime(Date(1, 7, 1))) == 0);
204 assert(DateTime(Date(1, 1, 6)).opCmp(DateTime(Date(1, 1, 6))) == 0);
206 assert(DateTime(Date(1999, 7, 1)).opCmp(DateTime(Date(1999, 7, 1))) == 0);
207 assert(DateTime(Date(1999, 7, 6)).opCmp(DateTime(Date(1999, 7, 6))) == 0);
209 assert(DateTime(Date(1, 7, 6)).opCmp(DateTime(Date(1, 7, 6))) == 0);
211 assert(DateTime(Date(1999, 7, 6)).opCmp(DateTime(Date(2000, 7, 6))) < 0);
212 assert(DateTime(Date(2000, 7, 6)).opCmp(DateTime(Date(1999, 7, 6))) > 0);
213 assert(DateTime(Date(1999, 7, 6)).opCmp(DateTime(Date(1999, 8, 6))) < 0);
214 assert(DateTime(Date(1999, 8, 6)).opCmp(DateTime(Date(1999, 7, 6))) > 0);
215 assert(DateTime(Date(1999, 7, 6)).opCmp(DateTime(Date(1999, 7, 7))) < 0);
216 assert(DateTime(Date(1999, 7, 7)).opCmp(DateTime(Date(1999, 7, 6))) > 0);
218 assert(DateTime(Date(1999, 8, 7)).opCmp(DateTime(Date(2000, 7, 6))) < 0);
219 assert(DateTime(Date(2000, 8, 6)).opCmp(DateTime(Date(1999, 7, 7))) > 0);
220 assert(DateTime(Date(1999, 7, 7)).opCmp(DateTime(Date(2000, 7, 6))) < 0);
221 assert(DateTime(Date(2000, 7, 6)).opCmp(DateTime(Date(1999, 7, 7))) > 0);
222 assert(DateTime(Date(1999, 7, 7)).opCmp(DateTime(Date(1999, 8, 6))) < 0);
223 assert(DateTime(Date(1999, 8, 6)).opCmp(DateTime(Date(1999, 7, 7))) > 0);
226 assert(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0)).opCmp(
227 DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0))) == 0);
228 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 0)).opCmp(
229 DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 0))) == 0);
230 assert(DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 0)).opCmp(
231 DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 0))) == 0);
232 assert(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33)).opCmp(
233 DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33))) == 0);
235 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)).opCmp(
236 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0))) == 0);
237 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp(
238 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) == 0);
240 assert(DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)).opCmp(
241 DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33))) == 0);
242 assert(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33)).opCmp(
243 DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33))) == 0);
245 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp(
246 DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33))) < 0);
247 assert(DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)).opCmp(
248 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) > 0);
249 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp(
250 DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33))) < 0);
251 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)).opCmp(
252 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) > 0);
253 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp(
254 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34))) < 0);
255 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)).opCmp(
256 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) > 0);
258 assert(DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)).opCmp(
259 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34))) > 0);
260 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)).opCmp(
261 DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33))) < 0);
262 assert(DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)).opCmp(
263 DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33))) > 0);
264 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)).opCmp(
265 DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33))) < 0);
267 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)).opCmp(
268 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34))) > 0);
269 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)).opCmp(
270 DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33))) < 0);
272 assert(DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)).opCmp(
273 DateTime(Date(2000, 7, 6), TimeOfDay(12, 30, 33))) < 0);
274 assert(DateTime(Date(2000, 7, 6), TimeOfDay(12, 30, 33)).opCmp(
275 DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33))) > 0);
276 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)).opCmp(
277 DateTime(Date(2000, 7, 6), TimeOfDay(12, 30, 33))) < 0);
278 assert(DateTime(Date(2000, 7, 6), TimeOfDay(12, 30, 33)).opCmp(
279 DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33))) > 0);
280 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)).opCmp(
281 DateTime(Date(2000, 7, 6), TimeOfDay(12, 30, 33))) < 0);
282 assert(DateTime(Date(2000, 7, 6), TimeOfDay(12, 30, 33)).opCmp(
283 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34))) > 0);
285 assert(DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)).opCmp(
286 DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33))) < 0);
287 assert(DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33)).opCmp(
288 DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33))) > 0);
289 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)).opCmp(
290 DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33))) < 0);
291 assert(DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33)).opCmp(
292 DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33))) > 0);
293 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)).opCmp(
294 DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33))) < 0);
295 assert(DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33)).opCmp(
296 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34))) > 0);
298 assert(DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)).opCmp(
299 DateTime(Date(1999, 7, 7), TimeOfDay(12, 30, 33))) < 0);
300 assert(DateTime(Date(1999, 7, 7), TimeOfDay(12, 30, 33)).opCmp(
301 DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33))) > 0);
302 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)).opCmp(
303 DateTime(Date(1999, 7, 7), TimeOfDay(12, 31, 33))) < 0);
304 assert(DateTime(Date(1999, 7, 7), TimeOfDay(12, 30, 33)).opCmp(
305 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) > 0);
306 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)).opCmp(
307 DateTime(Date(1999, 7, 7), TimeOfDay(12, 30, 33))) < 0);
308 assert(DateTime(Date(1999, 7, 7), TimeOfDay(12, 30, 33)).opCmp(
309 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34))) > 0);
311 // Test B.C.
312 assert(DateTime(Date(-1, 1, 1), TimeOfDay(12, 30, 33)).opCmp(
313 DateTime(Date(-1, 1, 1), TimeOfDay(12, 30, 33))) == 0);
314 assert(DateTime(Date(-1, 7, 1), TimeOfDay(12, 30, 33)).opCmp(
315 DateTime(Date(-1, 7, 1), TimeOfDay(12, 30, 33))) == 0);
316 assert(DateTime(Date(-1, 1, 6), TimeOfDay(12, 30, 33)).opCmp(
317 DateTime(Date(-1, 1, 6), TimeOfDay(12, 30, 33))) == 0);
319 assert(DateTime(Date(-1999, 7, 1), TimeOfDay(12, 30, 33)).opCmp(
320 DateTime(Date(-1999, 7, 1), TimeOfDay(12, 30, 33))) == 0);
321 assert(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp(
322 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))) == 0);
324 assert(DateTime(Date(-1, 7, 6), TimeOfDay(12, 30, 33)).opCmp(
325 DateTime(Date(-1, 7, 6), TimeOfDay(12, 30, 33))) == 0);
327 assert(DateTime(Date(-2000, 7, 6), TimeOfDay(12, 30, 33)).opCmp(
328 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))) < 0);
329 assert(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp(
330 DateTime(Date(-2000, 7, 6), TimeOfDay(12, 30, 33))) > 0);
331 assert(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp(
332 DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33))) < 0);
333 assert(DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33)).opCmp(
334 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))) > 0);
335 assert(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp(
336 DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33))) < 0);
337 assert(DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33)).opCmp(
338 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))) > 0);
340 assert(DateTime(Date(-2000, 8, 6), TimeOfDay(12, 30, 33)).opCmp(
341 DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33))) < 0);
342 assert(DateTime(Date(-1999, 8, 7), TimeOfDay(12, 30, 33)).opCmp(
343 DateTime(Date(-2000, 7, 6), TimeOfDay(12, 30, 33))) > 0);
344 assert(DateTime(Date(-2000, 7, 6), TimeOfDay(12, 30, 33)).opCmp(
345 DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33))) < 0);
346 assert(DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33)).opCmp(
347 DateTime(Date(-2000, 7, 6), TimeOfDay(12, 30, 33))) > 0);
348 assert(DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33)).opCmp(
349 DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33))) < 0);
350 assert(DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33)).opCmp(
351 DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33))) > 0);
353 // Test Both
354 assert(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp(
355 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) < 0);
356 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp(
357 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))) > 0);
359 assert(DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33)).opCmp(
360 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) < 0);
361 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp(
362 DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33))) > 0);
364 assert(DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33)).opCmp(
365 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) < 0);
366 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp(
367 DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33))) > 0);
369 assert(DateTime(Date(-1999, 8, 7), TimeOfDay(12, 30, 33)).opCmp(
370 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) < 0);
371 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp(
372 DateTime(Date(-1999, 8, 7), TimeOfDay(12, 30, 33))) > 0);
374 assert(DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33)).opCmp(
375 DateTime(Date(1999, 6, 6), TimeOfDay(12, 30, 33))) < 0);
376 assert(DateTime(Date(1999, 6, 8), TimeOfDay(12, 30, 33)).opCmp(
377 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))) > 0);
379 auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 33, 30));
380 const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 33, 30));
381 immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 33, 30));
382 assert(dt.opCmp(dt) == 0);
383 assert(dt.opCmp(cdt) == 0);
384 assert(dt.opCmp(idt) == 0);
385 assert(cdt.opCmp(dt) == 0);
386 assert(cdt.opCmp(cdt) == 0);
387 assert(cdt.opCmp(idt) == 0);
388 assert(idt.opCmp(dt) == 0);
389 assert(idt.opCmp(cdt) == 0);
390 assert(idt.opCmp(idt) == 0);
395 The date portion of $(LREF DateTime).
397 @property Date date() const @safe pure nothrow @nogc
399 return _date;
402 @safe unittest
405 auto dt = DateTime.init;
406 assert(dt.date == Date.init);
410 auto dt = DateTime(Date(1999, 7, 6));
411 assert(dt.date == Date(1999, 7, 6));
414 const cdt = DateTime(1999, 7, 6);
415 immutable idt = DateTime(1999, 7, 6);
416 assert(cdt.date == Date(1999, 7, 6));
417 assert(idt.date == Date(1999, 7, 6));
422 The date portion of $(LREF DateTime).
424 Params:
425 date = The Date to set this $(LREF DateTime)'s date portion to.
427 @property void date(in Date date) @safe pure nothrow @nogc
429 _date = date;
432 @safe unittest
434 auto dt = DateTime.init;
435 dt.date = Date(1999, 7, 6);
436 assert(dt._date == Date(1999, 7, 6));
437 assert(dt._tod == TimeOfDay.init);
439 const cdt = DateTime(1999, 7, 6);
440 immutable idt = DateTime(1999, 7, 6);
441 static assert(!__traits(compiles, cdt.date = Date(2010, 1, 1)));
442 static assert(!__traits(compiles, idt.date = Date(2010, 1, 1)));
447 The time portion of $(LREF DateTime).
449 @property TimeOfDay timeOfDay() const @safe pure nothrow @nogc
451 return _tod;
454 @safe unittest
457 auto dt = DateTime.init;
458 assert(dt.timeOfDay == TimeOfDay.init);
462 auto dt = DateTime(Date.init, TimeOfDay(12, 30, 33));
463 assert(dt.timeOfDay == TimeOfDay(12, 30, 33));
466 const cdt = DateTime(1999, 7, 6, 12, 30, 33);
467 immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
468 assert(cdt.timeOfDay == TimeOfDay(12, 30, 33));
469 assert(idt.timeOfDay == TimeOfDay(12, 30, 33));
474 The time portion of $(LREF DateTime).
476 Params:
477 tod = The $(REF TimeOfDay,std,datetime,date) to set this
478 $(LREF DateTime)'s time portion to.
480 @property void timeOfDay(in TimeOfDay tod) @safe pure nothrow @nogc
482 _tod = tod;
485 @safe unittest
487 auto dt = DateTime.init;
488 dt.timeOfDay = TimeOfDay(12, 30, 33);
489 assert(dt._date == Date.init);
490 assert(dt._tod == TimeOfDay(12, 30, 33));
492 const cdt = DateTime(1999, 7, 6, 12, 30, 33);
493 immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
494 static assert(!__traits(compiles, cdt.timeOfDay = TimeOfDay(12, 30, 33)));
495 static assert(!__traits(compiles, idt.timeOfDay = TimeOfDay(12, 30, 33)));
500 Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive
501 are B.C.
503 @property short year() const @safe pure nothrow @nogc
505 return _date.year;
508 @safe unittest
510 assert(Date.init.year == 1);
511 assert(Date(1999, 7, 6).year == 1999);
512 assert(Date(-1999, 7, 6).year == -1999);
514 const cdt = DateTime(1999, 7, 6, 12, 30, 33);
515 immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
516 assert(idt.year == 1999);
517 assert(idt.year == 1999);
522 Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive
523 are B.C.
525 Params:
526 year = The year to set this $(LREF DateTime)'s year to.
528 Throws:
529 $(REF DateTimeException,std,datetime,date) if the new year is not
530 a leap year and if the resulting date would be on February 29th.
532 @property void year(int year) @safe pure
534 _date.year = year;
538 @safe unittest
540 assert(DateTime(Date(1999, 7, 6), TimeOfDay(9, 7, 5)).year == 1999);
541 assert(DateTime(Date(2010, 10, 4), TimeOfDay(0, 0, 30)).year == 2010);
542 assert(DateTime(Date(-7, 4, 5), TimeOfDay(7, 45, 2)).year == -7);
545 @safe unittest
547 static void testDT(DateTime dt, int year, in DateTime expected, size_t line = __LINE__)
549 dt.year = year;
550 assert(dt == expected);
553 testDT(DateTime(Date(1, 1, 1), TimeOfDay(12, 30, 33)),
554 1999,
555 DateTime(Date(1999, 1, 1), TimeOfDay(12, 30, 33)));
556 testDT(DateTime(Date(1, 1, 1), TimeOfDay(12, 30, 33)),
558 DateTime(Date(0, 1, 1), TimeOfDay(12, 30, 33)));
559 testDT(DateTime(Date(1, 1, 1), TimeOfDay(12, 30, 33)),
560 -1999,
561 DateTime(Date(-1999, 1, 1), TimeOfDay(12, 30, 33)));
563 const cdt = DateTime(1999, 7, 6, 12, 30, 33);
564 immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
565 static assert(!__traits(compiles, cdt.year = 7));
566 static assert(!__traits(compiles, idt.year = 7));
571 Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C.
573 Throws:
574 $(REF DateTimeException,std,datetime,date) if $(D isAD) is true.
576 @property short yearBC() const @safe pure
578 return _date.yearBC;
582 @safe unittest
584 assert(DateTime(Date(0, 1, 1), TimeOfDay(12, 30, 33)).yearBC == 1);
585 assert(DateTime(Date(-1, 1, 1), TimeOfDay(10, 7, 2)).yearBC == 2);
586 assert(DateTime(Date(-100, 1, 1), TimeOfDay(4, 59, 0)).yearBC == 101);
589 @safe unittest
591 assertThrown!DateTimeException((in DateTime dt){dt.yearBC;}(DateTime(Date(1, 1, 1))));
593 auto dt = DateTime(1999, 7, 6, 12, 30, 33);
594 const cdt = DateTime(1999, 7, 6, 12, 30, 33);
595 immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
596 dt.yearBC = 12;
597 assert(dt.yearBC == 12);
598 static assert(!__traits(compiles, cdt.yearBC = 12));
599 static assert(!__traits(compiles, idt.yearBC = 12));
604 Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C.
606 Params:
607 year = The year B.C. to set this $(LREF DateTime)'s year to.
609 Throws:
610 $(REF DateTimeException,std,datetime,date) if a non-positive value
611 is given.
613 @property void yearBC(int year) @safe pure
615 _date.yearBC = year;
619 @safe unittest
621 auto dt = DateTime(Date(2010, 1, 1), TimeOfDay(7, 30, 0));
622 dt.yearBC = 1;
623 assert(dt == DateTime(Date(0, 1, 1), TimeOfDay(7, 30, 0)));
625 dt.yearBC = 10;
626 assert(dt == DateTime(Date(-9, 1, 1), TimeOfDay(7, 30, 0)));
629 @safe unittest
631 assertThrown!DateTimeException((DateTime dt){dt.yearBC = -1;}(DateTime(Date(1, 1, 1))));
633 auto dt = DateTime(1999, 7, 6, 12, 30, 33);
634 const cdt = DateTime(1999, 7, 6, 12, 30, 33);
635 immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
636 dt.yearBC = 12;
637 assert(dt.yearBC == 12);
638 static assert(!__traits(compiles, cdt.yearBC = 12));
639 static assert(!__traits(compiles, idt.yearBC = 12));
644 Month of a Gregorian Year.
646 @property Month month() const @safe pure nothrow @nogc
648 return _date.month;
652 @safe unittest
654 assert(DateTime(Date(1999, 7, 6), TimeOfDay(9, 7, 5)).month == 7);
655 assert(DateTime(Date(2010, 10, 4), TimeOfDay(0, 0, 30)).month == 10);
656 assert(DateTime(Date(-7, 4, 5), TimeOfDay(7, 45, 2)).month == 4);
659 @safe unittest
661 assert(DateTime.init.month == 1);
662 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).month == 7);
663 assert(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)).month == 7);
665 const cdt = DateTime(1999, 7, 6, 12, 30, 33);
666 immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
667 assert(cdt.month == 7);
668 assert(idt.month == 7);
673 Month of a Gregorian Year.
675 Params:
676 month = The month to set this $(LREF DateTime)'s month to.
678 Throws:
679 $(REF DateTimeException,std,datetime,date) if the given month is
680 not a valid month.
682 @property void month(Month month) @safe pure
684 _date.month = month;
687 @safe unittest
689 static void testDT(DateTime dt, Month month, in DateTime expected = DateTime.init, size_t line = __LINE__)
691 dt.month = month;
692 assert(expected != DateTime.init);
693 assert(dt == expected);
696 assertThrown!DateTimeException(testDT(DateTime(Date(1, 1, 1), TimeOfDay(12, 30, 33)), cast(Month) 0));
697 assertThrown!DateTimeException(testDT(DateTime(Date(1, 1, 1), TimeOfDay(12, 30, 33)), cast(Month) 13));
699 testDT(DateTime(Date(1, 1, 1), TimeOfDay(12, 30, 33)),
700 cast(Month) 7,
701 DateTime(Date(1, 7, 1), TimeOfDay(12, 30, 33)));
702 testDT(DateTime(Date(-1, 1, 1), TimeOfDay(12, 30, 33)),
703 cast(Month) 7,
704 DateTime(Date(-1, 7, 1), TimeOfDay(12, 30, 33)));
706 const cdt = DateTime(1999, 7, 6, 12, 30, 33);
707 immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
708 static assert(!__traits(compiles, cdt.month = 12));
709 static assert(!__traits(compiles, idt.month = 12));
714 Day of a Gregorian Month.
716 @property ubyte day() const @safe pure nothrow @nogc
718 return _date.day;
722 @safe unittest
724 assert(DateTime(Date(1999, 7, 6), TimeOfDay(9, 7, 5)).day == 6);
725 assert(DateTime(Date(2010, 10, 4), TimeOfDay(0, 0, 30)).day == 4);
726 assert(DateTime(Date(-7, 4, 5), TimeOfDay(7, 45, 2)).day == 5);
729 @safe unittest
731 import std.format : format;
732 import std.range : chain;
734 static void test(DateTime dateTime, int expected)
736 assert(dateTime.day == expected, format("Value given: %s", dateTime));
739 foreach (year; chain(testYearsBC, testYearsAD))
741 foreach (md; testMonthDays)
743 foreach (tod; testTODs)
744 test(DateTime(Date(year, md.month, md.day), tod), md.day);
748 const cdt = DateTime(1999, 7, 6, 12, 30, 33);
749 immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
750 assert(cdt.day == 6);
751 assert(idt.day == 6);
756 Day of a Gregorian Month.
758 Params:
759 day = The day of the month to set this $(LREF DateTime)'s day to.
761 Throws:
762 $(REF DateTimeException,std,datetime,date) if the given day is not
763 a valid day of the current month.
765 @property void day(int day) @safe pure
767 _date.day = day;
770 @safe unittest
772 import std.exception : assertNotThrown;
774 static void testDT(DateTime dt, int day)
776 dt.day = day;
779 // Test A.D.
780 assertThrown!DateTimeException(testDT(DateTime(Date(1, 1, 1)), 0));
781 assertThrown!DateTimeException(testDT(DateTime(Date(1, 1, 1)), 32));
782 assertThrown!DateTimeException(testDT(DateTime(Date(1, 2, 1)), 29));
783 assertThrown!DateTimeException(testDT(DateTime(Date(4, 2, 1)), 30));
784 assertThrown!DateTimeException(testDT(DateTime(Date(1, 3, 1)), 32));
785 assertThrown!DateTimeException(testDT(DateTime(Date(1, 4, 1)), 31));
786 assertThrown!DateTimeException(testDT(DateTime(Date(1, 5, 1)), 32));
787 assertThrown!DateTimeException(testDT(DateTime(Date(1, 6, 1)), 31));
788 assertThrown!DateTimeException(testDT(DateTime(Date(1, 7, 1)), 32));
789 assertThrown!DateTimeException(testDT(DateTime(Date(1, 8, 1)), 32));
790 assertThrown!DateTimeException(testDT(DateTime(Date(1, 9, 1)), 31));
791 assertThrown!DateTimeException(testDT(DateTime(Date(1, 10, 1)), 32));
792 assertThrown!DateTimeException(testDT(DateTime(Date(1, 11, 1)), 31));
793 assertThrown!DateTimeException(testDT(DateTime(Date(1, 12, 1)), 32));
795 assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 1, 1)), 31));
796 assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 2, 1)), 28));
797 assertNotThrown!DateTimeException(testDT(DateTime(Date(4, 2, 1)), 29));
798 assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 3, 1)), 31));
799 assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 4, 1)), 30));
800 assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 5, 1)), 31));
801 assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 6, 1)), 30));
802 assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 7, 1)), 31));
803 assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 8, 1)), 31));
804 assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 9, 1)), 30));
805 assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 10, 1)), 31));
806 assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 11, 1)), 30));
807 assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 12, 1)), 31));
810 auto dt = DateTime(Date(1, 1, 1), TimeOfDay(7, 12, 22));
811 dt.day = 6;
812 assert(dt == DateTime(Date(1, 1, 6), TimeOfDay(7, 12, 22)));
815 // Test B.C.
816 assertThrown!DateTimeException(testDT(DateTime(Date(-1, 1, 1)), 0));
817 assertThrown!DateTimeException(testDT(DateTime(Date(-1, 1, 1)), 32));
818 assertThrown!DateTimeException(testDT(DateTime(Date(-1, 2, 1)), 29));
819 assertThrown!DateTimeException(testDT(DateTime(Date(0, 2, 1)), 30));
820 assertThrown!DateTimeException(testDT(DateTime(Date(-1, 3, 1)), 32));
821 assertThrown!DateTimeException(testDT(DateTime(Date(-1, 4, 1)), 31));
822 assertThrown!DateTimeException(testDT(DateTime(Date(-1, 5, 1)), 32));
823 assertThrown!DateTimeException(testDT(DateTime(Date(-1, 6, 1)), 31));
824 assertThrown!DateTimeException(testDT(DateTime(Date(-1, 7, 1)), 32));
825 assertThrown!DateTimeException(testDT(DateTime(Date(-1, 8, 1)), 32));
826 assertThrown!DateTimeException(testDT(DateTime(Date(-1, 9, 1)), 31));
827 assertThrown!DateTimeException(testDT(DateTime(Date(-1, 10, 1)), 32));
828 assertThrown!DateTimeException(testDT(DateTime(Date(-1, 11, 1)), 31));
829 assertThrown!DateTimeException(testDT(DateTime(Date(-1, 12, 1)), 32));
831 assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 1, 1)), 31));
832 assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 2, 1)), 28));
833 assertNotThrown!DateTimeException(testDT(DateTime(Date(0, 2, 1)), 29));
834 assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 3, 1)), 31));
835 assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 4, 1)), 30));
836 assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 5, 1)), 31));
837 assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 6, 1)), 30));
838 assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 7, 1)), 31));
839 assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 8, 1)), 31));
840 assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 9, 1)), 30));
841 assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 10, 1)), 31));
842 assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 11, 1)), 30));
843 assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 12, 1)), 31));
845 auto dt = DateTime(Date(-1, 1, 1), TimeOfDay(7, 12, 22));
846 dt.day = 6;
847 assert(dt == DateTime(Date(-1, 1, 6), TimeOfDay(7, 12, 22)));
849 const cdt = DateTime(1999, 7, 6, 12, 30, 33);
850 immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
851 static assert(!__traits(compiles, cdt.day = 27));
852 static assert(!__traits(compiles, idt.day = 27));
857 Hours past midnight.
859 @property ubyte hour() const @safe pure nothrow @nogc
861 return _tod.hour;
864 @safe unittest
866 assert(DateTime.init.hour == 0);
867 assert(DateTime(Date.init, TimeOfDay(12, 0, 0)).hour == 12);
869 const cdt = DateTime(1999, 7, 6, 12, 30, 33);
870 immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
871 assert(cdt.hour == 12);
872 assert(idt.hour == 12);
877 Hours past midnight.
879 Params:
880 hour = The hour of the day to set this $(LREF DateTime)'s hour to.
882 Throws:
883 $(REF DateTimeException,std,datetime,date) if the given hour would
884 result in an invalid $(LREF DateTime).
886 @property void hour(int hour) @safe pure
888 _tod.hour = hour;
891 @safe unittest
893 assertThrown!DateTimeException((){DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0)).hour = 24;}());
895 auto dt = DateTime.init;
896 dt.hour = 12;
897 assert(dt == DateTime(1, 1, 1, 12, 0, 0));
899 const cdt = DateTime(1999, 7, 6, 12, 30, 33);
900 immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
901 static assert(!__traits(compiles, cdt.hour = 27));
902 static assert(!__traits(compiles, idt.hour = 27));
907 Minutes past the hour.
909 @property ubyte minute() const @safe pure nothrow @nogc
911 return _tod.minute;
914 @safe unittest
916 assert(DateTime.init.minute == 0);
917 assert(DateTime(1, 1, 1, 0, 30, 0).minute == 30);
919 const cdt = DateTime(1999, 7, 6, 12, 30, 33);
920 immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
921 assert(cdt.minute == 30);
922 assert(idt.minute == 30);
927 Minutes past the hour.
929 Params:
930 minute = The minute to set this $(LREF DateTime)'s minute to.
932 Throws:
933 $(REF DateTimeException,std,datetime,date) if the given minute
934 would result in an invalid $(LREF DateTime).
936 @property void minute(int minute) @safe pure
938 _tod.minute = minute;
941 @safe unittest
943 assertThrown!DateTimeException((){DateTime.init.minute = 60;}());
945 auto dt = DateTime.init;
946 dt.minute = 30;
947 assert(dt == DateTime(1, 1, 1, 0, 30, 0));
949 const cdt = DateTime(1999, 7, 6, 12, 30, 33);
950 immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
951 static assert(!__traits(compiles, cdt.minute = 27));
952 static assert(!__traits(compiles, idt.minute = 27));
957 Seconds past the minute.
959 @property ubyte second() const @safe pure nothrow @nogc
961 return _tod.second;
964 @safe unittest
966 assert(DateTime.init.second == 0);
967 assert(DateTime(1, 1, 1, 0, 0, 33).second == 33);
969 const cdt = DateTime(1999, 7, 6, 12, 30, 33);
970 immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
971 assert(cdt.second == 33);
972 assert(idt.second == 33);
977 Seconds past the minute.
979 Params:
980 second = The second to set this $(LREF DateTime)'s second to.
982 Throws:
983 $(REF DateTimeException,std,datetime,date) if the given seconds
984 would result in an invalid $(LREF DateTime).
986 @property void second(int second) @safe pure
988 _tod.second = second;
991 @safe unittest
993 assertThrown!DateTimeException((){DateTime.init.second = 60;}());
995 auto dt = DateTime.init;
996 dt.second = 33;
997 assert(dt == DateTime(1, 1, 1, 0, 0, 33));
999 const cdt = DateTime(1999, 7, 6, 12, 30, 33);
1000 immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
1001 static assert(!__traits(compiles, cdt.second = 27));
1002 static assert(!__traits(compiles, idt.second = 27));
1007 Adds the given number of years or months to this $(LREF DateTime). A
1008 negative number will subtract.
1010 Note that if day overflow is allowed, and the date with the adjusted
1011 year/month overflows the number of days in the new month, then the month
1012 will be incremented by one, and the day set to the number of days
1013 overflowed. (e.g. if the day were 31 and the new month were June, then
1014 the month would be incremented to July, and the new day would be 1). If
1015 day overflow is not allowed, then the day will be set to the last valid
1016 day in the month (e.g. June 31st would become June 30th).
1018 Params:
1019 units = The type of units to add ("years" or "months").
1020 value = The number of months or years to add to this
1021 $(LREF DateTime).
1022 allowOverflow = Whether the days should be allowed to overflow,
1023 causing the month to increment.
1025 ref DateTime add(string units)
1026 (long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe pure nothrow @nogc
1027 if (units == "years" || units == "months")
1029 _date.add!units(value, allowOverflow);
1030 return this;
1034 @safe unittest
1036 auto dt1 = DateTime(2010, 1, 1, 12, 30, 33);
1037 dt1.add!"months"(11);
1038 assert(dt1 == DateTime(2010, 12, 1, 12, 30, 33));
1040 auto dt2 = DateTime(2010, 1, 1, 12, 30, 33);
1041 dt2.add!"months"(-11);
1042 assert(dt2 == DateTime(2009, 2, 1, 12, 30, 33));
1044 auto dt3 = DateTime(2000, 2, 29, 12, 30, 33);
1045 dt3.add!"years"(1);
1046 assert(dt3 == DateTime(2001, 3, 1, 12, 30, 33));
1048 auto dt4 = DateTime(2000, 2, 29, 12, 30, 33);
1049 dt4.add!"years"(1, AllowDayOverflow.no);
1050 assert(dt4 == DateTime(2001, 2, 28, 12, 30, 33));
1053 @safe unittest
1055 auto dt = DateTime(2000, 1, 31);
1056 dt.add!"years"(7).add!"months"(-4);
1057 assert(dt == DateTime(2006, 10, 1));
1059 const cdt = DateTime(1999, 7, 6, 12, 30, 33);
1060 immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
1061 static assert(!__traits(compiles, cdt.add!"years"(4)));
1062 static assert(!__traits(compiles, idt.add!"years"(4)));
1063 static assert(!__traits(compiles, cdt.add!"months"(4)));
1064 static assert(!__traits(compiles, idt.add!"months"(4)));
1069 Adds the given number of years or months to this $(LREF DateTime). A
1070 negative number will subtract.
1072 The difference between rolling and adding is that rolling does not
1073 affect larger units. Rolling a $(LREF DateTime) 12 months
1074 gets the exact same $(LREF DateTime). However, the days can still be
1075 affected due to the differing number of days in each month.
1077 Because there are no units larger than years, there is no difference
1078 between adding and rolling years.
1080 Params:
1081 units = The type of units to add ("years" or "months").
1082 value = The number of months or years to add to this
1083 $(LREF DateTime).
1084 allowOverflow = Whether the days should be allowed to overflow,
1085 causing the month to increment.
1087 ref DateTime roll(string units)
1088 (long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe pure nothrow @nogc
1089 if (units == "years" || units == "months")
1091 _date.roll!units(value, allowOverflow);
1092 return this;
1096 @safe unittest
1098 auto dt1 = DateTime(2010, 1, 1, 12, 33, 33);
1099 dt1.roll!"months"(1);
1100 assert(dt1 == DateTime(2010, 2, 1, 12, 33, 33));
1102 auto dt2 = DateTime(2010, 1, 1, 12, 33, 33);
1103 dt2.roll!"months"(-1);
1104 assert(dt2 == DateTime(2010, 12, 1, 12, 33, 33));
1106 auto dt3 = DateTime(1999, 1, 29, 12, 33, 33);
1107 dt3.roll!"months"(1);
1108 assert(dt3 == DateTime(1999, 3, 1, 12, 33, 33));
1110 auto dt4 = DateTime(1999, 1, 29, 12, 33, 33);
1111 dt4.roll!"months"(1, AllowDayOverflow.no);
1112 assert(dt4 == DateTime(1999, 2, 28, 12, 33, 33));
1114 auto dt5 = DateTime(2000, 2, 29, 12, 30, 33);
1115 dt5.roll!"years"(1);
1116 assert(dt5 == DateTime(2001, 3, 1, 12, 30, 33));
1118 auto dt6 = DateTime(2000, 2, 29, 12, 30, 33);
1119 dt6.roll!"years"(1, AllowDayOverflow.no);
1120 assert(dt6 == DateTime(2001, 2, 28, 12, 30, 33));
1123 @safe unittest
1125 auto dt = DateTime(2000, 1, 31);
1126 dt.roll!"years"(7).roll!"months"(-4);
1127 assert(dt == DateTime(2007, 10, 1));
1129 const cdt = DateTime(1999, 7, 6, 12, 30, 33);
1130 immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
1131 static assert(!__traits(compiles, cdt.roll!"years"(4)));
1132 static assert(!__traits(compiles, idt.roll!"years"(4)));
1133 static assert(!__traits(compiles, cdt.roll!"months"(4)));
1134 static assert(!__traits(compiles, idt.roll!"months"(4)));
1139 Adds the given number of units to this $(LREF DateTime). A negative
1140 number will subtract.
1142 The difference between rolling and adding is that rolling does not
1143 affect larger units. For instance, rolling a $(LREF DateTime) one
1144 year's worth of days gets the exact same $(LREF DateTime).
1146 Accepted units are $(D "days"), $(D "minutes"), $(D "hours"),
1147 $(D "minutes"), and $(D "seconds").
1149 Params:
1150 units = The units to add.
1151 value = The number of $(D_PARAM units) to add to this
1152 $(LREF DateTime).
1154 ref DateTime roll(string units)(long value) @safe pure nothrow @nogc
1155 if (units == "days")
1157 _date.roll!"days"(value);
1158 return this;
1162 @safe unittest
1164 auto dt1 = DateTime(2010, 1, 1, 11, 23, 12);
1165 dt1.roll!"days"(1);
1166 assert(dt1 == DateTime(2010, 1, 2, 11, 23, 12));
1167 dt1.roll!"days"(365);
1168 assert(dt1 == DateTime(2010, 1, 26, 11, 23, 12));
1169 dt1.roll!"days"(-32);
1170 assert(dt1 == DateTime(2010, 1, 25, 11, 23, 12));
1172 auto dt2 = DateTime(2010, 7, 4, 12, 0, 0);
1173 dt2.roll!"hours"(1);
1174 assert(dt2 == DateTime(2010, 7, 4, 13, 0, 0));
1176 auto dt3 = DateTime(2010, 1, 1, 0, 0, 0);
1177 dt3.roll!"seconds"(-1);
1178 assert(dt3 == DateTime(2010, 1, 1, 0, 0, 59));
1181 @safe unittest
1183 auto dt = DateTime(2000, 1, 31);
1184 dt.roll!"days"(7).roll!"days"(-4);
1185 assert(dt == DateTime(2000, 1, 3));
1187 const cdt = DateTime(1999, 7, 6, 12, 30, 33);
1188 immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
1189 static assert(!__traits(compiles, cdt.roll!"days"(4)));
1190 static assert(!__traits(compiles, idt.roll!"days"(4)));
1194 // Shares documentation with "days" version.
1195 ref DateTime roll(string units)(long value) @safe pure nothrow @nogc
1196 if (units == "hours" ||
1197 units == "minutes" ||
1198 units == "seconds")
1200 _tod.roll!units(value);
1201 return this;
1204 // Test roll!"hours"().
1205 @safe unittest
1207 static void testDT(DateTime orig, int hours, in DateTime expected, size_t line = __LINE__)
1209 orig.roll!"hours"(hours);
1210 assert(orig == expected);
1213 // Test A.D.
1214 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 0,
1215 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
1216 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1,
1217 DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)));
1218 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 2,
1219 DateTime(Date(1999, 7, 6), TimeOfDay(14, 30, 33)));
1220 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 3,
1221 DateTime(Date(1999, 7, 6), TimeOfDay(15, 30, 33)));
1222 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 4,
1223 DateTime(Date(1999, 7, 6), TimeOfDay(16, 30, 33)));
1224 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 5,
1225 DateTime(Date(1999, 7, 6), TimeOfDay(17, 30, 33)));
1226 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 6,
1227 DateTime(Date(1999, 7, 6), TimeOfDay(18, 30, 33)));
1228 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 7,
1229 DateTime(Date(1999, 7, 6), TimeOfDay(19, 30, 33)));
1230 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 8,
1231 DateTime(Date(1999, 7, 6), TimeOfDay(20, 30, 33)));
1232 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 9,
1233 DateTime(Date(1999, 7, 6), TimeOfDay(21, 30, 33)));
1234 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 10,
1235 DateTime(Date(1999, 7, 6), TimeOfDay(22, 30, 33)));
1236 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 11,
1237 DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33)));
1238 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 12,
1239 DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)));
1240 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 13,
1241 DateTime(Date(1999, 7, 6), TimeOfDay(1, 30, 33)));
1242 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 14,
1243 DateTime(Date(1999, 7, 6), TimeOfDay(2, 30, 33)));
1244 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 15,
1245 DateTime(Date(1999, 7, 6), TimeOfDay(3, 30, 33)));
1246 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 16,
1247 DateTime(Date(1999, 7, 6), TimeOfDay(4, 30, 33)));
1248 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 17,
1249 DateTime(Date(1999, 7, 6), TimeOfDay(5, 30, 33)));
1250 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 18,
1251 DateTime(Date(1999, 7, 6), TimeOfDay(6, 30, 33)));
1252 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 19,
1253 DateTime(Date(1999, 7, 6), TimeOfDay(7, 30, 33)));
1254 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 20,
1255 DateTime(Date(1999, 7, 6), TimeOfDay(8, 30, 33)));
1256 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 21,
1257 DateTime(Date(1999, 7, 6), TimeOfDay(9, 30, 33)));
1258 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 22,
1259 DateTime(Date(1999, 7, 6), TimeOfDay(10, 30, 33)));
1260 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 23,
1261 DateTime(Date(1999, 7, 6), TimeOfDay(11, 30, 33)));
1262 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 24,
1263 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
1264 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 25,
1265 DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)));
1267 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -1,
1268 DateTime(Date(1999, 7, 6), TimeOfDay(11, 30, 33)));
1269 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -2,
1270 DateTime(Date(1999, 7, 6), TimeOfDay(10, 30, 33)));
1271 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -3,
1272 DateTime(Date(1999, 7, 6), TimeOfDay(9, 30, 33)));
1273 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -4,
1274 DateTime(Date(1999, 7, 6), TimeOfDay(8, 30, 33)));
1275 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -5,
1276 DateTime(Date(1999, 7, 6), TimeOfDay(7, 30, 33)));
1277 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -6,
1278 DateTime(Date(1999, 7, 6), TimeOfDay(6, 30, 33)));
1279 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -7,
1280 DateTime(Date(1999, 7, 6), TimeOfDay(5, 30, 33)));
1281 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -8,
1282 DateTime(Date(1999, 7, 6), TimeOfDay(4, 30, 33)));
1283 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -9,
1284 DateTime(Date(1999, 7, 6), TimeOfDay(3, 30, 33)));
1285 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -10,
1286 DateTime(Date(1999, 7, 6), TimeOfDay(2, 30, 33)));
1287 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -11,
1288 DateTime(Date(1999, 7, 6), TimeOfDay(1, 30, 33)));
1289 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -12,
1290 DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)));
1291 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -13,
1292 DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33)));
1293 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -14,
1294 DateTime(Date(1999, 7, 6), TimeOfDay(22, 30, 33)));
1295 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -15,
1296 DateTime(Date(1999, 7, 6), TimeOfDay(21, 30, 33)));
1297 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -16,
1298 DateTime(Date(1999, 7, 6), TimeOfDay(20, 30, 33)));
1299 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -17,
1300 DateTime(Date(1999, 7, 6), TimeOfDay(19, 30, 33)));
1301 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -18,
1302 DateTime(Date(1999, 7, 6), TimeOfDay(18, 30, 33)));
1303 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -19,
1304 DateTime(Date(1999, 7, 6), TimeOfDay(17, 30, 33)));
1305 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -20,
1306 DateTime(Date(1999, 7, 6), TimeOfDay(16, 30, 33)));
1307 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -21,
1308 DateTime(Date(1999, 7, 6), TimeOfDay(15, 30, 33)));
1309 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -22,
1310 DateTime(Date(1999, 7, 6), TimeOfDay(14, 30, 33)));
1311 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -23,
1312 DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)));
1313 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -24,
1314 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
1315 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -25,
1316 DateTime(Date(1999, 7, 6), TimeOfDay(11, 30, 33)));
1318 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)), 1,
1319 DateTime(Date(1999, 7, 6), TimeOfDay(1, 30, 33)));
1320 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)), 0,
1321 DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)));
1322 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)), -1,
1323 DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33)));
1325 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33)), 1,
1326 DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)));
1327 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33)), 0,
1328 DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33)));
1329 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33)), -1,
1330 DateTime(Date(1999, 7, 6), TimeOfDay(22, 30, 33)));
1332 testDT(DateTime(Date(1999, 7, 31), TimeOfDay(23, 30, 33)), 1,
1333 DateTime(Date(1999, 7, 31), TimeOfDay(0, 30, 33)));
1334 testDT(DateTime(Date(1999, 8, 1), TimeOfDay(0, 30, 33)), -1,
1335 DateTime(Date(1999, 8, 1), TimeOfDay(23, 30, 33)));
1337 testDT(DateTime(Date(1999, 12, 31), TimeOfDay(23, 30, 33)), 1,
1338 DateTime(Date(1999, 12, 31), TimeOfDay(0, 30, 33)));
1339 testDT(DateTime(Date(2000, 1, 1), TimeOfDay(0, 30, 33)), -1,
1340 DateTime(Date(2000, 1, 1), TimeOfDay(23, 30, 33)));
1342 testDT(DateTime(Date(1999, 2, 28), TimeOfDay(23, 30, 33)), 25,
1343 DateTime(Date(1999, 2, 28), TimeOfDay(0, 30, 33)));
1344 testDT(DateTime(Date(1999, 3, 2), TimeOfDay(0, 30, 33)), -25,
1345 DateTime(Date(1999, 3, 2), TimeOfDay(23, 30, 33)));
1347 testDT(DateTime(Date(2000, 2, 28), TimeOfDay(23, 30, 33)), 25,
1348 DateTime(Date(2000, 2, 28), TimeOfDay(0, 30, 33)));
1349 testDT(DateTime(Date(2000, 3, 1), TimeOfDay(0, 30, 33)), -25,
1350 DateTime(Date(2000, 3, 1), TimeOfDay(23, 30, 33)));
1352 // Test B.C.
1353 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 0,
1354 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
1355 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1,
1356 DateTime(Date(-1999, 7, 6), TimeOfDay(13, 30, 33)));
1357 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 2,
1358 DateTime(Date(-1999, 7, 6), TimeOfDay(14, 30, 33)));
1359 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 3,
1360 DateTime(Date(-1999, 7, 6), TimeOfDay(15, 30, 33)));
1361 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 4,
1362 DateTime(Date(-1999, 7, 6), TimeOfDay(16, 30, 33)));
1363 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 5,
1364 DateTime(Date(-1999, 7, 6), TimeOfDay(17, 30, 33)));
1365 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 6,
1366 DateTime(Date(-1999, 7, 6), TimeOfDay(18, 30, 33)));
1367 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 7,
1368 DateTime(Date(-1999, 7, 6), TimeOfDay(19, 30, 33)));
1369 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 8,
1370 DateTime(Date(-1999, 7, 6), TimeOfDay(20, 30, 33)));
1371 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 9,
1372 DateTime(Date(-1999, 7, 6), TimeOfDay(21, 30, 33)));
1373 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 10,
1374 DateTime(Date(-1999, 7, 6), TimeOfDay(22, 30, 33)));
1375 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 11,
1376 DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33)));
1377 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 12,
1378 DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33)));
1379 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 13,
1380 DateTime(Date(-1999, 7, 6), TimeOfDay(1, 30, 33)));
1381 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 14,
1382 DateTime(Date(-1999, 7, 6), TimeOfDay(2, 30, 33)));
1383 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 15,
1384 DateTime(Date(-1999, 7, 6), TimeOfDay(3, 30, 33)));
1385 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 16,
1386 DateTime(Date(-1999, 7, 6), TimeOfDay(4, 30, 33)));
1387 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 17,
1388 DateTime(Date(-1999, 7, 6), TimeOfDay(5, 30, 33)));
1389 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 18,
1390 DateTime(Date(-1999, 7, 6), TimeOfDay(6, 30, 33)));
1391 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 19,
1392 DateTime(Date(-1999, 7, 6), TimeOfDay(7, 30, 33)));
1393 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 20,
1394 DateTime(Date(-1999, 7, 6), TimeOfDay(8, 30, 33)));
1395 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 21,
1396 DateTime(Date(-1999, 7, 6), TimeOfDay(9, 30, 33)));
1397 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 22,
1398 DateTime(Date(-1999, 7, 6), TimeOfDay(10, 30, 33)));
1399 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 23,
1400 DateTime(Date(-1999, 7, 6), TimeOfDay(11, 30, 33)));
1401 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 24,
1402 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
1403 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 25,
1404 DateTime(Date(-1999, 7, 6), TimeOfDay(13, 30, 33)));
1406 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -1,
1407 DateTime(Date(-1999, 7, 6), TimeOfDay(11, 30, 33)));
1408 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -2,
1409 DateTime(Date(-1999, 7, 6), TimeOfDay(10, 30, 33)));
1410 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -3,
1411 DateTime(Date(-1999, 7, 6), TimeOfDay(9, 30, 33)));
1412 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -4,
1413 DateTime(Date(-1999, 7, 6), TimeOfDay(8, 30, 33)));
1414 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -5,
1415 DateTime(Date(-1999, 7, 6), TimeOfDay(7, 30, 33)));
1416 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -6,
1417 DateTime(Date(-1999, 7, 6), TimeOfDay(6, 30, 33)));
1418 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -7,
1419 DateTime(Date(-1999, 7, 6), TimeOfDay(5, 30, 33)));
1420 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -8,
1421 DateTime(Date(-1999, 7, 6), TimeOfDay(4, 30, 33)));
1422 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -9,
1423 DateTime(Date(-1999, 7, 6), TimeOfDay(3, 30, 33)));
1424 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -10,
1425 DateTime(Date(-1999, 7, 6), TimeOfDay(2, 30, 33)));
1426 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -11,
1427 DateTime(Date(-1999, 7, 6), TimeOfDay(1, 30, 33)));
1428 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -12,
1429 DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33)));
1430 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -13,
1431 DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33)));
1432 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -14,
1433 DateTime(Date(-1999, 7, 6), TimeOfDay(22, 30, 33)));
1434 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -15,
1435 DateTime(Date(-1999, 7, 6), TimeOfDay(21, 30, 33)));
1436 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -16,
1437 DateTime(Date(-1999, 7, 6), TimeOfDay(20, 30, 33)));
1438 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -17,
1439 DateTime(Date(-1999, 7, 6), TimeOfDay(19, 30, 33)));
1440 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -18,
1441 DateTime(Date(-1999, 7, 6), TimeOfDay(18, 30, 33)));
1442 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -19,
1443 DateTime(Date(-1999, 7, 6), TimeOfDay(17, 30, 33)));
1444 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -20,
1445 DateTime(Date(-1999, 7, 6), TimeOfDay(16, 30, 33)));
1446 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -21,
1447 DateTime(Date(-1999, 7, 6), TimeOfDay(15, 30, 33)));
1448 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -22,
1449 DateTime(Date(-1999, 7, 6), TimeOfDay(14, 30, 33)));
1450 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -23,
1451 DateTime(Date(-1999, 7, 6), TimeOfDay(13, 30, 33)));
1452 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -24,
1453 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
1454 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -25,
1455 DateTime(Date(-1999, 7, 6), TimeOfDay(11, 30, 33)));
1457 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33)), 1,
1458 DateTime(Date(-1999, 7, 6), TimeOfDay(1, 30, 33)));
1459 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33)), 0,
1460 DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33)));
1461 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33)), -1,
1462 DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33)));
1464 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33)), 1,
1465 DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33)));
1466 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33)), 0,
1467 DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33)));
1468 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33)), -1,
1469 DateTime(Date(-1999, 7, 6), TimeOfDay(22, 30, 33)));
1471 testDT(DateTime(Date(-1999, 7, 31), TimeOfDay(23, 30, 33)), 1,
1472 DateTime(Date(-1999, 7, 31), TimeOfDay(0, 30, 33)));
1473 testDT(DateTime(Date(-1999, 8, 1), TimeOfDay(0, 30, 33)), -1,
1474 DateTime(Date(-1999, 8, 1), TimeOfDay(23, 30, 33)));
1476 testDT(DateTime(Date(-2001, 12, 31), TimeOfDay(23, 30, 33)), 1,
1477 DateTime(Date(-2001, 12, 31), TimeOfDay(0, 30, 33)));
1478 testDT(DateTime(Date(-2000, 1, 1), TimeOfDay(0, 30, 33)), -1,
1479 DateTime(Date(-2000, 1, 1), TimeOfDay(23, 30, 33)));
1481 testDT(DateTime(Date(-2001, 2, 28), TimeOfDay(23, 30, 33)), 25,
1482 DateTime(Date(-2001, 2, 28), TimeOfDay(0, 30, 33)));
1483 testDT(DateTime(Date(-2001, 3, 2), TimeOfDay(0, 30, 33)), -25,
1484 DateTime(Date(-2001, 3, 2), TimeOfDay(23, 30, 33)));
1486 testDT(DateTime(Date(-2000, 2, 28), TimeOfDay(23, 30, 33)), 25,
1487 DateTime(Date(-2000, 2, 28), TimeOfDay(0, 30, 33)));
1488 testDT(DateTime(Date(-2000, 3, 1), TimeOfDay(0, 30, 33)), -25,
1489 DateTime(Date(-2000, 3, 1), TimeOfDay(23, 30, 33)));
1491 // Test Both
1492 testDT(DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33)), 17_546,
1493 DateTime(Date(-1, 1, 1), TimeOfDay(13, 30, 33)));
1494 testDT(DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33)), -17_546,
1495 DateTime(Date(1, 1, 1), TimeOfDay(11, 30, 33)));
1497 auto dt = DateTime(2000, 1, 31, 9, 7, 6);
1498 dt.roll!"hours"(27).roll!"hours"(-9);
1499 assert(dt == DateTime(2000, 1, 31, 3, 7, 6));
1501 const cdt = DateTime(1999, 7, 6, 12, 30, 33);
1502 immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
1503 static assert(!__traits(compiles, cdt.roll!"hours"(4)));
1504 static assert(!__traits(compiles, idt.roll!"hours"(4)));
1507 // Test roll!"minutes"().
1508 @safe unittest
1510 static void testDT(DateTime orig, int minutes, in DateTime expected, size_t line = __LINE__)
1512 orig.roll!"minutes"(minutes);
1513 assert(orig == expected);
1516 // Test A.D.
1517 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 0,
1518 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
1519 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1,
1520 DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)));
1521 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 2,
1522 DateTime(Date(1999, 7, 6), TimeOfDay(12, 32, 33)));
1523 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 3,
1524 DateTime(Date(1999, 7, 6), TimeOfDay(12, 33, 33)));
1525 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 4,
1526 DateTime(Date(1999, 7, 6), TimeOfDay(12, 34, 33)));
1527 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 5,
1528 DateTime(Date(1999, 7, 6), TimeOfDay(12, 35, 33)));
1529 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 10,
1530 DateTime(Date(1999, 7, 6), TimeOfDay(12, 40, 33)));
1531 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 15,
1532 DateTime(Date(1999, 7, 6), TimeOfDay(12, 45, 33)));
1533 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 29,
1534 DateTime(Date(1999, 7, 6), TimeOfDay(12, 59, 33)));
1535 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 30,
1536 DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)));
1537 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 45,
1538 DateTime(Date(1999, 7, 6), TimeOfDay(12, 15, 33)));
1539 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 60,
1540 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
1541 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 75,
1542 DateTime(Date(1999, 7, 6), TimeOfDay(12, 45, 33)));
1543 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 90,
1544 DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)));
1545 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 100,
1546 DateTime(Date(1999, 7, 6), TimeOfDay(12, 10, 33)));
1548 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 689,
1549 DateTime(Date(1999, 7, 6), TimeOfDay(12, 59, 33)));
1550 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 690,
1551 DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)));
1552 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 691,
1553 DateTime(Date(1999, 7, 6), TimeOfDay(12, 1, 33)));
1554 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 960,
1555 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
1556 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1439,
1557 DateTime(Date(1999, 7, 6), TimeOfDay(12, 29, 33)));
1558 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1440,
1559 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
1560 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1441,
1561 DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)));
1562 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 2880,
1563 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
1565 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -1,
1566 DateTime(Date(1999, 7, 6), TimeOfDay(12, 29, 33)));
1567 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -2,
1568 DateTime(Date(1999, 7, 6), TimeOfDay(12, 28, 33)));
1569 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -3,
1570 DateTime(Date(1999, 7, 6), TimeOfDay(12, 27, 33)));
1571 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -4,
1572 DateTime(Date(1999, 7, 6), TimeOfDay(12, 26, 33)));
1573 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -5,
1574 DateTime(Date(1999, 7, 6), TimeOfDay(12, 25, 33)));
1575 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -10,
1576 DateTime(Date(1999, 7, 6), TimeOfDay(12, 20, 33)));
1577 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -15,
1578 DateTime(Date(1999, 7, 6), TimeOfDay(12, 15, 33)));
1579 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -29,
1580 DateTime(Date(1999, 7, 6), TimeOfDay(12, 1, 33)));
1581 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -30,
1582 DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)));
1583 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -45,
1584 DateTime(Date(1999, 7, 6), TimeOfDay(12, 45, 33)));
1585 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -60,
1586 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
1587 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -75,
1588 DateTime(Date(1999, 7, 6), TimeOfDay(12, 15, 33)));
1589 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -90,
1590 DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)));
1591 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -100,
1592 DateTime(Date(1999, 7, 6), TimeOfDay(12, 50, 33)));
1594 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -749,
1595 DateTime(Date(1999, 7, 6), TimeOfDay(12, 1, 33)));
1596 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -750,
1597 DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)));
1598 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -751,
1599 DateTime(Date(1999, 7, 6), TimeOfDay(12, 59, 33)));
1600 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -960,
1601 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
1602 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -1439,
1603 DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)));
1604 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -1440,
1605 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
1606 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -1441,
1607 DateTime(Date(1999, 7, 6), TimeOfDay(12, 29, 33)));
1608 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -2880,
1609 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
1611 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)), 1,
1612 DateTime(Date(1999, 7, 6), TimeOfDay(12, 1, 33)));
1613 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)), 0,
1614 DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)));
1615 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)), -1,
1616 DateTime(Date(1999, 7, 6), TimeOfDay(12, 59, 33)));
1618 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(11, 59, 33)), 1,
1619 DateTime(Date(1999, 7, 6), TimeOfDay(11, 0, 33)));
1620 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(11, 59, 33)), 0,
1621 DateTime(Date(1999, 7, 6), TimeOfDay(11, 59, 33)));
1622 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(11, 59, 33)), -1,
1623 DateTime(Date(1999, 7, 6), TimeOfDay(11, 58, 33)));
1625 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33)), 1,
1626 DateTime(Date(1999, 7, 6), TimeOfDay(0, 1, 33)));
1627 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33)), 0,
1628 DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33)));
1629 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33)), -1,
1630 DateTime(Date(1999, 7, 6), TimeOfDay(0, 59, 33)));
1632 testDT(DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 33)), 1,
1633 DateTime(Date(1999, 7, 5), TimeOfDay(23, 0, 33)));
1634 testDT(DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 33)), 0,
1635 DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 33)));
1636 testDT(DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 33)), -1,
1637 DateTime(Date(1999, 7, 5), TimeOfDay(23, 58, 33)));
1639 testDT(DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 33)), 1,
1640 DateTime(Date(1998, 12, 31), TimeOfDay(23, 0, 33)));
1641 testDT(DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 33)), 0,
1642 DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 33)));
1643 testDT(DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 33)), -1,
1644 DateTime(Date(1998, 12, 31), TimeOfDay(23, 58, 33)));
1646 // Test B.C.
1647 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 0,
1648 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
1649 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1,
1650 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 31, 33)));
1651 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 2,
1652 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 32, 33)));
1653 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 3,
1654 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 33, 33)));
1655 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 4,
1656 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 34, 33)));
1657 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 5,
1658 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 35, 33)));
1659 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 10,
1660 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 40, 33)));
1661 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 15,
1662 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 45, 33)));
1663 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 29,
1664 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 59, 33)));
1665 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 30,
1666 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)));
1667 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 45,
1668 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 15, 33)));
1669 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 60,
1670 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
1671 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 75,
1672 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 45, 33)));
1673 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 90,
1674 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)));
1675 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 100,
1676 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 10, 33)));
1678 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 689,
1679 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 59, 33)));
1680 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 690,
1681 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)));
1682 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 691,
1683 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 1, 33)));
1684 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 960,
1685 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
1686 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1439,
1687 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 29, 33)));
1688 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1440,
1689 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
1690 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1441,
1691 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 31, 33)));
1692 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 2880,
1693 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
1695 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -1,
1696 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 29, 33)));
1697 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -2,
1698 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 28, 33)));
1699 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -3,
1700 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 27, 33)));
1701 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -4,
1702 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 26, 33)));
1703 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -5,
1704 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 25, 33)));
1705 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -10,
1706 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 20, 33)));
1707 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -15,
1708 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 15, 33)));
1709 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -29,
1710 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 1, 33)));
1711 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -30,
1712 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)));
1713 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -45,
1714 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 45, 33)));
1715 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -60,
1716 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
1717 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -75,
1718 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 15, 33)));
1719 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -90,
1720 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)));
1721 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -100,
1722 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 50, 33)));
1724 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -749,
1725 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 1, 33)));
1726 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -750,
1727 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)));
1728 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -751,
1729 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 59, 33)));
1730 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -960,
1731 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
1732 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -1439,
1733 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 31, 33)));
1734 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -1440,
1735 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
1736 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -1441,
1737 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 29, 33)));
1738 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -2880,
1739 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
1741 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)), 1,
1742 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 1, 33)));
1743 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)), 0,
1744 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)));
1745 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)), -1,
1746 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 59, 33)));
1748 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(11, 59, 33)), 1,
1749 DateTime(Date(-1999, 7, 6), TimeOfDay(11, 0, 33)));
1750 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(11, 59, 33)), 0,
1751 DateTime(Date(-1999, 7, 6), TimeOfDay(11, 59, 33)));
1752 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(11, 59, 33)), -1,
1753 DateTime(Date(-1999, 7, 6), TimeOfDay(11, 58, 33)));
1755 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 33)), 1,
1756 DateTime(Date(-1999, 7, 6), TimeOfDay(0, 1, 33)));
1757 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 33)), 0,
1758 DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 33)));
1759 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 33)), -1,
1760 DateTime(Date(-1999, 7, 6), TimeOfDay(0, 59, 33)));
1762 testDT(DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 33)), 1,
1763 DateTime(Date(-1999, 7, 5), TimeOfDay(23, 0, 33)));
1764 testDT(DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 33)), 0,
1765 DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 33)));
1766 testDT(DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 33)), -1,
1767 DateTime(Date(-1999, 7, 5), TimeOfDay(23, 58, 33)));
1769 testDT(DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 33)), 1,
1770 DateTime(Date(-2000, 12, 31), TimeOfDay(23, 0, 33)));
1771 testDT(DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 33)), 0,
1772 DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 33)));
1773 testDT(DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 33)), -1,
1774 DateTime(Date(-2000, 12, 31), TimeOfDay(23, 58, 33)));
1776 // Test Both
1777 testDT(DateTime(Date(1, 1, 1), TimeOfDay(0, 0, 0)), -1,
1778 DateTime(Date(1, 1, 1), TimeOfDay(0, 59, 0)));
1779 testDT(DateTime(Date(0, 12, 31), TimeOfDay(23, 59, 0)), 1,
1780 DateTime(Date(0, 12, 31), TimeOfDay(23, 0, 0)));
1782 testDT(DateTime(Date(0, 1, 1), TimeOfDay(0, 0, 0)), -1,
1783 DateTime(Date(0, 1, 1), TimeOfDay(0, 59, 0)));
1784 testDT(DateTime(Date(-1, 12, 31), TimeOfDay(23, 59, 0)), 1,
1785 DateTime(Date(-1, 12, 31), TimeOfDay(23, 0, 0)));
1787 testDT(DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33)), 1_052_760,
1788 DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33)));
1789 testDT(DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33)), -1_052_760,
1790 DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33)));
1792 testDT(DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33)), 1_052_782,
1793 DateTime(Date(-1, 1, 1), TimeOfDay(11, 52, 33)));
1794 testDT(DateTime(Date(1, 1, 1), TimeOfDay(13, 52, 33)), -1_052_782,
1795 DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33)));
1797 auto dt = DateTime(2000, 1, 31, 9, 7, 6);
1798 dt.roll!"minutes"(92).roll!"minutes"(-292);
1799 assert(dt == DateTime(2000, 1, 31, 9, 47, 6));
1801 const cdt = DateTime(1999, 7, 6, 12, 30, 33);
1802 immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
1803 static assert(!__traits(compiles, cdt.roll!"minutes"(4)));
1804 static assert(!__traits(compiles, idt.roll!"minutes"(4)));
1807 // Test roll!"seconds"().
1808 @safe unittest
1810 static void testDT(DateTime orig, int seconds, in DateTime expected, size_t line = __LINE__)
1812 orig.roll!"seconds"(seconds);
1813 assert(orig == expected);
1816 // Test A.D.
1817 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 0,
1818 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
1819 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1,
1820 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)));
1821 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 2,
1822 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 35)));
1823 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 3,
1824 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 36)));
1825 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 4,
1826 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 37)));
1827 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 5,
1828 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 38)));
1829 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 10,
1830 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 43)));
1831 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 15,
1832 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 48)));
1833 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 26,
1834 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 59)));
1835 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 27,
1836 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)));
1837 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 30,
1838 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 3)));
1839 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 59,
1840 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 32)));
1841 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 60,
1842 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
1843 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 61,
1844 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)));
1846 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1766,
1847 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 59)));
1848 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1767,
1849 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)));
1850 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1768,
1851 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 1)));
1852 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 2007,
1853 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)));
1854 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 3599,
1855 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 32)));
1856 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 3600,
1857 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
1858 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 3601,
1859 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)));
1860 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 7200,
1861 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
1863 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -1,
1864 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 32)));
1865 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -2,
1866 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 31)));
1867 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -3,
1868 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 30)));
1869 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -4,
1870 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 29)));
1871 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -5,
1872 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 28)));
1873 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -10,
1874 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 23)));
1875 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -15,
1876 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 18)));
1877 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -33,
1878 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)));
1879 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -34,
1880 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 59)));
1881 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -35,
1882 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 58)));
1883 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -59,
1884 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)));
1885 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -60,
1886 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
1887 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -61,
1888 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 32)));
1890 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)), 1,
1891 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 1)));
1892 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)), 0,
1893 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)));
1894 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)), -1,
1895 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 59)));
1897 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 0)), 1,
1898 DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 1)));
1899 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 0)), 0,
1900 DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 0)));
1901 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 0)), -1,
1902 DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 59)));
1904 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0)), 1,
1905 DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 1)));
1906 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0)), 0,
1907 DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0)));
1908 testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0)), -1,
1909 DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 59)));
1911 testDT(DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 59)), 1,
1912 DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 0)));
1913 testDT(DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 59)), 0,
1914 DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 59)));
1915 testDT(DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 59)), -1,
1916 DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 58)));
1918 testDT(DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 59)), 1,
1919 DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 0)));
1920 testDT(DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 59)), 0,
1921 DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 59)));
1922 testDT(DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 59)), -1,
1923 DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 58)));
1925 // Test B.C.
1926 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 0,
1927 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
1928 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1,
1929 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 34)));
1930 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 2,
1931 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 35)));
1932 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 3,
1933 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 36)));
1934 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 4,
1935 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 37)));
1936 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 5,
1937 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 38)));
1938 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 10,
1939 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 43)));
1940 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 15,
1941 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 48)));
1942 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 26,
1943 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 59)));
1944 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 27,
1945 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)));
1946 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 30,
1947 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 3)));
1948 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 59,
1949 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 32)));
1950 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 60,
1951 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
1952 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 61,
1953 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 34)));
1955 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1766,
1956 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 59)));
1957 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1767,
1958 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)));
1959 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1768,
1960 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 1)));
1961 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 2007,
1962 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)));
1963 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 3599,
1964 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 32)));
1965 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 3600,
1966 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
1967 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 3601,
1968 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 34)));
1969 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 7200,
1970 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
1972 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -1,
1973 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 32)));
1974 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -2,
1975 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 31)));
1976 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -3,
1977 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 30)));
1978 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -4,
1979 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 29)));
1980 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -5,
1981 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 28)));
1982 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -10,
1983 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 23)));
1984 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -15,
1985 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 18)));
1986 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -33,
1987 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)));
1988 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -34,
1989 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 59)));
1990 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -35,
1991 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 58)));
1992 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -59,
1993 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 34)));
1994 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -60,
1995 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
1996 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -61,
1997 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 32)));
1999 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)), 1,
2000 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 1)));
2001 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)), 0,
2002 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)));
2003 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)), -1,
2004 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 59)));
2006 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 0)), 1,
2007 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 1)));
2008 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 0)), 0,
2009 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 0)));
2010 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 0)), -1,
2011 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 59)));
2013 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 0)), 1,
2014 DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 1)));
2015 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 0)), 0,
2016 DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 0)));
2017 testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 0)), -1,
2018 DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 59)));
2020 testDT(DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 59)), 1,
2021 DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 0)));
2022 testDT(DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 59)), 0,
2023 DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 59)));
2024 testDT(DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 59)), -1,
2025 DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 58)));
2027 testDT(DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 59)), 1,
2028 DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 0)));
2029 testDT(DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 59)), 0,
2030 DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 59)));
2031 testDT(DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 59)), -1,
2032 DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 58)));
2034 // Test Both
2035 testDT(DateTime(Date(1, 1, 1), TimeOfDay(0, 0, 0)), -1,
2036 DateTime(Date(1, 1, 1), TimeOfDay(0, 0, 59)));
2037 testDT(DateTime(Date(0, 12, 31), TimeOfDay(23, 59, 59)), 1,
2038 DateTime(Date(0, 12, 31), TimeOfDay(23, 59, 0)));
2040 testDT(DateTime(Date(0, 1, 1), TimeOfDay(0, 0, 0)), -1,
2041 DateTime(Date(0, 1, 1), TimeOfDay(0, 0, 59)));
2042 testDT(DateTime(Date(-1, 12, 31), TimeOfDay(23, 59, 59)), 1,
2043 DateTime(Date(-1, 12, 31), TimeOfDay(23, 59, 0)));
2045 testDT(DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33)), 63_165_600L,
2046 DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33)));
2047 testDT(DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33)), -63_165_600L,
2048 DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33)));
2050 testDT(DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33)), 63_165_617L,
2051 DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 50)));
2052 testDT(DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 50)), -63_165_617L,
2053 DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33)));
2055 auto dt = DateTime(2000, 1, 31, 9, 7, 6);
2056 dt.roll!"seconds"(92).roll!"seconds"(-292);
2057 assert(dt == DateTime(2000, 1, 31, 9, 7, 46));
2059 const cdt = DateTime(1999, 7, 6, 12, 30, 33);
2060 immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
2061 static assert(!__traits(compiles, cdt.roll!"seconds"(4)));
2062 static assert(!__traits(compiles, idt.roll!"seconds"(4)));
2067 Gives the result of adding or subtracting a $(REF Duration, core,time)
2068 from this $(LREF DateTime).
2070 The legal types of arithmetic for $(LREF DateTime) using this operator
2073 $(BOOKTABLE,
2074 $(TR $(TD DateTime) $(TD +) $(TD Duration) $(TD -->) $(TD DateTime))
2075 $(TR $(TD DateTime) $(TD -) $(TD Duration) $(TD -->) $(TD DateTime))
2078 Params:
2079 duration = The $(REF Duration, core,time) to add to or subtract from
2080 this $(LREF DateTime).
2082 DateTime opBinary(string op)(Duration duration) const @safe pure nothrow @nogc
2083 if (op == "+" || op == "-")
2085 DateTime retval = this;
2086 immutable seconds = duration.total!"seconds";
2087 mixin("return retval._addSeconds(" ~ op ~ "seconds);");
2091 @safe unittest
2093 import core.time : hours, seconds;
2095 assert(DateTime(2015, 12, 31, 23, 59, 59) + seconds(1) ==
2096 DateTime(2016, 1, 1, 0, 0, 0));
2098 assert(DateTime(2015, 12, 31, 23, 59, 59) + hours(1) ==
2099 DateTime(2016, 1, 1, 0, 59, 59));
2101 assert(DateTime(2016, 1, 1, 0, 0, 0) - seconds(1) ==
2102 DateTime(2015, 12, 31, 23, 59, 59));
2104 assert(DateTime(2016, 1, 1, 0, 59, 59) - hours(1) ==
2105 DateTime(2015, 12, 31, 23, 59, 59));
2108 @safe unittest
2110 auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2112 assert(dt + dur!"weeks"(7) == DateTime(Date(1999, 8, 24), TimeOfDay(12, 30, 33)));
2113 assert(dt + dur!"weeks"(-7) == DateTime(Date(1999, 5, 18), TimeOfDay(12, 30, 33)));
2114 assert(dt + dur!"days"(7) == DateTime(Date(1999, 7, 13), TimeOfDay(12, 30, 33)));
2115 assert(dt + dur!"days"(-7) == DateTime(Date(1999, 6, 29), TimeOfDay(12, 30, 33)));
2117 assert(dt + dur!"hours"(7) == DateTime(Date(1999, 7, 6), TimeOfDay(19, 30, 33)));
2118 assert(dt + dur!"hours"(-7) == DateTime(Date(1999, 7, 6), TimeOfDay(5, 30, 33)));
2119 assert(dt + dur!"minutes"(7) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 37, 33)));
2120 assert(dt + dur!"minutes"(-7) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 23, 33)));
2121 assert(dt + dur!"seconds"(7) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
2122 assert(dt + dur!"seconds"(-7) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
2123 assert(dt + dur!"msecs"(7_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
2124 assert(dt + dur!"msecs"(-7_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
2125 assert(dt + dur!"usecs"(7_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
2126 assert(dt + dur!"usecs"(-7_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
2127 assert(dt + dur!"hnsecs"(70_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
2128 assert(dt + dur!"hnsecs"(-70_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
2130 assert(dt - dur!"weeks"(-7) == DateTime(Date(1999, 8, 24), TimeOfDay(12, 30, 33)));
2131 assert(dt - dur!"weeks"(7) == DateTime(Date(1999, 5, 18), TimeOfDay(12, 30, 33)));
2132 assert(dt - dur!"days"(-7) == DateTime(Date(1999, 7, 13), TimeOfDay(12, 30, 33)));
2133 assert(dt - dur!"days"(7) == DateTime(Date(1999, 6, 29), TimeOfDay(12, 30, 33)));
2135 assert(dt - dur!"hours"(-7) == DateTime(Date(1999, 7, 6), TimeOfDay(19, 30, 33)));
2136 assert(dt - dur!"hours"(7) == DateTime(Date(1999, 7, 6), TimeOfDay(5, 30, 33)));
2137 assert(dt - dur!"minutes"(-7) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 37, 33)));
2138 assert(dt - dur!"minutes"(7) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 23, 33)));
2139 assert(dt - dur!"seconds"(-7) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
2140 assert(dt - dur!"seconds"(7) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
2141 assert(dt - dur!"msecs"(-7_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
2142 assert(dt - dur!"msecs"(7_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
2143 assert(dt - dur!"usecs"(-7_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
2144 assert(dt - dur!"usecs"(7_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
2145 assert(dt - dur!"hnsecs"(-70_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
2146 assert(dt - dur!"hnsecs"(70_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
2148 auto duration = dur!"seconds"(12);
2149 const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2150 immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2151 assert(cdt + duration == DateTime(1999, 7, 6, 12, 30, 45));
2152 assert(idt + duration == DateTime(1999, 7, 6, 12, 30, 45));
2153 assert(cdt - duration == DateTime(1999, 7, 6, 12, 30, 21));
2154 assert(idt - duration == DateTime(1999, 7, 6, 12, 30, 21));
2157 // Explicitly undocumented. It will be removed in January 2018. @@@DEPRECATED_2018-01@@@
2158 deprecated("Use Duration instead of TickDuration.")
2159 DateTime opBinary(string op)(in TickDuration td) const @safe pure nothrow @nogc
2160 if (op == "+" || op == "-")
2162 DateTime retval = this;
2163 immutable seconds = td.seconds;
2164 mixin("return retval._addSeconds(" ~ op ~ "seconds);");
2167 deprecated @safe unittest
2169 // This probably only runs in cases where gettimeofday() is used, but it's
2170 // hard to do this test correctly with variable ticksPerSec.
2171 if (TickDuration.ticksPerSec == 1_000_000)
2173 auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2175 assert(dt + TickDuration.from!"usecs"(7_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
2176 assert(dt + TickDuration.from!"usecs"(-7_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
2178 assert(dt - TickDuration.from!"usecs"(-7_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
2179 assert(dt - TickDuration.from!"usecs"(7_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
2185 Gives the result of adding or subtracting a duration from this
2186 $(LREF DateTime), as well as assigning the result to this
2187 $(LREF DateTime).
2189 The legal types of arithmetic for $(LREF DateTime) using this operator
2192 $(BOOKTABLE,
2193 $(TR $(TD DateTime) $(TD +) $(TD duration) $(TD -->) $(TD DateTime))
2194 $(TR $(TD DateTime) $(TD -) $(TD duration) $(TD -->) $(TD DateTime))
2197 Params:
2198 duration = The duration to add to or subtract from this
2199 $(LREF DateTime).
2201 ref DateTime opOpAssign(string op, D)(in D duration) @safe pure nothrow @nogc
2202 if ((op == "+" || op == "-") &&
2203 (is(Unqual!D == Duration) ||
2204 is(Unqual!D == TickDuration)))
2206 import std.format : format;
2208 DateTime retval = this;
2210 static if (is(Unqual!D == Duration))
2211 immutable hnsecs = duration.total!"hnsecs";
2212 else static if (is(Unqual!D == TickDuration))
2213 immutable hnsecs = duration.hnsecs;
2215 mixin(format(`return _addSeconds(convert!("hnsecs", "seconds")(%shnsecs));`, op));
2218 @safe unittest
2220 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"weeks"(7) ==
2221 DateTime(Date(1999, 8, 24), TimeOfDay(12, 30, 33)));
2222 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"weeks"(-7) ==
2223 DateTime(Date(1999, 5, 18), TimeOfDay(12, 30, 33)));
2224 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"days"(7) ==
2225 DateTime(Date(1999, 7, 13), TimeOfDay(12, 30, 33)));
2226 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"days"(-7) ==
2227 DateTime(Date(1999, 6, 29), TimeOfDay(12, 30, 33)));
2229 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"hours"(7) ==
2230 DateTime(Date(1999, 7, 6), TimeOfDay(19, 30, 33)));
2231 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"hours"(-7) ==
2232 DateTime(Date(1999, 7, 6), TimeOfDay(5, 30, 33)));
2233 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"minutes"(7) ==
2234 DateTime(Date(1999, 7, 6), TimeOfDay(12, 37, 33)));
2235 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"minutes"(-7) ==
2236 DateTime(Date(1999, 7, 6), TimeOfDay(12, 23, 33)));
2237 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"seconds"(7) ==
2238 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
2239 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"seconds"(-7) ==
2240 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
2241 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"msecs"(7_000) ==
2242 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
2243 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"msecs"(-7_000) ==
2244 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
2245 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"usecs"(7_000_000) ==
2246 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
2247 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"usecs"(-7_000_000) ==
2248 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
2249 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"hnsecs"(70_000_000) ==
2250 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
2251 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"hnsecs"(-70_000_000) ==
2252 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
2254 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"weeks"(-7) ==
2255 DateTime(Date(1999, 8, 24), TimeOfDay(12, 30, 33)));
2256 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"weeks"(7) ==
2257 DateTime(Date(1999, 5, 18), TimeOfDay(12, 30, 33)));
2258 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"days"(-7) ==
2259 DateTime(Date(1999, 7, 13), TimeOfDay(12, 30, 33)));
2260 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"days"(7) ==
2261 DateTime(Date(1999, 6, 29), TimeOfDay(12, 30, 33)));
2263 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"hours"(-7) ==
2264 DateTime(Date(1999, 7, 6), TimeOfDay(19, 30, 33)));
2265 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"hours"(7) ==
2266 DateTime(Date(1999, 7, 6), TimeOfDay(5, 30, 33)));
2267 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"minutes"(-7) ==
2268 DateTime(Date(1999, 7, 6), TimeOfDay(12, 37, 33)));
2269 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"minutes"(7) ==
2270 DateTime(Date(1999, 7, 6), TimeOfDay(12, 23, 33)));
2271 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"seconds"(-7) ==
2272 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
2273 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"seconds"(7) ==
2274 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
2275 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"msecs"(-7_000) ==
2276 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
2277 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"msecs"(7_000) ==
2278 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
2279 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"usecs"(-7_000_000) ==
2280 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
2281 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"usecs"(7_000_000) ==
2282 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
2283 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"hnsecs"(-70_000_000) ==
2284 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
2285 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"hnsecs"(70_000_000) ==
2286 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
2288 auto dt = DateTime(2000, 1, 31, 9, 7, 6);
2289 (dt += dur!"seconds"(92)) -= dur!"days"(-500);
2290 assert(dt == DateTime(2001, 6, 14, 9, 8, 38));
2292 auto duration = dur!"seconds"(12);
2293 const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2294 immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2295 static assert(!__traits(compiles, cdt += duration));
2296 static assert(!__traits(compiles, idt += duration));
2297 static assert(!__traits(compiles, cdt -= duration));
2298 static assert(!__traits(compiles, idt -= duration));
2301 // Explicitly undocumented. It will be removed in January 2018. @@@DEPRECATED_2018-01@@@
2302 deprecated("Use Duration instead of TickDuration.")
2303 ref DateTime opOpAssign(string op)(TickDuration td) @safe pure nothrow @nogc
2304 if (op == "+" || op == "-")
2306 DateTime retval = this;
2307 immutable seconds = td.seconds;
2308 mixin("return _addSeconds(" ~ op ~ "seconds);");
2311 deprecated @safe unittest
2313 // This probably only runs in cases where gettimeofday() is used, but it's
2314 // hard to do this test correctly with variable ticksPerSec.
2315 if (TickDuration.ticksPerSec == 1_000_000)
2318 auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2319 dt += TickDuration.from!"usecs"(7_000_000);
2320 assert(dt == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
2324 auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2325 dt += TickDuration.from!"usecs"(-7_000_000);
2326 assert(dt == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
2330 auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2331 dt -= TickDuration.from!"usecs"(-7_000_000);
2332 assert(dt == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40)));
2336 auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2337 dt -= TickDuration.from!"usecs"(7_000_000);
2338 assert(dt == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26)));
2345 Gives the difference between two $(LREF DateTime)s.
2347 The legal types of arithmetic for $(LREF DateTime) using this operator are
2349 $(BOOKTABLE,
2350 $(TR $(TD DateTime) $(TD -) $(TD DateTime) $(TD -->) $(TD duration))
2353 Duration opBinary(string op)(in DateTime rhs) const @safe pure nothrow @nogc
2354 if (op == "-")
2356 immutable dateResult = _date - rhs.date;
2357 immutable todResult = _tod - rhs._tod;
2359 return dur!"hnsecs"(dateResult.total!"hnsecs" + todResult.total!"hnsecs");
2362 @safe unittest
2364 auto dt = DateTime(1999, 7, 6, 12, 30, 33);
2366 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - DateTime(Date(1998, 7, 6), TimeOfDay(12, 30, 33)) ==
2367 dur!"seconds"(31_536_000));
2368 assert(DateTime(Date(1998, 7, 6), TimeOfDay(12, 30, 33)) - DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) ==
2369 dur!"seconds"(-31_536_000));
2371 assert(DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33)) - DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) ==
2372 dur!"seconds"(26_78_400));
2373 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33)) ==
2374 dur!"seconds"(-26_78_400));
2376 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - DateTime(Date(1999, 7, 5), TimeOfDay(12, 30, 33)) ==
2377 dur!"seconds"(86_400));
2378 assert(DateTime(Date(1999, 7, 5), TimeOfDay(12, 30, 33)) - DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) ==
2379 dur!"seconds"(-86_400));
2381 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - DateTime(Date(1999, 7, 6), TimeOfDay(11, 30, 33)) ==
2382 dur!"seconds"(3600));
2383 assert(DateTime(Date(1999, 7, 6), TimeOfDay(11, 30, 33)) - DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) ==
2384 dur!"seconds"(-3600));
2386 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)) - DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) ==
2387 dur!"seconds"(60));
2388 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)) ==
2389 dur!"seconds"(-60));
2391 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)) - DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) ==
2392 dur!"seconds"(1));
2393 assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)) ==
2394 dur!"seconds"(-1));
2396 assert(DateTime(1, 1, 1, 12, 30, 33) - DateTime(1, 1, 1, 0, 0, 0) == dur!"seconds"(45033));
2397 assert(DateTime(1, 1, 1, 0, 0, 0) - DateTime(1, 1, 1, 12, 30, 33) == dur!"seconds"(-45033));
2398 assert(DateTime(0, 12, 31, 12, 30, 33) - DateTime(1, 1, 1, 0, 0, 0) == dur!"seconds"(-41367));
2399 assert(DateTime(1, 1, 1, 0, 0, 0) - DateTime(0, 12, 31, 12, 30, 33) == dur!"seconds"(41367));
2401 const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2402 immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2403 assert(dt - dt == Duration.zero);
2404 assert(cdt - dt == Duration.zero);
2405 assert(idt - dt == Duration.zero);
2407 assert(dt - cdt == Duration.zero);
2408 assert(cdt - cdt == Duration.zero);
2409 assert(idt - cdt == Duration.zero);
2411 assert(dt - idt == Duration.zero);
2412 assert(cdt - idt == Duration.zero);
2413 assert(idt - idt == Duration.zero);
2418 Returns the difference between the two $(LREF DateTime)s in months.
2420 To get the difference in years, subtract the year property
2421 of two $(LREF DateTime)s. To get the difference in days or weeks,
2422 subtract the $(LREF DateTime)s themselves and use the
2423 $(REF Duration, core,time) that results. Because converting between
2424 months and smaller units requires a specific date (which
2425 $(REF Duration, core,time)s don't have), getting the difference in
2426 months requires some math using both the year and month properties, so
2427 this is a convenience function for getting the difference in months.
2429 Note that the number of days in the months or how far into the month
2430 either date is is irrelevant. It is the difference in the month property
2431 combined with the difference in years * 12. So, for instance,
2432 December 31st and January 1st are one month apart just as December 1st
2433 and January 31st are one month apart.
2435 Params:
2436 rhs = The $(LREF DateTime) to subtract from this one.
2438 int diffMonths(in DateTime rhs) const @safe pure nothrow @nogc
2440 return _date.diffMonths(rhs._date);
2444 @safe unittest
2446 assert(DateTime(1999, 2, 1, 12, 2, 3).diffMonths(
2447 DateTime(1999, 1, 31, 23, 59, 59)) == 1);
2449 assert(DateTime(1999, 1, 31, 0, 0, 0).diffMonths(
2450 DateTime(1999, 2, 1, 12, 3, 42)) == -1);
2452 assert(DateTime(1999, 3, 1, 5, 30, 0).diffMonths(
2453 DateTime(1999, 1, 1, 2, 4, 7)) == 2);
2455 assert(DateTime(1999, 1, 1, 7, 2, 4).diffMonths(
2456 DateTime(1999, 3, 31, 0, 30, 58)) == -2);
2459 @safe unittest
2461 auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2462 const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2463 immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2464 assert(dt.diffMonths(dt) == 0);
2465 assert(cdt.diffMonths(dt) == 0);
2466 assert(idt.diffMonths(dt) == 0);
2468 assert(dt.diffMonths(cdt) == 0);
2469 assert(cdt.diffMonths(cdt) == 0);
2470 assert(idt.diffMonths(cdt) == 0);
2472 assert(dt.diffMonths(idt) == 0);
2473 assert(cdt.diffMonths(idt) == 0);
2474 assert(idt.diffMonths(idt) == 0);
2479 Whether this $(LREF DateTime) is in a leap year.
2481 @property bool isLeapYear() const @safe pure nothrow @nogc
2483 return _date.isLeapYear;
2486 @safe unittest
2488 auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2489 const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2490 immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2491 assert(!dt.isLeapYear);
2492 assert(!cdt.isLeapYear);
2493 assert(!idt.isLeapYear);
2498 Day of the week this $(LREF DateTime) is on.
2500 @property DayOfWeek dayOfWeek() const @safe pure nothrow @nogc
2502 return _date.dayOfWeek;
2505 @safe unittest
2507 auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2508 const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2509 immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2510 assert(dt.dayOfWeek == DayOfWeek.tue);
2511 assert(cdt.dayOfWeek == DayOfWeek.tue);
2512 assert(idt.dayOfWeek == DayOfWeek.tue);
2517 Day of the year this $(LREF DateTime) is on.
2519 @property ushort dayOfYear() const @safe pure nothrow @nogc
2521 return _date.dayOfYear;
2525 @safe unittest
2527 assert(DateTime(Date(1999, 1, 1), TimeOfDay(12, 22, 7)).dayOfYear == 1);
2528 assert(DateTime(Date(1999, 12, 31), TimeOfDay(7, 2, 59)).dayOfYear == 365);
2529 assert(DateTime(Date(2000, 12, 31), TimeOfDay(21, 20, 0)).dayOfYear == 366);
2532 @safe unittest
2534 auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2535 const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2536 immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2537 assert(dt.dayOfYear == 187);
2538 assert(cdt.dayOfYear == 187);
2539 assert(idt.dayOfYear == 187);
2544 Day of the year.
2546 Params:
2547 day = The day of the year to set which day of the year this
2548 $(LREF DateTime) is on.
2550 @property void dayOfYear(int day) @safe pure
2552 _date.dayOfYear = day;
2555 @safe unittest
2557 auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2558 const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2559 immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2560 dt.dayOfYear = 12;
2561 assert(dt.dayOfYear == 12);
2562 static assert(!__traits(compiles, cdt.dayOfYear = 12));
2563 static assert(!__traits(compiles, idt.dayOfYear = 12));
2568 The Xth day of the Gregorian Calendar that this $(LREF DateTime) is on.
2570 @property int dayOfGregorianCal() const @safe pure nothrow @nogc
2572 return _date.dayOfGregorianCal;
2576 @safe unittest
2578 assert(DateTime(Date(1, 1, 1), TimeOfDay(0, 0, 0)).dayOfGregorianCal == 1);
2579 assert(DateTime(Date(1, 12, 31), TimeOfDay(23, 59, 59)).dayOfGregorianCal == 365);
2580 assert(DateTime(Date(2, 1, 1), TimeOfDay(2, 2, 2)).dayOfGregorianCal == 366);
2582 assert(DateTime(Date(0, 12, 31), TimeOfDay(7, 7, 7)).dayOfGregorianCal == 0);
2583 assert(DateTime(Date(0, 1, 1), TimeOfDay(19, 30, 0)).dayOfGregorianCal == -365);
2584 assert(DateTime(Date(-1, 12, 31), TimeOfDay(4, 7, 0)).dayOfGregorianCal == -366);
2586 assert(DateTime(Date(2000, 1, 1), TimeOfDay(9, 30, 20)).dayOfGregorianCal == 730_120);
2587 assert(DateTime(Date(2010, 12, 31), TimeOfDay(15, 45, 50)).dayOfGregorianCal == 734_137);
2590 @safe unittest
2592 const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2593 immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2594 assert(cdt.dayOfGregorianCal == 729_941);
2595 assert(idt.dayOfGregorianCal == 729_941);
2600 The Xth day of the Gregorian Calendar that this $(LREF DateTime) is on.
2601 Setting this property does not affect the time portion of
2602 $(LREF DateTime).
2604 Params:
2605 days = The day of the Gregorian Calendar to set this $(LREF DateTime)
2608 @property void dayOfGregorianCal(int days) @safe pure nothrow @nogc
2610 _date.dayOfGregorianCal = days;
2614 @safe unittest
2616 auto dt = DateTime(Date.init, TimeOfDay(12, 0, 0));
2617 dt.dayOfGregorianCal = 1;
2618 assert(dt == DateTime(Date(1, 1, 1), TimeOfDay(12, 0, 0)));
2620 dt.dayOfGregorianCal = 365;
2621 assert(dt == DateTime(Date(1, 12, 31), TimeOfDay(12, 0, 0)));
2623 dt.dayOfGregorianCal = 366;
2624 assert(dt == DateTime(Date(2, 1, 1), TimeOfDay(12, 0, 0)));
2626 dt.dayOfGregorianCal = 0;
2627 assert(dt == DateTime(Date(0, 12, 31), TimeOfDay(12, 0, 0)));
2629 dt.dayOfGregorianCal = -365;
2630 assert(dt == DateTime(Date(-0, 1, 1), TimeOfDay(12, 0, 0)));
2632 dt.dayOfGregorianCal = -366;
2633 assert(dt == DateTime(Date(-1, 12, 31), TimeOfDay(12, 0, 0)));
2635 dt.dayOfGregorianCal = 730_120;
2636 assert(dt == DateTime(Date(2000, 1, 1), TimeOfDay(12, 0, 0)));
2638 dt.dayOfGregorianCal = 734_137;
2639 assert(dt == DateTime(Date(2010, 12, 31), TimeOfDay(12, 0, 0)));
2642 @safe unittest
2644 const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2645 immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2646 static assert(!__traits(compiles, cdt.dayOfGregorianCal = 7));
2647 static assert(!__traits(compiles, idt.dayOfGregorianCal = 7));
2652 The ISO 8601 week of the year that this $(LREF DateTime) is in.
2654 See_Also:
2655 $(HTTP en.wikipedia.org/wiki/ISO_week_date, ISO Week Date)
2657 @property ubyte isoWeek() const @safe pure nothrow
2659 return _date.isoWeek;
2662 @safe unittest
2664 auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2665 const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2666 immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2667 assert(dt.isoWeek == 27);
2668 assert(cdt.isoWeek == 27);
2669 assert(idt.isoWeek == 27);
2674 $(LREF DateTime) for the last day in the month that this
2675 $(LREF DateTime) is in. The time portion of endOfMonth is always
2676 23:59:59.
2678 @property DateTime endOfMonth() const @safe pure nothrow
2681 return DateTime(_date.endOfMonth, TimeOfDay(23, 59, 59));
2682 catch (Exception e)
2683 assert(0, "DateTime constructor threw.");
2687 @safe unittest
2689 assert(DateTime(Date(1999, 1, 6), TimeOfDay(0, 0, 0)).endOfMonth ==
2690 DateTime(Date(1999, 1, 31), TimeOfDay(23, 59, 59)));
2692 assert(DateTime(Date(1999, 2, 7), TimeOfDay(19, 30, 0)).endOfMonth ==
2693 DateTime(Date(1999, 2, 28), TimeOfDay(23, 59, 59)));
2695 assert(DateTime(Date(2000, 2, 7), TimeOfDay(5, 12, 27)).endOfMonth ==
2696 DateTime(Date(2000, 2, 29), TimeOfDay(23, 59, 59)));
2698 assert(DateTime(Date(2000, 6, 4), TimeOfDay(12, 22, 9)).endOfMonth ==
2699 DateTime(Date(2000, 6, 30), TimeOfDay(23, 59, 59)));
2702 @safe unittest
2704 // Test A.D.
2705 assert(DateTime(1999, 1, 1, 0, 13, 26).endOfMonth == DateTime(1999, 1, 31, 23, 59, 59));
2706 assert(DateTime(1999, 2, 1, 1, 14, 27).endOfMonth == DateTime(1999, 2, 28, 23, 59, 59));
2707 assert(DateTime(2000, 2, 1, 2, 15, 28).endOfMonth == DateTime(2000, 2, 29, 23, 59, 59));
2708 assert(DateTime(1999, 3, 1, 3, 16, 29).endOfMonth == DateTime(1999, 3, 31, 23, 59, 59));
2709 assert(DateTime(1999, 4, 1, 4, 17, 30).endOfMonth == DateTime(1999, 4, 30, 23, 59, 59));
2710 assert(DateTime(1999, 5, 1, 5, 18, 31).endOfMonth == DateTime(1999, 5, 31, 23, 59, 59));
2711 assert(DateTime(1999, 6, 1, 6, 19, 32).endOfMonth == DateTime(1999, 6, 30, 23, 59, 59));
2712 assert(DateTime(1999, 7, 1, 7, 20, 33).endOfMonth == DateTime(1999, 7, 31, 23, 59, 59));
2713 assert(DateTime(1999, 8, 1, 8, 21, 34).endOfMonth == DateTime(1999, 8, 31, 23, 59, 59));
2714 assert(DateTime(1999, 9, 1, 9, 22, 35).endOfMonth == DateTime(1999, 9, 30, 23, 59, 59));
2715 assert(DateTime(1999, 10, 1, 10, 23, 36).endOfMonth == DateTime(1999, 10, 31, 23, 59, 59));
2716 assert(DateTime(1999, 11, 1, 11, 24, 37).endOfMonth == DateTime(1999, 11, 30, 23, 59, 59));
2717 assert(DateTime(1999, 12, 1, 12, 25, 38).endOfMonth == DateTime(1999, 12, 31, 23, 59, 59));
2719 // Test B.C.
2720 assert(DateTime(-1999, 1, 1, 0, 13, 26).endOfMonth == DateTime(-1999, 1, 31, 23, 59, 59));
2721 assert(DateTime(-1999, 2, 1, 1, 14, 27).endOfMonth == DateTime(-1999, 2, 28, 23, 59, 59));
2722 assert(DateTime(-2000, 2, 1, 2, 15, 28).endOfMonth == DateTime(-2000, 2, 29, 23, 59, 59));
2723 assert(DateTime(-1999, 3, 1, 3, 16, 29).endOfMonth == DateTime(-1999, 3, 31, 23, 59, 59));
2724 assert(DateTime(-1999, 4, 1, 4, 17, 30).endOfMonth == DateTime(-1999, 4, 30, 23, 59, 59));
2725 assert(DateTime(-1999, 5, 1, 5, 18, 31).endOfMonth == DateTime(-1999, 5, 31, 23, 59, 59));
2726 assert(DateTime(-1999, 6, 1, 6, 19, 32).endOfMonth == DateTime(-1999, 6, 30, 23, 59, 59));
2727 assert(DateTime(-1999, 7, 1, 7, 20, 33).endOfMonth == DateTime(-1999, 7, 31, 23, 59, 59));
2728 assert(DateTime(-1999, 8, 1, 8, 21, 34).endOfMonth == DateTime(-1999, 8, 31, 23, 59, 59));
2729 assert(DateTime(-1999, 9, 1, 9, 22, 35).endOfMonth == DateTime(-1999, 9, 30, 23, 59, 59));
2730 assert(DateTime(-1999, 10, 1, 10, 23, 36).endOfMonth == DateTime(-1999, 10, 31, 23, 59, 59));
2731 assert(DateTime(-1999, 11, 1, 11, 24, 37).endOfMonth == DateTime(-1999, 11, 30, 23, 59, 59));
2732 assert(DateTime(-1999, 12, 1, 12, 25, 38).endOfMonth == DateTime(-1999, 12, 31, 23, 59, 59));
2734 const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2735 immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2736 assert(cdt.endOfMonth == DateTime(1999, 7, 31, 23, 59, 59));
2737 assert(idt.endOfMonth == DateTime(1999, 7, 31, 23, 59, 59));
2742 The last day in the month that this $(LREF DateTime) is in.
2744 @property ubyte daysInMonth() const @safe pure nothrow @nogc
2746 return _date.daysInMonth;
2750 @safe unittest
2752 assert(DateTime(Date(1999, 1, 6), TimeOfDay(0, 0, 0)).daysInMonth == 31);
2753 assert(DateTime(Date(1999, 2, 7), TimeOfDay(19, 30, 0)).daysInMonth == 28);
2754 assert(DateTime(Date(2000, 2, 7), TimeOfDay(5, 12, 27)).daysInMonth == 29);
2755 assert(DateTime(Date(2000, 6, 4), TimeOfDay(12, 22, 9)).daysInMonth == 30);
2758 @safe unittest
2760 const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2761 immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2762 assert(cdt.daysInMonth == 31);
2763 assert(idt.daysInMonth == 31);
2768 Whether the current year is a date in A.D.
2770 @property bool isAD() const @safe pure nothrow @nogc
2772 return _date.isAD;
2776 @safe unittest
2778 assert(DateTime(Date(1, 1, 1), TimeOfDay(12, 7, 0)).isAD);
2779 assert(DateTime(Date(2010, 12, 31), TimeOfDay(0, 0, 0)).isAD);
2780 assert(!DateTime(Date(0, 12, 31), TimeOfDay(23, 59, 59)).isAD);
2781 assert(!DateTime(Date(-2010, 1, 1), TimeOfDay(2, 2, 2)).isAD);
2784 @safe unittest
2786 const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2787 immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2788 assert(cdt.isAD);
2789 assert(idt.isAD);
2794 The $(HTTP en.wikipedia.org/wiki/Julian_day, Julian day) for this
2795 $(LREF DateTime) at the given time. For example, prior to noon,
2796 1996-03-31 would be the Julian day number 2_450_173, so this function
2797 returns 2_450_173, while from noon onward, the julian day number would
2798 be 2_450_174, so this function returns 2_450_174.
2800 @property long julianDay() const @safe pure nothrow @nogc
2802 if (_tod._hour < 12)
2803 return _date.julianDay - 1;
2804 else
2805 return _date.julianDay;
2808 @safe unittest
2810 assert(DateTime(Date(-4713, 11, 24), TimeOfDay(0, 0, 0)).julianDay == -1);
2811 assert(DateTime(Date(-4713, 11, 24), TimeOfDay(12, 0, 0)).julianDay == 0);
2813 assert(DateTime(Date(0, 12, 31), TimeOfDay(0, 0, 0)).julianDay == 1_721_424);
2814 assert(DateTime(Date(0, 12, 31), TimeOfDay(12, 0, 0)).julianDay == 1_721_425);
2816 assert(DateTime(Date(1, 1, 1), TimeOfDay(0, 0, 0)).julianDay == 1_721_425);
2817 assert(DateTime(Date(1, 1, 1), TimeOfDay(12, 0, 0)).julianDay == 1_721_426);
2819 assert(DateTime(Date(1582, 10, 15), TimeOfDay(0, 0, 0)).julianDay == 2_299_160);
2820 assert(DateTime(Date(1582, 10, 15), TimeOfDay(12, 0, 0)).julianDay == 2_299_161);
2822 assert(DateTime(Date(1858, 11, 17), TimeOfDay(0, 0, 0)).julianDay == 2_400_000);
2823 assert(DateTime(Date(1858, 11, 17), TimeOfDay(12, 0, 0)).julianDay == 2_400_001);
2825 assert(DateTime(Date(1982, 1, 4), TimeOfDay(0, 0, 0)).julianDay == 2_444_973);
2826 assert(DateTime(Date(1982, 1, 4), TimeOfDay(12, 0, 0)).julianDay == 2_444_974);
2828 assert(DateTime(Date(1996, 3, 31), TimeOfDay(0, 0, 0)).julianDay == 2_450_173);
2829 assert(DateTime(Date(1996, 3, 31), TimeOfDay(12, 0, 0)).julianDay == 2_450_174);
2831 assert(DateTime(Date(2010, 8, 24), TimeOfDay(0, 0, 0)).julianDay == 2_455_432);
2832 assert(DateTime(Date(2010, 8, 24), TimeOfDay(12, 0, 0)).julianDay == 2_455_433);
2834 const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2835 immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2836 assert(cdt.julianDay == 2_451_366);
2837 assert(idt.julianDay == 2_451_366);
2842 The modified $(HTTP en.wikipedia.org/wiki/Julian_day, Julian day) for any
2843 time on this date (since, the modified Julian day changes at midnight).
2845 @property long modJulianDay() const @safe pure nothrow @nogc
2847 return _date.modJulianDay;
2850 @safe unittest
2852 assert(DateTime(Date(1858, 11, 17), TimeOfDay(0, 0, 0)).modJulianDay == 0);
2853 assert(DateTime(Date(1858, 11, 17), TimeOfDay(12, 0, 0)).modJulianDay == 0);
2855 assert(DateTime(Date(2010, 8, 24), TimeOfDay(0, 0, 0)).modJulianDay == 55_432);
2856 assert(DateTime(Date(2010, 8, 24), TimeOfDay(12, 0, 0)).modJulianDay == 55_432);
2858 const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2859 immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
2860 assert(cdt.modJulianDay == 51_365);
2861 assert(idt.modJulianDay == 51_365);
2866 Converts this $(LREF DateTime) to a string with the format YYYYMMDDTHHMMSS.
2868 string toISOString() const @safe pure nothrow
2870 import std.format : format;
2873 return format!("%sT%02d%02d%02d")(
2874 _date.toISOString(),
2875 _tod._hour,
2876 _tod._minute,
2877 _tod._second
2880 catch (Exception e)
2882 assert(0, "format() threw.");
2887 @safe unittest
2889 assert(DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)).toISOString() ==
2890 "20100704T070612");
2892 assert(DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)).toISOString() ==
2893 "19981225T021500");
2895 assert(DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)).toISOString() ==
2896 "00000105T230959");
2898 assert(DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2)).toISOString() ==
2899 "-00040105T000002");
2902 @safe unittest
2904 // Test A.D.
2905 assert(DateTime(Date(9, 12, 4), TimeOfDay(0, 0, 0)).toISOString() == "00091204T000000");
2906 assert(DateTime(Date(99, 12, 4), TimeOfDay(5, 6, 12)).toISOString() == "00991204T050612");
2907 assert(DateTime(Date(999, 12, 4), TimeOfDay(13, 44, 59)).toISOString() == "09991204T134459");
2908 assert(DateTime(Date(9999, 7, 4), TimeOfDay(23, 59, 59)).toISOString() == "99990704T235959");
2909 assert(DateTime(Date(10000, 10, 20), TimeOfDay(1, 1, 1)).toISOString() == "+100001020T010101");
2911 // Test B.C.
2912 assert(DateTime(Date(0, 12, 4), TimeOfDay(0, 12, 4)).toISOString() == "00001204T001204");
2913 assert(DateTime(Date(-9, 12, 4), TimeOfDay(0, 0, 0)).toISOString() == "-00091204T000000");
2914 assert(DateTime(Date(-99, 12, 4), TimeOfDay(5, 6, 12)).toISOString() == "-00991204T050612");
2915 assert(DateTime(Date(-999, 12, 4), TimeOfDay(13, 44, 59)).toISOString() == "-09991204T134459");
2916 assert(DateTime(Date(-9999, 7, 4), TimeOfDay(23, 59, 59)).toISOString() == "-99990704T235959");
2917 assert(DateTime(Date(-10000, 10, 20), TimeOfDay(1, 1, 1)).toISOString() == "-100001020T010101");
2919 const cdt = DateTime(1999, 7, 6, 12, 30, 33);
2920 immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
2921 assert(cdt.toISOString() == "19990706T123033");
2922 assert(idt.toISOString() == "19990706T123033");
2927 Converts this $(LREF DateTime) to a string with the format
2928 YYYY-MM-DDTHH:MM:SS.
2930 string toISOExtString() const @safe pure nothrow
2932 import std.format : format;
2935 return format!("%sT%02d:%02d:%02d")(
2936 _date.toISOExtString(),
2937 _tod._hour,
2938 _tod._minute,
2939 _tod._second
2942 catch (Exception e)
2944 assert(0, "format() threw.");
2949 @safe unittest
2951 assert(DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)).toISOExtString() ==
2952 "2010-07-04T07:06:12");
2954 assert(DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)).toISOExtString() ==
2955 "1998-12-25T02:15:00");
2957 assert(DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)).toISOExtString() ==
2958 "0000-01-05T23:09:59");
2960 assert(DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2)).toISOExtString() ==
2961 "-0004-01-05T00:00:02");
2964 @safe unittest
2966 // Test A.D.
2967 assert(DateTime(Date(9, 12, 4), TimeOfDay(0, 0, 0)).toISOExtString() == "0009-12-04T00:00:00");
2968 assert(DateTime(Date(99, 12, 4), TimeOfDay(5, 6, 12)).toISOExtString() == "0099-12-04T05:06:12");
2969 assert(DateTime(Date(999, 12, 4), TimeOfDay(13, 44, 59)).toISOExtString() == "0999-12-04T13:44:59");
2970 assert(DateTime(Date(9999, 7, 4), TimeOfDay(23, 59, 59)).toISOExtString() == "9999-07-04T23:59:59");
2971 assert(DateTime(Date(10000, 10, 20), TimeOfDay(1, 1, 1)).toISOExtString() == "+10000-10-20T01:01:01");
2973 // Test B.C.
2974 assert(DateTime(Date(0, 12, 4), TimeOfDay(0, 12, 4)).toISOExtString() == "0000-12-04T00:12:04");
2975 assert(DateTime(Date(-9, 12, 4), TimeOfDay(0, 0, 0)).toISOExtString() == "-0009-12-04T00:00:00");
2976 assert(DateTime(Date(-99, 12, 4), TimeOfDay(5, 6, 12)).toISOExtString() == "-0099-12-04T05:06:12");
2977 assert(DateTime(Date(-999, 12, 4), TimeOfDay(13, 44, 59)).toISOExtString() == "-0999-12-04T13:44:59");
2978 assert(DateTime(Date(-9999, 7, 4), TimeOfDay(23, 59, 59)).toISOExtString() == "-9999-07-04T23:59:59");
2979 assert(DateTime(Date(-10000, 10, 20), TimeOfDay(1, 1, 1)).toISOExtString() == "-10000-10-20T01:01:01");
2981 const cdt = DateTime(1999, 7, 6, 12, 30, 33);
2982 immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
2983 assert(cdt.toISOExtString() == "1999-07-06T12:30:33");
2984 assert(idt.toISOExtString() == "1999-07-06T12:30:33");
2988 Converts this $(LREF DateTime) to a string with the format
2989 YYYY-Mon-DD HH:MM:SS.
2991 string toSimpleString() const @safe pure nothrow
2993 import std.format : format;
2996 return format!("%s %02d:%02d:%02d")(
2997 _date.toSimpleString(),
2998 _tod._hour,
2999 _tod._minute,
3000 _tod._second
3003 catch (Exception e)
3005 assert(0, "format() threw.");
3010 @safe unittest
3012 assert(DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)).toSimpleString() ==
3013 "2010-Jul-04 07:06:12");
3015 assert(DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)).toSimpleString() ==
3016 "1998-Dec-25 02:15:00");
3018 assert(DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)).toSimpleString() ==
3019 "0000-Jan-05 23:09:59");
3021 assert(DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2)).toSimpleString() ==
3022 "-0004-Jan-05 00:00:02");
3025 @safe unittest
3027 // Test A.D.
3028 assert(DateTime(Date(9, 12, 4), TimeOfDay(0, 0, 0)).toSimpleString() == "0009-Dec-04 00:00:00");
3029 assert(DateTime(Date(99, 12, 4), TimeOfDay(5, 6, 12)).toSimpleString() == "0099-Dec-04 05:06:12");
3030 assert(DateTime(Date(999, 12, 4), TimeOfDay(13, 44, 59)).toSimpleString() == "0999-Dec-04 13:44:59");
3031 assert(DateTime(Date(9999, 7, 4), TimeOfDay(23, 59, 59)).toSimpleString() == "9999-Jul-04 23:59:59");
3032 assert(DateTime(Date(10000, 10, 20), TimeOfDay(1, 1, 1)).toSimpleString() == "+10000-Oct-20 01:01:01");
3034 // Test B.C.
3035 assert(DateTime(Date(0, 12, 4), TimeOfDay(0, 12, 4)).toSimpleString() == "0000-Dec-04 00:12:04");
3036 assert(DateTime(Date(-9, 12, 4), TimeOfDay(0, 0, 0)).toSimpleString() == "-0009-Dec-04 00:00:00");
3037 assert(DateTime(Date(-99, 12, 4), TimeOfDay(5, 6, 12)).toSimpleString() == "-0099-Dec-04 05:06:12");
3038 assert(DateTime(Date(-999, 12, 4), TimeOfDay(13, 44, 59)).toSimpleString() == "-0999-Dec-04 13:44:59");
3039 assert(DateTime(Date(-9999, 7, 4), TimeOfDay(23, 59, 59)).toSimpleString() == "-9999-Jul-04 23:59:59");
3040 assert(DateTime(Date(-10000, 10, 20), TimeOfDay(1, 1, 1)).toSimpleString() == "-10000-Oct-20 01:01:01");
3042 const cdt = DateTime(1999, 7, 6, 12, 30, 33);
3043 immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
3044 assert(cdt.toSimpleString() == "1999-Jul-06 12:30:33");
3045 assert(idt.toSimpleString() == "1999-Jul-06 12:30:33");
3050 Converts this $(LREF DateTime) to a string.
3052 This function exists to make it easy to convert a $(LREF DateTime) to a
3053 string for code that does not care what the exact format is - just that
3054 it presents the information in a clear manner. It also makes it easy to
3055 simply convert a $(LREF DateTime) to a string when using functions such
3056 as `to!string`, `format`, or `writeln` which use toString to convert
3057 user-defined types. So, it is unlikely that much code will call
3058 toString directly.
3060 The format of the string is purposefully unspecified, and code that
3061 cares about the format of the string should use `toISOString`,
3062 `toISOExtString`, `toSimpleString`, or some other custom formatting
3063 function that explicitly generates the format that the code needs. The
3064 reason is that the code is then clear about what format it's using,
3065 making it less error-prone to maintain the code and interact with other
3066 software that consumes the generated strings. It's for this same reason
3067 that $(LREF DateTime) has no `fromString` function, whereas it does have
3068 `fromISOString`, `fromISOExtString`, and `fromSimpleString`.
3070 The format returned by toString may or may not change in the future.
3072 string toString() const @safe pure nothrow
3074 return toSimpleString();
3077 @safe unittest
3079 auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
3080 const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
3081 immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33));
3082 assert(dt.toString());
3083 assert(cdt.toString());
3084 assert(idt.toString());
3090 Creates a $(LREF DateTime) from a string with the format YYYYMMDDTHHMMSS.
3091 Whitespace is stripped from the given string.
3093 Params:
3094 isoString = A string formatted in the ISO format for dates and times.
3096 Throws:
3097 $(REF DateTimeException,std,datetime,date) if the given string is
3098 not in the ISO format or if the resulting $(LREF DateTime) would not
3099 be valid.
3101 static DateTime fromISOString(S)(in S isoString) @safe pure
3102 if (isSomeString!S)
3104 import std.algorithm.searching : countUntil;
3105 import std.exception : enforce;
3106 import std.format : format;
3107 import std.string : strip;
3109 auto str = strip(isoString);
3111 enforce(str.length >= 15, new DateTimeException(format("Invalid ISO String: %s", isoString)));
3112 auto t = str.countUntil('T');
3114 enforce(t != -1, new DateTimeException(format("Invalid ISO String: %s", isoString)));
3116 immutable date = Date.fromISOString(str[0 .. t]);
3117 immutable tod = TimeOfDay.fromISOString(str[t+1 .. $]);
3119 return DateTime(date, tod);
3123 @safe unittest
3125 assert(DateTime.fromISOString("20100704T070612") ==
3126 DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)));
3128 assert(DateTime.fromISOString("19981225T021500") ==
3129 DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)));
3131 assert(DateTime.fromISOString("00000105T230959") ==
3132 DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)));
3134 assert(DateTime.fromISOString("-00040105T000002") ==
3135 DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2)));
3137 assert(DateTime.fromISOString(" 20100704T070612 ") ==
3138 DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)));
3141 @safe unittest
3143 assertThrown!DateTimeException(DateTime.fromISOString(""));
3144 assertThrown!DateTimeException(DateTime.fromISOString("20100704000000"));
3145 assertThrown!DateTimeException(DateTime.fromISOString("20100704 000000"));
3146 assertThrown!DateTimeException(DateTime.fromISOString("20100704t000000"));
3147 assertThrown!DateTimeException(DateTime.fromISOString("20100704T000000."));
3148 assertThrown!DateTimeException(DateTime.fromISOString("20100704T000000.0"));
3150 assertThrown!DateTimeException(DateTime.fromISOString("2010-07-0400:00:00"));
3151 assertThrown!DateTimeException(DateTime.fromISOString("2010-07-04 00:00:00"));
3152 assertThrown!DateTimeException(DateTime.fromISOString("2010-07-04t00:00:00"));
3153 assertThrown!DateTimeException(DateTime.fromISOString("2010-07-04T00:00:00."));
3154 assertThrown!DateTimeException(DateTime.fromISOString("2010-07-04T00:00:00.0"));
3156 assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-0400:00:00"));
3157 assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04 00:00:00"));
3158 assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04t00:00:00"));
3159 assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04T00:00:00"));
3160 assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04 00:00:00."));
3161 assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04 00:00:00.0"));
3163 assertThrown!DateTimeException(DateTime.fromISOString("2010-12-22T172201"));
3164 assertThrown!DateTimeException(DateTime.fromISOString("2010-Dec-22 17:22:01"));
3166 assert(DateTime.fromISOString("20101222T172201") == DateTime(Date(2010, 12, 22), TimeOfDay(17, 22, 01)));
3167 assert(DateTime.fromISOString("19990706T123033") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
3168 assert(DateTime.fromISOString("-19990706T123033") == DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
3169 assert(DateTime.fromISOString("+019990706T123033") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
3170 assert(DateTime.fromISOString("19990706T123033 ") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
3171 assert(DateTime.fromISOString(" 19990706T123033") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
3172 assert(DateTime.fromISOString(" 19990706T123033 ") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
3175 // bug# 17801
3176 @safe unittest
3178 import std.conv : to;
3179 import std.meta : AliasSeq;
3180 foreach (C; AliasSeq!(char, wchar, dchar))
3182 foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[]))
3183 assert(DateTime.fromISOString(to!S("20121221T141516")) == DateTime(2012, 12, 21, 14, 15, 16));
3189 Creates a $(LREF DateTime) from a string with the format
3190 YYYY-MM-DDTHH:MM:SS. Whitespace is stripped from the given string.
3192 Params:
3193 isoExtString = A string formatted in the ISO Extended format for dates
3194 and times.
3196 Throws:
3197 $(REF DateTimeException,std,datetime,date) if the given string is
3198 not in the ISO Extended format or if the resulting $(LREF DateTime)
3199 would not be valid.
3201 static DateTime fromISOExtString(S)(in S isoExtString) @safe pure
3202 if (isSomeString!(S))
3204 import std.algorithm.searching : countUntil;
3205 import std.exception : enforce;
3206 import std.format : format;
3207 import std.string : strip;
3209 auto str = strip(isoExtString);
3211 enforce(str.length >= 15, new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
3212 auto t = str.countUntil('T');
3214 enforce(t != -1, new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
3216 immutable date = Date.fromISOExtString(str[0 .. t]);
3217 immutable tod = TimeOfDay.fromISOExtString(str[t+1 .. $]);
3219 return DateTime(date, tod);
3223 @safe unittest
3225 assert(DateTime.fromISOExtString("2010-07-04T07:06:12") ==
3226 DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)));
3228 assert(DateTime.fromISOExtString("1998-12-25T02:15:00") ==
3229 DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)));
3231 assert(DateTime.fromISOExtString("0000-01-05T23:09:59") ==
3232 DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)));
3234 assert(DateTime.fromISOExtString("-0004-01-05T00:00:02") ==
3235 DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2)));
3237 assert(DateTime.fromISOExtString(" 2010-07-04T07:06:12 ") ==
3238 DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)));
3241 @safe unittest
3243 assertThrown!DateTimeException(DateTime.fromISOExtString(""));
3244 assertThrown!DateTimeException(DateTime.fromISOExtString("20100704000000"));
3245 assertThrown!DateTimeException(DateTime.fromISOExtString("20100704 000000"));
3246 assertThrown!DateTimeException(DateTime.fromISOExtString("20100704t000000"));
3247 assertThrown!DateTimeException(DateTime.fromISOExtString("20100704T000000."));
3248 assertThrown!DateTimeException(DateTime.fromISOExtString("20100704T000000.0"));
3250 assertThrown!DateTimeException(DateTime.fromISOExtString("2010-07:0400:00:00"));
3251 assertThrown!DateTimeException(DateTime.fromISOExtString("2010-07-04 00:00:00"));
3252 assertThrown!DateTimeException(DateTime.fromISOExtString("2010-07-04 00:00:00"));
3253 assertThrown!DateTimeException(DateTime.fromISOExtString("2010-07-04t00:00:00"));
3254 assertThrown!DateTimeException(DateTime.fromISOExtString("2010-07-04T00:00:00."));
3255 assertThrown!DateTimeException(DateTime.fromISOExtString("2010-07-04T00:00:00.0"));
3257 assertThrown!DateTimeException(DateTime.fromISOExtString("2010-Jul-0400:00:00"));
3258 assertThrown!DateTimeException(DateTime.fromISOExtString("2010-Jul-04t00:00:00"));
3259 assertThrown!DateTimeException(DateTime.fromISOExtString("2010-Jul-04 00:00:00."));
3260 assertThrown!DateTimeException(DateTime.fromISOExtString("2010-Jul-04 00:00:00.0"));
3262 assertThrown!DateTimeException(DateTime.fromISOExtString("20101222T172201"));
3263 assertThrown!DateTimeException(DateTime.fromISOExtString("2010-Dec-22 17:22:01"));
3265 assert(DateTime.fromISOExtString("2010-12-22T17:22:01") == DateTime(Date(2010, 12, 22), TimeOfDay(17, 22, 01)));
3266 assert(DateTime.fromISOExtString("1999-07-06T12:30:33") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
3267 assert(DateTime.fromISOExtString("-1999-07-06T12:30:33") == DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
3268 assert(DateTime.fromISOExtString("+01999-07-06T12:30:33") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
3269 assert(DateTime.fromISOExtString("1999-07-06T12:30:33 ") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
3270 assert(DateTime.fromISOExtString(" 1999-07-06T12:30:33") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
3271 assert(DateTime.fromISOExtString(" 1999-07-06T12:30:33 ") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
3274 // bug# 17801
3275 @safe unittest
3277 import std.conv : to;
3278 import std.meta : AliasSeq;
3279 foreach (C; AliasSeq!(char, wchar, dchar))
3281 foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[]))
3282 assert(DateTime.fromISOExtString(to!S("2012-12-21T14:15:16")) == DateTime(2012, 12, 21, 14, 15, 16));
3288 Creates a $(LREF DateTime) from a string with the format
3289 YYYY-Mon-DD HH:MM:SS. Whitespace is stripped from the given string.
3291 Params:
3292 simpleString = A string formatted in the way that toSimpleString
3293 formats dates and times.
3295 Throws:
3296 $(REF DateTimeException,std,datetime,date) if the given string is
3297 not in the correct format or if the resulting $(LREF DateTime)
3298 would not be valid.
3300 static DateTime fromSimpleString(S)(in S simpleString) @safe pure
3301 if (isSomeString!(S))
3303 import std.algorithm.searching : countUntil;
3304 import std.exception : enforce;
3305 import std.format : format;
3306 import std.string : strip;
3308 auto str = strip(simpleString);
3310 enforce(str.length >= 15, new DateTimeException(format("Invalid string format: %s", simpleString)));
3311 auto t = str.countUntil(' ');
3313 enforce(t != -1, new DateTimeException(format("Invalid string format: %s", simpleString)));
3315 immutable date = Date.fromSimpleString(str[0 .. t]);
3316 immutable tod = TimeOfDay.fromISOExtString(str[t+1 .. $]);
3318 return DateTime(date, tod);
3322 @safe unittest
3324 assert(DateTime.fromSimpleString("2010-Jul-04 07:06:12") ==
3325 DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)));
3326 assert(DateTime.fromSimpleString("1998-Dec-25 02:15:00") ==
3327 DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)));
3328 assert(DateTime.fromSimpleString("0000-Jan-05 23:09:59") ==
3329 DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)));
3330 assert(DateTime.fromSimpleString("-0004-Jan-05 00:00:02") ==
3331 DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2)));
3332 assert(DateTime.fromSimpleString(" 2010-Jul-04 07:06:12 ") ==
3333 DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)));
3336 @safe unittest
3338 assertThrown!DateTimeException(DateTime.fromISOString(""));
3339 assertThrown!DateTimeException(DateTime.fromISOString("20100704000000"));
3340 assertThrown!DateTimeException(DateTime.fromISOString("20100704 000000"));
3341 assertThrown!DateTimeException(DateTime.fromISOString("20100704t000000"));
3342 assertThrown!DateTimeException(DateTime.fromISOString("20100704T000000."));
3343 assertThrown!DateTimeException(DateTime.fromISOString("20100704T000000.0"));
3345 assertThrown!DateTimeException(DateTime.fromISOString("2010-07-0400:00:00"));
3346 assertThrown!DateTimeException(DateTime.fromISOString("2010-07-04 00:00:00"));
3347 assertThrown!DateTimeException(DateTime.fromISOString("2010-07-04t00:00:00"));
3348 assertThrown!DateTimeException(DateTime.fromISOString("2010-07-04T00:00:00."));
3349 assertThrown!DateTimeException(DateTime.fromISOString("2010-07-04T00:00:00.0"));
3351 assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-0400:00:00"));
3352 assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04 00:00:00"));
3353 assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04t00:00:00"));
3354 assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04T00:00:00"));
3355 assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04 00:00:00."));
3356 assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04 00:00:00.0"));
3358 assertThrown!DateTimeException(DateTime.fromSimpleString("20101222T172201"));
3359 assertThrown!DateTimeException(DateTime.fromSimpleString("2010-12-22T172201"));
3361 assert(DateTime.fromSimpleString("2010-Dec-22 17:22:01") ==
3362 DateTime(Date(2010, 12, 22), TimeOfDay(17, 22, 01)));
3363 assert(DateTime.fromSimpleString("1999-Jul-06 12:30:33") ==
3364 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
3365 assert(DateTime.fromSimpleString("-1999-Jul-06 12:30:33") ==
3366 DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)));
3367 assert(DateTime.fromSimpleString("+01999-Jul-06 12:30:33") ==
3368 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
3369 assert(DateTime.fromSimpleString("1999-Jul-06 12:30:33 ") ==
3370 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
3371 assert(DateTime.fromSimpleString(" 1999-Jul-06 12:30:33") ==
3372 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
3373 assert(DateTime.fromSimpleString(" 1999-Jul-06 12:30:33 ") ==
3374 DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)));
3377 // bug# 17801
3378 @safe unittest
3380 import std.conv : to;
3381 import std.meta : AliasSeq;
3382 foreach (C; AliasSeq!(char, wchar, dchar))
3384 foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[]))
3385 assert(DateTime.fromSimpleString(to!S("2012-Dec-21 14:15:16")) == DateTime(2012, 12, 21, 14, 15, 16));
3391 Returns the $(LREF DateTime) farthest in the past which is representable
3392 by $(LREF DateTime).
3394 @property static DateTime min() @safe pure nothrow @nogc
3395 out(result)
3397 assert(result._date == Date.min);
3398 assert(result._tod == TimeOfDay.min);
3400 body
3402 auto dt = DateTime.init;
3403 dt._date._year = short.min;
3404 dt._date._month = Month.jan;
3405 dt._date._day = 1;
3407 return dt;
3410 @safe unittest
3412 assert(DateTime.min.year < 0);
3413 assert(DateTime.min < DateTime.max);
3418 Returns the $(LREF DateTime) farthest in the future which is
3419 representable by $(LREF DateTime).
3421 @property static DateTime max() @safe pure nothrow @nogc
3422 out(result)
3424 assert(result._date == Date.max);
3425 assert(result._tod == TimeOfDay.max);
3427 body
3429 auto dt = DateTime.init;
3430 dt._date._year = short.max;
3431 dt._date._month = Month.dec;
3432 dt._date._day = 31;
3433 dt._tod._hour = TimeOfDay.maxHour;
3434 dt._tod._minute = TimeOfDay.maxMinute;
3435 dt._tod._second = TimeOfDay.maxSecond;
3437 return dt;
3440 @safe unittest
3442 assert(DateTime.max.year > 0);
3443 assert(DateTime.max > DateTime.min);
3447 private:
3450 Add seconds to the time of day. Negative values will subtract. If the
3451 number of seconds overflows (or underflows), then the seconds will wrap,
3452 increasing (or decreasing) the number of minutes accordingly. The
3453 same goes for any larger units.
3455 Params:
3456 seconds = The number of seconds to add to this $(LREF DateTime).
3458 ref DateTime _addSeconds(long seconds) return @safe pure nothrow @nogc
3460 long hnsecs = convert!("seconds", "hnsecs")(seconds);
3461 hnsecs += convert!("hours", "hnsecs")(_tod._hour);
3462 hnsecs += convert!("minutes", "hnsecs")(_tod._minute);
3463 hnsecs += convert!("seconds", "hnsecs")(_tod._second);
3465 auto days = splitUnitsFromHNSecs!"days"(hnsecs);
3467 if (hnsecs < 0)
3469 hnsecs += convert!("days", "hnsecs")(1);
3470 --days;
3473 _date._addDays(days);
3475 immutable newHours = splitUnitsFromHNSecs!"hours"(hnsecs);
3476 immutable newMinutes = splitUnitsFromHNSecs!"minutes"(hnsecs);
3477 immutable newSeconds = splitUnitsFromHNSecs!"seconds"(hnsecs);
3479 _tod._hour = cast(ubyte) newHours;
3480 _tod._minute = cast(ubyte) newMinutes;
3481 _tod._second = cast(ubyte) newSeconds;
3483 return this;
3486 @safe unittest
3488 static void testDT(DateTime orig, int seconds, in DateTime expected, size_t line = __LINE__)
3490 orig._addSeconds(seconds);
3491 assert(orig == expected);
3494 // Test A.D.
3495 testDT(DateTime(1999, 7, 6, 12, 30, 33), 0, DateTime(1999, 7, 6, 12, 30, 33));
3496 testDT(DateTime(1999, 7, 6, 12, 30, 33), 1, DateTime(1999, 7, 6, 12, 30, 34));
3497 testDT(DateTime(1999, 7, 6, 12, 30, 33), 2, DateTime(1999, 7, 6, 12, 30, 35));
3498 testDT(DateTime(1999, 7, 6, 12, 30, 33), 3, DateTime(1999, 7, 6, 12, 30, 36));
3499 testDT(DateTime(1999, 7, 6, 12, 30, 33), 4, DateTime(1999, 7, 6, 12, 30, 37));
3500 testDT(DateTime(1999, 7, 6, 12, 30, 33), 5, DateTime(1999, 7, 6, 12, 30, 38));
3501 testDT(DateTime(1999, 7, 6, 12, 30, 33), 10, DateTime(1999, 7, 6, 12, 30, 43));
3502 testDT(DateTime(1999, 7, 6, 12, 30, 33), 15, DateTime(1999, 7, 6, 12, 30, 48));
3503 testDT(DateTime(1999, 7, 6, 12, 30, 33), 26, DateTime(1999, 7, 6, 12, 30, 59));
3504 testDT(DateTime(1999, 7, 6, 12, 30, 33), 27, DateTime(1999, 7, 6, 12, 31, 0));
3505 testDT(DateTime(1999, 7, 6, 12, 30, 33), 30, DateTime(1999, 7, 6, 12, 31, 3));
3506 testDT(DateTime(1999, 7, 6, 12, 30, 33), 59, DateTime(1999, 7, 6, 12, 31, 32));
3507 testDT(DateTime(1999, 7, 6, 12, 30, 33), 60, DateTime(1999, 7, 6, 12, 31, 33));
3508 testDT(DateTime(1999, 7, 6, 12, 30, 33), 61, DateTime(1999, 7, 6, 12, 31, 34));
3510 testDT(DateTime(1999, 7, 6, 12, 30, 33), 1766, DateTime(1999, 7, 6, 12, 59, 59));
3511 testDT(DateTime(1999, 7, 6, 12, 30, 33), 1767, DateTime(1999, 7, 6, 13, 0, 0));
3512 testDT(DateTime(1999, 7, 6, 12, 30, 33), 1768, DateTime(1999, 7, 6, 13, 0, 1));
3513 testDT(DateTime(1999, 7, 6, 12, 30, 33), 2007, DateTime(1999, 7, 6, 13, 4, 0));
3514 testDT(DateTime(1999, 7, 6, 12, 30, 33), 3599, DateTime(1999, 7, 6, 13, 30, 32));
3515 testDT(DateTime(1999, 7, 6, 12, 30, 33), 3600, DateTime(1999, 7, 6, 13, 30, 33));
3516 testDT(DateTime(1999, 7, 6, 12, 30, 33), 3601, DateTime(1999, 7, 6, 13, 30, 34));
3517 testDT(DateTime(1999, 7, 6, 12, 30, 33), 7200, DateTime(1999, 7, 6, 14, 30, 33));
3518 testDT(DateTime(1999, 7, 6, 23, 0, 0), 432_123, DateTime(1999, 7, 11, 23, 2, 3));
3520 testDT(DateTime(1999, 7, 6, 12, 30, 33), -1, DateTime(1999, 7, 6, 12, 30, 32));
3521 testDT(DateTime(1999, 7, 6, 12, 30, 33), -2, DateTime(1999, 7, 6, 12, 30, 31));
3522 testDT(DateTime(1999, 7, 6, 12, 30, 33), -3, DateTime(1999, 7, 6, 12, 30, 30));
3523 testDT(DateTime(1999, 7, 6, 12, 30, 33), -4, DateTime(1999, 7, 6, 12, 30, 29));
3524 testDT(DateTime(1999, 7, 6, 12, 30, 33), -5, DateTime(1999, 7, 6, 12, 30, 28));
3525 testDT(DateTime(1999, 7, 6, 12, 30, 33), -10, DateTime(1999, 7, 6, 12, 30, 23));
3526 testDT(DateTime(1999, 7, 6, 12, 30, 33), -15, DateTime(1999, 7, 6, 12, 30, 18));
3527 testDT(DateTime(1999, 7, 6, 12, 30, 33), -33, DateTime(1999, 7, 6, 12, 30, 0));
3528 testDT(DateTime(1999, 7, 6, 12, 30, 33), -34, DateTime(1999, 7, 6, 12, 29, 59));
3529 testDT(DateTime(1999, 7, 6, 12, 30, 33), -35, DateTime(1999, 7, 6, 12, 29, 58));
3530 testDT(DateTime(1999, 7, 6, 12, 30, 33), -59, DateTime(1999, 7, 6, 12, 29, 34));
3531 testDT(DateTime(1999, 7, 6, 12, 30, 33), -60, DateTime(1999, 7, 6, 12, 29, 33));
3532 testDT(DateTime(1999, 7, 6, 12, 30, 33), -61, DateTime(1999, 7, 6, 12, 29, 32));
3534 testDT(DateTime(1999, 7, 6, 12, 30, 33), -1833, DateTime(1999, 7, 6, 12, 0, 0));
3535 testDT(DateTime(1999, 7, 6, 12, 30, 33), -1834, DateTime(1999, 7, 6, 11, 59, 59));
3536 testDT(DateTime(1999, 7, 6, 12, 30, 33), -3600, DateTime(1999, 7, 6, 11, 30, 33));
3537 testDT(DateTime(1999, 7, 6, 12, 30, 33), -3601, DateTime(1999, 7, 6, 11, 30, 32));
3538 testDT(DateTime(1999, 7, 6, 12, 30, 33), -5134, DateTime(1999, 7, 6, 11, 4, 59));
3539 testDT(DateTime(1999, 7, 6, 23, 0, 0), -432_123, DateTime(1999, 7, 1, 22, 57, 57));
3541 testDT(DateTime(1999, 7, 6, 12, 30, 0), 1, DateTime(1999, 7, 6, 12, 30, 1));
3542 testDT(DateTime(1999, 7, 6, 12, 30, 0), 0, DateTime(1999, 7, 6, 12, 30, 0));
3543 testDT(DateTime(1999, 7, 6, 12, 30, 0), -1, DateTime(1999, 7, 6, 12, 29, 59));
3545 testDT(DateTime(1999, 7, 6, 12, 0, 0), 1, DateTime(1999, 7, 6, 12, 0, 1));
3546 testDT(DateTime(1999, 7, 6, 12, 0, 0), 0, DateTime(1999, 7, 6, 12, 0, 0));
3547 testDT(DateTime(1999, 7, 6, 12, 0, 0), -1, DateTime(1999, 7, 6, 11, 59, 59));
3549 testDT(DateTime(1999, 7, 6, 0, 0, 0), 1, DateTime(1999, 7, 6, 0, 0, 1));
3550 testDT(DateTime(1999, 7, 6, 0, 0, 0), 0, DateTime(1999, 7, 6, 0, 0, 0));
3551 testDT(DateTime(1999, 7, 6, 0, 0, 0), -1, DateTime(1999, 7, 5, 23, 59, 59));
3553 testDT(DateTime(1999, 7, 5, 23, 59, 59), 1, DateTime(1999, 7, 6, 0, 0, 0));
3554 testDT(DateTime(1999, 7, 5, 23, 59, 59), 0, DateTime(1999, 7, 5, 23, 59, 59));
3555 testDT(DateTime(1999, 7, 5, 23, 59, 59), -1, DateTime(1999, 7, 5, 23, 59, 58));
3557 testDT(DateTime(1998, 12, 31, 23, 59, 59), 1, DateTime(1999, 1, 1, 0, 0, 0));
3558 testDT(DateTime(1998, 12, 31, 23, 59, 59), 0, DateTime(1998, 12, 31, 23, 59, 59));
3559 testDT(DateTime(1998, 12, 31, 23, 59, 59), -1, DateTime(1998, 12, 31, 23, 59, 58));
3561 testDT(DateTime(1998, 1, 1, 0, 0, 0), 1, DateTime(1998, 1, 1, 0, 0, 1));
3562 testDT(DateTime(1998, 1, 1, 0, 0, 0), 0, DateTime(1998, 1, 1, 0, 0, 0));
3563 testDT(DateTime(1998, 1, 1, 0, 0, 0), -1, DateTime(1997, 12, 31, 23, 59, 59));
3565 // Test B.C.
3566 testDT(DateTime(-1999, 7, 6, 12, 30, 33), 0, DateTime(-1999, 7, 6, 12, 30, 33));
3567 testDT(DateTime(-1999, 7, 6, 12, 30, 33), 1, DateTime(-1999, 7, 6, 12, 30, 34));
3568 testDT(DateTime(-1999, 7, 6, 12, 30, 33), 2, DateTime(-1999, 7, 6, 12, 30, 35));
3569 testDT(DateTime(-1999, 7, 6, 12, 30, 33), 3, DateTime(-1999, 7, 6, 12, 30, 36));
3570 testDT(DateTime(-1999, 7, 6, 12, 30, 33), 4, DateTime(-1999, 7, 6, 12, 30, 37));
3571 testDT(DateTime(-1999, 7, 6, 12, 30, 33), 5, DateTime(-1999, 7, 6, 12, 30, 38));
3572 testDT(DateTime(-1999, 7, 6, 12, 30, 33), 10, DateTime(-1999, 7, 6, 12, 30, 43));
3573 testDT(DateTime(-1999, 7, 6, 12, 30, 33), 15, DateTime(-1999, 7, 6, 12, 30, 48));
3574 testDT(DateTime(-1999, 7, 6, 12, 30, 33), 26, DateTime(-1999, 7, 6, 12, 30, 59));
3575 testDT(DateTime(-1999, 7, 6, 12, 30, 33), 27, DateTime(-1999, 7, 6, 12, 31, 0));
3576 testDT(DateTime(-1999, 7, 6, 12, 30, 33), 30, DateTime(-1999, 7, 6, 12, 31, 3));
3577 testDT(DateTime(-1999, 7, 6, 12, 30, 33), 59, DateTime(-1999, 7, 6, 12, 31, 32));
3578 testDT(DateTime(-1999, 7, 6, 12, 30, 33), 60, DateTime(-1999, 7, 6, 12, 31, 33));
3579 testDT(DateTime(-1999, 7, 6, 12, 30, 33), 61, DateTime(-1999, 7, 6, 12, 31, 34));
3581 testDT(DateTime(-1999, 7, 6, 12, 30, 33), 1766, DateTime(-1999, 7, 6, 12, 59, 59));
3582 testDT(DateTime(-1999, 7, 6, 12, 30, 33), 1767, DateTime(-1999, 7, 6, 13, 0, 0));
3583 testDT(DateTime(-1999, 7, 6, 12, 30, 33), 1768, DateTime(-1999, 7, 6, 13, 0, 1));
3584 testDT(DateTime(-1999, 7, 6, 12, 30, 33), 2007, DateTime(-1999, 7, 6, 13, 4, 0));
3585 testDT(DateTime(-1999, 7, 6, 12, 30, 33), 3599, DateTime(-1999, 7, 6, 13, 30, 32));
3586 testDT(DateTime(-1999, 7, 6, 12, 30, 33), 3600, DateTime(-1999, 7, 6, 13, 30, 33));
3587 testDT(DateTime(-1999, 7, 6, 12, 30, 33), 3601, DateTime(-1999, 7, 6, 13, 30, 34));
3588 testDT(DateTime(-1999, 7, 6, 12, 30, 33), 7200, DateTime(-1999, 7, 6, 14, 30, 33));
3589 testDT(DateTime(-1999, 7, 6, 23, 0, 0), 432_123, DateTime(-1999, 7, 11, 23, 2, 3));
3591 testDT(DateTime(-1999, 7, 6, 12, 30, 33), -1, DateTime(-1999, 7, 6, 12, 30, 32));
3592 testDT(DateTime(-1999, 7, 6, 12, 30, 33), -2, DateTime(-1999, 7, 6, 12, 30, 31));
3593 testDT(DateTime(-1999, 7, 6, 12, 30, 33), -3, DateTime(-1999, 7, 6, 12, 30, 30));
3594 testDT(DateTime(-1999, 7, 6, 12, 30, 33), -4, DateTime(-1999, 7, 6, 12, 30, 29));
3595 testDT(DateTime(-1999, 7, 6, 12, 30, 33), -5, DateTime(-1999, 7, 6, 12, 30, 28));
3596 testDT(DateTime(-1999, 7, 6, 12, 30, 33), -10, DateTime(-1999, 7, 6, 12, 30, 23));
3597 testDT(DateTime(-1999, 7, 6, 12, 30, 33), -15, DateTime(-1999, 7, 6, 12, 30, 18));
3598 testDT(DateTime(-1999, 7, 6, 12, 30, 33), -33, DateTime(-1999, 7, 6, 12, 30, 0));
3599 testDT(DateTime(-1999, 7, 6, 12, 30, 33), -34, DateTime(-1999, 7, 6, 12, 29, 59));
3600 testDT(DateTime(-1999, 7, 6, 12, 30, 33), -35, DateTime(-1999, 7, 6, 12, 29, 58));
3601 testDT(DateTime(-1999, 7, 6, 12, 30, 33), -59, DateTime(-1999, 7, 6, 12, 29, 34));
3602 testDT(DateTime(-1999, 7, 6, 12, 30, 33), -60, DateTime(-1999, 7, 6, 12, 29, 33));
3603 testDT(DateTime(-1999, 7, 6, 12, 30, 33), -61, DateTime(-1999, 7, 6, 12, 29, 32));
3605 testDT(DateTime(-1999, 7, 6, 12, 30, 33), -1833, DateTime(-1999, 7, 6, 12, 0, 0));
3606 testDT(DateTime(-1999, 7, 6, 12, 30, 33), -1834, DateTime(-1999, 7, 6, 11, 59, 59));
3607 testDT(DateTime(-1999, 7, 6, 12, 30, 33), -3600, DateTime(-1999, 7, 6, 11, 30, 33));
3608 testDT(DateTime(-1999, 7, 6, 12, 30, 33), -3601, DateTime(-1999, 7, 6, 11, 30, 32));
3609 testDT(DateTime(-1999, 7, 6, 12, 30, 33), -5134, DateTime(-1999, 7, 6, 11, 4, 59));
3610 testDT(DateTime(-1999, 7, 6, 12, 30, 33), -7200, DateTime(-1999, 7, 6, 10, 30, 33));
3611 testDT(DateTime(-1999, 7, 6, 23, 0, 0), -432_123, DateTime(-1999, 7, 1, 22, 57, 57));
3613 testDT(DateTime(-1999, 7, 6, 12, 30, 0), 1, DateTime(-1999, 7, 6, 12, 30, 1));
3614 testDT(DateTime(-1999, 7, 6, 12, 30, 0), 0, DateTime(-1999, 7, 6, 12, 30, 0));
3615 testDT(DateTime(-1999, 7, 6, 12, 30, 0), -1, DateTime(-1999, 7, 6, 12, 29, 59));
3617 testDT(DateTime(-1999, 7, 6, 12, 0, 0), 1, DateTime(-1999, 7, 6, 12, 0, 1));
3618 testDT(DateTime(-1999, 7, 6, 12, 0, 0), 0, DateTime(-1999, 7, 6, 12, 0, 0));
3619 testDT(DateTime(-1999, 7, 6, 12, 0, 0), -1, DateTime(-1999, 7, 6, 11, 59, 59));
3621 testDT(DateTime(-1999, 7, 6, 0, 0, 0), 1, DateTime(-1999, 7, 6, 0, 0, 1));
3622 testDT(DateTime(-1999, 7, 6, 0, 0, 0), 0, DateTime(-1999, 7, 6, 0, 0, 0));
3623 testDT(DateTime(-1999, 7, 6, 0, 0, 0), -1, DateTime(-1999, 7, 5, 23, 59, 59));
3625 testDT(DateTime(-1999, 7, 5, 23, 59, 59), 1, DateTime(-1999, 7, 6, 0, 0, 0));
3626 testDT(DateTime(-1999, 7, 5, 23, 59, 59), 0, DateTime(-1999, 7, 5, 23, 59, 59));
3627 testDT(DateTime(-1999, 7, 5, 23, 59, 59), -1, DateTime(-1999, 7, 5, 23, 59, 58));
3629 testDT(DateTime(-2000, 12, 31, 23, 59, 59), 1, DateTime(-1999, 1, 1, 0, 0, 0));
3630 testDT(DateTime(-2000, 12, 31, 23, 59, 59), 0, DateTime(-2000, 12, 31, 23, 59, 59));
3631 testDT(DateTime(-2000, 12, 31, 23, 59, 59), -1, DateTime(-2000, 12, 31, 23, 59, 58));
3633 testDT(DateTime(-2000, 1, 1, 0, 0, 0), 1, DateTime(-2000, 1, 1, 0, 0, 1));
3634 testDT(DateTime(-2000, 1, 1, 0, 0, 0), 0, DateTime(-2000, 1, 1, 0, 0, 0));
3635 testDT(DateTime(-2000, 1, 1, 0, 0, 0), -1, DateTime(-2001, 12, 31, 23, 59, 59));
3637 // Test Both
3638 testDT(DateTime(1, 1, 1, 0, 0, 0), -1, DateTime(0, 12, 31, 23, 59, 59));
3639 testDT(DateTime(0, 12, 31, 23, 59, 59), 1, DateTime(1, 1, 1, 0, 0, 0));
3641 testDT(DateTime(0, 1, 1, 0, 0, 0), -1, DateTime(-1, 12, 31, 23, 59, 59));
3642 testDT(DateTime(-1, 12, 31, 23, 59, 59), 1, DateTime(0, 1, 1, 0, 0, 0));
3644 testDT(DateTime(-1, 1, 1, 11, 30, 33), 63_165_600L, DateTime(1, 1, 1, 13, 30, 33));
3645 testDT(DateTime(1, 1, 1, 13, 30, 33), -63_165_600L, DateTime(-1, 1, 1, 11, 30, 33));
3647 testDT(DateTime(-1, 1, 1, 11, 30, 33), 63_165_617L, DateTime(1, 1, 1, 13, 30, 50));
3648 testDT(DateTime(1, 1, 1, 13, 30, 50), -63_165_617L, DateTime(-1, 1, 1, 11, 30, 33));
3650 const cdt = DateTime(1999, 7, 6, 12, 30, 33);
3651 immutable idt = DateTime(1999, 7, 6, 12, 30, 33);
3652 static assert(!__traits(compiles, cdt._addSeconds(4)));
3653 static assert(!__traits(compiles, idt._addSeconds(4)));
3657 Date _date;
3658 TimeOfDay _tod;
3663 Represents a date in the
3664 $(HTTP en.wikipedia.org/wiki/Proleptic_Gregorian_calendar, Proleptic
3665 Gregorian Calendar) ranging from 32,768 B.C. to 32,767 A.D. Positive years
3666 are A.D. Non-positive years are B.C.
3668 Year, month, and day are kept separately internally so that $(D Date) is
3669 optimized for calendar-based operations.
3671 $(D Date) uses the Proleptic Gregorian Calendar, so it assumes the Gregorian
3672 leap year calculations for its entire length. As per
3673 $(HTTP en.wikipedia.org/wiki/ISO_8601, ISO 8601), it treats 1 B.C. as
3674 year 0, i.e. 1 B.C. is 0, 2 B.C. is -1, etc. Use $(LREF yearBC) to use B.C.
3675 as a positive integer with 1 B.C. being the year prior to 1 A.D.
3677 Year 0 is a leap year.
3679 struct Date
3681 public:
3684 Throws:
3685 $(REF DateTimeException,std,datetime,date) if the resulting
3686 $(LREF Date) would not be valid.
3688 Params:
3689 year = Year of the Gregorian Calendar. Positive values are A.D.
3690 Non-positive values are B.C. with year 0 being the year
3691 prior to 1 A.D.
3692 month = Month of the year (January is 1).
3693 day = Day of the month.
3695 this(int year, int month, int day) @safe pure
3697 enforceValid!"months"(cast(Month) month);
3698 enforceValid!"days"(year, cast(Month) month, day);
3700 _year = cast(short) year;
3701 _month = cast(Month) month;
3702 _day = cast(ubyte) day;
3705 @safe unittest
3707 import std.exception : assertNotThrown;
3708 assert(Date(1, 1, 1) == Date.init);
3710 static void testDate(in Date date, int year, int month, int day)
3712 assert(date._year == year);
3713 assert(date._month == month);
3714 assert(date._day == day);
3717 testDate(Date(1999, 1 , 1), 1999, Month.jan, 1);
3718 testDate(Date(1999, 7 , 1), 1999, Month.jul, 1);
3719 testDate(Date(1999, 7 , 6), 1999, Month.jul, 6);
3721 // Test A.D.
3722 assertThrown!DateTimeException(Date(1, 0, 1));
3723 assertThrown!DateTimeException(Date(1, 1, 0));
3724 assertThrown!DateTimeException(Date(1999, 13, 1));
3725 assertThrown!DateTimeException(Date(1999, 1, 32));
3726 assertThrown!DateTimeException(Date(1999, 2, 29));
3727 assertThrown!DateTimeException(Date(2000, 2, 30));
3728 assertThrown!DateTimeException(Date(1999, 3, 32));
3729 assertThrown!DateTimeException(Date(1999, 4, 31));
3730 assertThrown!DateTimeException(Date(1999, 5, 32));
3731 assertThrown!DateTimeException(Date(1999, 6, 31));
3732 assertThrown!DateTimeException(Date(1999, 7, 32));
3733 assertThrown!DateTimeException(Date(1999, 8, 32));
3734 assertThrown!DateTimeException(Date(1999, 9, 31));
3735 assertThrown!DateTimeException(Date(1999, 10, 32));
3736 assertThrown!DateTimeException(Date(1999, 11, 31));
3737 assertThrown!DateTimeException(Date(1999, 12, 32));
3739 assertNotThrown!DateTimeException(Date(1999, 1, 31));
3740 assertNotThrown!DateTimeException(Date(1999, 2, 28));
3741 assertNotThrown!DateTimeException(Date(2000, 2, 29));
3742 assertNotThrown!DateTimeException(Date(1999, 3, 31));
3743 assertNotThrown!DateTimeException(Date(1999, 4, 30));
3744 assertNotThrown!DateTimeException(Date(1999, 5, 31));
3745 assertNotThrown!DateTimeException(Date(1999, 6, 30));
3746 assertNotThrown!DateTimeException(Date(1999, 7, 31));
3747 assertNotThrown!DateTimeException(Date(1999, 8, 31));
3748 assertNotThrown!DateTimeException(Date(1999, 9, 30));
3749 assertNotThrown!DateTimeException(Date(1999, 10, 31));
3750 assertNotThrown!DateTimeException(Date(1999, 11, 30));
3751 assertNotThrown!DateTimeException(Date(1999, 12, 31));
3753 // Test B.C.
3754 assertNotThrown!DateTimeException(Date(0, 1, 1));
3755 assertNotThrown!DateTimeException(Date(-1, 1, 1));
3756 assertNotThrown!DateTimeException(Date(-1, 12, 31));
3757 assertNotThrown!DateTimeException(Date(-1, 2, 28));
3758 assertNotThrown!DateTimeException(Date(-4, 2, 29));
3760 assertThrown!DateTimeException(Date(-1, 2, 29));
3761 assertThrown!DateTimeException(Date(-2, 2, 29));
3762 assertThrown!DateTimeException(Date(-3, 2, 29));
3767 Params:
3768 day = The Xth day of the Gregorian Calendar that the constructed
3769 $(LREF Date) will be for.
3771 this(int day) @safe pure nothrow @nogc
3773 if (day > 0)
3775 int years = (day / daysIn400Years) * 400 + 1;
3776 day %= daysIn400Years;
3779 immutable tempYears = day / daysIn100Years;
3781 if (tempYears == 4)
3783 years += 300;
3784 day -= daysIn100Years * 3;
3786 else
3788 years += tempYears * 100;
3789 day %= daysIn100Years;
3793 years += (day / daysIn4Years) * 4;
3794 day %= daysIn4Years;
3797 immutable tempYears = day / daysInYear;
3799 if (tempYears == 4)
3801 years += 3;
3802 day -= daysInYear * 3;
3804 else
3806 years += tempYears;
3807 day %= daysInYear;
3811 if (day == 0)
3813 _year = cast(short)(years - 1);
3814 _month = Month.dec;
3815 _day = 31;
3817 else
3819 _year = cast(short) years;
3821 setDayOfYear(day);
3824 else if (day <= 0 && -day < daysInLeapYear)
3826 _year = 0;
3828 setDayOfYear(daysInLeapYear + day);
3830 else
3832 day += daysInLeapYear - 1;
3833 int years = (day / daysIn400Years) * 400 - 1;
3834 day %= daysIn400Years;
3837 immutable tempYears = day / daysIn100Years;
3839 if (tempYears == -4)
3841 years -= 300;
3842 day += daysIn100Years * 3;
3844 else
3846 years += tempYears * 100;
3847 day %= daysIn100Years;
3851 years += (day / daysIn4Years) * 4;
3852 day %= daysIn4Years;
3855 immutable tempYears = day / daysInYear;
3857 if (tempYears == -4)
3859 years -= 3;
3860 day += daysInYear * 3;
3862 else
3864 years += tempYears;
3865 day %= daysInYear;
3869 if (day == 0)
3871 _year = cast(short)(years + 1);
3872 _month = Month.jan;
3873 _day = 1;
3875 else
3877 _year = cast(short) years;
3878 immutable newDoY = (yearIsLeapYear(_year) ? daysInLeapYear : daysInYear) + day + 1;
3880 setDayOfYear(newDoY);
3885 @safe unittest
3887 import std.range : chain;
3889 // Test A.D.
3890 foreach (gd; chain(testGregDaysBC, testGregDaysAD))
3891 assert(Date(gd.day) == gd.date);
3896 Compares this $(LREF Date) with the given $(LREF Date).
3898 Returns:
3899 $(BOOKTABLE,
3900 $(TR $(TD this &lt; rhs) $(TD &lt; 0))
3901 $(TR $(TD this == rhs) $(TD 0))
3902 $(TR $(TD this &gt; rhs) $(TD &gt; 0))
3905 int opCmp(in Date rhs) const @safe pure nothrow @nogc
3907 if (_year < rhs._year)
3908 return -1;
3909 if (_year > rhs._year)
3910 return 1;
3912 if (_month < rhs._month)
3913 return -1;
3914 if (_month > rhs._month)
3915 return 1;
3917 if (_day < rhs._day)
3918 return -1;
3919 if (_day > rhs._day)
3920 return 1;
3922 return 0;
3925 @safe unittest
3927 // Test A.D.
3928 assert(Date(1, 1, 1).opCmp(Date.init) == 0);
3930 assert(Date(1999, 1, 1).opCmp(Date(1999, 1, 1)) == 0);
3931 assert(Date(1, 7, 1).opCmp(Date(1, 7, 1)) == 0);
3932 assert(Date(1, 1, 6).opCmp(Date(1, 1, 6)) == 0);
3934 assert(Date(1999, 7, 1).opCmp(Date(1999, 7, 1)) == 0);
3935 assert(Date(1999, 7, 6).opCmp(Date(1999, 7, 6)) == 0);
3937 assert(Date(1, 7, 6).opCmp(Date(1, 7, 6)) == 0);
3939 assert(Date(1999, 7, 6).opCmp(Date(2000, 7, 6)) < 0);
3940 assert(Date(2000, 7, 6).opCmp(Date(1999, 7, 6)) > 0);
3941 assert(Date(1999, 7, 6).opCmp(Date(1999, 8, 6)) < 0);
3942 assert(Date(1999, 8, 6).opCmp(Date(1999, 7, 6)) > 0);
3943 assert(Date(1999, 7, 6).opCmp(Date(1999, 7, 7)) < 0);
3944 assert(Date(1999, 7, 7).opCmp(Date(1999, 7, 6)) > 0);
3946 assert(Date(1999, 8, 7).opCmp(Date(2000, 7, 6)) < 0);
3947 assert(Date(2000, 8, 6).opCmp(Date(1999, 7, 7)) > 0);
3948 assert(Date(1999, 7, 7).opCmp(Date(2000, 7, 6)) < 0);
3949 assert(Date(2000, 7, 6).opCmp(Date(1999, 7, 7)) > 0);
3950 assert(Date(1999, 7, 7).opCmp(Date(1999, 8, 6)) < 0);
3951 assert(Date(1999, 8, 6).opCmp(Date(1999, 7, 7)) > 0);
3953 // Test B.C.
3954 assert(Date(0, 1, 1).opCmp(Date(0, 1, 1)) == 0);
3955 assert(Date(-1, 1, 1).opCmp(Date(-1, 1, 1)) == 0);
3956 assert(Date(-1, 7, 1).opCmp(Date(-1, 7, 1)) == 0);
3957 assert(Date(-1, 1, 6).opCmp(Date(-1, 1, 6)) == 0);
3959 assert(Date(-1999, 7, 1).opCmp(Date(-1999, 7, 1)) == 0);
3960 assert(Date(-1999, 7, 6).opCmp(Date(-1999, 7, 6)) == 0);
3962 assert(Date(-1, 7, 6).opCmp(Date(-1, 7, 6)) == 0);
3964 assert(Date(-2000, 7, 6).opCmp(Date(-1999, 7, 6)) < 0);
3965 assert(Date(-1999, 7, 6).opCmp(Date(-2000, 7, 6)) > 0);
3966 assert(Date(-1999, 7, 6).opCmp(Date(-1999, 8, 6)) < 0);
3967 assert(Date(-1999, 8, 6).opCmp(Date(-1999, 7, 6)) > 0);
3968 assert(Date(-1999, 7, 6).opCmp(Date(-1999, 7, 7)) < 0);
3969 assert(Date(-1999, 7, 7).opCmp(Date(-1999, 7, 6)) > 0);
3971 assert(Date(-2000, 8, 6).opCmp(Date(-1999, 7, 7)) < 0);
3972 assert(Date(-1999, 8, 7).opCmp(Date(-2000, 7, 6)) > 0);
3973 assert(Date(-2000, 7, 6).opCmp(Date(-1999, 7, 7)) < 0);
3974 assert(Date(-1999, 7, 7).opCmp(Date(-2000, 7, 6)) > 0);
3975 assert(Date(-1999, 7, 7).opCmp(Date(-1999, 8, 6)) < 0);
3976 assert(Date(-1999, 8, 6).opCmp(Date(-1999, 7, 7)) > 0);
3978 // Test Both
3979 assert(Date(-1999, 7, 6).opCmp(Date(1999, 7, 6)) < 0);
3980 assert(Date(1999, 7, 6).opCmp(Date(-1999, 7, 6)) > 0);
3982 assert(Date(-1999, 8, 6).opCmp(Date(1999, 7, 6)) < 0);
3983 assert(Date(1999, 7, 6).opCmp(Date(-1999, 8, 6)) > 0);
3985 assert(Date(-1999, 7, 7).opCmp(Date(1999, 7, 6)) < 0);
3986 assert(Date(1999, 7, 6).opCmp(Date(-1999, 7, 7)) > 0);
3988 assert(Date(-1999, 8, 7).opCmp(Date(1999, 7, 6)) < 0);
3989 assert(Date(1999, 7, 6).opCmp(Date(-1999, 8, 7)) > 0);
3991 assert(Date(-1999, 8, 6).opCmp(Date(1999, 6, 6)) < 0);
3992 assert(Date(1999, 6, 8).opCmp(Date(-1999, 7, 6)) > 0);
3994 auto date = Date(1999, 7, 6);
3995 const cdate = Date(1999, 7, 6);
3996 immutable idate = Date(1999, 7, 6);
3997 assert(date.opCmp(date) == 0);
3998 assert(date.opCmp(cdate) == 0);
3999 assert(date.opCmp(idate) == 0);
4000 assert(cdate.opCmp(date) == 0);
4001 assert(cdate.opCmp(cdate) == 0);
4002 assert(cdate.opCmp(idate) == 0);
4003 assert(idate.opCmp(date) == 0);
4004 assert(idate.opCmp(cdate) == 0);
4005 assert(idate.opCmp(idate) == 0);
4010 Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive
4011 are B.C.
4013 @property short year() const @safe pure nothrow @nogc
4015 return _year;
4019 @safe unittest
4021 assert(Date(1999, 7, 6).year == 1999);
4022 assert(Date(2010, 10, 4).year == 2010);
4023 assert(Date(-7, 4, 5).year == -7);
4026 @safe unittest
4028 assert(Date.init.year == 1);
4029 assert(Date(1999, 7, 6).year == 1999);
4030 assert(Date(-1999, 7, 6).year == -1999);
4032 const cdate = Date(1999, 7, 6);
4033 immutable idate = Date(1999, 7, 6);
4034 assert(cdate.year == 1999);
4035 assert(idate.year == 1999);
4039 Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive
4040 are B.C.
4042 Params:
4043 year = The year to set this Date's year to.
4045 Throws:
4046 $(REF DateTimeException,std,datetime,date) if the new year is not
4047 a leap year and the resulting date would be on February 29th.
4049 @property void year(int year) @safe pure
4051 enforceValid!"days"(year, _month, _day);
4052 _year = cast(short) year;
4056 @safe unittest
4058 assert(Date(1999, 7, 6).year == 1999);
4059 assert(Date(2010, 10, 4).year == 2010);
4060 assert(Date(-7, 4, 5).year == -7);
4063 @safe unittest
4065 static void testDateInvalid(Date date, int year)
4067 date.year = year;
4070 static void testDate(Date date, int year, in Date expected)
4072 date.year = year;
4073 assert(date == expected);
4076 assertThrown!DateTimeException(testDateInvalid(Date(4, 2, 29), 1));
4078 testDate(Date(1, 1, 1), 1999, Date(1999, 1, 1));
4079 testDate(Date(1, 1, 1), 0, Date(0, 1, 1));
4080 testDate(Date(1, 1, 1), -1999, Date(-1999, 1, 1));
4082 const cdate = Date(1999, 7, 6);
4083 immutable idate = Date(1999, 7, 6);
4084 static assert(!__traits(compiles, cdate.year = 1999));
4085 static assert(!__traits(compiles, idate.year = 1999));
4090 Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C.
4092 Throws:
4093 $(REF DateTimeException,std,datetime,date) if $(D isAD) is true.
4095 @property ushort yearBC() const @safe pure
4097 import std.format : format;
4099 if (isAD)
4100 throw new DateTimeException(format("Year %s is A.D.", _year));
4101 return cast(ushort)((_year * -1) + 1);
4105 @safe unittest
4107 assert(Date(0, 1, 1).yearBC == 1);
4108 assert(Date(-1, 1, 1).yearBC == 2);
4109 assert(Date(-100, 1, 1).yearBC == 101);
4112 @safe unittest
4114 assertThrown!DateTimeException((in Date date){date.yearBC;}(Date(1, 1, 1)));
4116 auto date = Date(0, 7, 6);
4117 const cdate = Date(0, 7, 6);
4118 immutable idate = Date(0, 7, 6);
4119 assert(date.yearBC == 1);
4120 assert(cdate.yearBC == 1);
4121 assert(idate.yearBC == 1);
4126 Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C.
4128 Params:
4129 year = The year B.C. to set this $(LREF Date)'s year to.
4131 Throws:
4132 $(REF DateTimeException,std,datetime,date) if a non-positive value
4133 is given.
4135 @property void yearBC(int year) @safe pure
4137 if (year <= 0)
4138 throw new DateTimeException("The given year is not a year B.C.");
4139 _year = cast(short)((year - 1) * -1);
4143 @safe unittest
4145 auto date = Date(2010, 1, 1);
4146 date.yearBC = 1;
4147 assert(date == Date(0, 1, 1));
4149 date.yearBC = 10;
4150 assert(date == Date(-9, 1, 1));
4153 @safe unittest
4155 assertThrown!DateTimeException((Date date){date.yearBC = -1;}(Date(1, 1, 1)));
4157 auto date = Date(0, 7, 6);
4158 const cdate = Date(0, 7, 6);
4159 immutable idate = Date(0, 7, 6);
4160 date.yearBC = 7;
4161 assert(date.yearBC == 7);
4162 static assert(!__traits(compiles, cdate.yearBC = 7));
4163 static assert(!__traits(compiles, idate.yearBC = 7));
4168 Month of a Gregorian Year.
4170 @property Month month() const @safe pure nothrow @nogc
4172 return _month;
4176 @safe unittest
4178 assert(Date(1999, 7, 6).month == 7);
4179 assert(Date(2010, 10, 4).month == 10);
4180 assert(Date(-7, 4, 5).month == 4);
4183 @safe unittest
4185 assert(Date.init.month == 1);
4186 assert(Date(1999, 7, 6).month == 7);
4187 assert(Date(-1999, 7, 6).month == 7);
4189 const cdate = Date(1999, 7, 6);
4190 immutable idate = Date(1999, 7, 6);
4191 assert(cdate.month == 7);
4192 assert(idate.month == 7);
4196 Month of a Gregorian Year.
4198 Params:
4199 month = The month to set this $(LREF Date)'s month to.
4201 Throws:
4202 $(REF DateTimeException,std,datetime,date) if the given month is
4203 not a valid month or if the current day would not be valid in the
4204 given month.
4206 @property void month(Month month) @safe pure
4208 enforceValid!"months"(month);
4209 enforceValid!"days"(_year, month, _day);
4210 _month = cast(Month) month;
4213 @safe unittest
4215 static void testDate(Date date, Month month, in Date expected = Date.init)
4217 date.month = month;
4218 assert(expected != Date.init);
4219 assert(date == expected);
4222 assertThrown!DateTimeException(testDate(Date(1, 1, 1), cast(Month) 0));
4223 assertThrown!DateTimeException(testDate(Date(1, 1, 1), cast(Month) 13));
4224 assertThrown!DateTimeException(testDate(Date(1, 1, 29), cast(Month) 2));
4225 assertThrown!DateTimeException(testDate(Date(0, 1, 30), cast(Month) 2));
4227 testDate(Date(1, 1, 1), cast(Month) 7, Date(1, 7, 1));
4228 testDate(Date(-1, 1, 1), cast(Month) 7, Date(-1, 7, 1));
4230 const cdate = Date(1999, 7, 6);
4231 immutable idate = Date(1999, 7, 6);
4232 static assert(!__traits(compiles, cdate.month = 7));
4233 static assert(!__traits(compiles, idate.month = 7));
4238 Day of a Gregorian Month.
4240 @property ubyte day() const @safe pure nothrow @nogc
4242 return _day;
4246 @safe unittest
4248 assert(Date(1999, 7, 6).day == 6);
4249 assert(Date(2010, 10, 4).day == 4);
4250 assert(Date(-7, 4, 5).day == 5);
4253 @safe unittest
4255 import std.format : format;
4256 import std.range : chain;
4258 static void test(Date date, int expected)
4260 assert(date.day == expected, format("Value given: %s", date));
4263 foreach (year; chain(testYearsBC, testYearsAD))
4265 foreach (md; testMonthDays)
4266 test(Date(year, md.month, md.day), md.day);
4269 const cdate = Date(1999, 7, 6);
4270 immutable idate = Date(1999, 7, 6);
4271 assert(cdate.day == 6);
4272 assert(idate.day == 6);
4276 Day of a Gregorian Month.
4278 Params:
4279 day = The day of the month to set this $(LREF Date)'s day to.
4281 Throws:
4282 $(REF DateTimeException,std,datetime,date) if the given day is not
4283 a valid day of the current month.
4285 @property void day(int day) @safe pure
4287 enforceValid!"days"(_year, _month, day);
4288 _day = cast(ubyte) day;
4291 @safe unittest
4293 import std.exception : assertNotThrown;
4295 static void testDate(Date date, int day)
4297 date.day = day;
4300 // Test A.D.
4301 assertThrown!DateTimeException(testDate(Date(1, 1, 1), 0));
4302 assertThrown!DateTimeException(testDate(Date(1, 1, 1), 32));
4303 assertThrown!DateTimeException(testDate(Date(1, 2, 1), 29));
4304 assertThrown!DateTimeException(testDate(Date(4, 2, 1), 30));
4305 assertThrown!DateTimeException(testDate(Date(1, 3, 1), 32));
4306 assertThrown!DateTimeException(testDate(Date(1, 4, 1), 31));
4307 assertThrown!DateTimeException(testDate(Date(1, 5, 1), 32));
4308 assertThrown!DateTimeException(testDate(Date(1, 6, 1), 31));
4309 assertThrown!DateTimeException(testDate(Date(1, 7, 1), 32));
4310 assertThrown!DateTimeException(testDate(Date(1, 8, 1), 32));
4311 assertThrown!DateTimeException(testDate(Date(1, 9, 1), 31));
4312 assertThrown!DateTimeException(testDate(Date(1, 10, 1), 32));
4313 assertThrown!DateTimeException(testDate(Date(1, 11, 1), 31));
4314 assertThrown!DateTimeException(testDate(Date(1, 12, 1), 32));
4316 assertNotThrown!DateTimeException(testDate(Date(1, 1, 1), 31));
4317 assertNotThrown!DateTimeException(testDate(Date(1, 2, 1), 28));
4318 assertNotThrown!DateTimeException(testDate(Date(4, 2, 1), 29));
4319 assertNotThrown!DateTimeException(testDate(Date(1, 3, 1), 31));
4320 assertNotThrown!DateTimeException(testDate(Date(1, 4, 1), 30));
4321 assertNotThrown!DateTimeException(testDate(Date(1, 5, 1), 31));
4322 assertNotThrown!DateTimeException(testDate(Date(1, 6, 1), 30));
4323 assertNotThrown!DateTimeException(testDate(Date(1, 7, 1), 31));
4324 assertNotThrown!DateTimeException(testDate(Date(1, 8, 1), 31));
4325 assertNotThrown!DateTimeException(testDate(Date(1, 9, 1), 30));
4326 assertNotThrown!DateTimeException(testDate(Date(1, 10, 1), 31));
4327 assertNotThrown!DateTimeException(testDate(Date(1, 11, 1), 30));
4328 assertNotThrown!DateTimeException(testDate(Date(1, 12, 1), 31));
4331 auto date = Date(1, 1, 1);
4332 date.day = 6;
4333 assert(date == Date(1, 1, 6));
4336 // Test B.C.
4337 assertThrown!DateTimeException(testDate(Date(-1, 1, 1), 0));
4338 assertThrown!DateTimeException(testDate(Date(-1, 1, 1), 32));
4339 assertThrown!DateTimeException(testDate(Date(-1, 2, 1), 29));
4340 assertThrown!DateTimeException(testDate(Date(0, 2, 1), 30));
4341 assertThrown!DateTimeException(testDate(Date(-1, 3, 1), 32));
4342 assertThrown!DateTimeException(testDate(Date(-1, 4, 1), 31));
4343 assertThrown!DateTimeException(testDate(Date(-1, 5, 1), 32));
4344 assertThrown!DateTimeException(testDate(Date(-1, 6, 1), 31));
4345 assertThrown!DateTimeException(testDate(Date(-1, 7, 1), 32));
4346 assertThrown!DateTimeException(testDate(Date(-1, 8, 1), 32));
4347 assertThrown!DateTimeException(testDate(Date(-1, 9, 1), 31));
4348 assertThrown!DateTimeException(testDate(Date(-1, 10, 1), 32));
4349 assertThrown!DateTimeException(testDate(Date(-1, 11, 1), 31));
4350 assertThrown!DateTimeException(testDate(Date(-1, 12, 1), 32));
4352 assertNotThrown!DateTimeException(testDate(Date(-1, 1, 1), 31));
4353 assertNotThrown!DateTimeException(testDate(Date(-1, 2, 1), 28));
4354 assertNotThrown!DateTimeException(testDate(Date(0, 2, 1), 29));
4355 assertNotThrown!DateTimeException(testDate(Date(-1, 3, 1), 31));
4356 assertNotThrown!DateTimeException(testDate(Date(-1, 4, 1), 30));
4357 assertNotThrown!DateTimeException(testDate(Date(-1, 5, 1), 31));
4358 assertNotThrown!DateTimeException(testDate(Date(-1, 6, 1), 30));
4359 assertNotThrown!DateTimeException(testDate(Date(-1, 7, 1), 31));
4360 assertNotThrown!DateTimeException(testDate(Date(-1, 8, 1), 31));
4361 assertNotThrown!DateTimeException(testDate(Date(-1, 9, 1), 30));
4362 assertNotThrown!DateTimeException(testDate(Date(-1, 10, 1), 31));
4363 assertNotThrown!DateTimeException(testDate(Date(-1, 11, 1), 30));
4364 assertNotThrown!DateTimeException(testDate(Date(-1, 12, 1), 31));
4367 auto date = Date(-1, 1, 1);
4368 date.day = 6;
4369 assert(date == Date(-1, 1, 6));
4372 const cdate = Date(1999, 7, 6);
4373 immutable idate = Date(1999, 7, 6);
4374 static assert(!__traits(compiles, cdate.day = 6));
4375 static assert(!__traits(compiles, idate.day = 6));
4380 Adds the given number of years or months to this $(LREF Date). A
4381 negative number will subtract.
4383 Note that if day overflow is allowed, and the date with the adjusted
4384 year/month overflows the number of days in the new month, then the month
4385 will be incremented by one, and the day set to the number of days
4386 overflowed. (e.g. if the day were 31 and the new month were June, then
4387 the month would be incremented to July, and the new day would be 1). If
4388 day overflow is not allowed, then the day will be set to the last valid
4389 day in the month (e.g. June 31st would become June 30th).
4391 Params:
4392 units = The type of units to add ("years" or "months").
4393 value = The number of months or years to add to this
4394 $(LREF Date).
4395 allowOverflow = Whether the day should be allowed to overflow,
4396 causing the month to increment.
4398 @safe pure nothrow @nogc
4399 ref Date add(string units)(long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes)
4400 if (units == "years")
4402 _year += value;
4404 if (_month == Month.feb && _day == 29 && !yearIsLeapYear(_year))
4406 if (allowOverflow == AllowDayOverflow.yes)
4408 _month = Month.mar;
4409 _day = 1;
4411 else
4412 _day = 28;
4415 return this;
4419 @safe unittest
4421 auto d1 = Date(2010, 1, 1);
4422 d1.add!"months"(11);
4423 assert(d1 == Date(2010, 12, 1));
4425 auto d2 = Date(2010, 1, 1);
4426 d2.add!"months"(-11);
4427 assert(d2 == Date(2009, 2, 1));
4429 auto d3 = Date(2000, 2, 29);
4430 d3.add!"years"(1);
4431 assert(d3 == Date(2001, 3, 1));
4433 auto d4 = Date(2000, 2, 29);
4434 d4.add!"years"(1, AllowDayOverflow.no);
4435 assert(d4 == Date(2001, 2, 28));
4438 // Test add!"years"() with AllowDayOverflow.yes
4439 @safe unittest
4441 // Test A.D.
4443 auto date = Date(1999, 7, 6);
4444 date.add!"years"(7);
4445 assert(date == Date(2006, 7, 6));
4446 date.add!"years"(-9);
4447 assert(date == Date(1997, 7, 6));
4451 auto date = Date(1999, 2, 28);
4452 date.add!"years"(1);
4453 assert(date == Date(2000, 2, 28));
4457 auto date = Date(2000, 2, 29);
4458 date.add!"years"(-1);
4459 assert(date == Date(1999, 3, 1));
4462 // Test B.C.
4464 auto date = Date(-1999, 7, 6);
4465 date.add!"years"(-7);
4466 assert(date == Date(-2006, 7, 6));
4467 date.add!"years"(9);
4468 assert(date == Date(-1997, 7, 6));
4472 auto date = Date(-1999, 2, 28);
4473 date.add!"years"(-1);
4474 assert(date == Date(-2000, 2, 28));
4478 auto date = Date(-2000, 2, 29);
4479 date.add!"years"(1);
4480 assert(date == Date(-1999, 3, 1));
4483 // Test Both
4485 auto date = Date(4, 7, 6);
4486 date.add!"years"(-5);
4487 assert(date == Date(-1, 7, 6));
4488 date.add!"years"(5);
4489 assert(date == Date(4, 7, 6));
4493 auto date = Date(-4, 7, 6);
4494 date.add!"years"(5);
4495 assert(date == Date(1, 7, 6));
4496 date.add!"years"(-5);
4497 assert(date == Date(-4, 7, 6));
4501 auto date = Date(4, 7, 6);
4502 date.add!"years"(-8);
4503 assert(date == Date(-4, 7, 6));
4504 date.add!"years"(8);
4505 assert(date == Date(4, 7, 6));
4509 auto date = Date(-4, 7, 6);
4510 date.add!"years"(8);
4511 assert(date == Date(4, 7, 6));
4512 date.add!"years"(-8);
4513 assert(date == Date(-4, 7, 6));
4517 auto date = Date(-4, 2, 29);
4518 date.add!"years"(5);
4519 assert(date == Date(1, 3, 1));
4523 auto date = Date(4, 2, 29);
4524 date.add!"years"(-5);
4525 assert(date == Date(-1, 3, 1));
4529 auto date = Date(4, 2, 29);
4530 date.add!"years"(-5).add!"years"(7);
4531 assert(date == Date(6, 3, 1));
4534 const cdate = Date(1999, 7, 6);
4535 immutable idate = Date(1999, 7, 6);
4536 static assert(!__traits(compiles, cdate.add!"years"(7)));
4537 static assert(!__traits(compiles, idate.add!"years"(7)));
4540 // Test add!"years"() with AllowDayOverflow.no
4541 @safe unittest
4543 // Test A.D.
4545 auto date = Date(1999, 7, 6);
4546 date.add!"years"(7, AllowDayOverflow.no);
4547 assert(date == Date(2006, 7, 6));
4548 date.add!"years"(-9, AllowDayOverflow.no);
4549 assert(date == Date(1997, 7, 6));
4553 auto date = Date(1999, 2, 28);
4554 date.add!"years"(1, AllowDayOverflow.no);
4555 assert(date == Date(2000, 2, 28));
4559 auto date = Date(2000, 2, 29);
4560 date.add!"years"(-1, AllowDayOverflow.no);
4561 assert(date == Date(1999, 2, 28));
4564 // Test B.C.
4566 auto date = Date(-1999, 7, 6);
4567 date.add!"years"(-7, AllowDayOverflow.no);
4568 assert(date == Date(-2006, 7, 6));
4569 date.add!"years"(9, AllowDayOverflow.no);
4570 assert(date == Date(-1997, 7, 6));
4574 auto date = Date(-1999, 2, 28);
4575 date.add!"years"(-1, AllowDayOverflow.no);
4576 assert(date == Date(-2000, 2, 28));
4580 auto date = Date(-2000, 2, 29);
4581 date.add!"years"(1, AllowDayOverflow.no);
4582 assert(date == Date(-1999, 2, 28));
4585 // Test Both
4587 auto date = Date(4, 7, 6);
4588 date.add!"years"(-5, AllowDayOverflow.no);
4589 assert(date == Date(-1, 7, 6));
4590 date.add!"years"(5, AllowDayOverflow.no);
4591 assert(date == Date(4, 7, 6));
4595 auto date = Date(-4, 7, 6);
4596 date.add!"years"(5, AllowDayOverflow.no);
4597 assert(date == Date(1, 7, 6));
4598 date.add!"years"(-5, AllowDayOverflow.no);
4599 assert(date == Date(-4, 7, 6));
4603 auto date = Date(4, 7, 6);
4604 date.add!"years"(-8, AllowDayOverflow.no);
4605 assert(date == Date(-4, 7, 6));
4606 date.add!"years"(8, AllowDayOverflow.no);
4607 assert(date == Date(4, 7, 6));
4611 auto date = Date(-4, 7, 6);
4612 date.add!"years"(8, AllowDayOverflow.no);
4613 assert(date == Date(4, 7, 6));
4614 date.add!"years"(-8, AllowDayOverflow.no);
4615 assert(date == Date(-4, 7, 6));
4619 auto date = Date(-4, 2, 29);
4620 date.add!"years"(5, AllowDayOverflow.no);
4621 assert(date == Date(1, 2, 28));
4625 auto date = Date(4, 2, 29);
4626 date.add!"years"(-5, AllowDayOverflow.no);
4627 assert(date == Date(-1, 2, 28));
4631 auto date = Date(4, 2, 29);
4632 date.add!"years"(-5, AllowDayOverflow.no).add!"years"(7, AllowDayOverflow.no);
4633 assert(date == Date(6, 2, 28));
4638 // Shares documentation with "years" version.
4639 @safe pure nothrow @nogc
4640 ref Date add(string units)(long months, AllowDayOverflow allowOverflow = AllowDayOverflow.yes)
4641 if (units == "months")
4643 auto years = months / 12;
4644 months %= 12;
4645 auto newMonth = _month + months;
4647 if (months < 0)
4649 if (newMonth < 1)
4651 newMonth += 12;
4652 --years;
4655 else if (newMonth > 12)
4657 newMonth -= 12;
4658 ++years;
4661 _year += years;
4662 _month = cast(Month) newMonth;
4664 immutable currMaxDay = maxDay(_year, _month);
4665 immutable overflow = _day - currMaxDay;
4667 if (overflow > 0)
4669 if (allowOverflow == AllowDayOverflow.yes)
4671 ++_month;
4672 _day = cast(ubyte) overflow;
4674 else
4675 _day = cast(ubyte) currMaxDay;
4678 return this;
4681 // Test add!"months"() with AllowDayOverflow.yes
4682 @safe unittest
4684 // Test A.D.
4686 auto date = Date(1999, 7, 6);
4687 date.add!"months"(3);
4688 assert(date == Date(1999, 10, 6));
4689 date.add!"months"(-4);
4690 assert(date == Date(1999, 6, 6));
4694 auto date = Date(1999, 7, 6);
4695 date.add!"months"(6);
4696 assert(date == Date(2000, 1, 6));
4697 date.add!"months"(-6);
4698 assert(date == Date(1999, 7, 6));
4702 auto date = Date(1999, 7, 6);
4703 date.add!"months"(27);
4704 assert(date == Date(2001, 10, 6));
4705 date.add!"months"(-28);
4706 assert(date == Date(1999, 6, 6));
4710 auto date = Date(1999, 5, 31);
4711 date.add!"months"(1);
4712 assert(date == Date(1999, 7, 1));
4716 auto date = Date(1999, 5, 31);
4717 date.add!"months"(-1);
4718 assert(date == Date(1999, 5, 1));
4722 auto date = Date(1999, 2, 28);
4723 date.add!"months"(12);
4724 assert(date == Date(2000, 2, 28));
4728 auto date = Date(2000, 2, 29);
4729 date.add!"months"(12);
4730 assert(date == Date(2001, 3, 1));
4734 auto date = Date(1999, 7, 31);
4735 date.add!"months"(1);
4736 assert(date == Date(1999, 8, 31));
4737 date.add!"months"(1);
4738 assert(date == Date(1999, 10, 1));
4742 auto date = Date(1998, 8, 31);
4743 date.add!"months"(13);
4744 assert(date == Date(1999, 10, 1));
4745 date.add!"months"(-13);
4746 assert(date == Date(1998, 9, 1));
4750 auto date = Date(1997, 12, 31);
4751 date.add!"months"(13);
4752 assert(date == Date(1999, 1, 31));
4753 date.add!"months"(-13);
4754 assert(date == Date(1997, 12, 31));
4758 auto date = Date(1997, 12, 31);
4759 date.add!"months"(14);
4760 assert(date == Date(1999, 3, 3));
4761 date.add!"months"(-14);
4762 assert(date == Date(1998, 1, 3));
4766 auto date = Date(1998, 12, 31);
4767 date.add!"months"(14);
4768 assert(date == Date(2000, 3, 2));
4769 date.add!"months"(-14);
4770 assert(date == Date(1999, 1, 2));
4774 auto date = Date(1999, 12, 31);
4775 date.add!"months"(14);
4776 assert(date == Date(2001, 3, 3));
4777 date.add!"months"(-14);
4778 assert(date == Date(2000, 1, 3));
4781 // Test B.C.
4783 auto date = Date(-1999, 7, 6);
4784 date.add!"months"(3);
4785 assert(date == Date(-1999, 10, 6));
4786 date.add!"months"(-4);
4787 assert(date == Date(-1999, 6, 6));
4791 auto date = Date(-1999, 7, 6);
4792 date.add!"months"(6);
4793 assert(date == Date(-1998, 1, 6));
4794 date.add!"months"(-6);
4795 assert(date == Date(-1999, 7, 6));
4799 auto date = Date(-1999, 7, 6);
4800 date.add!"months"(-27);
4801 assert(date == Date(-2001, 4, 6));
4802 date.add!"months"(28);
4803 assert(date == Date(-1999, 8, 6));
4807 auto date = Date(-1999, 5, 31);
4808 date.add!"months"(1);
4809 assert(date == Date(-1999, 7, 1));
4813 auto date = Date(-1999, 5, 31);
4814 date.add!"months"(-1);
4815 assert(date == Date(-1999, 5, 1));
4819 auto date = Date(-1999, 2, 28);
4820 date.add!"months"(-12);
4821 assert(date == Date(-2000, 2, 28));
4825 auto date = Date(-2000, 2, 29);
4826 date.add!"months"(-12);
4827 assert(date == Date(-2001, 3, 1));
4831 auto date = Date(-1999, 7, 31);
4832 date.add!"months"(1);
4833 assert(date == Date(-1999, 8, 31));
4834 date.add!"months"(1);
4835 assert(date == Date(-1999, 10, 1));
4839 auto date = Date(-1998, 8, 31);
4840 date.add!"months"(13);
4841 assert(date == Date(-1997, 10, 1));
4842 date.add!"months"(-13);
4843 assert(date == Date(-1998, 9, 1));
4847 auto date = Date(-1997, 12, 31);
4848 date.add!"months"(13);
4849 assert(date == Date(-1995, 1, 31));
4850 date.add!"months"(-13);
4851 assert(date == Date(-1997, 12, 31));
4855 auto date = Date(-1997, 12, 31);
4856 date.add!"months"(14);
4857 assert(date == Date(-1995, 3, 3));
4858 date.add!"months"(-14);
4859 assert(date == Date(-1996, 1, 3));
4863 auto date = Date(-2002, 12, 31);
4864 date.add!"months"(14);
4865 assert(date == Date(-2000, 3, 2));
4866 date.add!"months"(-14);
4867 assert(date == Date(-2001, 1, 2));
4871 auto date = Date(-2001, 12, 31);
4872 date.add!"months"(14);
4873 assert(date == Date(-1999, 3, 3));
4874 date.add!"months"(-14);
4875 assert(date == Date(-2000, 1, 3));
4878 // Test Both
4880 auto date = Date(1, 1, 1);
4881 date.add!"months"(-1);
4882 assert(date == Date(0, 12, 1));
4883 date.add!"months"(1);
4884 assert(date == Date(1, 1, 1));
4888 auto date = Date(4, 1, 1);
4889 date.add!"months"(-48);
4890 assert(date == Date(0, 1, 1));
4891 date.add!"months"(48);
4892 assert(date == Date(4, 1, 1));
4896 auto date = Date(4, 3, 31);
4897 date.add!"months"(-49);
4898 assert(date == Date(0, 3, 2));
4899 date.add!"months"(49);
4900 assert(date == Date(4, 4, 2));
4904 auto date = Date(4, 3, 31);
4905 date.add!"months"(-85);
4906 assert(date == Date(-3, 3, 3));
4907 date.add!"months"(85);
4908 assert(date == Date(4, 4, 3));
4912 auto date = Date(-3, 3, 31);
4913 date.add!"months"(85).add!"months"(-83);
4914 assert(date == Date(-3, 6, 1));
4917 const cdate = Date(1999, 7, 6);
4918 immutable idate = Date(1999, 7, 6);
4919 static assert(!__traits(compiles, cdate.add!"months"(3)));
4920 static assert(!__traits(compiles, idate.add!"months"(3)));
4923 // Test add!"months"() with AllowDayOverflow.no
4924 @safe unittest
4926 // Test A.D.
4928 auto date = Date(1999, 7, 6);
4929 date.add!"months"(3, AllowDayOverflow.no);
4930 assert(date == Date(1999, 10, 6));
4931 date.add!"months"(-4, AllowDayOverflow.no);
4932 assert(date == Date(1999, 6, 6));
4936 auto date = Date(1999, 7, 6);
4937 date.add!"months"(6, AllowDayOverflow.no);
4938 assert(date == Date(2000, 1, 6));
4939 date.add!"months"(-6, AllowDayOverflow.no);
4940 assert(date == Date(1999, 7, 6));
4944 auto date = Date(1999, 7, 6);
4945 date.add!"months"(27, AllowDayOverflow.no);
4946 assert(date == Date(2001, 10, 6));
4947 date.add!"months"(-28, AllowDayOverflow.no);
4948 assert(date == Date(1999, 6, 6));
4952 auto date = Date(1999, 5, 31);
4953 date.add!"months"(1, AllowDayOverflow.no);
4954 assert(date == Date(1999, 6, 30));
4958 auto date = Date(1999, 5, 31);
4959 date.add!"months"(-1, AllowDayOverflow.no);
4960 assert(date == Date(1999, 4, 30));
4964 auto date = Date(1999, 2, 28);
4965 date.add!"months"(12, AllowDayOverflow.no);
4966 assert(date == Date(2000, 2, 28));
4970 auto date = Date(2000, 2, 29);
4971 date.add!"months"(12, AllowDayOverflow.no);
4972 assert(date == Date(2001, 2, 28));
4976 auto date = Date(1999, 7, 31);
4977 date.add!"months"(1, AllowDayOverflow.no);
4978 assert(date == Date(1999, 8, 31));
4979 date.add!"months"(1, AllowDayOverflow.no);
4980 assert(date == Date(1999, 9, 30));
4984 auto date = Date(1998, 8, 31);
4985 date.add!"months"(13, AllowDayOverflow.no);
4986 assert(date == Date(1999, 9, 30));
4987 date.add!"months"(-13, AllowDayOverflow.no);
4988 assert(date == Date(1998, 8, 30));
4992 auto date = Date(1997, 12, 31);
4993 date.add!"months"(13, AllowDayOverflow.no);
4994 assert(date == Date(1999, 1, 31));
4995 date.add!"months"(-13, AllowDayOverflow.no);
4996 assert(date == Date(1997, 12, 31));
5000 auto date = Date(1997, 12, 31);
5001 date.add!"months"(14, AllowDayOverflow.no);
5002 assert(date == Date(1999, 2, 28));
5003 date.add!"months"(-14, AllowDayOverflow.no);
5004 assert(date == Date(1997, 12, 28));
5008 auto date = Date(1998, 12, 31);
5009 date.add!"months"(14, AllowDayOverflow.no);
5010 assert(date == Date(2000, 2, 29));
5011 date.add!"months"(-14, AllowDayOverflow.no);
5012 assert(date == Date(1998, 12, 29));
5016 auto date = Date(1999, 12, 31);
5017 date.add!"months"(14, AllowDayOverflow.no);
5018 assert(date == Date(2001, 2, 28));
5019 date.add!"months"(-14, AllowDayOverflow.no);
5020 assert(date == Date(1999, 12, 28));
5023 // Test B.C.
5025 auto date = Date(-1999, 7, 6);
5026 date.add!"months"(3, AllowDayOverflow.no);
5027 assert(date == Date(-1999, 10, 6));
5028 date.add!"months"(-4, AllowDayOverflow.no);
5029 assert(date == Date(-1999, 6, 6));
5033 auto date = Date(-1999, 7, 6);
5034 date.add!"months"(6, AllowDayOverflow.no);
5035 assert(date == Date(-1998, 1, 6));
5036 date.add!"months"(-6, AllowDayOverflow.no);
5037 assert(date == Date(-1999, 7, 6));
5041 auto date = Date(-1999, 7, 6);
5042 date.add!"months"(-27, AllowDayOverflow.no);
5043 assert(date == Date(-2001, 4, 6));
5044 date.add!"months"(28, AllowDayOverflow.no);
5045 assert(date == Date(-1999, 8, 6));
5049 auto date = Date(-1999, 5, 31);
5050 date.add!"months"(1, AllowDayOverflow.no);
5051 assert(date == Date(-1999, 6, 30));
5055 auto date = Date(-1999, 5, 31);
5056 date.add!"months"(-1, AllowDayOverflow.no);
5057 assert(date == Date(-1999, 4, 30));
5061 auto date = Date(-1999, 2, 28);
5062 date.add!"months"(-12, AllowDayOverflow.no);
5063 assert(date == Date(-2000, 2, 28));
5067 auto date = Date(-2000, 2, 29);
5068 date.add!"months"(-12, AllowDayOverflow.no);
5069 assert(date == Date(-2001, 2, 28));
5073 auto date = Date(-1999, 7, 31);
5074 date.add!"months"(1, AllowDayOverflow.no);
5075 assert(date == Date(-1999, 8, 31));
5076 date.add!"months"(1, AllowDayOverflow.no);
5077 assert(date == Date(-1999, 9, 30));
5081 auto date = Date(-1998, 8, 31);
5082 date.add!"months"(13, AllowDayOverflow.no);
5083 assert(date == Date(-1997, 9, 30));
5084 date.add!"months"(-13, AllowDayOverflow.no);
5085 assert(date == Date(-1998, 8, 30));
5089 auto date = Date(-1997, 12, 31);
5090 date.add!"months"(13, AllowDayOverflow.no);
5091 assert(date == Date(-1995, 1, 31));
5092 date.add!"months"(-13, AllowDayOverflow.no);
5093 assert(date == Date(-1997, 12, 31));
5097 auto date = Date(-1997, 12, 31);
5098 date.add!"months"(14, AllowDayOverflow.no);
5099 assert(date == Date(-1995, 2, 28));
5100 date.add!"months"(-14, AllowDayOverflow.no);
5101 assert(date == Date(-1997, 12, 28));
5105 auto date = Date(-2002, 12, 31);
5106 date.add!"months"(14, AllowDayOverflow.no);
5107 assert(date == Date(-2000, 2, 29));
5108 date.add!"months"(-14, AllowDayOverflow.no);
5109 assert(date == Date(-2002, 12, 29));
5113 auto date = Date(-2001, 12, 31);
5114 date.add!"months"(14, AllowDayOverflow.no);
5115 assert(date == Date(-1999, 2, 28));
5116 date.add!"months"(-14, AllowDayOverflow.no);
5117 assert(date == Date(-2001, 12, 28));
5120 // Test Both
5122 auto date = Date(1, 1, 1);
5123 date.add!"months"(-1, AllowDayOverflow.no);
5124 assert(date == Date(0, 12, 1));
5125 date.add!"months"(1, AllowDayOverflow.no);
5126 assert(date == Date(1, 1, 1));
5130 auto date = Date(4, 1, 1);
5131 date.add!"months"(-48, AllowDayOverflow.no);
5132 assert(date == Date(0, 1, 1));
5133 date.add!"months"(48, AllowDayOverflow.no);
5134 assert(date == Date(4, 1, 1));
5138 auto date = Date(4, 3, 31);
5139 date.add!"months"(-49, AllowDayOverflow.no);
5140 assert(date == Date(0, 2, 29));
5141 date.add!"months"(49, AllowDayOverflow.no);
5142 assert(date == Date(4, 3, 29));
5146 auto date = Date(4, 3, 31);
5147 date.add!"months"(-85, AllowDayOverflow.no);
5148 assert(date == Date(-3, 2, 28));
5149 date.add!"months"(85, AllowDayOverflow.no);
5150 assert(date == Date(4, 3, 28));
5154 auto date = Date(-3, 3, 31);
5155 date.add!"months"(85, AllowDayOverflow.no).add!"months"(-83, AllowDayOverflow.no);
5156 assert(date == Date(-3, 5, 30));
5162 Adds the given number of years or months to this $(LREF Date). A negative
5163 number will subtract.
5165 The difference between rolling and adding is that rolling does not
5166 affect larger units. Rolling a $(LREF Date) 12 months gets
5167 the exact same $(LREF Date). However, the days can still be affected due
5168 to the differing number of days in each month.
5170 Because there are no units larger than years, there is no difference
5171 between adding and rolling years.
5173 Params:
5174 units = The type of units to add ("years" or "months").
5175 value = The number of months or years to add to this
5176 $(LREF Date).
5177 allowOverflow = Whether the day should be allowed to overflow,
5178 causing the month to increment.
5180 @safe pure nothrow @nogc
5181 ref Date roll(string units)(long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes)
5182 if (units == "years")
5184 return add!"years"(value, allowOverflow);
5188 @safe unittest
5190 auto d1 = Date(2010, 1, 1);
5191 d1.roll!"months"(1);
5192 assert(d1 == Date(2010, 2, 1));
5194 auto d2 = Date(2010, 1, 1);
5195 d2.roll!"months"(-1);
5196 assert(d2 == Date(2010, 12, 1));
5198 auto d3 = Date(1999, 1, 29);
5199 d3.roll!"months"(1);
5200 assert(d3 == Date(1999, 3, 1));
5202 auto d4 = Date(1999, 1, 29);
5203 d4.roll!"months"(1, AllowDayOverflow.no);
5204 assert(d4 == Date(1999, 2, 28));
5206 auto d5 = Date(2000, 2, 29);
5207 d5.roll!"years"(1);
5208 assert(d5 == Date(2001, 3, 1));
5210 auto d6 = Date(2000, 2, 29);
5211 d6.roll!"years"(1, AllowDayOverflow.no);
5212 assert(d6 == Date(2001, 2, 28));
5215 @safe unittest
5217 const cdate = Date(1999, 7, 6);
5218 immutable idate = Date(1999, 7, 6);
5219 static assert(!__traits(compiles, cdate.roll!"years"(3)));
5220 static assert(!__traits(compiles, idate.rolYears(3)));
5224 // Shares documentation with "years" version.
5225 @safe pure nothrow @nogc
5226 ref Date roll(string units)(long months, AllowDayOverflow allowOverflow = AllowDayOverflow.yes)
5227 if (units == "months")
5229 months %= 12;
5230 auto newMonth = _month + months;
5232 if (months < 0)
5234 if (newMonth < 1)
5235 newMonth += 12;
5237 else
5239 if (newMonth > 12)
5240 newMonth -= 12;
5243 _month = cast(Month) newMonth;
5245 immutable currMaxDay = maxDay(_year, _month);
5246 immutable overflow = _day - currMaxDay;
5248 if (overflow > 0)
5250 if (allowOverflow == AllowDayOverflow.yes)
5252 ++_month;
5253 _day = cast(ubyte) overflow;
5255 else
5256 _day = cast(ubyte) currMaxDay;
5259 return this;
5262 // Test roll!"months"() with AllowDayOverflow.yes
5263 @safe unittest
5265 // Test A.D.
5267 auto date = Date(1999, 7, 6);
5268 date.roll!"months"(3);
5269 assert(date == Date(1999, 10, 6));
5270 date.roll!"months"(-4);
5271 assert(date == Date(1999, 6, 6));
5275 auto date = Date(1999, 7, 6);
5276 date.roll!"months"(6);
5277 assert(date == Date(1999, 1, 6));
5278 date.roll!"months"(-6);
5279 assert(date == Date(1999, 7, 6));
5283 auto date = Date(1999, 7, 6);
5284 date.roll!"months"(27);
5285 assert(date == Date(1999, 10, 6));
5286 date.roll!"months"(-28);
5287 assert(date == Date(1999, 6, 6));
5291 auto date = Date(1999, 5, 31);
5292 date.roll!"months"(1);
5293 assert(date == Date(1999, 7, 1));
5297 auto date = Date(1999, 5, 31);
5298 date.roll!"months"(-1);
5299 assert(date == Date(1999, 5, 1));
5303 auto date = Date(1999, 2, 28);
5304 date.roll!"months"(12);
5305 assert(date == Date(1999, 2, 28));
5309 auto date = Date(2000, 2, 29);
5310 date.roll!"months"(12);
5311 assert(date == Date(2000, 2, 29));
5315 auto date = Date(1999, 7, 31);
5316 date.roll!"months"(1);
5317 assert(date == Date(1999, 8, 31));
5318 date.roll!"months"(1);
5319 assert(date == Date(1999, 10, 1));
5323 auto date = Date(1998, 8, 31);
5324 date.roll!"months"(13);
5325 assert(date == Date(1998, 10, 1));
5326 date.roll!"months"(-13);
5327 assert(date == Date(1998, 9, 1));
5331 auto date = Date(1997, 12, 31);
5332 date.roll!"months"(13);
5333 assert(date == Date(1997, 1, 31));
5334 date.roll!"months"(-13);
5335 assert(date == Date(1997, 12, 31));
5339 auto date = Date(1997, 12, 31);
5340 date.roll!"months"(14);
5341 assert(date == Date(1997, 3, 3));
5342 date.roll!"months"(-14);
5343 assert(date == Date(1997, 1, 3));
5347 auto date = Date(1998, 12, 31);
5348 date.roll!"months"(14);
5349 assert(date == Date(1998, 3, 3));
5350 date.roll!"months"(-14);
5351 assert(date == Date(1998, 1, 3));
5355 auto date = Date(1999, 12, 31);
5356 date.roll!"months"(14);
5357 assert(date == Date(1999, 3, 3));
5358 date.roll!"months"(-14);
5359 assert(date == Date(1999, 1, 3));
5362 // Test B.C.
5364 auto date = Date(-1999, 7, 6);
5365 date.roll!"months"(3);
5366 assert(date == Date(-1999, 10, 6));
5367 date.roll!"months"(-4);
5368 assert(date == Date(-1999, 6, 6));
5372 auto date = Date(-1999, 7, 6);
5373 date.roll!"months"(6);
5374 assert(date == Date(-1999, 1, 6));
5375 date.roll!"months"(-6);
5376 assert(date == Date(-1999, 7, 6));
5380 auto date = Date(-1999, 7, 6);
5381 date.roll!"months"(-27);
5382 assert(date == Date(-1999, 4, 6));
5383 date.roll!"months"(28);
5384 assert(date == Date(-1999, 8, 6));
5388 auto date = Date(-1999, 5, 31);
5389 date.roll!"months"(1);
5390 assert(date == Date(-1999, 7, 1));
5394 auto date = Date(-1999, 5, 31);
5395 date.roll!"months"(-1);
5396 assert(date == Date(-1999, 5, 1));
5400 auto date = Date(-1999, 2, 28);
5401 date.roll!"months"(-12);
5402 assert(date == Date(-1999, 2, 28));
5406 auto date = Date(-2000, 2, 29);
5407 date.roll!"months"(-12);
5408 assert(date == Date(-2000, 2, 29));
5412 auto date = Date(-1999, 7, 31);
5413 date.roll!"months"(1);
5414 assert(date == Date(-1999, 8, 31));
5415 date.roll!"months"(1);
5416 assert(date == Date(-1999, 10, 1));
5420 auto date = Date(-1998, 8, 31);
5421 date.roll!"months"(13);
5422 assert(date == Date(-1998, 10, 1));
5423 date.roll!"months"(-13);
5424 assert(date == Date(-1998, 9, 1));
5428 auto date = Date(-1997, 12, 31);
5429 date.roll!"months"(13);
5430 assert(date == Date(-1997, 1, 31));
5431 date.roll!"months"(-13);
5432 assert(date == Date(-1997, 12, 31));
5436 auto date = Date(-1997, 12, 31);
5437 date.roll!"months"(14);
5438 assert(date == Date(-1997, 3, 3));
5439 date.roll!"months"(-14);
5440 assert(date == Date(-1997, 1, 3));
5444 auto date = Date(-2002, 12, 31);
5445 date.roll!"months"(14);
5446 assert(date == Date(-2002, 3, 3));
5447 date.roll!"months"(-14);
5448 assert(date == Date(-2002, 1, 3));
5452 auto date = Date(-2001, 12, 31);
5453 date.roll!"months"(14);
5454 assert(date == Date(-2001, 3, 3));
5455 date.roll!"months"(-14);
5456 assert(date == Date(-2001, 1, 3));
5459 // Test Both
5461 auto date = Date(1, 1, 1);
5462 date.roll!"months"(-1);
5463 assert(date == Date(1, 12, 1));
5464 date.roll!"months"(1);
5465 assert(date == Date(1, 1, 1));
5469 auto date = Date(4, 1, 1);
5470 date.roll!"months"(-48);
5471 assert(date == Date(4, 1, 1));
5472 date.roll!"months"(48);
5473 assert(date == Date(4, 1, 1));
5477 auto date = Date(4, 3, 31);
5478 date.roll!"months"(-49);
5479 assert(date == Date(4, 3, 2));
5480 date.roll!"months"(49);
5481 assert(date == Date(4, 4, 2));
5485 auto date = Date(4, 3, 31);
5486 date.roll!"months"(-85);
5487 assert(date == Date(4, 3, 2));
5488 date.roll!"months"(85);
5489 assert(date == Date(4, 4, 2));
5493 auto date = Date(-1, 1, 1);
5494 date.roll!"months"(-1);
5495 assert(date == Date(-1, 12, 1));
5496 date.roll!"months"(1);
5497 assert(date == Date(-1, 1, 1));
5501 auto date = Date(-4, 1, 1);
5502 date.roll!"months"(-48);
5503 assert(date == Date(-4, 1, 1));
5504 date.roll!"months"(48);
5505 assert(date == Date(-4, 1, 1));
5509 auto date = Date(-4, 3, 31);
5510 date.roll!"months"(-49);
5511 assert(date == Date(-4, 3, 2));
5512 date.roll!"months"(49);
5513 assert(date == Date(-4, 4, 2));
5517 auto date = Date(-4, 3, 31);
5518 date.roll!"months"(-85);
5519 assert(date == Date(-4, 3, 2));
5520 date.roll!"months"(85);
5521 assert(date == Date(-4, 4, 2));
5525 auto date = Date(-3, 3, 31);
5526 date.roll!"months"(85).roll!"months"(-83);
5527 assert(date == Date(-3, 6, 1));
5530 const cdate = Date(1999, 7, 6);
5531 immutable idate = Date(1999, 7, 6);
5532 static assert(!__traits(compiles, cdate.roll!"months"(3)));
5533 static assert(!__traits(compiles, idate.roll!"months"(3)));
5536 // Test roll!"months"() with AllowDayOverflow.no
5537 @safe unittest
5539 // Test A.D.
5541 auto date = Date(1999, 7, 6);
5542 date.roll!"months"(3, AllowDayOverflow.no);
5543 assert(date == Date(1999, 10, 6));
5544 date.roll!"months"(-4, AllowDayOverflow.no);
5545 assert(date == Date(1999, 6, 6));
5549 auto date = Date(1999, 7, 6);
5550 date.roll!"months"(6, AllowDayOverflow.no);
5551 assert(date == Date(1999, 1, 6));
5552 date.roll!"months"(-6, AllowDayOverflow.no);
5553 assert(date == Date(1999, 7, 6));
5557 auto date = Date(1999, 7, 6);
5558 date.roll!"months"(27, AllowDayOverflow.no);
5559 assert(date == Date(1999, 10, 6));
5560 date.roll!"months"(-28, AllowDayOverflow.no);
5561 assert(date == Date(1999, 6, 6));
5565 auto date = Date(1999, 5, 31);
5566 date.roll!"months"(1, AllowDayOverflow.no);
5567 assert(date == Date(1999, 6, 30));
5571 auto date = Date(1999, 5, 31);
5572 date.roll!"months"(-1, AllowDayOverflow.no);
5573 assert(date == Date(1999, 4, 30));
5577 auto date = Date(1999, 2, 28);
5578 date.roll!"months"(12, AllowDayOverflow.no);
5579 assert(date == Date(1999, 2, 28));
5583 auto date = Date(2000, 2, 29);
5584 date.roll!"months"(12, AllowDayOverflow.no);
5585 assert(date == Date(2000, 2, 29));
5589 auto date = Date(1999, 7, 31);
5590 date.roll!"months"(1, AllowDayOverflow.no);
5591 assert(date == Date(1999, 8, 31));
5592 date.roll!"months"(1, AllowDayOverflow.no);
5593 assert(date == Date(1999, 9, 30));
5597 auto date = Date(1998, 8, 31);
5598 date.roll!"months"(13, AllowDayOverflow.no);
5599 assert(date == Date(1998, 9, 30));
5600 date.roll!"months"(-13, AllowDayOverflow.no);
5601 assert(date == Date(1998, 8, 30));
5605 auto date = Date(1997, 12, 31);
5606 date.roll!"months"(13, AllowDayOverflow.no);
5607 assert(date == Date(1997, 1, 31));
5608 date.roll!"months"(-13, AllowDayOverflow.no);
5609 assert(date == Date(1997, 12, 31));
5613 auto date = Date(1997, 12, 31);
5614 date.roll!"months"(14, AllowDayOverflow.no);
5615 assert(date == Date(1997, 2, 28));
5616 date.roll!"months"(-14, AllowDayOverflow.no);
5617 assert(date == Date(1997, 12, 28));
5621 auto date = Date(1998, 12, 31);
5622 date.roll!"months"(14, AllowDayOverflow.no);
5623 assert(date == Date(1998, 2, 28));
5624 date.roll!"months"(-14, AllowDayOverflow.no);
5625 assert(date == Date(1998, 12, 28));
5629 auto date = Date(1999, 12, 31);
5630 date.roll!"months"(14, AllowDayOverflow.no);
5631 assert(date == Date(1999, 2, 28));
5632 date.roll!"months"(-14, AllowDayOverflow.no);
5633 assert(date == Date(1999, 12, 28));
5636 // Test B.C.
5638 auto date = Date(-1999, 7, 6);
5639 date.roll!"months"(3, AllowDayOverflow.no);
5640 assert(date == Date(-1999, 10, 6));
5641 date.roll!"months"(-4, AllowDayOverflow.no);
5642 assert(date == Date(-1999, 6, 6));
5646 auto date = Date(-1999, 7, 6);
5647 date.roll!"months"(6, AllowDayOverflow.no);
5648 assert(date == Date(-1999, 1, 6));
5649 date.roll!"months"(-6, AllowDayOverflow.no);
5650 assert(date == Date(-1999, 7, 6));
5654 auto date = Date(-1999, 7, 6);
5655 date.roll!"months"(-27, AllowDayOverflow.no);
5656 assert(date == Date(-1999, 4, 6));
5657 date.roll!"months"(28, AllowDayOverflow.no);
5658 assert(date == Date(-1999, 8, 6));
5662 auto date = Date(-1999, 5, 31);
5663 date.roll!"months"(1, AllowDayOverflow.no);
5664 assert(date == Date(-1999, 6, 30));
5668 auto date = Date(-1999, 5, 31);
5669 date.roll!"months"(-1, AllowDayOverflow.no);
5670 assert(date == Date(-1999, 4, 30));
5674 auto date = Date(-1999, 2, 28);
5675 date.roll!"months"(-12, AllowDayOverflow.no);
5676 assert(date == Date(-1999, 2, 28));
5680 auto date = Date(-2000, 2, 29);
5681 date.roll!"months"(-12, AllowDayOverflow.no);
5682 assert(date == Date(-2000, 2, 29));
5686 auto date = Date(-1999, 7, 31);
5687 date.roll!"months"(1, AllowDayOverflow.no);
5688 assert(date == Date(-1999, 8, 31));
5689 date.roll!"months"(1, AllowDayOverflow.no);
5690 assert(date == Date(-1999, 9, 30));
5694 auto date = Date(-1998, 8, 31);
5695 date.roll!"months"(13, AllowDayOverflow.no);
5696 assert(date == Date(-1998, 9, 30));
5697 date.roll!"months"(-13, AllowDayOverflow.no);
5698 assert(date == Date(-1998, 8, 30));
5702 auto date = Date(-1997, 12, 31);
5703 date.roll!"months"(13, AllowDayOverflow.no);
5704 assert(date == Date(-1997, 1, 31));
5705 date.roll!"months"(-13, AllowDayOverflow.no);
5706 assert(date == Date(-1997, 12, 31));
5710 auto date = Date(-1997, 12, 31);
5711 date.roll!"months"(14, AllowDayOverflow.no);
5712 assert(date == Date(-1997, 2, 28));
5713 date.roll!"months"(-14, AllowDayOverflow.no);
5714 assert(date == Date(-1997, 12, 28));
5718 auto date = Date(-2002, 12, 31);
5719 date.roll!"months"(14, AllowDayOverflow.no);
5720 assert(date == Date(-2002, 2, 28));
5721 date.roll!"months"(-14, AllowDayOverflow.no);
5722 assert(date == Date(-2002, 12, 28));
5726 auto date = Date(-2001, 12, 31);
5727 date.roll!"months"(14, AllowDayOverflow.no);
5728 assert(date == Date(-2001, 2, 28));
5729 date.roll!"months"(-14, AllowDayOverflow.no);
5730 assert(date == Date(-2001, 12, 28));
5733 // Test Both
5735 auto date = Date(1, 1, 1);
5736 date.roll!"months"(-1, AllowDayOverflow.no);
5737 assert(date == Date(1, 12, 1));
5738 date.roll!"months"(1, AllowDayOverflow.no);
5739 assert(date == Date(1, 1, 1));
5743 auto date = Date(4, 1, 1);
5744 date.roll!"months"(-48, AllowDayOverflow.no);
5745 assert(date == Date(4, 1, 1));
5746 date.roll!"months"(48, AllowDayOverflow.no);
5747 assert(date == Date(4, 1, 1));
5751 auto date = Date(4, 3, 31);
5752 date.roll!"months"(-49, AllowDayOverflow.no);
5753 assert(date == Date(4, 2, 29));
5754 date.roll!"months"(49, AllowDayOverflow.no);
5755 assert(date == Date(4, 3, 29));
5759 auto date = Date(4, 3, 31);
5760 date.roll!"months"(-85, AllowDayOverflow.no);
5761 assert(date == Date(4, 2, 29));
5762 date.roll!"months"(85, AllowDayOverflow.no);
5763 assert(date == Date(4, 3, 29));
5767 auto date = Date(-1, 1, 1);
5768 date.roll!"months"(-1, AllowDayOverflow.no);
5769 assert(date == Date(-1, 12, 1));
5770 date.roll!"months"(1, AllowDayOverflow.no);
5771 assert(date == Date(-1, 1, 1));
5775 auto date = Date(-4, 1, 1);
5776 date.roll!"months"(-48, AllowDayOverflow.no);
5777 assert(date == Date(-4, 1, 1));
5778 date.roll!"months"(48, AllowDayOverflow.no);
5779 assert(date == Date(-4, 1, 1));
5783 auto date = Date(-4, 3, 31);
5784 date.roll!"months"(-49, AllowDayOverflow.no);
5785 assert(date == Date(-4, 2, 29));
5786 date.roll!"months"(49, AllowDayOverflow.no);
5787 assert(date == Date(-4, 3, 29));
5791 auto date = Date(-4, 3, 31);
5792 date.roll!"months"(-85, AllowDayOverflow.no);
5793 assert(date == Date(-4, 2, 29));
5794 date.roll!"months"(85, AllowDayOverflow.no);
5795 assert(date == Date(-4, 3, 29));
5799 auto date = Date(-3, 3, 31);
5800 date.roll!"months"(85, AllowDayOverflow.no).roll!"months"(-83, AllowDayOverflow.no);
5801 assert(date == Date(-3, 5, 30));
5807 Adds the given number of units to this $(LREF Date). A negative number
5808 will subtract.
5810 The difference between rolling and adding is that rolling does not
5811 affect larger units. For instance, rolling a $(LREF Date) one
5812 year's worth of days gets the exact same $(LREF Date).
5814 The only accepted units are $(D "days").
5816 Params:
5817 units = The units to add. Must be $(D "days").
5818 days = The number of days to add to this $(LREF Date).
5820 ref Date roll(string units)(long days) @safe pure nothrow @nogc
5821 if (units == "days")
5823 immutable limit = maxDay(_year, _month);
5824 days %= limit;
5825 auto newDay = _day + days;
5827 if (days < 0)
5829 if (newDay < 1)
5830 newDay += limit;
5832 else if (newDay > limit)
5833 newDay -= limit;
5835 _day = cast(ubyte) newDay;
5836 return this;
5840 @safe unittest
5842 auto d = Date(2010, 1, 1);
5843 d.roll!"days"(1);
5844 assert(d == Date(2010, 1, 2));
5845 d.roll!"days"(365);
5846 assert(d == Date(2010, 1, 26));
5847 d.roll!"days"(-32);
5848 assert(d == Date(2010, 1, 25));
5851 @safe unittest
5853 // Test A.D.
5855 auto date = Date(1999, 2, 28);
5856 date.roll!"days"(1);
5857 assert(date == Date(1999, 2, 1));
5858 date.roll!"days"(-1);
5859 assert(date == Date(1999, 2, 28));
5863 auto date = Date(2000, 2, 28);
5864 date.roll!"days"(1);
5865 assert(date == Date(2000, 2, 29));
5866 date.roll!"days"(1);
5867 assert(date == Date(2000, 2, 1));
5868 date.roll!"days"(-1);
5869 assert(date == Date(2000, 2, 29));
5873 auto date = Date(1999, 6, 30);
5874 date.roll!"days"(1);
5875 assert(date == Date(1999, 6, 1));
5876 date.roll!"days"(-1);
5877 assert(date == Date(1999, 6, 30));
5881 auto date = Date(1999, 7, 31);
5882 date.roll!"days"(1);
5883 assert(date == Date(1999, 7, 1));
5884 date.roll!"days"(-1);
5885 assert(date == Date(1999, 7, 31));
5889 auto date = Date(1999, 1, 1);
5890 date.roll!"days"(-1);
5891 assert(date == Date(1999, 1, 31));
5892 date.roll!"days"(1);
5893 assert(date == Date(1999, 1, 1));
5897 auto date = Date(1999, 7, 6);
5898 date.roll!"days"(9);
5899 assert(date == Date(1999, 7, 15));
5900 date.roll!"days"(-11);
5901 assert(date == Date(1999, 7, 4));
5902 date.roll!"days"(30);
5903 assert(date == Date(1999, 7, 3));
5904 date.roll!"days"(-3);
5905 assert(date == Date(1999, 7, 31));
5909 auto date = Date(1999, 7, 6);
5910 date.roll!"days"(365);
5911 assert(date == Date(1999, 7, 30));
5912 date.roll!"days"(-365);
5913 assert(date == Date(1999, 7, 6));
5914 date.roll!"days"(366);
5915 assert(date == Date(1999, 7, 31));
5916 date.roll!"days"(730);
5917 assert(date == Date(1999, 7, 17));
5918 date.roll!"days"(-1096);
5919 assert(date == Date(1999, 7, 6));
5923 auto date = Date(1999, 2, 6);
5924 date.roll!"days"(365);
5925 assert(date == Date(1999, 2, 7));
5926 date.roll!"days"(-365);
5927 assert(date == Date(1999, 2, 6));
5928 date.roll!"days"(366);
5929 assert(date == Date(1999, 2, 8));
5930 date.roll!"days"(730);
5931 assert(date == Date(1999, 2, 10));
5932 date.roll!"days"(-1096);
5933 assert(date == Date(1999, 2, 6));
5936 // Test B.C.
5938 auto date = Date(-1999, 2, 28);
5939 date.roll!"days"(1);
5940 assert(date == Date(-1999, 2, 1));
5941 date.roll!"days"(-1);
5942 assert(date == Date(-1999, 2, 28));
5946 auto date = Date(-2000, 2, 28);
5947 date.roll!"days"(1);
5948 assert(date == Date(-2000, 2, 29));
5949 date.roll!"days"(1);
5950 assert(date == Date(-2000, 2, 1));
5951 date.roll!"days"(-1);
5952 assert(date == Date(-2000, 2, 29));
5956 auto date = Date(-1999, 6, 30);
5957 date.roll!"days"(1);
5958 assert(date == Date(-1999, 6, 1));
5959 date.roll!"days"(-1);
5960 assert(date == Date(-1999, 6, 30));
5964 auto date = Date(-1999, 7, 31);
5965 date.roll!"days"(1);
5966 assert(date == Date(-1999, 7, 1));
5967 date.roll!"days"(-1);
5968 assert(date == Date(-1999, 7, 31));
5972 auto date = Date(-1999, 1, 1);
5973 date.roll!"days"(-1);
5974 assert(date == Date(-1999, 1, 31));
5975 date.roll!"days"(1);
5976 assert(date == Date(-1999, 1, 1));
5980 auto date = Date(-1999, 7, 6);
5981 date.roll!"days"(9);
5982 assert(date == Date(-1999, 7, 15));
5983 date.roll!"days"(-11);
5984 assert(date == Date(-1999, 7, 4));
5985 date.roll!"days"(30);
5986 assert(date == Date(-1999, 7, 3));
5987 date.roll!"days"(-3);
5988 assert(date == Date(-1999, 7, 31));
5992 auto date = Date(-1999, 7, 6);
5993 date.roll!"days"(365);
5994 assert(date == Date(-1999, 7, 30));
5995 date.roll!"days"(-365);
5996 assert(date == Date(-1999, 7, 6));
5997 date.roll!"days"(366);
5998 assert(date == Date(-1999, 7, 31));
5999 date.roll!"days"(730);
6000 assert(date == Date(-1999, 7, 17));
6001 date.roll!"days"(-1096);
6002 assert(date == Date(-1999, 7, 6));
6005 // Test Both
6007 auto date = Date(1, 7, 6);
6008 date.roll!"days"(-365);
6009 assert(date == Date(1, 7, 13));
6010 date.roll!"days"(365);
6011 assert(date == Date(1, 7, 6));
6012 date.roll!"days"(-731);
6013 assert(date == Date(1, 7, 19));
6014 date.roll!"days"(730);
6015 assert(date == Date(1, 7, 5));
6019 auto date = Date(0, 7, 6);
6020 date.roll!"days"(-365);
6021 assert(date == Date(0, 7, 13));
6022 date.roll!"days"(365);
6023 assert(date == Date(0, 7, 6));
6024 date.roll!"days"(-731);
6025 assert(date == Date(0, 7, 19));
6026 date.roll!"days"(730);
6027 assert(date == Date(0, 7, 5));
6031 auto date = Date(0, 7, 6);
6032 date.roll!"days"(-365).roll!"days"(362).roll!"days"(-12).roll!"days"(730);
6033 assert(date == Date(0, 7, 8));
6036 const cdate = Date(1999, 7, 6);
6037 immutable idate = Date(1999, 7, 6);
6038 static assert(!__traits(compiles, cdate.roll!"days"(12)));
6039 static assert(!__traits(compiles, idate.roll!"days"(12)));
6044 Gives the result of adding or subtracting a $(REF Duration, core,time)
6045 from
6047 The legal types of arithmetic for $(LREF Date) using this operator are
6049 $(BOOKTABLE,
6050 $(TR $(TD Date) $(TD +) $(TD Duration) $(TD -->) $(TD Date))
6051 $(TR $(TD Date) $(TD -) $(TD Duration) $(TD -->) $(TD Date))
6054 Params:
6055 duration = The $(REF Duration, core,time) to add to or subtract from
6056 this $(LREF Date).
6058 Date opBinary(string op)(Duration duration) const @safe pure nothrow @nogc
6059 if (op == "+" || op == "-")
6061 Date retval = this;
6062 immutable days = duration.total!"days";
6063 mixin("return retval._addDays(" ~ op ~ "days);");
6067 @safe unittest
6069 import core.time : days;
6071 assert(Date(2015, 12, 31) + days(1) == Date(2016, 1, 1));
6072 assert(Date(2004, 2, 26) + days(4) == Date(2004, 3, 1));
6074 assert(Date(2016, 1, 1) - days(1) == Date(2015, 12, 31));
6075 assert(Date(2004, 3, 1) - days(4) == Date(2004, 2, 26));
6078 @safe unittest
6080 auto date = Date(1999, 7, 6);
6082 assert(date + dur!"weeks"(7) == Date(1999, 8, 24));
6083 assert(date + dur!"weeks"(-7) == Date(1999, 5, 18));
6084 assert(date + dur!"days"(7) == Date(1999, 7, 13));
6085 assert(date + dur!"days"(-7) == Date(1999, 6, 29));
6087 assert(date + dur!"hours"(24) == Date(1999, 7, 7));
6088 assert(date + dur!"hours"(-24) == Date(1999, 7, 5));
6089 assert(date + dur!"minutes"(1440) == Date(1999, 7, 7));
6090 assert(date + dur!"minutes"(-1440) == Date(1999, 7, 5));
6091 assert(date + dur!"seconds"(86_400) == Date(1999, 7, 7));
6092 assert(date + dur!"seconds"(-86_400) == Date(1999, 7, 5));
6093 assert(date + dur!"msecs"(86_400_000) == Date(1999, 7, 7));
6094 assert(date + dur!"msecs"(-86_400_000) == Date(1999, 7, 5));
6095 assert(date + dur!"usecs"(86_400_000_000) == Date(1999, 7, 7));
6096 assert(date + dur!"usecs"(-86_400_000_000) == Date(1999, 7, 5));
6097 assert(date + dur!"hnsecs"(864_000_000_000) == Date(1999, 7, 7));
6098 assert(date + dur!"hnsecs"(-864_000_000_000) == Date(1999, 7, 5));
6100 assert(date - dur!"weeks"(-7) == Date(1999, 8, 24));
6101 assert(date - dur!"weeks"(7) == Date(1999, 5, 18));
6102 assert(date - dur!"days"(-7) == Date(1999, 7, 13));
6103 assert(date - dur!"days"(7) == Date(1999, 6, 29));
6105 assert(date - dur!"hours"(-24) == Date(1999, 7, 7));
6106 assert(date - dur!"hours"(24) == Date(1999, 7, 5));
6107 assert(date - dur!"minutes"(-1440) == Date(1999, 7, 7));
6108 assert(date - dur!"minutes"(1440) == Date(1999, 7, 5));
6109 assert(date - dur!"seconds"(-86_400) == Date(1999, 7, 7));
6110 assert(date - dur!"seconds"(86_400) == Date(1999, 7, 5));
6111 assert(date - dur!"msecs"(-86_400_000) == Date(1999, 7, 7));
6112 assert(date - dur!"msecs"(86_400_000) == Date(1999, 7, 5));
6113 assert(date - dur!"usecs"(-86_400_000_000) == Date(1999, 7, 7));
6114 assert(date - dur!"usecs"(86_400_000_000) == Date(1999, 7, 5));
6115 assert(date - dur!"hnsecs"(-864_000_000_000) == Date(1999, 7, 7));
6116 assert(date - dur!"hnsecs"(864_000_000_000) == Date(1999, 7, 5));
6118 auto duration = dur!"days"(12);
6119 const cdate = Date(1999, 7, 6);
6120 immutable idate = Date(1999, 7, 6);
6121 assert(date + duration == Date(1999, 7, 18));
6122 assert(cdate + duration == Date(1999, 7, 18));
6123 assert(idate + duration == Date(1999, 7, 18));
6125 assert(date - duration == Date(1999, 6, 24));
6126 assert(cdate - duration == Date(1999, 6, 24));
6127 assert(idate - duration == Date(1999, 6, 24));
6130 // Explicitly undocumented. It will be removed in January 2018. @@@DEPRECATED_2018-01@@@
6131 deprecated("Use Duration instead of TickDuration.")
6132 Date opBinary(string op)(TickDuration td) const @safe pure nothrow @nogc
6133 if (op == "+" || op == "-")
6135 Date retval = this;
6136 immutable days = convert!("hnsecs", "days")(td.hnsecs);
6137 mixin("return retval._addDays(" ~ op ~ "days);");
6140 deprecated @safe unittest
6142 // This probably only runs in cases where gettimeofday() is used, but it's
6143 // hard to do this test correctly with variable ticksPerSec.
6144 if (TickDuration.ticksPerSec == 1_000_000)
6146 auto date = Date(1999, 7, 6);
6148 assert(date + TickDuration.from!"usecs"(86_400_000_000) == Date(1999, 7, 7));
6149 assert(date + TickDuration.from!"usecs"(-86_400_000_000) == Date(1999, 7, 5));
6151 assert(date - TickDuration.from!"usecs"(-86_400_000_000) == Date(1999, 7, 7));
6152 assert(date - TickDuration.from!"usecs"(86_400_000_000) == Date(1999, 7, 5));
6158 Gives the result of adding or subtracting a $(REF Duration, core,time)
6159 from this $(LREF Date), as well as assigning the result to this
6160 $(LREF Date).
6162 The legal types of arithmetic for $(LREF Date) using this operator are
6164 $(BOOKTABLE,
6165 $(TR $(TD Date) $(TD +) $(TD Duration) $(TD -->) $(TD Date))
6166 $(TR $(TD Date) $(TD -) $(TD Duration) $(TD -->) $(TD Date))
6169 Params:
6170 duration = The $(REF Duration, core,time) to add to or subtract from
6171 this $(LREF Date).
6173 ref Date opOpAssign(string op)(Duration duration) @safe pure nothrow @nogc
6174 if (op == "+" || op == "-")
6176 immutable days = duration.total!"days";
6177 mixin("return _addDays(" ~ op ~ "days);");
6180 @safe unittest
6182 assert(Date(1999, 7, 6) + dur!"weeks"(7) == Date(1999, 8, 24));
6183 assert(Date(1999, 7, 6) + dur!"weeks"(-7) == Date(1999, 5, 18));
6184 assert(Date(1999, 7, 6) + dur!"days"(7) == Date(1999, 7, 13));
6185 assert(Date(1999, 7, 6) + dur!"days"(-7) == Date(1999, 6, 29));
6187 assert(Date(1999, 7, 6) + dur!"hours"(24) == Date(1999, 7, 7));
6188 assert(Date(1999, 7, 6) + dur!"hours"(-24) == Date(1999, 7, 5));
6189 assert(Date(1999, 7, 6) + dur!"minutes"(1440) == Date(1999, 7, 7));
6190 assert(Date(1999, 7, 6) + dur!"minutes"(-1440) == Date(1999, 7, 5));
6191 assert(Date(1999, 7, 6) + dur!"seconds"(86_400) == Date(1999, 7, 7));
6192 assert(Date(1999, 7, 6) + dur!"seconds"(-86_400) == Date(1999, 7, 5));
6193 assert(Date(1999, 7, 6) + dur!"msecs"(86_400_000) == Date(1999, 7, 7));
6194 assert(Date(1999, 7, 6) + dur!"msecs"(-86_400_000) == Date(1999, 7, 5));
6195 assert(Date(1999, 7, 6) + dur!"usecs"(86_400_000_000) == Date(1999, 7, 7));
6196 assert(Date(1999, 7, 6) + dur!"usecs"(-86_400_000_000) == Date(1999, 7, 5));
6197 assert(Date(1999, 7, 6) + dur!"hnsecs"(864_000_000_000) == Date(1999, 7, 7));
6198 assert(Date(1999, 7, 6) + dur!"hnsecs"(-864_000_000_000) == Date(1999, 7, 5));
6200 assert(Date(1999, 7, 6) - dur!"weeks"(-7) == Date(1999, 8, 24));
6201 assert(Date(1999, 7, 6) - dur!"weeks"(7) == Date(1999, 5, 18));
6202 assert(Date(1999, 7, 6) - dur!"days"(-7) == Date(1999, 7, 13));
6203 assert(Date(1999, 7, 6) - dur!"days"(7) == Date(1999, 6, 29));
6205 assert(Date(1999, 7, 6) - dur!"hours"(-24) == Date(1999, 7, 7));
6206 assert(Date(1999, 7, 6) - dur!"hours"(24) == Date(1999, 7, 5));
6207 assert(Date(1999, 7, 6) - dur!"minutes"(-1440) == Date(1999, 7, 7));
6208 assert(Date(1999, 7, 6) - dur!"minutes"(1440) == Date(1999, 7, 5));
6209 assert(Date(1999, 7, 6) - dur!"seconds"(-86_400) == Date(1999, 7, 7));
6210 assert(Date(1999, 7, 6) - dur!"seconds"(86_400) == Date(1999, 7, 5));
6211 assert(Date(1999, 7, 6) - dur!"msecs"(-86_400_000) == Date(1999, 7, 7));
6212 assert(Date(1999, 7, 6) - dur!"msecs"(86_400_000) == Date(1999, 7, 5));
6213 assert(Date(1999, 7, 6) - dur!"usecs"(-86_400_000_000) == Date(1999, 7, 7));
6214 assert(Date(1999, 7, 6) - dur!"usecs"(86_400_000_000) == Date(1999, 7, 5));
6215 assert(Date(1999, 7, 6) - dur!"hnsecs"(-864_000_000_000) == Date(1999, 7, 7));
6216 assert(Date(1999, 7, 6) - dur!"hnsecs"(864_000_000_000) == Date(1999, 7, 5));
6219 auto date = Date(0, 1, 31);
6220 (date += dur!"days"(507)) += dur!"days"(-2);
6221 assert(date == Date(1, 6, 19));
6224 auto duration = dur!"days"(12);
6225 auto date = Date(1999, 7, 6);
6226 const cdate = Date(1999, 7, 6);
6227 immutable idate = Date(1999, 7, 6);
6228 date += duration;
6229 static assert(!__traits(compiles, cdate += duration));
6230 static assert(!__traits(compiles, idate += duration));
6232 date -= duration;
6233 static assert(!__traits(compiles, cdate -= duration));
6234 static assert(!__traits(compiles, idate -= duration));
6237 // Explicitly undocumented. It will be removed in January 2018. @@@DEPRECATED_2018-01@@@
6238 deprecated("Use Duration instead of TickDuration.")
6239 ref Date opOpAssign(string op)(TickDuration td) @safe pure nothrow @nogc
6240 if (op == "+" || op == "-")
6242 immutable days = convert!("seconds", "days")(td.seconds);
6243 mixin("return _addDays(" ~ op ~ "days);");
6246 deprecated @safe unittest
6248 // This probably only runs in cases where gettimeofday() is used, but it's
6249 // hard to do this test correctly with variable ticksPerSec.
6250 if (TickDuration.ticksPerSec == 1_000_000)
6253 auto date = Date(1999, 7, 6);
6254 date += TickDuration.from!"usecs"(86_400_000_000);
6255 assert(date == Date(1999, 7, 7));
6259 auto date = Date(1999, 7, 6);
6260 date += TickDuration.from!"usecs"(-86_400_000_000);
6261 assert(date == Date(1999, 7, 5));
6265 auto date = Date(1999, 7, 6);
6266 date -= TickDuration.from!"usecs"(-86_400_000_000);
6267 assert(date == Date(1999, 7, 7));
6271 auto date = Date(1999, 7, 6);
6272 date -= TickDuration.from!"usecs"(86_400_000_000);
6273 assert(date == Date(1999, 7, 5));
6280 Gives the difference between two $(LREF Date)s.
6282 The legal types of arithmetic for $(LREF Date) using this operator are
6284 $(BOOKTABLE,
6285 $(TR $(TD Date) $(TD -) $(TD Date) $(TD -->) $(TD duration))
6288 Duration opBinary(string op)(in Date rhs) const @safe pure nothrow @nogc
6289 if (op == "-")
6291 return dur!"days"(this.dayOfGregorianCal - rhs.dayOfGregorianCal);
6294 @safe unittest
6296 auto date = Date(1999, 7, 6);
6298 assert(Date(1999, 7, 6) - Date(1998, 7, 6) == dur!"days"(365));
6299 assert(Date(1998, 7, 6) - Date(1999, 7, 6) == dur!"days"(-365));
6300 assert(Date(1999, 6, 6) - Date(1999, 5, 6) == dur!"days"(31));
6301 assert(Date(1999, 5, 6) - Date(1999, 6, 6) == dur!"days"(-31));
6302 assert(Date(1999, 1, 1) - Date(1998, 12, 31) == dur!"days"(1));
6303 assert(Date(1998, 12, 31) - Date(1999, 1, 1) == dur!"days"(-1));
6305 const cdate = Date(1999, 7, 6);
6306 immutable idate = Date(1999, 7, 6);
6307 assert(date - date == Duration.zero);
6308 assert(cdate - date == Duration.zero);
6309 assert(idate - date == Duration.zero);
6311 assert(date - cdate == Duration.zero);
6312 assert(cdate - cdate == Duration.zero);
6313 assert(idate - cdate == Duration.zero);
6315 assert(date - idate == Duration.zero);
6316 assert(cdate - idate == Duration.zero);
6317 assert(idate - idate == Duration.zero);
6322 Returns the difference between the two $(LREF Date)s in months.
6324 To get the difference in years, subtract the year property
6325 of two $(LREF Date)s. To get the difference in days or weeks,
6326 subtract the $(LREF Date)s themselves and use the
6327 $(REF Duration, core,time) that results. Because converting between
6328 months and smaller units requires a specific date (which
6329 $(REF Duration, core,time)s don't have), getting the difference in
6330 months requires some math using both the year and month properties, so
6331 this is a convenience function for getting the difference in months.
6333 Note that the number of days in the months or how far into the month
6334 either $(LREF Date) is is irrelevant. It is the difference in the month
6335 property combined with the difference in years * 12. So, for instance,
6336 December 31st and January 1st are one month apart just as December 1st
6337 and January 31st are one month apart.
6339 Params:
6340 rhs = The $(LREF Date) to subtract from this one.
6342 int diffMonths(in Date rhs) const @safe pure nothrow @nogc
6344 immutable yearDiff = _year - rhs._year;
6345 immutable monthDiff = _month - rhs._month;
6347 return yearDiff * 12 + monthDiff;
6351 @safe unittest
6353 assert(Date(1999, 2, 1).diffMonths(Date(1999, 1, 31)) == 1);
6354 assert(Date(1999, 1, 31).diffMonths(Date(1999, 2, 1)) == -1);
6355 assert(Date(1999, 3, 1).diffMonths(Date(1999, 1, 1)) == 2);
6356 assert(Date(1999, 1, 1).diffMonths(Date(1999, 3, 31)) == -2);
6359 @safe unittest
6361 auto date = Date(1999, 7, 6);
6363 // Test A.D.
6364 assert(date.diffMonths(Date(1998, 6, 5)) == 13);
6365 assert(date.diffMonths(Date(1998, 7, 5)) == 12);
6366 assert(date.diffMonths(Date(1998, 8, 5)) == 11);
6367 assert(date.diffMonths(Date(1998, 9, 5)) == 10);
6368 assert(date.diffMonths(Date(1998, 10, 5)) == 9);
6369 assert(date.diffMonths(Date(1998, 11, 5)) == 8);
6370 assert(date.diffMonths(Date(1998, 12, 5)) == 7);
6371 assert(date.diffMonths(Date(1999, 1, 5)) == 6);
6372 assert(date.diffMonths(Date(1999, 2, 6)) == 5);
6373 assert(date.diffMonths(Date(1999, 3, 6)) == 4);
6374 assert(date.diffMonths(Date(1999, 4, 6)) == 3);
6375 assert(date.diffMonths(Date(1999, 5, 6)) == 2);
6376 assert(date.diffMonths(Date(1999, 6, 6)) == 1);
6377 assert(date.diffMonths(date) == 0);
6378 assert(date.diffMonths(Date(1999, 8, 6)) == -1);
6379 assert(date.diffMonths(Date(1999, 9, 6)) == -2);
6380 assert(date.diffMonths(Date(1999, 10, 6)) == -3);
6381 assert(date.diffMonths(Date(1999, 11, 6)) == -4);
6382 assert(date.diffMonths(Date(1999, 12, 6)) == -5);
6383 assert(date.diffMonths(Date(2000, 1, 6)) == -6);
6384 assert(date.diffMonths(Date(2000, 2, 6)) == -7);
6385 assert(date.diffMonths(Date(2000, 3, 6)) == -8);
6386 assert(date.diffMonths(Date(2000, 4, 6)) == -9);
6387 assert(date.diffMonths(Date(2000, 5, 6)) == -10);
6388 assert(date.diffMonths(Date(2000, 6, 6)) == -11);
6389 assert(date.diffMonths(Date(2000, 7, 6)) == -12);
6390 assert(date.diffMonths(Date(2000, 8, 6)) == -13);
6392 assert(Date(1998, 6, 5).diffMonths(date) == -13);
6393 assert(Date(1998, 7, 5).diffMonths(date) == -12);
6394 assert(Date(1998, 8, 5).diffMonths(date) == -11);
6395 assert(Date(1998, 9, 5).diffMonths(date) == -10);
6396 assert(Date(1998, 10, 5).diffMonths(date) == -9);
6397 assert(Date(1998, 11, 5).diffMonths(date) == -8);
6398 assert(Date(1998, 12, 5).diffMonths(date) == -7);
6399 assert(Date(1999, 1, 5).diffMonths(date) == -6);
6400 assert(Date(1999, 2, 6).diffMonths(date) == -5);
6401 assert(Date(1999, 3, 6).diffMonths(date) == -4);
6402 assert(Date(1999, 4, 6).diffMonths(date) == -3);
6403 assert(Date(1999, 5, 6).diffMonths(date) == -2);
6404 assert(Date(1999, 6, 6).diffMonths(date) == -1);
6405 assert(Date(1999, 8, 6).diffMonths(date) == 1);
6406 assert(Date(1999, 9, 6).diffMonths(date) == 2);
6407 assert(Date(1999, 10, 6).diffMonths(date) == 3);
6408 assert(Date(1999, 11, 6).diffMonths(date) == 4);
6409 assert(Date(1999, 12, 6).diffMonths(date) == 5);
6410 assert(Date(2000, 1, 6).diffMonths(date) == 6);
6411 assert(Date(2000, 2, 6).diffMonths(date) == 7);
6412 assert(Date(2000, 3, 6).diffMonths(date) == 8);
6413 assert(Date(2000, 4, 6).diffMonths(date) == 9);
6414 assert(Date(2000, 5, 6).diffMonths(date) == 10);
6415 assert(Date(2000, 6, 6).diffMonths(date) == 11);
6416 assert(Date(2000, 7, 6).diffMonths(date) == 12);
6417 assert(Date(2000, 8, 6).diffMonths(date) == 13);
6419 assert(date.diffMonths(Date(1999, 6, 30)) == 1);
6420 assert(date.diffMonths(Date(1999, 7, 1)) == 0);
6421 assert(date.diffMonths(Date(1999, 7, 6)) == 0);
6422 assert(date.diffMonths(Date(1999, 7, 11)) == 0);
6423 assert(date.diffMonths(Date(1999, 7, 16)) == 0);
6424 assert(date.diffMonths(Date(1999, 7, 21)) == 0);
6425 assert(date.diffMonths(Date(1999, 7, 26)) == 0);
6426 assert(date.diffMonths(Date(1999, 7, 31)) == 0);
6427 assert(date.diffMonths(Date(1999, 8, 1)) == -1);
6429 assert(date.diffMonths(Date(1990, 6, 30)) == 109);
6430 assert(date.diffMonths(Date(1990, 7, 1)) == 108);
6431 assert(date.diffMonths(Date(1990, 7, 6)) == 108);
6432 assert(date.diffMonths(Date(1990, 7, 11)) == 108);
6433 assert(date.diffMonths(Date(1990, 7, 16)) == 108);
6434 assert(date.diffMonths(Date(1990, 7, 21)) == 108);
6435 assert(date.diffMonths(Date(1990, 7, 26)) == 108);
6436 assert(date.diffMonths(Date(1990, 7, 31)) == 108);
6437 assert(date.diffMonths(Date(1990, 8, 1)) == 107);
6439 assert(Date(1999, 6, 30).diffMonths(date) == -1);
6440 assert(Date(1999, 7, 1).diffMonths(date) == 0);
6441 assert(Date(1999, 7, 6).diffMonths(date) == 0);
6442 assert(Date(1999, 7, 11).diffMonths(date) == 0);
6443 assert(Date(1999, 7, 16).diffMonths(date) == 0);
6444 assert(Date(1999, 7, 21).diffMonths(date) == 0);
6445 assert(Date(1999, 7, 26).diffMonths(date) == 0);
6446 assert(Date(1999, 7, 31).diffMonths(date) == 0);
6447 assert(Date(1999, 8, 1).diffMonths(date) == 1);
6449 assert(Date(1990, 6, 30).diffMonths(date) == -109);
6450 assert(Date(1990, 7, 1).diffMonths(date) == -108);
6451 assert(Date(1990, 7, 6).diffMonths(date) == -108);
6452 assert(Date(1990, 7, 11).diffMonths(date) == -108);
6453 assert(Date(1990, 7, 16).diffMonths(date) == -108);
6454 assert(Date(1990, 7, 21).diffMonths(date) == -108);
6455 assert(Date(1990, 7, 26).diffMonths(date) == -108);
6456 assert(Date(1990, 7, 31).diffMonths(date) == -108);
6457 assert(Date(1990, 8, 1).diffMonths(date) == -107);
6459 // Test B.C.
6460 auto dateBC = Date(-1999, 7, 6);
6462 assert(dateBC.diffMonths(Date(-2000, 6, 5)) == 13);
6463 assert(dateBC.diffMonths(Date(-2000, 7, 5)) == 12);
6464 assert(dateBC.diffMonths(Date(-2000, 8, 5)) == 11);
6465 assert(dateBC.diffMonths(Date(-2000, 9, 5)) == 10);
6466 assert(dateBC.diffMonths(Date(-2000, 10, 5)) == 9);
6467 assert(dateBC.diffMonths(Date(-2000, 11, 5)) == 8);
6468 assert(dateBC.diffMonths(Date(-2000, 12, 5)) == 7);
6469 assert(dateBC.diffMonths(Date(-1999, 1, 5)) == 6);
6470 assert(dateBC.diffMonths(Date(-1999, 2, 6)) == 5);
6471 assert(dateBC.diffMonths(Date(-1999, 3, 6)) == 4);
6472 assert(dateBC.diffMonths(Date(-1999, 4, 6)) == 3);
6473 assert(dateBC.diffMonths(Date(-1999, 5, 6)) == 2);
6474 assert(dateBC.diffMonths(Date(-1999, 6, 6)) == 1);
6475 assert(dateBC.diffMonths(dateBC) == 0);
6476 assert(dateBC.diffMonths(Date(-1999, 8, 6)) == -1);
6477 assert(dateBC.diffMonths(Date(-1999, 9, 6)) == -2);
6478 assert(dateBC.diffMonths(Date(-1999, 10, 6)) == -3);
6479 assert(dateBC.diffMonths(Date(-1999, 11, 6)) == -4);
6480 assert(dateBC.diffMonths(Date(-1999, 12, 6)) == -5);
6481 assert(dateBC.diffMonths(Date(-1998, 1, 6)) == -6);
6482 assert(dateBC.diffMonths(Date(-1998, 2, 6)) == -7);
6483 assert(dateBC.diffMonths(Date(-1998, 3, 6)) == -8);
6484 assert(dateBC.diffMonths(Date(-1998, 4, 6)) == -9);
6485 assert(dateBC.diffMonths(Date(-1998, 5, 6)) == -10);
6486 assert(dateBC.diffMonths(Date(-1998, 6, 6)) == -11);
6487 assert(dateBC.diffMonths(Date(-1998, 7, 6)) == -12);
6488 assert(dateBC.diffMonths(Date(-1998, 8, 6)) == -13);
6490 assert(Date(-2000, 6, 5).diffMonths(dateBC) == -13);
6491 assert(Date(-2000, 7, 5).diffMonths(dateBC) == -12);
6492 assert(Date(-2000, 8, 5).diffMonths(dateBC) == -11);
6493 assert(Date(-2000, 9, 5).diffMonths(dateBC) == -10);
6494 assert(Date(-2000, 10, 5).diffMonths(dateBC) == -9);
6495 assert(Date(-2000, 11, 5).diffMonths(dateBC) == -8);
6496 assert(Date(-2000, 12, 5).diffMonths(dateBC) == -7);
6497 assert(Date(-1999, 1, 5).diffMonths(dateBC) == -6);
6498 assert(Date(-1999, 2, 6).diffMonths(dateBC) == -5);
6499 assert(Date(-1999, 3, 6).diffMonths(dateBC) == -4);
6500 assert(Date(-1999, 4, 6).diffMonths(dateBC) == -3);
6501 assert(Date(-1999, 5, 6).diffMonths(dateBC) == -2);
6502 assert(Date(-1999, 6, 6).diffMonths(dateBC) == -1);
6503 assert(Date(-1999, 8, 6).diffMonths(dateBC) == 1);
6504 assert(Date(-1999, 9, 6).diffMonths(dateBC) == 2);
6505 assert(Date(-1999, 10, 6).diffMonths(dateBC) == 3);
6506 assert(Date(-1999, 11, 6).diffMonths(dateBC) == 4);
6507 assert(Date(-1999, 12, 6).diffMonths(dateBC) == 5);
6508 assert(Date(-1998, 1, 6).diffMonths(dateBC) == 6);
6509 assert(Date(-1998, 2, 6).diffMonths(dateBC) == 7);
6510 assert(Date(-1998, 3, 6).diffMonths(dateBC) == 8);
6511 assert(Date(-1998, 4, 6).diffMonths(dateBC) == 9);
6512 assert(Date(-1998, 5, 6).diffMonths(dateBC) == 10);
6513 assert(Date(-1998, 6, 6).diffMonths(dateBC) == 11);
6514 assert(Date(-1998, 7, 6).diffMonths(dateBC) == 12);
6515 assert(Date(-1998, 8, 6).diffMonths(dateBC) == 13);
6517 assert(dateBC.diffMonths(Date(-1999, 6, 30)) == 1);
6518 assert(dateBC.diffMonths(Date(-1999, 7, 1)) == 0);
6519 assert(dateBC.diffMonths(Date(-1999, 7, 6)) == 0);
6520 assert(dateBC.diffMonths(Date(-1999, 7, 11)) == 0);
6521 assert(dateBC.diffMonths(Date(-1999, 7, 16)) == 0);
6522 assert(dateBC.diffMonths(Date(-1999, 7, 21)) == 0);
6523 assert(dateBC.diffMonths(Date(-1999, 7, 26)) == 0);
6524 assert(dateBC.diffMonths(Date(-1999, 7, 31)) == 0);
6525 assert(dateBC.diffMonths(Date(-1999, 8, 1)) == -1);
6527 assert(dateBC.diffMonths(Date(-2008, 6, 30)) == 109);
6528 assert(dateBC.diffMonths(Date(-2008, 7, 1)) == 108);
6529 assert(dateBC.diffMonths(Date(-2008, 7, 6)) == 108);
6530 assert(dateBC.diffMonths(Date(-2008, 7, 11)) == 108);
6531 assert(dateBC.diffMonths(Date(-2008, 7, 16)) == 108);
6532 assert(dateBC.diffMonths(Date(-2008, 7, 21)) == 108);
6533 assert(dateBC.diffMonths(Date(-2008, 7, 26)) == 108);
6534 assert(dateBC.diffMonths(Date(-2008, 7, 31)) == 108);
6535 assert(dateBC.diffMonths(Date(-2008, 8, 1)) == 107);
6537 assert(Date(-1999, 6, 30).diffMonths(dateBC) == -1);
6538 assert(Date(-1999, 7, 1).diffMonths(dateBC) == 0);
6539 assert(Date(-1999, 7, 6).diffMonths(dateBC) == 0);
6540 assert(Date(-1999, 7, 11).diffMonths(dateBC) == 0);
6541 assert(Date(-1999, 7, 16).diffMonths(dateBC) == 0);
6542 assert(Date(-1999, 7, 21).diffMonths(dateBC) == 0);
6543 assert(Date(-1999, 7, 26).diffMonths(dateBC) == 0);
6544 assert(Date(-1999, 7, 31).diffMonths(dateBC) == 0);
6545 assert(Date(-1999, 8, 1).diffMonths(dateBC) == 1);
6547 assert(Date(-2008, 6, 30).diffMonths(dateBC) == -109);
6548 assert(Date(-2008, 7, 1).diffMonths(dateBC) == -108);
6549 assert(Date(-2008, 7, 6).diffMonths(dateBC) == -108);
6550 assert(Date(-2008, 7, 11).diffMonths(dateBC) == -108);
6551 assert(Date(-2008, 7, 16).diffMonths(dateBC) == -108);
6552 assert(Date(-2008, 7, 21).diffMonths(dateBC) == -108);
6553 assert(Date(-2008, 7, 26).diffMonths(dateBC) == -108);
6554 assert(Date(-2008, 7, 31).diffMonths(dateBC) == -108);
6555 assert(Date(-2008, 8, 1).diffMonths(dateBC) == -107);
6557 // Test Both
6558 assert(Date(3, 3, 3).diffMonths(Date(-5, 5, 5)) == 94);
6559 assert(Date(-5, 5, 5).diffMonths(Date(3, 3, 3)) == -94);
6561 const cdate = Date(1999, 7, 6);
6562 immutable idate = Date(1999, 7, 6);
6563 assert(date.diffMonths(date) == 0);
6564 assert(cdate.diffMonths(date) == 0);
6565 assert(idate.diffMonths(date) == 0);
6567 assert(date.diffMonths(cdate) == 0);
6568 assert(cdate.diffMonths(cdate) == 0);
6569 assert(idate.diffMonths(cdate) == 0);
6571 assert(date.diffMonths(idate) == 0);
6572 assert(cdate.diffMonths(idate) == 0);
6573 assert(idate.diffMonths(idate) == 0);
6578 Whether this $(LREF Date) is in a leap year.
6580 @property bool isLeapYear() const @safe pure nothrow @nogc
6582 return yearIsLeapYear(_year);
6585 @safe unittest
6587 auto date = Date(1999, 7, 6);
6588 const cdate = Date(1999, 7, 6);
6589 immutable idate = Date(1999, 7, 6);
6590 static assert(!__traits(compiles, date.isLeapYear = true));
6591 static assert(!__traits(compiles, cdate.isLeapYear = true));
6592 static assert(!__traits(compiles, idate.isLeapYear = true));
6597 Day of the week this $(LREF Date) is on.
6599 @property DayOfWeek dayOfWeek() const @safe pure nothrow @nogc
6601 return getDayOfWeek(dayOfGregorianCal);
6604 @safe unittest
6606 const cdate = Date(1999, 7, 6);
6607 immutable idate = Date(1999, 7, 6);
6608 assert(cdate.dayOfWeek == DayOfWeek.tue);
6609 static assert(!__traits(compiles, cdate.dayOfWeek = DayOfWeek.sun));
6610 assert(idate.dayOfWeek == DayOfWeek.tue);
6611 static assert(!__traits(compiles, idate.dayOfWeek = DayOfWeek.sun));
6616 Day of the year this $(LREF Date) is on.
6618 @property ushort dayOfYear() const @safe pure nothrow @nogc
6620 if (_month >= Month.jan && _month <= Month.dec)
6622 immutable int[] lastDay = isLeapYear ? lastDayLeap : lastDayNonLeap;
6623 auto monthIndex = _month - Month.jan;
6625 return cast(ushort)(lastDay[monthIndex] + _day);
6627 assert(0, "Invalid month.");
6631 @safe unittest
6633 assert(Date(1999, 1, 1).dayOfYear == 1);
6634 assert(Date(1999, 12, 31).dayOfYear == 365);
6635 assert(Date(2000, 12, 31).dayOfYear == 366);
6638 @safe unittest
6640 import std.algorithm.iteration : filter;
6641 import std.range : chain;
6643 foreach (year; filter!((a){return !yearIsLeapYear(a);})(chain(testYearsBC, testYearsAD)))
6645 foreach (doy; testDaysOfYear)
6646 assert(Date(year, doy.md.month, doy.md.day).dayOfYear == doy.day);
6649 foreach (year; filter!((a){return yearIsLeapYear(a);})(chain(testYearsBC, testYearsAD)))
6651 foreach (doy; testDaysOfLeapYear)
6652 assert(Date(year, doy.md.month, doy.md.day).dayOfYear == doy.day);
6655 const cdate = Date(1999, 7, 6);
6656 immutable idate = Date(1999, 7, 6);
6657 assert(cdate.dayOfYear == 187);
6658 assert(idate.dayOfYear == 187);
6662 Day of the year.
6664 Params:
6665 day = The day of the year to set which day of the year this
6666 $(LREF Date) is on.
6668 Throws:
6669 $(REF DateTimeException,std,datetime,date) if the given day is an
6670 invalid day of the year.
6672 @property void dayOfYear(int day) @safe pure
6674 setDayOfYear!true(day);
6677 private void setDayOfYear(bool useExceptions = false)(int day)
6679 immutable int[] lastDay = isLeapYear ? lastDayLeap : lastDayNonLeap;
6681 bool dayOutOfRange = day <= 0 || day > (isLeapYear ? daysInLeapYear : daysInYear);
6682 enum errorMsg = "Invalid day of the year.";
6684 static if (useExceptions)
6686 if (dayOutOfRange) throw new DateTimeException(errorMsg);
6688 else
6690 assert(!dayOutOfRange, errorMsg);
6693 foreach (i; 1 .. lastDay.length)
6695 if (day <= lastDay[i])
6697 _month = cast(Month)(cast(int) Month.jan + i - 1);
6698 _day = cast(ubyte)(day - lastDay[i - 1]);
6699 return;
6702 assert(0, "Invalid day of the year.");
6705 @safe unittest
6707 static void test(Date date, int day, MonthDay expected, size_t line = __LINE__)
6709 date.dayOfYear = day;
6710 assert(date.month == expected.month);
6711 assert(date.day == expected.day);
6714 foreach (doy; testDaysOfYear)
6716 test(Date(1999, 1, 1), doy.day, doy.md);
6717 test(Date(-1, 1, 1), doy.day, doy.md);
6720 foreach (doy; testDaysOfLeapYear)
6722 test(Date(2000, 1, 1), doy.day, doy.md);
6723 test(Date(-4, 1, 1), doy.day, doy.md);
6726 const cdate = Date(1999, 7, 6);
6727 immutable idate = Date(1999, 7, 6);
6728 static assert(!__traits(compiles, cdate.dayOfYear = 187));
6729 static assert(!__traits(compiles, idate.dayOfYear = 187));
6734 The Xth day of the Gregorian Calendar that this $(LREF Date) is on.
6736 @property int dayOfGregorianCal() const @safe pure nothrow @nogc
6738 if (isAD)
6740 if (_year == 1)
6741 return dayOfYear;
6743 int years = _year - 1;
6744 auto days = (years / 400) * daysIn400Years;
6745 years %= 400;
6747 days += (years / 100) * daysIn100Years;
6748 years %= 100;
6750 days += (years / 4) * daysIn4Years;
6751 years %= 4;
6753 days += years * daysInYear;
6755 days += dayOfYear;
6757 return days;
6759 else if (_year == 0)
6760 return dayOfYear - daysInLeapYear;
6761 else
6763 int years = _year;
6764 auto days = (years / 400) * daysIn400Years;
6765 years %= 400;
6767 days += (years / 100) * daysIn100Years;
6768 years %= 100;
6770 days += (years / 4) * daysIn4Years;
6771 years %= 4;
6773 if (years < 0)
6775 days -= daysInLeapYear;
6776 ++years;
6778 days += years * daysInYear;
6780 days -= daysInYear - dayOfYear;
6782 else
6783 days -= daysInLeapYear - dayOfYear;
6785 return days;
6790 @safe unittest
6792 assert(Date(1, 1, 1).dayOfGregorianCal == 1);
6793 assert(Date(1, 12, 31).dayOfGregorianCal == 365);
6794 assert(Date(2, 1, 1).dayOfGregorianCal == 366);
6796 assert(Date(0, 12, 31).dayOfGregorianCal == 0);
6797 assert(Date(0, 1, 1).dayOfGregorianCal == -365);
6798 assert(Date(-1, 12, 31).dayOfGregorianCal == -366);
6800 assert(Date(2000, 1, 1).dayOfGregorianCal == 730_120);
6801 assert(Date(2010, 12, 31).dayOfGregorianCal == 734_137);
6804 @safe unittest
6806 import std.range : chain;
6808 foreach (gd; chain(testGregDaysBC, testGregDaysAD))
6809 assert(gd.date.dayOfGregorianCal == gd.day);
6811 auto date = Date(1999, 7, 6);
6812 const cdate = Date(1999, 7, 6);
6813 immutable idate = Date(1999, 7, 6);
6814 assert(date.dayOfGregorianCal == 729_941);
6815 assert(cdate.dayOfGregorianCal == 729_941);
6816 assert(idate.dayOfGregorianCal == 729_941);
6820 The Xth day of the Gregorian Calendar that this $(LREF Date) is on.
6822 Params:
6823 day = The day of the Gregorian Calendar to set this $(LREF Date) to.
6825 @property void dayOfGregorianCal(int day) @safe pure nothrow @nogc
6827 this = Date(day);
6831 @safe unittest
6833 auto date = Date.init;
6834 date.dayOfGregorianCal = 1;
6835 assert(date == Date(1, 1, 1));
6837 date.dayOfGregorianCal = 365;
6838 assert(date == Date(1, 12, 31));
6840 date.dayOfGregorianCal = 366;
6841 assert(date == Date(2, 1, 1));
6843 date.dayOfGregorianCal = 0;
6844 assert(date == Date(0, 12, 31));
6846 date.dayOfGregorianCal = -365;
6847 assert(date == Date(-0, 1, 1));
6849 date.dayOfGregorianCal = -366;
6850 assert(date == Date(-1, 12, 31));
6852 date.dayOfGregorianCal = 730_120;
6853 assert(date == Date(2000, 1, 1));
6855 date.dayOfGregorianCal = 734_137;
6856 assert(date == Date(2010, 12, 31));
6859 @safe unittest
6861 auto date = Date(1999, 7, 6);
6862 const cdate = Date(1999, 7, 6);
6863 immutable idate = Date(1999, 7, 6);
6864 date.dayOfGregorianCal = 187;
6865 assert(date.dayOfGregorianCal == 187);
6866 static assert(!__traits(compiles, cdate.dayOfGregorianCal = 187));
6867 static assert(!__traits(compiles, idate.dayOfGregorianCal = 187));
6872 The ISO 8601 week of the year that this $(LREF Date) is in.
6874 See_Also:
6875 $(HTTP en.wikipedia.org/wiki/ISO_week_date, ISO Week Date)
6877 @property ubyte isoWeek() const @safe pure nothrow
6879 immutable weekday = dayOfWeek;
6880 immutable adjustedWeekday = weekday == DayOfWeek.sun ? 7 : weekday;
6881 immutable week = (dayOfYear - adjustedWeekday + 10) / 7;
6885 if (week == 53)
6887 switch (Date(_year + 1, 1, 1).dayOfWeek)
6889 case DayOfWeek.mon:
6890 case DayOfWeek.tue:
6891 case DayOfWeek.wed:
6892 case DayOfWeek.thu:
6893 return 1;
6894 case DayOfWeek.fri:
6895 case DayOfWeek.sat:
6896 case DayOfWeek.sun:
6897 return 53;
6898 default:
6899 assert(0, "Invalid ISO Week");
6902 else if (week > 0)
6903 return cast(ubyte) week;
6904 else
6905 return Date(_year - 1, 12, 31).isoWeek;
6907 catch (Exception e)
6908 assert(0, "Date's constructor threw.");
6911 @safe unittest
6913 // Test A.D.
6914 assert(Date(2009, 12, 28).isoWeek == 53);
6915 assert(Date(2009, 12, 29).isoWeek == 53);
6916 assert(Date(2009, 12, 30).isoWeek == 53);
6917 assert(Date(2009, 12, 31).isoWeek == 53);
6918 assert(Date(2010, 1, 1).isoWeek == 53);
6919 assert(Date(2010, 1, 2).isoWeek == 53);
6920 assert(Date(2010, 1, 3).isoWeek == 53);
6921 assert(Date(2010, 1, 4).isoWeek == 1);
6922 assert(Date(2010, 1, 5).isoWeek == 1);
6923 assert(Date(2010, 1, 6).isoWeek == 1);
6924 assert(Date(2010, 1, 7).isoWeek == 1);
6925 assert(Date(2010, 1, 8).isoWeek == 1);
6926 assert(Date(2010, 1, 9).isoWeek == 1);
6927 assert(Date(2010, 1, 10).isoWeek == 1);
6928 assert(Date(2010, 1, 11).isoWeek == 2);
6929 assert(Date(2010, 12, 31).isoWeek == 52);
6931 assert(Date(2004, 12, 26).isoWeek == 52);
6932 assert(Date(2004, 12, 27).isoWeek == 53);
6933 assert(Date(2004, 12, 28).isoWeek == 53);
6934 assert(Date(2004, 12, 29).isoWeek == 53);
6935 assert(Date(2004, 12, 30).isoWeek == 53);
6936 assert(Date(2004, 12, 31).isoWeek == 53);
6937 assert(Date(2005, 1, 1).isoWeek == 53);
6938 assert(Date(2005, 1, 2).isoWeek == 53);
6940 assert(Date(2005, 12, 31).isoWeek == 52);
6941 assert(Date(2007, 1, 1).isoWeek == 1);
6943 assert(Date(2007, 12, 30).isoWeek == 52);
6944 assert(Date(2007, 12, 31).isoWeek == 1);
6945 assert(Date(2008, 1, 1).isoWeek == 1);
6947 assert(Date(2008, 12, 28).isoWeek == 52);
6948 assert(Date(2008, 12, 29).isoWeek == 1);
6949 assert(Date(2008, 12, 30).isoWeek == 1);
6950 assert(Date(2008, 12, 31).isoWeek == 1);
6951 assert(Date(2009, 1, 1).isoWeek == 1);
6952 assert(Date(2009, 1, 2).isoWeek == 1);
6953 assert(Date(2009, 1, 3).isoWeek == 1);
6954 assert(Date(2009, 1, 4).isoWeek == 1);
6956 // Test B.C.
6957 // The algorithm should work identically for both A.D. and B.C. since
6958 // it doesn't really take the year into account, so B.C. testing
6959 // probably isn't really needed.
6960 assert(Date(0, 12, 31).isoWeek == 52);
6961 assert(Date(0, 1, 4).isoWeek == 1);
6962 assert(Date(0, 1, 1).isoWeek == 52);
6964 const cdate = Date(1999, 7, 6);
6965 immutable idate = Date(1999, 7, 6);
6966 assert(cdate.isoWeek == 27);
6967 static assert(!__traits(compiles, cdate.isoWeek = 3));
6968 assert(idate.isoWeek == 27);
6969 static assert(!__traits(compiles, idate.isoWeek = 3));
6974 $(LREF Date) for the last day in the month that this $(LREF Date) is in.
6976 @property Date endOfMonth() const @safe pure nothrow
6979 return Date(_year, _month, maxDay(_year, _month));
6980 catch (Exception e)
6981 assert(0, "Date's constructor threw.");
6985 @safe unittest
6987 assert(Date(1999, 1, 6).endOfMonth == Date(1999, 1, 31));
6988 assert(Date(1999, 2, 7).endOfMonth == Date(1999, 2, 28));
6989 assert(Date(2000, 2, 7).endOfMonth == Date(2000, 2, 29));
6990 assert(Date(2000, 6, 4).endOfMonth == Date(2000, 6, 30));
6993 @safe unittest
6995 // Test A.D.
6996 assert(Date(1999, 1, 1).endOfMonth == Date(1999, 1, 31));
6997 assert(Date(1999, 2, 1).endOfMonth == Date(1999, 2, 28));
6998 assert(Date(2000, 2, 1).endOfMonth == Date(2000, 2, 29));
6999 assert(Date(1999, 3, 1).endOfMonth == Date(1999, 3, 31));
7000 assert(Date(1999, 4, 1).endOfMonth == Date(1999, 4, 30));
7001 assert(Date(1999, 5, 1).endOfMonth == Date(1999, 5, 31));
7002 assert(Date(1999, 6, 1).endOfMonth == Date(1999, 6, 30));
7003 assert(Date(1999, 7, 1).endOfMonth == Date(1999, 7, 31));
7004 assert(Date(1999, 8, 1).endOfMonth == Date(1999, 8, 31));
7005 assert(Date(1999, 9, 1).endOfMonth == Date(1999, 9, 30));
7006 assert(Date(1999, 10, 1).endOfMonth == Date(1999, 10, 31));
7007 assert(Date(1999, 11, 1).endOfMonth == Date(1999, 11, 30));
7008 assert(Date(1999, 12, 1).endOfMonth == Date(1999, 12, 31));
7010 // Test B.C.
7011 assert(Date(-1999, 1, 1).endOfMonth == Date(-1999, 1, 31));
7012 assert(Date(-1999, 2, 1).endOfMonth == Date(-1999, 2, 28));
7013 assert(Date(-2000, 2, 1).endOfMonth == Date(-2000, 2, 29));
7014 assert(Date(-1999, 3, 1).endOfMonth == Date(-1999, 3, 31));
7015 assert(Date(-1999, 4, 1).endOfMonth == Date(-1999, 4, 30));
7016 assert(Date(-1999, 5, 1).endOfMonth == Date(-1999, 5, 31));
7017 assert(Date(-1999, 6, 1).endOfMonth == Date(-1999, 6, 30));
7018 assert(Date(-1999, 7, 1).endOfMonth == Date(-1999, 7, 31));
7019 assert(Date(-1999, 8, 1).endOfMonth == Date(-1999, 8, 31));
7020 assert(Date(-1999, 9, 1).endOfMonth == Date(-1999, 9, 30));
7021 assert(Date(-1999, 10, 1).endOfMonth == Date(-1999, 10, 31));
7022 assert(Date(-1999, 11, 1).endOfMonth == Date(-1999, 11, 30));
7023 assert(Date(-1999, 12, 1).endOfMonth == Date(-1999, 12, 31));
7025 const cdate = Date(1999, 7, 6);
7026 immutable idate = Date(1999, 7, 6);
7027 static assert(!__traits(compiles, cdate.endOfMonth = Date(1999, 7, 30)));
7028 static assert(!__traits(compiles, idate.endOfMonth = Date(1999, 7, 30)));
7033 The last day in the month that this $(LREF Date) is in.
7035 @property ubyte daysInMonth() const @safe pure nothrow @nogc
7037 return maxDay(_year, _month);
7041 @safe unittest
7043 assert(Date(1999, 1, 6).daysInMonth == 31);
7044 assert(Date(1999, 2, 7).daysInMonth == 28);
7045 assert(Date(2000, 2, 7).daysInMonth == 29);
7046 assert(Date(2000, 6, 4).daysInMonth == 30);
7049 @safe unittest
7051 // Test A.D.
7052 assert(Date(1999, 1, 1).daysInMonth == 31);
7053 assert(Date(1999, 2, 1).daysInMonth == 28);
7054 assert(Date(2000, 2, 1).daysInMonth == 29);
7055 assert(Date(1999, 3, 1).daysInMonth == 31);
7056 assert(Date(1999, 4, 1).daysInMonth == 30);
7057 assert(Date(1999, 5, 1).daysInMonth == 31);
7058 assert(Date(1999, 6, 1).daysInMonth == 30);
7059 assert(Date(1999, 7, 1).daysInMonth == 31);
7060 assert(Date(1999, 8, 1).daysInMonth == 31);
7061 assert(Date(1999, 9, 1).daysInMonth == 30);
7062 assert(Date(1999, 10, 1).daysInMonth == 31);
7063 assert(Date(1999, 11, 1).daysInMonth == 30);
7064 assert(Date(1999, 12, 1).daysInMonth == 31);
7066 // Test B.C.
7067 assert(Date(-1999, 1, 1).daysInMonth == 31);
7068 assert(Date(-1999, 2, 1).daysInMonth == 28);
7069 assert(Date(-2000, 2, 1).daysInMonth == 29);
7070 assert(Date(-1999, 3, 1).daysInMonth == 31);
7071 assert(Date(-1999, 4, 1).daysInMonth == 30);
7072 assert(Date(-1999, 5, 1).daysInMonth == 31);
7073 assert(Date(-1999, 6, 1).daysInMonth == 30);
7074 assert(Date(-1999, 7, 1).daysInMonth == 31);
7075 assert(Date(-1999, 8, 1).daysInMonth == 31);
7076 assert(Date(-1999, 9, 1).daysInMonth == 30);
7077 assert(Date(-1999, 10, 1).daysInMonth == 31);
7078 assert(Date(-1999, 11, 1).daysInMonth == 30);
7079 assert(Date(-1999, 12, 1).daysInMonth == 31);
7081 const cdate = Date(1999, 7, 6);
7082 immutable idate = Date(1999, 7, 6);
7083 static assert(!__traits(compiles, cdate.daysInMonth = 30));
7084 static assert(!__traits(compiles, idate.daysInMonth = 30));
7089 Whether the current year is a date in A.D.
7091 @property bool isAD() const @safe pure nothrow @nogc
7093 return _year > 0;
7097 @safe unittest
7099 assert(Date(1, 1, 1).isAD);
7100 assert(Date(2010, 12, 31).isAD);
7101 assert(!Date(0, 12, 31).isAD);
7102 assert(!Date(-2010, 1, 1).isAD);
7105 @safe unittest
7107 assert(Date(2010, 7, 4).isAD);
7108 assert(Date(1, 1, 1).isAD);
7109 assert(!Date(0, 1, 1).isAD);
7110 assert(!Date(-1, 1, 1).isAD);
7111 assert(!Date(-2010, 7, 4).isAD);
7113 const cdate = Date(1999, 7, 6);
7114 immutable idate = Date(1999, 7, 6);
7115 assert(cdate.isAD);
7116 assert(idate.isAD);
7121 The $(HTTP en.wikipedia.org/wiki/Julian_day, Julian day) for this
7122 $(LREF Date) at noon (since the Julian day changes at noon).
7124 @property long julianDay() const @safe pure nothrow @nogc
7126 return dayOfGregorianCal + 1_721_425;
7129 @safe unittest
7131 assert(Date(-4713, 11, 24).julianDay == 0);
7132 assert(Date(0, 12, 31).julianDay == 1_721_425);
7133 assert(Date(1, 1, 1).julianDay == 1_721_426);
7134 assert(Date(1582, 10, 15).julianDay == 2_299_161);
7135 assert(Date(1858, 11, 17).julianDay == 2_400_001);
7136 assert(Date(1982, 1, 4).julianDay == 2_444_974);
7137 assert(Date(1996, 3, 31).julianDay == 2_450_174);
7138 assert(Date(2010, 8, 24).julianDay == 2_455_433);
7140 const cdate = Date(1999, 7, 6);
7141 immutable idate = Date(1999, 7, 6);
7142 assert(cdate.julianDay == 2_451_366);
7143 assert(idate.julianDay == 2_451_366);
7148 The modified $(HTTP en.wikipedia.org/wiki/Julian_day, Julian day) for
7149 any time on this date (since, the modified Julian day changes at
7150 midnight).
7152 @property long modJulianDay() const @safe pure nothrow @nogc
7154 return julianDay - 2_400_001;
7157 @safe unittest
7159 assert(Date(1858, 11, 17).modJulianDay == 0);
7160 assert(Date(2010, 8, 24).modJulianDay == 55_432);
7162 const cdate = Date(1999, 7, 6);
7163 immutable idate = Date(1999, 7, 6);
7164 assert(cdate.modJulianDay == 51_365);
7165 assert(idate.modJulianDay == 51_365);
7170 Converts this $(LREF Date) to a string with the format YYYYMMDD.
7172 string toISOString() const @safe pure nothrow
7174 import std.format : format;
7177 if (_year >= 0)
7179 if (_year < 10_000)
7180 return format("%04d%02d%02d", _year, _month, _day);
7181 else
7182 return format("+%05d%02d%02d", _year, _month, _day);
7184 else if (_year > -10_000)
7185 return format("%05d%02d%02d", _year, _month, _day);
7186 else
7187 return format("%06d%02d%02d", _year, _month, _day);
7189 catch (Exception e)
7190 assert(0, "format() threw.");
7194 @safe unittest
7196 assert(Date(2010, 7, 4).toISOString() == "20100704");
7197 assert(Date(1998, 12, 25).toISOString() == "19981225");
7198 assert(Date(0, 1, 5).toISOString() == "00000105");
7199 assert(Date(-4, 1, 5).toISOString() == "-00040105");
7202 @safe unittest
7204 // Test A.D.
7205 assert(Date(9, 12, 4).toISOString() == "00091204");
7206 assert(Date(99, 12, 4).toISOString() == "00991204");
7207 assert(Date(999, 12, 4).toISOString() == "09991204");
7208 assert(Date(9999, 7, 4).toISOString() == "99990704");
7209 assert(Date(10000, 10, 20).toISOString() == "+100001020");
7211 // Test B.C.
7212 assert(Date(0, 12, 4).toISOString() == "00001204");
7213 assert(Date(-9, 12, 4).toISOString() == "-00091204");
7214 assert(Date(-99, 12, 4).toISOString() == "-00991204");
7215 assert(Date(-999, 12, 4).toISOString() == "-09991204");
7216 assert(Date(-9999, 7, 4).toISOString() == "-99990704");
7217 assert(Date(-10000, 10, 20).toISOString() == "-100001020");
7219 const cdate = Date(1999, 7, 6);
7220 immutable idate = Date(1999, 7, 6);
7221 assert(cdate.toISOString() == "19990706");
7222 assert(idate.toISOString() == "19990706");
7226 Converts this $(LREF Date) to a string with the format YYYY-MM-DD.
7228 string toISOExtString() const @safe pure nothrow
7230 import std.format : format;
7233 if (_year >= 0)
7235 if (_year < 10_000)
7236 return format("%04d-%02d-%02d", _year, _month, _day);
7237 else
7238 return format("+%05d-%02d-%02d", _year, _month, _day);
7240 else if (_year > -10_000)
7241 return format("%05d-%02d-%02d", _year, _month, _day);
7242 else
7243 return format("%06d-%02d-%02d", _year, _month, _day);
7245 catch (Exception e)
7246 assert(0, "format() threw.");
7250 @safe unittest
7252 assert(Date(2010, 7, 4).toISOExtString() == "2010-07-04");
7253 assert(Date(1998, 12, 25).toISOExtString() == "1998-12-25");
7254 assert(Date(0, 1, 5).toISOExtString() == "0000-01-05");
7255 assert(Date(-4, 1, 5).toISOExtString() == "-0004-01-05");
7258 @safe unittest
7260 // Test A.D.
7261 assert(Date(9, 12, 4).toISOExtString() == "0009-12-04");
7262 assert(Date(99, 12, 4).toISOExtString() == "0099-12-04");
7263 assert(Date(999, 12, 4).toISOExtString() == "0999-12-04");
7264 assert(Date(9999, 7, 4).toISOExtString() == "9999-07-04");
7265 assert(Date(10000, 10, 20).toISOExtString() == "+10000-10-20");
7267 // Test B.C.
7268 assert(Date(0, 12, 4).toISOExtString() == "0000-12-04");
7269 assert(Date(-9, 12, 4).toISOExtString() == "-0009-12-04");
7270 assert(Date(-99, 12, 4).toISOExtString() == "-0099-12-04");
7271 assert(Date(-999, 12, 4).toISOExtString() == "-0999-12-04");
7272 assert(Date(-9999, 7, 4).toISOExtString() == "-9999-07-04");
7273 assert(Date(-10000, 10, 20).toISOExtString() == "-10000-10-20");
7275 const cdate = Date(1999, 7, 6);
7276 immutable idate = Date(1999, 7, 6);
7277 assert(cdate.toISOExtString() == "1999-07-06");
7278 assert(idate.toISOExtString() == "1999-07-06");
7282 Converts this $(LREF Date) to a string with the format YYYY-Mon-DD.
7284 string toSimpleString() const @safe pure nothrow
7286 import std.format : format;
7289 if (_year >= 0)
7291 if (_year < 10_000)
7292 return format("%04d-%s-%02d", _year, monthToString(_month), _day);
7293 else
7294 return format("+%05d-%s-%02d", _year, monthToString(_month), _day);
7296 else if (_year > -10_000)
7297 return format("%05d-%s-%02d", _year, monthToString(_month), _day);
7298 else
7299 return format("%06d-%s-%02d", _year, monthToString(_month), _day);
7301 catch (Exception e)
7302 assert(0, "format() threw.");
7306 @safe unittest
7308 assert(Date(2010, 7, 4).toSimpleString() == "2010-Jul-04");
7309 assert(Date(1998, 12, 25).toSimpleString() == "1998-Dec-25");
7310 assert(Date(0, 1, 5).toSimpleString() == "0000-Jan-05");
7311 assert(Date(-4, 1, 5).toSimpleString() == "-0004-Jan-05");
7314 @safe unittest
7316 // Test A.D.
7317 assert(Date(9, 12, 4).toSimpleString() == "0009-Dec-04");
7318 assert(Date(99, 12, 4).toSimpleString() == "0099-Dec-04");
7319 assert(Date(999, 12, 4).toSimpleString() == "0999-Dec-04");
7320 assert(Date(9999, 7, 4).toSimpleString() == "9999-Jul-04");
7321 assert(Date(10000, 10, 20).toSimpleString() == "+10000-Oct-20");
7323 // Test B.C.
7324 assert(Date(0, 12, 4).toSimpleString() == "0000-Dec-04");
7325 assert(Date(-9, 12, 4).toSimpleString() == "-0009-Dec-04");
7326 assert(Date(-99, 12, 4).toSimpleString() == "-0099-Dec-04");
7327 assert(Date(-999, 12, 4).toSimpleString() == "-0999-Dec-04");
7328 assert(Date(-9999, 7, 4).toSimpleString() == "-9999-Jul-04");
7329 assert(Date(-10000, 10, 20).toSimpleString() == "-10000-Oct-20");
7331 const cdate = Date(1999, 7, 6);
7332 immutable idate = Date(1999, 7, 6);
7333 assert(cdate.toSimpleString() == "1999-Jul-06");
7334 assert(idate.toSimpleString() == "1999-Jul-06");
7339 Converts this $(LREF Date) to a string.
7341 This function exists to make it easy to convert a $(LREF Date) to a
7342 string for code that does not care what the exact format is - just that
7343 it presents the information in a clear manner. It also makes it easy to
7344 simply convert a $(LREF Date) to a string when using functions such as
7345 `to!string`, `format`, or `writeln` which use toString to convert
7346 user-defined types. So, it is unlikely that much code will call
7347 toString directly.
7349 The format of the string is purposefully unspecified, and code that
7350 cares about the format of the string should use `toISOString`,
7351 `toISOExtString`, `toSimpleString`, or some other custom formatting
7352 function that explicitly generates the format that the code needs. The
7353 reason is that the code is then clear about what format it's using,
7354 making it less error-prone to maintain the code and interact with other
7355 software that consumes the generated strings. It's for this same reason
7356 $(LREF Date) has no `fromString` function, whereas it does have
7357 `fromISOString`, `fromISOExtString`, and `fromSimpleString`.
7359 The format returned by toString may or may not change in the future.
7361 string toString() const @safe pure nothrow
7363 return toSimpleString();
7366 @safe unittest
7368 auto date = Date(1999, 7, 6);
7369 const cdate = Date(1999, 7, 6);
7370 immutable idate = Date(1999, 7, 6);
7371 assert(date.toString());
7372 assert(cdate.toString());
7373 assert(idate.toString());
7378 Creates a $(LREF Date) from a string with the format YYYYMMDD. Whitespace
7379 is stripped from the given string.
7381 Params:
7382 isoString = A string formatted in the ISO format for dates.
7384 Throws:
7385 $(REF DateTimeException,std,datetime,date) if the given string is
7386 not in the ISO format or if the resulting $(LREF Date) would not be
7387 valid.
7389 static Date fromISOString(S)(in S isoString) @safe pure
7390 if (isSomeString!S)
7392 import std.algorithm.searching : startsWith;
7393 import std.conv : to, text, ConvException;
7394 import std.exception : enforce;
7395 import std.string : strip;
7397 auto str = isoString.strip;
7399 enforce!DateTimeException(str.length >= 8, text("Invalid ISO String: ", isoString));
7401 int day, month, year;
7402 auto yearStr = str[0 .. $ - 4];
7406 // using conversion to uint plus cast because it checks for +/-
7407 // for us quickly while throwing ConvException
7408 day = cast(int) to!uint(str[$ - 2 .. $]);
7409 month = cast(int) to!uint(str[$ - 4 .. $ - 2]);
7411 if (yearStr.length > 4)
7413 enforce!DateTimeException(yearStr.startsWith('-', '+'),
7414 text("Invalid ISO String: ", isoString));
7415 year = to!int(yearStr);
7417 else
7419 year = cast(int) to!uint(yearStr);
7422 catch (ConvException)
7424 throw new DateTimeException(text("Invalid ISO String: ", isoString));
7427 return Date(year, month, day);
7431 @safe unittest
7433 assert(Date.fromISOString("20100704") == Date(2010, 7, 4));
7434 assert(Date.fromISOString("19981225") == Date(1998, 12, 25));
7435 assert(Date.fromISOString("00000105") == Date(0, 1, 5));
7436 assert(Date.fromISOString("-00040105") == Date(-4, 1, 5));
7437 assert(Date.fromISOString(" 20100704 ") == Date(2010, 7, 4));
7440 @safe unittest
7442 assertThrown!DateTimeException(Date.fromISOString(""));
7443 assertThrown!DateTimeException(Date.fromISOString("990704"));
7444 assertThrown!DateTimeException(Date.fromISOString("0100704"));
7445 assertThrown!DateTimeException(Date.fromISOString("2010070"));
7446 assertThrown!DateTimeException(Date.fromISOString("2010070 "));
7447 assertThrown!DateTimeException(Date.fromISOString("120100704"));
7448 assertThrown!DateTimeException(Date.fromISOString("-0100704"));
7449 assertThrown!DateTimeException(Date.fromISOString("+0100704"));
7450 assertThrown!DateTimeException(Date.fromISOString("2010070a"));
7451 assertThrown!DateTimeException(Date.fromISOString("20100a04"));
7452 assertThrown!DateTimeException(Date.fromISOString("2010a704"));
7454 assertThrown!DateTimeException(Date.fromISOString("99-07-04"));
7455 assertThrown!DateTimeException(Date.fromISOString("010-07-04"));
7456 assertThrown!DateTimeException(Date.fromISOString("2010-07-0"));
7457 assertThrown!DateTimeException(Date.fromISOString("2010-07-0 "));
7458 assertThrown!DateTimeException(Date.fromISOString("12010-07-04"));
7459 assertThrown!DateTimeException(Date.fromISOString("-010-07-04"));
7460 assertThrown!DateTimeException(Date.fromISOString("+010-07-04"));
7461 assertThrown!DateTimeException(Date.fromISOString("2010-07-0a"));
7462 assertThrown!DateTimeException(Date.fromISOString("2010-0a-04"));
7463 assertThrown!DateTimeException(Date.fromISOString("2010-a7-04"));
7464 assertThrown!DateTimeException(Date.fromISOString("2010/07/04"));
7465 assertThrown!DateTimeException(Date.fromISOString("2010/7/04"));
7466 assertThrown!DateTimeException(Date.fromISOString("2010/7/4"));
7467 assertThrown!DateTimeException(Date.fromISOString("2010/07/4"));
7468 assertThrown!DateTimeException(Date.fromISOString("2010-7-04"));
7469 assertThrown!DateTimeException(Date.fromISOString("2010-7-4"));
7470 assertThrown!DateTimeException(Date.fromISOString("2010-07-4"));
7472 assertThrown!DateTimeException(Date.fromISOString("99Jul04"));
7473 assertThrown!DateTimeException(Date.fromISOString("010Jul04"));
7474 assertThrown!DateTimeException(Date.fromISOString("2010Jul0"));
7475 assertThrown!DateTimeException(Date.fromISOString("2010Jul0 "));
7476 assertThrown!DateTimeException(Date.fromISOString("12010Jul04"));
7477 assertThrown!DateTimeException(Date.fromISOString("-010Jul04"));
7478 assertThrown!DateTimeException(Date.fromISOString("+010Jul04"));
7479 assertThrown!DateTimeException(Date.fromISOString("2010Jul0a"));
7480 assertThrown!DateTimeException(Date.fromISOString("2010Jua04"));
7481 assertThrown!DateTimeException(Date.fromISOString("2010aul04"));
7483 assertThrown!DateTimeException(Date.fromISOString("99-Jul-04"));
7484 assertThrown!DateTimeException(Date.fromISOString("010-Jul-04"));
7485 assertThrown!DateTimeException(Date.fromISOString("2010-Jul-0"));
7486 assertThrown!DateTimeException(Date.fromISOString("2010-Jul-0 "));
7487 assertThrown!DateTimeException(Date.fromISOString("12010-Jul-04"));
7488 assertThrown!DateTimeException(Date.fromISOString("-010-Jul-04"));
7489 assertThrown!DateTimeException(Date.fromISOString("+010-Jul-04"));
7490 assertThrown!DateTimeException(Date.fromISOString("2010-Jul-0a"));
7491 assertThrown!DateTimeException(Date.fromISOString("2010-Jua-04"));
7492 assertThrown!DateTimeException(Date.fromISOString("2010-Jal-04"));
7493 assertThrown!DateTimeException(Date.fromISOString("2010-aul-04"));
7495 assertThrown!DateTimeException(Date.fromISOString("2010-07-04"));
7496 assertThrown!DateTimeException(Date.fromISOString("2010-Jul-04"));
7498 assert(Date.fromISOString("19990706") == Date(1999, 7, 6));
7499 assert(Date.fromISOString("-19990706") == Date(-1999, 7, 6));
7500 assert(Date.fromISOString("+019990706") == Date(1999, 7, 6));
7501 assert(Date.fromISOString("19990706 ") == Date(1999, 7, 6));
7502 assert(Date.fromISOString(" 19990706") == Date(1999, 7, 6));
7503 assert(Date.fromISOString(" 19990706 ") == Date(1999, 7, 6));
7506 // bug# 17801
7507 @safe unittest
7509 import std.conv : to;
7510 import std.meta : AliasSeq;
7511 foreach (C; AliasSeq!(char, wchar, dchar))
7513 foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[]))
7514 assert(Date.fromISOString(to!S("20121221")) == Date(2012, 12, 21));
7520 Creates a $(LREF Date) from a string with the format YYYY-MM-DD.
7521 Whitespace is stripped from the given string.
7523 Params:
7524 isoExtString = A string formatted in the ISO Extended format for
7525 dates.
7527 Throws:
7528 $(REF DateTimeException,std,datetime,date) if the given string is
7529 not in the ISO Extended format or if the resulting $(LREF Date)
7530 would not be valid.
7532 static Date fromISOExtString(S)(in S isoExtString) @safe pure
7533 if (isSomeString!(S))
7535 import std.algorithm.searching : all, startsWith;
7536 import std.ascii : isDigit;
7537 import std.conv : to;
7538 import std.exception : enforce;
7539 import std.format : format;
7540 import std.string : strip;
7542 auto dstr = to!dstring(strip(isoExtString));
7544 enforce(dstr.length >= 10, new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
7546 auto day = dstr[$-2 .. $];
7547 auto month = dstr[$-5 .. $-3];
7548 auto year = dstr[0 .. $-6];
7550 enforce(dstr[$-3] == '-', new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
7551 enforce(dstr[$-6] == '-', new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
7552 enforce(all!isDigit(day),
7553 new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
7554 enforce(all!isDigit(month),
7555 new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
7557 if (year.length > 4)
7559 enforce(year.startsWith('-', '+'),
7560 new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
7561 enforce(all!isDigit(year[1..$]),
7562 new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
7564 else
7565 enforce(all!isDigit(year),
7566 new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
7568 return Date(to!short(year), to!ubyte(month), to!ubyte(day));
7572 @safe unittest
7574 assert(Date.fromISOExtString("2010-07-04") == Date(2010, 7, 4));
7575 assert(Date.fromISOExtString("1998-12-25") == Date(1998, 12, 25));
7576 assert(Date.fromISOExtString("0000-01-05") == Date(0, 1, 5));
7577 assert(Date.fromISOExtString("-0004-01-05") == Date(-4, 1, 5));
7578 assert(Date.fromISOExtString(" 2010-07-04 ") == Date(2010, 7, 4));
7581 @safe unittest
7583 assertThrown!DateTimeException(Date.fromISOExtString(""));
7584 assertThrown!DateTimeException(Date.fromISOExtString("990704"));
7585 assertThrown!DateTimeException(Date.fromISOExtString("0100704"));
7586 assertThrown!DateTimeException(Date.fromISOExtString("2010070"));
7587 assertThrown!DateTimeException(Date.fromISOExtString("2010070 "));
7588 assertThrown!DateTimeException(Date.fromISOExtString("120100704"));
7589 assertThrown!DateTimeException(Date.fromISOExtString("-0100704"));
7590 assertThrown!DateTimeException(Date.fromISOExtString("+0100704"));
7591 assertThrown!DateTimeException(Date.fromISOExtString("2010070a"));
7592 assertThrown!DateTimeException(Date.fromISOExtString("20100a04"));
7593 assertThrown!DateTimeException(Date.fromISOExtString("2010a704"));
7595 assertThrown!DateTimeException(Date.fromISOExtString("99-07-04"));
7596 assertThrown!DateTimeException(Date.fromISOExtString("010-07-04"));
7597 assertThrown!DateTimeException(Date.fromISOExtString("2010-07-0"));
7598 assertThrown!DateTimeException(Date.fromISOExtString("2010-07-0 "));
7599 assertThrown!DateTimeException(Date.fromISOExtString("12010-07-04"));
7600 assertThrown!DateTimeException(Date.fromISOExtString("-010-07-04"));
7601 assertThrown!DateTimeException(Date.fromISOExtString("+010-07-04"));
7602 assertThrown!DateTimeException(Date.fromISOExtString("2010-07-0a"));
7603 assertThrown!DateTimeException(Date.fromISOExtString("2010-0a-04"));
7604 assertThrown!DateTimeException(Date.fromISOExtString("2010-a7-04"));
7605 assertThrown!DateTimeException(Date.fromISOExtString("2010/07/04"));
7606 assertThrown!DateTimeException(Date.fromISOExtString("2010/7/04"));
7607 assertThrown!DateTimeException(Date.fromISOExtString("2010/7/4"));
7608 assertThrown!DateTimeException(Date.fromISOExtString("2010/07/4"));
7609 assertThrown!DateTimeException(Date.fromISOExtString("2010-7-04"));
7610 assertThrown!DateTimeException(Date.fromISOExtString("2010-7-4"));
7611 assertThrown!DateTimeException(Date.fromISOExtString("2010-07-4"));
7613 assertThrown!DateTimeException(Date.fromISOExtString("99Jul04"));
7614 assertThrown!DateTimeException(Date.fromISOExtString("010Jul04"));
7615 assertThrown!DateTimeException(Date.fromISOExtString("2010Jul0"));
7616 assertThrown!DateTimeException(Date.fromISOExtString("2010-Jul-0 "));
7617 assertThrown!DateTimeException(Date.fromISOExtString("12010Jul04"));
7618 assertThrown!DateTimeException(Date.fromISOExtString("-010Jul04"));
7619 assertThrown!DateTimeException(Date.fromISOExtString("+010Jul04"));
7620 assertThrown!DateTimeException(Date.fromISOExtString("2010Jul0a"));
7621 assertThrown!DateTimeException(Date.fromISOExtString("2010Jua04"));
7622 assertThrown!DateTimeException(Date.fromISOExtString("2010aul04"));
7624 assertThrown!DateTimeException(Date.fromISOExtString("99-Jul-04"));
7625 assertThrown!DateTimeException(Date.fromISOExtString("010-Jul-04"));
7626 assertThrown!DateTimeException(Date.fromISOExtString("2010-Jul-0"));
7627 assertThrown!DateTimeException(Date.fromISOExtString("2010Jul0 "));
7628 assertThrown!DateTimeException(Date.fromISOExtString("12010-Jul-04"));
7629 assertThrown!DateTimeException(Date.fromISOExtString("-010-Jul-04"));
7630 assertThrown!DateTimeException(Date.fromISOExtString("+010-Jul-04"));
7631 assertThrown!DateTimeException(Date.fromISOExtString("2010-Jul-0a"));
7632 assertThrown!DateTimeException(Date.fromISOExtString("2010-Jua-04"));
7633 assertThrown!DateTimeException(Date.fromISOExtString("2010-Jal-04"));
7634 assertThrown!DateTimeException(Date.fromISOExtString("2010-aul-04"));
7636 assertThrown!DateTimeException(Date.fromISOExtString("20100704"));
7637 assertThrown!DateTimeException(Date.fromISOExtString("2010-Jul-04"));
7639 assert(Date.fromISOExtString("1999-07-06") == Date(1999, 7, 6));
7640 assert(Date.fromISOExtString("-1999-07-06") == Date(-1999, 7, 6));
7641 assert(Date.fromISOExtString("+01999-07-06") == Date(1999, 7, 6));
7642 assert(Date.fromISOExtString("1999-07-06 ") == Date(1999, 7, 6));
7643 assert(Date.fromISOExtString(" 1999-07-06") == Date(1999, 7, 6));
7644 assert(Date.fromISOExtString(" 1999-07-06 ") == Date(1999, 7, 6));
7647 // bug# 17801
7648 @safe unittest
7650 import std.conv : to;
7651 import std.meta : AliasSeq;
7652 foreach (C; AliasSeq!(char, wchar, dchar))
7654 foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[]))
7655 assert(Date.fromISOExtString(to!S("2012-12-21")) == Date(2012, 12, 21));
7661 Creates a $(LREF Date) from a string with the format YYYY-Mon-DD.
7662 Whitespace is stripped from the given string.
7664 Params:
7665 simpleString = A string formatted in the way that toSimpleString
7666 formats dates.
7668 Throws:
7669 $(REF DateTimeException,std,datetime,date) if the given string is
7670 not in the correct format or if the resulting $(LREF Date) would not
7671 be valid.
7673 static Date fromSimpleString(S)(in S simpleString) @safe pure
7674 if (isSomeString!(S))
7676 import std.algorithm.searching : all, startsWith;
7677 import std.ascii : isDigit;
7678 import std.conv : to;
7679 import std.exception : enforce;
7680 import std.format : format;
7681 import std.string : strip;
7683 auto dstr = to!dstring(strip(simpleString));
7685 enforce(dstr.length >= 11, new DateTimeException(format("Invalid string format: %s", simpleString)));
7687 auto day = dstr[$-2 .. $];
7688 auto month = monthFromString(to!string(dstr[$-6 .. $-3]));
7689 auto year = dstr[0 .. $-7];
7691 enforce(dstr[$-3] == '-', new DateTimeException(format("Invalid string format: %s", simpleString)));
7692 enforce(dstr[$-7] == '-', new DateTimeException(format("Invalid string format: %s", simpleString)));
7693 enforce(all!isDigit(day), new DateTimeException(format("Invalid string format: %s", simpleString)));
7695 if (year.length > 4)
7697 enforce(year.startsWith('-', '+'),
7698 new DateTimeException(format("Invalid string format: %s", simpleString)));
7699 enforce(all!isDigit(year[1..$]),
7700 new DateTimeException(format("Invalid string format: %s", simpleString)));
7702 else
7703 enforce(all!isDigit(year),
7704 new DateTimeException(format("Invalid string format: %s", simpleString)));
7706 return Date(to!short(year), month, to!ubyte(day));
7710 @safe unittest
7712 assert(Date.fromSimpleString("2010-Jul-04") == Date(2010, 7, 4));
7713 assert(Date.fromSimpleString("1998-Dec-25") == Date(1998, 12, 25));
7714 assert(Date.fromSimpleString("0000-Jan-05") == Date(0, 1, 5));
7715 assert(Date.fromSimpleString("-0004-Jan-05") == Date(-4, 1, 5));
7716 assert(Date.fromSimpleString(" 2010-Jul-04 ") == Date(2010, 7, 4));
7719 @safe unittest
7721 assertThrown!DateTimeException(Date.fromSimpleString(""));
7722 assertThrown!DateTimeException(Date.fromSimpleString("990704"));
7723 assertThrown!DateTimeException(Date.fromSimpleString("0100704"));
7724 assertThrown!DateTimeException(Date.fromSimpleString("2010070"));
7725 assertThrown!DateTimeException(Date.fromSimpleString("2010070 "));
7726 assertThrown!DateTimeException(Date.fromSimpleString("120100704"));
7727 assertThrown!DateTimeException(Date.fromSimpleString("-0100704"));
7728 assertThrown!DateTimeException(Date.fromSimpleString("+0100704"));
7729 assertThrown!DateTimeException(Date.fromSimpleString("2010070a"));
7730 assertThrown!DateTimeException(Date.fromSimpleString("20100a04"));
7731 assertThrown!DateTimeException(Date.fromSimpleString("2010a704"));
7733 assertThrown!DateTimeException(Date.fromSimpleString("99-07-04"));
7734 assertThrown!DateTimeException(Date.fromSimpleString("010-07-04"));
7735 assertThrown!DateTimeException(Date.fromSimpleString("2010-07-0"));
7736 assertThrown!DateTimeException(Date.fromSimpleString("2010-07-0 "));
7737 assertThrown!DateTimeException(Date.fromSimpleString("12010-07-04"));
7738 assertThrown!DateTimeException(Date.fromSimpleString("-010-07-04"));
7739 assertThrown!DateTimeException(Date.fromSimpleString("+010-07-04"));
7740 assertThrown!DateTimeException(Date.fromSimpleString("2010-07-0a"));
7741 assertThrown!DateTimeException(Date.fromSimpleString("2010-0a-04"));
7742 assertThrown!DateTimeException(Date.fromSimpleString("2010-a7-04"));
7743 assertThrown!DateTimeException(Date.fromSimpleString("2010/07/04"));
7744 assertThrown!DateTimeException(Date.fromSimpleString("2010/7/04"));
7745 assertThrown!DateTimeException(Date.fromSimpleString("2010/7/4"));
7746 assertThrown!DateTimeException(Date.fromSimpleString("2010/07/4"));
7747 assertThrown!DateTimeException(Date.fromSimpleString("2010-7-04"));
7748 assertThrown!DateTimeException(Date.fromSimpleString("2010-7-4"));
7749 assertThrown!DateTimeException(Date.fromSimpleString("2010-07-4"));
7751 assertThrown!DateTimeException(Date.fromSimpleString("99Jul04"));
7752 assertThrown!DateTimeException(Date.fromSimpleString("010Jul04"));
7753 assertThrown!DateTimeException(Date.fromSimpleString("2010Jul0"));
7754 assertThrown!DateTimeException(Date.fromSimpleString("2010Jul0 "));
7755 assertThrown!DateTimeException(Date.fromSimpleString("12010Jul04"));
7756 assertThrown!DateTimeException(Date.fromSimpleString("-010Jul04"));
7757 assertThrown!DateTimeException(Date.fromSimpleString("+010Jul04"));
7758 assertThrown!DateTimeException(Date.fromSimpleString("2010Jul0a"));
7759 assertThrown!DateTimeException(Date.fromSimpleString("2010Jua04"));
7760 assertThrown!DateTimeException(Date.fromSimpleString("2010aul04"));
7762 assertThrown!DateTimeException(Date.fromSimpleString("99-Jul-04"));
7763 assertThrown!DateTimeException(Date.fromSimpleString("010-Jul-04"));
7764 assertThrown!DateTimeException(Date.fromSimpleString("2010-Jul-0"));
7765 assertThrown!DateTimeException(Date.fromSimpleString("2010-Jul-0 "));
7766 assertThrown!DateTimeException(Date.fromSimpleString("12010-Jul-04"));
7767 assertThrown!DateTimeException(Date.fromSimpleString("-010-Jul-04"));
7768 assertThrown!DateTimeException(Date.fromSimpleString("+010-Jul-04"));
7769 assertThrown!DateTimeException(Date.fromSimpleString("2010-Jul-0a"));
7770 assertThrown!DateTimeException(Date.fromSimpleString("2010-Jua-04"));
7771 assertThrown!DateTimeException(Date.fromSimpleString("2010-Jal-04"));
7772 assertThrown!DateTimeException(Date.fromSimpleString("2010-aul-04"));
7774 assertThrown!DateTimeException(Date.fromSimpleString("20100704"));
7775 assertThrown!DateTimeException(Date.fromSimpleString("2010-07-04"));
7777 assert(Date.fromSimpleString("1999-Jul-06") == Date(1999, 7, 6));
7778 assert(Date.fromSimpleString("-1999-Jul-06") == Date(-1999, 7, 6));
7779 assert(Date.fromSimpleString("+01999-Jul-06") == Date(1999, 7, 6));
7780 assert(Date.fromSimpleString("1999-Jul-06 ") == Date(1999, 7, 6));
7781 assert(Date.fromSimpleString(" 1999-Jul-06") == Date(1999, 7, 6));
7782 assert(Date.fromSimpleString(" 1999-Jul-06 ") == Date(1999, 7, 6));
7785 // bug# 17801
7786 @safe unittest
7788 import std.conv : to;
7789 import std.meta : AliasSeq;
7790 foreach (C; AliasSeq!(char, wchar, dchar))
7792 foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[]))
7793 assert(Date.fromSimpleString(to!S("2012-Dec-21")) == Date(2012, 12, 21));
7799 Returns the $(LREF Date) farthest in the past which is representable by
7800 $(LREF Date).
7802 @property static Date min() @safe pure nothrow @nogc
7804 auto date = Date.init;
7805 date._year = short.min;
7806 date._month = Month.jan;
7807 date._day = 1;
7809 return date;
7812 @safe unittest
7814 assert(Date.min.year < 0);
7815 assert(Date.min < Date.max);
7820 Returns the $(LREF Date) farthest in the future which is representable
7821 by $(LREF Date).
7823 @property static Date max() @safe pure nothrow @nogc
7825 auto date = Date.init;
7826 date._year = short.max;
7827 date._month = Month.dec;
7828 date._day = 31;
7830 return date;
7833 @safe unittest
7835 assert(Date.max.year > 0);
7836 assert(Date.max > Date.min);
7840 private:
7843 Whether the given values form a valid date.
7845 Params:
7846 year = The year to test.
7847 month = The month of the Gregorian Calendar to test.
7848 day = The day of the month to test.
7850 static bool _valid(int year, int month, int day) @safe pure nothrow @nogc
7852 if (!valid!"months"(month))
7853 return false;
7854 return valid!"days"(year, month, day);
7858 package:
7861 Adds the given number of days to this $(LREF Date). A negative number
7862 will subtract.
7864 The month will be adjusted along with the day if the number of days
7865 added (or subtracted) would overflow (or underflow) the current month.
7866 The year will be adjusted along with the month if the increase (or
7867 decrease) to the month would cause it to overflow (or underflow) the
7868 current year.
7870 $(D _addDays(numDays)) is effectively equivalent to
7871 $(D date.dayOfGregorianCal = date.dayOfGregorianCal + days).
7873 Params:
7874 days = The number of days to add to this Date.
7876 ref Date _addDays(long days) return @safe pure nothrow @nogc
7878 dayOfGregorianCal = cast(int)(dayOfGregorianCal + days);
7879 return this;
7882 @safe unittest
7884 // Test A.D.
7886 auto date = Date(1999, 2, 28);
7887 date._addDays(1);
7888 assert(date == Date(1999, 3, 1));
7889 date._addDays(-1);
7890 assert(date == Date(1999, 2, 28));
7894 auto date = Date(2000, 2, 28);
7895 date._addDays(1);
7896 assert(date == Date(2000, 2, 29));
7897 date._addDays(1);
7898 assert(date == Date(2000, 3, 1));
7899 date._addDays(-1);
7900 assert(date == Date(2000, 2, 29));
7904 auto date = Date(1999, 6, 30);
7905 date._addDays(1);
7906 assert(date == Date(1999, 7, 1));
7907 date._addDays(-1);
7908 assert(date == Date(1999, 6, 30));
7912 auto date = Date(1999, 7, 31);
7913 date._addDays(1);
7914 assert(date == Date(1999, 8, 1));
7915 date._addDays(-1);
7916 assert(date == Date(1999, 7, 31));
7920 auto date = Date(1999, 1, 1);
7921 date._addDays(-1);
7922 assert(date == Date(1998, 12, 31));
7923 date._addDays(1);
7924 assert(date == Date(1999, 1, 1));
7928 auto date = Date(1999, 7, 6);
7929 date._addDays(9);
7930 assert(date == Date(1999, 7, 15));
7931 date._addDays(-11);
7932 assert(date == Date(1999, 7, 4));
7933 date._addDays(30);
7934 assert(date == Date(1999, 8, 3));
7935 date._addDays(-3);
7936 assert(date == Date(1999, 7, 31));
7940 auto date = Date(1999, 7, 6);
7941 date._addDays(365);
7942 assert(date == Date(2000, 7, 5));
7943 date._addDays(-365);
7944 assert(date == Date(1999, 7, 6));
7945 date._addDays(366);
7946 assert(date == Date(2000, 7, 6));
7947 date._addDays(730);
7948 assert(date == Date(2002, 7, 6));
7949 date._addDays(-1096);
7950 assert(date == Date(1999, 7, 6));
7953 // Test B.C.
7955 auto date = Date(-1999, 2, 28);
7956 date._addDays(1);
7957 assert(date == Date(-1999, 3, 1));
7958 date._addDays(-1);
7959 assert(date == Date(-1999, 2, 28));
7963 auto date = Date(-2000, 2, 28);
7964 date._addDays(1);
7965 assert(date == Date(-2000, 2, 29));
7966 date._addDays(1);
7967 assert(date == Date(-2000, 3, 1));
7968 date._addDays(-1);
7969 assert(date == Date(-2000, 2, 29));
7973 auto date = Date(-1999, 6, 30);
7974 date._addDays(1);
7975 assert(date == Date(-1999, 7, 1));
7976 date._addDays(-1);
7977 assert(date == Date(-1999, 6, 30));
7981 auto date = Date(-1999, 7, 31);
7982 date._addDays(1);
7983 assert(date == Date(-1999, 8, 1));
7984 date._addDays(-1);
7985 assert(date == Date(-1999, 7, 31));
7989 auto date = Date(-1999, 1, 1);
7990 date._addDays(-1);
7991 assert(date == Date(-2000, 12, 31));
7992 date._addDays(1);
7993 assert(date == Date(-1999, 1, 1));
7997 auto date = Date(-1999, 7, 6);
7998 date._addDays(9);
7999 assert(date == Date(-1999, 7, 15));
8000 date._addDays(-11);
8001 assert(date == Date(-1999, 7, 4));
8002 date._addDays(30);
8003 assert(date == Date(-1999, 8, 3));
8004 date._addDays(-3);
8008 auto date = Date(-1999, 7, 6);
8009 date._addDays(365);
8010 assert(date == Date(-1998, 7, 6));
8011 date._addDays(-365);
8012 assert(date == Date(-1999, 7, 6));
8013 date._addDays(366);
8014 assert(date == Date(-1998, 7, 7));
8015 date._addDays(730);
8016 assert(date == Date(-1996, 7, 6));
8017 date._addDays(-1096);
8018 assert(date == Date(-1999, 7, 6));
8021 // Test Both
8023 auto date = Date(1, 7, 6);
8024 date._addDays(-365);
8025 assert(date == Date(0, 7, 6));
8026 date._addDays(365);
8027 assert(date == Date(1, 7, 6));
8028 date._addDays(-731);
8029 assert(date == Date(-1, 7, 6));
8030 date._addDays(730);
8031 assert(date == Date(1, 7, 5));
8034 const cdate = Date(1999, 7, 6);
8035 immutable idate = Date(1999, 7, 6);
8036 static assert(!__traits(compiles, cdate._addDays(12)));
8037 static assert(!__traits(compiles, idate._addDays(12)));
8041 @safe pure invariant()
8043 import std.format : format;
8044 assert(valid!"months"(_month),
8045 format("Invariant Failure: year [%s] month [%s] day [%s]", _year, _month, _day));
8046 assert(valid!"days"(_year, _month, _day),
8047 format("Invariant Failure: year [%s] month [%s] day [%s]", _year, _month, _day));
8050 short _year = 1;
8051 Month _month = Month.jan;
8052 ubyte _day = 1;
8057 Represents a time of day with hours, minutes, and seconds. It uses 24 hour
8058 time.
8060 struct TimeOfDay
8062 public:
8065 Params:
8066 hour = Hour of the day [0 - 24$(RPAREN).
8067 minute = Minute of the hour [0 - 60$(RPAREN).
8068 second = Second of the minute [0 - 60$(RPAREN).
8070 Throws:
8071 $(REF DateTimeException,std,datetime,date) if the resulting
8072 $(LREF TimeOfDay) would be not be valid.
8074 this(int hour, int minute, int second = 0) @safe pure
8076 enforceValid!"hours"(hour);
8077 enforceValid!"minutes"(minute);
8078 enforceValid!"seconds"(second);
8080 _hour = cast(ubyte) hour;
8081 _minute = cast(ubyte) minute;
8082 _second = cast(ubyte) second;
8085 @safe unittest
8087 assert(TimeOfDay(0, 0) == TimeOfDay.init);
8090 auto tod = TimeOfDay(0, 0);
8091 assert(tod._hour == 0);
8092 assert(tod._minute == 0);
8093 assert(tod._second == 0);
8097 auto tod = TimeOfDay(12, 30, 33);
8098 assert(tod._hour == 12);
8099 assert(tod._minute == 30);
8100 assert(tod._second == 33);
8104 auto tod = TimeOfDay(23, 59, 59);
8105 assert(tod._hour == 23);
8106 assert(tod._minute == 59);
8107 assert(tod._second == 59);
8110 assertThrown!DateTimeException(TimeOfDay(24, 0, 0));
8111 assertThrown!DateTimeException(TimeOfDay(0, 60, 0));
8112 assertThrown!DateTimeException(TimeOfDay(0, 0, 60));
8117 Compares this $(LREF TimeOfDay) with the given $(LREF TimeOfDay).
8119 Returns:
8120 $(BOOKTABLE,
8121 $(TR $(TD this &lt; rhs) $(TD &lt; 0))
8122 $(TR $(TD this == rhs) $(TD 0))
8123 $(TR $(TD this &gt; rhs) $(TD &gt; 0))
8126 int opCmp(in TimeOfDay rhs) const @safe pure nothrow @nogc
8128 if (_hour < rhs._hour)
8129 return -1;
8130 if (_hour > rhs._hour)
8131 return 1;
8133 if (_minute < rhs._minute)
8134 return -1;
8135 if (_minute > rhs._minute)
8136 return 1;
8138 if (_second < rhs._second)
8139 return -1;
8140 if (_second > rhs._second)
8141 return 1;
8143 return 0;
8146 @safe unittest
8148 assert(TimeOfDay(0, 0, 0).opCmp(TimeOfDay.init) == 0);
8150 assert(TimeOfDay(0, 0, 0).opCmp(TimeOfDay(0, 0, 0)) == 0);
8151 assert(TimeOfDay(12, 0, 0).opCmp(TimeOfDay(12, 0, 0)) == 0);
8152 assert(TimeOfDay(0, 30, 0).opCmp(TimeOfDay(0, 30, 0)) == 0);
8153 assert(TimeOfDay(0, 0, 33).opCmp(TimeOfDay(0, 0, 33)) == 0);
8155 assert(TimeOfDay(12, 30, 0).opCmp(TimeOfDay(12, 30, 0)) == 0);
8156 assert(TimeOfDay(12, 30, 33).opCmp(TimeOfDay(12, 30, 33)) == 0);
8158 assert(TimeOfDay(0, 30, 33).opCmp(TimeOfDay(0, 30, 33)) == 0);
8159 assert(TimeOfDay(0, 0, 33).opCmp(TimeOfDay(0, 0, 33)) == 0);
8161 assert(TimeOfDay(12, 30, 33).opCmp(TimeOfDay(13, 30, 33)) < 0);
8162 assert(TimeOfDay(13, 30, 33).opCmp(TimeOfDay(12, 30, 33)) > 0);
8163 assert(TimeOfDay(12, 30, 33).opCmp(TimeOfDay(12, 31, 33)) < 0);
8164 assert(TimeOfDay(12, 31, 33).opCmp(TimeOfDay(12, 30, 33)) > 0);
8165 assert(TimeOfDay(12, 30, 33).opCmp(TimeOfDay(12, 30, 34)) < 0);
8166 assert(TimeOfDay(12, 30, 34).opCmp(TimeOfDay(12, 30, 33)) > 0);
8168 assert(TimeOfDay(13, 30, 33).opCmp(TimeOfDay(12, 30, 34)) > 0);
8169 assert(TimeOfDay(12, 30, 34).opCmp(TimeOfDay(13, 30, 33)) < 0);
8170 assert(TimeOfDay(13, 30, 33).opCmp(TimeOfDay(12, 31, 33)) > 0);
8171 assert(TimeOfDay(12, 31, 33).opCmp(TimeOfDay(13, 30, 33)) < 0);
8173 assert(TimeOfDay(12, 31, 33).opCmp(TimeOfDay(12, 30, 34)) > 0);
8174 assert(TimeOfDay(12, 30, 34).opCmp(TimeOfDay(12, 31, 33)) < 0);
8176 const ctod = TimeOfDay(12, 30, 33);
8177 immutable itod = TimeOfDay(12, 30, 33);
8178 assert(ctod.opCmp(itod) == 0);
8179 assert(itod.opCmp(ctod) == 0);
8184 Hours past midnight.
8186 @property ubyte hour() const @safe pure nothrow @nogc
8188 return _hour;
8191 @safe unittest
8193 assert(TimeOfDay.init.hour == 0);
8194 assert(TimeOfDay(12, 0, 0).hour == 12);
8196 const ctod = TimeOfDay(12, 0, 0);
8197 immutable itod = TimeOfDay(12, 0, 0);
8198 assert(ctod.hour == 12);
8199 assert(itod.hour == 12);
8204 Hours past midnight.
8206 Params:
8207 hour = The hour of the day to set this $(LREF TimeOfDay)'s hour to.
8209 Throws:
8210 $(REF DateTimeException,std,datetime,date) if the given hour would
8211 result in an invalid $(LREF TimeOfDay).
8213 @property void hour(int hour) @safe pure
8215 enforceValid!"hours"(hour);
8216 _hour = cast(ubyte) hour;
8219 @safe unittest
8221 assertThrown!DateTimeException((){TimeOfDay(0, 0, 0).hour = 24;}());
8223 auto tod = TimeOfDay(0, 0, 0);
8224 tod.hour = 12;
8225 assert(tod == TimeOfDay(12, 0, 0));
8227 const ctod = TimeOfDay(0, 0, 0);
8228 immutable itod = TimeOfDay(0, 0, 0);
8229 static assert(!__traits(compiles, ctod.hour = 12));
8230 static assert(!__traits(compiles, itod.hour = 12));
8235 Minutes past the hour.
8237 @property ubyte minute() const @safe pure nothrow @nogc
8239 return _minute;
8242 @safe unittest
8244 assert(TimeOfDay.init.minute == 0);
8245 assert(TimeOfDay(0, 30, 0).minute == 30);
8247 const ctod = TimeOfDay(0, 30, 0);
8248 immutable itod = TimeOfDay(0, 30, 0);
8249 assert(ctod.minute == 30);
8250 assert(itod.minute == 30);
8255 Minutes past the hour.
8257 Params:
8258 minute = The minute to set this $(LREF TimeOfDay)'s minute to.
8260 Throws:
8261 $(REF DateTimeException,std,datetime,date) if the given minute
8262 would result in an invalid $(LREF TimeOfDay).
8264 @property void minute(int minute) @safe pure
8266 enforceValid!"minutes"(minute);
8267 _minute = cast(ubyte) minute;
8270 @safe unittest
8272 assertThrown!DateTimeException((){TimeOfDay(0, 0, 0).minute = 60;}());
8274 auto tod = TimeOfDay(0, 0, 0);
8275 tod.minute = 30;
8276 assert(tod == TimeOfDay(0, 30, 0));
8278 const ctod = TimeOfDay(0, 0, 0);
8279 immutable itod = TimeOfDay(0, 0, 0);
8280 static assert(!__traits(compiles, ctod.minute = 30));
8281 static assert(!__traits(compiles, itod.minute = 30));
8286 Seconds past the minute.
8288 @property ubyte second() const @safe pure nothrow @nogc
8290 return _second;
8293 @safe unittest
8295 assert(TimeOfDay.init.second == 0);
8296 assert(TimeOfDay(0, 0, 33).second == 33);
8298 const ctod = TimeOfDay(0, 0, 33);
8299 immutable itod = TimeOfDay(0, 0, 33);
8300 assert(ctod.second == 33);
8301 assert(itod.second == 33);
8306 Seconds past the minute.
8308 Params:
8309 second = The second to set this $(LREF TimeOfDay)'s second to.
8311 Throws:
8312 $(REF DateTimeException,std,datetime,date) if the given second
8313 would result in an invalid $(LREF TimeOfDay).
8315 @property void second(int second) @safe pure
8317 enforceValid!"seconds"(second);
8318 _second = cast(ubyte) second;
8321 @safe unittest
8323 assertThrown!DateTimeException((){TimeOfDay(0, 0, 0).second = 60;}());
8325 auto tod = TimeOfDay(0, 0, 0);
8326 tod.second = 33;
8327 assert(tod == TimeOfDay(0, 0, 33));
8329 const ctod = TimeOfDay(0, 0, 0);
8330 immutable itod = TimeOfDay(0, 0, 0);
8331 static assert(!__traits(compiles, ctod.second = 33));
8332 static assert(!__traits(compiles, itod.second = 33));
8337 Adds the given number of units to this $(LREF TimeOfDay). A negative
8338 number will subtract.
8340 The difference between rolling and adding is that rolling does not
8341 affect larger units. For instance, rolling a $(LREF TimeOfDay)
8342 one hours's worth of minutes gets the exact same
8343 $(LREF TimeOfDay).
8345 Accepted units are $(D "hours"), $(D "minutes"), and $(D "seconds").
8347 Params:
8348 units = The units to add.
8349 value = The number of $(D_PARAM units) to add to this
8350 $(LREF TimeOfDay).
8352 ref TimeOfDay roll(string units)(long value) @safe pure nothrow @nogc
8353 if (units == "hours")
8355 return this += dur!"hours"(value);
8359 @safe unittest
8361 auto tod1 = TimeOfDay(7, 12, 0);
8362 tod1.roll!"hours"(1);
8363 assert(tod1 == TimeOfDay(8, 12, 0));
8365 auto tod2 = TimeOfDay(7, 12, 0);
8366 tod2.roll!"hours"(-1);
8367 assert(tod2 == TimeOfDay(6, 12, 0));
8369 auto tod3 = TimeOfDay(23, 59, 0);
8370 tod3.roll!"minutes"(1);
8371 assert(tod3 == TimeOfDay(23, 0, 0));
8373 auto tod4 = TimeOfDay(0, 0, 0);
8374 tod4.roll!"minutes"(-1);
8375 assert(tod4 == TimeOfDay(0, 59, 0));
8377 auto tod5 = TimeOfDay(23, 59, 59);
8378 tod5.roll!"seconds"(1);
8379 assert(tod5 == TimeOfDay(23, 59, 0));
8381 auto tod6 = TimeOfDay(0, 0, 0);
8382 tod6.roll!"seconds"(-1);
8383 assert(tod6 == TimeOfDay(0, 0, 59));
8386 @safe unittest
8388 auto tod = TimeOfDay(12, 27, 2);
8389 tod.roll!"hours"(22).roll!"hours"(-7);
8390 assert(tod == TimeOfDay(3, 27, 2));
8392 const ctod = TimeOfDay(0, 0, 0);
8393 immutable itod = TimeOfDay(0, 0, 0);
8394 static assert(!__traits(compiles, ctod.roll!"hours"(53)));
8395 static assert(!__traits(compiles, itod.roll!"hours"(53)));
8399 // Shares documentation with "hours" version.
8400 ref TimeOfDay roll(string units)(long value) @safe pure nothrow @nogc
8401 if (units == "minutes" || units == "seconds")
8403 import std.format : format;
8405 enum memberVarStr = units[0 .. $ - 1];
8406 value %= 60;
8407 mixin(format("auto newVal = cast(ubyte)(_%s) + value;", memberVarStr));
8409 if (value < 0)
8411 if (newVal < 0)
8412 newVal += 60;
8414 else if (newVal >= 60)
8415 newVal -= 60;
8417 mixin(format("_%s = cast(ubyte) newVal;", memberVarStr));
8418 return this;
8421 // Test roll!"minutes"().
8422 @safe unittest
8424 static void testTOD(TimeOfDay orig, int minutes, in TimeOfDay expected, size_t line = __LINE__)
8426 orig.roll!"minutes"(minutes);
8427 assert(orig == expected);
8430 testTOD(TimeOfDay(12, 30, 33), 0, TimeOfDay(12, 30, 33));
8431 testTOD(TimeOfDay(12, 30, 33), 1, TimeOfDay(12, 31, 33));
8432 testTOD(TimeOfDay(12, 30, 33), 2, TimeOfDay(12, 32, 33));
8433 testTOD(TimeOfDay(12, 30, 33), 3, TimeOfDay(12, 33, 33));
8434 testTOD(TimeOfDay(12, 30, 33), 4, TimeOfDay(12, 34, 33));
8435 testTOD(TimeOfDay(12, 30, 33), 5, TimeOfDay(12, 35, 33));
8436 testTOD(TimeOfDay(12, 30, 33), 10, TimeOfDay(12, 40, 33));
8437 testTOD(TimeOfDay(12, 30, 33), 15, TimeOfDay(12, 45, 33));
8438 testTOD(TimeOfDay(12, 30, 33), 29, TimeOfDay(12, 59, 33));
8439 testTOD(TimeOfDay(12, 30, 33), 30, TimeOfDay(12, 0, 33));
8440 testTOD(TimeOfDay(12, 30, 33), 45, TimeOfDay(12, 15, 33));
8441 testTOD(TimeOfDay(12, 30, 33), 60, TimeOfDay(12, 30, 33));
8442 testTOD(TimeOfDay(12, 30, 33), 75, TimeOfDay(12, 45, 33));
8443 testTOD(TimeOfDay(12, 30, 33), 90, TimeOfDay(12, 0, 33));
8444 testTOD(TimeOfDay(12, 30, 33), 100, TimeOfDay(12, 10, 33));
8446 testTOD(TimeOfDay(12, 30, 33), 689, TimeOfDay(12, 59, 33));
8447 testTOD(TimeOfDay(12, 30, 33), 690, TimeOfDay(12, 0, 33));
8448 testTOD(TimeOfDay(12, 30, 33), 691, TimeOfDay(12, 1, 33));
8449 testTOD(TimeOfDay(12, 30, 33), 960, TimeOfDay(12, 30, 33));
8450 testTOD(TimeOfDay(12, 30, 33), 1439, TimeOfDay(12, 29, 33));
8451 testTOD(TimeOfDay(12, 30, 33), 1440, TimeOfDay(12, 30, 33));
8452 testTOD(TimeOfDay(12, 30, 33), 1441, TimeOfDay(12, 31, 33));
8453 testTOD(TimeOfDay(12, 30, 33), 2880, TimeOfDay(12, 30, 33));
8455 testTOD(TimeOfDay(12, 30, 33), -1, TimeOfDay(12, 29, 33));
8456 testTOD(TimeOfDay(12, 30, 33), -2, TimeOfDay(12, 28, 33));
8457 testTOD(TimeOfDay(12, 30, 33), -3, TimeOfDay(12, 27, 33));
8458 testTOD(TimeOfDay(12, 30, 33), -4, TimeOfDay(12, 26, 33));
8459 testTOD(TimeOfDay(12, 30, 33), -5, TimeOfDay(12, 25, 33));
8460 testTOD(TimeOfDay(12, 30, 33), -10, TimeOfDay(12, 20, 33));
8461 testTOD(TimeOfDay(12, 30, 33), -15, TimeOfDay(12, 15, 33));
8462 testTOD(TimeOfDay(12, 30, 33), -29, TimeOfDay(12, 1, 33));
8463 testTOD(TimeOfDay(12, 30, 33), -30, TimeOfDay(12, 0, 33));
8464 testTOD(TimeOfDay(12, 30, 33), -45, TimeOfDay(12, 45, 33));
8465 testTOD(TimeOfDay(12, 30, 33), -60, TimeOfDay(12, 30, 33));
8466 testTOD(TimeOfDay(12, 30, 33), -75, TimeOfDay(12, 15, 33));
8467 testTOD(TimeOfDay(12, 30, 33), -90, TimeOfDay(12, 0, 33));
8468 testTOD(TimeOfDay(12, 30, 33), -100, TimeOfDay(12, 50, 33));
8470 testTOD(TimeOfDay(12, 30, 33), -749, TimeOfDay(12, 1, 33));
8471 testTOD(TimeOfDay(12, 30, 33), -750, TimeOfDay(12, 0, 33));
8472 testTOD(TimeOfDay(12, 30, 33), -751, TimeOfDay(12, 59, 33));
8473 testTOD(TimeOfDay(12, 30, 33), -960, TimeOfDay(12, 30, 33));
8474 testTOD(TimeOfDay(12, 30, 33), -1439, TimeOfDay(12, 31, 33));
8475 testTOD(TimeOfDay(12, 30, 33), -1440, TimeOfDay(12, 30, 33));
8476 testTOD(TimeOfDay(12, 30, 33), -1441, TimeOfDay(12, 29, 33));
8477 testTOD(TimeOfDay(12, 30, 33), -2880, TimeOfDay(12, 30, 33));
8479 testTOD(TimeOfDay(12, 0, 33), 1, TimeOfDay(12, 1, 33));
8480 testTOD(TimeOfDay(12, 0, 33), 0, TimeOfDay(12, 0, 33));
8481 testTOD(TimeOfDay(12, 0, 33), -1, TimeOfDay(12, 59, 33));
8483 testTOD(TimeOfDay(11, 59, 33), 1, TimeOfDay(11, 0, 33));
8484 testTOD(TimeOfDay(11, 59, 33), 0, TimeOfDay(11, 59, 33));
8485 testTOD(TimeOfDay(11, 59, 33), -1, TimeOfDay(11, 58, 33));
8487 testTOD(TimeOfDay(0, 0, 33), 1, TimeOfDay(0, 1, 33));
8488 testTOD(TimeOfDay(0, 0, 33), 0, TimeOfDay(0, 0, 33));
8489 testTOD(TimeOfDay(0, 0, 33), -1, TimeOfDay(0, 59, 33));
8491 testTOD(TimeOfDay(23, 59, 33), 1, TimeOfDay(23, 0, 33));
8492 testTOD(TimeOfDay(23, 59, 33), 0, TimeOfDay(23, 59, 33));
8493 testTOD(TimeOfDay(23, 59, 33), -1, TimeOfDay(23, 58, 33));
8495 auto tod = TimeOfDay(12, 27, 2);
8496 tod.roll!"minutes"(97).roll!"minutes"(-102);
8497 assert(tod == TimeOfDay(12, 22, 2));
8499 const ctod = TimeOfDay(0, 0, 0);
8500 immutable itod = TimeOfDay(0, 0, 0);
8501 static assert(!__traits(compiles, ctod.roll!"minutes"(7)));
8502 static assert(!__traits(compiles, itod.roll!"minutes"(7)));
8505 // Test roll!"seconds"().
8506 @safe unittest
8508 static void testTOD(TimeOfDay orig, int seconds, in TimeOfDay expected, size_t line = __LINE__)
8510 orig.roll!"seconds"(seconds);
8511 assert(orig == expected);
8514 testTOD(TimeOfDay(12, 30, 33), 0, TimeOfDay(12, 30, 33));
8515 testTOD(TimeOfDay(12, 30, 33), 1, TimeOfDay(12, 30, 34));
8516 testTOD(TimeOfDay(12, 30, 33), 2, TimeOfDay(12, 30, 35));
8517 testTOD(TimeOfDay(12, 30, 33), 3, TimeOfDay(12, 30, 36));
8518 testTOD(TimeOfDay(12, 30, 33), 4, TimeOfDay(12, 30, 37));
8519 testTOD(TimeOfDay(12, 30, 33), 5, TimeOfDay(12, 30, 38));
8520 testTOD(TimeOfDay(12, 30, 33), 10, TimeOfDay(12, 30, 43));
8521 testTOD(TimeOfDay(12, 30, 33), 15, TimeOfDay(12, 30, 48));
8522 testTOD(TimeOfDay(12, 30, 33), 26, TimeOfDay(12, 30, 59));
8523 testTOD(TimeOfDay(12, 30, 33), 27, TimeOfDay(12, 30, 0));
8524 testTOD(TimeOfDay(12, 30, 33), 30, TimeOfDay(12, 30, 3));
8525 testTOD(TimeOfDay(12, 30, 33), 59, TimeOfDay(12, 30, 32));
8526 testTOD(TimeOfDay(12, 30, 33), 60, TimeOfDay(12, 30, 33));
8527 testTOD(TimeOfDay(12, 30, 33), 61, TimeOfDay(12, 30, 34));
8529 testTOD(TimeOfDay(12, 30, 33), 1766, TimeOfDay(12, 30, 59));
8530 testTOD(TimeOfDay(12, 30, 33), 1767, TimeOfDay(12, 30, 0));
8531 testTOD(TimeOfDay(12, 30, 33), 1768, TimeOfDay(12, 30, 1));
8532 testTOD(TimeOfDay(12, 30, 33), 2007, TimeOfDay(12, 30, 0));
8533 testTOD(TimeOfDay(12, 30, 33), 3599, TimeOfDay(12, 30, 32));
8534 testTOD(TimeOfDay(12, 30, 33), 3600, TimeOfDay(12, 30, 33));
8535 testTOD(TimeOfDay(12, 30, 33), 3601, TimeOfDay(12, 30, 34));
8536 testTOD(TimeOfDay(12, 30, 33), 7200, TimeOfDay(12, 30, 33));
8538 testTOD(TimeOfDay(12, 30, 33), -1, TimeOfDay(12, 30, 32));
8539 testTOD(TimeOfDay(12, 30, 33), -2, TimeOfDay(12, 30, 31));
8540 testTOD(TimeOfDay(12, 30, 33), -3, TimeOfDay(12, 30, 30));
8541 testTOD(TimeOfDay(12, 30, 33), -4, TimeOfDay(12, 30, 29));
8542 testTOD(TimeOfDay(12, 30, 33), -5, TimeOfDay(12, 30, 28));
8543 testTOD(TimeOfDay(12, 30, 33), -10, TimeOfDay(12, 30, 23));
8544 testTOD(TimeOfDay(12, 30, 33), -15, TimeOfDay(12, 30, 18));
8545 testTOD(TimeOfDay(12, 30, 33), -33, TimeOfDay(12, 30, 0));
8546 testTOD(TimeOfDay(12, 30, 33), -34, TimeOfDay(12, 30, 59));
8547 testTOD(TimeOfDay(12, 30, 33), -35, TimeOfDay(12, 30, 58));
8548 testTOD(TimeOfDay(12, 30, 33), -59, TimeOfDay(12, 30, 34));
8549 testTOD(TimeOfDay(12, 30, 33), -60, TimeOfDay(12, 30, 33));
8550 testTOD(TimeOfDay(12, 30, 33), -61, TimeOfDay(12, 30, 32));
8552 testTOD(TimeOfDay(12, 30, 0), 1, TimeOfDay(12, 30, 1));
8553 testTOD(TimeOfDay(12, 30, 0), 0, TimeOfDay(12, 30, 0));
8554 testTOD(TimeOfDay(12, 30, 0), -1, TimeOfDay(12, 30, 59));
8556 testTOD(TimeOfDay(12, 0, 0), 1, TimeOfDay(12, 0, 1));
8557 testTOD(TimeOfDay(12, 0, 0), 0, TimeOfDay(12, 0, 0));
8558 testTOD(TimeOfDay(12, 0, 0), -1, TimeOfDay(12, 0, 59));
8560 testTOD(TimeOfDay(0, 0, 0), 1, TimeOfDay(0, 0, 1));
8561 testTOD(TimeOfDay(0, 0, 0), 0, TimeOfDay(0, 0, 0));
8562 testTOD(TimeOfDay(0, 0, 0), -1, TimeOfDay(0, 0, 59));
8564 testTOD(TimeOfDay(23, 59, 59), 1, TimeOfDay(23, 59, 0));
8565 testTOD(TimeOfDay(23, 59, 59), 0, TimeOfDay(23, 59, 59));
8566 testTOD(TimeOfDay(23, 59, 59), -1, TimeOfDay(23, 59, 58));
8568 auto tod = TimeOfDay(12, 27, 2);
8569 tod.roll!"seconds"(105).roll!"seconds"(-77);
8570 assert(tod == TimeOfDay(12, 27, 30));
8572 const ctod = TimeOfDay(0, 0, 0);
8573 immutable itod = TimeOfDay(0, 0, 0);
8574 static assert(!__traits(compiles, ctod.roll!"seconds"(7)));
8575 static assert(!__traits(compiles, itod.roll!"seconds"(7)));
8580 Gives the result of adding or subtracting a $(REF Duration, core,time)
8581 from this $(LREF TimeOfDay).
8583 The legal types of arithmetic for $(LREF TimeOfDay) using this operator
8586 $(BOOKTABLE,
8587 $(TR $(TD TimeOfDay) $(TD +) $(TD Duration) $(TD -->) $(TD TimeOfDay))
8588 $(TR $(TD TimeOfDay) $(TD -) $(TD Duration) $(TD -->) $(TD TimeOfDay))
8591 Params:
8592 duration = The $(REF Duration, core,time) to add to or subtract from
8593 this $(LREF TimeOfDay).
8595 TimeOfDay opBinary(string op)(Duration duration) const @safe pure nothrow @nogc
8596 if (op == "+" || op == "-")
8598 TimeOfDay retval = this;
8599 immutable seconds = duration.total!"seconds";
8600 mixin("return retval._addSeconds(" ~ op ~ "seconds);");
8604 @safe unittest
8606 import core.time : hours, minutes, seconds;
8608 assert(TimeOfDay(12, 12, 12) + seconds(1) == TimeOfDay(12, 12, 13));
8609 assert(TimeOfDay(12, 12, 12) + minutes(1) == TimeOfDay(12, 13, 12));
8610 assert(TimeOfDay(12, 12, 12) + hours(1) == TimeOfDay(13, 12, 12));
8611 assert(TimeOfDay(23, 59, 59) + seconds(1) == TimeOfDay(0, 0, 0));
8613 assert(TimeOfDay(12, 12, 12) - seconds(1) == TimeOfDay(12, 12, 11));
8614 assert(TimeOfDay(12, 12, 12) - minutes(1) == TimeOfDay(12, 11, 12));
8615 assert(TimeOfDay(12, 12, 12) - hours(1) == TimeOfDay(11, 12, 12));
8616 assert(TimeOfDay(0, 0, 0) - seconds(1) == TimeOfDay(23, 59, 59));
8619 @safe unittest
8621 auto tod = TimeOfDay(12, 30, 33);
8623 assert(tod + dur!"hours"(7) == TimeOfDay(19, 30, 33));
8624 assert(tod + dur!"hours"(-7) == TimeOfDay(5, 30, 33));
8625 assert(tod + dur!"minutes"(7) == TimeOfDay(12, 37, 33));
8626 assert(tod + dur!"minutes"(-7) == TimeOfDay(12, 23, 33));
8627 assert(tod + dur!"seconds"(7) == TimeOfDay(12, 30, 40));
8628 assert(tod + dur!"seconds"(-7) == TimeOfDay(12, 30, 26));
8630 assert(tod + dur!"msecs"(7000) == TimeOfDay(12, 30, 40));
8631 assert(tod + dur!"msecs"(-7000) == TimeOfDay(12, 30, 26));
8632 assert(tod + dur!"usecs"(7_000_000) == TimeOfDay(12, 30, 40));
8633 assert(tod + dur!"usecs"(-7_000_000) == TimeOfDay(12, 30, 26));
8634 assert(tod + dur!"hnsecs"(70_000_000) == TimeOfDay(12, 30, 40));
8635 assert(tod + dur!"hnsecs"(-70_000_000) == TimeOfDay(12, 30, 26));
8637 assert(tod - dur!"hours"(-7) == TimeOfDay(19, 30, 33));
8638 assert(tod - dur!"hours"(7) == TimeOfDay(5, 30, 33));
8639 assert(tod - dur!"minutes"(-7) == TimeOfDay(12, 37, 33));
8640 assert(tod - dur!"minutes"(7) == TimeOfDay(12, 23, 33));
8641 assert(tod - dur!"seconds"(-7) == TimeOfDay(12, 30, 40));
8642 assert(tod - dur!"seconds"(7) == TimeOfDay(12, 30, 26));
8644 assert(tod - dur!"msecs"(-7000) == TimeOfDay(12, 30, 40));
8645 assert(tod - dur!"msecs"(7000) == TimeOfDay(12, 30, 26));
8646 assert(tod - dur!"usecs"(-7_000_000) == TimeOfDay(12, 30, 40));
8647 assert(tod - dur!"usecs"(7_000_000) == TimeOfDay(12, 30, 26));
8648 assert(tod - dur!"hnsecs"(-70_000_000) == TimeOfDay(12, 30, 40));
8649 assert(tod - dur!"hnsecs"(70_000_000) == TimeOfDay(12, 30, 26));
8651 auto duration = dur!"hours"(11);
8652 const ctod = TimeOfDay(12, 30, 33);
8653 immutable itod = TimeOfDay(12, 30, 33);
8654 assert(tod + duration == TimeOfDay(23, 30, 33));
8655 assert(ctod + duration == TimeOfDay(23, 30, 33));
8656 assert(itod + duration == TimeOfDay(23, 30, 33));
8658 assert(tod - duration == TimeOfDay(1, 30, 33));
8659 assert(ctod - duration == TimeOfDay(1, 30, 33));
8660 assert(itod - duration == TimeOfDay(1, 30, 33));
8663 // Explicitly undocumented. It will be removed in January 2018. @@@DEPRECATED_2018-01@@@
8664 deprecated("Use Duration instead of TickDuration.")
8665 TimeOfDay opBinary(string op)(TickDuration td) const @safe pure nothrow @nogc
8666 if (op == "+" || op == "-")
8668 TimeOfDay retval = this;
8669 immutable seconds = td.seconds;
8670 mixin("return retval._addSeconds(" ~ op ~ "seconds);");
8673 deprecated @safe unittest
8675 // This probably only runs in cases where gettimeofday() is used, but it's
8676 // hard to do this test correctly with variable ticksPerSec.
8677 if (TickDuration.ticksPerSec == 1_000_000)
8679 auto tod = TimeOfDay(12, 30, 33);
8681 assert(tod + TickDuration.from!"usecs"(7_000_000) == TimeOfDay(12, 30, 40));
8682 assert(tod + TickDuration.from!"usecs"(-7_000_000) == TimeOfDay(12, 30, 26));
8684 assert(tod - TickDuration.from!"usecs"(-7_000_000) == TimeOfDay(12, 30, 40));
8685 assert(tod - TickDuration.from!"usecs"(7_000_000) == TimeOfDay(12, 30, 26));
8691 Gives the result of adding or subtracting a $(REF Duration, core,time)
8692 from this $(LREF TimeOfDay), as well as assigning the result to this
8693 $(LREF TimeOfDay).
8695 The legal types of arithmetic for $(LREF TimeOfDay) using this operator
8698 $(BOOKTABLE,
8699 $(TR $(TD TimeOfDay) $(TD +) $(TD Duration) $(TD -->) $(TD TimeOfDay))
8700 $(TR $(TD TimeOfDay) $(TD -) $(TD Duration) $(TD -->) $(TD TimeOfDay))
8703 Params:
8704 duration = The $(REF Duration, core,time) to add to or subtract from
8705 this $(LREF TimeOfDay).
8707 ref TimeOfDay opOpAssign(string op)(Duration duration) @safe pure nothrow @nogc
8708 if (op == "+" || op == "-")
8710 immutable seconds = duration.total!"seconds";
8711 mixin("return _addSeconds(" ~ op ~ "seconds);");
8714 @safe unittest
8716 auto duration = dur!"hours"(12);
8718 assert(TimeOfDay(12, 30, 33) + dur!"hours"(7) == TimeOfDay(19, 30, 33));
8719 assert(TimeOfDay(12, 30, 33) + dur!"hours"(-7) == TimeOfDay(5, 30, 33));
8720 assert(TimeOfDay(12, 30, 33) + dur!"minutes"(7) == TimeOfDay(12, 37, 33));
8721 assert(TimeOfDay(12, 30, 33) + dur!"minutes"(-7) == TimeOfDay(12, 23, 33));
8722 assert(TimeOfDay(12, 30, 33) + dur!"seconds"(7) == TimeOfDay(12, 30, 40));
8723 assert(TimeOfDay(12, 30, 33) + dur!"seconds"(-7) == TimeOfDay(12, 30, 26));
8725 assert(TimeOfDay(12, 30, 33) + dur!"msecs"(7000) == TimeOfDay(12, 30, 40));
8726 assert(TimeOfDay(12, 30, 33) + dur!"msecs"(-7000) == TimeOfDay(12, 30, 26));
8727 assert(TimeOfDay(12, 30, 33) + dur!"usecs"(7_000_000) == TimeOfDay(12, 30, 40));
8728 assert(TimeOfDay(12, 30, 33) + dur!"usecs"(-7_000_000) == TimeOfDay(12, 30, 26));
8729 assert(TimeOfDay(12, 30, 33) + dur!"hnsecs"(70_000_000) == TimeOfDay(12, 30, 40));
8730 assert(TimeOfDay(12, 30, 33) + dur!"hnsecs"(-70_000_000) == TimeOfDay(12, 30, 26));
8732 assert(TimeOfDay(12, 30, 33) - dur!"hours"(-7) == TimeOfDay(19, 30, 33));
8733 assert(TimeOfDay(12, 30, 33) - dur!"hours"(7) == TimeOfDay(5, 30, 33));
8734 assert(TimeOfDay(12, 30, 33) - dur!"minutes"(-7) == TimeOfDay(12, 37, 33));
8735 assert(TimeOfDay(12, 30, 33) - dur!"minutes"(7) == TimeOfDay(12, 23, 33));
8736 assert(TimeOfDay(12, 30, 33) - dur!"seconds"(-7) == TimeOfDay(12, 30, 40));
8737 assert(TimeOfDay(12, 30, 33) - dur!"seconds"(7) == TimeOfDay(12, 30, 26));
8739 assert(TimeOfDay(12, 30, 33) - dur!"msecs"(-7000) == TimeOfDay(12, 30, 40));
8740 assert(TimeOfDay(12, 30, 33) - dur!"msecs"(7000) == TimeOfDay(12, 30, 26));
8741 assert(TimeOfDay(12, 30, 33) - dur!"usecs"(-7_000_000) == TimeOfDay(12, 30, 40));
8742 assert(TimeOfDay(12, 30, 33) - dur!"usecs"(7_000_000) == TimeOfDay(12, 30, 26));
8743 assert(TimeOfDay(12, 30, 33) - dur!"hnsecs"(-70_000_000) == TimeOfDay(12, 30, 40));
8744 assert(TimeOfDay(12, 30, 33) - dur!"hnsecs"(70_000_000) == TimeOfDay(12, 30, 26));
8746 auto tod = TimeOfDay(19, 17, 22);
8747 (tod += dur!"seconds"(9)) += dur!"seconds"(-7292);
8748 assert(tod == TimeOfDay(17, 15, 59));
8750 const ctod = TimeOfDay(12, 33, 30);
8751 immutable itod = TimeOfDay(12, 33, 30);
8752 static assert(!__traits(compiles, ctod += duration));
8753 static assert(!__traits(compiles, itod += duration));
8754 static assert(!__traits(compiles, ctod -= duration));
8755 static assert(!__traits(compiles, itod -= duration));
8758 // Explicitly undocumented. It will be removed in January 2018. @@@DEPRECATED_2018-01@@@
8759 deprecated("Use Duration instead of TickDuration.")
8760 ref TimeOfDay opOpAssign(string op)(TickDuration td) @safe pure nothrow @nogc
8761 if (op == "+" || op == "-")
8763 immutable seconds = td.seconds;
8764 mixin("return _addSeconds(" ~ op ~ "seconds);");
8767 deprecated @safe unittest
8769 // This probably only runs in cases where gettimeofday() is used, but it's
8770 // hard to do this test correctly with variable ticksPerSec.
8771 if (TickDuration.ticksPerSec == 1_000_000)
8774 auto tod = TimeOfDay(12, 30, 33);
8775 tod += TickDuration.from!"usecs"(7_000_000);
8776 assert(tod == TimeOfDay(12, 30, 40));
8780 auto tod = TimeOfDay(12, 30, 33);
8781 tod += TickDuration.from!"usecs"(-7_000_000);
8782 assert(tod == TimeOfDay(12, 30, 26));
8786 auto tod = TimeOfDay(12, 30, 33);
8787 tod -= TickDuration.from!"usecs"(-7_000_000);
8788 assert(tod == TimeOfDay(12, 30, 40));
8792 auto tod = TimeOfDay(12, 30, 33);
8793 tod -= TickDuration.from!"usecs"(7_000_000);
8794 assert(tod == TimeOfDay(12, 30, 26));
8801 Gives the difference between two $(LREF TimeOfDay)s.
8803 The legal types of arithmetic for $(LREF TimeOfDay) using this operator
8806 $(BOOKTABLE,
8807 $(TR $(TD TimeOfDay) $(TD -) $(TD TimeOfDay) $(TD -->) $(TD duration))
8810 Params:
8811 rhs = The $(LREF TimeOfDay) to subtract from this one.
8813 Duration opBinary(string op)(in TimeOfDay rhs) const @safe pure nothrow @nogc
8814 if (op == "-")
8816 immutable lhsSec = _hour * 3600 + _minute * 60 + _second;
8817 immutable rhsSec = rhs._hour * 3600 + rhs._minute * 60 + rhs._second;
8819 return dur!"seconds"(lhsSec - rhsSec);
8822 @safe unittest
8824 auto tod = TimeOfDay(12, 30, 33);
8826 assert(TimeOfDay(7, 12, 52) - TimeOfDay(12, 30, 33) == dur!"seconds"(-19_061));
8827 assert(TimeOfDay(12, 30, 33) - TimeOfDay(7, 12, 52) == dur!"seconds"(19_061));
8828 assert(TimeOfDay(12, 30, 33) - TimeOfDay(14, 30, 33) == dur!"seconds"(-7200));
8829 assert(TimeOfDay(14, 30, 33) - TimeOfDay(12, 30, 33) == dur!"seconds"(7200));
8830 assert(TimeOfDay(12, 30, 33) - TimeOfDay(12, 34, 33) == dur!"seconds"(-240));
8831 assert(TimeOfDay(12, 34, 33) - TimeOfDay(12, 30, 33) == dur!"seconds"(240));
8832 assert(TimeOfDay(12, 30, 33) - TimeOfDay(12, 30, 34) == dur!"seconds"(-1));
8833 assert(TimeOfDay(12, 30, 34) - TimeOfDay(12, 30, 33) == dur!"seconds"(1));
8835 const ctod = TimeOfDay(12, 30, 33);
8836 immutable itod = TimeOfDay(12, 30, 33);
8837 assert(tod - tod == Duration.zero);
8838 assert(ctod - tod == Duration.zero);
8839 assert(itod - tod == Duration.zero);
8841 assert(tod - ctod == Duration.zero);
8842 assert(ctod - ctod == Duration.zero);
8843 assert(itod - ctod == Duration.zero);
8845 assert(tod - itod == Duration.zero);
8846 assert(ctod - itod == Duration.zero);
8847 assert(itod - itod == Duration.zero);
8852 Converts this $(LREF TimeOfDay) to a string with the format HHMMSS.
8854 string toISOString() const @safe pure nothrow
8856 import std.format : format;
8858 return format("%02d%02d%02d", _hour, _minute, _second);
8859 catch (Exception e)
8860 assert(0, "format() threw.");
8864 @safe unittest
8866 assert(TimeOfDay(0, 0, 0).toISOString() == "000000");
8867 assert(TimeOfDay(12, 30, 33).toISOString() == "123033");
8870 @safe unittest
8872 auto tod = TimeOfDay(12, 30, 33);
8873 const ctod = TimeOfDay(12, 30, 33);
8874 immutable itod = TimeOfDay(12, 30, 33);
8875 assert(tod.toISOString() == "123033");
8876 assert(ctod.toISOString() == "123033");
8877 assert(itod.toISOString() == "123033");
8882 Converts this $(LREF TimeOfDay) to a string with the format HH:MM:SS.
8884 string toISOExtString() const @safe pure nothrow
8886 import std.format : format;
8888 return format("%02d:%02d:%02d", _hour, _minute, _second);
8889 catch (Exception e)
8890 assert(0, "format() threw.");
8894 @safe unittest
8896 assert(TimeOfDay(0, 0, 0).toISOExtString() == "00:00:00");
8897 assert(TimeOfDay(12, 30, 33).toISOExtString() == "12:30:33");
8900 @safe unittest
8902 auto tod = TimeOfDay(12, 30, 33);
8903 const ctod = TimeOfDay(12, 30, 33);
8904 immutable itod = TimeOfDay(12, 30, 33);
8905 assert(tod.toISOExtString() == "12:30:33");
8906 assert(ctod.toISOExtString() == "12:30:33");
8907 assert(itod.toISOExtString() == "12:30:33");
8912 Converts this TimeOfDay to a string.
8914 This function exists to make it easy to convert a $(LREF TimeOfDay) to a
8915 string for code that does not care what the exact format is - just that
8916 it presents the information in a clear manner. It also makes it easy to
8917 simply convert a $(LREF TimeOfDay) to a string when using functions such
8918 as `to!string`, `format`, or `writeln` which use toString to convert
8919 user-defined types. So, it is unlikely that much code will call
8920 toString directly.
8922 The format of the string is purposefully unspecified, and code that
8923 cares about the format of the string should use `toISOString`,
8924 `toISOExtString`, or some other custom formatting function that
8925 explicitly generates the format that the code needs. The reason is that
8926 the code is then clear about what format it's using, making it less
8927 error-prone to maintain the code and interact with other software that
8928 consumes the generated strings. It's for this same reason that
8929 $(LREF TimeOfDay) has no `fromString` function, whereas it does have
8930 `fromISOString` and `fromISOExtString`.
8932 The format returned by toString may or may not change in the future.
8934 string toString() const @safe pure nothrow
8936 return toISOExtString();
8939 @safe unittest
8941 auto tod = TimeOfDay(12, 30, 33);
8942 const ctod = TimeOfDay(12, 30, 33);
8943 immutable itod = TimeOfDay(12, 30, 33);
8944 assert(tod.toString());
8945 assert(ctod.toString());
8946 assert(itod.toString());
8951 Creates a $(LREF TimeOfDay) from a string with the format HHMMSS.
8952 Whitespace is stripped from the given string.
8954 Params:
8955 isoString = A string formatted in the ISO format for times.
8957 Throws:
8958 $(REF DateTimeException,std,datetime,date) if the given string is
8959 not in the ISO format or if the resulting $(LREF TimeOfDay) would
8960 not be valid.
8962 static TimeOfDay fromISOString(S)(in S isoString) @safe pure
8963 if (isSomeString!S)
8965 import std.conv : to, text, ConvException;
8966 import std.exception : enforce;
8967 import std.string : strip;
8969 int hours, minutes, seconds;
8970 auto str = strip(isoString);
8972 enforce!DateTimeException(str.length == 6, text("Invalid ISO String: ", isoString));
8976 // cast to int from uint is used because it checks for
8977 // non digits without extra loops
8978 hours = cast(int) to!uint(str[0 .. 2]);
8979 minutes = cast(int) to!uint(str[2 .. 4]);
8980 seconds = cast(int) to!uint(str[4 .. $]);
8982 catch (ConvException)
8984 throw new DateTimeException(text("Invalid ISO String: ", isoString));
8987 return TimeOfDay(hours, minutes, seconds);
8991 @safe unittest
8993 assert(TimeOfDay.fromISOString("000000") == TimeOfDay(0, 0, 0));
8994 assert(TimeOfDay.fromISOString("123033") == TimeOfDay(12, 30, 33));
8995 assert(TimeOfDay.fromISOString(" 123033 ") == TimeOfDay(12, 30, 33));
8998 @safe unittest
9000 assertThrown!DateTimeException(TimeOfDay.fromISOString(""));
9001 assertThrown!DateTimeException(TimeOfDay.fromISOString("0"));
9002 assertThrown!DateTimeException(TimeOfDay.fromISOString("00"));
9003 assertThrown!DateTimeException(TimeOfDay.fromISOString("000"));
9004 assertThrown!DateTimeException(TimeOfDay.fromISOString("0000"));
9005 assertThrown!DateTimeException(TimeOfDay.fromISOString("00000"));
9006 assertThrown!DateTimeException(TimeOfDay.fromISOString("13033"));
9007 assertThrown!DateTimeException(TimeOfDay.fromISOString("1277"));
9008 assertThrown!DateTimeException(TimeOfDay.fromISOString("12707"));
9009 assertThrown!DateTimeException(TimeOfDay.fromISOString("12070"));
9010 assertThrown!DateTimeException(TimeOfDay.fromISOString("12303a"));
9011 assertThrown!DateTimeException(TimeOfDay.fromISOString("1230a3"));
9012 assertThrown!DateTimeException(TimeOfDay.fromISOString("123a33"));
9013 assertThrown!DateTimeException(TimeOfDay.fromISOString("12a033"));
9014 assertThrown!DateTimeException(TimeOfDay.fromISOString("1a0033"));
9015 assertThrown!DateTimeException(TimeOfDay.fromISOString("a20033"));
9016 assertThrown!DateTimeException(TimeOfDay.fromISOString("1200330"));
9017 assertThrown!DateTimeException(TimeOfDay.fromISOString("0120033"));
9018 assertThrown!DateTimeException(TimeOfDay.fromISOString("-120033"));
9019 assertThrown!DateTimeException(TimeOfDay.fromISOString("+120033"));
9020 assertThrown!DateTimeException(TimeOfDay.fromISOString("120033am"));
9021 assertThrown!DateTimeException(TimeOfDay.fromISOString("120033pm"));
9023 assertThrown!DateTimeException(TimeOfDay.fromISOString("0::"));
9024 assertThrown!DateTimeException(TimeOfDay.fromISOString(":0:"));
9025 assertThrown!DateTimeException(TimeOfDay.fromISOString("::0"));
9026 assertThrown!DateTimeException(TimeOfDay.fromISOString("0:0:0"));
9027 assertThrown!DateTimeException(TimeOfDay.fromISOString("0:0:00"));
9028 assertThrown!DateTimeException(TimeOfDay.fromISOString("0:00:0"));
9029 assertThrown!DateTimeException(TimeOfDay.fromISOString("00:0:0"));
9030 assertThrown!DateTimeException(TimeOfDay.fromISOString("00:00:0"));
9031 assertThrown!DateTimeException(TimeOfDay.fromISOString("00:0:00"));
9032 assertThrown!DateTimeException(TimeOfDay.fromISOString("13:0:33"));
9033 assertThrown!DateTimeException(TimeOfDay.fromISOString("12:7:7"));
9034 assertThrown!DateTimeException(TimeOfDay.fromISOString("12:7:07"));
9035 assertThrown!DateTimeException(TimeOfDay.fromISOString("12:07:0"));
9036 assertThrown!DateTimeException(TimeOfDay.fromISOString("12:30:3a"));
9037 assertThrown!DateTimeException(TimeOfDay.fromISOString("12:30:a3"));
9038 assertThrown!DateTimeException(TimeOfDay.fromISOString("12:3a:33"));
9039 assertThrown!DateTimeException(TimeOfDay.fromISOString("12:a0:33"));
9040 assertThrown!DateTimeException(TimeOfDay.fromISOString("1a:00:33"));
9041 assertThrown!DateTimeException(TimeOfDay.fromISOString("a2:00:33"));
9042 assertThrown!DateTimeException(TimeOfDay.fromISOString("12:003:30"));
9043 assertThrown!DateTimeException(TimeOfDay.fromISOString("120:03:30"));
9044 assertThrown!DateTimeException(TimeOfDay.fromISOString("012:00:33"));
9045 assertThrown!DateTimeException(TimeOfDay.fromISOString("01:200:33"));
9046 assertThrown!DateTimeException(TimeOfDay.fromISOString("-12:00:33"));
9047 assertThrown!DateTimeException(TimeOfDay.fromISOString("+12:00:33"));
9048 assertThrown!DateTimeException(TimeOfDay.fromISOString("12:00:33am"));
9049 assertThrown!DateTimeException(TimeOfDay.fromISOString("12:00:33pm"));
9051 assertThrown!DateTimeException(TimeOfDay.fromISOString("12:00:33"));
9053 assert(TimeOfDay.fromISOString("011217") == TimeOfDay(1, 12, 17));
9054 assert(TimeOfDay.fromISOString("001412") == TimeOfDay(0, 14, 12));
9055 assert(TimeOfDay.fromISOString("000007") == TimeOfDay(0, 0, 7));
9056 assert(TimeOfDay.fromISOString("011217 ") == TimeOfDay(1, 12, 17));
9057 assert(TimeOfDay.fromISOString(" 011217") == TimeOfDay(1, 12, 17));
9058 assert(TimeOfDay.fromISOString(" 011217 ") == TimeOfDay(1, 12, 17));
9061 // bug# 17801
9062 @safe unittest
9064 import std.conv : to;
9065 import std.meta : AliasSeq;
9066 foreach (C; AliasSeq!(char, wchar, dchar))
9068 foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[]))
9069 assert(TimeOfDay.fromISOString(to!S("141516")) == TimeOfDay(14, 15, 16));
9075 Creates a $(LREF TimeOfDay) from a string with the format HH:MM:SS.
9076 Whitespace is stripped from the given string.
9078 Params:
9079 isoExtString = A string formatted in the ISO Extended format for
9080 times.
9082 Throws:
9083 $(REF DateTimeException,std,datetime,date) if the given string is
9084 not in the ISO Extended format or if the resulting $(LREF TimeOfDay)
9085 would not be valid.
9087 static TimeOfDay fromISOExtString(S)(in S isoExtString) @safe pure
9088 if (isSomeString!S)
9090 import std.algorithm.searching : all;
9091 import std.ascii : isDigit;
9092 import std.conv : to;
9093 import std.exception : enforce;
9094 import std.format : format;
9095 import std.string : strip;
9097 auto dstr = to!dstring(strip(isoExtString));
9099 enforce(dstr.length == 8, new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
9101 auto hours = dstr[0 .. 2];
9102 auto minutes = dstr[3 .. 5];
9103 auto seconds = dstr[6 .. $];
9105 enforce(dstr[2] == ':', new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
9106 enforce(dstr[5] == ':', new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
9107 enforce(all!isDigit(hours),
9108 new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
9109 enforce(all!isDigit(minutes),
9110 new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
9111 enforce(all!isDigit(seconds),
9112 new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)));
9114 return TimeOfDay(to!int(hours), to!int(minutes), to!int(seconds));
9118 @safe unittest
9120 assert(TimeOfDay.fromISOExtString("00:00:00") == TimeOfDay(0, 0, 0));
9121 assert(TimeOfDay.fromISOExtString("12:30:33") == TimeOfDay(12, 30, 33));
9122 assert(TimeOfDay.fromISOExtString(" 12:30:33 ") == TimeOfDay(12, 30, 33));
9125 @safe unittest
9127 assertThrown!DateTimeException(TimeOfDay.fromISOExtString(""));
9128 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("0"));
9129 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("00"));
9130 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("000"));
9131 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("0000"));
9132 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("00000"));
9133 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("13033"));
9134 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("1277"));
9135 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12707"));
9136 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12070"));
9137 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12303a"));
9138 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("1230a3"));
9139 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("123a33"));
9140 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12a033"));
9141 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("1a0033"));
9142 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("a20033"));
9143 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("1200330"));
9144 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("0120033"));
9145 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("-120033"));
9146 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("+120033"));
9147 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("120033am"));
9148 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("120033pm"));
9150 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("0::"));
9151 assertThrown!DateTimeException(TimeOfDay.fromISOExtString(":0:"));
9152 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("::0"));
9153 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("0:0:0"));
9154 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("0:0:00"));
9155 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("0:00:0"));
9156 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("00:0:0"));
9157 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("00:00:0"));
9158 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("00:0:00"));
9159 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("13:0:33"));
9160 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12:7:7"));
9161 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12:7:07"));
9162 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12:07:0"));
9163 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12:30:3a"));
9164 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12:30:a3"));
9165 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12:3a:33"));
9166 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12:a0:33"));
9167 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("1a:00:33"));
9168 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("a2:00:33"));
9169 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12:003:30"));
9170 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("120:03:30"));
9171 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("012:00:33"));
9172 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("01:200:33"));
9173 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("-12:00:33"));
9174 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("+12:00:33"));
9175 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12:00:33am"));
9176 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("12:00:33pm"));
9178 assertThrown!DateTimeException(TimeOfDay.fromISOExtString("120033"));
9180 assert(TimeOfDay.fromISOExtString("01:12:17") == TimeOfDay(1, 12, 17));
9181 assert(TimeOfDay.fromISOExtString("00:14:12") == TimeOfDay(0, 14, 12));
9182 assert(TimeOfDay.fromISOExtString("00:00:07") == TimeOfDay(0, 0, 7));
9183 assert(TimeOfDay.fromISOExtString("01:12:17 ") == TimeOfDay(1, 12, 17));
9184 assert(TimeOfDay.fromISOExtString(" 01:12:17") == TimeOfDay(1, 12, 17));
9185 assert(TimeOfDay.fromISOExtString(" 01:12:17 ") == TimeOfDay(1, 12, 17));
9188 // bug# 17801
9189 @safe unittest
9191 import std.conv : to;
9192 import std.meta : AliasSeq;
9193 foreach (C; AliasSeq!(char, wchar, dchar))
9195 foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[]))
9196 assert(TimeOfDay.fromISOExtString(to!S("14:15:16")) == TimeOfDay(14, 15, 16));
9202 Returns midnight.
9204 @property static TimeOfDay min() @safe pure nothrow @nogc
9206 return TimeOfDay.init;
9209 @safe unittest
9211 assert(TimeOfDay.min.hour == 0);
9212 assert(TimeOfDay.min.minute == 0);
9213 assert(TimeOfDay.min.second == 0);
9214 assert(TimeOfDay.min < TimeOfDay.max);
9219 Returns one second short of midnight.
9221 @property static TimeOfDay max() @safe pure nothrow @nogc
9223 auto tod = TimeOfDay.init;
9224 tod._hour = maxHour;
9225 tod._minute = maxMinute;
9226 tod._second = maxSecond;
9228 return tod;
9231 @safe unittest
9233 assert(TimeOfDay.max.hour == 23);
9234 assert(TimeOfDay.max.minute == 59);
9235 assert(TimeOfDay.max.second == 59);
9236 assert(TimeOfDay.max > TimeOfDay.min);
9240 private:
9243 Add seconds to the time of day. Negative values will subtract. If the
9244 number of seconds overflows (or underflows), then the seconds will wrap,
9245 increasing (or decreasing) the number of minutes accordingly. If the
9246 number of minutes overflows (or underflows), then the minutes will wrap.
9247 If the number of minutes overflows(or underflows), then the hour will
9248 wrap. (e.g. adding 90 seconds to 23:59:00 would result in 00:00:30).
9250 Params:
9251 seconds = The number of seconds to add to this TimeOfDay.
9253 ref TimeOfDay _addSeconds(long seconds) return @safe pure nothrow @nogc
9255 long hnsecs = convert!("seconds", "hnsecs")(seconds);
9256 hnsecs += convert!("hours", "hnsecs")(_hour);
9257 hnsecs += convert!("minutes", "hnsecs")(_minute);
9258 hnsecs += convert!("seconds", "hnsecs")(_second);
9260 hnsecs %= convert!("days", "hnsecs")(1);
9262 if (hnsecs < 0)
9263 hnsecs += convert!("days", "hnsecs")(1);
9265 immutable newHours = splitUnitsFromHNSecs!"hours"(hnsecs);
9266 immutable newMinutes = splitUnitsFromHNSecs!"minutes"(hnsecs);
9267 immutable newSeconds = splitUnitsFromHNSecs!"seconds"(hnsecs);
9269 _hour = cast(ubyte) newHours;
9270 _minute = cast(ubyte) newMinutes;
9271 _second = cast(ubyte) newSeconds;
9273 return this;
9276 @safe unittest
9278 static void testTOD(TimeOfDay orig, int seconds, in TimeOfDay expected, size_t line = __LINE__)
9280 orig._addSeconds(seconds);
9281 assert(orig == expected);
9284 testTOD(TimeOfDay(12, 30, 33), 0, TimeOfDay(12, 30, 33));
9285 testTOD(TimeOfDay(12, 30, 33), 1, TimeOfDay(12, 30, 34));
9286 testTOD(TimeOfDay(12, 30, 33), 2, TimeOfDay(12, 30, 35));
9287 testTOD(TimeOfDay(12, 30, 33), 3, TimeOfDay(12, 30, 36));
9288 testTOD(TimeOfDay(12, 30, 33), 4, TimeOfDay(12, 30, 37));
9289 testTOD(TimeOfDay(12, 30, 33), 5, TimeOfDay(12, 30, 38));
9290 testTOD(TimeOfDay(12, 30, 33), 10, TimeOfDay(12, 30, 43));
9291 testTOD(TimeOfDay(12, 30, 33), 15, TimeOfDay(12, 30, 48));
9292 testTOD(TimeOfDay(12, 30, 33), 26, TimeOfDay(12, 30, 59));
9293 testTOD(TimeOfDay(12, 30, 33), 27, TimeOfDay(12, 31, 0));
9294 testTOD(TimeOfDay(12, 30, 33), 30, TimeOfDay(12, 31, 3));
9295 testTOD(TimeOfDay(12, 30, 33), 59, TimeOfDay(12, 31, 32));
9296 testTOD(TimeOfDay(12, 30, 33), 60, TimeOfDay(12, 31, 33));
9297 testTOD(TimeOfDay(12, 30, 33), 61, TimeOfDay(12, 31, 34));
9299 testTOD(TimeOfDay(12, 30, 33), 1766, TimeOfDay(12, 59, 59));
9300 testTOD(TimeOfDay(12, 30, 33), 1767, TimeOfDay(13, 0, 0));
9301 testTOD(TimeOfDay(12, 30, 33), 1768, TimeOfDay(13, 0, 1));
9302 testTOD(TimeOfDay(12, 30, 33), 2007, TimeOfDay(13, 4, 0));
9303 testTOD(TimeOfDay(12, 30, 33), 3599, TimeOfDay(13, 30, 32));
9304 testTOD(TimeOfDay(12, 30, 33), 3600, TimeOfDay(13, 30, 33));
9305 testTOD(TimeOfDay(12, 30, 33), 3601, TimeOfDay(13, 30, 34));
9306 testTOD(TimeOfDay(12, 30, 33), 7200, TimeOfDay(14, 30, 33));
9308 testTOD(TimeOfDay(12, 30, 33), -1, TimeOfDay(12, 30, 32));
9309 testTOD(TimeOfDay(12, 30, 33), -2, TimeOfDay(12, 30, 31));
9310 testTOD(TimeOfDay(12, 30, 33), -3, TimeOfDay(12, 30, 30));
9311 testTOD(TimeOfDay(12, 30, 33), -4, TimeOfDay(12, 30, 29));
9312 testTOD(TimeOfDay(12, 30, 33), -5, TimeOfDay(12, 30, 28));
9313 testTOD(TimeOfDay(12, 30, 33), -10, TimeOfDay(12, 30, 23));
9314 testTOD(TimeOfDay(12, 30, 33), -15, TimeOfDay(12, 30, 18));
9315 testTOD(TimeOfDay(12, 30, 33), -33, TimeOfDay(12, 30, 0));
9316 testTOD(TimeOfDay(12, 30, 33), -34, TimeOfDay(12, 29, 59));
9317 testTOD(TimeOfDay(12, 30, 33), -35, TimeOfDay(12, 29, 58));
9318 testTOD(TimeOfDay(12, 30, 33), -59, TimeOfDay(12, 29, 34));
9319 testTOD(TimeOfDay(12, 30, 33), -60, TimeOfDay(12, 29, 33));
9320 testTOD(TimeOfDay(12, 30, 33), -61, TimeOfDay(12, 29, 32));
9322 testTOD(TimeOfDay(12, 30, 33), -1833, TimeOfDay(12, 0, 0));
9323 testTOD(TimeOfDay(12, 30, 33), -1834, TimeOfDay(11, 59, 59));
9324 testTOD(TimeOfDay(12, 30, 33), -3600, TimeOfDay(11, 30, 33));
9325 testTOD(TimeOfDay(12, 30, 33), -3601, TimeOfDay(11, 30, 32));
9326 testTOD(TimeOfDay(12, 30, 33), -5134, TimeOfDay(11, 4, 59));
9327 testTOD(TimeOfDay(12, 30, 33), -7200, TimeOfDay(10, 30, 33));
9329 testTOD(TimeOfDay(12, 30, 0), 1, TimeOfDay(12, 30, 1));
9330 testTOD(TimeOfDay(12, 30, 0), 0, TimeOfDay(12, 30, 0));
9331 testTOD(TimeOfDay(12, 30, 0), -1, TimeOfDay(12, 29, 59));
9333 testTOD(TimeOfDay(12, 0, 0), 1, TimeOfDay(12, 0, 1));
9334 testTOD(TimeOfDay(12, 0, 0), 0, TimeOfDay(12, 0, 0));
9335 testTOD(TimeOfDay(12, 0, 0), -1, TimeOfDay(11, 59, 59));
9337 testTOD(TimeOfDay(0, 0, 0), 1, TimeOfDay(0, 0, 1));
9338 testTOD(TimeOfDay(0, 0, 0), 0, TimeOfDay(0, 0, 0));
9339 testTOD(TimeOfDay(0, 0, 0), -1, TimeOfDay(23, 59, 59));
9341 testTOD(TimeOfDay(23, 59, 59), 1, TimeOfDay(0, 0, 0));
9342 testTOD(TimeOfDay(23, 59, 59), 0, TimeOfDay(23, 59, 59));
9343 testTOD(TimeOfDay(23, 59, 59), -1, TimeOfDay(23, 59, 58));
9345 const ctod = TimeOfDay(0, 0, 0);
9346 immutable itod = TimeOfDay(0, 0, 0);
9347 static assert(!__traits(compiles, ctod._addSeconds(7)));
9348 static assert(!__traits(compiles, itod._addSeconds(7)));
9353 Whether the given values form a valid $(LREF TimeOfDay).
9355 static bool _valid(int hour, int minute, int second) @safe pure nothrow @nogc
9357 return valid!"hours"(hour) && valid!"minutes"(minute) && valid!"seconds"(second);
9361 @safe pure invariant()
9363 import std.format : format;
9364 assert(_valid(_hour, _minute, _second),
9365 format("Invariant Failure: hour [%s] minute [%s] second [%s]", _hour, _minute, _second));
9369 package:
9371 ubyte _hour;
9372 ubyte _minute;
9373 ubyte _second;
9375 enum ubyte maxHour = 24 - 1;
9376 enum ubyte maxMinute = 60 - 1;
9377 enum ubyte maxSecond = 60 - 1;
9382 Returns whether the given value is valid for the given unit type when in a
9383 time point. Naturally, a duration is not held to a particular range, but
9384 the values in a time point are (e.g. a month must be in the range of
9385 1 - 12 inclusive).
9387 Params:
9388 units = The units of time to validate.
9389 value = The number to validate.
9391 bool valid(string units)(int value) @safe pure nothrow @nogc
9392 if (units == "months" ||
9393 units == "hours" ||
9394 units == "minutes" ||
9395 units == "seconds")
9397 static if (units == "months")
9398 return value >= Month.jan && value <= Month.dec;
9399 else static if (units == "hours")
9400 return value >= 0 && value <= 23;
9401 else static if (units == "minutes")
9402 return value >= 0 && value <= 59;
9403 else static if (units == "seconds")
9404 return value >= 0 && value <= 59;
9408 @safe unittest
9410 assert(valid!"hours"(12));
9411 assert(!valid!"hours"(32));
9412 assert(valid!"months"(12));
9413 assert(!valid!"months"(13));
9417 Returns whether the given day is valid for the given year and month.
9419 Params:
9420 units = The units of time to validate.
9421 year = The year of the day to validate.
9422 month = The month of the day to validate (January is 1).
9423 day = The day to validate.
9425 bool valid(string units)(int year, int month, int day) @safe pure nothrow @nogc
9426 if (units == "days")
9428 return day > 0 && day <= maxDay(year, month);
9432 @safe pure nothrow @nogc unittest
9434 assert(valid!"days"(2016, 2, 29));
9435 assert(!valid!"days"(2016, 2, 30));
9436 assert(valid!"days"(2017, 2, 20));
9437 assert(!valid!"days"(2017, 2, 29));
9442 Params:
9443 units = The units of time to validate.
9444 value = The number to validate.
9445 file = The file that the $(LREF DateTimeException) will list if thrown.
9446 line = The line number that the $(LREF DateTimeException) will list if
9447 thrown.
9449 Throws:
9450 $(LREF DateTimeException) if $(D valid!units(value)) is false.
9452 void enforceValid(string units)(int value, string file = __FILE__, size_t line = __LINE__) @safe pure
9453 if (units == "months" ||
9454 units == "hours" ||
9455 units == "minutes" ||
9456 units == "seconds")
9458 import std.format : format;
9460 static if (units == "months")
9462 if (!valid!units(value))
9463 throw new DateTimeException(format("%s is not a valid month of the year.", value), file, line);
9465 else static if (units == "hours")
9467 if (!valid!units(value))
9468 throw new DateTimeException(format("%s is not a valid hour of the day.", value), file, line);
9470 else static if (units == "minutes")
9472 if (!valid!units(value))
9473 throw new DateTimeException(format("%s is not a valid minute of an hour.", value), file, line);
9475 else static if (units == "seconds")
9477 if (!valid!units(value))
9478 throw new DateTimeException(format("%s is not a valid second of a minute.", value), file, line);
9484 Params:
9485 units = The units of time to validate.
9486 year = The year of the day to validate.
9487 month = The month of the day to validate.
9488 day = The day to validate.
9489 file = The file that the $(LREF DateTimeException) will list if thrown.
9490 line = The line number that the $(LREF DateTimeException) will list if
9491 thrown.
9493 Throws:
9494 $(LREF DateTimeException) if $(D valid!"days"(year, month, day)) is false.
9496 void enforceValid(string units)
9497 (int year, Month month, int day, string file = __FILE__, size_t line = __LINE__) @safe pure
9498 if (units == "days")
9500 import std.format : format;
9501 if (!valid!"days"(year, month, day))
9502 throw new DateTimeException(format("%s is not a valid day in %s in %s", day, month, year), file, line);
9507 Returns the number of days from the current day of the week to the given
9508 day of the week. If they are the same, then the result is 0.
9510 Params:
9511 currDoW = The current day of the week.
9512 dow = The day of the week to get the number of days to.
9514 int daysToDayOfWeek(DayOfWeek currDoW, DayOfWeek dow) @safe pure nothrow @nogc
9516 if (currDoW == dow)
9517 return 0;
9518 if (currDoW < dow)
9519 return dow - currDoW;
9520 return DayOfWeek.sat - currDoW + dow + 1;
9524 @safe pure nothrow @nogc unittest
9526 assert(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.mon) == 0);
9527 assert(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.sun) == 6);
9528 assert(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.wed) == 2);
9531 @safe unittest
9533 assert(daysToDayOfWeek(DayOfWeek.sun, DayOfWeek.sun) == 0);
9534 assert(daysToDayOfWeek(DayOfWeek.sun, DayOfWeek.mon) == 1);
9535 assert(daysToDayOfWeek(DayOfWeek.sun, DayOfWeek.tue) == 2);
9536 assert(daysToDayOfWeek(DayOfWeek.sun, DayOfWeek.wed) == 3);
9537 assert(daysToDayOfWeek(DayOfWeek.sun, DayOfWeek.thu) == 4);
9538 assert(daysToDayOfWeek(DayOfWeek.sun, DayOfWeek.fri) == 5);
9539 assert(daysToDayOfWeek(DayOfWeek.sun, DayOfWeek.sat) == 6);
9541 assert(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.sun) == 6);
9542 assert(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.mon) == 0);
9543 assert(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.tue) == 1);
9544 assert(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.wed) == 2);
9545 assert(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.thu) == 3);
9546 assert(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.fri) == 4);
9547 assert(daysToDayOfWeek(DayOfWeek.mon, DayOfWeek.sat) == 5);
9549 assert(daysToDayOfWeek(DayOfWeek.tue, DayOfWeek.sun) == 5);
9550 assert(daysToDayOfWeek(DayOfWeek.tue, DayOfWeek.mon) == 6);
9551 assert(daysToDayOfWeek(DayOfWeek.tue, DayOfWeek.tue) == 0);
9552 assert(daysToDayOfWeek(DayOfWeek.tue, DayOfWeek.wed) == 1);
9553 assert(daysToDayOfWeek(DayOfWeek.tue, DayOfWeek.thu) == 2);
9554 assert(daysToDayOfWeek(DayOfWeek.tue, DayOfWeek.fri) == 3);
9555 assert(daysToDayOfWeek(DayOfWeek.tue, DayOfWeek.sat) == 4);
9557 assert(daysToDayOfWeek(DayOfWeek.wed, DayOfWeek.sun) == 4);
9558 assert(daysToDayOfWeek(DayOfWeek.wed, DayOfWeek.mon) == 5);
9559 assert(daysToDayOfWeek(DayOfWeek.wed, DayOfWeek.tue) == 6);
9560 assert(daysToDayOfWeek(DayOfWeek.wed, DayOfWeek.wed) == 0);
9561 assert(daysToDayOfWeek(DayOfWeek.wed, DayOfWeek.thu) == 1);
9562 assert(daysToDayOfWeek(DayOfWeek.wed, DayOfWeek.fri) == 2);
9563 assert(daysToDayOfWeek(DayOfWeek.wed, DayOfWeek.sat) == 3);
9565 assert(daysToDayOfWeek(DayOfWeek.thu, DayOfWeek.sun) == 3);
9566 assert(daysToDayOfWeek(DayOfWeek.thu, DayOfWeek.mon) == 4);
9567 assert(daysToDayOfWeek(DayOfWeek.thu, DayOfWeek.tue) == 5);
9568 assert(daysToDayOfWeek(DayOfWeek.thu, DayOfWeek.wed) == 6);
9569 assert(daysToDayOfWeek(DayOfWeek.thu, DayOfWeek.thu) == 0);
9570 assert(daysToDayOfWeek(DayOfWeek.thu, DayOfWeek.fri) == 1);
9571 assert(daysToDayOfWeek(DayOfWeek.thu, DayOfWeek.sat) == 2);
9573 assert(daysToDayOfWeek(DayOfWeek.fri, DayOfWeek.sun) == 2);
9574 assert(daysToDayOfWeek(DayOfWeek.fri, DayOfWeek.mon) == 3);
9575 assert(daysToDayOfWeek(DayOfWeek.fri, DayOfWeek.tue) == 4);
9576 assert(daysToDayOfWeek(DayOfWeek.fri, DayOfWeek.wed) == 5);
9577 assert(daysToDayOfWeek(DayOfWeek.fri, DayOfWeek.thu) == 6);
9578 assert(daysToDayOfWeek(DayOfWeek.fri, DayOfWeek.fri) == 0);
9579 assert(daysToDayOfWeek(DayOfWeek.fri, DayOfWeek.sat) == 1);
9581 assert(daysToDayOfWeek(DayOfWeek.sat, DayOfWeek.sun) == 1);
9582 assert(daysToDayOfWeek(DayOfWeek.sat, DayOfWeek.mon) == 2);
9583 assert(daysToDayOfWeek(DayOfWeek.sat, DayOfWeek.tue) == 3);
9584 assert(daysToDayOfWeek(DayOfWeek.sat, DayOfWeek.wed) == 4);
9585 assert(daysToDayOfWeek(DayOfWeek.sat, DayOfWeek.thu) == 5);
9586 assert(daysToDayOfWeek(DayOfWeek.sat, DayOfWeek.fri) == 6);
9587 assert(daysToDayOfWeek(DayOfWeek.sat, DayOfWeek.sat) == 0);
9592 Returns the number of months from the current months of the year to the
9593 given month of the year. If they are the same, then the result is 0.
9595 Params:
9596 currMonth = The current month of the year.
9597 month = The month of the year to get the number of months to.
9599 int monthsToMonth(int currMonth, int month) @safe pure
9601 enforceValid!"months"(currMonth);
9602 enforceValid!"months"(month);
9604 if (currMonth == month)
9605 return 0;
9606 if (currMonth < month)
9607 return month - currMonth;
9608 return Month.dec - currMonth + month;
9612 @safe pure unittest
9614 assert(monthsToMonth(Month.jan, Month.jan) == 0);
9615 assert(monthsToMonth(Month.jan, Month.dec) == 11);
9616 assert(monthsToMonth(Month.jul, Month.oct) == 3);
9619 @safe unittest
9621 assert(monthsToMonth(Month.jan, Month.jan) == 0);
9622 assert(monthsToMonth(Month.jan, Month.feb) == 1);
9623 assert(monthsToMonth(Month.jan, Month.mar) == 2);
9624 assert(monthsToMonth(Month.jan, Month.apr) == 3);
9625 assert(monthsToMonth(Month.jan, Month.may) == 4);
9626 assert(monthsToMonth(Month.jan, Month.jun) == 5);
9627 assert(monthsToMonth(Month.jan, Month.jul) == 6);
9628 assert(monthsToMonth(Month.jan, Month.aug) == 7);
9629 assert(monthsToMonth(Month.jan, Month.sep) == 8);
9630 assert(monthsToMonth(Month.jan, Month.oct) == 9);
9631 assert(monthsToMonth(Month.jan, Month.nov) == 10);
9632 assert(monthsToMonth(Month.jan, Month.dec) == 11);
9634 assert(monthsToMonth(Month.may, Month.jan) == 8);
9635 assert(monthsToMonth(Month.may, Month.feb) == 9);
9636 assert(monthsToMonth(Month.may, Month.mar) == 10);
9637 assert(monthsToMonth(Month.may, Month.apr) == 11);
9638 assert(monthsToMonth(Month.may, Month.may) == 0);
9639 assert(monthsToMonth(Month.may, Month.jun) == 1);
9640 assert(monthsToMonth(Month.may, Month.jul) == 2);
9641 assert(monthsToMonth(Month.may, Month.aug) == 3);
9642 assert(monthsToMonth(Month.may, Month.sep) == 4);
9643 assert(monthsToMonth(Month.may, Month.oct) == 5);
9644 assert(monthsToMonth(Month.may, Month.nov) == 6);
9645 assert(monthsToMonth(Month.may, Month.dec) == 7);
9647 assert(monthsToMonth(Month.oct, Month.jan) == 3);
9648 assert(monthsToMonth(Month.oct, Month.feb) == 4);
9649 assert(monthsToMonth(Month.oct, Month.mar) == 5);
9650 assert(monthsToMonth(Month.oct, Month.apr) == 6);
9651 assert(monthsToMonth(Month.oct, Month.may) == 7);
9652 assert(monthsToMonth(Month.oct, Month.jun) == 8);
9653 assert(monthsToMonth(Month.oct, Month.jul) == 9);
9654 assert(monthsToMonth(Month.oct, Month.aug) == 10);
9655 assert(monthsToMonth(Month.oct, Month.sep) == 11);
9656 assert(monthsToMonth(Month.oct, Month.oct) == 0);
9657 assert(monthsToMonth(Month.oct, Month.nov) == 1);
9658 assert(monthsToMonth(Month.oct, Month.dec) == 2);
9660 assert(monthsToMonth(Month.dec, Month.jan) == 1);
9661 assert(monthsToMonth(Month.dec, Month.feb) == 2);
9662 assert(monthsToMonth(Month.dec, Month.mar) == 3);
9663 assert(monthsToMonth(Month.dec, Month.apr) == 4);
9664 assert(monthsToMonth(Month.dec, Month.may) == 5);
9665 assert(monthsToMonth(Month.dec, Month.jun) == 6);
9666 assert(monthsToMonth(Month.dec, Month.jul) == 7);
9667 assert(monthsToMonth(Month.dec, Month.aug) == 8);
9668 assert(monthsToMonth(Month.dec, Month.sep) == 9);
9669 assert(monthsToMonth(Month.dec, Month.oct) == 10);
9670 assert(monthsToMonth(Month.dec, Month.nov) == 11);
9671 assert(monthsToMonth(Month.dec, Month.dec) == 0);
9676 Whether the given Gregorian Year is a leap year.
9678 Params:
9679 year = The year to to be tested.
9681 bool yearIsLeapYear(int year) @safe pure nothrow @nogc
9683 if (year % 400 == 0)
9684 return true;
9685 if (year % 100 == 0)
9686 return false;
9687 return year % 4 == 0;
9691 @safe unittest
9693 foreach (year; [1, 2, 100, 2001, 2002, 2003, 2005, 2006, 2007, 2009, 2010])
9695 assert(!yearIsLeapYear(year));
9696 assert(!yearIsLeapYear(-year));
9699 foreach (year; [0, 4, 8, 400, 800, 1600, 1996, 2000, 2004, 2008, 2012])
9701 assert(yearIsLeapYear(year));
9702 assert(yearIsLeapYear(-year));
9706 @safe unittest
9708 import std.format : format;
9709 foreach (year; [1, 2, 3, 5, 6, 7, 100, 200, 300, 500, 600, 700, 1998, 1999,
9710 2001, 2002, 2003, 2005, 2006, 2007, 2009, 2010, 2011])
9712 assert(!yearIsLeapYear(year), format("year: %s.", year));
9713 assert(!yearIsLeapYear(-year), format("year: %s.", year));
9716 foreach (year; [0, 4, 8, 400, 800, 1600, 1996, 2000, 2004, 2008, 2012])
9718 assert(yearIsLeapYear(year), format("year: %s.", year));
9719 assert(yearIsLeapYear(-year), format("year: %s.", year));
9725 Whether the given type defines all of the necessary functions for it to
9726 function as a time point.
9728 1. $(D T) must define a static property named $(D min) which is the smallest
9729 value of $(D T) as $(D Unqual!T).
9731 2. $(D T) must define a static property named $(D max) which is the largest
9732 value of $(D T) as $(D Unqual!T).
9734 3. $(D T) must define an $(D opBinary) for addition and subtraction that
9735 accepts $(REF Duration, core,time) and returns $(D Unqual!T).
9737 4. $(D T) must define an $(D opOpAssign) for addition and subtraction that
9738 accepts $(REF Duration, core,time) and returns $(D ref Unqual!T).
9740 5. $(D T) must define a $(D opBinary) for subtraction which accepts $(D T)
9741 and returns returns $(REF Duration, core,time).
9743 template isTimePoint(T)
9745 import core.time : Duration;
9746 import std.traits : FunctionAttribute, functionAttributes, Unqual;
9748 enum isTimePoint = hasMin &&
9749 hasMax &&
9750 hasOverloadedOpBinaryWithDuration &&
9751 hasOverloadedOpAssignWithDuration &&
9752 hasOverloadedOpBinaryWithSelf &&
9753 !is(U == Duration);
9755 private:
9757 alias U = Unqual!T;
9759 enum hasMin = __traits(hasMember, T, "min") &&
9760 is(typeof(T.min) == U) &&
9761 is(typeof({static assert(__traits(isStaticFunction, T.min));}));
9763 enum hasMax = __traits(hasMember, T, "max") &&
9764 is(typeof(T.max) == U) &&
9765 is(typeof({static assert(__traits(isStaticFunction, T.max));}));
9767 enum hasOverloadedOpBinaryWithDuration = is(typeof(T.init + Duration.init) == U) &&
9768 is(typeof(T.init - Duration.init) == U);
9770 enum hasOverloadedOpAssignWithDuration = is(typeof(U.init += Duration.init) == U) &&
9771 is(typeof(U.init -= Duration.init) == U) &&
9772 is(typeof(
9774 // Until the overload with TickDuration is removed, this is ambiguous.
9775 //alias add = U.opOpAssign!"+";
9776 //alias sub = U.opOpAssign!"-";
9777 U u;
9778 auto ref add() { return u += Duration.init; }
9779 auto ref sub() { return u -= Duration.init; }
9780 alias FA = FunctionAttribute;
9781 static assert((functionAttributes!add & FA.ref_) != 0);
9782 static assert((functionAttributes!sub & FA.ref_) != 0);
9783 }));
9785 enum hasOverloadedOpBinaryWithSelf = is(typeof(T.init - T.init) == Duration);
9789 @safe unittest
9791 import core.time : Duration;
9792 import std.datetime.interval : Interval;
9793 import std.datetime.systime : SysTime;
9795 static assert(isTimePoint!Date);
9796 static assert(isTimePoint!DateTime);
9797 static assert(isTimePoint!SysTime);
9798 static assert(isTimePoint!TimeOfDay);
9800 static assert(!isTimePoint!int);
9801 static assert(!isTimePoint!Duration);
9802 static assert(!isTimePoint!(Interval!SysTime));
9805 @safe unittest
9807 import core.time;
9808 import std.datetime.interval;
9809 import std.datetime.systime;
9810 import std.meta : AliasSeq;
9812 foreach (TP; AliasSeq!(Date, DateTime, SysTime, TimeOfDay))
9814 static assert(isTimePoint!(const TP), TP.stringof);
9815 static assert(isTimePoint!(immutable TP), TP.stringof);
9818 foreach (T; AliasSeq!(float, string, Duration, Interval!Date, PosInfInterval!Date, NegInfInterval!Date))
9819 static assert(!isTimePoint!T, T.stringof);
9824 Whether all of the given strings are valid units of time.
9826 $(D "nsecs") is not considered a valid unit of time. Nothing in std.datetime
9827 can handle precision greater than hnsecs, and the few functions in core.time
9828 which deal with "nsecs" deal with it explicitly.
9830 bool validTimeUnits(string[] units...) @safe pure nothrow @nogc
9832 import std.algorithm.searching : canFind;
9833 foreach (str; units)
9835 if (!canFind(timeStrings[], str))
9836 return false;
9838 return true;
9842 @safe @nogc nothrow unittest
9844 assert(validTimeUnits("msecs", "seconds", "minutes"));
9845 assert(validTimeUnits("days", "weeks", "months"));
9846 assert(!validTimeUnits("ms", "seconds", "minutes"));
9851 Compares two time unit strings. $(D "years") are the largest units and
9852 $(D "hnsecs") are the smallest.
9854 Returns:
9855 $(BOOKTABLE,
9856 $(TR $(TD this &lt; rhs) $(TD &lt; 0))
9857 $(TR $(TD this == rhs) $(TD 0))
9858 $(TR $(TD this &gt; rhs) $(TD &gt; 0))
9861 Throws:
9862 $(LREF DateTimeException) if either of the given strings is not a valid
9863 time unit string.
9865 int cmpTimeUnits(string lhs, string rhs) @safe pure
9867 import std.algorithm.searching : countUntil;
9868 import std.exception : enforce;
9869 import std.format : format;
9871 auto tstrings = timeStrings;
9872 immutable indexOfLHS = countUntil(tstrings, lhs);
9873 immutable indexOfRHS = countUntil(tstrings, rhs);
9875 enforce(indexOfLHS != -1, format("%s is not a valid TimeString", lhs));
9876 enforce(indexOfRHS != -1, format("%s is not a valid TimeString", rhs));
9878 if (indexOfLHS < indexOfRHS)
9879 return -1;
9880 if (indexOfLHS > indexOfRHS)
9881 return 1;
9883 return 0;
9887 @safe pure unittest
9889 assert(cmpTimeUnits("hours", "hours") == 0);
9890 assert(cmpTimeUnits("hours", "weeks") < 0);
9891 assert(cmpTimeUnits("months", "seconds") > 0);
9894 @safe unittest
9896 foreach (i, outerUnits; timeStrings)
9898 assert(cmpTimeUnits(outerUnits, outerUnits) == 0);
9900 // For some reason, $ won't compile.
9901 foreach (innerUnits; timeStrings[i + 1 .. timeStrings.length])
9902 assert(cmpTimeUnits(outerUnits, innerUnits) == -1);
9905 foreach (i, outerUnits; timeStrings)
9907 foreach (innerUnits; timeStrings[0 .. i])
9908 assert(cmpTimeUnits(outerUnits, innerUnits) == 1);
9914 Compares two time unit strings at compile time. $(D "years") are the largest
9915 units and $(D "hnsecs") are the smallest.
9917 This template is used instead of $(D cmpTimeUnits) because exceptions
9918 can't be thrown at compile time and $(D cmpTimeUnits) must enforce that
9919 the strings it's given are valid time unit strings. This template uses a
9920 template constraint instead.
9922 Returns:
9923 $(BOOKTABLE,
9924 $(TR $(TD this &lt; rhs) $(TD &lt; 0))
9925 $(TR $(TD this == rhs) $(TD 0))
9926 $(TR $(TD this &gt; rhs) $(TD &gt; 0))
9929 template CmpTimeUnits(string lhs, string rhs)
9930 if (validTimeUnits(lhs, rhs))
9932 enum CmpTimeUnits = cmpTimeUnitsCTFE(lhs, rhs);
9936 // Helper function for CmpTimeUnits.
9937 private int cmpTimeUnitsCTFE(string lhs, string rhs) @safe pure nothrow @nogc
9939 import std.algorithm.searching : countUntil;
9940 auto tstrings = timeStrings;
9941 immutable indexOfLHS = countUntil(tstrings, lhs);
9942 immutable indexOfRHS = countUntil(tstrings, rhs);
9944 if (indexOfLHS < indexOfRHS)
9945 return -1;
9946 if (indexOfLHS > indexOfRHS)
9947 return 1;
9949 return 0;
9952 @safe unittest
9954 import std.format : format;
9955 import std.meta : AliasSeq;
9957 static string genTest(size_t index)
9959 auto currUnits = timeStrings[index];
9960 auto test = format(`assert(CmpTimeUnits!("%s", "%s") == 0);`, currUnits, currUnits);
9962 foreach (units; timeStrings[index + 1 .. $])
9963 test ~= format(`assert(CmpTimeUnits!("%s", "%s") == -1);`, currUnits, units);
9965 foreach (units; timeStrings[0 .. index])
9966 test ~= format(`assert(CmpTimeUnits!("%s", "%s") == 1);`, currUnits, units);
9968 return test;
9971 static assert(timeStrings.length == 10);
9972 foreach (n; AliasSeq!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9))
9973 mixin(genTest(n));
9977 package:
9981 Array of the short (three letter) names of each month.
9983 immutable string[12] _monthNames = ["Jan",
9984 "Feb",
9985 "Mar",
9986 "Apr",
9987 "May",
9988 "Jun",
9989 "Jul",
9990 "Aug",
9991 "Sep",
9992 "Oct",
9993 "Nov",
9994 "Dec"];
9997 The maximum valid Day in the given month in the given year.
9999 Params:
10000 year = The year to get the day for.
10001 month = The month of the Gregorian Calendar to get the day for.
10003 ubyte maxDay(int year, int month) @safe pure nothrow @nogc
10006 assert(valid!"months"(month));
10008 body
10010 switch (month)
10012 case Month.jan, Month.mar, Month.may, Month.jul, Month.aug, Month.oct, Month.dec:
10013 return 31;
10014 case Month.feb:
10015 return yearIsLeapYear(year) ? 29 : 28;
10016 case Month.apr, Month.jun, Month.sep, Month.nov:
10017 return 30;
10018 default:
10019 assert(0, "Invalid month.");
10023 @safe unittest
10025 // Test A.D.
10026 assert(maxDay(1999, 1) == 31);
10027 assert(maxDay(1999, 2) == 28);
10028 assert(maxDay(1999, 3) == 31);
10029 assert(maxDay(1999, 4) == 30);
10030 assert(maxDay(1999, 5) == 31);
10031 assert(maxDay(1999, 6) == 30);
10032 assert(maxDay(1999, 7) == 31);
10033 assert(maxDay(1999, 8) == 31);
10034 assert(maxDay(1999, 9) == 30);
10035 assert(maxDay(1999, 10) == 31);
10036 assert(maxDay(1999, 11) == 30);
10037 assert(maxDay(1999, 12) == 31);
10039 assert(maxDay(2000, 1) == 31);
10040 assert(maxDay(2000, 2) == 29);
10041 assert(maxDay(2000, 3) == 31);
10042 assert(maxDay(2000, 4) == 30);
10043 assert(maxDay(2000, 5) == 31);
10044 assert(maxDay(2000, 6) == 30);
10045 assert(maxDay(2000, 7) == 31);
10046 assert(maxDay(2000, 8) == 31);
10047 assert(maxDay(2000, 9) == 30);
10048 assert(maxDay(2000, 10) == 31);
10049 assert(maxDay(2000, 11) == 30);
10050 assert(maxDay(2000, 12) == 31);
10052 // Test B.C.
10053 assert(maxDay(-1999, 1) == 31);
10054 assert(maxDay(-1999, 2) == 28);
10055 assert(maxDay(-1999, 3) == 31);
10056 assert(maxDay(-1999, 4) == 30);
10057 assert(maxDay(-1999, 5) == 31);
10058 assert(maxDay(-1999, 6) == 30);
10059 assert(maxDay(-1999, 7) == 31);
10060 assert(maxDay(-1999, 8) == 31);
10061 assert(maxDay(-1999, 9) == 30);
10062 assert(maxDay(-1999, 10) == 31);
10063 assert(maxDay(-1999, 11) == 30);
10064 assert(maxDay(-1999, 12) == 31);
10066 assert(maxDay(-2000, 1) == 31);
10067 assert(maxDay(-2000, 2) == 29);
10068 assert(maxDay(-2000, 3) == 31);
10069 assert(maxDay(-2000, 4) == 30);
10070 assert(maxDay(-2000, 5) == 31);
10071 assert(maxDay(-2000, 6) == 30);
10072 assert(maxDay(-2000, 7) == 31);
10073 assert(maxDay(-2000, 8) == 31);
10074 assert(maxDay(-2000, 9) == 30);
10075 assert(maxDay(-2000, 10) == 31);
10076 assert(maxDay(-2000, 11) == 30);
10077 assert(maxDay(-2000, 12) == 31);
10081 Splits out a particular unit from hnsecs and gives the value for that
10082 unit and the remaining hnsecs. It really shouldn't be used unless unless
10083 all units larger than the given units have already been split out.
10085 Params:
10086 units = The units to split out.
10087 hnsecs = The current total hnsecs. Upon returning, it is the hnsecs left
10088 after splitting out the given units.
10090 Returns:
10091 The number of the given units from converting hnsecs to those units.
10093 long splitUnitsFromHNSecs(string units)(ref long hnsecs) @safe pure nothrow @nogc
10094 if (validTimeUnits(units) && CmpTimeUnits!(units, "months") < 0)
10096 import core.time : convert;
10097 immutable value = convert!("hnsecs", units)(hnsecs);
10098 hnsecs -= convert!(units, "hnsecs")(value);
10099 return value;
10102 @safe unittest
10104 auto hnsecs = 2595000000007L;
10105 immutable days = splitUnitsFromHNSecs!"days"(hnsecs);
10106 assert(days == 3);
10107 assert(hnsecs == 3000000007);
10109 immutable minutes = splitUnitsFromHNSecs!"minutes"(hnsecs);
10110 assert(minutes == 5);
10111 assert(hnsecs == 7);
10116 Returns the day of the week for the given day of the Gregorian Calendar.
10118 Params:
10119 day = The day of the Gregorian Calendar for which to get the day of
10120 the week.
10122 DayOfWeek getDayOfWeek(int day) @safe pure nothrow @nogc
10124 // January 1st, 1 A.D. was a Monday
10125 if (day >= 0)
10126 return cast(DayOfWeek)(day % 7);
10127 else
10129 immutable dow = cast(DayOfWeek)((day % 7) + 7);
10131 if (dow == 7)
10132 return DayOfWeek.sun;
10133 else
10134 return dow;
10138 @safe unittest
10140 import std.datetime.systime : SysTime;
10142 // Test A.D.
10143 assert(getDayOfWeek(SysTime(Date(1, 1, 1)).dayOfGregorianCal) == DayOfWeek.mon);
10144 assert(getDayOfWeek(SysTime(Date(1, 1, 2)).dayOfGregorianCal) == DayOfWeek.tue);
10145 assert(getDayOfWeek(SysTime(Date(1, 1, 3)).dayOfGregorianCal) == DayOfWeek.wed);
10146 assert(getDayOfWeek(SysTime(Date(1, 1, 4)).dayOfGregorianCal) == DayOfWeek.thu);
10147 assert(getDayOfWeek(SysTime(Date(1, 1, 5)).dayOfGregorianCal) == DayOfWeek.fri);
10148 assert(getDayOfWeek(SysTime(Date(1, 1, 6)).dayOfGregorianCal) == DayOfWeek.sat);
10149 assert(getDayOfWeek(SysTime(Date(1, 1, 7)).dayOfGregorianCal) == DayOfWeek.sun);
10150 assert(getDayOfWeek(SysTime(Date(1, 1, 8)).dayOfGregorianCal) == DayOfWeek.mon);
10151 assert(getDayOfWeek(SysTime(Date(1, 1, 9)).dayOfGregorianCal) == DayOfWeek.tue);
10152 assert(getDayOfWeek(SysTime(Date(2, 1, 1)).dayOfGregorianCal) == DayOfWeek.tue);
10153 assert(getDayOfWeek(SysTime(Date(3, 1, 1)).dayOfGregorianCal) == DayOfWeek.wed);
10154 assert(getDayOfWeek(SysTime(Date(4, 1, 1)).dayOfGregorianCal) == DayOfWeek.thu);
10155 assert(getDayOfWeek(SysTime(Date(5, 1, 1)).dayOfGregorianCal) == DayOfWeek.sat);
10156 assert(getDayOfWeek(SysTime(Date(2000, 1, 1)).dayOfGregorianCal) == DayOfWeek.sat);
10157 assert(getDayOfWeek(SysTime(Date(2010, 8, 22)).dayOfGregorianCal) == DayOfWeek.sun);
10158 assert(getDayOfWeek(SysTime(Date(2010, 8, 23)).dayOfGregorianCal) == DayOfWeek.mon);
10159 assert(getDayOfWeek(SysTime(Date(2010, 8, 24)).dayOfGregorianCal) == DayOfWeek.tue);
10160 assert(getDayOfWeek(SysTime(Date(2010, 8, 25)).dayOfGregorianCal) == DayOfWeek.wed);
10161 assert(getDayOfWeek(SysTime(Date(2010, 8, 26)).dayOfGregorianCal) == DayOfWeek.thu);
10162 assert(getDayOfWeek(SysTime(Date(2010, 8, 27)).dayOfGregorianCal) == DayOfWeek.fri);
10163 assert(getDayOfWeek(SysTime(Date(2010, 8, 28)).dayOfGregorianCal) == DayOfWeek.sat);
10164 assert(getDayOfWeek(SysTime(Date(2010, 8, 29)).dayOfGregorianCal) == DayOfWeek.sun);
10166 // Test B.C.
10167 assert(getDayOfWeek(SysTime(Date(0, 12, 31)).dayOfGregorianCal) == DayOfWeek.sun);
10168 assert(getDayOfWeek(SysTime(Date(0, 12, 30)).dayOfGregorianCal) == DayOfWeek.sat);
10169 assert(getDayOfWeek(SysTime(Date(0, 12, 29)).dayOfGregorianCal) == DayOfWeek.fri);
10170 assert(getDayOfWeek(SysTime(Date(0, 12, 28)).dayOfGregorianCal) == DayOfWeek.thu);
10171 assert(getDayOfWeek(SysTime(Date(0, 12, 27)).dayOfGregorianCal) == DayOfWeek.wed);
10172 assert(getDayOfWeek(SysTime(Date(0, 12, 26)).dayOfGregorianCal) == DayOfWeek.tue);
10173 assert(getDayOfWeek(SysTime(Date(0, 12, 25)).dayOfGregorianCal) == DayOfWeek.mon);
10174 assert(getDayOfWeek(SysTime(Date(0, 12, 24)).dayOfGregorianCal) == DayOfWeek.sun);
10175 assert(getDayOfWeek(SysTime(Date(0, 12, 23)).dayOfGregorianCal) == DayOfWeek.sat);
10179 private:
10181 enum daysInYear = 365; // The number of days in a non-leap year.
10182 enum daysInLeapYear = 366; // The numbef or days in a leap year.
10183 enum daysIn4Years = daysInYear * 3 + daysInLeapYear; // Number of days in 4 years.
10184 enum daysIn100Years = daysIn4Years * 25 - 1; // The number of days in 100 years.
10185 enum daysIn400Years = daysIn100Years * 4 + 1; // The number of days in 400 years.
10188 Array of integers representing the last days of each month in a year.
10190 immutable int[13] lastDayNonLeap = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];
10193 Array of integers representing the last days of each month in a leap year.
10195 immutable int[13] lastDayLeap = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366];
10199 Returns the string representation of the given month.
10201 string monthToString(Month month) @safe pure
10203 import std.format : format;
10204 assert(month >= Month.jan && month <= Month.dec, format("Invalid month: %s", month));
10205 return _monthNames[month - Month.jan];
10208 @safe unittest
10210 assert(monthToString(Month.jan) == "Jan");
10211 assert(monthToString(Month.feb) == "Feb");
10212 assert(monthToString(Month.mar) == "Mar");
10213 assert(monthToString(Month.apr) == "Apr");
10214 assert(monthToString(Month.may) == "May");
10215 assert(monthToString(Month.jun) == "Jun");
10216 assert(monthToString(Month.jul) == "Jul");
10217 assert(monthToString(Month.aug) == "Aug");
10218 assert(monthToString(Month.sep) == "Sep");
10219 assert(monthToString(Month.oct) == "Oct");
10220 assert(monthToString(Month.nov) == "Nov");
10221 assert(monthToString(Month.dec) == "Dec");
10226 Returns the Month corresponding to the given string.
10228 Params:
10229 monthStr = The string representation of the month to get the Month for.
10231 Throws:
10232 $(REF DateTimeException,std,datetime,date) if the given month is not a
10233 valid month string.
10235 Month monthFromString(string monthStr) @safe pure
10237 import std.format : format;
10238 switch (monthStr)
10240 case "Jan":
10241 return Month.jan;
10242 case "Feb":
10243 return Month.feb;
10244 case "Mar":
10245 return Month.mar;
10246 case "Apr":
10247 return Month.apr;
10248 case "May":
10249 return Month.may;
10250 case "Jun":
10251 return Month.jun;
10252 case "Jul":
10253 return Month.jul;
10254 case "Aug":
10255 return Month.aug;
10256 case "Sep":
10257 return Month.sep;
10258 case "Oct":
10259 return Month.oct;
10260 case "Nov":
10261 return Month.nov;
10262 case "Dec":
10263 return Month.dec;
10264 default:
10265 throw new DateTimeException(format("Invalid month %s", monthStr));
10269 @safe unittest
10271 import std.stdio : writeln;
10272 import std.traits : EnumMembers;
10273 foreach (badStr; ["Ja", "Janu", "Januar", "Januarys", "JJanuary", "JANUARY",
10274 "JAN", "january", "jaNuary", "jaN", "jaNuaRy", "jAn"])
10276 scope(failure) writeln(badStr);
10277 assertThrown!DateTimeException(monthFromString(badStr));
10280 foreach (month; EnumMembers!Month)
10282 scope(failure) writeln(month);
10283 assert(monthFromString(monthToString(month)) == month);
10288 version (unittest)
10290 // All of these helper arrays are sorted in ascending order.
10291 auto testYearsBC = [-1999, -1200, -600, -4, -1, 0];
10292 auto testYearsAD = [1, 4, 1000, 1999, 2000, 2012];
10294 // I'd use a Tuple, but I get forward reference errors if I try.
10295 struct MonthDay
10297 Month month;
10298 short day;
10300 this(int m, short d)
10302 month = cast(Month) m;
10303 day = d;
10307 MonthDay[] testMonthDays = [MonthDay(1, 1),
10308 MonthDay(1, 2),
10309 MonthDay(3, 17),
10310 MonthDay(7, 4),
10311 MonthDay(10, 27),
10312 MonthDay(12, 30),
10313 MonthDay(12, 31)];
10315 auto testDays = [1, 2, 9, 10, 16, 20, 25, 28, 29, 30, 31];
10317 auto testTODs = [TimeOfDay(0, 0, 0),
10318 TimeOfDay(0, 0, 1),
10319 TimeOfDay(0, 1, 0),
10320 TimeOfDay(1, 0, 0),
10321 TimeOfDay(13, 13, 13),
10322 TimeOfDay(23, 59, 59)];
10324 auto testHours = [0, 1, 12, 22, 23];
10325 auto testMinSecs = [0, 1, 30, 58, 59];
10327 // Throwing exceptions is incredibly expensive, so we want to use a smaller
10328 // set of values for tests using assertThrown.
10329 auto testTODsThrown = [TimeOfDay(0, 0, 0),
10330 TimeOfDay(13, 13, 13),
10331 TimeOfDay(23, 59, 59)];
10333 Date[] testDatesBC;
10334 Date[] testDatesAD;
10336 DateTime[] testDateTimesBC;
10337 DateTime[] testDateTimesAD;
10339 // I'd use a Tuple, but I get forward reference errors if I try.
10340 struct GregDay { int day; Date date; }
10341 auto testGregDaysBC = [GregDay(-1_373_427, Date(-3760, 9, 7)), // Start of the Hebrew Calendar
10342 GregDay(-735_233, Date(-2012, 1, 1)),
10343 GregDay(-735_202, Date(-2012, 2, 1)),
10344 GregDay(-735_175, Date(-2012, 2, 28)),
10345 GregDay(-735_174, Date(-2012, 2, 29)),
10346 GregDay(-735_173, Date(-2012, 3, 1)),
10347 GregDay(-734_502, Date(-2010, 1, 1)),
10348 GregDay(-734_472, Date(-2010, 1, 31)),
10349 GregDay(-734_471, Date(-2010, 2, 1)),
10350 GregDay(-734_444, Date(-2010, 2, 28)),
10351 GregDay(-734_443, Date(-2010, 3, 1)),
10352 GregDay(-734_413, Date(-2010, 3, 31)),
10353 GregDay(-734_412, Date(-2010, 4, 1)),
10354 GregDay(-734_383, Date(-2010, 4, 30)),
10355 GregDay(-734_382, Date(-2010, 5, 1)),
10356 GregDay(-734_352, Date(-2010, 5, 31)),
10357 GregDay(-734_351, Date(-2010, 6, 1)),
10358 GregDay(-734_322, Date(-2010, 6, 30)),
10359 GregDay(-734_321, Date(-2010, 7, 1)),
10360 GregDay(-734_291, Date(-2010, 7, 31)),
10361 GregDay(-734_290, Date(-2010, 8, 1)),
10362 GregDay(-734_260, Date(-2010, 8, 31)),
10363 GregDay(-734_259, Date(-2010, 9, 1)),
10364 GregDay(-734_230, Date(-2010, 9, 30)),
10365 GregDay(-734_229, Date(-2010, 10, 1)),
10366 GregDay(-734_199, Date(-2010, 10, 31)),
10367 GregDay(-734_198, Date(-2010, 11, 1)),
10368 GregDay(-734_169, Date(-2010, 11, 30)),
10369 GregDay(-734_168, Date(-2010, 12, 1)),
10370 GregDay(-734_139, Date(-2010, 12, 30)),
10371 GregDay(-734_138, Date(-2010, 12, 31)),
10372 GregDay(-731_215, Date(-2001, 1, 1)),
10373 GregDay(-730_850, Date(-2000, 1, 1)),
10374 GregDay(-730_849, Date(-2000, 1, 2)),
10375 GregDay(-730_486, Date(-2000, 12, 30)),
10376 GregDay(-730_485, Date(-2000, 12, 31)),
10377 GregDay(-730_484, Date(-1999, 1, 1)),
10378 GregDay(-694_690, Date(-1901, 1, 1)),
10379 GregDay(-694_325, Date(-1900, 1, 1)),
10380 GregDay(-585_118, Date(-1601, 1, 1)),
10381 GregDay(-584_753, Date(-1600, 1, 1)),
10382 GregDay(-584_388, Date(-1600, 12, 31)),
10383 GregDay(-584_387, Date(-1599, 1, 1)),
10384 GregDay(-365_972, Date(-1001, 1, 1)),
10385 GregDay(-365_607, Date(-1000, 1, 1)),
10386 GregDay(-183_351, Date(-501, 1, 1)),
10387 GregDay(-182_986, Date(-500, 1, 1)),
10388 GregDay(-182_621, Date(-499, 1, 1)),
10389 GregDay(-146_827, Date(-401, 1, 1)),
10390 GregDay(-146_462, Date(-400, 1, 1)),
10391 GregDay(-146_097, Date(-400, 12, 31)),
10392 GregDay(-110_302, Date(-301, 1, 1)),
10393 GregDay(-109_937, Date(-300, 1, 1)),
10394 GregDay(-73_778, Date(-201, 1, 1)),
10395 GregDay(-73_413, Date(-200, 1, 1)),
10396 GregDay(-38_715, Date(-105, 1, 1)),
10397 GregDay(-37_254, Date(-101, 1, 1)),
10398 GregDay(-36_889, Date(-100, 1, 1)),
10399 GregDay(-36_524, Date(-99, 1, 1)),
10400 GregDay(-36_160, Date(-99, 12, 31)),
10401 GregDay(-35_794, Date(-97, 1, 1)),
10402 GregDay(-18_627, Date(-50, 1, 1)),
10403 GregDay(-18_262, Date(-49, 1, 1)),
10404 GregDay(-3652, Date(-9, 1, 1)),
10405 GregDay(-2191, Date(-5, 1, 1)),
10406 GregDay(-1827, Date(-5, 12, 31)),
10407 GregDay(-1826, Date(-4, 1, 1)),
10408 GregDay(-1825, Date(-4, 1, 2)),
10409 GregDay(-1462, Date(-4, 12, 30)),
10410 GregDay(-1461, Date(-4, 12, 31)),
10411 GregDay(-1460, Date(-3, 1, 1)),
10412 GregDay(-1096, Date(-3, 12, 31)),
10413 GregDay(-1095, Date(-2, 1, 1)),
10414 GregDay(-731, Date(-2, 12, 31)),
10415 GregDay(-730, Date(-1, 1, 1)),
10416 GregDay(-367, Date(-1, 12, 30)),
10417 GregDay(-366, Date(-1, 12, 31)),
10418 GregDay(-365, Date(0, 1, 1)),
10419 GregDay(-31, Date(0, 11, 30)),
10420 GregDay(-30, Date(0, 12, 1)),
10421 GregDay(-1, Date(0, 12, 30)),
10422 GregDay(0, Date(0, 12, 31))];
10424 auto testGregDaysAD = [GregDay(1, Date(1, 1, 1)),
10425 GregDay(2, Date(1, 1, 2)),
10426 GregDay(32, Date(1, 2, 1)),
10427 GregDay(365, Date(1, 12, 31)),
10428 GregDay(366, Date(2, 1, 1)),
10429 GregDay(731, Date(3, 1, 1)),
10430 GregDay(1096, Date(4, 1, 1)),
10431 GregDay(1097, Date(4, 1, 2)),
10432 GregDay(1460, Date(4, 12, 30)),
10433 GregDay(1461, Date(4, 12, 31)),
10434 GregDay(1462, Date(5, 1, 1)),
10435 GregDay(17_898, Date(50, 1, 1)),
10436 GregDay(35_065, Date(97, 1, 1)),
10437 GregDay(36_160, Date(100, 1, 1)),
10438 GregDay(36_525, Date(101, 1, 1)),
10439 GregDay(37_986, Date(105, 1, 1)),
10440 GregDay(72_684, Date(200, 1, 1)),
10441 GregDay(73_049, Date(201, 1, 1)),
10442 GregDay(109_208, Date(300, 1, 1)),
10443 GregDay(109_573, Date(301, 1, 1)),
10444 GregDay(145_732, Date(400, 1, 1)),
10445 GregDay(146_098, Date(401, 1, 1)),
10446 GregDay(182_257, Date(500, 1, 1)),
10447 GregDay(182_622, Date(501, 1, 1)),
10448 GregDay(364_878, Date(1000, 1, 1)),
10449 GregDay(365_243, Date(1001, 1, 1)),
10450 GregDay(584_023, Date(1600, 1, 1)),
10451 GregDay(584_389, Date(1601, 1, 1)),
10452 GregDay(693_596, Date(1900, 1, 1)),
10453 GregDay(693_961, Date(1901, 1, 1)),
10454 GregDay(729_755, Date(1999, 1, 1)),
10455 GregDay(730_120, Date(2000, 1, 1)),
10456 GregDay(730_121, Date(2000, 1, 2)),
10457 GregDay(730_484, Date(2000, 12, 30)),
10458 GregDay(730_485, Date(2000, 12, 31)),
10459 GregDay(730_486, Date(2001, 1, 1)),
10460 GregDay(733_773, Date(2010, 1, 1)),
10461 GregDay(733_774, Date(2010, 1, 2)),
10462 GregDay(733_803, Date(2010, 1, 31)),
10463 GregDay(733_804, Date(2010, 2, 1)),
10464 GregDay(733_831, Date(2010, 2, 28)),
10465 GregDay(733_832, Date(2010, 3, 1)),
10466 GregDay(733_862, Date(2010, 3, 31)),
10467 GregDay(733_863, Date(2010, 4, 1)),
10468 GregDay(733_892, Date(2010, 4, 30)),
10469 GregDay(733_893, Date(2010, 5, 1)),
10470 GregDay(733_923, Date(2010, 5, 31)),
10471 GregDay(733_924, Date(2010, 6, 1)),
10472 GregDay(733_953, Date(2010, 6, 30)),
10473 GregDay(733_954, Date(2010, 7, 1)),
10474 GregDay(733_984, Date(2010, 7, 31)),
10475 GregDay(733_985, Date(2010, 8, 1)),
10476 GregDay(734_015, Date(2010, 8, 31)),
10477 GregDay(734_016, Date(2010, 9, 1)),
10478 GregDay(734_045, Date(2010, 9, 30)),
10479 GregDay(734_046, Date(2010, 10, 1)),
10480 GregDay(734_076, Date(2010, 10, 31)),
10481 GregDay(734_077, Date(2010, 11, 1)),
10482 GregDay(734_106, Date(2010, 11, 30)),
10483 GregDay(734_107, Date(2010, 12, 1)),
10484 GregDay(734_136, Date(2010, 12, 30)),
10485 GregDay(734_137, Date(2010, 12, 31)),
10486 GregDay(734_503, Date(2012, 1, 1)),
10487 GregDay(734_534, Date(2012, 2, 1)),
10488 GregDay(734_561, Date(2012, 2, 28)),
10489 GregDay(734_562, Date(2012, 2, 29)),
10490 GregDay(734_563, Date(2012, 3, 1)),
10491 GregDay(734_858, Date(2012, 12, 21))];
10493 // I'd use a Tuple, but I get forward reference errors if I try.
10494 struct DayOfYear { int day; MonthDay md; }
10495 auto testDaysOfYear = [DayOfYear(1, MonthDay(1, 1)),
10496 DayOfYear(2, MonthDay(1, 2)),
10497 DayOfYear(3, MonthDay(1, 3)),
10498 DayOfYear(31, MonthDay(1, 31)),
10499 DayOfYear(32, MonthDay(2, 1)),
10500 DayOfYear(59, MonthDay(2, 28)),
10501 DayOfYear(60, MonthDay(3, 1)),
10502 DayOfYear(90, MonthDay(3, 31)),
10503 DayOfYear(91, MonthDay(4, 1)),
10504 DayOfYear(120, MonthDay(4, 30)),
10505 DayOfYear(121, MonthDay(5, 1)),
10506 DayOfYear(151, MonthDay(5, 31)),
10507 DayOfYear(152, MonthDay(6, 1)),
10508 DayOfYear(181, MonthDay(6, 30)),
10509 DayOfYear(182, MonthDay(7, 1)),
10510 DayOfYear(212, MonthDay(7, 31)),
10511 DayOfYear(213, MonthDay(8, 1)),
10512 DayOfYear(243, MonthDay(8, 31)),
10513 DayOfYear(244, MonthDay(9, 1)),
10514 DayOfYear(273, MonthDay(9, 30)),
10515 DayOfYear(274, MonthDay(10, 1)),
10516 DayOfYear(304, MonthDay(10, 31)),
10517 DayOfYear(305, MonthDay(11, 1)),
10518 DayOfYear(334, MonthDay(11, 30)),
10519 DayOfYear(335, MonthDay(12, 1)),
10520 DayOfYear(363, MonthDay(12, 29)),
10521 DayOfYear(364, MonthDay(12, 30)),
10522 DayOfYear(365, MonthDay(12, 31))];
10524 auto testDaysOfLeapYear = [DayOfYear(1, MonthDay(1, 1)),
10525 DayOfYear(2, MonthDay(1, 2)),
10526 DayOfYear(3, MonthDay(1, 3)),
10527 DayOfYear(31, MonthDay(1, 31)),
10528 DayOfYear(32, MonthDay(2, 1)),
10529 DayOfYear(59, MonthDay(2, 28)),
10530 DayOfYear(60, MonthDay(2, 29)),
10531 DayOfYear(61, MonthDay(3, 1)),
10532 DayOfYear(91, MonthDay(3, 31)),
10533 DayOfYear(92, MonthDay(4, 1)),
10534 DayOfYear(121, MonthDay(4, 30)),
10535 DayOfYear(122, MonthDay(5, 1)),
10536 DayOfYear(152, MonthDay(5, 31)),
10537 DayOfYear(153, MonthDay(6, 1)),
10538 DayOfYear(182, MonthDay(6, 30)),
10539 DayOfYear(183, MonthDay(7, 1)),
10540 DayOfYear(213, MonthDay(7, 31)),
10541 DayOfYear(214, MonthDay(8, 1)),
10542 DayOfYear(244, MonthDay(8, 31)),
10543 DayOfYear(245, MonthDay(9, 1)),
10544 DayOfYear(274, MonthDay(9, 30)),
10545 DayOfYear(275, MonthDay(10, 1)),
10546 DayOfYear(305, MonthDay(10, 31)),
10547 DayOfYear(306, MonthDay(11, 1)),
10548 DayOfYear(335, MonthDay(11, 30)),
10549 DayOfYear(336, MonthDay(12, 1)),
10550 DayOfYear(364, MonthDay(12, 29)),
10551 DayOfYear(365, MonthDay(12, 30)),
10552 DayOfYear(366, MonthDay(12, 31))];
10554 void initializeTests() @safe
10556 foreach (year; testYearsBC)
10558 foreach (md; testMonthDays)
10559 testDatesBC ~= Date(year, md.month, md.day);
10562 foreach (year; testYearsAD)
10564 foreach (md; testMonthDays)
10565 testDatesAD ~= Date(year, md.month, md.day);
10568 foreach (dt; testDatesBC)
10570 foreach (tod; testTODs)
10571 testDateTimesBC ~= DateTime(dt, tod);
10574 foreach (dt; testDatesAD)
10576 foreach (tod; testTODs)
10577 testDateTimesAD ~= DateTime(dt, tod);