1 // Written in the D programming language 2 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/_systime.d) 7 +/ 8 module std.datetime.systime; 9 10 import core.time; 11 import std.datetime.date; 12 import std.datetime.timezone; 13 import std.exception : enforce; 14 import std.format : format; 15 import std.range.primitives; 16 import std.traits : isIntegral, isSigned, isSomeString, Unqual; 17 18 version (Windows) 19 { 20 import core.stdc.time : time_t; 21 import core.sys.windows.windows; 22 import core.sys.windows.winsock2; 23 } 24 else version (Posix) 25 { 26 import core.sys.posix.signal : timespec; 27 import core.sys.posix.sys.types : time_t; 28 } 29 30 version (unittest) 31 { 32 import core.exception : AssertError; 33 import std.exception : assertThrown; 34 } 35 36 37 @safe unittest 38 { 39 initializeTests(); 40 } 41 42 43 /++ 44 Effectively a namespace to make it clear that the methods it contains are 45 getting the time from the system clock. It cannot be instantiated. 46 +/ 47 final class Clock 48 { 49 public: 50 51 /++ 52 Returns the current time in the given time zone. 53 54 Params: 55 clockType = The $(REF ClockType, core,time) indicates which system 56 clock to use to get the current time. Very few programs 57 need to use anything other than the default. 58 tz = The time zone for the SysTime that's returned. 59 60 Throws: 61 $(REF DateTimeException,std,datetime,date) if it fails to get the 62 time. 63 +/ 64 static SysTime currTime(ClockType clockType = ClockType.normal)(immutable TimeZone tz = LocalTime()) @safe 65 { 66 return SysTime(currStdTime!clockType, tz); 67 } 68 69 @safe unittest 70 { 71 import std.format : format; 72 import std.stdio : writefln; 73 assert(currTime().timezone is LocalTime()); 74 assert(currTime(UTC()).timezone is UTC()); 75 76 // core.stdc.time.time does not always use unix time on Windows systems. 77 // In particular, dmc does not use unix time. If we can guarantee that 78 // the MS runtime uses unix time, then we may be able run this test 79 // then, but for now, we're just not going to run this test on Windows. 80 version (Posix) 81 { 82 static import core.stdc.time; 83 static import std.math; 84 immutable unixTimeD = currTime().toUnixTime(); 85 immutable unixTimeC = core.stdc.time.time(null); 86 assert(std.math.abs(unixTimeC - unixTimeD) <= 2); 87 } 88 89 auto norm1 = Clock.currTime; 90 auto norm2 = Clock.currTime(UTC()); 91 assert(norm1 <= norm2, format("%s %s", norm1, norm2)); 92 assert(abs(norm1 - norm2) <= seconds(2)); 93 94 import std.meta : AliasSeq; 95 foreach (ct; AliasSeq!(ClockType.coarse, ClockType.precise, ClockType.second)) 96 { 97 scope(failure) writefln("ClockType.%s", ct); 98 auto value1 = Clock.currTime!ct; 99 auto value2 = Clock.currTime!ct(UTC()); 100 assert(value1 <= value2, format("%s %s", value1, value2)); 101 assert(abs(value1 - value2) <= seconds(2)); 102 } 103 } 104 105 106 /++ 107 Returns the number of hnsecs since midnight, January 1st, 1 A.D. for the 108 current time. 109 110 Params: 111 clockType = The $(REF ClockType, core,time) indicates which system 112 clock to use to get the current time. Very few programs 113 need to use anything other than the default. 114 115 Throws: 116 $(REF DateTimeException,std,datetime,date) if it fails to get the 117 time. 118 +/ 119 static @property long currStdTime(ClockType clockType = ClockType.normal)() @trusted 120 { 121 static if (clockType != ClockType.coarse && 122 clockType != ClockType.normal && 123 clockType != ClockType.precise && 124 clockType != ClockType.second) 125 { 126 static assert(0, format("ClockType.%s is not supported by Clock.currTime or Clock.currStdTime", clockType)); 127 } 128 129 version (Windows) 130 { 131 FILETIME fileTime; 132 GetSystemTimeAsFileTime(&fileTime); 133 immutable result = FILETIMEToStdTime(&fileTime); 134 static if (clockType == ClockType.second) 135 { 136 // Ideally, this would use core.std.time.time, but the C runtime 137 // has to be using unix time for that to work, and that's not 138 // guaranteed on Windows. Digital Mars does not use unix time. 139 // MS may or may not. If it does, then this can be made to use 140 // core.stdc.time for MS, but for now, we'll leave it like this. 141 return convert!("seconds", "hnsecs")(convert!("hnsecs", "seconds")(result)); 142 } 143 else 144 return result; 145 } 146 else version (Posix) 147 { 148 static import core.stdc.time; 149 enum hnsecsToUnixEpoch = unixTimeToStdTime(0); 150 151 version (OSX) 152 { 153 static if (clockType == ClockType.second) 154 return unixTimeToStdTime(core.stdc.time.time(null)); 155 else 156 { 157 import core.sys.posix.sys.time : gettimeofday, timeval; 158 timeval tv; 159 if (gettimeofday(&tv, null) != 0) 160 throw new TimeException("Call to gettimeofday() failed"); 161 return convert!("seconds", "hnsecs")(tv.tv_sec) + 162 convert!("usecs", "hnsecs")(tv.tv_usec) + 163 hnsecsToUnixEpoch; 164 } 165 } 166 else version (linux) 167 { 168 static if (clockType == ClockType.second) 169 return unixTimeToStdTime(core.stdc.time.time(null)); 170 else 171 { 172 import core.sys.linux.time : CLOCK_REALTIME_COARSE; 173 import core.sys.posix.time : clock_gettime, CLOCK_REALTIME; 174 static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME_COARSE; 175 else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME; 176 else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME; 177 else static assert(0, "Previous static if is wrong."); 178 timespec ts; 179 if (clock_gettime(clockArg, &ts) != 0) 180 throw new TimeException("Call to clock_gettime() failed"); 181 return convert!("seconds", "hnsecs")(ts.tv_sec) + 182 ts.tv_nsec / 100 + 183 hnsecsToUnixEpoch; 184 } 185 } 186 else version (FreeBSD) 187 { 188 import core.sys.freebsd.time : clock_gettime, CLOCK_REALTIME, 189 CLOCK_REALTIME_FAST, CLOCK_REALTIME_PRECISE, CLOCK_SECOND; 190 static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME_FAST; 191 else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME; 192 else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME_PRECISE; 193 else static if (clockType == ClockType.second) alias clockArg = CLOCK_SECOND; 194 else static assert(0, "Previous static if is wrong."); 195 timespec ts; 196 if (clock_gettime(clockArg, &ts) != 0) 197 throw new TimeException("Call to clock_gettime() failed"); 198 return convert!("seconds", "hnsecs")(ts.tv_sec) + 199 ts.tv_nsec / 100 + 200 hnsecsToUnixEpoch; 201 } 202 else version (NetBSD) 203 { 204 static if (clockType == ClockType.second) 205 return unixTimeToStdTime(core.stdc.time.time(null)); 206 else 207 { 208 import core.sys.posix.sys.time : gettimeofday, timeval; 209 timeval tv; 210 if (gettimeofday(&tv, null) != 0) 211 throw new TimeException("Call to gettimeofday() failed"); 212 return convert!("seconds", "hnsecs")(tv.tv_sec) + 213 convert!("usecs", "hnsecs")(tv.tv_usec) + 214 hnsecsToUnixEpoch; 215 } 216 } 217 else version (DragonFlyBSD) 218 { 219 import core.sys.dragonflybsd.time : clock_gettime, CLOCK_REALTIME, 220 CLOCK_REALTIME_FAST, CLOCK_REALTIME_PRECISE, CLOCK_SECOND; 221 static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME_FAST; 222 else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME; 223 else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME_PRECISE; 224 else static if (clockType == ClockType.second) alias clockArg = CLOCK_SECOND; 225 else static assert(0, "Previous static if is wrong."); 226 timespec ts; 227 if (clock_gettime(clockArg, &ts) != 0) 228 throw new TimeException("Call to clock_gettime() failed"); 229 return convert!("seconds", "hnsecs")(ts.tv_sec) + 230 ts.tv_nsec / 100 + 231 hnsecsToUnixEpoch; 232 } 233 else version (Solaris) 234 { 235 static if (clockType == ClockType.second) 236 return unixTimeToStdTime(core.stdc.time.time(null)); 237 else 238 { 239 import core.sys.solaris.time : clock_gettime, CLOCK_REALTIME; 240 static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME; 241 else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME; 242 else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME; 243 else static assert(0, "Previous static if is wrong."); 244 timespec ts; 245 if (clock_gettime(clockArg, &ts) != 0) 246 throw new TimeException("Call to clock_gettime() failed"); 247 return convert!("seconds", "hnsecs")(ts.tv_sec) + 248 ts.tv_nsec / 100 + 249 hnsecsToUnixEpoch; 250 } 251 } 252 else static assert(0, "Unsupported OS"); 253 } 254 else static assert(0, "Unsupported OS"); 255 } 256 257 @safe unittest 258 { 259 import std.format : format; 260 import std.math : abs; 261 import std.meta : AliasSeq; 262 import std.stdio : writefln; 263 enum limit = convert!("seconds", "hnsecs")(2); 264 265 auto norm1 = Clock.currStdTime; 266 auto norm2 = Clock.currStdTime; 267 assert(norm1 <= norm2, format("%s %s", norm1, norm2)); 268 assert(abs(norm1 - norm2) <= limit); 269 270 foreach (ct; AliasSeq!(ClockType.coarse, ClockType.precise, ClockType.second)) 271 { 272 scope(failure) writefln("ClockType.%s", ct); 273 auto value1 = Clock.currStdTime!ct; 274 auto value2 = Clock.currStdTime!ct; 275 assert(value1 <= value2, format("%s %s", value1, value2)); 276 assert(abs(value1 - value2) <= limit); 277 } 278 } 279 280 281 private: 282 283 @disable this() {} 284 } 285 286 287 /++ 288 $(D SysTime) is the type used to get the current time from the 289 system or doing anything that involves time zones. Unlike 290 $(REF DateTime,std,datetime,date), the time zone is an integral part of 291 $(D SysTime) (though for local time applications, time zones can be ignored 292 and it will work, since it defaults to using the local time zone). It holds 293 its internal time in std time (hnsecs since midnight, January 1st, 1 A.D. 294 UTC), so it interfaces well with the system time. However, that means that, 295 unlike $(REF DateTime,std,datetime,date), it is not optimized for 296 calendar-based operations, and getting individual units from it such as 297 years or days is going to involve conversions and be less efficient. 298 299 For calendar-based operations that don't 300 care about time zones, then $(REF DateTime,std,datetime,date) would be 301 the type to use. For system time, use $(D SysTime). 302 303 $(LREF Clock.currTime) will return the current time as a $(D SysTime). 304 To convert a $(D SysTime) to a $(REF Date,std,datetime,date) or 305 $(REF DateTime,std,datetime,date), simply cast it. To convert a 306 $(REF Date,std,datetime,date) or $(REF DateTime,std,datetime,date) to a 307 $(D SysTime), use $(D SysTime)'s constructor, and pass in the ntended time 308 zone with it (or don't pass in a $(REF TimeZone,std,datetime,timezone), and 309 the local time zone will be used). Be aware, however, that converting from a 310 $(REF DateTime,std,datetime,date) to a $(D SysTime) will not necessarily 311 be 100% accurate due to DST (one hour of the year doesn't exist and another 312 occurs twice). To not risk any conversion errors, keep times as 313 $(D SysTime)s. Aside from DST though, there shouldn't be any conversion 314 problems. 315 316 For using time zones other than local time or UTC, use 317 $(REF PosixTimeZone,std,datetime,timezone) on Posix systems (or on Windows, 318 if providing the TZ Database files), and use 319 $(REF WindowsTimeZone,std,datetime,timezone) on Windows systems. The time in 320 $(D SysTime) is kept internally in hnsecs from midnight, January 1st, 1 A.D. 321 UTC. Conversion error cannot happen when changing the time zone of a 322 $(D SysTime). $(REF LocalTime,std,datetime,timezone) is the 323 $(REF TimeZone,std,datetime,timezone) class which represents the local time, 324 and $(D UTC) is the $(REF TimeZone,std,datetime,timezone) class which 325 represents UTC. $(D SysTime) uses $(REF LocalTime,std,datetime,timezone) if 326 no $(REF TimeZone,std,datetime,timezone) is provided. For more details on 327 time zones, see the documentation for $(REF TimeZone,std,datetime,timezone), 328 $(REF PosixTimeZone,std,datetime,timezone), and 329 $(REF WindowsTimeZone,std,datetime,timezone). 330 331 $(D SysTime)'s range is from approximately 29,000 B.C. to approximately 332 29,000 A.D. 333 +/ 334 struct SysTime 335 { 336 import core.stdc.time : tm; 337 version (Posix) import core.sys.posix.sys.time : timeval; 338 import std.typecons : Rebindable; 339 340 public: 341 342 /++ 343 Params: 344 dateTime = The $(REF DateTime,std,datetime,date) to use to set 345 this $(LREF SysTime)'s internal std time. As 346 $(REF DateTime,std,datetime,date) has no concept of 347 time zone, tz is used as its time zone. 348 tz = The $(REF TimeZone,std,datetime,timezone) to use for this 349 $(LREF SysTime). If null, 350 $(REF LocalTime,std,datetime,timezone) will be used. The 351 given $(REF DateTime,std,datetime,date) is assumed to 352 be in the given time zone. 353 +/ 354 this(in DateTime dateTime, immutable TimeZone tz = null) @safe nothrow 355 { 356 try 357 this(dateTime, Duration.zero, tz); 358 catch (Exception e) 359 assert(0, "SysTime's constructor threw when it shouldn't have."); 360 } 361 362 @safe unittest 363 { 364 static void test(DateTime dt, immutable TimeZone tz, long expected) 365 { 366 auto sysTime = SysTime(dt, tz); 367 assert(sysTime._stdTime == expected); 368 assert(sysTime._timezone is (tz is null ? LocalTime() : tz), format("Given DateTime: %s", dt)); 369 } 370 371 test(DateTime.init, UTC(), 0); 372 test(DateTime(1, 1, 1, 12, 30, 33), UTC(), 450_330_000_000L); 373 test(DateTime(0, 12, 31, 12, 30, 33), UTC(), -413_670_000_000L); 374 test(DateTime(1, 1, 1, 0, 0, 0), UTC(), 0); 375 test(DateTime(1, 1, 1, 0, 0, 1), UTC(), 10_000_000L); 376 test(DateTime(0, 12, 31, 23, 59, 59), UTC(), -10_000_000L); 377 378 test(DateTime(1, 1, 1, 0, 0, 0), new immutable SimpleTimeZone(dur!"minutes"(-60)), 36_000_000_000L); 379 test(DateTime(1, 1, 1, 0, 0, 0), new immutable SimpleTimeZone(Duration.zero), 0); 380 test(DateTime(1, 1, 1, 0, 0, 0), new immutable SimpleTimeZone(dur!"minutes"(60)), -36_000_000_000L); 381 } 382 383 /++ 384 Params: 385 dateTime = The $(REF DateTime,std,datetime,date) to use to set 386 this $(LREF SysTime)'s internal std time. As 387 $(REF DateTime,std,datetime,date) has no concept of 388 time zone, tz is used as its time zone. 389 fracSecs = The fractional seconds portion of the time. 390 tz = The $(REF TimeZone,std,datetime,timezone) to use for this 391 $(LREF SysTime). If null, 392 $(REF LocalTime,std,datetime,timezone) will be used. The 393 given $(REF DateTime,std,datetime,date) is assumed to 394 be in the given time zone. 395 396 Throws: 397 $(REF DateTimeException,std,datetime,date) if $(D fracSecs) is negative or if it's 398 greater than or equal to one second. 399 +/ 400 this(in DateTime dateTime, in Duration fracSecs, immutable TimeZone tz = null) @safe 401 { 402 enforce(fracSecs >= Duration.zero, new DateTimeException("A SysTime cannot have negative fractional seconds.")); 403 enforce(fracSecs < seconds(1), new DateTimeException("Fractional seconds must be less than one second.")); 404 auto nonNullTZ = tz is null ? LocalTime() : tz; 405 406 immutable dateDiff = dateTime.date - Date.init; 407 immutable todDiff = dateTime.timeOfDay - TimeOfDay.init; 408 409 immutable adjustedTime = dateDiff + todDiff + fracSecs; 410 immutable standardTime = nonNullTZ.tzToUTC(adjustedTime.total!"hnsecs"); 411 412 this(standardTime, nonNullTZ); 413 } 414 415 @safe unittest 416 { 417 static void test(DateTime dt, Duration fracSecs, immutable TimeZone tz, long expected) 418 { 419 auto sysTime = SysTime(dt, fracSecs, tz); 420 assert(sysTime._stdTime == expected); 421 assert(sysTime._timezone is (tz is null ? LocalTime() : tz), 422 format("Given DateTime: %s, Given Duration: %s", dt, fracSecs)); 423 } 424 425 test(DateTime.init, Duration.zero, UTC(), 0); 426 test(DateTime(1, 1, 1, 12, 30, 33), Duration.zero, UTC(), 450_330_000_000L); 427 test(DateTime(0, 12, 31, 12, 30, 33), Duration.zero, UTC(), -413_670_000_000L); 428 test(DateTime(1, 1, 1, 0, 0, 0), msecs(1), UTC(), 10_000L); 429 test(DateTime(0, 12, 31, 23, 59, 59), msecs(999), UTC(), -10_000L); 430 431 test(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC(), -1); 432 test(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC(), -9_999_999); 433 test(DateTime(0, 12, 31, 23, 59, 59), Duration.zero, UTC(), -10_000_000); 434 435 assertThrown!DateTimeException(SysTime(DateTime.init, hnsecs(-1), UTC())); 436 assertThrown!DateTimeException(SysTime(DateTime.init, seconds(1), UTC())); 437 } 438 439 /++ 440 Params: 441 date = The $(REF Date,std,datetime,date) to use to set this 442 $(LREF SysTime)'s internal std time. As 443 $(REF Date,std,datetime,date) has no concept of time zone, tz 444 is used as its time zone. 445 tz = The $(REF TimeZone,std,datetime,timezone) to use for this 446 $(LREF SysTime). If null, 447 $(REF LocalTime,std,datetime,timezone) will be used. The 448 given $(REF Date,std,datetime,date) is assumed to be in the 449 given time zone. 450 +/ 451 this(in Date date, immutable TimeZone tz = null) @safe nothrow 452 { 453 _timezone = tz is null ? LocalTime() : tz; 454 455 try 456 { 457 immutable adjustedTime = (date - Date(1, 1, 1)).total!"hnsecs"; 458 immutable standardTime = _timezone.tzToUTC(adjustedTime); 459 460 this(standardTime, _timezone); 461 } 462 catch (Exception e) 463 assert(0, "Date's constructor through when it shouldn't have."); 464 } 465 466 @safe unittest 467 { 468 static void test(Date d, immutable TimeZone tz, long expected) 469 { 470 auto sysTime = SysTime(d, tz); 471 assert(sysTime._stdTime == expected); 472 assert(sysTime._timezone is (tz is null ? LocalTime() : tz), format("Given Date: %s", d)); 473 } 474 475 test(Date.init, UTC(), 0); 476 test(Date(1, 1, 1), UTC(), 0); 477 test(Date(1, 1, 2), UTC(), 864000000000); 478 test(Date(0, 12, 31), UTC(), -864000000000); 479 } 480 481 /++ 482 Note: 483 Whereas the other constructors take in the given date/time, assume 484 that it's in the given time zone, and convert it to hnsecs in UTC 485 since midnight, January 1st, 1 A.D. UTC - i.e. std time - this 486 constructor takes a std time, which is specifically already in UTC, 487 so no conversion takes place. Of course, the various getter 488 properties and functions will use the given time zone's conversion 489 function to convert the results to that time zone, but no conversion 490 of the arguments to this constructor takes place. 491 492 Params: 493 stdTime = The number of hnsecs since midnight, January 1st, 1 A.D. 494 UTC. 495 tz = The $(REF TimeZone,std,datetime,timezone) to use for this 496 $(LREF SysTime). If null, 497 $(REF LocalTime,std,datetime,timezone) will be used. 498 +/ 499 this(long stdTime, immutable TimeZone tz = null) @safe pure nothrow 500 { 501 _stdTime = stdTime; 502 _timezone = tz is null ? LocalTime() : tz; 503 } 504 505 @safe unittest 506 { 507 static void test(long stdTime, immutable TimeZone tz) 508 { 509 auto sysTime = SysTime(stdTime, tz); 510 assert(sysTime._stdTime == stdTime); 511 assert(sysTime._timezone is (tz is null ? LocalTime() : tz), format("Given stdTime: %s", stdTime)); 512 } 513 514 foreach (stdTime; [-1234567890L, -250, 0, 250, 1235657390L]) 515 { 516 foreach (tz; testTZs) 517 test(stdTime, tz); 518 } 519 } 520 521 /++ 522 Params: 523 rhs = The $(LREF SysTime) to assign to this one. 524 +/ 525 ref SysTime opAssign(const ref SysTime rhs) return @safe pure nothrow 526 { 527 _stdTime = rhs._stdTime; 528 _timezone = rhs._timezone; 529 return this; 530 } 531 532 /++ 533 Params: 534 rhs = The $(LREF SysTime) to assign to this one. 535 +/ 536 ref SysTime opAssign(SysTime rhs) scope return @safe pure nothrow 537 { 538 _stdTime = rhs._stdTime; 539 _timezone = rhs._timezone; 540 return this; 541 } 542 543 /++ 544 Checks for equality between this $(LREF SysTime) and the given 545 $(LREF SysTime). 546 547 Note that the time zone is ignored. Only the internal 548 std times (which are in UTC) are compared. 549 +/ 550 bool opEquals(const SysTime rhs) @safe const pure nothrow 551 { 552 return opEquals(rhs); 553 } 554 555 /// ditto 556 bool opEquals(const ref SysTime rhs) @safe const pure nothrow 557 { 558 return _stdTime == rhs._stdTime; 559 } 560 561 @safe unittest 562 { 563 import std.range : chain; 564 565 assert(SysTime(DateTime.init, UTC()) == SysTime(0, UTC())); 566 assert(SysTime(DateTime.init, UTC()) == SysTime(0)); 567 assert(SysTime(Date.init, UTC()) == SysTime(0)); 568 assert(SysTime(0) == SysTime(0)); 569 570 static void test(DateTime dt, immutable TimeZone tz1, immutable TimeZone tz2) 571 { 572 auto st1 = SysTime(dt); 573 st1.timezone = tz1; 574 575 auto st2 = SysTime(dt); 576 st2.timezone = tz2; 577 578 assert(st1 == st2); 579 } 580 581 foreach (tz1; testTZs) 582 { 583 foreach (tz2; testTZs) 584 { 585 foreach (dt; chain(testDateTimesBC, testDateTimesAD)) 586 test(dt, tz1, tz2); 587 } 588 } 589 590 auto st = SysTime(DateTime(1999, 7, 6, 12, 33, 30)); 591 const cst = SysTime(DateTime(1999, 7, 6, 12, 33, 30)); 592 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 33, 30)); 593 assert(st == st); 594 assert(st == cst); 595 //assert(st == ist); 596 assert(cst == st); 597 assert(cst == cst); 598 //assert(cst == ist); 599 //assert(ist == st); 600 //assert(ist == cst); 601 //assert(ist == ist); 602 } 603 604 /++ 605 Compares this $(LREF SysTime) with the given $(LREF SysTime). 606 607 Time zone is irrelevant when comparing $(LREF SysTime)s. 608 609 Returns: 610 $(BOOKTABLE, 611 $(TR $(TD this < rhs) $(TD < 0)) 612 $(TR $(TD this == rhs) $(TD 0)) 613 $(TR $(TD this > rhs) $(TD > 0)) 614 ) 615 +/ 616 int opCmp(in SysTime rhs) @safe const pure nothrow 617 { 618 if (_stdTime < rhs._stdTime) 619 return -1; 620 if (_stdTime > rhs._stdTime) 621 return 1; 622 return 0; 623 } 624 625 @safe unittest 626 { 627 import std.algorithm.iteration : map; 628 import std.array : array; 629 import std.range : chain; 630 631 assert(SysTime(DateTime.init, UTC()).opCmp(SysTime(0, UTC())) == 0); 632 assert(SysTime(DateTime.init, UTC()).opCmp(SysTime(0)) == 0); 633 assert(SysTime(Date.init, UTC()).opCmp(SysTime(0)) == 0); 634 assert(SysTime(0).opCmp(SysTime(0)) == 0); 635 636 static void testEqual(SysTime st, immutable TimeZone tz1, immutable TimeZone tz2) 637 { 638 auto st1 = st; 639 st1.timezone = tz1; 640 641 auto st2 = st; 642 st2.timezone = tz2; 643 644 assert(st1.opCmp(st2) == 0); 645 } 646 647 auto sts = array(map!SysTime(chain(testDateTimesBC, testDateTimesAD))); 648 649 foreach (st; sts) 650 { 651 foreach (tz1; testTZs) 652 { 653 foreach (tz2; testTZs) 654 testEqual(st, tz1, tz2); 655 } 656 } 657 658 static void testCmp(SysTime st1, immutable TimeZone tz1, SysTime st2, immutable TimeZone tz2) 659 { 660 st1.timezone = tz1; 661 st2.timezone = tz2; 662 assert(st1.opCmp(st2) < 0); 663 assert(st2.opCmp(st1) > 0); 664 } 665 666 foreach (si, st1; sts) 667 { 668 foreach (st2; sts[si + 1 .. $]) 669 { 670 foreach (tz1; testTZs) 671 { 672 foreach (tz2; testTZs) 673 testCmp(st1, tz1, st2, tz2); 674 } 675 } 676 } 677 678 auto st = SysTime(DateTime(1999, 7, 6, 12, 33, 30)); 679 const cst = SysTime(DateTime(1999, 7, 6, 12, 33, 30)); 680 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 33, 30)); 681 assert(st.opCmp(st) == 0); 682 assert(st.opCmp(cst) == 0); 683 //assert(st.opCmp(ist) == 0); 684 assert(cst.opCmp(st) == 0); 685 assert(cst.opCmp(cst) == 0); 686 //assert(cst.opCmp(ist) == 0); 687 //assert(ist.opCmp(st) == 0); 688 //assert(ist.opCmp(cst) == 0); 689 //assert(ist.opCmp(ist) == 0); 690 } 691 692 /** 693 * Returns: A hash of the $(LREF SysTime) 694 */ 695 size_t toHash() const @nogc pure nothrow @safe 696 { 697 static if (is(size_t == ulong)) 698 return _stdTime; 699 else 700 { 701 // MurmurHash2 702 enum ulong m = 0xc6a4a7935bd1e995UL; 703 enum ulong n = m * 16; 704 enum uint r = 47; 705 706 ulong k = _stdTime; 707 k *= m; 708 k ^= k >> r; 709 k *= m; 710 711 ulong h = n; 712 h ^= k; 713 h *= m; 714 715 return cast(size_t) h; 716 } 717 } 718 719 @safe unittest 720 { 721 assert(SysTime(0).toHash == SysTime(0).toHash); 722 assert(SysTime(DateTime(2000, 1, 1)).toHash == SysTime(DateTime(2000, 1, 1)).toHash); 723 assert(SysTime(DateTime(2000, 1, 1)).toHash != SysTime(DateTime(2000, 1, 2)).toHash); 724 725 // test that timezones aren't taken into account 726 assert(SysTime(0, LocalTime()).toHash == SysTime(0, LocalTime()).toHash); 727 assert(SysTime(0, LocalTime()).toHash == SysTime(0, UTC()).toHash); 728 assert(SysTime(DateTime(2000, 1, 1), LocalTime()).toHash == SysTime(DateTime(2000, 1, 1), LocalTime()).toHash); 729 immutable zone = new SimpleTimeZone(dur!"minutes"(60)); 730 assert(SysTime(DateTime(2000, 1, 1, 1), zone).toHash == SysTime(DateTime(2000, 1, 1), UTC()).toHash); 731 assert(SysTime(DateTime(2000, 1, 1), zone).toHash != SysTime(DateTime(2000, 1, 1), UTC()).toHash); 732 } 733 734 /++ 735 Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive 736 are B.C. 737 +/ 738 @property short year() @safe const nothrow 739 { 740 return (cast(Date) this).year; 741 } 742 743 @safe unittest 744 { 745 import std.range : chain; 746 static void test(SysTime sysTime, long expected) 747 { 748 assert(sysTime.year == expected, format("Value given: %s", sysTime)); 749 } 750 751 test(SysTime(0, UTC()), 1); 752 test(SysTime(1, UTC()), 1); 753 test(SysTime(-1, UTC()), 0); 754 755 foreach (year; chain(testYearsBC, testYearsAD)) 756 { 757 foreach (md; testMonthDays) 758 { 759 foreach (tod; testTODs) 760 { 761 auto dt = DateTime(Date(year, md.month, md.day), tod); 762 foreach (tz; testTZs) 763 { 764 foreach (fs; testFracSecs) 765 test(SysTime(dt, fs, tz), year); 766 } 767 } 768 } 769 } 770 771 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 772 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 773 assert(cst.year == 1999); 774 //assert(ist.year == 1999); 775 } 776 777 /++ 778 Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive 779 are B.C. 780 781 Params: 782 year = The year to set this $(LREF SysTime)'s year to. 783 784 Throws: 785 $(REF DateTimeException,std,datetime,date) if the new year is not 786 a leap year and the resulting date would be on February 29th. 787 +/ 788 @property void year(int year) @safe 789 { 790 auto hnsecs = adjTime; 791 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 792 793 if (hnsecs < 0) 794 { 795 hnsecs += convert!("hours", "hnsecs")(24); 796 --days; 797 } 798 799 auto date = Date(cast(int) days); 800 date.year = year; 801 802 immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1); 803 adjTime = newDaysHNSecs + hnsecs; 804 } 805 806 /// 807 @safe unittest 808 { 809 import std.datetime.date : DateTime; 810 811 assert(SysTime(DateTime(1999, 7, 6, 9, 7, 5)).year == 1999); 812 assert(SysTime(DateTime(2010, 10, 4, 0, 0, 30)).year == 2010); 813 assert(SysTime(DateTime(-7, 4, 5, 7, 45, 2)).year == -7); 814 } 815 816 @safe unittest 817 { 818 import std.range : chain; 819 820 static void test(SysTime st, int year, in SysTime expected) 821 { 822 st.year = year; 823 assert(st == expected); 824 } 825 826 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 827 { 828 auto dt = cast(DateTime) st; 829 830 foreach (year; chain(testYearsBC, testYearsAD)) 831 { 832 auto e = SysTime(DateTime(year, dt.month, dt.day, dt.hour, dt.minute, dt.second), 833 st.fracSecs, 834 st.timezone); 835 test(st, year, e); 836 } 837 } 838 839 foreach (fs; testFracSecs) 840 { 841 foreach (tz; testTZs) 842 { 843 foreach (tod; testTODs) 844 { 845 test(SysTime(DateTime(Date(1999, 2, 28), tod), fs, tz), 2000, 846 SysTime(DateTime(Date(2000, 2, 28), tod), fs, tz)); 847 test(SysTime(DateTime(Date(2000, 2, 28), tod), fs, tz), 1999, 848 SysTime(DateTime(Date(1999, 2, 28), tod), fs, tz)); 849 } 850 851 foreach (tod; testTODsThrown) 852 { 853 auto st = SysTime(DateTime(Date(2000, 2, 29), tod), fs, tz); 854 assertThrown!DateTimeException(st.year = 1999); 855 } 856 } 857 } 858 859 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 860 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 861 static assert(!__traits(compiles, cst.year = 7)); 862 //static assert(!__traits(compiles, ist.year = 7)); 863 } 864 865 /++ 866 Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C. 867 868 Throws: 869 $(REF DateTimeException,std,datetime,date) if $(D isAD) is true. 870 +/ 871 @property ushort yearBC() @safe const 872 { 873 return (cast(Date) this).yearBC; 874 } 875 876 /// 877 @safe unittest 878 { 879 import std.datetime.date : DateTime; 880 881 assert(SysTime(DateTime(0, 1, 1, 12, 30, 33)).yearBC == 1); 882 assert(SysTime(DateTime(-1, 1, 1, 10, 7, 2)).yearBC == 2); 883 assert(SysTime(DateTime(-100, 1, 1, 4, 59, 0)).yearBC == 101); 884 } 885 886 @safe unittest 887 { 888 import std.exception : assertNotThrown; 889 foreach (st; testSysTimesBC) 890 { 891 auto msg = format("SysTime: %s", st); 892 assertNotThrown!DateTimeException(st.yearBC, msg); 893 assert(st.yearBC == (st.year * -1) + 1, msg); 894 } 895 896 foreach (st; [testSysTimesAD[0], testSysTimesAD[$/2], testSysTimesAD[$-1]]) 897 assertThrown!DateTimeException(st.yearBC, format("SysTime: %s", st)); 898 899 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 900 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 901 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 902 st.year = 12; 903 assert(st.year == 12); 904 static assert(!__traits(compiles, cst.year = 12)); 905 //static assert(!__traits(compiles, ist.year = 12)); 906 } 907 908 909 /++ 910 Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C. 911 912 Params: 913 year = The year B.C. to set this $(LREF SysTime)'s year to. 914 915 Throws: 916 $(REF DateTimeException,std,datetime,date) if a non-positive value 917 is given. 918 +/ 919 @property void yearBC(int year) @safe 920 { 921 auto hnsecs = adjTime; 922 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 923 924 if (hnsecs < 0) 925 { 926 hnsecs += convert!("hours", "hnsecs")(24); 927 --days; 928 } 929 930 auto date = Date(cast(int) days); 931 date.yearBC = year; 932 933 immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1); 934 adjTime = newDaysHNSecs + hnsecs; 935 } 936 937 @safe unittest 938 { 939 auto st = SysTime(DateTime(2010, 1, 1, 7, 30, 0)); 940 st.yearBC = 1; 941 assert(st == SysTime(DateTime(0, 1, 1, 7, 30, 0))); 942 943 st.yearBC = 10; 944 assert(st == SysTime(DateTime(-9, 1, 1, 7, 30, 0))); 945 } 946 947 @safe unittest 948 { 949 import std.range : chain; 950 static void test(SysTime st, int year, in SysTime expected) 951 { 952 st.yearBC = year; 953 assert(st == expected, format("SysTime: %s", st)); 954 } 955 956 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 957 { 958 auto dt = cast(DateTime) st; 959 960 foreach (year; testYearsBC) 961 { 962 auto e = SysTime(DateTime(year, dt.month, dt.day, dt.hour, dt.minute, dt.second), 963 st.fracSecs, 964 st.timezone); 965 test(st, (year * -1) + 1, e); 966 } 967 } 968 969 foreach (st; [testSysTimesBC[0], testSysTimesBC[$ - 1], testSysTimesAD[0], testSysTimesAD[$ - 1]]) 970 { 971 foreach (year; testYearsBC) 972 assertThrown!DateTimeException(st.yearBC = year); 973 } 974 975 foreach (fs; testFracSecs) 976 { 977 foreach (tz; testTZs) 978 { 979 foreach (tod; testTODs) 980 { 981 test(SysTime(DateTime(Date(-1999, 2, 28), tod), fs, tz), 2001, 982 SysTime(DateTime(Date(-2000, 2, 28), tod), fs, tz)); 983 test(SysTime(DateTime(Date(-2000, 2, 28), tod), fs, tz), 2000, 984 SysTime(DateTime(Date(-1999, 2, 28), tod), fs, tz)); 985 } 986 987 foreach (tod; testTODsThrown) 988 { 989 auto st = SysTime(DateTime(Date(-2000, 2, 29), tod), fs, tz); 990 assertThrown!DateTimeException(st.year = -1999); 991 } 992 } 993 } 994 995 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 996 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 997 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 998 st.yearBC = 12; 999 assert(st.yearBC == 12); 1000 static assert(!__traits(compiles, cst.yearBC = 12)); 1001 //static assert(!__traits(compiles, ist.yearBC = 12)); 1002 } 1003 1004 /++ 1005 Month of a Gregorian Year. 1006 +/ 1007 @property Month month() @safe const nothrow 1008 { 1009 return (cast(Date) this).month; 1010 } 1011 1012 /// 1013 @safe unittest 1014 { 1015 import std.datetime.date : DateTime; 1016 1017 assert(SysTime(DateTime(1999, 7, 6, 9, 7, 5)).month == 7); 1018 assert(SysTime(DateTime(2010, 10, 4, 0, 0, 30)).month == 10); 1019 assert(SysTime(DateTime(-7, 4, 5, 7, 45, 2)).month == 4); 1020 } 1021 1022 @safe unittest 1023 { 1024 import std.range : chain; 1025 1026 static void test(SysTime sysTime, Month expected) 1027 { 1028 assert(sysTime.month == expected, format("Value given: %s", sysTime)); 1029 } 1030 1031 test(SysTime(0, UTC()), Month.jan); 1032 test(SysTime(1, UTC()), Month.jan); 1033 test(SysTime(-1, UTC()), Month.dec); 1034 1035 foreach (year; chain(testYearsBC, testYearsAD)) 1036 { 1037 foreach (md; testMonthDays) 1038 { 1039 foreach (tod; testTODs) 1040 { 1041 auto dt = DateTime(Date(year, md.month, md.day), tod); 1042 foreach (fs; testFracSecs) 1043 { 1044 foreach (tz; testTZs) 1045 test(SysTime(dt, fs, tz), md.month); 1046 } 1047 } 1048 } 1049 } 1050 1051 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1052 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1053 assert(cst.month == 7); 1054 //assert(ist.month == 7); 1055 } 1056 1057 1058 /++ 1059 Month of a Gregorian Year. 1060 1061 Params: 1062 month = The month to set this $(LREF SysTime)'s month to. 1063 1064 Throws: 1065 $(REF DateTimeException,std,datetime,date) if the given month is 1066 not a valid month. 1067 +/ 1068 @property void month(Month month) @safe 1069 { 1070 auto hnsecs = adjTime; 1071 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 1072 1073 if (hnsecs < 0) 1074 { 1075 hnsecs += convert!("hours", "hnsecs")(24); 1076 --days; 1077 } 1078 1079 auto date = Date(cast(int) days); 1080 date.month = month; 1081 1082 immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1); 1083 adjTime = newDaysHNSecs + hnsecs; 1084 } 1085 1086 @safe unittest 1087 { 1088 import std.algorithm.iteration : filter; 1089 import std.range : chain; 1090 1091 static void test(SysTime st, Month month, in SysTime expected) 1092 { 1093 st.month = cast(Month) month; 1094 assert(st == expected); 1095 } 1096 1097 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 1098 { 1099 auto dt = cast(DateTime) st; 1100 1101 foreach (md; testMonthDays) 1102 { 1103 if (st.day > maxDay(dt.year, md.month)) 1104 continue; 1105 auto e = SysTime(DateTime(dt.year, md.month, dt.day, dt.hour, dt.minute, dt.second), 1106 st.fracSecs, 1107 st.timezone); 1108 test(st, md.month, e); 1109 } 1110 } 1111 1112 foreach (fs; testFracSecs) 1113 { 1114 foreach (tz; testTZs) 1115 { 1116 foreach (tod; testTODs) 1117 { 1118 foreach (year; filter!((a){return yearIsLeapYear(a);}) (chain(testYearsBC, testYearsAD))) 1119 { 1120 test(SysTime(DateTime(Date(year, 1, 29), tod), fs, tz), 1121 Month.feb, 1122 SysTime(DateTime(Date(year, 2, 29), tod), fs, tz)); 1123 } 1124 1125 foreach (year; chain(testYearsBC, testYearsAD)) 1126 { 1127 test(SysTime(DateTime(Date(year, 1, 28), tod), fs, tz), 1128 Month.feb, 1129 SysTime(DateTime(Date(year, 2, 28), tod), fs, tz)); 1130 test(SysTime(DateTime(Date(year, 7, 30), tod), fs, tz), 1131 Month.jun, 1132 SysTime(DateTime(Date(year, 6, 30), tod), fs, tz)); 1133 } 1134 } 1135 } 1136 } 1137 1138 foreach (fs; [testFracSecs[0], testFracSecs[$-1]]) 1139 { 1140 foreach (tz; testTZs) 1141 { 1142 foreach (tod; testTODsThrown) 1143 { 1144 foreach (year; [testYearsBC[$-3], testYearsBC[$-2], 1145 testYearsBC[$-2], testYearsAD[0], 1146 testYearsAD[$-2], testYearsAD[$-1]]) 1147 { 1148 auto day = yearIsLeapYear(year) ? 30 : 29; 1149 auto st1 = SysTime(DateTime(Date(year, 1, day), tod), fs, tz); 1150 assertThrown!DateTimeException(st1.month = Month.feb); 1151 1152 auto st2 = SysTime(DateTime(Date(year, 7, 31), tod), fs, tz); 1153 assertThrown!DateTimeException(st2.month = Month.jun); 1154 } 1155 } 1156 } 1157 } 1158 1159 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1160 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1161 static assert(!__traits(compiles, cst.month = 12)); 1162 //static assert(!__traits(compiles, ist.month = 12)); 1163 } 1164 1165 /++ 1166 Day of a Gregorian Month. 1167 +/ 1168 @property ubyte day() @safe const nothrow 1169 { 1170 return (cast(Date) this).day; 1171 } 1172 1173 /// 1174 @safe unittest 1175 { 1176 import std.datetime.date : DateTime; 1177 1178 assert(SysTime(DateTime(1999, 7, 6, 9, 7, 5)).day == 6); 1179 assert(SysTime(DateTime(2010, 10, 4, 0, 0, 30)).day == 4); 1180 assert(SysTime(DateTime(-7, 4, 5, 7, 45, 2)).day == 5); 1181 } 1182 1183 @safe unittest 1184 { 1185 import std.range : chain; 1186 1187 static void test(SysTime sysTime, int expected) 1188 { 1189 assert(sysTime.day == expected, format("Value given: %s", sysTime)); 1190 } 1191 1192 test(SysTime(0, UTC()), 1); 1193 test(SysTime(1, UTC()), 1); 1194 test(SysTime(-1, UTC()), 31); 1195 1196 foreach (year; chain(testYearsBC, testYearsAD)) 1197 { 1198 foreach (md; testMonthDays) 1199 { 1200 foreach (tod; testTODs) 1201 { 1202 auto dt = DateTime(Date(year, md.month, md.day), tod); 1203 1204 foreach (tz; testTZs) 1205 { 1206 foreach (fs; testFracSecs) 1207 test(SysTime(dt, fs, tz), md.day); 1208 } 1209 } 1210 } 1211 } 1212 1213 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1214 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1215 assert(cst.day == 6); 1216 //assert(ist.day == 6); 1217 } 1218 1219 1220 /++ 1221 Day of a Gregorian Month. 1222 1223 Params: 1224 day = The day of the month to set this $(LREF SysTime)'s day to. 1225 1226 Throws: 1227 $(REF DateTimeException,std,datetime,date) if the given day is not 1228 a valid day of the current month. 1229 +/ 1230 @property void day(int day) @safe 1231 { 1232 auto hnsecs = adjTime; 1233 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 1234 1235 if (hnsecs < 0) 1236 { 1237 hnsecs += convert!("hours", "hnsecs")(24); 1238 --days; 1239 } 1240 1241 auto date = Date(cast(int) days); 1242 date.day = day; 1243 1244 immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1); 1245 adjTime = newDaysHNSecs + hnsecs; 1246 } 1247 1248 @safe unittest 1249 { 1250 import std.range : chain; 1251 import std.traits : EnumMembers; 1252 1253 foreach (day; chain(testDays)) 1254 { 1255 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 1256 { 1257 auto dt = cast(DateTime) st; 1258 1259 if (day > maxDay(dt.year, dt.month)) 1260 continue; 1261 auto expected = SysTime(DateTime(dt.year, dt.month, day, dt.hour, dt.minute, dt.second), 1262 st.fracSecs, 1263 st.timezone); 1264 st.day = day; 1265 assert(st == expected, format("[%s] [%s]", st, expected)); 1266 } 1267 } 1268 1269 foreach (tz; testTZs) 1270 { 1271 foreach (tod; testTODs) 1272 { 1273 foreach (fs; testFracSecs) 1274 { 1275 foreach (year; chain(testYearsBC, testYearsAD)) 1276 { 1277 foreach (month; EnumMembers!Month) 1278 { 1279 auto st = SysTime(DateTime(Date(year, month, 1), tod), fs, tz); 1280 immutable max = maxDay(year, month); 1281 auto expected = SysTime(DateTime(Date(year, month, max), tod), fs, tz); 1282 1283 st.day = max; 1284 assert(st == expected, format("[%s] [%s]", st, expected)); 1285 } 1286 } 1287 } 1288 } 1289 } 1290 1291 foreach (tz; testTZs) 1292 { 1293 foreach (tod; testTODsThrown) 1294 { 1295 foreach (fs; [testFracSecs[0], testFracSecs[$-1]]) 1296 { 1297 foreach (year; [testYearsBC[$-3], testYearsBC[$-2], 1298 testYearsBC[$-2], testYearsAD[0], 1299 testYearsAD[$-2], testYearsAD[$-1]]) 1300 { 1301 foreach (month; EnumMembers!Month) 1302 { 1303 auto st = SysTime(DateTime(Date(year, month, 1), tod), fs, tz); 1304 immutable max = maxDay(year, month); 1305 1306 assertThrown!DateTimeException(st.day = max + 1); 1307 } 1308 } 1309 } 1310 } 1311 } 1312 1313 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1314 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1315 static assert(!__traits(compiles, cst.day = 27)); 1316 //static assert(!__traits(compiles, ist.day = 27)); 1317 } 1318 1319 1320 /++ 1321 Hours past midnight. 1322 +/ 1323 @property ubyte hour() @safe const nothrow 1324 { 1325 auto hnsecs = adjTime; 1326 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 1327 1328 if (hnsecs < 0) 1329 { 1330 hnsecs += convert!("hours", "hnsecs")(24); 1331 --days; 1332 } 1333 1334 return cast(ubyte) getUnitsFromHNSecs!"hours"(hnsecs); 1335 } 1336 1337 @safe unittest 1338 { 1339 import std.range : chain; 1340 1341 static void test(SysTime sysTime, int expected) 1342 { 1343 assert(sysTime.hour == expected, format("Value given: %s", sysTime)); 1344 } 1345 1346 test(SysTime(0, UTC()), 0); 1347 test(SysTime(1, UTC()), 0); 1348 test(SysTime(-1, UTC()), 23); 1349 1350 foreach (tz; testTZs) 1351 { 1352 foreach (year; chain(testYearsBC, testYearsAD)) 1353 { 1354 foreach (md; testMonthDays) 1355 { 1356 foreach (hour; testHours) 1357 { 1358 foreach (minute; testMinSecs) 1359 { 1360 foreach (second; testMinSecs) 1361 { 1362 auto dt = DateTime(Date(year, md.month, md.day), TimeOfDay(hour, minute, second)); 1363 foreach (fs; testFracSecs) 1364 test(SysTime(dt, fs, tz), hour); 1365 } 1366 } 1367 } 1368 } 1369 } 1370 } 1371 1372 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1373 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1374 assert(cst.hour == 12); 1375 //assert(ist.hour == 12); 1376 } 1377 1378 1379 /++ 1380 Hours past midnight. 1381 1382 Params: 1383 hour = The hours to set this $(LREF SysTime)'s hour to. 1384 1385 Throws: 1386 $(REF DateTimeException,std,datetime,date) if the given hour are 1387 not a valid hour of the day. 1388 +/ 1389 @property void hour(int hour) @safe 1390 { 1391 enforceValid!"hours"(hour); 1392 1393 auto hnsecs = adjTime; 1394 auto days = splitUnitsFromHNSecs!"days"(hnsecs); 1395 immutable daysHNSecs = convert!("days", "hnsecs")(days); 1396 immutable negative = hnsecs < 0; 1397 1398 if (negative) 1399 hnsecs += convert!("hours", "hnsecs")(24); 1400 1401 hnsecs = removeUnitsFromHNSecs!"hours"(hnsecs); 1402 hnsecs += convert!("hours", "hnsecs")(hour); 1403 1404 if (negative) 1405 hnsecs -= convert!("hours", "hnsecs")(24); 1406 1407 adjTime = daysHNSecs + hnsecs; 1408 } 1409 1410 @safe unittest 1411 { 1412 import std.range : chain; 1413 1414 foreach (hour; chain(testHours)) 1415 { 1416 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 1417 { 1418 auto dt = cast(DateTime) st; 1419 auto expected = SysTime(DateTime(dt.year, dt.month, dt.day, hour, dt.minute, dt.second), 1420 st.fracSecs, 1421 st.timezone); 1422 st.hour = hour; 1423 assert(st == expected, format("[%s] [%s]", st, expected)); 1424 } 1425 } 1426 1427 auto st = testSysTimesAD[0]; 1428 assertThrown!DateTimeException(st.hour = -1); 1429 assertThrown!DateTimeException(st.hour = 60); 1430 1431 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1432 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1433 static assert(!__traits(compiles, cst.hour = 27)); 1434 //static assert(!__traits(compiles, ist.hour = 27)); 1435 } 1436 1437 1438 /++ 1439 Minutes past the current hour. 1440 +/ 1441 @property ubyte minute() @safe const nothrow 1442 { 1443 auto hnsecs = adjTime; 1444 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 1445 1446 if (hnsecs < 0) 1447 { 1448 hnsecs += convert!("hours", "hnsecs")(24); 1449 --days; 1450 } 1451 1452 hnsecs = removeUnitsFromHNSecs!"hours"(hnsecs); 1453 1454 return cast(ubyte) getUnitsFromHNSecs!"minutes"(hnsecs); 1455 } 1456 1457 @safe unittest 1458 { 1459 import std.range : chain; 1460 1461 static void test(SysTime sysTime, int expected) 1462 { 1463 assert(sysTime.minute == expected, format("Value given: %s", sysTime)); 1464 } 1465 1466 test(SysTime(0, UTC()), 0); 1467 test(SysTime(1, UTC()), 0); 1468 test(SysTime(-1, UTC()), 59); 1469 1470 foreach (tz; testTZs) 1471 { 1472 foreach (year; chain(testYearsBC, testYearsAD)) 1473 { 1474 foreach (md; testMonthDays) 1475 { 1476 foreach (hour; testHours) 1477 { 1478 foreach (minute; testMinSecs) 1479 { 1480 foreach (second; testMinSecs) 1481 { 1482 auto dt = DateTime(Date(year, md.month, md.day), TimeOfDay(hour, minute, second)); 1483 foreach (fs; testFracSecs) 1484 test(SysTime(dt, fs, tz), minute); 1485 } 1486 } 1487 } 1488 } 1489 } 1490 } 1491 1492 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1493 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1494 assert(cst.minute == 30); 1495 //assert(ist.minute == 30); 1496 } 1497 1498 1499 /++ 1500 Minutes past the current hour. 1501 1502 Params: 1503 minute = The minute to set this $(LREF SysTime)'s minute to. 1504 1505 Throws: 1506 $(REF DateTimeException,std,datetime,date) if the given minute are 1507 not a valid minute of an hour. 1508 +/ 1509 @property void minute(int minute) @safe 1510 { 1511 enforceValid!"minutes"(minute); 1512 1513 auto hnsecs = adjTime; 1514 auto days = splitUnitsFromHNSecs!"days"(hnsecs); 1515 immutable daysHNSecs = convert!("days", "hnsecs")(days); 1516 immutable negative = hnsecs < 0; 1517 1518 if (negative) 1519 hnsecs += convert!("hours", "hnsecs")(24); 1520 1521 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 1522 hnsecs = removeUnitsFromHNSecs!"minutes"(hnsecs); 1523 1524 hnsecs += convert!("hours", "hnsecs")(hour); 1525 hnsecs += convert!("minutes", "hnsecs")(minute); 1526 1527 if (negative) 1528 hnsecs -= convert!("hours", "hnsecs")(24); 1529 1530 adjTime = daysHNSecs + hnsecs; 1531 } 1532 1533 @safe unittest 1534 { 1535 import std.range : chain; 1536 1537 foreach (minute; testMinSecs) 1538 { 1539 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 1540 { 1541 auto dt = cast(DateTime) st; 1542 auto expected = SysTime(DateTime(dt.year, dt.month, dt.day, dt.hour, minute, dt.second), 1543 st.fracSecs, 1544 st.timezone); 1545 st.minute = minute; 1546 assert(st == expected, format("[%s] [%s]", st, expected)); 1547 } 1548 } 1549 1550 auto st = testSysTimesAD[0]; 1551 assertThrown!DateTimeException(st.minute = -1); 1552 assertThrown!DateTimeException(st.minute = 60); 1553 1554 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1555 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1556 static assert(!__traits(compiles, cst.minute = 27)); 1557 //static assert(!__traits(compiles, ist.minute = 27)); 1558 } 1559 1560 1561 /++ 1562 Seconds past the current minute. 1563 +/ 1564 @property ubyte second() @safe const nothrow 1565 { 1566 auto hnsecs = adjTime; 1567 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 1568 1569 if (hnsecs < 0) 1570 { 1571 hnsecs += convert!("hours", "hnsecs")(24); 1572 --days; 1573 } 1574 1575 hnsecs = removeUnitsFromHNSecs!"hours"(hnsecs); 1576 hnsecs = removeUnitsFromHNSecs!"minutes"(hnsecs); 1577 1578 return cast(ubyte) getUnitsFromHNSecs!"seconds"(hnsecs); 1579 } 1580 1581 @safe unittest 1582 { 1583 import std.range : chain; 1584 1585 static void test(SysTime sysTime, int expected) 1586 { 1587 assert(sysTime.second == expected, format("Value given: %s", sysTime)); 1588 } 1589 1590 test(SysTime(0, UTC()), 0); 1591 test(SysTime(1, UTC()), 0); 1592 test(SysTime(-1, UTC()), 59); 1593 1594 foreach (tz; testTZs) 1595 { 1596 foreach (year; chain(testYearsBC, testYearsAD)) 1597 { 1598 foreach (md; testMonthDays) 1599 { 1600 foreach (hour; testHours) 1601 { 1602 foreach (minute; testMinSecs) 1603 { 1604 foreach (second; testMinSecs) 1605 { 1606 auto dt = DateTime(Date(year, md.month, md.day), TimeOfDay(hour, minute, second)); 1607 foreach (fs; testFracSecs) 1608 test(SysTime(dt, fs, tz), second); 1609 } 1610 } 1611 } 1612 } 1613 } 1614 } 1615 1616 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1617 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1618 assert(cst.second == 33); 1619 //assert(ist.second == 33); 1620 } 1621 1622 1623 /++ 1624 Seconds past the current minute. 1625 1626 Params: 1627 second = The second to set this $(LREF SysTime)'s second to. 1628 1629 Throws: 1630 $(REF DateTimeException,std,datetime,date) if the given second are 1631 not a valid second of a minute. 1632 +/ 1633 @property void second(int second) @safe 1634 { 1635 enforceValid!"seconds"(second); 1636 1637 auto hnsecs = adjTime; 1638 auto days = splitUnitsFromHNSecs!"days"(hnsecs); 1639 immutable daysHNSecs = convert!("days", "hnsecs")(days); 1640 immutable negative = hnsecs < 0; 1641 1642 if (negative) 1643 hnsecs += convert!("hours", "hnsecs")(24); 1644 1645 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 1646 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 1647 hnsecs = removeUnitsFromHNSecs!"seconds"(hnsecs); 1648 1649 hnsecs += convert!("hours", "hnsecs")(hour); 1650 hnsecs += convert!("minutes", "hnsecs")(minute); 1651 hnsecs += convert!("seconds", "hnsecs")(second); 1652 1653 if (negative) 1654 hnsecs -= convert!("hours", "hnsecs")(24); 1655 1656 adjTime = daysHNSecs + hnsecs; 1657 } 1658 1659 @safe unittest 1660 { 1661 import std.range : chain; 1662 1663 foreach (second; testMinSecs) 1664 { 1665 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 1666 { 1667 auto dt = cast(DateTime) st; 1668 auto expected = SysTime(DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, second), 1669 st.fracSecs, 1670 st.timezone); 1671 st.second = second; 1672 assert(st == expected, format("[%s] [%s]", st, expected)); 1673 } 1674 } 1675 1676 auto st = testSysTimesAD[0]; 1677 assertThrown!DateTimeException(st.second = -1); 1678 assertThrown!DateTimeException(st.second = 60); 1679 1680 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1681 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1682 static assert(!__traits(compiles, cst.seconds = 27)); 1683 //static assert(!__traits(compiles, ist.seconds = 27)); 1684 } 1685 1686 1687 /++ 1688 Fractional seconds past the second (i.e. the portion of a 1689 $(LREF SysTime) which is less than a second). 1690 +/ 1691 @property Duration fracSecs() @safe const nothrow 1692 { 1693 auto hnsecs = removeUnitsFromHNSecs!"days"(adjTime); 1694 1695 if (hnsecs < 0) 1696 hnsecs += convert!("hours", "hnsecs")(24); 1697 1698 return dur!"hnsecs"(removeUnitsFromHNSecs!"seconds"(hnsecs)); 1699 } 1700 1701 /// 1702 @safe unittest 1703 { 1704 import core.time : msecs, usecs, hnsecs, nsecs; 1705 import std.datetime.date : DateTime; 1706 1707 auto dt = DateTime(1982, 4, 1, 20, 59, 22); 1708 assert(SysTime(dt, msecs(213)).fracSecs == msecs(213)); 1709 assert(SysTime(dt, usecs(5202)).fracSecs == usecs(5202)); 1710 assert(SysTime(dt, hnsecs(1234567)).fracSecs == hnsecs(1234567)); 1711 1712 // SysTime and Duration both have a precision of hnsecs (100 ns), 1713 // so nsecs are going to be truncated. 1714 assert(SysTime(dt, nsecs(123456789)).fracSecs == nsecs(123456700)); 1715 } 1716 1717 @safe unittest 1718 { 1719 import std.range : chain; 1720 1721 assert(SysTime(0, UTC()).fracSecs == Duration.zero); 1722 assert(SysTime(1, UTC()).fracSecs == hnsecs(1)); 1723 assert(SysTime(-1, UTC()).fracSecs == hnsecs(9_999_999)); 1724 1725 foreach (tz; testTZs) 1726 { 1727 foreach (year; chain(testYearsBC, testYearsAD)) 1728 { 1729 foreach (md; testMonthDays) 1730 { 1731 foreach (hour; testHours) 1732 { 1733 foreach (minute; testMinSecs) 1734 { 1735 foreach (second; testMinSecs) 1736 { 1737 auto dt = DateTime(Date(year, md.month, md.day), TimeOfDay(hour, minute, second)); 1738 foreach (fs; testFracSecs) 1739 assert(SysTime(dt, fs, tz).fracSecs == fs); 1740 } 1741 } 1742 } 1743 } 1744 } 1745 } 1746 1747 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1748 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1749 assert(cst.fracSecs == Duration.zero); 1750 //assert(ist.fracSecs == Duration.zero); 1751 } 1752 1753 1754 /++ 1755 Fractional seconds past the second (i.e. the portion of a 1756 $(LREF SysTime) which is less than a second). 1757 1758 Params: 1759 fracSecs = The duration to set this $(LREF SysTime)'s fractional 1760 seconds to. 1761 1762 Throws: 1763 $(REF DateTimeException,std,datetime,date) if the given duration 1764 is negative or if it's greater than or equal to one second. 1765 +/ 1766 @property void fracSecs(Duration fracSecs) @safe 1767 { 1768 enforce(fracSecs >= Duration.zero, new DateTimeException("A SysTime cannot have negative fractional seconds.")); 1769 enforce(fracSecs < seconds(1), new DateTimeException("Fractional seconds must be less than one second.")); 1770 1771 auto oldHNSecs = adjTime; 1772 auto days = splitUnitsFromHNSecs!"days"(oldHNSecs); 1773 immutable daysHNSecs = convert!("days", "hnsecs")(days); 1774 immutable negative = oldHNSecs < 0; 1775 1776 if (negative) 1777 oldHNSecs += convert!("hours", "hnsecs")(24); 1778 1779 immutable seconds = splitUnitsFromHNSecs!"seconds"(oldHNSecs); 1780 immutable secondsHNSecs = convert!("seconds", "hnsecs")(seconds); 1781 auto newHNSecs = fracSecs.total!"hnsecs" + secondsHNSecs; 1782 1783 if (negative) 1784 newHNSecs -= convert!("hours", "hnsecs")(24); 1785 1786 adjTime = daysHNSecs + newHNSecs; 1787 } 1788 1789 /// 1790 @safe unittest 1791 { 1792 import core.time : Duration, msecs, hnsecs, nsecs; 1793 import std.datetime.date : DateTime; 1794 1795 auto st = SysTime(DateTime(1982, 4, 1, 20, 59, 22)); 1796 assert(st.fracSecs == Duration.zero); 1797 1798 st.fracSecs = msecs(213); 1799 assert(st.fracSecs == msecs(213)); 1800 1801 st.fracSecs = hnsecs(1234567); 1802 assert(st.fracSecs == hnsecs(1234567)); 1803 1804 // SysTime has a precision of hnsecs (100 ns), so nsecs are 1805 // going to be truncated. 1806 st.fracSecs = nsecs(123456789); 1807 assert(st.fracSecs == hnsecs(1234567)); 1808 } 1809 1810 @safe unittest 1811 { 1812 import std.range : chain; 1813 1814 foreach (fracSec; testFracSecs) 1815 { 1816 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 1817 { 1818 auto dt = cast(DateTime) st; 1819 auto expected = SysTime(dt, fracSec, st.timezone); 1820 st.fracSecs = fracSec; 1821 assert(st == expected, format("[%s] [%s]", st, expected)); 1822 } 1823 } 1824 1825 auto st = testSysTimesAD[0]; 1826 assertThrown!DateTimeException(st.fracSecs = hnsecs(-1)); 1827 assertThrown!DateTimeException(st.fracSecs = seconds(1)); 1828 1829 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1830 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1831 static assert(!__traits(compiles, cst.fracSecs = msecs(7))); 1832 //static assert(!__traits(compiles, ist.fracSecs = msecs(7))); 1833 } 1834 1835 1836 /++ 1837 The total hnsecs from midnight, January 1st, 1 A.D. UTC. This is the 1838 internal representation of $(LREF SysTime). 1839 +/ 1840 @property long stdTime() @safe const pure nothrow 1841 { 1842 return _stdTime; 1843 } 1844 1845 @safe unittest 1846 { 1847 assert(SysTime(0).stdTime == 0); 1848 assert(SysTime(1).stdTime == 1); 1849 assert(SysTime(-1).stdTime == -1); 1850 assert(SysTime(DateTime(1, 1, 1, 0, 0, 33), hnsecs(502), UTC()).stdTime == 330_000_502L); 1851 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 0), UTC()).stdTime == 621_355_968_000_000_000L); 1852 1853 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1854 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1855 assert(cst.stdTime > 0); 1856 //assert(ist.stdTime > 0); 1857 } 1858 1859 1860 /++ 1861 The total hnsecs from midnight, January 1st, 1 A.D. UTC. This is the 1862 internal representation of $(LREF SysTime). 1863 1864 Params: 1865 stdTime = The number of hnsecs since January 1st, 1 A.D. UTC. 1866 +/ 1867 @property void stdTime(long stdTime) @safe pure nothrow 1868 { 1869 _stdTime = stdTime; 1870 } 1871 1872 @safe unittest 1873 { 1874 static void test(long stdTime, in SysTime expected, size_t line = __LINE__) 1875 { 1876 auto st = SysTime(0, UTC()); 1877 st.stdTime = stdTime; 1878 assert(st == expected); 1879 } 1880 1881 test(0, SysTime(Date(1, 1, 1), UTC())); 1882 test(1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC())); 1883 test(-1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC())); 1884 test(330_000_502L, SysTime(DateTime(1, 1, 1, 0, 0, 33), hnsecs(502), UTC())); 1885 test(621_355_968_000_000_000L, SysTime(DateTime(1970, 1, 1, 0, 0, 0), UTC())); 1886 1887 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1888 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1889 static assert(!__traits(compiles, cst.stdTime = 27)); 1890 //static assert(!__traits(compiles, ist.stdTime = 27)); 1891 } 1892 1893 1894 /++ 1895 The current time zone of this $(LREF SysTime). Its internal time is 1896 always kept in UTC, so there are no conversion issues between time zones 1897 due to DST. Functions which return all or part of the time - such as 1898 hours - adjust the time to this $(LREF SysTime)'s time zone before 1899 returning. 1900 +/ 1901 @property immutable(TimeZone) timezone() @safe const pure nothrow 1902 { 1903 return _timezone; 1904 } 1905 1906 1907 /++ 1908 The current time zone of this $(LREF SysTime). It's internal time is 1909 always kept in UTC, so there are no conversion issues between time zones 1910 due to DST. Functions which return all or part of the time - such as 1911 hours - adjust the time to this $(LREF SysTime)'s time zone before 1912 returning. 1913 1914 Params: 1915 timezone = The $(REF _TimeZone,std,datetime,_timezone) to set this 1916 $(LREF SysTime)'s time zone to. 1917 +/ 1918 @property void timezone(immutable TimeZone timezone) @safe pure nothrow 1919 { 1920 if (timezone is null) 1921 _timezone = LocalTime(); 1922 else 1923 _timezone = timezone; 1924 } 1925 1926 1927 /++ 1928 Returns whether DST is in effect for this $(LREF SysTime). 1929 +/ 1930 @property bool dstInEffect() @safe const nothrow 1931 { 1932 return _timezone.dstInEffect(_stdTime); 1933 // This function's unit testing is done in the time zone classes. 1934 } 1935 1936 1937 /++ 1938 Returns what the offset from UTC is for this $(LREF SysTime). 1939 It includes the DST offset in effect at that time (if any). 1940 +/ 1941 @property Duration utcOffset() @safe const nothrow 1942 { 1943 return _timezone.utcOffsetAt(_stdTime); 1944 } 1945 1946 1947 /++ 1948 Returns a $(LREF SysTime) with the same std time as this one, but with 1949 $(REF LocalTime,std,datetime,timezone) as its time zone. 1950 +/ 1951 SysTime toLocalTime() @safe const pure nothrow 1952 { 1953 return SysTime(_stdTime, LocalTime()); 1954 } 1955 1956 @safe unittest 1957 { 1958 { 1959 auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), hnsecs(27)); 1960 assert(sysTime == sysTime.toLocalTime()); 1961 assert(sysTime._stdTime == sysTime.toLocalTime()._stdTime); 1962 assert(sysTime.toLocalTime().timezone is LocalTime()); 1963 assert(sysTime.toLocalTime().timezone is sysTime.timezone); 1964 assert(sysTime.toLocalTime().timezone !is UTC()); 1965 } 1966 1967 { 1968 auto stz = new immutable SimpleTimeZone(dur!"minutes"(-3 * 60)); 1969 auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), hnsecs(27), stz); 1970 assert(sysTime == sysTime.toLocalTime()); 1971 assert(sysTime._stdTime == sysTime.toLocalTime()._stdTime); 1972 assert(sysTime.toLocalTime().timezone is LocalTime()); 1973 assert(sysTime.toLocalTime().timezone !is UTC()); 1974 assert(sysTime.toLocalTime().timezone !is stz); 1975 } 1976 } 1977 1978 1979 /++ 1980 Returns a $(LREF SysTime) with the same std time as this one, but with 1981 $(D UTC) as its time zone. 1982 +/ 1983 SysTime toUTC() @safe const pure nothrow 1984 { 1985 return SysTime(_stdTime, UTC()); 1986 } 1987 1988 @safe unittest 1989 { 1990 auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), hnsecs(27)); 1991 assert(sysTime == sysTime.toUTC()); 1992 assert(sysTime._stdTime == sysTime.toUTC()._stdTime); 1993 assert(sysTime.toUTC().timezone is UTC()); 1994 assert(sysTime.toUTC().timezone !is LocalTime()); 1995 assert(sysTime.toUTC().timezone !is sysTime.timezone); 1996 } 1997 1998 1999 /++ 2000 Returns a $(LREF SysTime) with the same std time as this one, but with 2001 given time zone as its time zone. 2002 +/ 2003 SysTime toOtherTZ(immutable TimeZone tz) @safe const pure nothrow 2004 { 2005 if (tz is null) 2006 return SysTime(_stdTime, LocalTime()); 2007 else 2008 return SysTime(_stdTime, tz); 2009 } 2010 2011 @safe unittest 2012 { 2013 auto stz = new immutable SimpleTimeZone(dur!"minutes"(11 * 60)); 2014 auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), hnsecs(27)); 2015 assert(sysTime == sysTime.toOtherTZ(stz)); 2016 assert(sysTime._stdTime == sysTime.toOtherTZ(stz)._stdTime); 2017 assert(sysTime.toOtherTZ(stz).timezone is stz); 2018 assert(sysTime.toOtherTZ(stz).timezone !is LocalTime()); 2019 assert(sysTime.toOtherTZ(stz).timezone !is UTC()); 2020 } 2021 2022 2023 /++ 2024 Converts this $(LREF SysTime) to unix time (i.e. seconds from midnight, 2025 January 1st, 1970 in UTC). 2026 2027 The C standard does not specify the representation of time_t, so it is 2028 implementation defined. On POSIX systems, unix time is equivalent to 2029 time_t, but that's not necessarily true on other systems (e.g. it is 2030 not true for the Digital Mars C runtime). So, be careful when using unix 2031 time with C functions on non-POSIX systems. 2032 2033 By default, the return type is time_t (which is normally an alias for 2034 int on 32-bit systems and long on 64-bit systems), but if a different 2035 size is required than either int or long can be passed as a template 2036 argument to get the desired size. 2037 2038 If the return type is int, and the result can't fit in an int, then the 2039 closest value that can be held in 32 bits will be used (so $(D int.max) 2040 if it goes over and $(D int.min) if it goes under). However, no attempt 2041 is made to deal with integer overflow if the return type is long. 2042 2043 Params: 2044 T = The return type (int or long). It defaults to time_t, which is 2045 normally 32 bits on a 32-bit system and 64 bits on a 64-bit 2046 system. 2047 2048 Returns: 2049 A signed integer representing the unix time which is equivalent to 2050 this SysTime. 2051 +/ 2052 T toUnixTime(T = time_t)() @safe const pure nothrow 2053 if (is(T == int) || is(T == long)) 2054 { 2055 return stdTimeToUnixTime!T(_stdTime); 2056 } 2057 2058 /// 2059 @safe unittest 2060 { 2061 import core.time : hours; 2062 import std.datetime.date : DateTime; 2063 import std.datetime.timezone : SimpleTimeZone, UTC; 2064 2065 assert(SysTime(DateTime(1970, 1, 1), UTC()).toUnixTime() == 0); 2066 2067 auto pst = new immutable SimpleTimeZone(hours(-8)); 2068 assert(SysTime(DateTime(1970, 1, 1), pst).toUnixTime() == 28800); 2069 2070 auto utc = SysTime(DateTime(2007, 12, 22, 8, 14, 45), UTC()); 2071 assert(utc.toUnixTime() == 1_198_311_285); 2072 2073 auto ca = SysTime(DateTime(2007, 12, 22, 8, 14, 45), pst); 2074 assert(ca.toUnixTime() == 1_198_340_085); 2075 } 2076 2077 @safe unittest 2078 { 2079 import std.meta : AliasSeq; 2080 assert(SysTime(DateTime(1970, 1, 1), UTC()).toUnixTime() == 0); 2081 foreach (units; AliasSeq!("hnsecs", "usecs", "msecs")) 2082 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 0), dur!units(1), UTC()).toUnixTime() == 0); 2083 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), UTC()).toUnixTime() == 1); 2084 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toUnixTime() == 0); 2085 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999_999), UTC()).toUnixTime() == 0); 2086 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), msecs(999), UTC()).toUnixTime() == 0); 2087 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), UTC()).toUnixTime() == -1); 2088 } 2089 2090 2091 /++ 2092 Converts from unix time (i.e. seconds from midnight, January 1st, 1970 2093 in UTC) to a $(LREF SysTime). 2094 2095 The C standard does not specify the representation of time_t, so it is 2096 implementation defined. On POSIX systems, unix time is equivalent to 2097 time_t, but that's not necessarily true on other systems (e.g. it is 2098 not true for the Digital Mars C runtime). So, be careful when using unix 2099 time with C functions on non-POSIX systems. 2100 2101 Params: 2102 unixTime = Seconds from midnight, January 1st, 1970 in UTC. 2103 tz = The time zone for the SysTime that's returned. 2104 +/ 2105 static SysTime fromUnixTime(long unixTime, immutable TimeZone tz = LocalTime()) @safe pure nothrow 2106 { 2107 return SysTime(unixTimeToStdTime(unixTime), tz); 2108 } 2109 2110 /// 2111 @safe unittest 2112 { 2113 import core.time : hours; 2114 import std.datetime.date : DateTime; 2115 import std.datetime.timezone : SimpleTimeZone, UTC; 2116 2117 assert(SysTime.fromUnixTime(0) == 2118 SysTime(DateTime(1970, 1, 1), UTC())); 2119 2120 auto pst = new immutable SimpleTimeZone(hours(-8)); 2121 assert(SysTime.fromUnixTime(28800) == 2122 SysTime(DateTime(1970, 1, 1), pst)); 2123 2124 auto st1 = SysTime.fromUnixTime(1_198_311_285, UTC()); 2125 assert(st1 == SysTime(DateTime(2007, 12, 22, 8, 14, 45), UTC())); 2126 assert(st1.timezone is UTC()); 2127 assert(st1 == SysTime(DateTime(2007, 12, 22, 0, 14, 45), pst)); 2128 2129 auto st2 = SysTime.fromUnixTime(1_198_311_285, pst); 2130 assert(st2 == SysTime(DateTime(2007, 12, 22, 8, 14, 45), UTC())); 2131 assert(st2.timezone is pst); 2132 assert(st2 == SysTime(DateTime(2007, 12, 22, 0, 14, 45), pst)); 2133 } 2134 2135 @safe unittest 2136 { 2137 assert(SysTime.fromUnixTime(0) == SysTime(DateTime(1970, 1, 1), UTC())); 2138 assert(SysTime.fromUnixTime(1) == SysTime(DateTime(1970, 1, 1, 0, 0, 1), UTC())); 2139 assert(SysTime.fromUnixTime(-1) == SysTime(DateTime(1969, 12, 31, 23, 59, 59), UTC())); 2140 2141 auto st = SysTime.fromUnixTime(0); 2142 auto dt = cast(DateTime) st; 2143 assert(dt <= DateTime(1970, 2, 1) && dt >= DateTime(1969, 12, 31)); 2144 assert(st.timezone is LocalTime()); 2145 2146 auto aest = new immutable SimpleTimeZone(hours(10)); 2147 assert(SysTime.fromUnixTime(-36000) == SysTime(DateTime(1970, 1, 1), aest)); 2148 } 2149 2150 2151 /++ 2152 Returns a $(D timeval) which represents this $(LREF SysTime). 2153 2154 Note that like all conversions in std.datetime, this is a truncating 2155 conversion. 2156 2157 If $(D timeval.tv_sec) is int, and the result can't fit in an int, then 2158 the closest value that can be held in 32 bits will be used for 2159 $(D tv_sec). (so $(D int.max) if it goes over and $(D int.min) if it 2160 goes under). 2161 +/ 2162 timeval toTimeVal() @safe const pure nothrow 2163 { 2164 immutable tv_sec = toUnixTime!(typeof(timeval.tv_sec))(); 2165 immutable fracHNSecs = removeUnitsFromHNSecs!"seconds"(_stdTime - 621_355_968_000_000_000L); 2166 immutable tv_usec = cast(typeof(timeval.tv_usec))convert!("hnsecs", "usecs")(fracHNSecs); 2167 return timeval(tv_sec, tv_usec); 2168 } 2169 2170 @safe unittest 2171 { 2172 assert(SysTime(DateTime(1970, 1, 1), UTC()).toTimeVal() == timeval(0, 0)); 2173 assert(SysTime(DateTime(1970, 1, 1), hnsecs(9), UTC()).toTimeVal() == timeval(0, 0)); 2174 assert(SysTime(DateTime(1970, 1, 1), hnsecs(10), UTC()).toTimeVal() == timeval(0, 1)); 2175 assert(SysTime(DateTime(1970, 1, 1), usecs(7), UTC()).toTimeVal() == timeval(0, 7)); 2176 2177 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), UTC()).toTimeVal() == timeval(1, 0)); 2178 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), hnsecs(9), UTC()).toTimeVal() == timeval(1, 0)); 2179 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), hnsecs(10), UTC()).toTimeVal() == timeval(1, 1)); 2180 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), usecs(7), UTC()).toTimeVal() == timeval(1, 7)); 2181 2182 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toTimeVal() == timeval(0, 0)); 2183 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_990), UTC()).toTimeVal() == timeval(0, -1)); 2184 2185 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999_999), UTC()).toTimeVal() == timeval(0, -1)); 2186 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999), UTC()).toTimeVal() == timeval(0, -999_001)); 2187 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), msecs(999), UTC()).toTimeVal() == timeval(0, -1000)); 2188 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), UTC()).toTimeVal() == timeval(-1, 0)); 2189 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 58), usecs(17), UTC()).toTimeVal() == timeval(-1, -999_983)); 2190 } 2191 2192 2193 version (StdDdoc) 2194 { 2195 private struct timespec {} 2196 /++ 2197 Returns a $(D timespec) which represents this $(LREF SysTime). 2198 2199 $(BLUE This function is Posix-Only.) 2200 +/ 2201 timespec toTimeSpec() @safe const pure nothrow; 2202 } 2203 else version (Posix) 2204 { 2205 timespec toTimeSpec() @safe const pure nothrow 2206 { 2207 immutable tv_sec = toUnixTime!(typeof(timespec.tv_sec))(); 2208 immutable fracHNSecs = removeUnitsFromHNSecs!"seconds"(_stdTime - 621_355_968_000_000_000L); 2209 immutable tv_nsec = cast(typeof(timespec.tv_nsec))convert!("hnsecs", "nsecs")(fracHNSecs); 2210 return timespec(tv_sec, tv_nsec); 2211 } 2212 2213 @safe unittest 2214 { 2215 assert(SysTime(DateTime(1970, 1, 1), UTC()).toTimeSpec() == timespec(0, 0)); 2216 assert(SysTime(DateTime(1970, 1, 1), hnsecs(9), UTC()).toTimeSpec() == timespec(0, 900)); 2217 assert(SysTime(DateTime(1970, 1, 1), hnsecs(10), UTC()).toTimeSpec() == timespec(0, 1000)); 2218 assert(SysTime(DateTime(1970, 1, 1), usecs(7), UTC()).toTimeSpec() == timespec(0, 7000)); 2219 2220 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), UTC()).toTimeSpec() == timespec(1, 0)); 2221 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), hnsecs(9), UTC()).toTimeSpec() == timespec(1, 900)); 2222 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), hnsecs(10), UTC()).toTimeSpec() == timespec(1, 1000)); 2223 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), usecs(7), UTC()).toTimeSpec() == timespec(1, 7000)); 2224 2225 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toTimeSpec() == 2226 timespec(0, -100)); 2227 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_990), UTC()).toTimeSpec() == 2228 timespec(0, -1000)); 2229 2230 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999_999), UTC()).toTimeSpec() == 2231 timespec(0, -1_000)); 2232 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999), UTC()).toTimeSpec() == 2233 timespec(0, -999_001_000)); 2234 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), msecs(999), UTC()).toTimeSpec() == 2235 timespec(0, -1_000_000)); 2236 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), UTC()).toTimeSpec() == 2237 timespec(-1, 0)); 2238 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 58), usecs(17), UTC()).toTimeSpec() == 2239 timespec(-1, -999_983_000)); 2240 } 2241 } 2242 2243 /++ 2244 Returns a $(D tm) which represents this $(LREF SysTime). 2245 +/ 2246 tm toTM() @safe const nothrow 2247 { 2248 auto dateTime = cast(DateTime) this; 2249 tm timeInfo; 2250 2251 timeInfo.tm_sec = dateTime.second; 2252 timeInfo.tm_min = dateTime.minute; 2253 timeInfo.tm_hour = dateTime.hour; 2254 timeInfo.tm_mday = dateTime.day; 2255 timeInfo.tm_mon = dateTime.month - 1; 2256 timeInfo.tm_year = dateTime.year - 1900; 2257 timeInfo.tm_wday = dateTime.dayOfWeek; 2258 timeInfo.tm_yday = dateTime.dayOfYear - 1; 2259 timeInfo.tm_isdst = _timezone.dstInEffect(_stdTime); 2260 2261 version (Posix) 2262 { 2263 import std.utf : toUTFz; 2264 timeInfo.tm_gmtoff = cast(int) convert!("hnsecs", "seconds")(adjTime - _stdTime); 2265 auto zone = (timeInfo.tm_isdst ? _timezone.dstName : _timezone.stdName); 2266 timeInfo.tm_zone = zone.toUTFz!(char*)(); 2267 } 2268 2269 return timeInfo; 2270 } 2271 2272 @system unittest 2273 { 2274 import std.conv : to; 2275 2276 version (Posix) 2277 { 2278 scope(exit) clearTZEnvVar(); 2279 setTZEnvVar("America/Los_Angeles"); 2280 } 2281 2282 { 2283 auto timeInfo = SysTime(DateTime(1970, 1, 1)).toTM(); 2284 2285 assert(timeInfo.tm_sec == 0); 2286 assert(timeInfo.tm_min == 0); 2287 assert(timeInfo.tm_hour == 0); 2288 assert(timeInfo.tm_mday == 1); 2289 assert(timeInfo.tm_mon == 0); 2290 assert(timeInfo.tm_year == 70); 2291 assert(timeInfo.tm_wday == 4); 2292 assert(timeInfo.tm_yday == 0); 2293 2294 version (Posix) 2295 assert(timeInfo.tm_isdst == 0); 2296 else version (Windows) 2297 assert(timeInfo.tm_isdst == 0 || timeInfo.tm_isdst == 1); 2298 2299 version (Posix) 2300 { 2301 assert(timeInfo.tm_gmtoff == -8 * 60 * 60); 2302 assert(to!string(timeInfo.tm_zone) == "PST"); 2303 } 2304 } 2305 2306 { 2307 auto timeInfo = SysTime(DateTime(2010, 7, 4, 12, 15, 7), hnsecs(15)).toTM(); 2308 2309 assert(timeInfo.tm_sec == 7); 2310 assert(timeInfo.tm_min == 15); 2311 assert(timeInfo.tm_hour == 12); 2312 assert(timeInfo.tm_mday == 4); 2313 assert(timeInfo.tm_mon == 6); 2314 assert(timeInfo.tm_year == 110); 2315 assert(timeInfo.tm_wday == 0); 2316 assert(timeInfo.tm_yday == 184); 2317 2318 version (Posix) 2319 assert(timeInfo.tm_isdst == 1); 2320 else version (Windows) 2321 assert(timeInfo.tm_isdst == 0 || timeInfo.tm_isdst == 1); 2322 2323 version (Posix) 2324 { 2325 assert(timeInfo.tm_gmtoff == -7 * 60 * 60); 2326 assert(to!string(timeInfo.tm_zone) == "PDT"); 2327 } 2328 } 2329 } 2330 2331 2332 /++ 2333 Adds the given number of years or months to this $(LREF SysTime). A 2334 negative number will subtract. 2335 2336 Note that if day overflow is allowed, and the date with the adjusted 2337 year/month overflows the number of days in the new month, then the month 2338 will be incremented by one, and the day set to the number of days 2339 overflowed. (e.g. if the day were 31 and the new month were June, then 2340 the month would be incremented to July, and the new day would be 1). If 2341 day overflow is not allowed, then the day will be set to the last valid 2342 day in the month (e.g. June 31st would become June 30th). 2343 2344 Params: 2345 units = The type of units to add ("years" or "months"). 2346 value = The number of months or years to add to this 2347 $(LREF SysTime). 2348 allowOverflow = Whether the days should be allowed to overflow, 2349 causing the month to increment. 2350 +/ 2351 ref SysTime add(string units)(long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe nothrow 2352 if (units == "years" || units == "months") 2353 { 2354 auto hnsecs = adjTime; 2355 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 2356 2357 if (hnsecs < 0) 2358 { 2359 hnsecs += convert!("hours", "hnsecs")(24); 2360 --days; 2361 } 2362 2363 auto date = Date(cast(int) days); 2364 date.add!units(value, allowOverflow); 2365 days = date.dayOfGregorianCal - 1; 2366 2367 if (days < 0) 2368 { 2369 hnsecs -= convert!("hours", "hnsecs")(24); 2370 ++days; 2371 } 2372 2373 immutable newDaysHNSecs = convert!("days", "hnsecs")(days); 2374 2375 adjTime = newDaysHNSecs + hnsecs; 2376 2377 return this; 2378 } 2379 2380 @safe unittest 2381 { 2382 auto st1 = SysTime(DateTime(2010, 1, 1, 12, 30, 33)); 2383 st1.add!"months"(11); 2384 assert(st1 == SysTime(DateTime(2010, 12, 1, 12, 30, 33))); 2385 2386 auto st2 = SysTime(DateTime(2010, 1, 1, 12, 30, 33)); 2387 st2.add!"months"(-11); 2388 assert(st2 == SysTime(DateTime(2009, 2, 1, 12, 30, 33))); 2389 2390 auto st3 = SysTime(DateTime(2000, 2, 29, 12, 30, 33)); 2391 st3.add!"years"(1); 2392 assert(st3 == SysTime(DateTime(2001, 3, 1, 12, 30, 33))); 2393 2394 auto st4 = SysTime(DateTime(2000, 2, 29, 12, 30, 33)); 2395 st4.add!"years"(1, AllowDayOverflow.no); 2396 assert(st4 == SysTime(DateTime(2001, 2, 28, 12, 30, 33))); 2397 } 2398 2399 // Test add!"years"() with AllowDayOverflow.yes 2400 @safe unittest 2401 { 2402 // Test A.D. 2403 { 2404 auto sysTime = SysTime(Date(1999, 7, 6)); 2405 sysTime.add!"years"(7); 2406 assert(sysTime == SysTime(Date(2006, 7, 6))); 2407 sysTime.add!"years"(-9); 2408 assert(sysTime == SysTime(Date(1997, 7, 6))); 2409 } 2410 2411 { 2412 auto sysTime = SysTime(Date(1999, 2, 28)); 2413 sysTime.add!"years"(1); 2414 assert(sysTime == SysTime(Date(2000, 2, 28))); 2415 } 2416 2417 { 2418 auto sysTime = SysTime(Date(2000, 2, 29)); 2419 sysTime.add!"years"(-1); 2420 assert(sysTime == SysTime(Date(1999, 3, 1))); 2421 } 2422 2423 { 2424 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 7, 3), msecs(234)); 2425 sysTime.add!"years"(7); 2426 assert(sysTime == SysTime(DateTime(2006, 7, 6, 12, 7, 3), msecs(234))); 2427 sysTime.add!"years"(-9); 2428 assert(sysTime == SysTime(DateTime(1997, 7, 6, 12, 7, 3), msecs(234))); 2429 } 2430 2431 { 2432 auto sysTime = SysTime(DateTime(1999, 2, 28, 0, 7, 2), usecs(1207)); 2433 sysTime.add!"years"(1); 2434 assert(sysTime == SysTime(DateTime(2000, 2, 28, 0, 7, 2), usecs(1207))); 2435 } 2436 2437 { 2438 auto sysTime = SysTime(DateTime(2000, 2, 29, 0, 7, 2), usecs(1207)); 2439 sysTime.add!"years"(-1); 2440 assert(sysTime == SysTime(DateTime(1999, 3, 1, 0, 7, 2), usecs(1207))); 2441 } 2442 2443 // Test B.C. 2444 { 2445 auto sysTime = SysTime(Date(-1999, 7, 6)); 2446 sysTime.add!"years"(-7); 2447 assert(sysTime == SysTime(Date(-2006, 7, 6))); 2448 sysTime.add!"years"(9); 2449 assert(sysTime == SysTime(Date(-1997, 7, 6))); 2450 } 2451 2452 { 2453 auto sysTime = SysTime(Date(-1999, 2, 28)); 2454 sysTime.add!"years"(-1); 2455 assert(sysTime == SysTime(Date(-2000, 2, 28))); 2456 } 2457 2458 { 2459 auto sysTime = SysTime(Date(-2000, 2, 29)); 2460 sysTime.add!"years"(1); 2461 assert(sysTime == SysTime(Date(-1999, 3, 1))); 2462 } 2463 2464 { 2465 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 7, 3), msecs(234)); 2466 sysTime.add!"years"(-7); 2467 assert(sysTime == SysTime(DateTime(-2006, 7, 6, 12, 7, 3), msecs(234))); 2468 sysTime.add!"years"(9); 2469 assert(sysTime == SysTime(DateTime(-1997, 7, 6, 12, 7, 3), msecs(234))); 2470 } 2471 2472 { 2473 auto sysTime = SysTime(DateTime(-1999, 2, 28, 3, 3, 3), hnsecs(3)); 2474 sysTime.add!"years"(-1); 2475 assert(sysTime == SysTime(DateTime(-2000, 2, 28, 3, 3, 3), hnsecs(3))); 2476 } 2477 2478 { 2479 auto sysTime = SysTime(DateTime(-2000, 2, 29, 3, 3, 3), hnsecs(3)); 2480 sysTime.add!"years"(1); 2481 assert(sysTime == SysTime(DateTime(-1999, 3, 1, 3, 3, 3), hnsecs(3))); 2482 } 2483 2484 // Test Both 2485 { 2486 auto sysTime = SysTime(Date(4, 7, 6)); 2487 sysTime.add!"years"(-5); 2488 assert(sysTime == SysTime(Date(-1, 7, 6))); 2489 sysTime.add!"years"(5); 2490 assert(sysTime == SysTime(Date(4, 7, 6))); 2491 } 2492 2493 { 2494 auto sysTime = SysTime(Date(-4, 7, 6)); 2495 sysTime.add!"years"(5); 2496 assert(sysTime == SysTime(Date(1, 7, 6))); 2497 sysTime.add!"years"(-5); 2498 assert(sysTime == SysTime(Date(-4, 7, 6))); 2499 } 2500 2501 { 2502 auto sysTime = SysTime(Date(4, 7, 6)); 2503 sysTime.add!"years"(-8); 2504 assert(sysTime == SysTime(Date(-4, 7, 6))); 2505 sysTime.add!"years"(8); 2506 assert(sysTime == SysTime(Date(4, 7, 6))); 2507 } 2508 2509 { 2510 auto sysTime = SysTime(Date(-4, 7, 6)); 2511 sysTime.add!"years"(8); 2512 assert(sysTime == SysTime(Date(4, 7, 6))); 2513 sysTime.add!"years"(-8); 2514 assert(sysTime == SysTime(Date(-4, 7, 6))); 2515 } 2516 2517 { 2518 auto sysTime = SysTime(Date(-4, 2, 29)); 2519 sysTime.add!"years"(5); 2520 assert(sysTime == SysTime(Date(1, 3, 1))); 2521 } 2522 2523 { 2524 auto sysTime = SysTime(Date(4, 2, 29)); 2525 sysTime.add!"years"(-5); 2526 assert(sysTime == SysTime(Date(-1, 3, 1))); 2527 } 2528 2529 { 2530 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 2531 sysTime.add!"years"(-1); 2532 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0))); 2533 sysTime.add!"years"(1); 2534 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 2535 } 2536 2537 { 2538 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 2539 sysTime.add!"years"(-1); 2540 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 2541 sysTime.add!"years"(1); 2542 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 2543 } 2544 2545 { 2546 auto sysTime = SysTime(DateTime(0, 1, 1, 0, 0, 0)); 2547 sysTime.add!"years"(1); 2548 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 2549 sysTime.add!"years"(-1); 2550 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0))); 2551 } 2552 2553 { 2554 auto sysTime = SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 2555 sysTime.add!"years"(1); 2556 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 2557 sysTime.add!"years"(-1); 2558 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 2559 } 2560 2561 { 2562 auto sysTime = SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329)); 2563 sysTime.add!"years"(-5); 2564 assert(sysTime == SysTime(DateTime(-1, 7, 6, 14, 7, 1), usecs(54329))); 2565 sysTime.add!"years"(5); 2566 assert(sysTime == SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329))); 2567 } 2568 2569 { 2570 auto sysTime = SysTime(DateTime(-4, 7, 6, 14, 7, 1), usecs(54329)); 2571 sysTime.add!"years"(5); 2572 assert(sysTime == SysTime(DateTime(1, 7, 6, 14, 7, 1), usecs(54329))); 2573 sysTime.add!"years"(-5); 2574 assert(sysTime == SysTime(DateTime(-4, 7, 6, 14, 7, 1), usecs(54329))); 2575 } 2576 2577 { 2578 auto sysTime = SysTime(DateTime(-4, 2, 29, 5, 5, 5), msecs(555)); 2579 sysTime.add!"years"(5); 2580 assert(sysTime == SysTime(DateTime(1, 3, 1, 5, 5, 5), msecs(555))); 2581 } 2582 2583 { 2584 auto sysTime = SysTime(DateTime(4, 2, 29, 5, 5, 5), msecs(555)); 2585 sysTime.add!"years"(-5); 2586 assert(sysTime == SysTime(DateTime(-1, 3, 1, 5, 5, 5), msecs(555))); 2587 } 2588 2589 { 2590 auto sysTime = SysTime(DateTime(4, 2, 29, 5, 5, 5), msecs(555)); 2591 sysTime.add!"years"(-5).add!"years"(7); 2592 assert(sysTime == SysTime(DateTime(6, 3, 1, 5, 5, 5), msecs(555))); 2593 } 2594 2595 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 2596 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 2597 static assert(!__traits(compiles, cst.add!"years"(4))); 2598 //static assert(!__traits(compiles, ist.add!"years"(4))); 2599 } 2600 2601 // Test add!"years"() with AllowDayOverflow.no 2602 @safe unittest 2603 { 2604 // Test A.D. 2605 { 2606 auto sysTime = SysTime(Date(1999, 7, 6)); 2607 sysTime.add!"years"(7, AllowDayOverflow.no); 2608 assert(sysTime == SysTime(Date(2006, 7, 6))); 2609 sysTime.add!"years"(-9, AllowDayOverflow.no); 2610 assert(sysTime == SysTime(Date(1997, 7, 6))); 2611 } 2612 2613 { 2614 auto sysTime = SysTime(Date(1999, 2, 28)); 2615 sysTime.add!"years"(1, AllowDayOverflow.no); 2616 assert(sysTime == SysTime(Date(2000, 2, 28))); 2617 } 2618 2619 { 2620 auto sysTime = SysTime(Date(2000, 2, 29)); 2621 sysTime.add!"years"(-1, AllowDayOverflow.no); 2622 assert(sysTime == SysTime(Date(1999, 2, 28))); 2623 } 2624 2625 { 2626 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 7, 3), msecs(234)); 2627 sysTime.add!"years"(7, AllowDayOverflow.no); 2628 assert(sysTime == SysTime(DateTime(2006, 7, 6, 12, 7, 3), msecs(234))); 2629 sysTime.add!"years"(-9, AllowDayOverflow.no); 2630 assert(sysTime == SysTime(DateTime(1997, 7, 6, 12, 7, 3), msecs(234))); 2631 } 2632 2633 { 2634 auto sysTime = SysTime(DateTime(1999, 2, 28, 0, 7, 2), usecs(1207)); 2635 sysTime.add!"years"(1, AllowDayOverflow.no); 2636 assert(sysTime == SysTime(DateTime(2000, 2, 28, 0, 7, 2), usecs(1207))); 2637 } 2638 2639 { 2640 auto sysTime = SysTime(DateTime(2000, 2, 29, 0, 7, 2), usecs(1207)); 2641 sysTime.add!"years"(-1, AllowDayOverflow.no); 2642 assert(sysTime == SysTime(DateTime(1999, 2, 28, 0, 7, 2), usecs(1207))); 2643 } 2644 2645 // Test B.C. 2646 { 2647 auto sysTime = SysTime(Date(-1999, 7, 6)); 2648 sysTime.add!"years"(-7, AllowDayOverflow.no); 2649 assert(sysTime == SysTime(Date(-2006, 7, 6))); 2650 sysTime.add!"years"(9, AllowDayOverflow.no); 2651 assert(sysTime == SysTime(Date(-1997, 7, 6))); 2652 } 2653 2654 { 2655 auto sysTime = SysTime(Date(-1999, 2, 28)); 2656 sysTime.add!"years"(-1, AllowDayOverflow.no); 2657 assert(sysTime == SysTime(Date(-2000, 2, 28))); 2658 } 2659 2660 { 2661 auto sysTime = SysTime(Date(-2000, 2, 29)); 2662 sysTime.add!"years"(1, AllowDayOverflow.no); 2663 assert(sysTime == SysTime(Date(-1999, 2, 28))); 2664 } 2665 2666 { 2667 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 7, 3), msecs(234)); 2668 sysTime.add!"years"(-7, AllowDayOverflow.no); 2669 assert(sysTime == SysTime(DateTime(-2006, 7, 6, 12, 7, 3), msecs(234))); 2670 sysTime.add!"years"(9, AllowDayOverflow.no); 2671 assert(sysTime == SysTime(DateTime(-1997, 7, 6, 12, 7, 3), msecs(234))); 2672 } 2673 2674 { 2675 auto sysTime = SysTime(DateTime(-1999, 2, 28, 3, 3, 3), hnsecs(3)); 2676 sysTime.add!"years"(-1, AllowDayOverflow.no); 2677 assert(sysTime == SysTime(DateTime(-2000, 2, 28, 3, 3, 3), hnsecs(3))); 2678 } 2679 2680 { 2681 auto sysTime = SysTime(DateTime(-2000, 2, 29, 3, 3, 3), hnsecs(3)); 2682 sysTime.add!"years"(1, AllowDayOverflow.no); 2683 assert(sysTime == SysTime(DateTime(-1999, 2, 28, 3, 3, 3), hnsecs(3))); 2684 } 2685 2686 // Test Both 2687 { 2688 auto sysTime = SysTime(Date(4, 7, 6)); 2689 sysTime.add!"years"(-5, AllowDayOverflow.no); 2690 assert(sysTime == SysTime(Date(-1, 7, 6))); 2691 sysTime.add!"years"(5, AllowDayOverflow.no); 2692 assert(sysTime == SysTime(Date(4, 7, 6))); 2693 } 2694 2695 { 2696 auto sysTime = SysTime(Date(-4, 7, 6)); 2697 sysTime.add!"years"(5, AllowDayOverflow.no); 2698 assert(sysTime == SysTime(Date(1, 7, 6))); 2699 sysTime.add!"years"(-5, AllowDayOverflow.no); 2700 assert(sysTime == SysTime(Date(-4, 7, 6))); 2701 } 2702 2703 { 2704 auto sysTime = SysTime(Date(4, 7, 6)); 2705 sysTime.add!"years"(-8, AllowDayOverflow.no); 2706 assert(sysTime == SysTime(Date(-4, 7, 6))); 2707 sysTime.add!"years"(8, AllowDayOverflow.no); 2708 assert(sysTime == SysTime(Date(4, 7, 6))); 2709 } 2710 2711 { 2712 auto sysTime = SysTime(Date(-4, 7, 6)); 2713 sysTime.add!"years"(8, AllowDayOverflow.no); 2714 assert(sysTime == SysTime(Date(4, 7, 6))); 2715 sysTime.add!"years"(-8, AllowDayOverflow.no); 2716 assert(sysTime == SysTime(Date(-4, 7, 6))); 2717 } 2718 2719 { 2720 auto sysTime = SysTime(Date(-4, 2, 29)); 2721 sysTime.add!"years"(5, AllowDayOverflow.no); 2722 assert(sysTime == SysTime(Date(1, 2, 28))); 2723 } 2724 2725 { 2726 auto sysTime = SysTime(Date(4, 2, 29)); 2727 sysTime.add!"years"(-5, AllowDayOverflow.no); 2728 assert(sysTime == SysTime(Date(-1, 2, 28))); 2729 } 2730 2731 { 2732 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 2733 sysTime.add!"years"(-1, AllowDayOverflow.no); 2734 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0))); 2735 sysTime.add!"years"(1, AllowDayOverflow.no); 2736 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 2737 } 2738 2739 { 2740 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 2741 sysTime.add!"years"(-1, AllowDayOverflow.no); 2742 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 2743 sysTime.add!"years"(1, AllowDayOverflow.no); 2744 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 2745 } 2746 2747 { 2748 auto sysTime = SysTime(DateTime(0, 1, 1, 0, 0, 0)); 2749 sysTime.add!"years"(1, AllowDayOverflow.no); 2750 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 2751 sysTime.add!"years"(-1, AllowDayOverflow.no); 2752 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0))); 2753 } 2754 2755 { 2756 auto sysTime = SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 2757 sysTime.add!"years"(1, AllowDayOverflow.no); 2758 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 2759 sysTime.add!"years"(-1, AllowDayOverflow.no); 2760 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 2761 } 2762 2763 { 2764 auto sysTime = SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329)); 2765 sysTime.add!"years"(-5); 2766 assert(sysTime == SysTime(DateTime(-1, 7, 6, 14, 7, 1), usecs(54329))); 2767 sysTime.add!"years"(5); 2768 assert(sysTime == SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329))); 2769 } 2770 2771 { 2772 auto sysTime = SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329)); 2773 sysTime.add!"years"(-5, AllowDayOverflow.no); 2774 assert(sysTime == SysTime(DateTime(-1, 7, 6, 14, 7, 1), usecs(54329))); 2775 sysTime.add!"years"(5, AllowDayOverflow.no); 2776 assert(sysTime == SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329))); 2777 } 2778 2779 { 2780 auto sysTime = SysTime(DateTime(-4, 7, 6, 14, 7, 1), usecs(54329)); 2781 sysTime.add!"years"(5, AllowDayOverflow.no); 2782 assert(sysTime == SysTime(DateTime(1, 7, 6, 14, 7, 1), usecs(54329))); 2783 sysTime.add!"years"(-5, AllowDayOverflow.no); 2784 assert(sysTime == SysTime(DateTime(-4, 7, 6, 14, 7, 1), usecs(54329))); 2785 } 2786 2787 { 2788 auto sysTime = SysTime(DateTime(-4, 2, 29, 5, 5, 5), msecs(555)); 2789 sysTime.add!"years"(5, AllowDayOverflow.no); 2790 assert(sysTime == SysTime(DateTime(1, 2, 28, 5, 5, 5), msecs(555))); 2791 } 2792 2793 { 2794 auto sysTime = SysTime(DateTime(4, 2, 29, 5, 5, 5), msecs(555)); 2795 sysTime.add!"years"(-5, AllowDayOverflow.no); 2796 assert(sysTime == SysTime(DateTime(-1, 2, 28, 5, 5, 5), msecs(555))); 2797 } 2798 2799 { 2800 auto sysTime = SysTime(DateTime(4, 2, 29, 5, 5, 5), msecs(555)); 2801 sysTime.add!"years"(-5, AllowDayOverflow.no).add!"years"(7, AllowDayOverflow.no); 2802 assert(sysTime == SysTime(DateTime(6, 2, 28, 5, 5, 5), msecs(555))); 2803 } 2804 } 2805 2806 // Test add!"months"() with AllowDayOverflow.yes 2807 @safe unittest 2808 { 2809 // Test A.D. 2810 { 2811 auto sysTime = SysTime(Date(1999, 7, 6)); 2812 sysTime.add!"months"(3); 2813 assert(sysTime == SysTime(Date(1999, 10, 6))); 2814 sysTime.add!"months"(-4); 2815 assert(sysTime == SysTime(Date(1999, 6, 6))); 2816 } 2817 2818 { 2819 auto sysTime = SysTime(Date(1999, 7, 6)); 2820 sysTime.add!"months"(6); 2821 assert(sysTime == SysTime(Date(2000, 1, 6))); 2822 sysTime.add!"months"(-6); 2823 assert(sysTime == SysTime(Date(1999, 7, 6))); 2824 } 2825 2826 { 2827 auto sysTime = SysTime(Date(1999, 7, 6)); 2828 sysTime.add!"months"(27); 2829 assert(sysTime == SysTime(Date(2001, 10, 6))); 2830 sysTime.add!"months"(-28); 2831 assert(sysTime == SysTime(Date(1999, 6, 6))); 2832 } 2833 2834 { 2835 auto sysTime = SysTime(Date(1999, 5, 31)); 2836 sysTime.add!"months"(1); 2837 assert(sysTime == SysTime(Date(1999, 7, 1))); 2838 } 2839 2840 { 2841 auto sysTime = SysTime(Date(1999, 5, 31)); 2842 sysTime.add!"months"(-1); 2843 assert(sysTime == SysTime(Date(1999, 5, 1))); 2844 } 2845 2846 { 2847 auto sysTime = SysTime(Date(1999, 2, 28)); 2848 sysTime.add!"months"(12); 2849 assert(sysTime == SysTime(Date(2000, 2, 28))); 2850 } 2851 2852 { 2853 auto sysTime = SysTime(Date(2000, 2, 29)); 2854 sysTime.add!"months"(12); 2855 assert(sysTime == SysTime(Date(2001, 3, 1))); 2856 } 2857 2858 { 2859 auto sysTime = SysTime(Date(1999, 7, 31)); 2860 sysTime.add!"months"(1); 2861 assert(sysTime == SysTime(Date(1999, 8, 31))); 2862 sysTime.add!"months"(1); 2863 assert(sysTime == SysTime(Date(1999, 10, 1))); 2864 } 2865 2866 { 2867 auto sysTime = SysTime(Date(1998, 8, 31)); 2868 sysTime.add!"months"(13); 2869 assert(sysTime == SysTime(Date(1999, 10, 1))); 2870 sysTime.add!"months"(-13); 2871 assert(sysTime == SysTime(Date(1998, 9, 1))); 2872 } 2873 2874 { 2875 auto sysTime = SysTime(Date(1997, 12, 31)); 2876 sysTime.add!"months"(13); 2877 assert(sysTime == SysTime(Date(1999, 1, 31))); 2878 sysTime.add!"months"(-13); 2879 assert(sysTime == SysTime(Date(1997, 12, 31))); 2880 } 2881 2882 { 2883 auto sysTime = SysTime(Date(1997, 12, 31)); 2884 sysTime.add!"months"(14); 2885 assert(sysTime == SysTime(Date(1999, 3, 3))); 2886 sysTime.add!"months"(-14); 2887 assert(sysTime == SysTime(Date(1998, 1, 3))); 2888 } 2889 2890 { 2891 auto sysTime = SysTime(Date(1998, 12, 31)); 2892 sysTime.add!"months"(14); 2893 assert(sysTime == SysTime(Date(2000, 3, 2))); 2894 sysTime.add!"months"(-14); 2895 assert(sysTime == SysTime(Date(1999, 1, 2))); 2896 } 2897 2898 { 2899 auto sysTime = SysTime(Date(1999, 12, 31)); 2900 sysTime.add!"months"(14); 2901 assert(sysTime == SysTime(Date(2001, 3, 3))); 2902 sysTime.add!"months"(-14); 2903 assert(sysTime == SysTime(Date(2000, 1, 3))); 2904 } 2905 2906 { 2907 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), usecs(5007)); 2908 sysTime.add!"months"(3); 2909 assert(sysTime == SysTime(DateTime(1999, 10, 6, 12, 2, 7), usecs(5007))); 2910 sysTime.add!"months"(-4); 2911 assert(sysTime == SysTime(DateTime(1999, 6, 6, 12, 2, 7), usecs(5007))); 2912 } 2913 2914 { 2915 auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), hnsecs(422202)); 2916 sysTime.add!"months"(14); 2917 assert(sysTime == SysTime(DateTime(2000, 3, 2, 7, 7, 7), hnsecs(422202))); 2918 sysTime.add!"months"(-14); 2919 assert(sysTime == SysTime(DateTime(1999, 1, 2, 7, 7, 7), hnsecs(422202))); 2920 } 2921 2922 { 2923 auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), hnsecs(422202)); 2924 sysTime.add!"months"(14); 2925 assert(sysTime == SysTime(DateTime(2001, 3, 3, 7, 7, 7), hnsecs(422202))); 2926 sysTime.add!"months"(-14); 2927 assert(sysTime == SysTime(DateTime(2000, 1, 3, 7, 7, 7), hnsecs(422202))); 2928 } 2929 2930 // Test B.C. 2931 { 2932 auto sysTime = SysTime(Date(-1999, 7, 6)); 2933 sysTime.add!"months"(3); 2934 assert(sysTime == SysTime(Date(-1999, 10, 6))); 2935 sysTime.add!"months"(-4); 2936 assert(sysTime == SysTime(Date(-1999, 6, 6))); 2937 } 2938 2939 { 2940 auto sysTime = SysTime(Date(-1999, 7, 6)); 2941 sysTime.add!"months"(6); 2942 assert(sysTime == SysTime(Date(-1998, 1, 6))); 2943 sysTime.add!"months"(-6); 2944 assert(sysTime == SysTime(Date(-1999, 7, 6))); 2945 } 2946 2947 { 2948 auto sysTime = SysTime(Date(-1999, 7, 6)); 2949 sysTime.add!"months"(-27); 2950 assert(sysTime == SysTime(Date(-2001, 4, 6))); 2951 sysTime.add!"months"(28); 2952 assert(sysTime == SysTime(Date(-1999, 8, 6))); 2953 } 2954 2955 { 2956 auto sysTime = SysTime(Date(-1999, 5, 31)); 2957 sysTime.add!"months"(1); 2958 assert(sysTime == SysTime(Date(-1999, 7, 1))); 2959 } 2960 2961 { 2962 auto sysTime = SysTime(Date(-1999, 5, 31)); 2963 sysTime.add!"months"(-1); 2964 assert(sysTime == SysTime(Date(-1999, 5, 1))); 2965 } 2966 2967 { 2968 auto sysTime = SysTime(Date(-1999, 2, 28)); 2969 sysTime.add!"months"(-12); 2970 assert(sysTime == SysTime(Date(-2000, 2, 28))); 2971 } 2972 2973 { 2974 auto sysTime = SysTime(Date(-2000, 2, 29)); 2975 sysTime.add!"months"(-12); 2976 assert(sysTime == SysTime(Date(-2001, 3, 1))); 2977 } 2978 2979 { 2980 auto sysTime = SysTime(Date(-1999, 7, 31)); 2981 sysTime.add!"months"(1); 2982 assert(sysTime == SysTime(Date(-1999, 8, 31))); 2983 sysTime.add!"months"(1); 2984 assert(sysTime == SysTime(Date(-1999, 10, 1))); 2985 } 2986 2987 { 2988 auto sysTime = SysTime(Date(-1998, 8, 31)); 2989 sysTime.add!"months"(13); 2990 assert(sysTime == SysTime(Date(-1997, 10, 1))); 2991 sysTime.add!"months"(-13); 2992 assert(sysTime == SysTime(Date(-1998, 9, 1))); 2993 } 2994 2995 { 2996 auto sysTime = SysTime(Date(-1997, 12, 31)); 2997 sysTime.add!"months"(13); 2998 assert(sysTime == SysTime(Date(-1995, 1, 31))); 2999 sysTime.add!"months"(-13); 3000 assert(sysTime == SysTime(Date(-1997, 12, 31))); 3001 } 3002 3003 { 3004 auto sysTime = SysTime(Date(-1997, 12, 31)); 3005 sysTime.add!"months"(14); 3006 assert(sysTime == SysTime(Date(-1995, 3, 3))); 3007 sysTime.add!"months"(-14); 3008 assert(sysTime == SysTime(Date(-1996, 1, 3))); 3009 } 3010 3011 { 3012 auto sysTime = SysTime(Date(-2002, 12, 31)); 3013 sysTime.add!"months"(14); 3014 assert(sysTime == SysTime(Date(-2000, 3, 2))); 3015 sysTime.add!"months"(-14); 3016 assert(sysTime == SysTime(Date(-2001, 1, 2))); 3017 } 3018 3019 { 3020 auto sysTime = SysTime(Date(-2001, 12, 31)); 3021 sysTime.add!"months"(14); 3022 assert(sysTime == SysTime(Date(-1999, 3, 3))); 3023 sysTime.add!"months"(-14); 3024 assert(sysTime == SysTime(Date(-2000, 1, 3))); 3025 } 3026 3027 { 3028 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), usecs(5007)); 3029 sysTime.add!"months"(3); 3030 assert(sysTime == SysTime(DateTime(-1999, 10, 6, 12, 2, 7), usecs(5007))); 3031 sysTime.add!"months"(-4); 3032 assert(sysTime == SysTime(DateTime(-1999, 6, 6, 12, 2, 7), usecs(5007))); 3033 } 3034 3035 { 3036 auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), hnsecs(422202)); 3037 sysTime.add!"months"(14); 3038 assert(sysTime == SysTime(DateTime(-2000, 3, 2, 7, 7, 7), hnsecs(422202))); 3039 sysTime.add!"months"(-14); 3040 assert(sysTime == SysTime(DateTime(-2001, 1, 2, 7, 7, 7), hnsecs(422202))); 3041 } 3042 3043 { 3044 auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), hnsecs(422202)); 3045 sysTime.add!"months"(14); 3046 assert(sysTime == SysTime(DateTime(-1999, 3, 3, 7, 7, 7), hnsecs(422202))); 3047 sysTime.add!"months"(-14); 3048 assert(sysTime == SysTime(DateTime(-2000, 1, 3, 7, 7, 7), hnsecs(422202))); 3049 } 3050 3051 // Test Both 3052 { 3053 auto sysTime = SysTime(Date(1, 1, 1)); 3054 sysTime.add!"months"(-1); 3055 assert(sysTime == SysTime(Date(0, 12, 1))); 3056 sysTime.add!"months"(1); 3057 assert(sysTime == SysTime(Date(1, 1, 1))); 3058 } 3059 3060 { 3061 auto sysTime = SysTime(Date(4, 1, 1)); 3062 sysTime.add!"months"(-48); 3063 assert(sysTime == SysTime(Date(0, 1, 1))); 3064 sysTime.add!"months"(48); 3065 assert(sysTime == SysTime(Date(4, 1, 1))); 3066 } 3067 3068 { 3069 auto sysTime = SysTime(Date(4, 3, 31)); 3070 sysTime.add!"months"(-49); 3071 assert(sysTime == SysTime(Date(0, 3, 2))); 3072 sysTime.add!"months"(49); 3073 assert(sysTime == SysTime(Date(4, 4, 2))); 3074 } 3075 3076 { 3077 auto sysTime = SysTime(Date(4, 3, 31)); 3078 sysTime.add!"months"(-85); 3079 assert(sysTime == SysTime(Date(-3, 3, 3))); 3080 sysTime.add!"months"(85); 3081 assert(sysTime == SysTime(Date(4, 4, 3))); 3082 } 3083 3084 { 3085 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 3086 sysTime.add!"months"(-1); 3087 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 3088 sysTime.add!"months"(1); 3089 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 3090 } 3091 3092 { 3093 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 3094 sysTime.add!"months"(-1); 3095 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 3096 sysTime.add!"months"(1); 3097 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3098 } 3099 3100 { 3101 auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0)); 3102 sysTime.add!"months"(1); 3103 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 3104 sysTime.add!"months"(-1); 3105 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 3106 } 3107 3108 { 3109 auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)); 3110 sysTime.add!"months"(1); 3111 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3112 sysTime.add!"months"(-1); 3113 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 3114 } 3115 3116 { 3117 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17)); 3118 sysTime.add!"months"(-1); 3119 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 7, 9), hnsecs(17))); 3120 sysTime.add!"months"(1); 3121 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17))); 3122 } 3123 3124 { 3125 auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), msecs(9)); 3126 sysTime.add!"months"(-85); 3127 assert(sysTime == SysTime(DateTime(-3, 3, 3, 12, 11, 10), msecs(9))); 3128 sysTime.add!"months"(85); 3129 assert(sysTime == SysTime(DateTime(4, 4, 3, 12, 11, 10), msecs(9))); 3130 } 3131 3132 { 3133 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 3134 sysTime.add!"months"(85); 3135 assert(sysTime == SysTime(DateTime(4, 5, 1, 12, 11, 10), msecs(9))); 3136 sysTime.add!"months"(-85); 3137 assert(sysTime == SysTime(DateTime(-3, 4, 1, 12, 11, 10), msecs(9))); 3138 } 3139 3140 { 3141 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 3142 sysTime.add!"months"(85).add!"months"(-83); 3143 assert(sysTime == SysTime(DateTime(-3, 6, 1, 12, 11, 10), msecs(9))); 3144 } 3145 3146 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 3147 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 3148 static assert(!__traits(compiles, cst.add!"months"(4))); 3149 //static assert(!__traits(compiles, ist.add!"months"(4))); 3150 } 3151 3152 // Test add!"months"() with AllowDayOverflow.no 3153 @safe unittest 3154 { 3155 // Test A.D. 3156 { 3157 auto sysTime = SysTime(Date(1999, 7, 6)); 3158 sysTime.add!"months"(3, AllowDayOverflow.no); 3159 assert(sysTime == SysTime(Date(1999, 10, 6))); 3160 sysTime.add!"months"(-4, AllowDayOverflow.no); 3161 assert(sysTime == SysTime(Date(1999, 6, 6))); 3162 } 3163 3164 { 3165 auto sysTime = SysTime(Date(1999, 7, 6)); 3166 sysTime.add!"months"(6, AllowDayOverflow.no); 3167 assert(sysTime == SysTime(Date(2000, 1, 6))); 3168 sysTime.add!"months"(-6, AllowDayOverflow.no); 3169 assert(sysTime == SysTime(Date(1999, 7, 6))); 3170 } 3171 3172 { 3173 auto sysTime = SysTime(Date(1999, 7, 6)); 3174 sysTime.add!"months"(27, AllowDayOverflow.no); 3175 assert(sysTime == SysTime(Date(2001, 10, 6))); 3176 sysTime.add!"months"(-28, AllowDayOverflow.no); 3177 assert(sysTime == SysTime(Date(1999, 6, 6))); 3178 } 3179 3180 { 3181 auto sysTime = SysTime(Date(1999, 5, 31)); 3182 sysTime.add!"months"(1, AllowDayOverflow.no); 3183 assert(sysTime == SysTime(Date(1999, 6, 30))); 3184 } 3185 3186 { 3187 auto sysTime = SysTime(Date(1999, 5, 31)); 3188 sysTime.add!"months"(-1, AllowDayOverflow.no); 3189 assert(sysTime == SysTime(Date(1999, 4, 30))); 3190 } 3191 3192 { 3193 auto sysTime = SysTime(Date(1999, 2, 28)); 3194 sysTime.add!"months"(12, AllowDayOverflow.no); 3195 assert(sysTime == SysTime(Date(2000, 2, 28))); 3196 } 3197 3198 { 3199 auto sysTime = SysTime(Date(2000, 2, 29)); 3200 sysTime.add!"months"(12, AllowDayOverflow.no); 3201 assert(sysTime == SysTime(Date(2001, 2, 28))); 3202 } 3203 3204 { 3205 auto sysTime = SysTime(Date(1999, 7, 31)); 3206 sysTime.add!"months"(1, AllowDayOverflow.no); 3207 assert(sysTime == SysTime(Date(1999, 8, 31))); 3208 sysTime.add!"months"(1, AllowDayOverflow.no); 3209 assert(sysTime == SysTime(Date(1999, 9, 30))); 3210 } 3211 3212 { 3213 auto sysTime = SysTime(Date(1998, 8, 31)); 3214 sysTime.add!"months"(13, AllowDayOverflow.no); 3215 assert(sysTime == SysTime(Date(1999, 9, 30))); 3216 sysTime.add!"months"(-13, AllowDayOverflow.no); 3217 assert(sysTime == SysTime(Date(1998, 8, 30))); 3218 } 3219 3220 { 3221 auto sysTime = SysTime(Date(1997, 12, 31)); 3222 sysTime.add!"months"(13, AllowDayOverflow.no); 3223 assert(sysTime == SysTime(Date(1999, 1, 31))); 3224 sysTime.add!"months"(-13, AllowDayOverflow.no); 3225 assert(sysTime == SysTime(Date(1997, 12, 31))); 3226 } 3227 3228 { 3229 auto sysTime = SysTime(Date(1997, 12, 31)); 3230 sysTime.add!"months"(14, AllowDayOverflow.no); 3231 assert(sysTime == SysTime(Date(1999, 2, 28))); 3232 sysTime.add!"months"(-14, AllowDayOverflow.no); 3233 assert(sysTime == SysTime(Date(1997, 12, 28))); 3234 } 3235 3236 { 3237 auto sysTime = SysTime(Date(1998, 12, 31)); 3238 sysTime.add!"months"(14, AllowDayOverflow.no); 3239 assert(sysTime == SysTime(Date(2000, 2, 29))); 3240 sysTime.add!"months"(-14, AllowDayOverflow.no); 3241 assert(sysTime == SysTime(Date(1998, 12, 29))); 3242 } 3243 3244 { 3245 auto sysTime = SysTime(Date(1999, 12, 31)); 3246 sysTime.add!"months"(14, AllowDayOverflow.no); 3247 assert(sysTime == SysTime(Date(2001, 2, 28))); 3248 sysTime.add!"months"(-14, AllowDayOverflow.no); 3249 assert(sysTime == SysTime(Date(1999, 12, 28))); 3250 } 3251 3252 { 3253 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), usecs(5007)); 3254 sysTime.add!"months"(3, AllowDayOverflow.no); 3255 assert(sysTime == SysTime(DateTime(1999, 10, 6, 12, 2, 7), usecs(5007))); 3256 sysTime.add!"months"(-4, AllowDayOverflow.no); 3257 assert(sysTime == SysTime(DateTime(1999, 6, 6, 12, 2, 7), usecs(5007))); 3258 } 3259 3260 { 3261 auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), hnsecs(422202)); 3262 sysTime.add!"months"(14, AllowDayOverflow.no); 3263 assert(sysTime == SysTime(DateTime(2000, 2, 29, 7, 7, 7), hnsecs(422202))); 3264 sysTime.add!"months"(-14, AllowDayOverflow.no); 3265 assert(sysTime == SysTime(DateTime(1998, 12, 29, 7, 7, 7), hnsecs(422202))); 3266 } 3267 3268 { 3269 auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), hnsecs(422202)); 3270 sysTime.add!"months"(14, AllowDayOverflow.no); 3271 assert(sysTime == SysTime(DateTime(2001, 2, 28, 7, 7, 7), hnsecs(422202))); 3272 sysTime.add!"months"(-14, AllowDayOverflow.no); 3273 assert(sysTime == SysTime(DateTime(1999, 12, 28, 7, 7, 7), hnsecs(422202))); 3274 } 3275 3276 // Test B.C. 3277 { 3278 auto sysTime = SysTime(Date(-1999, 7, 6)); 3279 sysTime.add!"months"(3, AllowDayOverflow.no); 3280 assert(sysTime == SysTime(Date(-1999, 10, 6))); 3281 sysTime.add!"months"(-4, AllowDayOverflow.no); 3282 assert(sysTime == SysTime(Date(-1999, 6, 6))); 3283 } 3284 3285 { 3286 auto sysTime = SysTime(Date(-1999, 7, 6)); 3287 sysTime.add!"months"(6, AllowDayOverflow.no); 3288 assert(sysTime == SysTime(Date(-1998, 1, 6))); 3289 sysTime.add!"months"(-6, AllowDayOverflow.no); 3290 assert(sysTime == SysTime(Date(-1999, 7, 6))); 3291 } 3292 3293 { 3294 auto sysTime = SysTime(Date(-1999, 7, 6)); 3295 sysTime.add!"months"(-27, AllowDayOverflow.no); 3296 assert(sysTime == SysTime(Date(-2001, 4, 6))); 3297 sysTime.add!"months"(28, AllowDayOverflow.no); 3298 assert(sysTime == SysTime(Date(-1999, 8, 6))); 3299 } 3300 3301 { 3302 auto sysTime = SysTime(Date(-1999, 5, 31)); 3303 sysTime.add!"months"(1, AllowDayOverflow.no); 3304 assert(sysTime == SysTime(Date(-1999, 6, 30))); 3305 } 3306 3307 { 3308 auto sysTime = SysTime(Date(-1999, 5, 31)); 3309 sysTime.add!"months"(-1, AllowDayOverflow.no); 3310 assert(sysTime == SysTime(Date(-1999, 4, 30))); 3311 } 3312 3313 { 3314 auto sysTime = SysTime(Date(-1999, 2, 28)); 3315 sysTime.add!"months"(-12, AllowDayOverflow.no); 3316 assert(sysTime == SysTime(Date(-2000, 2, 28))); 3317 } 3318 3319 { 3320 auto sysTime = SysTime(Date(-2000, 2, 29)); 3321 sysTime.add!"months"(-12, AllowDayOverflow.no); 3322 assert(sysTime == SysTime(Date(-2001, 2, 28))); 3323 } 3324 3325 { 3326 auto sysTime = SysTime(Date(-1999, 7, 31)); 3327 sysTime.add!"months"(1, AllowDayOverflow.no); 3328 assert(sysTime == SysTime(Date(-1999, 8, 31))); 3329 sysTime.add!"months"(1, AllowDayOverflow.no); 3330 assert(sysTime == SysTime(Date(-1999, 9, 30))); 3331 } 3332 3333 { 3334 auto sysTime = SysTime(Date(-1998, 8, 31)); 3335 sysTime.add!"months"(13, AllowDayOverflow.no); 3336 assert(sysTime == SysTime(Date(-1997, 9, 30))); 3337 sysTime.add!"months"(-13, AllowDayOverflow.no); 3338 assert(sysTime == SysTime(Date(-1998, 8, 30))); 3339 } 3340 3341 { 3342 auto sysTime = SysTime(Date(-1997, 12, 31)); 3343 sysTime.add!"months"(13, AllowDayOverflow.no); 3344 assert(sysTime == SysTime(Date(-1995, 1, 31))); 3345 sysTime.add!"months"(-13, AllowDayOverflow.no); 3346 assert(sysTime == SysTime(Date(-1997, 12, 31))); 3347 } 3348 3349 { 3350 auto sysTime = SysTime(Date(-1997, 12, 31)); 3351 sysTime.add!"months"(14, AllowDayOverflow.no); 3352 assert(sysTime == SysTime(Date(-1995, 2, 28))); 3353 sysTime.add!"months"(-14, AllowDayOverflow.no); 3354 assert(sysTime == SysTime(Date(-1997, 12, 28))); 3355 } 3356 3357 { 3358 auto sysTime = SysTime(Date(-2002, 12, 31)); 3359 sysTime.add!"months"(14, AllowDayOverflow.no); 3360 assert(sysTime == SysTime(Date(-2000, 2, 29))); 3361 sysTime.add!"months"(-14, AllowDayOverflow.no); 3362 assert(sysTime == SysTime(Date(-2002, 12, 29))); 3363 } 3364 3365 { 3366 auto sysTime = SysTime(Date(-2001, 12, 31)); 3367 sysTime.add!"months"(14, AllowDayOverflow.no); 3368 assert(sysTime == SysTime(Date(-1999, 2, 28))); 3369 sysTime.add!"months"(-14, AllowDayOverflow.no); 3370 assert(sysTime == SysTime(Date(-2001, 12, 28))); 3371 } 3372 3373 { 3374 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), usecs(5007)); 3375 sysTime.add!"months"(3, AllowDayOverflow.no); 3376 assert(sysTime == SysTime(DateTime(-1999, 10, 6, 12, 2, 7), usecs(5007))); 3377 sysTime.add!"months"(-4, AllowDayOverflow.no); 3378 assert(sysTime == SysTime(DateTime(-1999, 6, 6, 12, 2, 7), usecs(5007))); 3379 } 3380 3381 { 3382 auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), hnsecs(422202)); 3383 sysTime.add!"months"(14, AllowDayOverflow.no); 3384 assert(sysTime == SysTime(DateTime(-2000, 2, 29, 7, 7, 7), hnsecs(422202))); 3385 sysTime.add!"months"(-14, AllowDayOverflow.no); 3386 assert(sysTime == SysTime(DateTime(-2002, 12, 29, 7, 7, 7), hnsecs(422202))); 3387 } 3388 3389 { 3390 auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), hnsecs(422202)); 3391 sysTime.add!"months"(14, AllowDayOverflow.no); 3392 assert(sysTime == SysTime(DateTime(-1999, 2, 28, 7, 7, 7), hnsecs(422202))); 3393 sysTime.add!"months"(-14, AllowDayOverflow.no); 3394 assert(sysTime == SysTime(DateTime(-2001, 12, 28, 7, 7, 7), hnsecs(422202))); 3395 } 3396 3397 // Test Both 3398 { 3399 auto sysTime = SysTime(Date(1, 1, 1)); 3400 sysTime.add!"months"(-1, AllowDayOverflow.no); 3401 assert(sysTime == SysTime(Date(0, 12, 1))); 3402 sysTime.add!"months"(1, AllowDayOverflow.no); 3403 assert(sysTime == SysTime(Date(1, 1, 1))); 3404 } 3405 3406 { 3407 auto sysTime = SysTime(Date(4, 1, 1)); 3408 sysTime.add!"months"(-48, AllowDayOverflow.no); 3409 assert(sysTime == SysTime(Date(0, 1, 1))); 3410 sysTime.add!"months"(48, AllowDayOverflow.no); 3411 assert(sysTime == SysTime(Date(4, 1, 1))); 3412 } 3413 3414 { 3415 auto sysTime = SysTime(Date(4, 3, 31)); 3416 sysTime.add!"months"(-49, AllowDayOverflow.no); 3417 assert(sysTime == SysTime(Date(0, 2, 29))); 3418 sysTime.add!"months"(49, AllowDayOverflow.no); 3419 assert(sysTime == SysTime(Date(4, 3, 29))); 3420 } 3421 3422 { 3423 auto sysTime = SysTime(Date(4, 3, 31)); 3424 sysTime.add!"months"(-85, AllowDayOverflow.no); 3425 assert(sysTime == SysTime(Date(-3, 2, 28))); 3426 sysTime.add!"months"(85, AllowDayOverflow.no); 3427 assert(sysTime == SysTime(Date(4, 3, 28))); 3428 } 3429 3430 { 3431 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 3432 sysTime.add!"months"(-1, AllowDayOverflow.no); 3433 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 3434 sysTime.add!"months"(1, AllowDayOverflow.no); 3435 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 3436 } 3437 3438 { 3439 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 3440 sysTime.add!"months"(-1, AllowDayOverflow.no); 3441 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 3442 sysTime.add!"months"(1, AllowDayOverflow.no); 3443 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3444 } 3445 3446 { 3447 auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0)); 3448 sysTime.add!"months"(1, AllowDayOverflow.no); 3449 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 3450 sysTime.add!"months"(-1, AllowDayOverflow.no); 3451 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 3452 } 3453 3454 { 3455 auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)); 3456 sysTime.add!"months"(1, AllowDayOverflow.no); 3457 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3458 sysTime.add!"months"(-1, AllowDayOverflow.no); 3459 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 3460 } 3461 3462 { 3463 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17)); 3464 sysTime.add!"months"(-1, AllowDayOverflow.no); 3465 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 7, 9), hnsecs(17))); 3466 sysTime.add!"months"(1, AllowDayOverflow.no); 3467 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17))); 3468 } 3469 3470 { 3471 auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), msecs(9)); 3472 sysTime.add!"months"(-85, AllowDayOverflow.no); 3473 assert(sysTime == SysTime(DateTime(-3, 2, 28, 12, 11, 10), msecs(9))); 3474 sysTime.add!"months"(85, AllowDayOverflow.no); 3475 assert(sysTime == SysTime(DateTime(4, 3, 28, 12, 11, 10), msecs(9))); 3476 } 3477 3478 { 3479 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 3480 sysTime.add!"months"(85, AllowDayOverflow.no); 3481 assert(sysTime == SysTime(DateTime(4, 4, 30, 12, 11, 10), msecs(9))); 3482 sysTime.add!"months"(-85, AllowDayOverflow.no); 3483 assert(sysTime == SysTime(DateTime(-3, 3, 30, 12, 11, 10), msecs(9))); 3484 } 3485 3486 { 3487 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 3488 sysTime.add!"months"(85, AllowDayOverflow.no).add!"months"(-83, AllowDayOverflow.no); 3489 assert(sysTime == SysTime(DateTime(-3, 5, 30, 12, 11, 10), msecs(9))); 3490 } 3491 } 3492 3493 3494 /++ 3495 Adds the given number of years or months to this $(LREF SysTime). A 3496 negative number will subtract. 3497 3498 The difference between rolling and adding is that rolling does not 3499 affect larger units. Rolling a $(LREF SysTime) 12 months 3500 gets the exact same $(LREF SysTime). However, the days can still be 3501 affected due to the differing number of days in each month. 3502 3503 Because there are no units larger than years, there is no difference 3504 between adding and rolling years. 3505 3506 Params: 3507 units = The type of units to add ("years" or "months"). 3508 value = The number of months or years to add to this 3509 $(LREF SysTime). 3510 allowOverflow = Whether the days should be allowed to overflow, 3511 causing the month to increment. 3512 +/ 3513 ref SysTime roll(string units)(long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe nothrow 3514 if (units == "years") 3515 { 3516 return add!"years"(value, allowOverflow); 3517 } 3518 3519 /// 3520 @safe unittest 3521 { 3522 import std.datetime.date : AllowDayOverflow, DateTime; 3523 3524 auto st1 = SysTime(DateTime(2010, 1, 1, 12, 33, 33)); 3525 st1.roll!"months"(1); 3526 assert(st1 == SysTime(DateTime(2010, 2, 1, 12, 33, 33))); 3527 3528 auto st2 = SysTime(DateTime(2010, 1, 1, 12, 33, 33)); 3529 st2.roll!"months"(-1); 3530 assert(st2 == SysTime(DateTime(2010, 12, 1, 12, 33, 33))); 3531 3532 auto st3 = SysTime(DateTime(1999, 1, 29, 12, 33, 33)); 3533 st3.roll!"months"(1); 3534 assert(st3 == SysTime(DateTime(1999, 3, 1, 12, 33, 33))); 3535 3536 auto st4 = SysTime(DateTime(1999, 1, 29, 12, 33, 33)); 3537 st4.roll!"months"(1, AllowDayOverflow.no); 3538 assert(st4 == SysTime(DateTime(1999, 2, 28, 12, 33, 33))); 3539 3540 auto st5 = SysTime(DateTime(2000, 2, 29, 12, 30, 33)); 3541 st5.roll!"years"(1); 3542 assert(st5 == SysTime(DateTime(2001, 3, 1, 12, 30, 33))); 3543 3544 auto st6 = SysTime(DateTime(2000, 2, 29, 12, 30, 33)); 3545 st6.roll!"years"(1, AllowDayOverflow.no); 3546 assert(st6 == SysTime(DateTime(2001, 2, 28, 12, 30, 33))); 3547 } 3548 3549 @safe unittest 3550 { 3551 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 3552 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 3553 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 3554 st.roll!"years"(4); 3555 static assert(!__traits(compiles, cst.roll!"years"(4))); 3556 //static assert(!__traits(compiles, ist.roll!"years"(4))); 3557 } 3558 3559 3560 // Shares documentation with "years" overload. 3561 ref SysTime roll(string units)(long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe nothrow 3562 if (units == "months") 3563 { 3564 auto hnsecs = adjTime; 3565 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 3566 3567 if (hnsecs < 0) 3568 { 3569 hnsecs += convert!("hours", "hnsecs")(24); 3570 --days; 3571 } 3572 3573 auto date = Date(cast(int) days); 3574 date.roll!"months"(value, allowOverflow); 3575 days = date.dayOfGregorianCal - 1; 3576 3577 if (days < 0) 3578 { 3579 hnsecs -= convert!("hours", "hnsecs")(24); 3580 ++days; 3581 } 3582 3583 immutable newDaysHNSecs = convert!("days", "hnsecs")(days); 3584 adjTime = newDaysHNSecs + hnsecs; 3585 return this; 3586 } 3587 3588 // Test roll!"months"() with AllowDayOverflow.yes 3589 @safe unittest 3590 { 3591 // Test A.D. 3592 { 3593 auto sysTime = SysTime(Date(1999, 7, 6)); 3594 sysTime.roll!"months"(3); 3595 assert(sysTime == SysTime(Date(1999, 10, 6))); 3596 sysTime.roll!"months"(-4); 3597 assert(sysTime == SysTime(Date(1999, 6, 6))); 3598 } 3599 3600 { 3601 auto sysTime = SysTime(Date(1999, 7, 6)); 3602 sysTime.roll!"months"(6); 3603 assert(sysTime == SysTime(Date(1999, 1, 6))); 3604 sysTime.roll!"months"(-6); 3605 assert(sysTime == SysTime(Date(1999, 7, 6))); 3606 } 3607 3608 { 3609 auto sysTime = SysTime(Date(1999, 7, 6)); 3610 sysTime.roll!"months"(27); 3611 assert(sysTime == SysTime(Date(1999, 10, 6))); 3612 sysTime.roll!"months"(-28); 3613 assert(sysTime == SysTime(Date(1999, 6, 6))); 3614 } 3615 3616 { 3617 auto sysTime = SysTime(Date(1999, 5, 31)); 3618 sysTime.roll!"months"(1); 3619 assert(sysTime == SysTime(Date(1999, 7, 1))); 3620 } 3621 3622 { 3623 auto sysTime = SysTime(Date(1999, 5, 31)); 3624 sysTime.roll!"months"(-1); 3625 assert(sysTime == SysTime(Date(1999, 5, 1))); 3626 } 3627 3628 { 3629 auto sysTime = SysTime(Date(1999, 2, 28)); 3630 sysTime.roll!"months"(12); 3631 assert(sysTime == SysTime(Date(1999, 2, 28))); 3632 } 3633 3634 { 3635 auto sysTime = SysTime(Date(2000, 2, 29)); 3636 sysTime.roll!"months"(12); 3637 assert(sysTime == SysTime(Date(2000, 2, 29))); 3638 } 3639 3640 { 3641 auto sysTime = SysTime(Date(1999, 7, 31)); 3642 sysTime.roll!"months"(1); 3643 assert(sysTime == SysTime(Date(1999, 8, 31))); 3644 sysTime.roll!"months"(1); 3645 assert(sysTime == SysTime(Date(1999, 10, 1))); 3646 } 3647 3648 { 3649 auto sysTime = SysTime(Date(1998, 8, 31)); 3650 sysTime.roll!"months"(13); 3651 assert(sysTime == SysTime(Date(1998, 10, 1))); 3652 sysTime.roll!"months"(-13); 3653 assert(sysTime == SysTime(Date(1998, 9, 1))); 3654 } 3655 3656 { 3657 auto sysTime = SysTime(Date(1997, 12, 31)); 3658 sysTime.roll!"months"(13); 3659 assert(sysTime == SysTime(Date(1997, 1, 31))); 3660 sysTime.roll!"months"(-13); 3661 assert(sysTime == SysTime(Date(1997, 12, 31))); 3662 } 3663 3664 { 3665 auto sysTime = SysTime(Date(1997, 12, 31)); 3666 sysTime.roll!"months"(14); 3667 assert(sysTime == SysTime(Date(1997, 3, 3))); 3668 sysTime.roll!"months"(-14); 3669 assert(sysTime == SysTime(Date(1997, 1, 3))); 3670 } 3671 3672 { 3673 auto sysTime = SysTime(Date(1998, 12, 31)); 3674 sysTime.roll!"months"(14); 3675 assert(sysTime == SysTime(Date(1998, 3, 3))); 3676 sysTime.roll!"months"(-14); 3677 assert(sysTime == SysTime(Date(1998, 1, 3))); 3678 } 3679 3680 { 3681 auto sysTime = SysTime(Date(1999, 12, 31)); 3682 sysTime.roll!"months"(14); 3683 assert(sysTime == SysTime(Date(1999, 3, 3))); 3684 sysTime.roll!"months"(-14); 3685 assert(sysTime == SysTime(Date(1999, 1, 3))); 3686 } 3687 3688 { 3689 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), usecs(5007)); 3690 sysTime.roll!"months"(3); 3691 assert(sysTime == SysTime(DateTime(1999, 10, 6, 12, 2, 7), usecs(5007))); 3692 sysTime.roll!"months"(-4); 3693 assert(sysTime == SysTime(DateTime(1999, 6, 6, 12, 2, 7), usecs(5007))); 3694 } 3695 3696 { 3697 auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), hnsecs(422202)); 3698 sysTime.roll!"months"(14); 3699 assert(sysTime == SysTime(DateTime(1998, 3, 3, 7, 7, 7), hnsecs(422202))); 3700 sysTime.roll!"months"(-14); 3701 assert(sysTime == SysTime(DateTime(1998, 1, 3, 7, 7, 7), hnsecs(422202))); 3702 } 3703 3704 { 3705 auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), hnsecs(422202)); 3706 sysTime.roll!"months"(14); 3707 assert(sysTime == SysTime(DateTime(1999, 3, 3, 7, 7, 7), hnsecs(422202))); 3708 sysTime.roll!"months"(-14); 3709 assert(sysTime == SysTime(DateTime(1999, 1, 3, 7, 7, 7), hnsecs(422202))); 3710 } 3711 3712 // Test B.C. 3713 { 3714 auto sysTime = SysTime(Date(-1999, 7, 6)); 3715 sysTime.roll!"months"(3); 3716 assert(sysTime == SysTime(Date(-1999, 10, 6))); 3717 sysTime.roll!"months"(-4); 3718 assert(sysTime == SysTime(Date(-1999, 6, 6))); 3719 } 3720 3721 { 3722 auto sysTime = SysTime(Date(-1999, 7, 6)); 3723 sysTime.roll!"months"(6); 3724 assert(sysTime == SysTime(Date(-1999, 1, 6))); 3725 sysTime.roll!"months"(-6); 3726 assert(sysTime == SysTime(Date(-1999, 7, 6))); 3727 } 3728 3729 { 3730 auto sysTime = SysTime(Date(-1999, 7, 6)); 3731 sysTime.roll!"months"(-27); 3732 assert(sysTime == SysTime(Date(-1999, 4, 6))); 3733 sysTime.roll!"months"(28); 3734 assert(sysTime == SysTime(Date(-1999, 8, 6))); 3735 } 3736 3737 { 3738 auto sysTime = SysTime(Date(-1999, 5, 31)); 3739 sysTime.roll!"months"(1); 3740 assert(sysTime == SysTime(Date(-1999, 7, 1))); 3741 } 3742 3743 { 3744 auto sysTime = SysTime(Date(-1999, 5, 31)); 3745 sysTime.roll!"months"(-1); 3746 assert(sysTime == SysTime(Date(-1999, 5, 1))); 3747 } 3748 3749 { 3750 auto sysTime = SysTime(Date(-1999, 2, 28)); 3751 sysTime.roll!"months"(-12); 3752 assert(sysTime == SysTime(Date(-1999, 2, 28))); 3753 } 3754 3755 { 3756 auto sysTime = SysTime(Date(-2000, 2, 29)); 3757 sysTime.roll!"months"(-12); 3758 assert(sysTime == SysTime(Date(-2000, 2, 29))); 3759 } 3760 3761 { 3762 auto sysTime = SysTime(Date(-1999, 7, 31)); 3763 sysTime.roll!"months"(1); 3764 assert(sysTime == SysTime(Date(-1999, 8, 31))); 3765 sysTime.roll!"months"(1); 3766 assert(sysTime == SysTime(Date(-1999, 10, 1))); 3767 } 3768 3769 { 3770 auto sysTime = SysTime(Date(-1998, 8, 31)); 3771 sysTime.roll!"months"(13); 3772 assert(sysTime == SysTime(Date(-1998, 10, 1))); 3773 sysTime.roll!"months"(-13); 3774 assert(sysTime == SysTime(Date(-1998, 9, 1))); 3775 } 3776 3777 { 3778 auto sysTime = SysTime(Date(-1997, 12, 31)); 3779 sysTime.roll!"months"(13); 3780 assert(sysTime == SysTime(Date(-1997, 1, 31))); 3781 sysTime.roll!"months"(-13); 3782 assert(sysTime == SysTime(Date(-1997, 12, 31))); 3783 } 3784 3785 { 3786 auto sysTime = SysTime(Date(-1997, 12, 31)); 3787 sysTime.roll!"months"(14); 3788 assert(sysTime == SysTime(Date(-1997, 3, 3))); 3789 sysTime.roll!"months"(-14); 3790 assert(sysTime == SysTime(Date(-1997, 1, 3))); 3791 } 3792 3793 { 3794 auto sysTime = SysTime(Date(-2002, 12, 31)); 3795 sysTime.roll!"months"(14); 3796 assert(sysTime == SysTime(Date(-2002, 3, 3))); 3797 sysTime.roll!"months"(-14); 3798 assert(sysTime == SysTime(Date(-2002, 1, 3))); 3799 } 3800 3801 { 3802 auto sysTime = SysTime(Date(-2001, 12, 31)); 3803 sysTime.roll!"months"(14); 3804 assert(sysTime == SysTime(Date(-2001, 3, 3))); 3805 sysTime.roll!"months"(-14); 3806 assert(sysTime == SysTime(Date(-2001, 1, 3))); 3807 } 3808 3809 { 3810 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 3811 sysTime.roll!"months"(-1); 3812 assert(sysTime == SysTime(DateTime(1, 12, 1, 0, 0, 0))); 3813 sysTime.roll!"months"(1); 3814 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 3815 } 3816 3817 { 3818 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 3819 sysTime.roll!"months"(-1); 3820 assert(sysTime == SysTime(DateTime(1, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 3821 sysTime.roll!"months"(1); 3822 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3823 } 3824 3825 { 3826 auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0)); 3827 sysTime.roll!"months"(1); 3828 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0))); 3829 sysTime.roll!"months"(-1); 3830 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 3831 } 3832 3833 { 3834 auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)); 3835 sysTime.roll!"months"(1); 3836 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3837 sysTime.roll!"months"(-1); 3838 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 3839 } 3840 3841 { 3842 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), hnsecs(5007)); 3843 sysTime.roll!"months"(3); 3844 assert(sysTime == SysTime(DateTime(-1999, 10, 6, 12, 2, 7), hnsecs(5007))); 3845 sysTime.roll!"months"(-4); 3846 assert(sysTime == SysTime(DateTime(-1999, 6, 6, 12, 2, 7), hnsecs(5007))); 3847 } 3848 3849 { 3850 auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), hnsecs(422202)); 3851 sysTime.roll!"months"(14); 3852 assert(sysTime == SysTime(DateTime(-2002, 3, 3, 7, 7, 7), hnsecs(422202))); 3853 sysTime.roll!"months"(-14); 3854 assert(sysTime == SysTime(DateTime(-2002, 1, 3, 7, 7, 7), hnsecs(422202))); 3855 } 3856 3857 { 3858 auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), hnsecs(422202)); 3859 sysTime.roll!"months"(14); 3860 assert(sysTime == SysTime(DateTime(-2001, 3, 3, 7, 7, 7), hnsecs(422202))); 3861 sysTime.roll!"months"(-14); 3862 assert(sysTime == SysTime(DateTime(-2001, 1, 3, 7, 7, 7), hnsecs(422202))); 3863 } 3864 3865 // Test Both 3866 { 3867 auto sysTime = SysTime(Date(1, 1, 1)); 3868 sysTime.roll!"months"(-1); 3869 assert(sysTime == SysTime(Date(1, 12, 1))); 3870 sysTime.roll!"months"(1); 3871 assert(sysTime == SysTime(Date(1, 1, 1))); 3872 } 3873 3874 { 3875 auto sysTime = SysTime(Date(4, 1, 1)); 3876 sysTime.roll!"months"(-48); 3877 assert(sysTime == SysTime(Date(4, 1, 1))); 3878 sysTime.roll!"months"(48); 3879 assert(sysTime == SysTime(Date(4, 1, 1))); 3880 } 3881 3882 { 3883 auto sysTime = SysTime(Date(4, 3, 31)); 3884 sysTime.roll!"months"(-49); 3885 assert(sysTime == SysTime(Date(4, 3, 2))); 3886 sysTime.roll!"months"(49); 3887 assert(sysTime == SysTime(Date(4, 4, 2))); 3888 } 3889 3890 { 3891 auto sysTime = SysTime(Date(4, 3, 31)); 3892 sysTime.roll!"months"(-85); 3893 assert(sysTime == SysTime(Date(4, 3, 2))); 3894 sysTime.roll!"months"(85); 3895 assert(sysTime == SysTime(Date(4, 4, 2))); 3896 } 3897 3898 { 3899 auto sysTime = SysTime(Date(-1, 1, 1)); 3900 sysTime.roll!"months"(-1); 3901 assert(sysTime == SysTime(Date(-1, 12, 1))); 3902 sysTime.roll!"months"(1); 3903 assert(sysTime == SysTime(Date(-1, 1, 1))); 3904 } 3905 3906 { 3907 auto sysTime = SysTime(Date(-4, 1, 1)); 3908 sysTime.roll!"months"(-48); 3909 assert(sysTime == SysTime(Date(-4, 1, 1))); 3910 sysTime.roll!"months"(48); 3911 assert(sysTime == SysTime(Date(-4, 1, 1))); 3912 } 3913 3914 { 3915 auto sysTime = SysTime(Date(-4, 3, 31)); 3916 sysTime.roll!"months"(-49); 3917 assert(sysTime == SysTime(Date(-4, 3, 2))); 3918 sysTime.roll!"months"(49); 3919 assert(sysTime == SysTime(Date(-4, 4, 2))); 3920 } 3921 3922 { 3923 auto sysTime = SysTime(Date(-4, 3, 31)); 3924 sysTime.roll!"months"(-85); 3925 assert(sysTime == SysTime(Date(-4, 3, 2))); 3926 sysTime.roll!"months"(85); 3927 assert(sysTime == SysTime(Date(-4, 4, 2))); 3928 } 3929 3930 { 3931 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17)); 3932 sysTime.roll!"months"(-1); 3933 assert(sysTime == SysTime(DateTime(1, 12, 1, 0, 7, 9), hnsecs(17))); 3934 sysTime.roll!"months"(1); 3935 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17))); 3936 } 3937 3938 { 3939 auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), msecs(9)); 3940 sysTime.roll!"months"(-85); 3941 assert(sysTime == SysTime(DateTime(4, 3, 2, 12, 11, 10), msecs(9))); 3942 sysTime.roll!"months"(85); 3943 assert(sysTime == SysTime(DateTime(4, 4, 2, 12, 11, 10), msecs(9))); 3944 } 3945 3946 { 3947 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 3948 sysTime.roll!"months"(85); 3949 assert(sysTime == SysTime(DateTime(-3, 5, 1, 12, 11, 10), msecs(9))); 3950 sysTime.roll!"months"(-85); 3951 assert(sysTime == SysTime(DateTime(-3, 4, 1, 12, 11, 10), msecs(9))); 3952 } 3953 3954 { 3955 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 3956 sysTime.roll!"months"(85).roll!"months"(-83); 3957 assert(sysTime == SysTime(DateTime(-3, 6, 1, 12, 11, 10), msecs(9))); 3958 } 3959 3960 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 3961 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 3962 static assert(!__traits(compiles, cst.roll!"months"(4))); 3963 //static assert(!__traits(compiles, ist.roll!"months"(4))); 3964 } 3965 3966 // Test roll!"months"() with AllowDayOverflow.no 3967 @safe unittest 3968 { 3969 // Test A.D. 3970 { 3971 auto sysTime = SysTime(Date(1999, 7, 6)); 3972 sysTime.roll!"months"(3, AllowDayOverflow.no); 3973 assert(sysTime == SysTime(Date(1999, 10, 6))); 3974 sysTime.roll!"months"(-4, AllowDayOverflow.no); 3975 assert(sysTime == SysTime(Date(1999, 6, 6))); 3976 } 3977 3978 { 3979 auto sysTime = SysTime(Date(1999, 7, 6)); 3980 sysTime.roll!"months"(6, AllowDayOverflow.no); 3981 assert(sysTime == SysTime(Date(1999, 1, 6))); 3982 sysTime.roll!"months"(-6, AllowDayOverflow.no); 3983 assert(sysTime == SysTime(Date(1999, 7, 6))); 3984 } 3985 3986 { 3987 auto sysTime = SysTime(Date(1999, 7, 6)); 3988 sysTime.roll!"months"(27, AllowDayOverflow.no); 3989 assert(sysTime == SysTime(Date(1999, 10, 6))); 3990 sysTime.roll!"months"(-28, AllowDayOverflow.no); 3991 assert(sysTime == SysTime(Date(1999, 6, 6))); 3992 } 3993 3994 { 3995 auto sysTime = SysTime(Date(1999, 5, 31)); 3996 sysTime.roll!"months"(1, AllowDayOverflow.no); 3997 assert(sysTime == SysTime(Date(1999, 6, 30))); 3998 } 3999 4000 { 4001 auto sysTime = SysTime(Date(1999, 5, 31)); 4002 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4003 assert(sysTime == SysTime(Date(1999, 4, 30))); 4004 } 4005 4006 { 4007 auto sysTime = SysTime(Date(1999, 2, 28)); 4008 sysTime.roll!"months"(12, AllowDayOverflow.no); 4009 assert(sysTime == SysTime(Date(1999, 2, 28))); 4010 } 4011 4012 { 4013 auto sysTime = SysTime(Date(2000, 2, 29)); 4014 sysTime.roll!"months"(12, AllowDayOverflow.no); 4015 assert(sysTime == SysTime(Date(2000, 2, 29))); 4016 } 4017 4018 { 4019 auto sysTime = SysTime(Date(1999, 7, 31)); 4020 sysTime.roll!"months"(1, AllowDayOverflow.no); 4021 assert(sysTime == SysTime(Date(1999, 8, 31))); 4022 sysTime.roll!"months"(1, AllowDayOverflow.no); 4023 assert(sysTime == SysTime(Date(1999, 9, 30))); 4024 } 4025 4026 { 4027 auto sysTime = SysTime(Date(1998, 8, 31)); 4028 sysTime.roll!"months"(13, AllowDayOverflow.no); 4029 assert(sysTime == SysTime(Date(1998, 9, 30))); 4030 sysTime.roll!"months"(-13, AllowDayOverflow.no); 4031 assert(sysTime == SysTime(Date(1998, 8, 30))); 4032 } 4033 4034 { 4035 auto sysTime = SysTime(Date(1997, 12, 31)); 4036 sysTime.roll!"months"(13, AllowDayOverflow.no); 4037 assert(sysTime == SysTime(Date(1997, 1, 31))); 4038 sysTime.roll!"months"(-13, AllowDayOverflow.no); 4039 assert(sysTime == SysTime(Date(1997, 12, 31))); 4040 } 4041 4042 { 4043 auto sysTime = SysTime(Date(1997, 12, 31)); 4044 sysTime.roll!"months"(14, AllowDayOverflow.no); 4045 assert(sysTime == SysTime(Date(1997, 2, 28))); 4046 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4047 assert(sysTime == SysTime(Date(1997, 12, 28))); 4048 } 4049 4050 { 4051 auto sysTime = SysTime(Date(1998, 12, 31)); 4052 sysTime.roll!"months"(14, AllowDayOverflow.no); 4053 assert(sysTime == SysTime(Date(1998, 2, 28))); 4054 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4055 assert(sysTime == SysTime(Date(1998, 12, 28))); 4056 } 4057 4058 { 4059 auto sysTime = SysTime(Date(1999, 12, 31)); 4060 sysTime.roll!"months"(14, AllowDayOverflow.no); 4061 assert(sysTime == SysTime(Date(1999, 2, 28))); 4062 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4063 assert(sysTime == SysTime(Date(1999, 12, 28))); 4064 } 4065 4066 { 4067 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), usecs(5007)); 4068 sysTime.roll!"months"(3, AllowDayOverflow.no); 4069 assert(sysTime == SysTime(DateTime(1999, 10, 6, 12, 2, 7), usecs(5007))); 4070 sysTime.roll!"months"(-4, AllowDayOverflow.no); 4071 assert(sysTime == SysTime(DateTime(1999, 6, 6, 12, 2, 7), usecs(5007))); 4072 } 4073 4074 { 4075 auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), hnsecs(422202)); 4076 sysTime.roll!"months"(14, AllowDayOverflow.no); 4077 assert(sysTime == SysTime(DateTime(1998, 2, 28, 7, 7, 7), hnsecs(422202))); 4078 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4079 assert(sysTime == SysTime(DateTime(1998, 12, 28, 7, 7, 7), hnsecs(422202))); 4080 } 4081 4082 { 4083 auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), hnsecs(422202)); 4084 sysTime.roll!"months"(14, AllowDayOverflow.no); 4085 assert(sysTime == SysTime(DateTime(1999, 2, 28, 7, 7, 7), hnsecs(422202))); 4086 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4087 assert(sysTime == SysTime(DateTime(1999, 12, 28, 7, 7, 7), hnsecs(422202))); 4088 } 4089 4090 // Test B.C. 4091 { 4092 auto sysTime = SysTime(Date(-1999, 7, 6)); 4093 sysTime.roll!"months"(3, AllowDayOverflow.no); 4094 assert(sysTime == SysTime(Date(-1999, 10, 6))); 4095 sysTime.roll!"months"(-4, AllowDayOverflow.no); 4096 assert(sysTime == SysTime(Date(-1999, 6, 6))); 4097 } 4098 4099 { 4100 auto sysTime = SysTime(Date(-1999, 7, 6)); 4101 sysTime.roll!"months"(6, AllowDayOverflow.no); 4102 assert(sysTime == SysTime(Date(-1999, 1, 6))); 4103 sysTime.roll!"months"(-6, AllowDayOverflow.no); 4104 assert(sysTime == SysTime(Date(-1999, 7, 6))); 4105 } 4106 4107 { 4108 auto sysTime = SysTime(Date(-1999, 7, 6)); 4109 sysTime.roll!"months"(-27, AllowDayOverflow.no); 4110 assert(sysTime == SysTime(Date(-1999, 4, 6))); 4111 sysTime.roll!"months"(28, AllowDayOverflow.no); 4112 assert(sysTime == SysTime(Date(-1999, 8, 6))); 4113 } 4114 4115 { 4116 auto sysTime = SysTime(Date(-1999, 5, 31)); 4117 sysTime.roll!"months"(1, AllowDayOverflow.no); 4118 assert(sysTime == SysTime(Date(-1999, 6, 30))); 4119 } 4120 4121 { 4122 auto sysTime = SysTime(Date(-1999, 5, 31)); 4123 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4124 assert(sysTime == SysTime(Date(-1999, 4, 30))); 4125 } 4126 4127 { 4128 auto sysTime = SysTime(Date(-1999, 2, 28)); 4129 sysTime.roll!"months"(-12, AllowDayOverflow.no); 4130 assert(sysTime == SysTime(Date(-1999, 2, 28))); 4131 } 4132 4133 { 4134 auto sysTime = SysTime(Date(-2000, 2, 29)); 4135 sysTime.roll!"months"(-12, AllowDayOverflow.no); 4136 assert(sysTime == SysTime(Date(-2000, 2, 29))); 4137 } 4138 4139 { 4140 auto sysTime = SysTime(Date(-1999, 7, 31)); 4141 sysTime.roll!"months"(1, AllowDayOverflow.no); 4142 assert(sysTime == SysTime(Date(-1999, 8, 31))); 4143 sysTime.roll!"months"(1, AllowDayOverflow.no); 4144 assert(sysTime == SysTime(Date(-1999, 9, 30))); 4145 } 4146 4147 { 4148 auto sysTime = SysTime(Date(-1998, 8, 31)); 4149 sysTime.roll!"months"(13, AllowDayOverflow.no); 4150 assert(sysTime == SysTime(Date(-1998, 9, 30))); 4151 sysTime.roll!"months"(-13, AllowDayOverflow.no); 4152 assert(sysTime == SysTime(Date(-1998, 8, 30))); 4153 } 4154 4155 { 4156 auto sysTime = SysTime(Date(-1997, 12, 31)); 4157 sysTime.roll!"months"(13, AllowDayOverflow.no); 4158 assert(sysTime == SysTime(Date(-1997, 1, 31))); 4159 sysTime.roll!"months"(-13, AllowDayOverflow.no); 4160 assert(sysTime == SysTime(Date(-1997, 12, 31))); 4161 } 4162 4163 { 4164 auto sysTime = SysTime(Date(-1997, 12, 31)); 4165 sysTime.roll!"months"(14, AllowDayOverflow.no); 4166 assert(sysTime == SysTime(Date(-1997, 2, 28))); 4167 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4168 assert(sysTime == SysTime(Date(-1997, 12, 28))); 4169 } 4170 4171 { 4172 auto sysTime = SysTime(Date(-2002, 12, 31)); 4173 sysTime.roll!"months"(14, AllowDayOverflow.no); 4174 assert(sysTime == SysTime(Date(-2002, 2, 28))); 4175 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4176 assert(sysTime == SysTime(Date(-2002, 12, 28))); 4177 } 4178 4179 { 4180 auto sysTime = SysTime(Date(-2001, 12, 31)); 4181 sysTime.roll!"months"(14, AllowDayOverflow.no); 4182 assert(sysTime == SysTime(Date(-2001, 2, 28))); 4183 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4184 assert(sysTime == SysTime(Date(-2001, 12, 28))); 4185 } 4186 4187 { 4188 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), usecs(5007)); 4189 sysTime.roll!"months"(3, AllowDayOverflow.no); 4190 assert(sysTime == SysTime(DateTime(-1999, 10, 6, 12, 2, 7), usecs(5007))); 4191 sysTime.roll!"months"(-4, AllowDayOverflow.no); 4192 assert(sysTime == SysTime(DateTime(-1999, 6, 6, 12, 2, 7), usecs(5007))); 4193 } 4194 4195 { 4196 auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), hnsecs(422202)); 4197 sysTime.roll!"months"(14, AllowDayOverflow.no); 4198 assert(sysTime == SysTime(DateTime(-2002, 2, 28, 7, 7, 7), hnsecs(422202))); 4199 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4200 assert(sysTime == SysTime(DateTime(-2002, 12, 28, 7, 7, 7), hnsecs(422202))); 4201 } 4202 4203 { 4204 auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), hnsecs(422202)); 4205 sysTime.roll!"months"(14, AllowDayOverflow.no); 4206 assert(sysTime == SysTime(DateTime(-2001, 2, 28, 7, 7, 7), hnsecs(422202))); 4207 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4208 assert(sysTime == SysTime(DateTime(-2001, 12, 28, 7, 7, 7), hnsecs(422202))); 4209 } 4210 4211 // Test Both 4212 { 4213 auto sysTime = SysTime(Date(1, 1, 1)); 4214 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4215 assert(sysTime == SysTime(Date(1, 12, 1))); 4216 sysTime.roll!"months"(1, AllowDayOverflow.no); 4217 assert(sysTime == SysTime(Date(1, 1, 1))); 4218 } 4219 4220 { 4221 auto sysTime = SysTime(Date(4, 1, 1)); 4222 sysTime.roll!"months"(-48, AllowDayOverflow.no); 4223 assert(sysTime == SysTime(Date(4, 1, 1))); 4224 sysTime.roll!"months"(48, AllowDayOverflow.no); 4225 assert(sysTime == SysTime(Date(4, 1, 1))); 4226 } 4227 4228 { 4229 auto sysTime = SysTime(Date(4, 3, 31)); 4230 sysTime.roll!"months"(-49, AllowDayOverflow.no); 4231 assert(sysTime == SysTime(Date(4, 2, 29))); 4232 sysTime.roll!"months"(49, AllowDayOverflow.no); 4233 assert(sysTime == SysTime(Date(4, 3, 29))); 4234 } 4235 4236 { 4237 auto sysTime = SysTime(Date(4, 3, 31)); 4238 sysTime.roll!"months"(-85, AllowDayOverflow.no); 4239 assert(sysTime == SysTime(Date(4, 2, 29))); 4240 sysTime.roll!"months"(85, AllowDayOverflow.no); 4241 assert(sysTime == SysTime(Date(4, 3, 29))); 4242 } 4243 4244 { 4245 auto sysTime = SysTime(Date(-1, 1, 1)); 4246 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4247 assert(sysTime == SysTime(Date(-1, 12, 1))); 4248 sysTime.roll!"months"(1, AllowDayOverflow.no); 4249 assert(sysTime == SysTime(Date(-1, 1, 1))); 4250 } 4251 4252 { 4253 auto sysTime = SysTime(Date(-4, 1, 1)); 4254 sysTime.roll!"months"(-48, AllowDayOverflow.no); 4255 assert(sysTime == SysTime(Date(-4, 1, 1))); 4256 sysTime.roll!"months"(48, AllowDayOverflow.no); 4257 assert(sysTime == SysTime(Date(-4, 1, 1))); 4258 } 4259 4260 { 4261 auto sysTime = SysTime(Date(-4, 3, 31)); 4262 sysTime.roll!"months"(-49, AllowDayOverflow.no); 4263 assert(sysTime == SysTime(Date(-4, 2, 29))); 4264 sysTime.roll!"months"(49, AllowDayOverflow.no); 4265 assert(sysTime == SysTime(Date(-4, 3, 29))); 4266 } 4267 4268 { 4269 auto sysTime = SysTime(Date(-4, 3, 31)); 4270 sysTime.roll!"months"(-85, AllowDayOverflow.no); 4271 assert(sysTime == SysTime(Date(-4, 2, 29))); 4272 sysTime.roll!"months"(85, AllowDayOverflow.no); 4273 assert(sysTime == SysTime(Date(-4, 3, 29))); 4274 } 4275 4276 { 4277 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 4278 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4279 assert(sysTime == SysTime(DateTime(1, 12, 1, 0, 0, 0))); 4280 sysTime.roll!"months"(1, AllowDayOverflow.no); 4281 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 4282 } 4283 4284 { 4285 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 4286 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4287 assert(sysTime == SysTime(DateTime(1, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 4288 sysTime.roll!"months"(1, AllowDayOverflow.no); 4289 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 4290 } 4291 4292 { 4293 auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0)); 4294 sysTime.roll!"months"(1, AllowDayOverflow.no); 4295 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0))); 4296 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4297 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 4298 } 4299 4300 { 4301 auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)); 4302 sysTime.roll!"months"(1, AllowDayOverflow.no); 4303 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 4304 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4305 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 4306 } 4307 4308 { 4309 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17)); 4310 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4311 assert(sysTime == SysTime(DateTime(1, 12, 1, 0, 7, 9), hnsecs(17))); 4312 sysTime.roll!"months"(1, AllowDayOverflow.no); 4313 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17))); 4314 } 4315 4316 { 4317 auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), msecs(9)); 4318 sysTime.roll!"months"(-85, AllowDayOverflow.no); 4319 assert(sysTime == SysTime(DateTime(4, 2, 29, 12, 11, 10), msecs(9))); 4320 sysTime.roll!"months"(85, AllowDayOverflow.no); 4321 assert(sysTime == SysTime(DateTime(4, 3, 29, 12, 11, 10), msecs(9))); 4322 } 4323 4324 { 4325 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 4326 sysTime.roll!"months"(85, AllowDayOverflow.no); 4327 assert(sysTime == SysTime(DateTime(-3, 4, 30, 12, 11, 10), msecs(9))); 4328 sysTime.roll!"months"(-85, AllowDayOverflow.no); 4329 assert(sysTime == SysTime(DateTime(-3, 3, 30, 12, 11, 10), msecs(9))); 4330 } 4331 4332 { 4333 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 4334 sysTime.roll!"months"(85, AllowDayOverflow.no).roll!"months"(-83, AllowDayOverflow.no); 4335 assert(sysTime == SysTime(DateTime(-3, 5, 30, 12, 11, 10), msecs(9))); 4336 } 4337 } 4338 4339 4340 /++ 4341 Adds the given number of units to this $(LREF SysTime). A negative number 4342 will subtract. 4343 4344 The difference between rolling and adding is that rolling does not 4345 affect larger units. For instance, rolling a $(LREF SysTime) one 4346 year's worth of days gets the exact same $(LREF SysTime). 4347 4348 Accepted units are $(D "days"), $(D "minutes"), $(D "hours"), 4349 $(D "minutes"), $(D "seconds"), $(D "msecs"), $(D "usecs"), and 4350 $(D "hnsecs"). 4351 4352 Note that when rolling msecs, usecs or hnsecs, they all add up to a 4353 second. So, for example, rolling 1000 msecs is exactly the same as 4354 rolling 100,000 usecs. 4355 4356 Params: 4357 units = The units to add. 4358 value = The number of $(D_PARAM units) to add to this 4359 $(LREF SysTime). 4360 +/ 4361 ref SysTime roll(string units)(long value) @safe nothrow 4362 if (units == "days") 4363 { 4364 auto hnsecs = adjTime; 4365 auto gdays = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 4366 4367 if (hnsecs < 0) 4368 { 4369 hnsecs += convert!("hours", "hnsecs")(24); 4370 --gdays; 4371 } 4372 4373 auto date = Date(cast(int) gdays); 4374 date.roll!"days"(value); 4375 gdays = date.dayOfGregorianCal - 1; 4376 4377 if (gdays < 0) 4378 { 4379 hnsecs -= convert!("hours", "hnsecs")(24); 4380 ++gdays; 4381 } 4382 4383 immutable newDaysHNSecs = convert!("days", "hnsecs")(gdays); 4384 adjTime = newDaysHNSecs + hnsecs; 4385 return this; 4386 } 4387 4388 /// 4389 @safe unittest 4390 { 4391 import core.time : msecs, hnsecs; 4392 import std.datetime.date : DateTime; 4393 4394 auto st1 = SysTime(DateTime(2010, 1, 1, 11, 23, 12)); 4395 st1.roll!"days"(1); 4396 assert(st1 == SysTime(DateTime(2010, 1, 2, 11, 23, 12))); 4397 st1.roll!"days"(365); 4398 assert(st1 == SysTime(DateTime(2010, 1, 26, 11, 23, 12))); 4399 st1.roll!"days"(-32); 4400 assert(st1 == SysTime(DateTime(2010, 1, 25, 11, 23, 12))); 4401 4402 auto st2 = SysTime(DateTime(2010, 7, 4, 12, 0, 0)); 4403 st2.roll!"hours"(1); 4404 assert(st2 == SysTime(DateTime(2010, 7, 4, 13, 0, 0))); 4405 4406 auto st3 = SysTime(DateTime(2010, 2, 12, 12, 0, 0)); 4407 st3.roll!"hours"(-1); 4408 assert(st3 == SysTime(DateTime(2010, 2, 12, 11, 0, 0))); 4409 4410 auto st4 = SysTime(DateTime(2009, 12, 31, 0, 0, 0)); 4411 st4.roll!"minutes"(1); 4412 assert(st4 == SysTime(DateTime(2009, 12, 31, 0, 1, 0))); 4413 4414 auto st5 = SysTime(DateTime(2010, 1, 1, 0, 0, 0)); 4415 st5.roll!"minutes"(-1); 4416 assert(st5 == SysTime(DateTime(2010, 1, 1, 0, 59, 0))); 4417 4418 auto st6 = SysTime(DateTime(2009, 12, 31, 0, 0, 0)); 4419 st6.roll!"seconds"(1); 4420 assert(st6 == SysTime(DateTime(2009, 12, 31, 0, 0, 1))); 4421 4422 auto st7 = SysTime(DateTime(2010, 1, 1, 0, 0, 0)); 4423 st7.roll!"seconds"(-1); 4424 assert(st7 == SysTime(DateTime(2010, 1, 1, 0, 0, 59))); 4425 4426 auto dt = DateTime(2010, 1, 1, 0, 0, 0); 4427 auto st8 = SysTime(dt); 4428 st8.roll!"msecs"(1); 4429 assert(st8 == SysTime(dt, msecs(1))); 4430 4431 auto st9 = SysTime(dt); 4432 st9.roll!"msecs"(-1); 4433 assert(st9 == SysTime(dt, msecs(999))); 4434 4435 auto st10 = SysTime(dt); 4436 st10.roll!"hnsecs"(1); 4437 assert(st10 == SysTime(dt, hnsecs(1))); 4438 4439 auto st11 = SysTime(dt); 4440 st11.roll!"hnsecs"(-1); 4441 assert(st11 == SysTime(dt, hnsecs(9_999_999))); 4442 } 4443 4444 @safe unittest 4445 { 4446 // Test A.D. 4447 { 4448 auto sysTime = SysTime(Date(1999, 2, 28)); 4449 sysTime.roll!"days"(1); 4450 assert(sysTime == SysTime(Date(1999, 2, 1))); 4451 sysTime.roll!"days"(-1); 4452 assert(sysTime == SysTime(Date(1999, 2, 28))); 4453 } 4454 4455 { 4456 auto sysTime = SysTime(Date(2000, 2, 28)); 4457 sysTime.roll!"days"(1); 4458 assert(sysTime == SysTime(Date(2000, 2, 29))); 4459 sysTime.roll!"days"(1); 4460 assert(sysTime == SysTime(Date(2000, 2, 1))); 4461 sysTime.roll!"days"(-1); 4462 assert(sysTime == SysTime(Date(2000, 2, 29))); 4463 } 4464 4465 { 4466 auto sysTime = SysTime(Date(1999, 6, 30)); 4467 sysTime.roll!"days"(1); 4468 assert(sysTime == SysTime(Date(1999, 6, 1))); 4469 sysTime.roll!"days"(-1); 4470 assert(sysTime == SysTime(Date(1999, 6, 30))); 4471 } 4472 4473 { 4474 auto sysTime = SysTime(Date(1999, 7, 31)); 4475 sysTime.roll!"days"(1); 4476 assert(sysTime == SysTime(Date(1999, 7, 1))); 4477 sysTime.roll!"days"(-1); 4478 assert(sysTime == SysTime(Date(1999, 7, 31))); 4479 } 4480 4481 { 4482 auto sysTime = SysTime(Date(1999, 1, 1)); 4483 sysTime.roll!"days"(-1); 4484 assert(sysTime == SysTime(Date(1999, 1, 31))); 4485 sysTime.roll!"days"(1); 4486 assert(sysTime == SysTime(Date(1999, 1, 1))); 4487 } 4488 4489 { 4490 auto sysTime = SysTime(Date(1999, 7, 6)); 4491 sysTime.roll!"days"(9); 4492 assert(sysTime == SysTime(Date(1999, 7, 15))); 4493 sysTime.roll!"days"(-11); 4494 assert(sysTime == SysTime(Date(1999, 7, 4))); 4495 sysTime.roll!"days"(30); 4496 assert(sysTime == SysTime(Date(1999, 7, 3))); 4497 sysTime.roll!"days"(-3); 4498 assert(sysTime == SysTime(Date(1999, 7, 31))); 4499 } 4500 4501 { 4502 auto sysTime = SysTime(Date(1999, 7, 6)); 4503 sysTime.roll!"days"(365); 4504 assert(sysTime == SysTime(Date(1999, 7, 30))); 4505 sysTime.roll!"days"(-365); 4506 assert(sysTime == SysTime(Date(1999, 7, 6))); 4507 sysTime.roll!"days"(366); 4508 assert(sysTime == SysTime(Date(1999, 7, 31))); 4509 sysTime.roll!"days"(730); 4510 assert(sysTime == SysTime(Date(1999, 7, 17))); 4511 sysTime.roll!"days"(-1096); 4512 assert(sysTime == SysTime(Date(1999, 7, 6))); 4513 } 4514 4515 { 4516 auto sysTime = SysTime(Date(1999, 2, 6)); 4517 sysTime.roll!"days"(365); 4518 assert(sysTime == SysTime(Date(1999, 2, 7))); 4519 sysTime.roll!"days"(-365); 4520 assert(sysTime == SysTime(Date(1999, 2, 6))); 4521 sysTime.roll!"days"(366); 4522 assert(sysTime == SysTime(Date(1999, 2, 8))); 4523 sysTime.roll!"days"(730); 4524 assert(sysTime == SysTime(Date(1999, 2, 10))); 4525 sysTime.roll!"days"(-1096); 4526 assert(sysTime == SysTime(Date(1999, 2, 6))); 4527 } 4528 4529 { 4530 auto sysTime = SysTime(DateTime(1999, 2, 28, 7, 9, 2), usecs(234578)); 4531 sysTime.roll!"days"(1); 4532 assert(sysTime == SysTime(DateTime(1999, 2, 1, 7, 9, 2), usecs(234578))); 4533 sysTime.roll!"days"(-1); 4534 assert(sysTime == SysTime(DateTime(1999, 2, 28, 7, 9, 2), usecs(234578))); 4535 } 4536 4537 { 4538 auto sysTime = SysTime(DateTime(1999, 7, 6, 7, 9, 2), usecs(234578)); 4539 sysTime.roll!"days"(9); 4540 assert(sysTime == SysTime(DateTime(1999, 7, 15, 7, 9, 2), usecs(234578))); 4541 sysTime.roll!"days"(-11); 4542 assert(sysTime == SysTime(DateTime(1999, 7, 4, 7, 9, 2), usecs(234578))); 4543 sysTime.roll!"days"(30); 4544 assert(sysTime == SysTime(DateTime(1999, 7, 3, 7, 9, 2), usecs(234578))); 4545 sysTime.roll!"days"(-3); 4546 assert(sysTime == SysTime(DateTime(1999, 7, 31, 7, 9, 2), usecs(234578))); 4547 } 4548 4549 // Test B.C. 4550 { 4551 auto sysTime = SysTime(Date(-1999, 2, 28)); 4552 sysTime.roll!"days"(1); 4553 assert(sysTime == SysTime(Date(-1999, 2, 1))); 4554 sysTime.roll!"days"(-1); 4555 assert(sysTime == SysTime(Date(-1999, 2, 28))); 4556 } 4557 4558 { 4559 auto sysTime = SysTime(Date(-2000, 2, 28)); 4560 sysTime.roll!"days"(1); 4561 assert(sysTime == SysTime(Date(-2000, 2, 29))); 4562 sysTime.roll!"days"(1); 4563 assert(sysTime == SysTime(Date(-2000, 2, 1))); 4564 sysTime.roll!"days"(-1); 4565 assert(sysTime == SysTime(Date(-2000, 2, 29))); 4566 } 4567 4568 { 4569 auto sysTime = SysTime(Date(-1999, 6, 30)); 4570 sysTime.roll!"days"(1); 4571 assert(sysTime == SysTime(Date(-1999, 6, 1))); 4572 sysTime.roll!"days"(-1); 4573 assert(sysTime == SysTime(Date(-1999, 6, 30))); 4574 } 4575 4576 { 4577 auto sysTime = SysTime(Date(-1999, 7, 31)); 4578 sysTime.roll!"days"(1); 4579 assert(sysTime == SysTime(Date(-1999, 7, 1))); 4580 sysTime.roll!"days"(-1); 4581 assert(sysTime == SysTime(Date(-1999, 7, 31))); 4582 } 4583 4584 { 4585 auto sysTime = SysTime(Date(-1999, 1, 1)); 4586 sysTime.roll!"days"(-1); 4587 assert(sysTime == SysTime(Date(-1999, 1, 31))); 4588 sysTime.roll!"days"(1); 4589 assert(sysTime == SysTime(Date(-1999, 1, 1))); 4590 } 4591 4592 { 4593 auto sysTime = SysTime(Date(-1999, 7, 6)); 4594 sysTime.roll!"days"(9); 4595 assert(sysTime == SysTime(Date(-1999, 7, 15))); 4596 sysTime.roll!"days"(-11); 4597 assert(sysTime == SysTime(Date(-1999, 7, 4))); 4598 sysTime.roll!"days"(30); 4599 assert(sysTime == SysTime(Date(-1999, 7, 3))); 4600 sysTime.roll!"days"(-3); 4601 assert(sysTime == SysTime(Date(-1999, 7, 31))); 4602 } 4603 4604 { 4605 auto sysTime = SysTime(Date(-1999, 7, 6)); 4606 sysTime.roll!"days"(365); 4607 assert(sysTime == SysTime(Date(-1999, 7, 30))); 4608 sysTime.roll!"days"(-365); 4609 assert(sysTime == SysTime(Date(-1999, 7, 6))); 4610 sysTime.roll!"days"(366); 4611 assert(sysTime == SysTime(Date(-1999, 7, 31))); 4612 sysTime.roll!"days"(730); 4613 assert(sysTime == SysTime(Date(-1999, 7, 17))); 4614 sysTime.roll!"days"(-1096); 4615 assert(sysTime == SysTime(Date(-1999, 7, 6))); 4616 } 4617 4618 { 4619 auto sysTime = SysTime(DateTime(-1999, 2, 28, 7, 9, 2), usecs(234578)); 4620 sysTime.roll!"days"(1); 4621 assert(sysTime == SysTime(DateTime(-1999, 2, 1, 7, 9, 2), usecs(234578))); 4622 sysTime.roll!"days"(-1); 4623 assert(sysTime == SysTime(DateTime(-1999, 2, 28, 7, 9, 2), usecs(234578))); 4624 } 4625 4626 { 4627 auto sysTime = SysTime(DateTime(-1999, 7, 6, 7, 9, 2), usecs(234578)); 4628 sysTime.roll!"days"(9); 4629 assert(sysTime == SysTime(DateTime(-1999, 7, 15, 7, 9, 2), usecs(234578))); 4630 sysTime.roll!"days"(-11); 4631 assert(sysTime == SysTime(DateTime(-1999, 7, 4, 7, 9, 2), usecs(234578))); 4632 sysTime.roll!"days"(30); 4633 assert(sysTime == SysTime(DateTime(-1999, 7, 3, 7, 9, 2), usecs(234578))); 4634 sysTime.roll!"days"(-3); 4635 } 4636 4637 // Test Both 4638 { 4639 auto sysTime = SysTime(Date(1, 7, 6)); 4640 sysTime.roll!"days"(-365); 4641 assert(sysTime == SysTime(Date(1, 7, 13))); 4642 sysTime.roll!"days"(365); 4643 assert(sysTime == SysTime(Date(1, 7, 6))); 4644 sysTime.roll!"days"(-731); 4645 assert(sysTime == SysTime(Date(1, 7, 19))); 4646 sysTime.roll!"days"(730); 4647 assert(sysTime == SysTime(Date(1, 7, 5))); 4648 } 4649 4650 { 4651 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 4652 sysTime.roll!"days"(-1); 4653 assert(sysTime == SysTime(DateTime(1, 1, 31, 0, 0, 0))); 4654 sysTime.roll!"days"(1); 4655 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 4656 } 4657 4658 { 4659 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 4660 sysTime.roll!"days"(-1); 4661 assert(sysTime == SysTime(DateTime(1, 1, 31, 23, 59, 59), hnsecs(9_999_999))); 4662 sysTime.roll!"days"(1); 4663 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 4664 } 4665 4666 { 4667 auto sysTime = SysTime(DateTime(0, 12, 31, 0, 0, 0)); 4668 sysTime.roll!"days"(1); 4669 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 4670 sysTime.roll!"days"(-1); 4671 assert(sysTime == SysTime(DateTime(0, 12, 31, 0, 0, 0))); 4672 } 4673 4674 { 4675 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 4676 sysTime.roll!"days"(1); 4677 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 4678 sysTime.roll!"days"(-1); 4679 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 4680 } 4681 4682 { 4683 auto sysTime = SysTime(DateTime(1, 7, 6, 13, 13, 9), msecs(22)); 4684 sysTime.roll!"days"(-365); 4685 assert(sysTime == SysTime(DateTime(1, 7, 13, 13, 13, 9), msecs(22))); 4686 sysTime.roll!"days"(365); 4687 assert(sysTime == SysTime(DateTime(1, 7, 6, 13, 13, 9), msecs(22))); 4688 sysTime.roll!"days"(-731); 4689 assert(sysTime == SysTime(DateTime(1, 7, 19, 13, 13, 9), msecs(22))); 4690 sysTime.roll!"days"(730); 4691 assert(sysTime == SysTime(DateTime(1, 7, 5, 13, 13, 9), msecs(22))); 4692 } 4693 4694 { 4695 auto sysTime = SysTime(DateTime(0, 7, 6, 13, 13, 9), msecs(22)); 4696 sysTime.roll!"days"(-365); 4697 assert(sysTime == SysTime(DateTime(0, 7, 13, 13, 13, 9), msecs(22))); 4698 sysTime.roll!"days"(365); 4699 assert(sysTime == SysTime(DateTime(0, 7, 6, 13, 13, 9), msecs(22))); 4700 sysTime.roll!"days"(-731); 4701 assert(sysTime == SysTime(DateTime(0, 7, 19, 13, 13, 9), msecs(22))); 4702 sysTime.roll!"days"(730); 4703 assert(sysTime == SysTime(DateTime(0, 7, 5, 13, 13, 9), msecs(22))); 4704 } 4705 4706 { 4707 auto sysTime = SysTime(DateTime(0, 7, 6, 13, 13, 9), msecs(22)); 4708 sysTime.roll!"days"(-365).roll!"days"(362).roll!"days"(-12).roll!"days"(730); 4709 assert(sysTime == SysTime(DateTime(0, 7, 8, 13, 13, 9), msecs(22))); 4710 } 4711 4712 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 4713 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 4714 static assert(!__traits(compiles, cst.roll!"days"(4))); 4715 //static assert(!__traits(compiles, ist.roll!"days"(4))); 4716 } 4717 4718 4719 // Shares documentation with "days" version. 4720 ref SysTime roll(string units)(long value) @safe nothrow 4721 if (units == "hours" || units == "minutes" || units == "seconds") 4722 { 4723 try 4724 { 4725 auto hnsecs = adjTime; 4726 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 4727 4728 if (hnsecs < 0) 4729 { 4730 hnsecs += convert!("hours", "hnsecs")(24); 4731 --days; 4732 } 4733 4734 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 4735 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 4736 immutable second = splitUnitsFromHNSecs!"seconds"(hnsecs); 4737 4738 auto dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour, 4739 cast(int) minute, cast(int) second)); 4740 dateTime.roll!units(value); 4741 --days; 4742 4743 hnsecs += convert!("hours", "hnsecs")(dateTime.hour); 4744 hnsecs += convert!("minutes", "hnsecs")(dateTime.minute); 4745 hnsecs += convert!("seconds", "hnsecs")(dateTime.second); 4746 4747 if (days < 0) 4748 { 4749 hnsecs -= convert!("hours", "hnsecs")(24); 4750 ++days; 4751 } 4752 4753 immutable newDaysHNSecs = convert!("days", "hnsecs")(days); 4754 adjTime = newDaysHNSecs + hnsecs; 4755 return this; 4756 } 4757 catch (Exception e) 4758 assert(0, "Either DateTime's constructor or TimeOfDay's constructor threw."); 4759 } 4760 4761 // Test roll!"hours"(). 4762 @safe unittest 4763 { 4764 static void testST(SysTime orig, int hours, in SysTime expected, size_t line = __LINE__) 4765 { 4766 orig.roll!"hours"(hours); 4767 if (orig != expected) 4768 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 4769 } 4770 4771 // Test A.D. 4772 immutable d = msecs(45); 4773 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), d); 4774 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 4775 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 13, 30, 33), d)); 4776 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 14, 30, 33), d)); 4777 testST(beforeAD, 3, SysTime(DateTime(1999, 7, 6, 15, 30, 33), d)); 4778 testST(beforeAD, 4, SysTime(DateTime(1999, 7, 6, 16, 30, 33), d)); 4779 testST(beforeAD, 5, SysTime(DateTime(1999, 7, 6, 17, 30, 33), d)); 4780 testST(beforeAD, 6, SysTime(DateTime(1999, 7, 6, 18, 30, 33), d)); 4781 testST(beforeAD, 7, SysTime(DateTime(1999, 7, 6, 19, 30, 33), d)); 4782 testST(beforeAD, 8, SysTime(DateTime(1999, 7, 6, 20, 30, 33), d)); 4783 testST(beforeAD, 9, SysTime(DateTime(1999, 7, 6, 21, 30, 33), d)); 4784 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 22, 30, 33), d)); 4785 testST(beforeAD, 11, SysTime(DateTime(1999, 7, 6, 23, 30, 33), d)); 4786 testST(beforeAD, 12, SysTime(DateTime(1999, 7, 6, 0, 30, 33), d)); 4787 testST(beforeAD, 13, SysTime(DateTime(1999, 7, 6, 1, 30, 33), d)); 4788 testST(beforeAD, 14, SysTime(DateTime(1999, 7, 6, 2, 30, 33), d)); 4789 testST(beforeAD, 15, SysTime(DateTime(1999, 7, 6, 3, 30, 33), d)); 4790 testST(beforeAD, 16, SysTime(DateTime(1999, 7, 6, 4, 30, 33), d)); 4791 testST(beforeAD, 17, SysTime(DateTime(1999, 7, 6, 5, 30, 33), d)); 4792 testST(beforeAD, 18, SysTime(DateTime(1999, 7, 6, 6, 30, 33), d)); 4793 testST(beforeAD, 19, SysTime(DateTime(1999, 7, 6, 7, 30, 33), d)); 4794 testST(beforeAD, 20, SysTime(DateTime(1999, 7, 6, 8, 30, 33), d)); 4795 testST(beforeAD, 21, SysTime(DateTime(1999, 7, 6, 9, 30, 33), d)); 4796 testST(beforeAD, 22, SysTime(DateTime(1999, 7, 6, 10, 30, 33), d)); 4797 testST(beforeAD, 23, SysTime(DateTime(1999, 7, 6, 11, 30, 33), d)); 4798 testST(beforeAD, 24, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 4799 testST(beforeAD, 25, SysTime(DateTime(1999, 7, 6, 13, 30, 33), d)); 4800 testST(beforeAD, 50, SysTime(DateTime(1999, 7, 6, 14, 30, 33), d)); 4801 testST(beforeAD, 10_000, SysTime(DateTime(1999, 7, 6, 4, 30, 33), d)); 4802 4803 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 11, 30, 33), d)); 4804 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 10, 30, 33), d)); 4805 testST(beforeAD, -3, SysTime(DateTime(1999, 7, 6, 9, 30, 33), d)); 4806 testST(beforeAD, -4, SysTime(DateTime(1999, 7, 6, 8, 30, 33), d)); 4807 testST(beforeAD, -5, SysTime(DateTime(1999, 7, 6, 7, 30, 33), d)); 4808 testST(beforeAD, -6, SysTime(DateTime(1999, 7, 6, 6, 30, 33), d)); 4809 testST(beforeAD, -7, SysTime(DateTime(1999, 7, 6, 5, 30, 33), d)); 4810 testST(beforeAD, -8, SysTime(DateTime(1999, 7, 6, 4, 30, 33), d)); 4811 testST(beforeAD, -9, SysTime(DateTime(1999, 7, 6, 3, 30, 33), d)); 4812 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 2, 30, 33), d)); 4813 testST(beforeAD, -11, SysTime(DateTime(1999, 7, 6, 1, 30, 33), d)); 4814 testST(beforeAD, -12, SysTime(DateTime(1999, 7, 6, 0, 30, 33), d)); 4815 testST(beforeAD, -13, SysTime(DateTime(1999, 7, 6, 23, 30, 33), d)); 4816 testST(beforeAD, -14, SysTime(DateTime(1999, 7, 6, 22, 30, 33), d)); 4817 testST(beforeAD, -15, SysTime(DateTime(1999, 7, 6, 21, 30, 33), d)); 4818 testST(beforeAD, -16, SysTime(DateTime(1999, 7, 6, 20, 30, 33), d)); 4819 testST(beforeAD, -17, SysTime(DateTime(1999, 7, 6, 19, 30, 33), d)); 4820 testST(beforeAD, -18, SysTime(DateTime(1999, 7, 6, 18, 30, 33), d)); 4821 testST(beforeAD, -19, SysTime(DateTime(1999, 7, 6, 17, 30, 33), d)); 4822 testST(beforeAD, -20, SysTime(DateTime(1999, 7, 6, 16, 30, 33), d)); 4823 testST(beforeAD, -21, SysTime(DateTime(1999, 7, 6, 15, 30, 33), d)); 4824 testST(beforeAD, -22, SysTime(DateTime(1999, 7, 6, 14, 30, 33), d)); 4825 testST(beforeAD, -23, SysTime(DateTime(1999, 7, 6, 13, 30, 33), d)); 4826 testST(beforeAD, -24, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 4827 testST(beforeAD, -25, SysTime(DateTime(1999, 7, 6, 11, 30, 33), d)); 4828 testST(beforeAD, -50, SysTime(DateTime(1999, 7, 6, 10, 30, 33), d)); 4829 testST(beforeAD, -10_000, SysTime(DateTime(1999, 7, 6, 20, 30, 33), d)); 4830 4831 testST(SysTime(DateTime(1999, 7, 6, 0, 30, 33), d), 1, SysTime(DateTime(1999, 7, 6, 1, 30, 33), d)); 4832 testST(SysTime(DateTime(1999, 7, 6, 0, 30, 33), d), 0, SysTime(DateTime(1999, 7, 6, 0, 30, 33), d)); 4833 testST(SysTime(DateTime(1999, 7, 6, 0, 30, 33), d), -1, SysTime(DateTime(1999, 7, 6, 23, 30, 33), d)); 4834 4835 testST(SysTime(DateTime(1999, 7, 6, 23, 30, 33), d), 1, SysTime(DateTime(1999, 7, 6, 0, 30, 33), d)); 4836 testST(SysTime(DateTime(1999, 7, 6, 23, 30, 33), d), 0, SysTime(DateTime(1999, 7, 6, 23, 30, 33), d)); 4837 testST(SysTime(DateTime(1999, 7, 6, 23, 30, 33), d), -1, SysTime(DateTime(1999, 7, 6, 22, 30, 33), d)); 4838 4839 testST(SysTime(DateTime(1999, 7, 31, 23, 30, 33), d), 1, SysTime(DateTime(1999, 7, 31, 0, 30, 33), d)); 4840 testST(SysTime(DateTime(1999, 8, 1, 0, 30, 33), d), -1, SysTime(DateTime(1999, 8, 1, 23, 30, 33), d)); 4841 4842 testST(SysTime(DateTime(1999, 12, 31, 23, 30, 33), d), 1, SysTime(DateTime(1999, 12, 31, 0, 30, 33), d)); 4843 testST(SysTime(DateTime(2000, 1, 1, 0, 30, 33), d), -1, SysTime(DateTime(2000, 1, 1, 23, 30, 33), d)); 4844 4845 testST(SysTime(DateTime(1999, 2, 28, 23, 30, 33), d), 25, SysTime(DateTime(1999, 2, 28, 0, 30, 33), d)); 4846 testST(SysTime(DateTime(1999, 3, 2, 0, 30, 33), d), -25, SysTime(DateTime(1999, 3, 2, 23, 30, 33), d)); 4847 4848 testST(SysTime(DateTime(2000, 2, 28, 23, 30, 33), d), 25, SysTime(DateTime(2000, 2, 28, 0, 30, 33), d)); 4849 testST(SysTime(DateTime(2000, 3, 1, 0, 30, 33), d), -25, SysTime(DateTime(2000, 3, 1, 23, 30, 33), d)); 4850 4851 // Test B.C. 4852 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d); 4853 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 4854 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), d)); 4855 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 14, 30, 33), d)); 4856 testST(beforeBC, 3, SysTime(DateTime(-1999, 7, 6, 15, 30, 33), d)); 4857 testST(beforeBC, 4, SysTime(DateTime(-1999, 7, 6, 16, 30, 33), d)); 4858 testST(beforeBC, 5, SysTime(DateTime(-1999, 7, 6, 17, 30, 33), d)); 4859 testST(beforeBC, 6, SysTime(DateTime(-1999, 7, 6, 18, 30, 33), d)); 4860 testST(beforeBC, 7, SysTime(DateTime(-1999, 7, 6, 19, 30, 33), d)); 4861 testST(beforeBC, 8, SysTime(DateTime(-1999, 7, 6, 20, 30, 33), d)); 4862 testST(beforeBC, 9, SysTime(DateTime(-1999, 7, 6, 21, 30, 33), d)); 4863 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 22, 30, 33), d)); 4864 testST(beforeBC, 11, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d)); 4865 testST(beforeBC, 12, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d)); 4866 testST(beforeBC, 13, SysTime(DateTime(-1999, 7, 6, 1, 30, 33), d)); 4867 testST(beforeBC, 14, SysTime(DateTime(-1999, 7, 6, 2, 30, 33), d)); 4868 testST(beforeBC, 15, SysTime(DateTime(-1999, 7, 6, 3, 30, 33), d)); 4869 testST(beforeBC, 16, SysTime(DateTime(-1999, 7, 6, 4, 30, 33), d)); 4870 testST(beforeBC, 17, SysTime(DateTime(-1999, 7, 6, 5, 30, 33), d)); 4871 testST(beforeBC, 18, SysTime(DateTime(-1999, 7, 6, 6, 30, 33), d)); 4872 testST(beforeBC, 19, SysTime(DateTime(-1999, 7, 6, 7, 30, 33), d)); 4873 testST(beforeBC, 20, SysTime(DateTime(-1999, 7, 6, 8, 30, 33), d)); 4874 testST(beforeBC, 21, SysTime(DateTime(-1999, 7, 6, 9, 30, 33), d)); 4875 testST(beforeBC, 22, SysTime(DateTime(-1999, 7, 6, 10, 30, 33), d)); 4876 testST(beforeBC, 23, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), d)); 4877 testST(beforeBC, 24, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 4878 testST(beforeBC, 25, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), d)); 4879 testST(beforeBC, 50, SysTime(DateTime(-1999, 7, 6, 14, 30, 33), d)); 4880 testST(beforeBC, 10_000, SysTime(DateTime(-1999, 7, 6, 4, 30, 33), d)); 4881 4882 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), d)); 4883 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 10, 30, 33), d)); 4884 testST(beforeBC, -3, SysTime(DateTime(-1999, 7, 6, 9, 30, 33), d)); 4885 testST(beforeBC, -4, SysTime(DateTime(-1999, 7, 6, 8, 30, 33), d)); 4886 testST(beforeBC, -5, SysTime(DateTime(-1999, 7, 6, 7, 30, 33), d)); 4887 testST(beforeBC, -6, SysTime(DateTime(-1999, 7, 6, 6, 30, 33), d)); 4888 testST(beforeBC, -7, SysTime(DateTime(-1999, 7, 6, 5, 30, 33), d)); 4889 testST(beforeBC, -8, SysTime(DateTime(-1999, 7, 6, 4, 30, 33), d)); 4890 testST(beforeBC, -9, SysTime(DateTime(-1999, 7, 6, 3, 30, 33), d)); 4891 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 2, 30, 33), d)); 4892 testST(beforeBC, -11, SysTime(DateTime(-1999, 7, 6, 1, 30, 33), d)); 4893 testST(beforeBC, -12, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d)); 4894 testST(beforeBC, -13, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d)); 4895 testST(beforeBC, -14, SysTime(DateTime(-1999, 7, 6, 22, 30, 33), d)); 4896 testST(beforeBC, -15, SysTime(DateTime(-1999, 7, 6, 21, 30, 33), d)); 4897 testST(beforeBC, -16, SysTime(DateTime(-1999, 7, 6, 20, 30, 33), d)); 4898 testST(beforeBC, -17, SysTime(DateTime(-1999, 7, 6, 19, 30, 33), d)); 4899 testST(beforeBC, -18, SysTime(DateTime(-1999, 7, 6, 18, 30, 33), d)); 4900 testST(beforeBC, -19, SysTime(DateTime(-1999, 7, 6, 17, 30, 33), d)); 4901 testST(beforeBC, -20, SysTime(DateTime(-1999, 7, 6, 16, 30, 33), d)); 4902 testST(beforeBC, -21, SysTime(DateTime(-1999, 7, 6, 15, 30, 33), d)); 4903 testST(beforeBC, -22, SysTime(DateTime(-1999, 7, 6, 14, 30, 33), d)); 4904 testST(beforeBC, -23, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), d)); 4905 testST(beforeBC, -24, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 4906 testST(beforeBC, -25, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), d)); 4907 testST(beforeBC, -50, SysTime(DateTime(-1999, 7, 6, 10, 30, 33), d)); 4908 testST(beforeBC, -10_000, SysTime(DateTime(-1999, 7, 6, 20, 30, 33), d)); 4909 4910 testST(SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 1, 30, 33), d)); 4911 testST(SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d)); 4912 testST(SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d)); 4913 4914 testST(SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d)); 4915 testST(SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d)); 4916 testST(SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 22, 30, 33), d)); 4917 4918 testST(SysTime(DateTime(-1999, 7, 31, 23, 30, 33), d), 1, SysTime(DateTime(-1999, 7, 31, 0, 30, 33), d)); 4919 testST(SysTime(DateTime(-1999, 8, 1, 0, 30, 33), d), -1, SysTime(DateTime(-1999, 8, 1, 23, 30, 33), d)); 4920 4921 testST(SysTime(DateTime(-2001, 12, 31, 23, 30, 33), d), 1, SysTime(DateTime(-2001, 12, 31, 0, 30, 33), d)); 4922 testST(SysTime(DateTime(-2000, 1, 1, 0, 30, 33), d), -1, SysTime(DateTime(-2000, 1, 1, 23, 30, 33), d)); 4923 4924 testST(SysTime(DateTime(-2001, 2, 28, 23, 30, 33), d), 25, SysTime(DateTime(-2001, 2, 28, 0, 30, 33), d)); 4925 testST(SysTime(DateTime(-2001, 3, 2, 0, 30, 33), d), -25, SysTime(DateTime(-2001, 3, 2, 23, 30, 33), d)); 4926 4927 testST(SysTime(DateTime(-2000, 2, 28, 23, 30, 33), d), 25, SysTime(DateTime(-2000, 2, 28, 0, 30, 33), d)); 4928 testST(SysTime(DateTime(-2000, 3, 1, 0, 30, 33), d), -25, SysTime(DateTime(-2000, 3, 1, 23, 30, 33), d)); 4929 4930 // Test Both 4931 testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 17_546, SysTime(DateTime(-1, 1, 1, 13, 30, 33), d)); 4932 testST(SysTime(DateTime(1, 1, 1, 13, 30, 33), d), -17_546, SysTime(DateTime(1, 1, 1, 11, 30, 33), d)); 4933 4934 { 4935 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 4936 sysTime.roll!"hours"(-1); 4937 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 0, 0))); 4938 sysTime.roll!"hours"(1); 4939 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 4940 } 4941 4942 { 4943 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 59, 59), hnsecs(9_999_999)); 4944 sysTime.roll!"hours"(-1); 4945 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 4946 sysTime.roll!"hours"(1); 4947 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 59, 59), hnsecs(9_999_999))); 4948 } 4949 4950 { 4951 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 0, 0)); 4952 sysTime.roll!"hours"(1); 4953 assert(sysTime == SysTime(DateTime(0, 12, 31, 0, 0, 0))); 4954 sysTime.roll!"hours"(-1); 4955 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 0, 0))); 4956 } 4957 4958 { 4959 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 4960 sysTime.roll!"hours"(1); 4961 assert(sysTime == SysTime(DateTime(0, 12, 31, 0, 59, 59), hnsecs(9_999_999))); 4962 sysTime.roll!"hours"(-1); 4963 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 4964 } 4965 4966 { 4967 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 4968 sysTime.roll!"hours"(1).roll!"hours"(-67); 4969 assert(sysTime == SysTime(DateTime(0, 12, 31, 5, 59, 59), hnsecs(9_999_999))); 4970 } 4971 4972 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 4973 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 4974 static assert(!__traits(compiles, cst.roll!"hours"(4))); 4975 //static assert(!__traits(compiles, ist.roll!"hours"(4))); 4976 } 4977 4978 // Test roll!"minutes"(). 4979 @safe unittest 4980 { 4981 static void testST(SysTime orig, int minutes, in SysTime expected, size_t line = __LINE__) 4982 { 4983 orig.roll!"minutes"(minutes); 4984 if (orig != expected) 4985 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 4986 } 4987 4988 // Test A.D. 4989 immutable d = usecs(7203); 4990 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), d); 4991 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 4992 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 31, 33), d)); 4993 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 32, 33), d)); 4994 testST(beforeAD, 3, SysTime(DateTime(1999, 7, 6, 12, 33, 33), d)); 4995 testST(beforeAD, 4, SysTime(DateTime(1999, 7, 6, 12, 34, 33), d)); 4996 testST(beforeAD, 5, SysTime(DateTime(1999, 7, 6, 12, 35, 33), d)); 4997 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 40, 33), d)); 4998 testST(beforeAD, 15, SysTime(DateTime(1999, 7, 6, 12, 45, 33), d)); 4999 testST(beforeAD, 29, SysTime(DateTime(1999, 7, 6, 12, 59, 33), d)); 5000 testST(beforeAD, 30, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5001 testST(beforeAD, 45, SysTime(DateTime(1999, 7, 6, 12, 15, 33), d)); 5002 testST(beforeAD, 60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5003 testST(beforeAD, 75, SysTime(DateTime(1999, 7, 6, 12, 45, 33), d)); 5004 testST(beforeAD, 90, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5005 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 10, 33), d)); 5006 5007 testST(beforeAD, 689, SysTime(DateTime(1999, 7, 6, 12, 59, 33), d)); 5008 testST(beforeAD, 690, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5009 testST(beforeAD, 691, SysTime(DateTime(1999, 7, 6, 12, 1, 33), d)); 5010 testST(beforeAD, 960, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5011 testST(beforeAD, 1439, SysTime(DateTime(1999, 7, 6, 12, 29, 33), d)); 5012 testST(beforeAD, 1440, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5013 testST(beforeAD, 1441, SysTime(DateTime(1999, 7, 6, 12, 31, 33), d)); 5014 testST(beforeAD, 2880, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5015 5016 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 29, 33), d)); 5017 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 28, 33), d)); 5018 testST(beforeAD, -3, SysTime(DateTime(1999, 7, 6, 12, 27, 33), d)); 5019 testST(beforeAD, -4, SysTime(DateTime(1999, 7, 6, 12, 26, 33), d)); 5020 testST(beforeAD, -5, SysTime(DateTime(1999, 7, 6, 12, 25, 33), d)); 5021 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 20, 33), d)); 5022 testST(beforeAD, -15, SysTime(DateTime(1999, 7, 6, 12, 15, 33), d)); 5023 testST(beforeAD, -29, SysTime(DateTime(1999, 7, 6, 12, 1, 33), d)); 5024 testST(beforeAD, -30, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5025 testST(beforeAD, -45, SysTime(DateTime(1999, 7, 6, 12, 45, 33), d)); 5026 testST(beforeAD, -60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5027 testST(beforeAD, -75, SysTime(DateTime(1999, 7, 6, 12, 15, 33), d)); 5028 testST(beforeAD, -90, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5029 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 50, 33), d)); 5030 5031 testST(beforeAD, -749, SysTime(DateTime(1999, 7, 6, 12, 1, 33), d)); 5032 testST(beforeAD, -750, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5033 testST(beforeAD, -751, SysTime(DateTime(1999, 7, 6, 12, 59, 33), d)); 5034 testST(beforeAD, -960, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5035 testST(beforeAD, -1439, SysTime(DateTime(1999, 7, 6, 12, 31, 33), d)); 5036 testST(beforeAD, -1440, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5037 testST(beforeAD, -1441, SysTime(DateTime(1999, 7, 6, 12, 29, 33), d)); 5038 testST(beforeAD, -2880, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5039 5040 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 33), d), 1, SysTime(DateTime(1999, 7, 6, 12, 1, 33), d)); 5041 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 33), d), 0, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5042 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 33), d), -1, SysTime(DateTime(1999, 7, 6, 12, 59, 33), d)); 5043 5044 testST(SysTime(DateTime(1999, 7, 6, 11, 59, 33), d), 1, SysTime(DateTime(1999, 7, 6, 11, 0, 33), d)); 5045 testST(SysTime(DateTime(1999, 7, 6, 11, 59, 33), d), 0, SysTime(DateTime(1999, 7, 6, 11, 59, 33), d)); 5046 testST(SysTime(DateTime(1999, 7, 6, 11, 59, 33), d), -1, SysTime(DateTime(1999, 7, 6, 11, 58, 33), d)); 5047 5048 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 33), d), 1, SysTime(DateTime(1999, 7, 6, 0, 1, 33), d)); 5049 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 33), d), 0, SysTime(DateTime(1999, 7, 6, 0, 0, 33), d)); 5050 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 33), d), -1, SysTime(DateTime(1999, 7, 6, 0, 59, 33), d)); 5051 5052 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 33), d), 1, SysTime(DateTime(1999, 7, 5, 23, 0, 33), d)); 5053 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 33), d), 0, SysTime(DateTime(1999, 7, 5, 23, 59, 33), d)); 5054 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 33), d), -1, SysTime(DateTime(1999, 7, 5, 23, 58, 33), d)); 5055 5056 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 33), d), 1, SysTime(DateTime(1998, 12, 31, 23, 0, 33), d)); 5057 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 33), d), 0, SysTime(DateTime(1998, 12, 31, 23, 59, 33), d)); 5058 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 33), d), -1, SysTime(DateTime(1998, 12, 31, 23, 58, 33), d)); 5059 5060 // Test B.C. 5061 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d); 5062 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5063 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), d)); 5064 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 32, 33), d)); 5065 testST(beforeBC, 3, SysTime(DateTime(-1999, 7, 6, 12, 33, 33), d)); 5066 testST(beforeBC, 4, SysTime(DateTime(-1999, 7, 6, 12, 34, 33), d)); 5067 testST(beforeBC, 5, SysTime(DateTime(-1999, 7, 6, 12, 35, 33), d)); 5068 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 40, 33), d)); 5069 testST(beforeBC, 15, SysTime(DateTime(-1999, 7, 6, 12, 45, 33), d)); 5070 testST(beforeBC, 29, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), d)); 5071 testST(beforeBC, 30, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5072 testST(beforeBC, 45, SysTime(DateTime(-1999, 7, 6, 12, 15, 33), d)); 5073 testST(beforeBC, 60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5074 testST(beforeBC, 75, SysTime(DateTime(-1999, 7, 6, 12, 45, 33), d)); 5075 testST(beforeBC, 90, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5076 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 10, 33), d)); 5077 5078 testST(beforeBC, 689, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), d)); 5079 testST(beforeBC, 690, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5080 testST(beforeBC, 691, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), d)); 5081 testST(beforeBC, 960, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5082 testST(beforeBC, 1439, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), d)); 5083 testST(beforeBC, 1440, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5084 testST(beforeBC, 1441, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), d)); 5085 testST(beforeBC, 2880, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5086 5087 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), d)); 5088 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 28, 33), d)); 5089 testST(beforeBC, -3, SysTime(DateTime(-1999, 7, 6, 12, 27, 33), d)); 5090 testST(beforeBC, -4, SysTime(DateTime(-1999, 7, 6, 12, 26, 33), d)); 5091 testST(beforeBC, -5, SysTime(DateTime(-1999, 7, 6, 12, 25, 33), d)); 5092 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 20, 33), d)); 5093 testST(beforeBC, -15, SysTime(DateTime(-1999, 7, 6, 12, 15, 33), d)); 5094 testST(beforeBC, -29, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), d)); 5095 testST(beforeBC, -30, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5096 testST(beforeBC, -45, SysTime(DateTime(-1999, 7, 6, 12, 45, 33), d)); 5097 testST(beforeBC, -60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5098 testST(beforeBC, -75, SysTime(DateTime(-1999, 7, 6, 12, 15, 33), d)); 5099 testST(beforeBC, -90, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5100 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 50, 33), d)); 5101 5102 testST(beforeBC, -749, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), d)); 5103 testST(beforeBC, -750, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5104 testST(beforeBC, -751, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), d)); 5105 testST(beforeBC, -960, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5106 testST(beforeBC, -1439, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), d)); 5107 testST(beforeBC, -1440, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5108 testST(beforeBC, -1441, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), d)); 5109 testST(beforeBC, -2880, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5110 5111 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), d)); 5112 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5113 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), d)); 5114 5115 testST(SysTime(DateTime(-1999, 7, 6, 11, 59, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 11, 0, 33), d)); 5116 testST(SysTime(DateTime(-1999, 7, 6, 11, 59, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 11, 59, 33), d)); 5117 testST(SysTime(DateTime(-1999, 7, 6, 11, 59, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 11, 58, 33), d)); 5118 5119 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 0, 1, 33), d)); 5120 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 0, 0, 33), d)); 5121 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 0, 59, 33), d)); 5122 5123 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 33), d), 1, SysTime(DateTime(-1999, 7, 5, 23, 0, 33), d)); 5124 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 33), d), 0, SysTime(DateTime(-1999, 7, 5, 23, 59, 33), d)); 5125 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 33), d), -1, SysTime(DateTime(-1999, 7, 5, 23, 58, 33), d)); 5126 5127 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 33), d), 1, SysTime(DateTime(-2000, 12, 31, 23, 0, 33), d)); 5128 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 33), d), 0, SysTime(DateTime(-2000, 12, 31, 23, 59, 33), d)); 5129 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 33), d), -1, SysTime(DateTime(-2000, 12, 31, 23, 58, 33), d)); 5130 5131 // Test Both 5132 testST(SysTime(DateTime(1, 1, 1, 0, 0, 0)), -1, SysTime(DateTime(1, 1, 1, 0, 59, 0))); 5133 testST(SysTime(DateTime(0, 12, 31, 23, 59, 0)), 1, SysTime(DateTime(0, 12, 31, 23, 0, 0))); 5134 5135 testST(SysTime(DateTime(0, 1, 1, 0, 0, 0)), -1, SysTime(DateTime(0, 1, 1, 0, 59, 0))); 5136 testST(SysTime(DateTime(-1, 12, 31, 23, 59, 0)), 1, SysTime(DateTime(-1, 12, 31, 23, 0, 0))); 5137 5138 testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 1_052_760, SysTime(DateTime(-1, 1, 1, 11, 30, 33), d)); 5139 testST(SysTime(DateTime(1, 1, 1, 13, 30, 33), d), -1_052_760, SysTime(DateTime(1, 1, 1, 13, 30, 33), d)); 5140 5141 testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 1_052_782, SysTime(DateTime(-1, 1, 1, 11, 52, 33), d)); 5142 testST(SysTime(DateTime(1, 1, 1, 13, 52, 33), d), -1_052_782, SysTime(DateTime(1, 1, 1, 13, 30, 33), d)); 5143 5144 { 5145 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 5146 sysTime.roll!"minutes"(-1); 5147 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 59, 0))); 5148 sysTime.roll!"minutes"(1); 5149 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5150 } 5151 5152 { 5153 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 59), hnsecs(9_999_999)); 5154 sysTime.roll!"minutes"(-1); 5155 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 59, 59), hnsecs(9_999_999))); 5156 sysTime.roll!"minutes"(1); 5157 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 59), hnsecs(9_999_999))); 5158 } 5159 5160 { 5161 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 0)); 5162 sysTime.roll!"minutes"(1); 5163 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 0, 0))); 5164 sysTime.roll!"minutes"(-1); 5165 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 0))); 5166 } 5167 5168 { 5169 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5170 sysTime.roll!"minutes"(1); 5171 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 0, 59), hnsecs(9_999_999))); 5172 sysTime.roll!"minutes"(-1); 5173 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5174 } 5175 5176 { 5177 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5178 sysTime.roll!"minutes"(1).roll!"minutes"(-79); 5179 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 41, 59), hnsecs(9_999_999))); 5180 } 5181 5182 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5183 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5184 static assert(!__traits(compiles, cst.roll!"minutes"(4))); 5185 //static assert(!__traits(compiles, ist.roll!"minutes"(4))); 5186 } 5187 5188 // Test roll!"seconds"(). 5189 @safe unittest 5190 { 5191 static void testST(SysTime orig, int seconds, in SysTime expected, size_t line = __LINE__) 5192 { 5193 orig.roll!"seconds"(seconds); 5194 if (orig != expected) 5195 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 5196 } 5197 5198 // Test A.D. 5199 immutable d = msecs(274); 5200 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), d); 5201 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5202 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 34), d)); 5203 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 35), d)); 5204 testST(beforeAD, 3, SysTime(DateTime(1999, 7, 6, 12, 30, 36), d)); 5205 testST(beforeAD, 4, SysTime(DateTime(1999, 7, 6, 12, 30, 37), d)); 5206 testST(beforeAD, 5, SysTime(DateTime(1999, 7, 6, 12, 30, 38), d)); 5207 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 43), d)); 5208 testST(beforeAD, 15, SysTime(DateTime(1999, 7, 6, 12, 30, 48), d)); 5209 testST(beforeAD, 26, SysTime(DateTime(1999, 7, 6, 12, 30, 59), d)); 5210 testST(beforeAD, 27, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d)); 5211 testST(beforeAD, 30, SysTime(DateTime(1999, 7, 6, 12, 30, 3), d)); 5212 testST(beforeAD, 59, SysTime(DateTime(1999, 7, 6, 12, 30, 32), d)); 5213 testST(beforeAD, 60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5214 testST(beforeAD, 61, SysTime(DateTime(1999, 7, 6, 12, 30, 34), d)); 5215 5216 testST(beforeAD, 1766, SysTime(DateTime(1999, 7, 6, 12, 30, 59), d)); 5217 testST(beforeAD, 1767, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d)); 5218 testST(beforeAD, 1768, SysTime(DateTime(1999, 7, 6, 12, 30, 1), d)); 5219 testST(beforeAD, 2007, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d)); 5220 testST(beforeAD, 3599, SysTime(DateTime(1999, 7, 6, 12, 30, 32), d)); 5221 testST(beforeAD, 3600, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5222 testST(beforeAD, 3601, SysTime(DateTime(1999, 7, 6, 12, 30, 34), d)); 5223 testST(beforeAD, 7200, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5224 5225 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 32), d)); 5226 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 31), d)); 5227 testST(beforeAD, -3, SysTime(DateTime(1999, 7, 6, 12, 30, 30), d)); 5228 testST(beforeAD, -4, SysTime(DateTime(1999, 7, 6, 12, 30, 29), d)); 5229 testST(beforeAD, -5, SysTime(DateTime(1999, 7, 6, 12, 30, 28), d)); 5230 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 23), d)); 5231 testST(beforeAD, -15, SysTime(DateTime(1999, 7, 6, 12, 30, 18), d)); 5232 testST(beforeAD, -33, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d)); 5233 testST(beforeAD, -34, SysTime(DateTime(1999, 7, 6, 12, 30, 59), d)); 5234 testST(beforeAD, -35, SysTime(DateTime(1999, 7, 6, 12, 30, 58), d)); 5235 testST(beforeAD, -59, SysTime(DateTime(1999, 7, 6, 12, 30, 34), d)); 5236 testST(beforeAD, -60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5237 testST(beforeAD, -61, SysTime(DateTime(1999, 7, 6, 12, 30, 32), d)); 5238 5239 testST(SysTime(DateTime(1999, 7, 6, 12, 30, 0), d), 1, SysTime(DateTime(1999, 7, 6, 12, 30, 1), d)); 5240 testST(SysTime(DateTime(1999, 7, 6, 12, 30, 0), d), 0, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d)); 5241 testST(SysTime(DateTime(1999, 7, 6, 12, 30, 0), d), -1, SysTime(DateTime(1999, 7, 6, 12, 30, 59), d)); 5242 5243 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 0), d), 1, SysTime(DateTime(1999, 7, 6, 12, 0, 1), d)); 5244 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 0), d), 0, SysTime(DateTime(1999, 7, 6, 12, 0, 0), d)); 5245 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 0), d), -1, SysTime(DateTime(1999, 7, 6, 12, 0, 59), d)); 5246 5247 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 0), d), 1, SysTime(DateTime(1999, 7, 6, 0, 0, 1), d)); 5248 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 0), d), 0, SysTime(DateTime(1999, 7, 6, 0, 0, 0), d)); 5249 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 0), d), -1, SysTime(DateTime(1999, 7, 6, 0, 0, 59), d)); 5250 5251 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 59), d), 1, SysTime(DateTime(1999, 7, 5, 23, 59, 0), d)); 5252 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 59), d), 0, SysTime(DateTime(1999, 7, 5, 23, 59, 59), d)); 5253 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 59), d), -1, SysTime(DateTime(1999, 7, 5, 23, 59, 58), d)); 5254 5255 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 59), d), 1, SysTime(DateTime(1998, 12, 31, 23, 59, 0), d)); 5256 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 59), d), 0, SysTime(DateTime(1998, 12, 31, 23, 59, 59), d)); 5257 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 59), d), -1, SysTime(DateTime(1998, 12, 31, 23, 59, 58), d)); 5258 5259 // Test B.C. 5260 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d); 5261 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5262 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), d)); 5263 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 35), d)); 5264 testST(beforeBC, 3, SysTime(DateTime(-1999, 7, 6, 12, 30, 36), d)); 5265 testST(beforeBC, 4, SysTime(DateTime(-1999, 7, 6, 12, 30, 37), d)); 5266 testST(beforeBC, 5, SysTime(DateTime(-1999, 7, 6, 12, 30, 38), d)); 5267 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 43), d)); 5268 testST(beforeBC, 15, SysTime(DateTime(-1999, 7, 6, 12, 30, 48), d)); 5269 testST(beforeBC, 26, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), d)); 5270 testST(beforeBC, 27, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d)); 5271 testST(beforeBC, 30, SysTime(DateTime(-1999, 7, 6, 12, 30, 3), d)); 5272 testST(beforeBC, 59, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), d)); 5273 testST(beforeBC, 60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5274 testST(beforeBC, 61, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), d)); 5275 5276 testST(beforeBC, 1766, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), d)); 5277 testST(beforeBC, 1767, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d)); 5278 testST(beforeBC, 1768, SysTime(DateTime(-1999, 7, 6, 12, 30, 1), d)); 5279 testST(beforeBC, 2007, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d)); 5280 testST(beforeBC, 3599, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), d)); 5281 testST(beforeBC, 3600, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5282 testST(beforeBC, 3601, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), d)); 5283 testST(beforeBC, 7200, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5284 5285 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), d)); 5286 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 31), d)); 5287 testST(beforeBC, -3, SysTime(DateTime(-1999, 7, 6, 12, 30, 30), d)); 5288 testST(beforeBC, -4, SysTime(DateTime(-1999, 7, 6, 12, 30, 29), d)); 5289 testST(beforeBC, -5, SysTime(DateTime(-1999, 7, 6, 12, 30, 28), d)); 5290 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 23), d)); 5291 testST(beforeBC, -15, SysTime(DateTime(-1999, 7, 6, 12, 30, 18), d)); 5292 testST(beforeBC, -33, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d)); 5293 testST(beforeBC, -34, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), d)); 5294 testST(beforeBC, -35, SysTime(DateTime(-1999, 7, 6, 12, 30, 58), d)); 5295 testST(beforeBC, -59, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), d)); 5296 testST(beforeBC, -60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5297 testST(beforeBC, -61, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), d)); 5298 5299 testST(SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d), 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 1), d)); 5300 testST(SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d), 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d)); 5301 testST(SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d), -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), d)); 5302 5303 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 0), d), 1, SysTime(DateTime(-1999, 7, 6, 12, 0, 1), d)); 5304 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 0), d), 0, SysTime(DateTime(-1999, 7, 6, 12, 0, 0), d)); 5305 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 0), d), -1, SysTime(DateTime(-1999, 7, 6, 12, 0, 59), d)); 5306 5307 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 0), d), 1, SysTime(DateTime(-1999, 7, 6, 0, 0, 1), d)); 5308 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 0), d), 0, SysTime(DateTime(-1999, 7, 6, 0, 0, 0), d)); 5309 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 0), d), -1, SysTime(DateTime(-1999, 7, 6, 0, 0, 59), d)); 5310 5311 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 59), d), 1, SysTime(DateTime(-1999, 7, 5, 23, 59, 0), d)); 5312 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 59), d), 0, SysTime(DateTime(-1999, 7, 5, 23, 59, 59), d)); 5313 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 59), d), -1, SysTime(DateTime(-1999, 7, 5, 23, 59, 58), d)); 5314 5315 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 59), d), 1, SysTime(DateTime(-2000, 12, 31, 23, 59, 0), d)); 5316 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 59), d), 0, SysTime(DateTime(-2000, 12, 31, 23, 59, 59), d)); 5317 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 59), d), -1, SysTime(DateTime(-2000, 12, 31, 23, 59, 58), d)); 5318 5319 // Test Both 5320 testST(SysTime(DateTime(1, 1, 1, 0, 0, 0), d), -1, SysTime(DateTime(1, 1, 1, 0, 0, 59), d)); 5321 testST(SysTime(DateTime(0, 12, 31, 23, 59, 59), d), 1, SysTime(DateTime(0, 12, 31, 23, 59, 0), d)); 5322 5323 testST(SysTime(DateTime(0, 1, 1, 0, 0, 0), d), -1, SysTime(DateTime(0, 1, 1, 0, 0, 59), d)); 5324 testST(SysTime(DateTime(-1, 12, 31, 23, 59, 59), d), 1, SysTime(DateTime(-1, 12, 31, 23, 59, 0), d)); 5325 5326 testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 63_165_600L, SysTime(DateTime(-1, 1, 1, 11, 30, 33), d)); 5327 testST(SysTime(DateTime(1, 1, 1, 13, 30, 33), d), -63_165_600L, SysTime(DateTime(1, 1, 1, 13, 30, 33), d)); 5328 5329 testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 63_165_617L, SysTime(DateTime(-1, 1, 1, 11, 30, 50), d)); 5330 testST(SysTime(DateTime(1, 1, 1, 13, 30, 50), d), -63_165_617L, SysTime(DateTime(1, 1, 1, 13, 30, 33), d)); 5331 5332 { 5333 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 5334 sysTime.roll!"seconds"(-1); 5335 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 59))); 5336 sysTime.roll!"seconds"(1); 5337 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5338 } 5339 5340 { 5341 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(9_999_999)); 5342 sysTime.roll!"seconds"(-1); 5343 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 59), hnsecs(9_999_999))); 5344 sysTime.roll!"seconds"(1); 5345 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 5346 } 5347 5348 { 5349 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59)); 5350 sysTime.roll!"seconds"(1); 5351 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 0))); 5352 sysTime.roll!"seconds"(-1); 5353 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59))); 5354 } 5355 5356 { 5357 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5358 sysTime.roll!"seconds"(1); 5359 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 0), hnsecs(9_999_999))); 5360 sysTime.roll!"seconds"(-1); 5361 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5362 } 5363 5364 { 5365 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5366 sysTime.roll!"seconds"(1).roll!"seconds"(-102); 5367 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 18), hnsecs(9_999_999))); 5368 } 5369 5370 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5371 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5372 static assert(!__traits(compiles, cst.roll!"seconds"(4))); 5373 //static assert(!__traits(compiles, ist.roll!"seconds"(4))); 5374 } 5375 5376 5377 // Shares documentation with "days" version. 5378 ref SysTime roll(string units)(long value) @safe nothrow 5379 if (units == "msecs" || units == "usecs" || units == "hnsecs") 5380 { 5381 auto hnsecs = adjTime; 5382 immutable days = splitUnitsFromHNSecs!"days"(hnsecs); 5383 immutable negative = hnsecs < 0; 5384 5385 if (negative) 5386 hnsecs += convert!("hours", "hnsecs")(24); 5387 5388 immutable seconds = splitUnitsFromHNSecs!"seconds"(hnsecs); 5389 hnsecs += convert!(units, "hnsecs")(value); 5390 hnsecs %= convert!("seconds", "hnsecs")(1); 5391 5392 if (hnsecs < 0) 5393 hnsecs += convert!("seconds", "hnsecs")(1); 5394 hnsecs += convert!("seconds", "hnsecs")(seconds); 5395 5396 if (negative) 5397 hnsecs -= convert!("hours", "hnsecs")(24); 5398 5399 immutable newDaysHNSecs = convert!("days", "hnsecs")(days); 5400 adjTime = newDaysHNSecs + hnsecs; 5401 return this; 5402 } 5403 5404 5405 // Test roll!"msecs"(). 5406 @safe unittest 5407 { 5408 static void testST(SysTime orig, int milliseconds, in SysTime expected, size_t line = __LINE__) 5409 { 5410 orig.roll!"msecs"(milliseconds); 5411 if (orig != expected) 5412 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 5413 } 5414 5415 // Test A.D. 5416 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274)); 5417 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274))); 5418 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(275))); 5419 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(276))); 5420 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(284))); 5421 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(374))); 5422 testST(beforeAD, 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999))); 5423 testST(beforeAD, 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5424 testST(beforeAD, 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274))); 5425 testST(beforeAD, 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(275))); 5426 testST(beforeAD, 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274))); 5427 testST(beforeAD, 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999))); 5428 testST(beforeAD, 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5429 testST(beforeAD, 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(1))); 5430 testST(beforeAD, 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999))); 5431 testST(beforeAD, 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5432 5433 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(273))); 5434 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(272))); 5435 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(264))); 5436 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(174))); 5437 testST(beforeAD, -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5438 testST(beforeAD, -275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999))); 5439 testST(beforeAD, -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274))); 5440 testST(beforeAD, -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(273))); 5441 testST(beforeAD, -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274))); 5442 testST(beforeAD, -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5443 testST(beforeAD, -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999))); 5444 testST(beforeAD, -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5445 testST(beforeAD, -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999))); 5446 5447 // Test B.C. 5448 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274)); 5449 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274))); 5450 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(275))); 5451 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(276))); 5452 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(284))); 5453 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(374))); 5454 testST(beforeBC, 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999))); 5455 testST(beforeBC, 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 5456 testST(beforeBC, 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274))); 5457 testST(beforeBC, 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(275))); 5458 testST(beforeBC, 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274))); 5459 testST(beforeBC, 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999))); 5460 testST(beforeBC, 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 5461 testST(beforeBC, 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(1))); 5462 testST(beforeBC, 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999))); 5463 testST(beforeBC, 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 5464 5465 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(273))); 5466 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(272))); 5467 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(264))); 5468 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(174))); 5469 testST(beforeBC, -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 5470 testST(beforeBC, -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999))); 5471 testST(beforeBC, -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274))); 5472 testST(beforeBC, -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(273))); 5473 testST(beforeBC, -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274))); 5474 testST(beforeBC, -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 5475 testST(beforeBC, -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999))); 5476 testST(beforeBC, -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 5477 testST(beforeBC, -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999))); 5478 5479 // Test Both 5480 auto beforeBoth1 = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 5481 testST(beforeBoth1, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), msecs(1))); 5482 testST(beforeBoth1, 0, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5483 testST(beforeBoth1, -1, SysTime(DateTime(1, 1, 1, 0, 0, 0), msecs(999))); 5484 testST(beforeBoth1, -2, SysTime(DateTime(1, 1, 1, 0, 0, 0), msecs(998))); 5485 testST(beforeBoth1, -1000, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5486 testST(beforeBoth1, -2000, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5487 testST(beforeBoth1, -2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), msecs(445))); 5488 5489 auto beforeBoth2 = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5490 testST(beforeBoth2, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_989_999))); 5491 testST(beforeBoth2, 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5492 testST(beforeBoth2, 1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9999))); 5493 testST(beforeBoth2, 2, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(19_999))); 5494 testST(beforeBoth2, 1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5495 testST(beforeBoth2, 2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5496 testST(beforeBoth2, 2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(5_549_999))); 5497 5498 { 5499 auto st = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5500 st.roll!"msecs"(1202).roll!"msecs"(-703); 5501 assert(st == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(4_989_999))); 5502 } 5503 5504 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5505 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5506 static assert(!__traits(compiles, cst.addMSecs(4))); 5507 //static assert(!__traits(compiles, ist.addMSecs(4))); 5508 } 5509 5510 // Test roll!"usecs"(). 5511 @safe unittest 5512 { 5513 static void testST(SysTime orig, long microseconds, in SysTime expected, size_t line = __LINE__) 5514 { 5515 orig.roll!"usecs"(microseconds); 5516 if (orig != expected) 5517 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 5518 } 5519 5520 // Test A.D. 5521 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274)); 5522 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 5523 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(275))); 5524 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(276))); 5525 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(284))); 5526 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(374))); 5527 testST(beforeAD, 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(999))); 5528 testST(beforeAD, 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(1000))); 5529 testST(beforeAD, 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(1274))); 5530 testST(beforeAD, 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(1275))); 5531 testST(beforeAD, 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(2274))); 5532 testST(beforeAD, 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(26_999))); 5533 testST(beforeAD, 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(27_000))); 5534 testST(beforeAD, 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(27_001))); 5535 testST(beforeAD, 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(766_999))); 5536 testST(beforeAD, 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(767_000))); 5537 testST(beforeAD, 1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 5538 testST(beforeAD, 60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 5539 testST(beforeAD, 3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 5540 5541 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(273))); 5542 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(272))); 5543 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(264))); 5544 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(174))); 5545 testST(beforeAD, -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5546 testST(beforeAD, -275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(999_999))); 5547 testST(beforeAD, -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(999_274))); 5548 testST(beforeAD, -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(999_273))); 5549 testST(beforeAD, -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(998_274))); 5550 testST(beforeAD, -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(967_000))); 5551 testST(beforeAD, -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(966_999))); 5552 testST(beforeAD, -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(167_000))); 5553 testST(beforeAD, -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(166_999))); 5554 testST(beforeAD, -1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 5555 testST(beforeAD, -60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 5556 testST(beforeAD, -3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 5557 5558 // Test B.C. 5559 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274)); 5560 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 5561 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(275))); 5562 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(276))); 5563 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(284))); 5564 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(374))); 5565 testST(beforeBC, 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(999))); 5566 testST(beforeBC, 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(1000))); 5567 testST(beforeBC, 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(1274))); 5568 testST(beforeBC, 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(1275))); 5569 testST(beforeBC, 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(2274))); 5570 testST(beforeBC, 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(26_999))); 5571 testST(beforeBC, 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(27_000))); 5572 testST(beforeBC, 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(27_001))); 5573 testST(beforeBC, 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(766_999))); 5574 testST(beforeBC, 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(767_000))); 5575 testST(beforeBC, 1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 5576 testST(beforeBC, 60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 5577 testST(beforeBC, 3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 5578 5579 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(273))); 5580 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(272))); 5581 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(264))); 5582 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(174))); 5583 testST(beforeBC, -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 5584 testST(beforeBC, -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(999_999))); 5585 testST(beforeBC, -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(999_274))); 5586 testST(beforeBC, -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(999_273))); 5587 testST(beforeBC, -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(998_274))); 5588 testST(beforeBC, -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(967_000))); 5589 testST(beforeBC, -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(966_999))); 5590 testST(beforeBC, -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(167_000))); 5591 testST(beforeBC, -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(166_999))); 5592 testST(beforeBC, -1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 5593 testST(beforeBC, -60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 5594 testST(beforeBC, -3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 5595 5596 // Test Both 5597 auto beforeBoth1 = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 5598 testST(beforeBoth1, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(1))); 5599 testST(beforeBoth1, 0, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5600 testST(beforeBoth1, -1, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(999_999))); 5601 testST(beforeBoth1, -2, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(999_998))); 5602 testST(beforeBoth1, -1000, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(999_000))); 5603 testST(beforeBoth1, -2000, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(998_000))); 5604 testST(beforeBoth1, -2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(997_445))); 5605 testST(beforeBoth1, -1_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5606 testST(beforeBoth1, -2_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5607 testST(beforeBoth1, -2_333_333, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(666_667))); 5608 5609 auto beforeBoth2 = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5610 testST(beforeBoth2, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_989))); 5611 testST(beforeBoth2, 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5612 testST(beforeBoth2, 1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9))); 5613 testST(beforeBoth2, 2, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(19))); 5614 testST(beforeBoth2, 1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9999))); 5615 testST(beforeBoth2, 2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(19_999))); 5616 testST(beforeBoth2, 2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(25_549))); 5617 testST(beforeBoth2, 1_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5618 testST(beforeBoth2, 2_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5619 testST(beforeBoth2, 2_333_333, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(3_333_329))); 5620 5621 { 5622 auto st = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5623 st.roll!"usecs"(9_020_027); 5624 assert(st == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(200_269))); 5625 } 5626 5627 { 5628 auto st = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5629 st.roll!"usecs"(9_020_027).roll!"usecs"(-70_034); 5630 assert(st == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_499_929))); 5631 } 5632 5633 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5634 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5635 static assert(!__traits(compiles, cst.roll!"usecs"(4))); 5636 //static assert(!__traits(compiles, ist.roll!"usecs"(4))); 5637 } 5638 5639 // Test roll!"hnsecs"(). 5640 @safe unittest 5641 { 5642 static void testST(SysTime orig, long hnsecs, in SysTime expected, size_t line = __LINE__) 5643 { 5644 orig.roll!"hnsecs"(hnsecs); 5645 if (orig != expected) 5646 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 5647 } 5648 5649 // Test A.D. 5650 auto dtAD = DateTime(1999, 7, 6, 12, 30, 33); 5651 auto beforeAD = SysTime(dtAD, hnsecs(274)); 5652 testST(beforeAD, 0, SysTime(dtAD, hnsecs(274))); 5653 testST(beforeAD, 1, SysTime(dtAD, hnsecs(275))); 5654 testST(beforeAD, 2, SysTime(dtAD, hnsecs(276))); 5655 testST(beforeAD, 10, SysTime(dtAD, hnsecs(284))); 5656 testST(beforeAD, 100, SysTime(dtAD, hnsecs(374))); 5657 testST(beforeAD, 725, SysTime(dtAD, hnsecs(999))); 5658 testST(beforeAD, 726, SysTime(dtAD, hnsecs(1000))); 5659 testST(beforeAD, 1000, SysTime(dtAD, hnsecs(1274))); 5660 testST(beforeAD, 1001, SysTime(dtAD, hnsecs(1275))); 5661 testST(beforeAD, 2000, SysTime(dtAD, hnsecs(2274))); 5662 testST(beforeAD, 26_725, SysTime(dtAD, hnsecs(26_999))); 5663 testST(beforeAD, 26_726, SysTime(dtAD, hnsecs(27_000))); 5664 testST(beforeAD, 26_727, SysTime(dtAD, hnsecs(27_001))); 5665 testST(beforeAD, 1_766_725, SysTime(dtAD, hnsecs(1_766_999))); 5666 testST(beforeAD, 1_766_726, SysTime(dtAD, hnsecs(1_767_000))); 5667 testST(beforeAD, 1_000_000, SysTime(dtAD, hnsecs(1_000_274))); 5668 testST(beforeAD, 60_000_000L, SysTime(dtAD, hnsecs(274))); 5669 testST(beforeAD, 3_600_000_000L, SysTime(dtAD, hnsecs(274))); 5670 testST(beforeAD, 600_000_000L, SysTime(dtAD, hnsecs(274))); 5671 testST(beforeAD, 36_000_000_000L, SysTime(dtAD, hnsecs(274))); 5672 5673 testST(beforeAD, -1, SysTime(dtAD, hnsecs(273))); 5674 testST(beforeAD, -2, SysTime(dtAD, hnsecs(272))); 5675 testST(beforeAD, -10, SysTime(dtAD, hnsecs(264))); 5676 testST(beforeAD, -100, SysTime(dtAD, hnsecs(174))); 5677 testST(beforeAD, -274, SysTime(dtAD)); 5678 testST(beforeAD, -275, SysTime(dtAD, hnsecs(9_999_999))); 5679 testST(beforeAD, -1000, SysTime(dtAD, hnsecs(9_999_274))); 5680 testST(beforeAD, -1001, SysTime(dtAD, hnsecs(9_999_273))); 5681 testST(beforeAD, -2000, SysTime(dtAD, hnsecs(9_998_274))); 5682 testST(beforeAD, -33_274, SysTime(dtAD, hnsecs(9_967_000))); 5683 testST(beforeAD, -33_275, SysTime(dtAD, hnsecs(9_966_999))); 5684 testST(beforeAD, -1_833_274, SysTime(dtAD, hnsecs(8_167_000))); 5685 testST(beforeAD, -1_833_275, SysTime(dtAD, hnsecs(8_166_999))); 5686 testST(beforeAD, -1_000_000, SysTime(dtAD, hnsecs(9_000_274))); 5687 testST(beforeAD, -60_000_000L, SysTime(dtAD, hnsecs(274))); 5688 testST(beforeAD, -3_600_000_000L, SysTime(dtAD, hnsecs(274))); 5689 testST(beforeAD, -600_000_000L, SysTime(dtAD, hnsecs(274))); 5690 testST(beforeAD, -36_000_000_000L, SysTime(dtAD, hnsecs(274))); 5691 5692 // Test B.C. 5693 auto dtBC = DateTime(-1999, 7, 6, 12, 30, 33); 5694 auto beforeBC = SysTime(dtBC, hnsecs(274)); 5695 testST(beforeBC, 0, SysTime(dtBC, hnsecs(274))); 5696 testST(beforeBC, 1, SysTime(dtBC, hnsecs(275))); 5697 testST(beforeBC, 2, SysTime(dtBC, hnsecs(276))); 5698 testST(beforeBC, 10, SysTime(dtBC, hnsecs(284))); 5699 testST(beforeBC, 100, SysTime(dtBC, hnsecs(374))); 5700 testST(beforeBC, 725, SysTime(dtBC, hnsecs(999))); 5701 testST(beforeBC, 726, SysTime(dtBC, hnsecs(1000))); 5702 testST(beforeBC, 1000, SysTime(dtBC, hnsecs(1274))); 5703 testST(beforeBC, 1001, SysTime(dtBC, hnsecs(1275))); 5704 testST(beforeBC, 2000, SysTime(dtBC, hnsecs(2274))); 5705 testST(beforeBC, 26_725, SysTime(dtBC, hnsecs(26_999))); 5706 testST(beforeBC, 26_726, SysTime(dtBC, hnsecs(27_000))); 5707 testST(beforeBC, 26_727, SysTime(dtBC, hnsecs(27_001))); 5708 testST(beforeBC, 1_766_725, SysTime(dtBC, hnsecs(1_766_999))); 5709 testST(beforeBC, 1_766_726, SysTime(dtBC, hnsecs(1_767_000))); 5710 testST(beforeBC, 1_000_000, SysTime(dtBC, hnsecs(1_000_274))); 5711 testST(beforeBC, 60_000_000L, SysTime(dtBC, hnsecs(274))); 5712 testST(beforeBC, 3_600_000_000L, SysTime(dtBC, hnsecs(274))); 5713 testST(beforeBC, 600_000_000L, SysTime(dtBC, hnsecs(274))); 5714 testST(beforeBC, 36_000_000_000L, SysTime(dtBC, hnsecs(274))); 5715 5716 testST(beforeBC, -1, SysTime(dtBC, hnsecs(273))); 5717 testST(beforeBC, -2, SysTime(dtBC, hnsecs(272))); 5718 testST(beforeBC, -10, SysTime(dtBC, hnsecs(264))); 5719 testST(beforeBC, -100, SysTime(dtBC, hnsecs(174))); 5720 testST(beforeBC, -274, SysTime(dtBC)); 5721 testST(beforeBC, -275, SysTime(dtBC, hnsecs(9_999_999))); 5722 testST(beforeBC, -1000, SysTime(dtBC, hnsecs(9_999_274))); 5723 testST(beforeBC, -1001, SysTime(dtBC, hnsecs(9_999_273))); 5724 testST(beforeBC, -2000, SysTime(dtBC, hnsecs(9_998_274))); 5725 testST(beforeBC, -33_274, SysTime(dtBC, hnsecs(9_967_000))); 5726 testST(beforeBC, -33_275, SysTime(dtBC, hnsecs(9_966_999))); 5727 testST(beforeBC, -1_833_274, SysTime(dtBC, hnsecs(8_167_000))); 5728 testST(beforeBC, -1_833_275, SysTime(dtBC, hnsecs(8_166_999))); 5729 testST(beforeBC, -1_000_000, SysTime(dtBC, hnsecs(9_000_274))); 5730 testST(beforeBC, -60_000_000L, SysTime(dtBC, hnsecs(274))); 5731 testST(beforeBC, -3_600_000_000L, SysTime(dtBC, hnsecs(274))); 5732 testST(beforeBC, -600_000_000L, SysTime(dtBC, hnsecs(274))); 5733 testST(beforeBC, -36_000_000_000L, SysTime(dtBC, hnsecs(274))); 5734 5735 // Test Both 5736 auto dtBoth1 = DateTime(1, 1, 1, 0, 0, 0); 5737 auto beforeBoth1 = SysTime(dtBoth1); 5738 testST(beforeBoth1, 1, SysTime(dtBoth1, hnsecs(1))); 5739 testST(beforeBoth1, 0, SysTime(dtBoth1)); 5740 testST(beforeBoth1, -1, SysTime(dtBoth1, hnsecs(9_999_999))); 5741 testST(beforeBoth1, -2, SysTime(dtBoth1, hnsecs(9_999_998))); 5742 testST(beforeBoth1, -1000, SysTime(dtBoth1, hnsecs(9_999_000))); 5743 testST(beforeBoth1, -2000, SysTime(dtBoth1, hnsecs(9_998_000))); 5744 testST(beforeBoth1, -2555, SysTime(dtBoth1, hnsecs(9_997_445))); 5745 testST(beforeBoth1, -1_000_000, SysTime(dtBoth1, hnsecs(9_000_000))); 5746 testST(beforeBoth1, -2_000_000, SysTime(dtBoth1, hnsecs(8_000_000))); 5747 testST(beforeBoth1, -2_333_333, SysTime(dtBoth1, hnsecs(7_666_667))); 5748 testST(beforeBoth1, -10_000_000, SysTime(dtBoth1)); 5749 testST(beforeBoth1, -20_000_000, SysTime(dtBoth1)); 5750 testST(beforeBoth1, -20_888_888, SysTime(dtBoth1, hnsecs(9_111_112))); 5751 5752 auto dtBoth2 = DateTime(0, 12, 31, 23, 59, 59); 5753 auto beforeBoth2 = SysTime(dtBoth2, hnsecs(9_999_999)); 5754 testST(beforeBoth2, -1, SysTime(dtBoth2, hnsecs(9_999_998))); 5755 testST(beforeBoth2, 0, SysTime(dtBoth2, hnsecs(9_999_999))); 5756 testST(beforeBoth2, 1, SysTime(dtBoth2)); 5757 testST(beforeBoth2, 2, SysTime(dtBoth2, hnsecs(1))); 5758 testST(beforeBoth2, 1000, SysTime(dtBoth2, hnsecs(999))); 5759 testST(beforeBoth2, 2000, SysTime(dtBoth2, hnsecs(1999))); 5760 testST(beforeBoth2, 2555, SysTime(dtBoth2, hnsecs(2554))); 5761 testST(beforeBoth2, 1_000_000, SysTime(dtBoth2, hnsecs(999_999))); 5762 testST(beforeBoth2, 2_000_000, SysTime(dtBoth2, hnsecs(1_999_999))); 5763 testST(beforeBoth2, 2_333_333, SysTime(dtBoth2, hnsecs(2_333_332))); 5764 testST(beforeBoth2, 10_000_000, SysTime(dtBoth2, hnsecs(9_999_999))); 5765 testST(beforeBoth2, 20_000_000, SysTime(dtBoth2, hnsecs(9_999_999))); 5766 testST(beforeBoth2, 20_888_888, SysTime(dtBoth2, hnsecs(888_887))); 5767 5768 { 5769 auto st = SysTime(dtBoth2, hnsecs(9_999_999)); 5770 st.roll!"hnsecs"(70_777_222).roll!"hnsecs"(-222_555_292); 5771 assert(st == SysTime(dtBoth2, hnsecs(8_221_929))); 5772 } 5773 5774 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5775 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5776 static assert(!__traits(compiles, cst.roll!"hnsecs"(4))); 5777 //static assert(!__traits(compiles, ist.roll!"hnsecs"(4))); 5778 } 5779 5780 5781 /++ 5782 Gives the result of adding or subtracting a $(REF Duration, core,time) 5783 from this $(LREF SysTime). 5784 5785 The legal types of arithmetic for $(LREF SysTime) using this operator 5786 are 5787 5788 $(BOOKTABLE, 5789 $(TR $(TD SysTime) $(TD +) $(TD Duration) $(TD -->) $(TD SysTime)) 5790 $(TR $(TD SysTime) $(TD -) $(TD Duration) $(TD -->) $(TD SysTime)) 5791 ) 5792 5793 Params: 5794 duration = The $(REF Duration, core,time) to add to or subtract from 5795 this $(LREF SysTime). 5796 +/ 5797 SysTime opBinary(string op)(Duration duration) @safe const pure nothrow 5798 if (op == "+" || op == "-") 5799 { 5800 SysTime retval = SysTime(this._stdTime, this._timezone); 5801 immutable hnsecs = duration.total!"hnsecs"; 5802 mixin("retval._stdTime " ~ op ~ "= hnsecs;"); 5803 return retval; 5804 } 5805 5806 /// 5807 @safe unittest 5808 { 5809 import core.time : hours, seconds; 5810 import std.datetime.date : DateTime; 5811 5812 assert(SysTime(DateTime(2015, 12, 31, 23, 59, 59)) + seconds(1) == 5813 SysTime(DateTime(2016, 1, 1, 0, 0, 0))); 5814 5815 assert(SysTime(DateTime(2015, 12, 31, 23, 59, 59)) + hours(1) == 5816 SysTime(DateTime(2016, 1, 1, 0, 59, 59))); 5817 5818 assert(SysTime(DateTime(2016, 1, 1, 0, 0, 0)) - seconds(1) == 5819 SysTime(DateTime(2015, 12, 31, 23, 59, 59))); 5820 5821 assert(SysTime(DateTime(2016, 1, 1, 0, 59, 59)) - hours(1) == 5822 SysTime(DateTime(2015, 12, 31, 23, 59, 59))); 5823 } 5824 5825 @safe unittest 5826 { 5827 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_678)); 5828 5829 assert(st + dur!"weeks"(7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33), hnsecs(2_345_678))); 5830 assert(st + dur!"weeks"(-7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33), hnsecs(2_345_678))); 5831 assert(st + dur!"days"(7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33), hnsecs(2_345_678))); 5832 assert(st + dur!"days"(-7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33), hnsecs(2_345_678))); 5833 assert(st + dur!"hours"(7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33), hnsecs(2_345_678))); 5834 assert(st + dur!"hours"(-7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33), hnsecs(2_345_678))); 5835 assert(st + dur!"minutes"(7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33), hnsecs(2_345_678))); 5836 assert(st + dur!"minutes"(-7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33), hnsecs(2_345_678))); 5837 assert(st + dur!"seconds"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40), hnsecs(2_345_678))); 5838 assert(st + dur!"seconds"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26), hnsecs(2_345_678))); 5839 assert(st + dur!"msecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_415_678))); 5840 assert(st + dur!"msecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_275_678))); 5841 assert(st + dur!"usecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_748))); 5842 assert(st + dur!"usecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_608))); 5843 assert(st + dur!"hnsecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_685))); 5844 assert(st + dur!"hnsecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_671))); 5845 5846 assert(st - dur!"weeks"(-7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33), hnsecs(2_345_678))); 5847 assert(st - dur!"weeks"(7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33), hnsecs(2_345_678))); 5848 assert(st - dur!"days"(-7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33), hnsecs(2_345_678))); 5849 assert(st - dur!"days"(7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33), hnsecs(2_345_678))); 5850 assert(st - dur!"hours"(-7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33), hnsecs(2_345_678))); 5851 assert(st - dur!"hours"(7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33), hnsecs(2_345_678))); 5852 assert(st - dur!"minutes"(-7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33), hnsecs(2_345_678))); 5853 assert(st - dur!"minutes"(7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33), hnsecs(2_345_678))); 5854 assert(st - dur!"seconds"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40), hnsecs(2_345_678))); 5855 assert(st - dur!"seconds"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26), hnsecs(2_345_678))); 5856 assert(st - dur!"msecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_415_678))); 5857 assert(st - dur!"msecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_275_678))); 5858 assert(st - dur!"usecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_748))); 5859 assert(st - dur!"usecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_608))); 5860 assert(st - dur!"hnsecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_685))); 5861 assert(st - dur!"hnsecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_671))); 5862 5863 static void testST(in SysTime orig, long hnsecs, in SysTime expected, size_t line = __LINE__) 5864 { 5865 auto result = orig + dur!"hnsecs"(hnsecs); 5866 if (result != expected) 5867 throw new AssertError(format("Failed. actual [%s] != expected [%s]", result, expected), __FILE__, line); 5868 } 5869 5870 // Test A.D. 5871 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274)); 5872 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274))); 5873 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(275))); 5874 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(276))); 5875 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(284))); 5876 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(374))); 5877 testST(beforeAD, 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(999))); 5878 testST(beforeAD, 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1000))); 5879 testST(beforeAD, 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1274))); 5880 testST(beforeAD, 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1275))); 5881 testST(beforeAD, 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2274))); 5882 testST(beforeAD, 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(26_999))); 5883 testST(beforeAD, 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_000))); 5884 testST(beforeAD, 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_001))); 5885 testST(beforeAD, 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_766_999))); 5886 testST(beforeAD, 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_767_000))); 5887 testST(beforeAD, 1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_000_274))); 5888 testST(beforeAD, 60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 39), hnsecs(274))); 5889 testST(beforeAD, 3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 36, 33), hnsecs(274))); 5890 testST(beforeAD, 600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 31, 33), hnsecs(274))); 5891 testST(beforeAD, 36_000_000_000L, SysTime(DateTime(1999, 7, 6, 13, 30, 33), hnsecs(274))); 5892 5893 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(273))); 5894 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(272))); 5895 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(264))); 5896 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(174))); 5897 testST(beforeAD, -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5898 testST(beforeAD, -275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_999))); 5899 testST(beforeAD, -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_274))); 5900 testST(beforeAD, -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_273))); 5901 testST(beforeAD, -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_998_274))); 5902 testST(beforeAD, -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_967_000))); 5903 testST(beforeAD, -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_966_999))); 5904 testST(beforeAD, -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_167_000))); 5905 testST(beforeAD, -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_166_999))); 5906 testST(beforeAD, -1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_000_274))); 5907 testST(beforeAD, -60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 27), hnsecs(274))); 5908 testST(beforeAD, -3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 24, 33), hnsecs(274))); 5909 testST(beforeAD, -600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 29, 33), hnsecs(274))); 5910 testST(beforeAD, -36_000_000_000L, SysTime(DateTime(1999, 7, 6, 11, 30, 33), hnsecs(274))); 5911 5912 // Test B.C. 5913 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274)); 5914 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274))); 5915 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(275))); 5916 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(276))); 5917 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(284))); 5918 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(374))); 5919 testST(beforeBC, 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(999))); 5920 testST(beforeBC, 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1000))); 5921 testST(beforeBC, 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1274))); 5922 testST(beforeBC, 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1275))); 5923 testST(beforeBC, 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(2274))); 5924 testST(beforeBC, 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(26_999))); 5925 testST(beforeBC, 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_000))); 5926 testST(beforeBC, 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_001))); 5927 testST(beforeBC, 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_766_999))); 5928 testST(beforeBC, 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_767_000))); 5929 testST(beforeBC, 1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_000_274))); 5930 testST(beforeBC, 60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 39), hnsecs(274))); 5931 testST(beforeBC, 3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 36, 33), hnsecs(274))); 5932 testST(beforeBC, 600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), hnsecs(274))); 5933 testST(beforeBC, 36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), hnsecs(274))); 5934 5935 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(273))); 5936 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(272))); 5937 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(264))); 5938 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(174))); 5939 testST(beforeBC, -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 5940 testST(beforeBC, -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_999))); 5941 testST(beforeBC, -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_274))); 5942 testST(beforeBC, -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_273))); 5943 testST(beforeBC, -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_998_274))); 5944 testST(beforeBC, -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_967_000))); 5945 testST(beforeBC, -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_966_999))); 5946 testST(beforeBC, -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_167_000))); 5947 testST(beforeBC, -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_166_999))); 5948 testST(beforeBC, -1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_000_274))); 5949 testST(beforeBC, -60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 27), hnsecs(274))); 5950 testST(beforeBC, -3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 24, 33), hnsecs(274))); 5951 testST(beforeBC, -600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), hnsecs(274))); 5952 testST(beforeBC, -36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), hnsecs(274))); 5953 5954 // Test Both 5955 auto beforeBoth1 = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 5956 testST(beforeBoth1, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 5957 testST(beforeBoth1, 0, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5958 testST(beforeBoth1, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5959 testST(beforeBoth1, -2, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998))); 5960 testST(beforeBoth1, -1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_000))); 5961 testST(beforeBoth1, -2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_998_000))); 5962 testST(beforeBoth1, -2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_997_445))); 5963 testST(beforeBoth1, -1_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_000_000))); 5964 testST(beforeBoth1, -2_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(8_000_000))); 5965 testST(beforeBoth1, -2_333_333, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(7_666_667))); 5966 testST(beforeBoth1, -10_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59))); 5967 testST(beforeBoth1, -20_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 58))); 5968 testST(beforeBoth1, -20_888_888, SysTime(DateTime(0, 12, 31, 23, 59, 57), hnsecs(9_111_112))); 5969 5970 auto beforeBoth2 = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5971 testST(beforeBoth2, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998))); 5972 testST(beforeBoth2, 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5973 testST(beforeBoth2, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5974 testST(beforeBoth2, 2, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 5975 testST(beforeBoth2, 1000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999))); 5976 testST(beforeBoth2, 2000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1999))); 5977 testST(beforeBoth2, 2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2554))); 5978 testST(beforeBoth2, 1_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999_999))); 5979 testST(beforeBoth2, 2_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1_999_999))); 5980 testST(beforeBoth2, 2_333_333, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2_333_332))); 5981 testST(beforeBoth2, 10_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 5982 testST(beforeBoth2, 20_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 1), hnsecs(9_999_999))); 5983 testST(beforeBoth2, 20_888_888, SysTime(DateTime(1, 1, 1, 0, 0, 2), hnsecs(888_887))); 5984 5985 auto duration = dur!"seconds"(12); 5986 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5987 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5988 assert(cst + duration == SysTime(DateTime(1999, 7, 6, 12, 30, 45))); 5989 //assert(ist + duration == SysTime(DateTime(1999, 7, 6, 12, 30, 45))); 5990 assert(cst - duration == SysTime(DateTime(1999, 7, 6, 12, 30, 21))); 5991 //assert(ist - duration == SysTime(DateTime(1999, 7, 6, 12, 30, 21))); 5992 } 5993 5994 5995 /++ 5996 Gives the result of adding or subtracting a $(REF Duration, core,time) from 5997 this $(LREF SysTime), as well as assigning the result to this 5998 $(LREF SysTime). 5999 6000 The legal types of arithmetic for $(LREF SysTime) using this operator are 6001 6002 $(BOOKTABLE, 6003 $(TR $(TD SysTime) $(TD +) $(TD Duration) $(TD -->) $(TD SysTime)) 6004 $(TR $(TD SysTime) $(TD -) $(TD Duration) $(TD -->) $(TD SysTime)) 6005 ) 6006 6007 Params: 6008 duration = The $(REF Duration, core,time) to add to or subtract from 6009 this $(LREF SysTime). 6010 +/ 6011 ref SysTime opOpAssign(string op)(Duration duration) @safe pure nothrow 6012 if (op == "+" || op == "-") 6013 { 6014 immutable hnsecs = duration.total!"hnsecs"; 6015 mixin("_stdTime " ~ op ~ "= hnsecs;"); 6016 return this; 6017 } 6018 6019 @safe unittest 6020 { 6021 auto before = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6022 assert(before + dur!"weeks"(7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33))); 6023 assert(before + dur!"weeks"(-7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33))); 6024 assert(before + dur!"days"(7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33))); 6025 assert(before + dur!"days"(-7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33))); 6026 6027 assert(before + dur!"hours"(7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33))); 6028 assert(before + dur!"hours"(-7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33))); 6029 assert(before + dur!"minutes"(7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33))); 6030 assert(before + dur!"minutes"(-7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33))); 6031 assert(before + dur!"seconds"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40))); 6032 assert(before + dur!"seconds"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26))); 6033 assert(before + dur!"msecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(7))); 6034 assert(before + dur!"msecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), msecs(993))); 6035 assert(before + dur!"usecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(7))); 6036 assert(before + dur!"usecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), usecs(999_993))); 6037 assert(before + dur!"hnsecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(7))); 6038 assert(before + dur!"hnsecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_993))); 6039 6040 assert(before - dur!"weeks"(-7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33))); 6041 assert(before - dur!"weeks"(7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33))); 6042 assert(before - dur!"days"(-7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33))); 6043 assert(before - dur!"days"(7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33))); 6044 6045 assert(before - dur!"hours"(-7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33))); 6046 assert(before - dur!"hours"(7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33))); 6047 assert(before - dur!"minutes"(-7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33))); 6048 assert(before - dur!"minutes"(7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33))); 6049 assert(before - dur!"seconds"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40))); 6050 assert(before - dur!"seconds"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26))); 6051 assert(before - dur!"msecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(7))); 6052 assert(before - dur!"msecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), msecs(993))); 6053 assert(before - dur!"usecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(7))); 6054 assert(before - dur!"usecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), usecs(999_993))); 6055 assert(before - dur!"hnsecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(7))); 6056 assert(before - dur!"hnsecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_993))); 6057 6058 static void testST(SysTime orig, long hnsecs, in SysTime expected, size_t line = __LINE__) 6059 { 6060 auto r = orig += dur!"hnsecs"(hnsecs); 6061 if (orig != expected) 6062 throw new AssertError(format("Failed 1. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 6063 if (r != expected) 6064 throw new AssertError(format("Failed 2. actual [%s] != expected [%s]", r, expected), __FILE__, line); 6065 } 6066 6067 // Test A.D. 6068 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274)); 6069 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274))); 6070 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(275))); 6071 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(276))); 6072 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(284))); 6073 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(374))); 6074 testST(beforeAD, 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(999))); 6075 testST(beforeAD, 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1000))); 6076 testST(beforeAD, 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1274))); 6077 testST(beforeAD, 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1275))); 6078 testST(beforeAD, 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2274))); 6079 testST(beforeAD, 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(26_999))); 6080 testST(beforeAD, 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_000))); 6081 testST(beforeAD, 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_001))); 6082 testST(beforeAD, 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_766_999))); 6083 testST(beforeAD, 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_767_000))); 6084 testST(beforeAD, 1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_000_274))); 6085 testST(beforeAD, 60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 39), hnsecs(274))); 6086 testST(beforeAD, 3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 36, 33), hnsecs(274))); 6087 testST(beforeAD, 600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 31, 33), hnsecs(274))); 6088 testST(beforeAD, 36_000_000_000L, SysTime(DateTime(1999, 7, 6, 13, 30, 33), hnsecs(274))); 6089 6090 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(273))); 6091 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(272))); 6092 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(264))); 6093 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(174))); 6094 testST(beforeAD, -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 6095 testST(beforeAD, -275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_999))); 6096 testST(beforeAD, -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_274))); 6097 testST(beforeAD, -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_273))); 6098 testST(beforeAD, -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_998_274))); 6099 testST(beforeAD, -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_967_000))); 6100 testST(beforeAD, -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_966_999))); 6101 testST(beforeAD, -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_167_000))); 6102 testST(beforeAD, -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_166_999))); 6103 testST(beforeAD, -1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_000_274))); 6104 testST(beforeAD, -60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 27), hnsecs(274))); 6105 testST(beforeAD, -3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 24, 33), hnsecs(274))); 6106 testST(beforeAD, -600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 29, 33), hnsecs(274))); 6107 testST(beforeAD, -36_000_000_000L, SysTime(DateTime(1999, 7, 6, 11, 30, 33), hnsecs(274))); 6108 6109 // Test B.C. 6110 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274)); 6111 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274))); 6112 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(275))); 6113 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(276))); 6114 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(284))); 6115 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(374))); 6116 testST(beforeBC, 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(999))); 6117 testST(beforeBC, 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1000))); 6118 testST(beforeBC, 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1274))); 6119 testST(beforeBC, 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1275))); 6120 testST(beforeBC, 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(2274))); 6121 testST(beforeBC, 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(26_999))); 6122 testST(beforeBC, 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_000))); 6123 testST(beforeBC, 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_001))); 6124 testST(beforeBC, 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_766_999))); 6125 testST(beforeBC, 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_767_000))); 6126 testST(beforeBC, 1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_000_274))); 6127 testST(beforeBC, 60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 39), hnsecs(274))); 6128 testST(beforeBC, 3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 36, 33), hnsecs(274))); 6129 testST(beforeBC, 600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), hnsecs(274))); 6130 testST(beforeBC, 36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), hnsecs(274))); 6131 6132 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(273))); 6133 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(272))); 6134 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(264))); 6135 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(174))); 6136 testST(beforeBC, -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 6137 testST(beforeBC, -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_999))); 6138 testST(beforeBC, -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_274))); 6139 testST(beforeBC, -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_273))); 6140 testST(beforeBC, -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_998_274))); 6141 testST(beforeBC, -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_967_000))); 6142 testST(beforeBC, -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_966_999))); 6143 testST(beforeBC, -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_167_000))); 6144 testST(beforeBC, -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_166_999))); 6145 testST(beforeBC, -1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_000_274))); 6146 testST(beforeBC, -60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 27), hnsecs(274))); 6147 testST(beforeBC, -3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 24, 33), hnsecs(274))); 6148 testST(beforeBC, -600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), hnsecs(274))); 6149 testST(beforeBC, -36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), hnsecs(274))); 6150 6151 // Test Both 6152 auto beforeBoth1 = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 6153 testST(beforeBoth1, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 6154 testST(beforeBoth1, 0, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6155 testST(beforeBoth1, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6156 testST(beforeBoth1, -2, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998))); 6157 testST(beforeBoth1, -1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_000))); 6158 testST(beforeBoth1, -2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_998_000))); 6159 testST(beforeBoth1, -2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_997_445))); 6160 testST(beforeBoth1, -1_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_000_000))); 6161 testST(beforeBoth1, -2_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(8_000_000))); 6162 testST(beforeBoth1, -2_333_333, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(7_666_667))); 6163 testST(beforeBoth1, -10_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59))); 6164 testST(beforeBoth1, -20_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 58))); 6165 testST(beforeBoth1, -20_888_888, SysTime(DateTime(0, 12, 31, 23, 59, 57), hnsecs(9_111_112))); 6166 6167 auto beforeBoth2 = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 6168 testST(beforeBoth2, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998))); 6169 testST(beforeBoth2, 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6170 testST(beforeBoth2, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6171 testST(beforeBoth2, 2, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 6172 testST(beforeBoth2, 1000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999))); 6173 testST(beforeBoth2, 2000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1999))); 6174 testST(beforeBoth2, 2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2554))); 6175 testST(beforeBoth2, 1_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999_999))); 6176 testST(beforeBoth2, 2_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1_999_999))); 6177 testST(beforeBoth2, 2_333_333, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2_333_332))); 6178 testST(beforeBoth2, 10_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 6179 testST(beforeBoth2, 20_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 1), hnsecs(9_999_999))); 6180 testST(beforeBoth2, 20_888_888, SysTime(DateTime(1, 1, 1, 0, 0, 2), hnsecs(888_887))); 6181 6182 { 6183 auto st = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 6184 (st += dur!"hnsecs"(52)) += dur!"seconds"(-907); 6185 assert(st == SysTime(DateTime(0, 12, 31, 23, 44, 53), hnsecs(51))); 6186 } 6187 6188 auto duration = dur!"seconds"(12); 6189 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6190 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6191 static assert(!__traits(compiles, cst += duration)); 6192 //static assert(!__traits(compiles, ist += duration)); 6193 static assert(!__traits(compiles, cst -= duration)); 6194 //static assert(!__traits(compiles, ist -= duration)); 6195 } 6196 6197 6198 /++ 6199 Gives the difference between two $(LREF SysTime)s. 6200 6201 The legal types of arithmetic for $(LREF SysTime) using this operator 6202 are 6203 6204 $(BOOKTABLE, 6205 $(TR $(TD SysTime) $(TD -) $(TD SysTime) $(TD -->) $(TD duration)) 6206 ) 6207 +/ 6208 Duration opBinary(string op)(in SysTime rhs) @safe const pure nothrow 6209 if (op == "-") 6210 { 6211 return dur!"hnsecs"(_stdTime - rhs._stdTime); 6212 } 6213 6214 @safe unittest 6215 { 6216 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1998, 7, 6, 12, 30, 33)) == 6217 dur!"seconds"(31_536_000)); 6218 assert(SysTime(DateTime(1998, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6219 dur!"seconds"(-31_536_000)); 6220 6221 assert(SysTime(DateTime(1999, 8, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6222 dur!"seconds"(26_78_400)); 6223 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 8, 6, 12, 30, 33)) == 6224 dur!"seconds"(-26_78_400)); 6225 6226 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 5, 12, 30, 33)) == 6227 dur!"seconds"(86_400)); 6228 assert(SysTime(DateTime(1999, 7, 5, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6229 dur!"seconds"(-86_400)); 6230 6231 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 11, 30, 33)) == 6232 dur!"seconds"(3600)); 6233 assert(SysTime(DateTime(1999, 7, 6, 11, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6234 dur!"seconds"(-3600)); 6235 6236 assert(SysTime(DateTime(1999, 7, 6, 12, 31, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6237 dur!"seconds"(60)); 6238 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 31, 33)) == 6239 dur!"seconds"(-60)); 6240 6241 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 34)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6242 dur!"seconds"(1)); 6243 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 34)) == 6244 dur!"seconds"(-1)); 6245 6246 { 6247 auto dt = DateTime(1999, 7, 6, 12, 30, 33); 6248 assert(SysTime(dt, msecs(532)) - SysTime(dt) == msecs(532)); 6249 assert(SysTime(dt) - SysTime(dt, msecs(532)) == msecs(-532)); 6250 6251 assert(SysTime(dt, usecs(333_347)) - SysTime(dt) == usecs(333_347)); 6252 assert(SysTime(dt) - SysTime(dt, usecs(333_347)) == usecs(-333_347)); 6253 6254 assert(SysTime(dt, hnsecs(1_234_567)) - SysTime(dt) == hnsecs(1_234_567)); 6255 assert(SysTime(dt) - SysTime(dt, hnsecs(1_234_567)) == hnsecs(-1_234_567)); 6256 } 6257 6258 assert(SysTime(DateTime(1, 1, 1, 12, 30, 33)) - SysTime(DateTime(1, 1, 1, 0, 0, 0)) == dur!"seconds"(45033)); 6259 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)) - SysTime(DateTime(1, 1, 1, 12, 30, 33)) == dur!"seconds"(-45033)); 6260 assert(SysTime(DateTime(0, 12, 31, 12, 30, 33)) - SysTime(DateTime(1, 1, 1, 0, 0, 0)) == dur!"seconds"(-41367)); 6261 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)) - SysTime(DateTime(0, 12, 31, 12, 30, 33)) == dur!"seconds"(41367)); 6262 6263 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)) - SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)) == 6264 dur!"hnsecs"(1)); 6265 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)) - SysTime(DateTime(1, 1, 1, 0, 0, 0)) == 6266 dur!"hnsecs"(-1)); 6267 6268 version (Posix) 6269 immutable tz = PosixTimeZone.getTimeZone("America/Los_Angeles"); 6270 else version (Windows) 6271 immutable tz = WindowsTimeZone.getTimeZone("Pacific Standard Time"); 6272 6273 { 6274 auto dt = DateTime(2011, 1, 13, 8, 17, 2); 6275 auto d = msecs(296); 6276 assert(SysTime(dt, d, tz) - SysTime(dt, d, tz) == Duration.zero); 6277 assert(SysTime(dt, d, tz) - SysTime(dt, d, UTC()) == hours(8)); 6278 assert(SysTime(dt, d, UTC()) - SysTime(dt, d, tz) == hours(-8)); 6279 } 6280 6281 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6282 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6283 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6284 assert(st - st == Duration.zero); 6285 assert(cst - st == Duration.zero); 6286 //assert(ist - st == Duration.zero); 6287 6288 assert(st - cst == Duration.zero); 6289 assert(cst - cst == Duration.zero); 6290 //assert(ist - cst == Duration.zero); 6291 6292 //assert(st - ist == Duration.zero); 6293 //assert(cst - ist == Duration.zero); 6294 //assert(ist - ist == Duration.zero); 6295 } 6296 6297 6298 /++ 6299 Returns the difference between the two $(LREF SysTime)s in months. 6300 6301 To get the difference in years, subtract the year property 6302 of two $(LREF SysTime)s. To get the difference in days or weeks, 6303 subtract the $(LREF SysTime)s themselves and use the 6304 $(REF Duration, core,time) that results. Because converting between 6305 months and smaller units requires a specific date (which 6306 $(REF Duration, core,time)s don't have), getting the difference in 6307 months requires some math using both the year and month properties, so 6308 this is a convenience function for getting the difference in months. 6309 6310 Note that the number of days in the months or how far into the month 6311 either date is is irrelevant. It is the difference in the month property 6312 combined with the difference in years * 12. So, for instance, 6313 December 31st and January 1st are one month apart just as December 1st 6314 and January 31st are one month apart. 6315 6316 Params: 6317 rhs = The $(LREF SysTime) to subtract from this one. 6318 +/ 6319 int diffMonths(in SysTime rhs) @safe const nothrow 6320 { 6321 return (cast(Date) this).diffMonths(cast(Date) rhs); 6322 } 6323 6324 /// 6325 @safe unittest 6326 { 6327 import std.datetime.date : Date; 6328 6329 assert(SysTime(Date(1999, 2, 1)).diffMonths( 6330 SysTime(Date(1999, 1, 31))) == 1); 6331 6332 assert(SysTime(Date(1999, 1, 31)).diffMonths( 6333 SysTime(Date(1999, 2, 1))) == -1); 6334 6335 assert(SysTime(Date(1999, 3, 1)).diffMonths( 6336 SysTime(Date(1999, 1, 1))) == 2); 6337 6338 assert(SysTime(Date(1999, 1, 1)).diffMonths( 6339 SysTime(Date(1999, 3, 31))) == -2); 6340 } 6341 6342 @safe unittest 6343 { 6344 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6345 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6346 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6347 assert(st.diffMonths(st) == 0); 6348 assert(cst.diffMonths(st) == 0); 6349 //assert(ist.diffMonths(st) == 0); 6350 6351 assert(st.diffMonths(cst) == 0); 6352 assert(cst.diffMonths(cst) == 0); 6353 //assert(ist.diffMonths(cst) == 0); 6354 6355 //assert(st.diffMonths(ist) == 0); 6356 //assert(cst.diffMonths(ist) == 0); 6357 //assert(ist.diffMonths(ist) == 0); 6358 } 6359 6360 6361 /++ 6362 Whether this $(LREF SysTime) is in a leap year. 6363 +/ 6364 @property bool isLeapYear() @safe const nothrow 6365 { 6366 return (cast(Date) this).isLeapYear; 6367 } 6368 6369 @safe unittest 6370 { 6371 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6372 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6373 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6374 assert(!st.isLeapYear); 6375 assert(!cst.isLeapYear); 6376 //assert(!ist.isLeapYear); 6377 } 6378 6379 6380 /++ 6381 Day of the week this $(LREF SysTime) is on. 6382 +/ 6383 @property DayOfWeek dayOfWeek() @safe const nothrow 6384 { 6385 return getDayOfWeek(dayOfGregorianCal); 6386 } 6387 6388 @safe unittest 6389 { 6390 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6391 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6392 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6393 assert(st.dayOfWeek == DayOfWeek.tue); 6394 assert(cst.dayOfWeek == DayOfWeek.tue); 6395 //assert(ist.dayOfWeek == DayOfWeek.tue); 6396 } 6397 6398 6399 /++ 6400 Day of the year this $(LREF SysTime) is on. 6401 +/ 6402 @property ushort dayOfYear() @safe const nothrow 6403 { 6404 return (cast(Date) this).dayOfYear; 6405 } 6406 6407 /// 6408 @safe unittest 6409 { 6410 import std.datetime.date : DateTime; 6411 6412 assert(SysTime(DateTime(1999, 1, 1, 12, 22, 7)).dayOfYear == 1); 6413 assert(SysTime(DateTime(1999, 12, 31, 7, 2, 59)).dayOfYear == 365); 6414 assert(SysTime(DateTime(2000, 12, 31, 21, 20, 0)).dayOfYear == 366); 6415 } 6416 6417 @safe unittest 6418 { 6419 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6420 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6421 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6422 assert(st.dayOfYear == 187); 6423 assert(cst.dayOfYear == 187); 6424 //assert(ist.dayOfYear == 187); 6425 } 6426 6427 6428 /++ 6429 Day of the year. 6430 6431 Params: 6432 day = The day of the year to set which day of the year this 6433 $(LREF SysTime) is on. 6434 +/ 6435 @property void dayOfYear(int day) @safe 6436 { 6437 immutable hnsecs = adjTime; 6438 immutable days = convert!("hnsecs", "days")(hnsecs); 6439 immutable theRest = hnsecs - convert!("days", "hnsecs")(days); 6440 6441 auto date = Date(cast(int) days); 6442 date.dayOfYear = day; 6443 6444 immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1); 6445 6446 adjTime = newDaysHNSecs + theRest; 6447 } 6448 6449 @safe unittest 6450 { 6451 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6452 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6453 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6454 st.dayOfYear = 12; 6455 assert(st.dayOfYear == 12); 6456 static assert(!__traits(compiles, cst.dayOfYear = 12)); 6457 //static assert(!__traits(compiles, ist.dayOfYear = 12)); 6458 } 6459 6460 6461 /++ 6462 The Xth day of the Gregorian Calendar that this $(LREF SysTime) is on. 6463 +/ 6464 @property int dayOfGregorianCal() @safe const nothrow 6465 { 6466 immutable adjustedTime = adjTime; 6467 6468 // We have to add one because 0 would be midnight, January 1st, 1 A.D., 6469 // which would be the 1st day of the Gregorian Calendar, not the 0th. So, 6470 // simply casting to days is one day off. 6471 if (adjustedTime > 0) 6472 return cast(int) getUnitsFromHNSecs!"days"(adjustedTime) + 1; 6473 6474 long hnsecs = adjustedTime; 6475 immutable days = cast(int) splitUnitsFromHNSecs!"days"(hnsecs); 6476 6477 return hnsecs == 0 ? days + 1 : days; 6478 } 6479 6480 /// 6481 @safe unittest 6482 { 6483 import std.datetime.date : DateTime; 6484 6485 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).dayOfGregorianCal == 1); 6486 assert(SysTime(DateTime(1, 12, 31, 23, 59, 59)).dayOfGregorianCal == 365); 6487 assert(SysTime(DateTime(2, 1, 1, 2, 2, 2)).dayOfGregorianCal == 366); 6488 6489 assert(SysTime(DateTime(0, 12, 31, 7, 7, 7)).dayOfGregorianCal == 0); 6490 assert(SysTime(DateTime(0, 1, 1, 19, 30, 0)).dayOfGregorianCal == -365); 6491 assert(SysTime(DateTime(-1, 12, 31, 4, 7, 0)).dayOfGregorianCal == -366); 6492 6493 assert(SysTime(DateTime(2000, 1, 1, 9, 30, 20)).dayOfGregorianCal == 730_120); 6494 assert(SysTime(DateTime(2010, 12, 31, 15, 45, 50)).dayOfGregorianCal == 734_137); 6495 } 6496 6497 @safe unittest 6498 { 6499 // Test A.D. 6500 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).dayOfGregorianCal == 1); 6501 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1)).dayOfGregorianCal == 1); 6502 assert(SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)).dayOfGregorianCal == 1); 6503 6504 assert(SysTime(DateTime(1, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 1); 6505 assert(SysTime(DateTime(1, 1, 2, 12, 2, 9), msecs(212)).dayOfGregorianCal == 2); 6506 assert(SysTime(DateTime(1, 2, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 32); 6507 assert(SysTime(DateTime(2, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 366); 6508 assert(SysTime(DateTime(3, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 731); 6509 assert(SysTime(DateTime(4, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 1096); 6510 assert(SysTime(DateTime(5, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 1462); 6511 assert(SysTime(DateTime(50, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 17_898); 6512 assert(SysTime(DateTime(97, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 35_065); 6513 assert(SysTime(DateTime(100, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 36_160); 6514 assert(SysTime(DateTime(101, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 36_525); 6515 assert(SysTime(DateTime(105, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 37_986); 6516 assert(SysTime(DateTime(200, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 72_684); 6517 assert(SysTime(DateTime(201, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 73_049); 6518 assert(SysTime(DateTime(300, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 109_208); 6519 assert(SysTime(DateTime(301, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 109_573); 6520 assert(SysTime(DateTime(400, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 145_732); 6521 assert(SysTime(DateTime(401, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 146_098); 6522 assert(SysTime(DateTime(500, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 182_257); 6523 assert(SysTime(DateTime(501, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 182_622); 6524 assert(SysTime(DateTime(1000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 364_878); 6525 assert(SysTime(DateTime(1001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 365_243); 6526 assert(SysTime(DateTime(1600, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 584_023); 6527 assert(SysTime(DateTime(1601, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 584_389); 6528 assert(SysTime(DateTime(1900, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 693_596); 6529 assert(SysTime(DateTime(1901, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 693_961); 6530 assert(SysTime(DateTime(1945, 11, 12, 12, 2, 9), msecs(212)).dayOfGregorianCal == 710_347); 6531 assert(SysTime(DateTime(1999, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 729_755); 6532 assert(SysTime(DateTime(2000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 730_120); 6533 assert(SysTime(DateTime(2001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 730_486); 6534 6535 assert(SysTime(DateTime(2010, 1, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_773); 6536 assert(SysTime(DateTime(2010, 1, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_803); 6537 assert(SysTime(DateTime(2010, 2, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_804); 6538 assert(SysTime(DateTime(2010, 2, 28, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_831); 6539 assert(SysTime(DateTime(2010, 3, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_832); 6540 assert(SysTime(DateTime(2010, 3, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_862); 6541 assert(SysTime(DateTime(2010, 4, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_863); 6542 assert(SysTime(DateTime(2010, 4, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_892); 6543 assert(SysTime(DateTime(2010, 5, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_893); 6544 assert(SysTime(DateTime(2010, 5, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_923); 6545 assert(SysTime(DateTime(2010, 6, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_924); 6546 assert(SysTime(DateTime(2010, 6, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_953); 6547 assert(SysTime(DateTime(2010, 7, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_954); 6548 assert(SysTime(DateTime(2010, 7, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_984); 6549 assert(SysTime(DateTime(2010, 8, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_985); 6550 assert(SysTime(DateTime(2010, 8, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_015); 6551 assert(SysTime(DateTime(2010, 9, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_016); 6552 assert(SysTime(DateTime(2010, 9, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_045); 6553 assert(SysTime(DateTime(2010, 10, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_046); 6554 assert(SysTime(DateTime(2010, 10, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_076); 6555 assert(SysTime(DateTime(2010, 11, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_077); 6556 assert(SysTime(DateTime(2010, 11, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_106); 6557 assert(SysTime(DateTime(2010, 12, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_107); 6558 assert(SysTime(DateTime(2010, 12, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_137); 6559 6560 assert(SysTime(DateTime(2012, 2, 1, 0, 0, 0)).dayOfGregorianCal == 734_534); 6561 assert(SysTime(DateTime(2012, 2, 28, 0, 0, 0)).dayOfGregorianCal == 734_561); 6562 assert(SysTime(DateTime(2012, 2, 29, 0, 0, 0)).dayOfGregorianCal == 734_562); 6563 assert(SysTime(DateTime(2012, 3, 1, 0, 0, 0)).dayOfGregorianCal == 734_563); 6564 6565 // Test B.C. 6566 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)).dayOfGregorianCal == 0); 6567 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998)).dayOfGregorianCal == 0); 6568 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59)).dayOfGregorianCal == 0); 6569 assert(SysTime(DateTime(0, 12, 31, 0, 0, 0), hnsecs(1)).dayOfGregorianCal == 0); 6570 assert(SysTime(DateTime(0, 12, 31, 0, 0, 0)).dayOfGregorianCal == 0); 6571 6572 assert(SysTime(DateTime(-1, 12, 31, 23, 59, 59), hnsecs(9_999_999)).dayOfGregorianCal == -366); 6573 assert(SysTime(DateTime(-1, 12, 31, 23, 59, 59), hnsecs(9_999_998)).dayOfGregorianCal == -366); 6574 assert(SysTime(DateTime(-1, 12, 31, 23, 59, 59)).dayOfGregorianCal == -366); 6575 assert(SysTime(DateTime(-1, 12, 31, 0, 0, 0)).dayOfGregorianCal == -366); 6576 6577 assert(SysTime(DateTime(0, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == 0); 6578 assert(SysTime(DateTime(0, 12, 30, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1); 6579 assert(SysTime(DateTime(0, 12, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -30); 6580 assert(SysTime(DateTime(0, 11, 30, 12, 2, 9), msecs(212)).dayOfGregorianCal == -31); 6581 6582 assert(SysTime(DateTime(-1, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -366); 6583 assert(SysTime(DateTime(-1, 12, 30, 12, 2, 9), msecs(212)).dayOfGregorianCal == -367); 6584 assert(SysTime(DateTime(-1, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730); 6585 assert(SysTime(DateTime(-2, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -731); 6586 assert(SysTime(DateTime(-2, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1095); 6587 assert(SysTime(DateTime(-3, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1096); 6588 assert(SysTime(DateTime(-3, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1460); 6589 assert(SysTime(DateTime(-4, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1461); 6590 assert(SysTime(DateTime(-4, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1826); 6591 assert(SysTime(DateTime(-5, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1827); 6592 assert(SysTime(DateTime(-5, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -2191); 6593 assert(SysTime(DateTime(-9, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -3652); 6594 6595 assert(SysTime(DateTime(-49, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -18_262); 6596 assert(SysTime(DateTime(-50, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -18_627); 6597 assert(SysTime(DateTime(-97, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -35_794); 6598 assert(SysTime(DateTime(-99, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -36_160); 6599 assert(SysTime(DateTime(-99, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -36_524); 6600 assert(SysTime(DateTime(-100, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -36_889); 6601 assert(SysTime(DateTime(-101, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -37_254); 6602 assert(SysTime(DateTime(-105, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -38_715); 6603 assert(SysTime(DateTime(-200, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -73_413); 6604 assert(SysTime(DateTime(-201, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -73_778); 6605 assert(SysTime(DateTime(-300, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -109_937); 6606 assert(SysTime(DateTime(-301, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -110_302); 6607 assert(SysTime(DateTime(-400, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -146_097); 6608 assert(SysTime(DateTime(-400, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -146_462); 6609 assert(SysTime(DateTime(-401, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -146_827); 6610 assert(SysTime(DateTime(-499, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -182_621); 6611 assert(SysTime(DateTime(-500, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -182_986); 6612 assert(SysTime(DateTime(-501, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -183_351); 6613 assert(SysTime(DateTime(-1000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -365_607); 6614 assert(SysTime(DateTime(-1001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -365_972); 6615 assert(SysTime(DateTime(-1599, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -584_387); 6616 assert(SysTime(DateTime(-1600, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -584_388); 6617 assert(SysTime(DateTime(-1600, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -584_753); 6618 assert(SysTime(DateTime(-1601, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -585_118); 6619 assert(SysTime(DateTime(-1900, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -694_325); 6620 assert(SysTime(DateTime(-1901, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -694_690); 6621 assert(SysTime(DateTime(-1999, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730_484); 6622 assert(SysTime(DateTime(-2000, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730_485); 6623 assert(SysTime(DateTime(-2000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730_850); 6624 assert(SysTime(DateTime(-2001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -731_215); 6625 6626 assert(SysTime(DateTime(-2010, 1, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_502); 6627 assert(SysTime(DateTime(-2010, 1, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_472); 6628 assert(SysTime(DateTime(-2010, 2, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_471); 6629 assert(SysTime(DateTime(-2010, 2, 28, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_444); 6630 assert(SysTime(DateTime(-2010, 3, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_443); 6631 assert(SysTime(DateTime(-2010, 3, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_413); 6632 assert(SysTime(DateTime(-2010, 4, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_412); 6633 assert(SysTime(DateTime(-2010, 4, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_383); 6634 assert(SysTime(DateTime(-2010, 5, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_382); 6635 assert(SysTime(DateTime(-2010, 5, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_352); 6636 assert(SysTime(DateTime(-2010, 6, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_351); 6637 assert(SysTime(DateTime(-2010, 6, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_322); 6638 assert(SysTime(DateTime(-2010, 7, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_321); 6639 assert(SysTime(DateTime(-2010, 7, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_291); 6640 assert(SysTime(DateTime(-2010, 8, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_290); 6641 assert(SysTime(DateTime(-2010, 8, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_260); 6642 assert(SysTime(DateTime(-2010, 9, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_259); 6643 assert(SysTime(DateTime(-2010, 9, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_230); 6644 assert(SysTime(DateTime(-2010, 10, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_229); 6645 assert(SysTime(DateTime(-2010, 10, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_199); 6646 assert(SysTime(DateTime(-2010, 11, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_198); 6647 assert(SysTime(DateTime(-2010, 11, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_169); 6648 assert(SysTime(DateTime(-2010, 12, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_168); 6649 assert(SysTime(DateTime(-2010, 12, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_138); 6650 6651 assert(SysTime(DateTime(-2012, 2, 1, 0, 0, 0)).dayOfGregorianCal == -735_202); 6652 assert(SysTime(DateTime(-2012, 2, 28, 0, 0, 0)).dayOfGregorianCal == -735_175); 6653 assert(SysTime(DateTime(-2012, 2, 29, 0, 0, 0)).dayOfGregorianCal == -735_174); 6654 assert(SysTime(DateTime(-2012, 3, 1, 0, 0, 0)).dayOfGregorianCal == -735_173); 6655 6656 // Start of Hebrew Calendar 6657 assert(SysTime(DateTime(-3760, 9, 7, 0, 0, 0)).dayOfGregorianCal == -1_373_427); 6658 6659 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6660 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6661 assert(cst.dayOfGregorianCal == 729_941); 6662 //assert(ist.dayOfGregorianCal == 729_941); 6663 } 6664 6665 6666 // Test that the logic for the day of the Gregorian Calendar is consistent 6667 // between Date and SysTime. 6668 @safe unittest 6669 { 6670 void test(Date date, SysTime st, size_t line = __LINE__) 6671 { 6672 if (date.dayOfGregorianCal != st.dayOfGregorianCal) 6673 { 6674 throw new AssertError(format("Date [%s] SysTime [%s]", date.dayOfGregorianCal, st.dayOfGregorianCal), 6675 __FILE__, line); 6676 } 6677 } 6678 6679 // Test A.D. 6680 test(Date(1, 1, 1), SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6681 test(Date(1, 1, 2), SysTime(DateTime(1, 1, 2, 0, 0, 0), hnsecs(500))); 6682 test(Date(1, 2, 1), SysTime(DateTime(1, 2, 1, 0, 0, 0), hnsecs(50_000))); 6683 test(Date(2, 1, 1), SysTime(DateTime(2, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 6684 test(Date(3, 1, 1), SysTime(DateTime(3, 1, 1, 12, 13, 14))); 6685 test(Date(4, 1, 1), SysTime(DateTime(4, 1, 1, 12, 13, 14), hnsecs(500))); 6686 test(Date(5, 1, 1), SysTime(DateTime(5, 1, 1, 12, 13, 14), hnsecs(50_000))); 6687 test(Date(50, 1, 1), SysTime(DateTime(50, 1, 1, 12, 13, 14), hnsecs(9_999_999))); 6688 test(Date(97, 1, 1), SysTime(DateTime(97, 1, 1, 23, 59, 59))); 6689 test(Date(100, 1, 1), SysTime(DateTime(100, 1, 1, 23, 59, 59), hnsecs(500))); 6690 test(Date(101, 1, 1), SysTime(DateTime(101, 1, 1, 23, 59, 59), hnsecs(50_000))); 6691 test(Date(105, 1, 1), SysTime(DateTime(105, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 6692 test(Date(200, 1, 1), SysTime(DateTime(200, 1, 1, 0, 0, 0))); 6693 test(Date(201, 1, 1), SysTime(DateTime(201, 1, 1, 0, 0, 0), hnsecs(500))); 6694 test(Date(300, 1, 1), SysTime(DateTime(300, 1, 1, 0, 0, 0), hnsecs(50_000))); 6695 test(Date(301, 1, 1), SysTime(DateTime(301, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 6696 test(Date(400, 1, 1), SysTime(DateTime(400, 1, 1, 12, 13, 14))); 6697 test(Date(401, 1, 1), SysTime(DateTime(401, 1, 1, 12, 13, 14), hnsecs(500))); 6698 test(Date(500, 1, 1), SysTime(DateTime(500, 1, 1, 12, 13, 14), hnsecs(50_000))); 6699 test(Date(501, 1, 1), SysTime(DateTime(501, 1, 1, 12, 13, 14), hnsecs(9_999_999))); 6700 test(Date(1000, 1, 1), SysTime(DateTime(1000, 1, 1, 23, 59, 59))); 6701 test(Date(1001, 1, 1), SysTime(DateTime(1001, 1, 1, 23, 59, 59), hnsecs(500))); 6702 test(Date(1600, 1, 1), SysTime(DateTime(1600, 1, 1, 23, 59, 59), hnsecs(50_000))); 6703 test(Date(1601, 1, 1), SysTime(DateTime(1601, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 6704 test(Date(1900, 1, 1), SysTime(DateTime(1900, 1, 1, 0, 0, 0))); 6705 test(Date(1901, 1, 1), SysTime(DateTime(1901, 1, 1, 0, 0, 0), hnsecs(500))); 6706 test(Date(1945, 11, 12), SysTime(DateTime(1945, 11, 12, 0, 0, 0), hnsecs(50_000))); 6707 test(Date(1999, 1, 1), SysTime(DateTime(1999, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 6708 test(Date(1999, 7, 6), SysTime(DateTime(1999, 7, 6, 12, 13, 14))); 6709 test(Date(2000, 1, 1), SysTime(DateTime(2000, 1, 1, 12, 13, 14), hnsecs(500))); 6710 test(Date(2001, 1, 1), SysTime(DateTime(2001, 1, 1, 12, 13, 14), hnsecs(50_000))); 6711 6712 test(Date(2010, 1, 1), SysTime(DateTime(2010, 1, 1, 12, 13, 14), hnsecs(9_999_999))); 6713 test(Date(2010, 1, 31), SysTime(DateTime(2010, 1, 31, 23, 0, 0))); 6714 test(Date(2010, 2, 1), SysTime(DateTime(2010, 2, 1, 23, 59, 59), hnsecs(500))); 6715 test(Date(2010, 2, 28), SysTime(DateTime(2010, 2, 28, 23, 59, 59), hnsecs(50_000))); 6716 test(Date(2010, 3, 1), SysTime(DateTime(2010, 3, 1, 23, 59, 59), hnsecs(9_999_999))); 6717 test(Date(2010, 3, 31), SysTime(DateTime(2010, 3, 31, 0, 0, 0))); 6718 test(Date(2010, 4, 1), SysTime(DateTime(2010, 4, 1, 0, 0, 0), hnsecs(500))); 6719 test(Date(2010, 4, 30), SysTime(DateTime(2010, 4, 30, 0, 0, 0), hnsecs(50_000))); 6720 test(Date(2010, 5, 1), SysTime(DateTime(2010, 5, 1, 0, 0, 0), hnsecs(9_999_999))); 6721 test(Date(2010, 5, 31), SysTime(DateTime(2010, 5, 31, 12, 13, 14))); 6722 test(Date(2010, 6, 1), SysTime(DateTime(2010, 6, 1, 12, 13, 14), hnsecs(500))); 6723 test(Date(2010, 6, 30), SysTime(DateTime(2010, 6, 30, 12, 13, 14), hnsecs(50_000))); 6724 test(Date(2010, 7, 1), SysTime(DateTime(2010, 7, 1, 12, 13, 14), hnsecs(9_999_999))); 6725 test(Date(2010, 7, 31), SysTime(DateTime(2010, 7, 31, 23, 59, 59))); 6726 test(Date(2010, 8, 1), SysTime(DateTime(2010, 8, 1, 23, 59, 59), hnsecs(500))); 6727 test(Date(2010, 8, 31), SysTime(DateTime(2010, 8, 31, 23, 59, 59), hnsecs(50_000))); 6728 test(Date(2010, 9, 1), SysTime(DateTime(2010, 9, 1, 23, 59, 59), hnsecs(9_999_999))); 6729 test(Date(2010, 9, 30), SysTime(DateTime(2010, 9, 30, 12, 0, 0))); 6730 test(Date(2010, 10, 1), SysTime(DateTime(2010, 10, 1, 0, 12, 0), hnsecs(500))); 6731 test(Date(2010, 10, 31), SysTime(DateTime(2010, 10, 31, 0, 0, 12), hnsecs(50_000))); 6732 test(Date(2010, 11, 1), SysTime(DateTime(2010, 11, 1, 23, 0, 0), hnsecs(9_999_999))); 6733 test(Date(2010, 11, 30), SysTime(DateTime(2010, 11, 30, 0, 59, 0))); 6734 test(Date(2010, 12, 1), SysTime(DateTime(2010, 12, 1, 0, 0, 59), hnsecs(500))); 6735 test(Date(2010, 12, 31), SysTime(DateTime(2010, 12, 31, 0, 59, 59), hnsecs(50_000))); 6736 6737 test(Date(2012, 2, 1), SysTime(DateTime(2012, 2, 1, 23, 0, 59), hnsecs(9_999_999))); 6738 test(Date(2012, 2, 28), SysTime(DateTime(2012, 2, 28, 23, 59, 0))); 6739 test(Date(2012, 2, 29), SysTime(DateTime(2012, 2, 29, 7, 7, 7), hnsecs(7))); 6740 test(Date(2012, 3, 1), SysTime(DateTime(2012, 3, 1, 7, 7, 7), hnsecs(7))); 6741 6742 // Test B.C. 6743 test(Date(0, 12, 31), SysTime(DateTime(0, 12, 31, 0, 0, 0))); 6744 test(Date(0, 12, 30), SysTime(DateTime(0, 12, 30, 0, 0, 0), hnsecs(500))); 6745 test(Date(0, 12, 1), SysTime(DateTime(0, 12, 1, 0, 0, 0), hnsecs(50_000))); 6746 test(Date(0, 11, 30), SysTime(DateTime(0, 11, 30, 0, 0, 0), hnsecs(9_999_999))); 6747 6748 test(Date(-1, 12, 31), SysTime(DateTime(-1, 12, 31, 12, 13, 14))); 6749 test(Date(-1, 12, 30), SysTime(DateTime(-1, 12, 30, 12, 13, 14), hnsecs(500))); 6750 test(Date(-1, 1, 1), SysTime(DateTime(-1, 1, 1, 12, 13, 14), hnsecs(50_000))); 6751 test(Date(-2, 12, 31), SysTime(DateTime(-2, 12, 31, 12, 13, 14), hnsecs(9_999_999))); 6752 test(Date(-2, 1, 1), SysTime(DateTime(-2, 1, 1, 23, 59, 59))); 6753 test(Date(-3, 12, 31), SysTime(DateTime(-3, 12, 31, 23, 59, 59), hnsecs(500))); 6754 test(Date(-3, 1, 1), SysTime(DateTime(-3, 1, 1, 23, 59, 59), hnsecs(50_000))); 6755 test(Date(-4, 12, 31), SysTime(DateTime(-4, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6756 test(Date(-4, 1, 1), SysTime(DateTime(-4, 1, 1, 0, 0, 0))); 6757 test(Date(-5, 12, 31), SysTime(DateTime(-5, 12, 31, 0, 0, 0), hnsecs(500))); 6758 test(Date(-5, 1, 1), SysTime(DateTime(-5, 1, 1, 0, 0, 0), hnsecs(50_000))); 6759 test(Date(-9, 1, 1), SysTime(DateTime(-9, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 6760 6761 test(Date(-49, 1, 1), SysTime(DateTime(-49, 1, 1, 12, 13, 14))); 6762 test(Date(-50, 1, 1), SysTime(DateTime(-50, 1, 1, 12, 13, 14), hnsecs(500))); 6763 test(Date(-97, 1, 1), SysTime(DateTime(-97, 1, 1, 12, 13, 14), hnsecs(50_000))); 6764 test(Date(-99, 12, 31), SysTime(DateTime(-99, 12, 31, 12, 13, 14), hnsecs(9_999_999))); 6765 test(Date(-99, 1, 1), SysTime(DateTime(-99, 1, 1, 23, 59, 59))); 6766 test(Date(-100, 1, 1), SysTime(DateTime(-100, 1, 1, 23, 59, 59), hnsecs(500))); 6767 test(Date(-101, 1, 1), SysTime(DateTime(-101, 1, 1, 23, 59, 59), hnsecs(50_000))); 6768 test(Date(-105, 1, 1), SysTime(DateTime(-105, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 6769 test(Date(-200, 1, 1), SysTime(DateTime(-200, 1, 1, 0, 0, 0))); 6770 test(Date(-201, 1, 1), SysTime(DateTime(-201, 1, 1, 0, 0, 0), hnsecs(500))); 6771 test(Date(-300, 1, 1), SysTime(DateTime(-300, 1, 1, 0, 0, 0), hnsecs(50_000))); 6772 test(Date(-301, 1, 1), SysTime(DateTime(-301, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 6773 test(Date(-400, 12, 31), SysTime(DateTime(-400, 12, 31, 12, 13, 14))); 6774 test(Date(-400, 1, 1), SysTime(DateTime(-400, 1, 1, 12, 13, 14), hnsecs(500))); 6775 test(Date(-401, 1, 1), SysTime(DateTime(-401, 1, 1, 12, 13, 14), hnsecs(50_000))); 6776 test(Date(-499, 1, 1), SysTime(DateTime(-499, 1, 1, 12, 13, 14), hnsecs(9_999_999))); 6777 test(Date(-500, 1, 1), SysTime(DateTime(-500, 1, 1, 23, 59, 59))); 6778 test(Date(-501, 1, 1), SysTime(DateTime(-501, 1, 1, 23, 59, 59), hnsecs(500))); 6779 test(Date(-1000, 1, 1), SysTime(DateTime(-1000, 1, 1, 23, 59, 59), hnsecs(50_000))); 6780 test(Date(-1001, 1, 1), SysTime(DateTime(-1001, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 6781 test(Date(-1599, 1, 1), SysTime(DateTime(-1599, 1, 1, 0, 0, 0))); 6782 test(Date(-1600, 12, 31), SysTime(DateTime(-1600, 12, 31, 0, 0, 0), hnsecs(500))); 6783 test(Date(-1600, 1, 1), SysTime(DateTime(-1600, 1, 1, 0, 0, 0), hnsecs(50_000))); 6784 test(Date(-1601, 1, 1), SysTime(DateTime(-1601, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 6785 test(Date(-1900, 1, 1), SysTime(DateTime(-1900, 1, 1, 12, 13, 14))); 6786 test(Date(-1901, 1, 1), SysTime(DateTime(-1901, 1, 1, 12, 13, 14), hnsecs(500))); 6787 test(Date(-1999, 1, 1), SysTime(DateTime(-1999, 1, 1, 12, 13, 14), hnsecs(50_000))); 6788 test(Date(-1999, 7, 6), SysTime(DateTime(-1999, 7, 6, 12, 13, 14), hnsecs(9_999_999))); 6789 test(Date(-2000, 12, 31), SysTime(DateTime(-2000, 12, 31, 23, 59, 59))); 6790 test(Date(-2000, 1, 1), SysTime(DateTime(-2000, 1, 1, 23, 59, 59), hnsecs(500))); 6791 test(Date(-2001, 1, 1), SysTime(DateTime(-2001, 1, 1, 23, 59, 59), hnsecs(50_000))); 6792 6793 test(Date(-2010, 1, 1), SysTime(DateTime(-2010, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 6794 test(Date(-2010, 1, 31), SysTime(DateTime(-2010, 1, 31, 0, 0, 0))); 6795 test(Date(-2010, 2, 1), SysTime(DateTime(-2010, 2, 1, 0, 0, 0), hnsecs(500))); 6796 test(Date(-2010, 2, 28), SysTime(DateTime(-2010, 2, 28, 0, 0, 0), hnsecs(50_000))); 6797 test(Date(-2010, 3, 1), SysTime(DateTime(-2010, 3, 1, 0, 0, 0), hnsecs(9_999_999))); 6798 test(Date(-2010, 3, 31), SysTime(DateTime(-2010, 3, 31, 12, 13, 14))); 6799 test(Date(-2010, 4, 1), SysTime(DateTime(-2010, 4, 1, 12, 13, 14), hnsecs(500))); 6800 test(Date(-2010, 4, 30), SysTime(DateTime(-2010, 4, 30, 12, 13, 14), hnsecs(50_000))); 6801 test(Date(-2010, 5, 1), SysTime(DateTime(-2010, 5, 1, 12, 13, 14), hnsecs(9_999_999))); 6802 test(Date(-2010, 5, 31), SysTime(DateTime(-2010, 5, 31, 23, 59, 59))); 6803 test(Date(-2010, 6, 1), SysTime(DateTime(-2010, 6, 1, 23, 59, 59), hnsecs(500))); 6804 test(Date(-2010, 6, 30), SysTime(DateTime(-2010, 6, 30, 23, 59, 59), hnsecs(50_000))); 6805 test(Date(-2010, 7, 1), SysTime(DateTime(-2010, 7, 1, 23, 59, 59), hnsecs(9_999_999))); 6806 test(Date(-2010, 7, 31), SysTime(DateTime(-2010, 7, 31, 0, 0, 0))); 6807 test(Date(-2010, 8, 1), SysTime(DateTime(-2010, 8, 1, 0, 0, 0), hnsecs(500))); 6808 test(Date(-2010, 8, 31), SysTime(DateTime(-2010, 8, 31, 0, 0, 0), hnsecs(50_000))); 6809 test(Date(-2010, 9, 1), SysTime(DateTime(-2010, 9, 1, 0, 0, 0), hnsecs(9_999_999))); 6810 test(Date(-2010, 9, 30), SysTime(DateTime(-2010, 9, 30, 12, 0, 0))); 6811 test(Date(-2010, 10, 1), SysTime(DateTime(-2010, 10, 1, 0, 12, 0), hnsecs(500))); 6812 test(Date(-2010, 10, 31), SysTime(DateTime(-2010, 10, 31, 0, 0, 12), hnsecs(50_000))); 6813 test(Date(-2010, 11, 1), SysTime(DateTime(-2010, 11, 1, 23, 0, 0), hnsecs(9_999_999))); 6814 test(Date(-2010, 11, 30), SysTime(DateTime(-2010, 11, 30, 0, 59, 0))); 6815 test(Date(-2010, 12, 1), SysTime(DateTime(-2010, 12, 1, 0, 0, 59), hnsecs(500))); 6816 test(Date(-2010, 12, 31), SysTime(DateTime(-2010, 12, 31, 0, 59, 59), hnsecs(50_000))); 6817 6818 test(Date(-2012, 2, 1), SysTime(DateTime(-2012, 2, 1, 23, 0, 59), hnsecs(9_999_999))); 6819 test(Date(-2012, 2, 28), SysTime(DateTime(-2012, 2, 28, 23, 59, 0))); 6820 test(Date(-2012, 2, 29), SysTime(DateTime(-2012, 2, 29, 7, 7, 7), hnsecs(7))); 6821 test(Date(-2012, 3, 1), SysTime(DateTime(-2012, 3, 1, 7, 7, 7), hnsecs(7))); 6822 6823 test(Date(-3760, 9, 7), SysTime(DateTime(-3760, 9, 7, 0, 0, 0))); 6824 } 6825 6826 6827 /++ 6828 The Xth day of the Gregorian Calendar that this $(LREF SysTime) is on. 6829 Setting this property does not affect the time portion of $(LREF SysTime). 6830 6831 Params: 6832 days = The day of the Gregorian Calendar to set this $(LREF SysTime) 6833 to. 6834 +/ 6835 @property void dayOfGregorianCal(int days) @safe nothrow 6836 { 6837 auto hnsecs = adjTime; 6838 hnsecs = removeUnitsFromHNSecs!"days"(hnsecs); 6839 6840 if (hnsecs < 0) 6841 hnsecs += convert!("hours", "hnsecs")(24); 6842 6843 if (--days < 0) 6844 { 6845 hnsecs -= convert!("hours", "hnsecs")(24); 6846 ++days; 6847 } 6848 6849 immutable newDaysHNSecs = convert!("days", "hnsecs")(days); 6850 6851 adjTime = newDaysHNSecs + hnsecs; 6852 } 6853 6854 /// 6855 @safe unittest 6856 { 6857 import std.datetime.date : DateTime; 6858 6859 auto st = SysTime(DateTime(0, 1, 1, 12, 0, 0)); 6860 st.dayOfGregorianCal = 1; 6861 assert(st == SysTime(DateTime(1, 1, 1, 12, 0, 0))); 6862 6863 st.dayOfGregorianCal = 365; 6864 assert(st == SysTime(DateTime(1, 12, 31, 12, 0, 0))); 6865 6866 st.dayOfGregorianCal = 366; 6867 assert(st == SysTime(DateTime(2, 1, 1, 12, 0, 0))); 6868 6869 st.dayOfGregorianCal = 0; 6870 assert(st == SysTime(DateTime(0, 12, 31, 12, 0, 0))); 6871 6872 st.dayOfGregorianCal = -365; 6873 assert(st == SysTime(DateTime(-0, 1, 1, 12, 0, 0))); 6874 6875 st.dayOfGregorianCal = -366; 6876 assert(st == SysTime(DateTime(-1, 12, 31, 12, 0, 0))); 6877 6878 st.dayOfGregorianCal = 730_120; 6879 assert(st == SysTime(DateTime(2000, 1, 1, 12, 0, 0))); 6880 6881 st.dayOfGregorianCal = 734_137; 6882 assert(st == SysTime(DateTime(2010, 12, 31, 12, 0, 0))); 6883 } 6884 6885 @safe unittest 6886 { 6887 void testST(SysTime orig, int day, in SysTime expected, size_t line = __LINE__) 6888 { 6889 orig.dayOfGregorianCal = day; 6890 if (orig != expected) 6891 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 6892 } 6893 6894 // Test A.D. 6895 testST(SysTime(DateTime(1, 1, 1, 0, 0, 0)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6896 testST(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 6897 testST(SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)), 1, 6898 SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 6899 6900 // Test B.C. 6901 testST(SysTime(DateTime(0, 1, 1, 0, 0, 0)), 0, SysTime(DateTime(0, 12, 31, 0, 0, 0))); 6902 testST(SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)), 0, 6903 SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6904 testST(SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(1)), 0, 6905 SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1))); 6906 testST(SysTime(DateTime(0, 1, 1, 23, 59, 59)), 0, SysTime(DateTime(0, 12, 31, 23, 59, 59))); 6907 6908 // Test Both. 6909 testST(SysTime(DateTime(-512, 7, 20, 0, 0, 0)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6910 testST(SysTime(DateTime(-513, 6, 6, 0, 0, 0), hnsecs(1)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 6911 testST(SysTime(DateTime(-511, 5, 7, 23, 59, 59), hnsecs(9_999_999)), 1, 6912 SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 6913 6914 testST(SysTime(DateTime(1607, 4, 8, 0, 0, 0)), 0, SysTime(DateTime(0, 12, 31, 0, 0, 0))); 6915 testST(SysTime(DateTime(1500, 3, 9, 23, 59, 59), hnsecs(9_999_999)), 0, 6916 SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6917 testST(SysTime(DateTime(999, 2, 10, 23, 59, 59), hnsecs(1)), 0, 6918 SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1))); 6919 testST(SysTime(DateTime(2007, 12, 11, 23, 59, 59)), 0, SysTime(DateTime(0, 12, 31, 23, 59, 59))); 6920 6921 6922 auto st = SysTime(DateTime(1, 1, 1, 12, 2, 9), msecs(212)); 6923 6924 void testST2(int day, in SysTime expected, size_t line = __LINE__) 6925 { 6926 st.dayOfGregorianCal = day; 6927 if (st != expected) 6928 throw new AssertError(format("Failed. actual [%s] != expected [%s]", st, expected), __FILE__, line); 6929 } 6930 6931 // Test A.D. 6932 testST2(1, SysTime(DateTime(1, 1, 1, 12, 2, 9), msecs(212))); 6933 testST2(2, SysTime(DateTime(1, 1, 2, 12, 2, 9), msecs(212))); 6934 testST2(32, SysTime(DateTime(1, 2, 1, 12, 2, 9), msecs(212))); 6935 testST2(366, SysTime(DateTime(2, 1, 1, 12, 2, 9), msecs(212))); 6936 testST2(731, SysTime(DateTime(3, 1, 1, 12, 2, 9), msecs(212))); 6937 testST2(1096, SysTime(DateTime(4, 1, 1, 12, 2, 9), msecs(212))); 6938 testST2(1462, SysTime(DateTime(5, 1, 1, 12, 2, 9), msecs(212))); 6939 testST2(17_898, SysTime(DateTime(50, 1, 1, 12, 2, 9), msecs(212))); 6940 testST2(35_065, SysTime(DateTime(97, 1, 1, 12, 2, 9), msecs(212))); 6941 testST2(36_160, SysTime(DateTime(100, 1, 1, 12, 2, 9), msecs(212))); 6942 testST2(36_525, SysTime(DateTime(101, 1, 1, 12, 2, 9), msecs(212))); 6943 testST2(37_986, SysTime(DateTime(105, 1, 1, 12, 2, 9), msecs(212))); 6944 testST2(72_684, SysTime(DateTime(200, 1, 1, 12, 2, 9), msecs(212))); 6945 testST2(73_049, SysTime(DateTime(201, 1, 1, 12, 2, 9), msecs(212))); 6946 testST2(109_208, SysTime(DateTime(300, 1, 1, 12, 2, 9), msecs(212))); 6947 testST2(109_573, SysTime(DateTime(301, 1, 1, 12, 2, 9), msecs(212))); 6948 testST2(145_732, SysTime(DateTime(400, 1, 1, 12, 2, 9), msecs(212))); 6949 testST2(146_098, SysTime(DateTime(401, 1, 1, 12, 2, 9), msecs(212))); 6950 testST2(182_257, SysTime(DateTime(500, 1, 1, 12, 2, 9), msecs(212))); 6951 testST2(182_622, SysTime(DateTime(501, 1, 1, 12, 2, 9), msecs(212))); 6952 testST2(364_878, SysTime(DateTime(1000, 1, 1, 12, 2, 9), msecs(212))); 6953 testST2(365_243, SysTime(DateTime(1001, 1, 1, 12, 2, 9), msecs(212))); 6954 testST2(584_023, SysTime(DateTime(1600, 1, 1, 12, 2, 9), msecs(212))); 6955 testST2(584_389, SysTime(DateTime(1601, 1, 1, 12, 2, 9), msecs(212))); 6956 testST2(693_596, SysTime(DateTime(1900, 1, 1, 12, 2, 9), msecs(212))); 6957 testST2(693_961, SysTime(DateTime(1901, 1, 1, 12, 2, 9), msecs(212))); 6958 testST2(729_755, SysTime(DateTime(1999, 1, 1, 12, 2, 9), msecs(212))); 6959 testST2(730_120, SysTime(DateTime(2000, 1, 1, 12, 2, 9), msecs(212))); 6960 testST2(730_486, SysTime(DateTime(2001, 1, 1, 12, 2, 9), msecs(212))); 6961 6962 testST2(733_773, SysTime(DateTime(2010, 1, 1, 12, 2, 9), msecs(212))); 6963 testST2(733_803, SysTime(DateTime(2010, 1, 31, 12, 2, 9), msecs(212))); 6964 testST2(733_804, SysTime(DateTime(2010, 2, 1, 12, 2, 9), msecs(212))); 6965 testST2(733_831, SysTime(DateTime(2010, 2, 28, 12, 2, 9), msecs(212))); 6966 testST2(733_832, SysTime(DateTime(2010, 3, 1, 12, 2, 9), msecs(212))); 6967 testST2(733_862, SysTime(DateTime(2010, 3, 31, 12, 2, 9), msecs(212))); 6968 testST2(733_863, SysTime(DateTime(2010, 4, 1, 12, 2, 9), msecs(212))); 6969 testST2(733_892, SysTime(DateTime(2010, 4, 30, 12, 2, 9), msecs(212))); 6970 testST2(733_893, SysTime(DateTime(2010, 5, 1, 12, 2, 9), msecs(212))); 6971 testST2(733_923, SysTime(DateTime(2010, 5, 31, 12, 2, 9), msecs(212))); 6972 testST2(733_924, SysTime(DateTime(2010, 6, 1, 12, 2, 9), msecs(212))); 6973 testST2(733_953, SysTime(DateTime(2010, 6, 30, 12, 2, 9), msecs(212))); 6974 testST2(733_954, SysTime(DateTime(2010, 7, 1, 12, 2, 9), msecs(212))); 6975 testST2(733_984, SysTime(DateTime(2010, 7, 31, 12, 2, 9), msecs(212))); 6976 testST2(733_985, SysTime(DateTime(2010, 8, 1, 12, 2, 9), msecs(212))); 6977 testST2(734_015, SysTime(DateTime(2010, 8, 31, 12, 2, 9), msecs(212))); 6978 testST2(734_016, SysTime(DateTime(2010, 9, 1, 12, 2, 9), msecs(212))); 6979 testST2(734_045, SysTime(DateTime(2010, 9, 30, 12, 2, 9), msecs(212))); 6980 testST2(734_046, SysTime(DateTime(2010, 10, 1, 12, 2, 9), msecs(212))); 6981 testST2(734_076, SysTime(DateTime(2010, 10, 31, 12, 2, 9), msecs(212))); 6982 testST2(734_077, SysTime(DateTime(2010, 11, 1, 12, 2, 9), msecs(212))); 6983 testST2(734_106, SysTime(DateTime(2010, 11, 30, 12, 2, 9), msecs(212))); 6984 testST2(734_107, SysTime(DateTime(2010, 12, 1, 12, 2, 9), msecs(212))); 6985 testST2(734_137, SysTime(DateTime(2010, 12, 31, 12, 2, 9), msecs(212))); 6986 6987 testST2(734_534, SysTime(DateTime(2012, 2, 1, 12, 2, 9), msecs(212))); 6988 testST2(734_561, SysTime(DateTime(2012, 2, 28, 12, 2, 9), msecs(212))); 6989 testST2(734_562, SysTime(DateTime(2012, 2, 29, 12, 2, 9), msecs(212))); 6990 testST2(734_563, SysTime(DateTime(2012, 3, 1, 12, 2, 9), msecs(212))); 6991 6992 testST2(734_534, SysTime(DateTime(2012, 2, 1, 12, 2, 9), msecs(212))); 6993 6994 testST2(734_561, SysTime(DateTime(2012, 2, 28, 12, 2, 9), msecs(212))); 6995 testST2(734_562, SysTime(DateTime(2012, 2, 29, 12, 2, 9), msecs(212))); 6996 testST2(734_563, SysTime(DateTime(2012, 3, 1, 12, 2, 9), msecs(212))); 6997 6998 // Test B.C. 6999 testST2(0, SysTime(DateTime(0, 12, 31, 12, 2, 9), msecs(212))); 7000 testST2(-1, SysTime(DateTime(0, 12, 30, 12, 2, 9), msecs(212))); 7001 testST2(-30, SysTime(DateTime(0, 12, 1, 12, 2, 9), msecs(212))); 7002 testST2(-31, SysTime(DateTime(0, 11, 30, 12, 2, 9), msecs(212))); 7003 7004 testST2(-366, SysTime(DateTime(-1, 12, 31, 12, 2, 9), msecs(212))); 7005 testST2(-367, SysTime(DateTime(-1, 12, 30, 12, 2, 9), msecs(212))); 7006 testST2(-730, SysTime(DateTime(-1, 1, 1, 12, 2, 9), msecs(212))); 7007 testST2(-731, SysTime(DateTime(-2, 12, 31, 12, 2, 9), msecs(212))); 7008 testST2(-1095, SysTime(DateTime(-2, 1, 1, 12, 2, 9), msecs(212))); 7009 testST2(-1096, SysTime(DateTime(-3, 12, 31, 12, 2, 9), msecs(212))); 7010 testST2(-1460, SysTime(DateTime(-3, 1, 1, 12, 2, 9), msecs(212))); 7011 testST2(-1461, SysTime(DateTime(-4, 12, 31, 12, 2, 9), msecs(212))); 7012 testST2(-1826, SysTime(DateTime(-4, 1, 1, 12, 2, 9), msecs(212))); 7013 testST2(-1827, SysTime(DateTime(-5, 12, 31, 12, 2, 9), msecs(212))); 7014 testST2(-2191, SysTime(DateTime(-5, 1, 1, 12, 2, 9), msecs(212))); 7015 testST2(-3652, SysTime(DateTime(-9, 1, 1, 12, 2, 9), msecs(212))); 7016 7017 testST2(-18_262, SysTime(DateTime(-49, 1, 1, 12, 2, 9), msecs(212))); 7018 testST2(-18_627, SysTime(DateTime(-50, 1, 1, 12, 2, 9), msecs(212))); 7019 testST2(-35_794, SysTime(DateTime(-97, 1, 1, 12, 2, 9), msecs(212))); 7020 testST2(-36_160, SysTime(DateTime(-99, 12, 31, 12, 2, 9), msecs(212))); 7021 testST2(-36_524, SysTime(DateTime(-99, 1, 1, 12, 2, 9), msecs(212))); 7022 testST2(-36_889, SysTime(DateTime(-100, 1, 1, 12, 2, 9), msecs(212))); 7023 testST2(-37_254, SysTime(DateTime(-101, 1, 1, 12, 2, 9), msecs(212))); 7024 testST2(-38_715, SysTime(DateTime(-105, 1, 1, 12, 2, 9), msecs(212))); 7025 testST2(-73_413, SysTime(DateTime(-200, 1, 1, 12, 2, 9), msecs(212))); 7026 testST2(-73_778, SysTime(DateTime(-201, 1, 1, 12, 2, 9), msecs(212))); 7027 testST2(-109_937, SysTime(DateTime(-300, 1, 1, 12, 2, 9), msecs(212))); 7028 testST2(-110_302, SysTime(DateTime(-301, 1, 1, 12, 2, 9), msecs(212))); 7029 testST2(-146_097, SysTime(DateTime(-400, 12, 31, 12, 2, 9), msecs(212))); 7030 testST2(-146_462, SysTime(DateTime(-400, 1, 1, 12, 2, 9), msecs(212))); 7031 testST2(-146_827, SysTime(DateTime(-401, 1, 1, 12, 2, 9), msecs(212))); 7032 testST2(-182_621, SysTime(DateTime(-499, 1, 1, 12, 2, 9), msecs(212))); 7033 testST2(-182_986, SysTime(DateTime(-500, 1, 1, 12, 2, 9), msecs(212))); 7034 testST2(-183_351, SysTime(DateTime(-501, 1, 1, 12, 2, 9), msecs(212))); 7035 testST2(-365_607, SysTime(DateTime(-1000, 1, 1, 12, 2, 9), msecs(212))); 7036 testST2(-365_972, SysTime(DateTime(-1001, 1, 1, 12, 2, 9), msecs(212))); 7037 testST2(-584_387, SysTime(DateTime(-1599, 1, 1, 12, 2, 9), msecs(212))); 7038 testST2(-584_388, SysTime(DateTime(-1600, 12, 31, 12, 2, 9), msecs(212))); 7039 testST2(-584_753, SysTime(DateTime(-1600, 1, 1, 12, 2, 9), msecs(212))); 7040 testST2(-585_118, SysTime(DateTime(-1601, 1, 1, 12, 2, 9), msecs(212))); 7041 testST2(-694_325, SysTime(DateTime(-1900, 1, 1, 12, 2, 9), msecs(212))); 7042 testST2(-694_690, SysTime(DateTime(-1901, 1, 1, 12, 2, 9), msecs(212))); 7043 testST2(-730_484, SysTime(DateTime(-1999, 1, 1, 12, 2, 9), msecs(212))); 7044 testST2(-730_485, SysTime(DateTime(-2000, 12, 31, 12, 2, 9), msecs(212))); 7045 testST2(-730_850, SysTime(DateTime(-2000, 1, 1, 12, 2, 9), msecs(212))); 7046 testST2(-731_215, SysTime(DateTime(-2001, 1, 1, 12, 2, 9), msecs(212))); 7047 7048 testST2(-734_502, SysTime(DateTime(-2010, 1, 1, 12, 2, 9), msecs(212))); 7049 testST2(-734_472, SysTime(DateTime(-2010, 1, 31, 12, 2, 9), msecs(212))); 7050 testST2(-734_471, SysTime(DateTime(-2010, 2, 1, 12, 2, 9), msecs(212))); 7051 testST2(-734_444, SysTime(DateTime(-2010, 2, 28, 12, 2, 9), msecs(212))); 7052 testST2(-734_443, SysTime(DateTime(-2010, 3, 1, 12, 2, 9), msecs(212))); 7053 testST2(-734_413, SysTime(DateTime(-2010, 3, 31, 12, 2, 9), msecs(212))); 7054 testST2(-734_412, SysTime(DateTime(-2010, 4, 1, 12, 2, 9), msecs(212))); 7055 testST2(-734_383, SysTime(DateTime(-2010, 4, 30, 12, 2, 9), msecs(212))); 7056 testST2(-734_382, SysTime(DateTime(-2010, 5, 1, 12, 2, 9), msecs(212))); 7057 testST2(-734_352, SysTime(DateTime(-2010, 5, 31, 12, 2, 9), msecs(212))); 7058 testST2(-734_351, SysTime(DateTime(-2010, 6, 1, 12, 2, 9), msecs(212))); 7059 testST2(-734_322, SysTime(DateTime(-2010, 6, 30, 12, 2, 9), msecs(212))); 7060 testST2(-734_321, SysTime(DateTime(-2010, 7, 1, 12, 2, 9), msecs(212))); 7061 testST2(-734_291, SysTime(DateTime(-2010, 7, 31, 12, 2, 9), msecs(212))); 7062 testST2(-734_290, SysTime(DateTime(-2010, 8, 1, 12, 2, 9), msecs(212))); 7063 testST2(-734_260, SysTime(DateTime(-2010, 8, 31, 12, 2, 9), msecs(212))); 7064 testST2(-734_259, SysTime(DateTime(-2010, 9, 1, 12, 2, 9), msecs(212))); 7065 testST2(-734_230, SysTime(DateTime(-2010, 9, 30, 12, 2, 9), msecs(212))); 7066 testST2(-734_229, SysTime(DateTime(-2010, 10, 1, 12, 2, 9), msecs(212))); 7067 testST2(-734_199, SysTime(DateTime(-2010, 10, 31, 12, 2, 9), msecs(212))); 7068 testST2(-734_198, SysTime(DateTime(-2010, 11, 1, 12, 2, 9), msecs(212))); 7069 testST2(-734_169, SysTime(DateTime(-2010, 11, 30, 12, 2, 9), msecs(212))); 7070 testST2(-734_168, SysTime(DateTime(-2010, 12, 1, 12, 2, 9), msecs(212))); 7071 testST2(-734_138, SysTime(DateTime(-2010, 12, 31, 12, 2, 9), msecs(212))); 7072 7073 testST2(-735_202, SysTime(DateTime(-2012, 2, 1, 12, 2, 9), msecs(212))); 7074 testST2(-735_175, SysTime(DateTime(-2012, 2, 28, 12, 2, 9), msecs(212))); 7075 testST2(-735_174, SysTime(DateTime(-2012, 2, 29, 12, 2, 9), msecs(212))); 7076 testST2(-735_173, SysTime(DateTime(-2012, 3, 1, 12, 2, 9), msecs(212))); 7077 7078 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7079 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7080 static assert(!__traits(compiles, cst.dayOfGregorianCal = 7)); 7081 //static assert(!__traits(compiles, ist.dayOfGregorianCal = 7)); 7082 } 7083 7084 7085 /++ 7086 The ISO 8601 week of the year that this $(LREF SysTime) is in. 7087 7088 See_Also: 7089 $(HTTP en.wikipedia.org/wiki/ISO_week_date, ISO Week Date). 7090 +/ 7091 @property ubyte isoWeek() @safe const nothrow 7092 { 7093 return (cast(Date) this).isoWeek; 7094 } 7095 7096 /// 7097 @safe unittest 7098 { 7099 import std.datetime.date : Date; 7100 7101 auto st = SysTime(Date(1999, 7, 6)); 7102 const cst = SysTime(Date(2010, 5, 1)); 7103 immutable ist = SysTime(Date(2015, 10, 10)); 7104 7105 assert(st.isoWeek == 27); 7106 assert(cst.isoWeek == 17); 7107 assert(ist.isoWeek == 41); 7108 } 7109 7110 7111 /++ 7112 $(LREF SysTime) for the last day in the month that this Date is in. 7113 The time portion of endOfMonth is always 23:59:59.9999999. 7114 +/ 7115 @property SysTime endOfMonth() @safe const nothrow 7116 { 7117 immutable hnsecs = adjTime; 7118 immutable days = getUnitsFromHNSecs!"days"(hnsecs); 7119 7120 auto date = Date(cast(int) days + 1).endOfMonth; 7121 auto newDays = date.dayOfGregorianCal - 1; 7122 long theTimeHNSecs; 7123 7124 if (newDays < 0) 7125 { 7126 theTimeHNSecs = -1; 7127 ++newDays; 7128 } 7129 else 7130 theTimeHNSecs = convert!("days", "hnsecs")(1) - 1; 7131 7132 immutable newDaysHNSecs = convert!("days", "hnsecs")(newDays); 7133 7134 auto retval = SysTime(this._stdTime, this._timezone); 7135 retval.adjTime = newDaysHNSecs + theTimeHNSecs; 7136 7137 return retval; 7138 } 7139 7140 /// 7141 @safe unittest 7142 { 7143 import core.time : msecs, usecs, hnsecs; 7144 import std.datetime.date : DateTime; 7145 7146 assert(SysTime(DateTime(1999, 1, 6, 0, 0, 0)).endOfMonth == 7147 SysTime(DateTime(1999, 1, 31, 23, 59, 59), hnsecs(9_999_999))); 7148 7149 assert(SysTime(DateTime(1999, 2, 7, 19, 30, 0), msecs(24)).endOfMonth == 7150 SysTime(DateTime(1999, 2, 28, 23, 59, 59), hnsecs(9_999_999))); 7151 7152 assert(SysTime(DateTime(2000, 2, 7, 5, 12, 27), usecs(5203)).endOfMonth == 7153 SysTime(DateTime(2000, 2, 29, 23, 59, 59), hnsecs(9_999_999))); 7154 7155 assert(SysTime(DateTime(2000, 6, 4, 12, 22, 9), hnsecs(12345)).endOfMonth == 7156 SysTime(DateTime(2000, 6, 30, 23, 59, 59), hnsecs(9_999_999))); 7157 } 7158 7159 @safe unittest 7160 { 7161 // Test A.D. 7162 assert(SysTime(Date(1999, 1, 1)).endOfMonth == SysTime(DateTime(1999, 1, 31, 23, 59, 59), hnsecs(9_999_999))); 7163 assert(SysTime(Date(1999, 2, 1)).endOfMonth == SysTime(DateTime(1999, 2, 28, 23, 59, 59), hnsecs(9_999_999))); 7164 assert(SysTime(Date(2000, 2, 1)).endOfMonth == SysTime(DateTime(2000, 2, 29, 23, 59, 59), hnsecs(9_999_999))); 7165 assert(SysTime(Date(1999, 3, 1)).endOfMonth == SysTime(DateTime(1999, 3, 31, 23, 59, 59), hnsecs(9_999_999))); 7166 assert(SysTime(Date(1999, 4, 1)).endOfMonth == SysTime(DateTime(1999, 4, 30, 23, 59, 59), hnsecs(9_999_999))); 7167 assert(SysTime(Date(1999, 5, 1)).endOfMonth == SysTime(DateTime(1999, 5, 31, 23, 59, 59), hnsecs(9_999_999))); 7168 assert(SysTime(Date(1999, 6, 1)).endOfMonth == SysTime(DateTime(1999, 6, 30, 23, 59, 59), hnsecs(9_999_999))); 7169 assert(SysTime(Date(1999, 7, 1)).endOfMonth == SysTime(DateTime(1999, 7, 31, 23, 59, 59), hnsecs(9_999_999))); 7170 assert(SysTime(Date(1999, 8, 1)).endOfMonth == SysTime(DateTime(1999, 8, 31, 23, 59, 59), hnsecs(9_999_999))); 7171 assert(SysTime(Date(1999, 9, 1)).endOfMonth == SysTime(DateTime(1999, 9, 30, 23, 59, 59), hnsecs(9_999_999))); 7172 assert(SysTime(Date(1999, 10, 1)).endOfMonth == SysTime(DateTime(1999, 10, 31, 23, 59, 59), hnsecs(9_999_999))); 7173 assert(SysTime(Date(1999, 11, 1)).endOfMonth == SysTime(DateTime(1999, 11, 30, 23, 59, 59), hnsecs(9_999_999))); 7174 assert(SysTime(Date(1999, 12, 1)).endOfMonth == SysTime(DateTime(1999, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 7175 7176 // Test B.C. 7177 assert(SysTime(Date(-1999, 1, 1)).endOfMonth == SysTime(DateTime(-1999, 1, 31, 23, 59, 59), hnsecs(9_999_999))); 7178 assert(SysTime(Date(-1999, 2, 1)).endOfMonth == SysTime(DateTime(-1999, 2, 28, 23, 59, 59), hnsecs(9_999_999))); 7179 assert(SysTime(Date(-2000, 2, 1)).endOfMonth == SysTime(DateTime(-2000, 2, 29, 23, 59, 59), hnsecs(9_999_999))); 7180 assert(SysTime(Date(-1999, 3, 1)).endOfMonth == SysTime(DateTime(-1999, 3, 31, 23, 59, 59), hnsecs(9_999_999))); 7181 assert(SysTime(Date(-1999, 4, 1)).endOfMonth == SysTime(DateTime(-1999, 4, 30, 23, 59, 59), hnsecs(9_999_999))); 7182 assert(SysTime(Date(-1999, 5, 1)).endOfMonth == SysTime(DateTime(-1999, 5, 31, 23, 59, 59), hnsecs(9_999_999))); 7183 assert(SysTime(Date(-1999, 6, 1)).endOfMonth == SysTime(DateTime(-1999, 6, 30, 23, 59, 59), hnsecs(9_999_999))); 7184 assert(SysTime(Date(-1999, 7, 1)).endOfMonth == SysTime(DateTime(-1999, 7, 31, 23, 59, 59), hnsecs(9_999_999))); 7185 assert(SysTime(Date(-1999, 8, 1)).endOfMonth == SysTime(DateTime(-1999, 8, 31, 23, 59, 59), hnsecs(9_999_999))); 7186 assert(SysTime(Date(-1999, 9, 1)).endOfMonth == SysTime(DateTime(-1999, 9, 30, 23, 59, 59), hnsecs(9_999_999))); 7187 assert(SysTime(Date(-1999, 10, 1)).endOfMonth == 7188 SysTime(DateTime(-1999, 10, 31, 23, 59, 59), hnsecs(9_999_999))); 7189 assert(SysTime(Date(-1999, 11, 1)).endOfMonth == 7190 SysTime(DateTime(-1999, 11, 30, 23, 59, 59), hnsecs(9_999_999))); 7191 assert(SysTime(Date(-1999, 12, 1)).endOfMonth == 7192 SysTime(DateTime(-1999, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 7193 7194 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7195 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7196 assert(cst.endOfMonth == SysTime(DateTime(1999, 7, 31, 23, 59, 59), hnsecs(9_999_999))); 7197 //assert(ist.endOfMonth == SysTime(DateTime(1999, 7, 31, 23, 59, 59), hnsecs(9_999_999))); 7198 } 7199 7200 7201 /++ 7202 The last day in the month that this $(LREF SysTime) is in. 7203 +/ 7204 @property ubyte daysInMonth() @safe const nothrow 7205 { 7206 return Date(dayOfGregorianCal).daysInMonth; 7207 } 7208 7209 /// 7210 @safe unittest 7211 { 7212 import std.datetime.date : DateTime; 7213 7214 assert(SysTime(DateTime(1999, 1, 6, 0, 0, 0)).daysInMonth == 31); 7215 assert(SysTime(DateTime(1999, 2, 7, 19, 30, 0)).daysInMonth == 28); 7216 assert(SysTime(DateTime(2000, 2, 7, 5, 12, 27)).daysInMonth == 29); 7217 assert(SysTime(DateTime(2000, 6, 4, 12, 22, 9)).daysInMonth == 30); 7218 } 7219 7220 @safe unittest 7221 { 7222 // Test A.D. 7223 assert(SysTime(DateTime(1999, 1, 1, 12, 1, 13)).daysInMonth == 31); 7224 assert(SysTime(DateTime(1999, 2, 1, 17, 13, 12)).daysInMonth == 28); 7225 assert(SysTime(DateTime(2000, 2, 1, 13, 2, 12)).daysInMonth == 29); 7226 assert(SysTime(DateTime(1999, 3, 1, 12, 13, 12)).daysInMonth == 31); 7227 assert(SysTime(DateTime(1999, 4, 1, 12, 6, 13)).daysInMonth == 30); 7228 assert(SysTime(DateTime(1999, 5, 1, 15, 13, 12)).daysInMonth == 31); 7229 assert(SysTime(DateTime(1999, 6, 1, 13, 7, 12)).daysInMonth == 30); 7230 assert(SysTime(DateTime(1999, 7, 1, 12, 13, 17)).daysInMonth == 31); 7231 assert(SysTime(DateTime(1999, 8, 1, 12, 3, 13)).daysInMonth == 31); 7232 assert(SysTime(DateTime(1999, 9, 1, 12, 13, 12)).daysInMonth == 30); 7233 assert(SysTime(DateTime(1999, 10, 1, 13, 19, 12)).daysInMonth == 31); 7234 assert(SysTime(DateTime(1999, 11, 1, 12, 13, 17)).daysInMonth == 30); 7235 assert(SysTime(DateTime(1999, 12, 1, 12, 52, 13)).daysInMonth == 31); 7236 7237 // Test B.C. 7238 assert(SysTime(DateTime(-1999, 1, 1, 12, 1, 13)).daysInMonth == 31); 7239 assert(SysTime(DateTime(-1999, 2, 1, 7, 13, 12)).daysInMonth == 28); 7240 assert(SysTime(DateTime(-2000, 2, 1, 13, 2, 12)).daysInMonth == 29); 7241 assert(SysTime(DateTime(-1999, 3, 1, 12, 13, 12)).daysInMonth == 31); 7242 assert(SysTime(DateTime(-1999, 4, 1, 12, 6, 13)).daysInMonth == 30); 7243 assert(SysTime(DateTime(-1999, 5, 1, 5, 13, 12)).daysInMonth == 31); 7244 assert(SysTime(DateTime(-1999, 6, 1, 13, 7, 12)).daysInMonth == 30); 7245 assert(SysTime(DateTime(-1999, 7, 1, 12, 13, 17)).daysInMonth == 31); 7246 assert(SysTime(DateTime(-1999, 8, 1, 12, 3, 13)).daysInMonth == 31); 7247 assert(SysTime(DateTime(-1999, 9, 1, 12, 13, 12)).daysInMonth == 30); 7248 assert(SysTime(DateTime(-1999, 10, 1, 13, 19, 12)).daysInMonth == 31); 7249 assert(SysTime(DateTime(-1999, 11, 1, 12, 13, 17)).daysInMonth == 30); 7250 assert(SysTime(DateTime(-1999, 12, 1, 12, 52, 13)).daysInMonth == 31); 7251 7252 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7253 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7254 assert(cst.daysInMonth == 31); 7255 //assert(ist.daysInMonth == 31); 7256 } 7257 7258 7259 /++ 7260 Whether the current year is a date in A.D. 7261 +/ 7262 @property bool isAD() @safe const nothrow 7263 { 7264 return adjTime >= 0; 7265 } 7266 7267 /// 7268 @safe unittest 7269 { 7270 import std.datetime.date : DateTime; 7271 7272 assert(SysTime(DateTime(1, 1, 1, 12, 7, 0)).isAD); 7273 assert(SysTime(DateTime(2010, 12, 31, 0, 0, 0)).isAD); 7274 assert(!SysTime(DateTime(0, 12, 31, 23, 59, 59)).isAD); 7275 assert(!SysTime(DateTime(-2010, 1, 1, 2, 2, 2)).isAD); 7276 } 7277 7278 @safe unittest 7279 { 7280 assert(SysTime(DateTime(2010, 7, 4, 12, 0, 9)).isAD); 7281 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).isAD); 7282 assert(!SysTime(DateTime(0, 12, 31, 23, 59, 59)).isAD); 7283 assert(!SysTime(DateTime(0, 1, 1, 23, 59, 59)).isAD); 7284 assert(!SysTime(DateTime(-1, 1, 1, 23 ,59 ,59)).isAD); 7285 assert(!SysTime(DateTime(-2010, 7, 4, 12, 2, 2)).isAD); 7286 7287 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7288 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7289 assert(cst.isAD); 7290 //assert(ist.isAD); 7291 } 7292 7293 7294 /++ 7295 The $(HTTP en.wikipedia.org/wiki/Julian_day, Julian day) 7296 for this $(LREF SysTime) at the given time. For example, 7297 prior to noon, 1996-03-31 would be the Julian day number 2_450_173, so 7298 this function returns 2_450_173, while from noon onward, the Julian 7299 day number would be 2_450_174, so this function returns 2_450_174. 7300 +/ 7301 @property long julianDay() @safe const nothrow 7302 { 7303 immutable jd = dayOfGregorianCal + 1_721_425; 7304 return hour < 12 ? jd - 1 : jd; 7305 } 7306 7307 @safe unittest 7308 { 7309 assert(SysTime(DateTime(-4713, 11, 24, 0, 0, 0)).julianDay == -1); 7310 assert(SysTime(DateTime(-4713, 11, 24, 12, 0, 0)).julianDay == 0); 7311 7312 assert(SysTime(DateTime(0, 12, 31, 0, 0, 0)).julianDay == 1_721_424); 7313 assert(SysTime(DateTime(0, 12, 31, 12, 0, 0)).julianDay == 1_721_425); 7314 7315 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).julianDay == 1_721_425); 7316 assert(SysTime(DateTime(1, 1, 1, 12, 0, 0)).julianDay == 1_721_426); 7317 7318 assert(SysTime(DateTime(1582, 10, 15, 0, 0, 0)).julianDay == 2_299_160); 7319 assert(SysTime(DateTime(1582, 10, 15, 12, 0, 0)).julianDay == 2_299_161); 7320 7321 assert(SysTime(DateTime(1858, 11, 17, 0, 0, 0)).julianDay == 2_400_000); 7322 assert(SysTime(DateTime(1858, 11, 17, 12, 0, 0)).julianDay == 2_400_001); 7323 7324 assert(SysTime(DateTime(1982, 1, 4, 0, 0, 0)).julianDay == 2_444_973); 7325 assert(SysTime(DateTime(1982, 1, 4, 12, 0, 0)).julianDay == 2_444_974); 7326 7327 assert(SysTime(DateTime(1996, 3, 31, 0, 0, 0)).julianDay == 2_450_173); 7328 assert(SysTime(DateTime(1996, 3, 31, 12, 0, 0)).julianDay == 2_450_174); 7329 7330 assert(SysTime(DateTime(2010, 8, 24, 0, 0, 0)).julianDay == 2_455_432); 7331 assert(SysTime(DateTime(2010, 8, 24, 12, 0, 0)).julianDay == 2_455_433); 7332 7333 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7334 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7335 assert(cst.julianDay == 2_451_366); 7336 //assert(ist.julianDay == 2_451_366); 7337 } 7338 7339 7340 /++ 7341 The modified $(HTTP en.wikipedia.org/wiki/Julian_day, Julian day) for 7342 any time on this date (since, the modified Julian day changes at 7343 midnight). 7344 +/ 7345 @property long modJulianDay() @safe const nothrow 7346 { 7347 return dayOfGregorianCal + 1_721_425 - 2_400_001; 7348 } 7349 7350 @safe unittest 7351 { 7352 assert(SysTime(DateTime(1858, 11, 17, 0, 0, 0)).modJulianDay == 0); 7353 assert(SysTime(DateTime(1858, 11, 17, 12, 0, 0)).modJulianDay == 0); 7354 7355 assert(SysTime(DateTime(2010, 8, 24, 0, 0, 0)).modJulianDay == 55_432); 7356 assert(SysTime(DateTime(2010, 8, 24, 12, 0, 0)).modJulianDay == 55_432); 7357 7358 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7359 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7360 assert(cst.modJulianDay == 51_365); 7361 //assert(ist.modJulianDay == 51_365); 7362 } 7363 7364 7365 /++ 7366 Returns a $(REF Date,std,datetime,date) equivalent to this $(LREF SysTime). 7367 +/ 7368 Date opCast(T)() @safe const nothrow 7369 if (is(Unqual!T == Date)) 7370 { 7371 return Date(dayOfGregorianCal); 7372 } 7373 7374 @safe unittest 7375 { 7376 assert(cast(Date) SysTime(Date(1999, 7, 6)) == Date(1999, 7, 6)); 7377 assert(cast(Date) SysTime(Date(2000, 12, 31)) == Date(2000, 12, 31)); 7378 assert(cast(Date) SysTime(Date(2001, 1, 1)) == Date(2001, 1, 1)); 7379 7380 assert(cast(Date) SysTime(DateTime(1999, 7, 6, 12, 10, 9)) == Date(1999, 7, 6)); 7381 assert(cast(Date) SysTime(DateTime(2000, 12, 31, 13, 11, 10)) == Date(2000, 12, 31)); 7382 assert(cast(Date) SysTime(DateTime(2001, 1, 1, 14, 12, 11)) == Date(2001, 1, 1)); 7383 7384 assert(cast(Date) SysTime(Date(-1999, 7, 6)) == Date(-1999, 7, 6)); 7385 assert(cast(Date) SysTime(Date(-2000, 12, 31)) == Date(-2000, 12, 31)); 7386 assert(cast(Date) SysTime(Date(-2001, 1, 1)) == Date(-2001, 1, 1)); 7387 7388 assert(cast(Date) SysTime(DateTime(-1999, 7, 6, 12, 10, 9)) == Date(-1999, 7, 6)); 7389 assert(cast(Date) SysTime(DateTime(-2000, 12, 31, 13, 11, 10)) == Date(-2000, 12, 31)); 7390 assert(cast(Date) SysTime(DateTime(-2001, 1, 1, 14, 12, 11)) == Date(-2001, 1, 1)); 7391 7392 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7393 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7394 assert(cast(Date) cst != Date.init); 7395 //assert(cast(Date) ist != Date.init); 7396 } 7397 7398 7399 /++ 7400 Returns a $(REF DateTime,std,datetime,date) equivalent to this 7401 $(LREF SysTime). 7402 +/ 7403 DateTime opCast(T)() @safe const nothrow 7404 if (is(Unqual!T == DateTime)) 7405 { 7406 try 7407 { 7408 auto hnsecs = adjTime; 7409 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 7410 7411 if (hnsecs < 0) 7412 { 7413 hnsecs += convert!("hours", "hnsecs")(24); 7414 --days; 7415 } 7416 7417 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 7418 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 7419 immutable second = getUnitsFromHNSecs!"seconds"(hnsecs); 7420 7421 return DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour, cast(int) minute, cast(int) second)); 7422 } 7423 catch (Exception e) 7424 assert(0, "Either DateTime's constructor or TimeOfDay's constructor threw."); 7425 } 7426 7427 @safe unittest 7428 { 7429 assert(cast(DateTime) SysTime(DateTime(1, 1, 6, 7, 12, 22)) == DateTime(1, 1, 6, 7, 12, 22)); 7430 assert(cast(DateTime) SysTime(DateTime(1, 1, 6, 7, 12, 22), msecs(22)) == DateTime(1, 1, 6, 7, 12, 22)); 7431 assert(cast(DateTime) SysTime(Date(1999, 7, 6)) == DateTime(1999, 7, 6, 0, 0, 0)); 7432 assert(cast(DateTime) SysTime(Date(2000, 12, 31)) == DateTime(2000, 12, 31, 0, 0, 0)); 7433 assert(cast(DateTime) SysTime(Date(2001, 1, 1)) == DateTime(2001, 1, 1, 0, 0, 0)); 7434 7435 assert(cast(DateTime) SysTime(DateTime(1999, 7, 6, 12, 10, 9)) == DateTime(1999, 7, 6, 12, 10, 9)); 7436 assert(cast(DateTime) SysTime(DateTime(2000, 12, 31, 13, 11, 10)) == DateTime(2000, 12, 31, 13, 11, 10)); 7437 assert(cast(DateTime) SysTime(DateTime(2001, 1, 1, 14, 12, 11)) == DateTime(2001, 1, 1, 14, 12, 11)); 7438 7439 assert(cast(DateTime) SysTime(DateTime(-1, 1, 6, 7, 12, 22)) == DateTime(-1, 1, 6, 7, 12, 22)); 7440 assert(cast(DateTime) SysTime(DateTime(-1, 1, 6, 7, 12, 22), msecs(22)) == DateTime(-1, 1, 6, 7, 12, 22)); 7441 assert(cast(DateTime) SysTime(Date(-1999, 7, 6)) == DateTime(-1999, 7, 6, 0, 0, 0)); 7442 assert(cast(DateTime) SysTime(Date(-2000, 12, 31)) == DateTime(-2000, 12, 31, 0, 0, 0)); 7443 assert(cast(DateTime) SysTime(Date(-2001, 1, 1)) == DateTime(-2001, 1, 1, 0, 0, 0)); 7444 7445 assert(cast(DateTime) SysTime(DateTime(-1999, 7, 6, 12, 10, 9)) == DateTime(-1999, 7, 6, 12, 10, 9)); 7446 assert(cast(DateTime) SysTime(DateTime(-2000, 12, 31, 13, 11, 10)) == DateTime(-2000, 12, 31, 13, 11, 10)); 7447 assert(cast(DateTime) SysTime(DateTime(-2001, 1, 1, 14, 12, 11)) == DateTime(-2001, 1, 1, 14, 12, 11)); 7448 7449 assert(cast(DateTime) SysTime(DateTime(2011, 1, 13, 8, 17, 2), msecs(296), LocalTime()) == 7450 DateTime(2011, 1, 13, 8, 17, 2)); 7451 7452 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7453 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7454 assert(cast(DateTime) cst != DateTime.init); 7455 //assert(cast(DateTime) ist != DateTime.init); 7456 } 7457 7458 7459 /++ 7460 Returns a $(REF TimeOfDay,std,datetime,date) equivalent to this 7461 $(LREF SysTime). 7462 +/ 7463 TimeOfDay opCast(T)() @safe const nothrow 7464 if (is(Unqual!T == TimeOfDay)) 7465 { 7466 try 7467 { 7468 auto hnsecs = adjTime; 7469 hnsecs = removeUnitsFromHNSecs!"days"(hnsecs); 7470 7471 if (hnsecs < 0) 7472 hnsecs += convert!("hours", "hnsecs")(24); 7473 7474 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 7475 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 7476 immutable second = getUnitsFromHNSecs!"seconds"(hnsecs); 7477 7478 return TimeOfDay(cast(int) hour, cast(int) minute, cast(int) second); 7479 } 7480 catch (Exception e) 7481 assert(0, "TimeOfDay's constructor threw."); 7482 } 7483 7484 @safe unittest 7485 { 7486 assert(cast(TimeOfDay) SysTime(Date(1999, 7, 6)) == TimeOfDay(0, 0, 0)); 7487 assert(cast(TimeOfDay) SysTime(Date(2000, 12, 31)) == TimeOfDay(0, 0, 0)); 7488 assert(cast(TimeOfDay) SysTime(Date(2001, 1, 1)) == TimeOfDay(0, 0, 0)); 7489 7490 assert(cast(TimeOfDay) SysTime(DateTime(1999, 7, 6, 12, 10, 9)) == TimeOfDay(12, 10, 9)); 7491 assert(cast(TimeOfDay) SysTime(DateTime(2000, 12, 31, 13, 11, 10)) == TimeOfDay(13, 11, 10)); 7492 assert(cast(TimeOfDay) SysTime(DateTime(2001, 1, 1, 14, 12, 11)) == TimeOfDay(14, 12, 11)); 7493 7494 assert(cast(TimeOfDay) SysTime(Date(-1999, 7, 6)) == TimeOfDay(0, 0, 0)); 7495 assert(cast(TimeOfDay) SysTime(Date(-2000, 12, 31)) == TimeOfDay(0, 0, 0)); 7496 assert(cast(TimeOfDay) SysTime(Date(-2001, 1, 1)) == TimeOfDay(0, 0, 0)); 7497 7498 assert(cast(TimeOfDay) SysTime(DateTime(-1999, 7, 6, 12, 10, 9)) == TimeOfDay(12, 10, 9)); 7499 assert(cast(TimeOfDay) SysTime(DateTime(-2000, 12, 31, 13, 11, 10)) == TimeOfDay(13, 11, 10)); 7500 assert(cast(TimeOfDay) SysTime(DateTime(-2001, 1, 1, 14, 12, 11)) == TimeOfDay(14, 12, 11)); 7501 7502 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7503 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7504 assert(cast(TimeOfDay) cst != TimeOfDay.init); 7505 //assert(cast(TimeOfDay) ist != TimeOfDay.init); 7506 } 7507 7508 7509 // Temporary hack until bug http://d.puremagic.com/issues/show_bug.cgi?id=4867 is fixed. 7510 // This allows assignment from const(SysTime) to SysTime. 7511 // It may be a good idea to keep it though, since casting from a type to itself 7512 // should be allowed, and it doesn't work without this opCast() since opCast() 7513 // has already been defined for other types. 7514 SysTime opCast(T)() @safe const pure nothrow 7515 if (is(Unqual!T == SysTime)) 7516 { 7517 return SysTime(_stdTime, _timezone); 7518 } 7519 7520 7521 /++ 7522 Converts this $(LREF SysTime) to a string with the format 7523 YYYYMMDDTHHMMSS.FFFFFFFTZ (where F is fractional seconds and TZ is time 7524 zone). 7525 7526 Note that the number of digits in the fractional seconds varies with the 7527 number of fractional seconds. It's a maximum of 7 (which would be 7528 hnsecs), but only has as many as are necessary to hold the correct value 7529 (so no trailing zeroes), and if there are no fractional seconds, then 7530 there is no decimal point. 7531 7532 If this $(LREF SysTime)'s time zone is 7533 $(REF LocalTime,std,datetime,timezone), then TZ is empty. If its time 7534 zone is $(D UTC), then it is "Z". Otherwise, it is the offset from UTC 7535 (e.g. +0100 or -0700). Note that the offset from UTC is $(I not) enough 7536 to uniquely identify the time zone. 7537 7538 Time zone offsets will be in the form +HHMM or -HHMM. 7539 7540 $(RED Warning: 7541 Previously, toISOString did the same as $(LREF toISOExtString) and 7542 generated +HH:MM or -HH:MM for the time zone when it was not 7543 $(REF LocalTime,std,datetime,timezone) or 7544 $(REF UTC,std,datetime,timezone), which is not in conformance with 7545 ISO 8601 for the non-extended string format. This has now been 7546 fixed. However, for now, fromISOString will continue to accept the 7547 extended format for the time zone so that any code which has been 7548 writing out the result of toISOString to read in later will continue 7549 to work. The current behavior will be kept until July 2019 at which 7550 point, fromISOString will be fixed to be standards compliant.) 7551 +/ 7552 string toISOString() @safe const nothrow 7553 { 7554 try 7555 { 7556 immutable adjustedTime = adjTime; 7557 long hnsecs = adjustedTime; 7558 7559 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 7560 7561 if (hnsecs < 0) 7562 { 7563 hnsecs += convert!("hours", "hnsecs")(24); 7564 --days; 7565 } 7566 7567 auto hour = splitUnitsFromHNSecs!"hours"(hnsecs); 7568 auto minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 7569 auto second = splitUnitsFromHNSecs!"seconds"(hnsecs); 7570 7571 auto dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour, 7572 cast(int) minute, cast(int) second)); 7573 auto fracSecStr = fracSecsToISOString(cast(int) hnsecs); 7574 7575 if (_timezone is LocalTime()) 7576 return dateTime.toISOString() ~ fracSecStr; 7577 7578 if (_timezone is UTC()) 7579 return dateTime.toISOString() ~ fracSecStr ~ "Z"; 7580 7581 immutable utcOffset = dur!"hnsecs"(adjustedTime - stdTime); 7582 7583 return format("%s%s%s", 7584 dateTime.toISOString(), 7585 fracSecStr, 7586 SimpleTimeZone.toISOExtString(utcOffset)); 7587 } 7588 catch (Exception e) 7589 assert(0, "format() threw."); 7590 } 7591 7592 /// 7593 @safe unittest 7594 { 7595 import core.time : msecs, hnsecs; 7596 import std.datetime.date : DateTime; 7597 7598 assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toISOString() == 7599 "20100704T070612"); 7600 7601 assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(24)).toISOString() == 7602 "19981225T021500.024"); 7603 7604 assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toISOString() == 7605 "00000105T230959"); 7606 7607 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toISOString() == 7608 "-00040105T000002.052092"); 7609 } 7610 7611 @safe unittest 7612 { 7613 // Test A.D. 7614 assert(SysTime(DateTime.init, UTC()).toISOString() == "00010101T000000Z"); 7615 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC()).toISOString() == "00010101T000000.0000001Z"); 7616 7617 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0)).toISOString() == "00091204T000000"); 7618 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12)).toISOString() == "00991204T050612"); 7619 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59)).toISOString() == "09991204T134459"); 7620 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59)).toISOString() == "99990704T235959"); 7621 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1)).toISOString() == "+100001020T010101"); 7622 7623 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0), msecs(42)).toISOString() == "00091204T000000.042"); 7624 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12), msecs(100)).toISOString() == "00991204T050612.1"); 7625 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59), usecs(45020)).toISOString() == "09991204T134459.04502"); 7626 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOString() == "99990704T235959.0000012"); 7627 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOString() == "+100001020T010101.050789"); 7628 7629 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 7630 new immutable SimpleTimeZone(dur!"minutes"(-360))).toISOString() == 7631 "20121221T121212-06:00"); 7632 7633 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 7634 new immutable SimpleTimeZone(dur!"minutes"(420))).toISOString() == 7635 "20121221T121212+07:00"); 7636 7637 // Test B.C. 7638 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toISOString() == 7639 "00001231T235959.9999999Z"); 7640 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC()).toISOString() == "00001231T235959.0000001Z"); 7641 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), UTC()).toISOString() == "00001231T235959Z"); 7642 7643 assert(SysTime(DateTime(0, 12, 4, 0, 12, 4)).toISOString() == "00001204T001204"); 7644 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0)).toISOString() == "-00091204T000000"); 7645 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12)).toISOString() == "-00991204T050612"); 7646 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59)).toISOString() == "-09991204T134459"); 7647 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59)).toISOString() == "-99990704T235959"); 7648 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1)).toISOString() == "-100001020T010101"); 7649 7650 assert(SysTime(DateTime(0, 12, 4, 0, 0, 0), msecs(7)).toISOString() == "00001204T000000.007"); 7651 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0), msecs(42)).toISOString() == "-00091204T000000.042"); 7652 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12), msecs(100)).toISOString() == "-00991204T050612.1"); 7653 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59), usecs(45020)).toISOString() == "-09991204T134459.04502"); 7654 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOString() == "-99990704T235959.0000012"); 7655 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOString() == "-100001020T010101.050789"); 7656 7657 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7658 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7659 assert(cast(TimeOfDay) cst != TimeOfDay.init); 7660 //assert(cast(TimeOfDay) ist != TimeOfDay.init); 7661 } 7662 7663 7664 7665 /++ 7666 Converts this $(LREF SysTime) to a string with the format 7667 YYYY-MM-DDTHH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ 7668 is the time zone). 7669 7670 Note that the number of digits in the fractional seconds varies with the 7671 number of fractional seconds. It's a maximum of 7 (which would be 7672 hnsecs), but only has as many as are necessary to hold the correct value 7673 (so no trailing zeroes), and if there are no fractional seconds, then 7674 there is no decimal point. 7675 7676 If this $(LREF SysTime)'s time zone is 7677 $(REF LocalTime,std,datetime,timezone), then TZ is empty. If its time 7678 zone is $(D UTC), then it is "Z". Otherwise, it is the offset from UTC 7679 (e.g. +01:00 or -07:00). Note that the offset from UTC is $(I not) 7680 enough to uniquely identify the time zone. 7681 7682 Time zone offsets will be in the form +HH:MM or -HH:MM. 7683 +/ 7684 string toISOExtString() @safe const nothrow 7685 { 7686 try 7687 { 7688 immutable adjustedTime = adjTime; 7689 long hnsecs = adjustedTime; 7690 7691 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 7692 7693 if (hnsecs < 0) 7694 { 7695 hnsecs += convert!("hours", "hnsecs")(24); 7696 --days; 7697 } 7698 7699 auto hour = splitUnitsFromHNSecs!"hours"(hnsecs); 7700 auto minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 7701 auto second = splitUnitsFromHNSecs!"seconds"(hnsecs); 7702 7703 auto dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour, 7704 cast(int) minute, cast(int) second)); 7705 auto fracSecStr = fracSecsToISOString(cast(int) hnsecs); 7706 7707 if (_timezone is LocalTime()) 7708 return dateTime.toISOExtString() ~ fracSecStr; 7709 7710 if (_timezone is UTC()) 7711 return dateTime.toISOExtString() ~ fracSecStr ~ "Z"; 7712 7713 immutable utcOffset = dur!"hnsecs"(adjustedTime - stdTime); 7714 7715 return format("%s%s%s", 7716 dateTime.toISOExtString(), 7717 fracSecStr, 7718 SimpleTimeZone.toISOExtString(utcOffset)); 7719 } 7720 catch (Exception e) 7721 assert(0, "format() threw."); 7722 } 7723 7724 /// 7725 @safe unittest 7726 { 7727 import core.time : msecs, hnsecs; 7728 import std.datetime.date : DateTime; 7729 7730 assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toISOExtString() == 7731 "2010-07-04T07:06:12"); 7732 7733 assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(24)).toISOExtString() == 7734 "1998-12-25T02:15:00.024"); 7735 7736 assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toISOExtString() == 7737 "0000-01-05T23:09:59"); 7738 7739 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toISOExtString() == 7740 "-0004-01-05T00:00:02.052092"); 7741 } 7742 7743 @safe unittest 7744 { 7745 // Test A.D. 7746 assert(SysTime(DateTime.init, UTC()).toISOExtString() == "0001-01-01T00:00:00Z"); 7747 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC()).toISOExtString() == 7748 "0001-01-01T00:00:00.0000001Z"); 7749 7750 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0)).toISOExtString() == "0009-12-04T00:00:00"); 7751 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12)).toISOExtString() == "0099-12-04T05:06:12"); 7752 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59)).toISOExtString() == "0999-12-04T13:44:59"); 7753 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59)).toISOExtString() == "9999-07-04T23:59:59"); 7754 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1)).toISOExtString() == "+10000-10-20T01:01:01"); 7755 7756 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0), msecs(42)).toISOExtString() == "0009-12-04T00:00:00.042"); 7757 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12), msecs(100)).toISOExtString() == "0099-12-04T05:06:12.1"); 7758 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59), usecs(45020)).toISOExtString() == "0999-12-04T13:44:59.04502"); 7759 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOExtString() == "9999-07-04T23:59:59.0000012"); 7760 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOExtString() == 7761 "+10000-10-20T01:01:01.050789"); 7762 7763 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 7764 new immutable SimpleTimeZone(dur!"minutes"(-360))).toISOExtString() == 7765 "2012-12-21T12:12:12-06:00"); 7766 7767 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 7768 new immutable SimpleTimeZone(dur!"minutes"(420))).toISOExtString() == 7769 "2012-12-21T12:12:12+07:00"); 7770 7771 // Test B.C. 7772 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toISOExtString() == 7773 "0000-12-31T23:59:59.9999999Z"); 7774 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC()).toISOExtString() == 7775 "0000-12-31T23:59:59.0000001Z"); 7776 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), UTC()).toISOExtString() == "0000-12-31T23:59:59Z"); 7777 7778 assert(SysTime(DateTime(0, 12, 4, 0, 12, 4)).toISOExtString() == "0000-12-04T00:12:04"); 7779 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0)).toISOExtString() == "-0009-12-04T00:00:00"); 7780 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12)).toISOExtString() == "-0099-12-04T05:06:12"); 7781 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59)).toISOExtString() == "-0999-12-04T13:44:59"); 7782 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59)).toISOExtString() == "-9999-07-04T23:59:59"); 7783 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1)).toISOExtString() == "-10000-10-20T01:01:01"); 7784 7785 assert(SysTime(DateTime(0, 12, 4, 0, 0, 0), msecs(7)).toISOExtString() == "0000-12-04T00:00:00.007"); 7786 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0), msecs(42)).toISOExtString() == "-0009-12-04T00:00:00.042"); 7787 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12), msecs(100)).toISOExtString() == "-0099-12-04T05:06:12.1"); 7788 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59), usecs(45020)).toISOExtString() == 7789 "-0999-12-04T13:44:59.04502"); 7790 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOExtString() == 7791 "-9999-07-04T23:59:59.0000012"); 7792 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOExtString() == 7793 "-10000-10-20T01:01:01.050789"); 7794 7795 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7796 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7797 assert(cast(TimeOfDay) cst != TimeOfDay.init); 7798 //assert(cast(TimeOfDay) ist != TimeOfDay.init); 7799 } 7800 7801 /++ 7802 Converts this $(LREF SysTime) to a string with the format 7803 YYYY-Mon-DD HH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ 7804 is the time zone). 7805 7806 Note that the number of digits in the fractional seconds varies with the 7807 number of fractional seconds. It's a maximum of 7 (which would be 7808 hnsecs), but only has as many as are necessary to hold the correct value 7809 (so no trailing zeroes), and if there are no fractional seconds, then 7810 there is no decimal point. 7811 7812 If this $(LREF SysTime)'s time zone is 7813 $(REF LocalTime,std,datetime,timezone), then TZ is empty. If its time 7814 zone is $(D UTC), then it is "Z". Otherwise, it is the offset from UTC 7815 (e.g. +01:00 or -07:00). Note that the offset from UTC is $(I not) 7816 enough to uniquely identify the time zone. 7817 7818 Time zone offsets will be in the form +HH:MM or -HH:MM. 7819 +/ 7820 string toSimpleString() @safe const nothrow 7821 { 7822 try 7823 { 7824 immutable adjustedTime = adjTime; 7825 long hnsecs = adjustedTime; 7826 7827 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 7828 7829 if (hnsecs < 0) 7830 { 7831 hnsecs += convert!("hours", "hnsecs")(24); 7832 --days; 7833 } 7834 7835 auto hour = splitUnitsFromHNSecs!"hours"(hnsecs); 7836 auto minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 7837 auto second = splitUnitsFromHNSecs!"seconds"(hnsecs); 7838 7839 auto dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour, 7840 cast(int) minute, cast(int) second)); 7841 auto fracSecStr = fracSecsToISOString(cast(int) hnsecs); 7842 7843 if (_timezone is LocalTime()) 7844 return dateTime.toSimpleString() ~ fracSecStr; 7845 7846 if (_timezone is UTC()) 7847 return dateTime.toSimpleString() ~ fracSecStr ~ "Z"; 7848 7849 immutable utcOffset = dur!"hnsecs"(adjustedTime - stdTime); 7850 7851 return format("%s%s%s", 7852 dateTime.toSimpleString(), 7853 fracSecStr, 7854 SimpleTimeZone.toISOExtString(utcOffset)); 7855 } 7856 catch (Exception e) 7857 assert(0, "format() threw."); 7858 } 7859 7860 /// 7861 @safe unittest 7862 { 7863 import core.time : msecs, hnsecs; 7864 import std.datetime.date : DateTime; 7865 7866 assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toSimpleString() == 7867 "2010-Jul-04 07:06:12"); 7868 7869 assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(24)).toSimpleString() == 7870 "1998-Dec-25 02:15:00.024"); 7871 7872 assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toSimpleString() == 7873 "0000-Jan-05 23:09:59"); 7874 7875 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toSimpleString() == 7876 "-0004-Jan-05 00:00:02.052092"); 7877 } 7878 7879 @safe unittest 7880 { 7881 // Test A.D. 7882 assert(SysTime(DateTime.init, UTC()).toString() == "0001-Jan-01 00:00:00Z"); 7883 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC()).toString() == "0001-Jan-01 00:00:00.0000001Z"); 7884 7885 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0)).toSimpleString() == "0009-Dec-04 00:00:00"); 7886 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12)).toSimpleString() == "0099-Dec-04 05:06:12"); 7887 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59)).toSimpleString() == "0999-Dec-04 13:44:59"); 7888 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59)).toSimpleString() == "9999-Jul-04 23:59:59"); 7889 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1)).toSimpleString() == "+10000-Oct-20 01:01:01"); 7890 7891 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0), msecs(42)).toSimpleString() == "0009-Dec-04 00:00:00.042"); 7892 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12), msecs(100)).toSimpleString() == "0099-Dec-04 05:06:12.1"); 7893 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59), usecs(45020)).toSimpleString() == 7894 "0999-Dec-04 13:44:59.04502"); 7895 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59), hnsecs(12)).toSimpleString() == 7896 "9999-Jul-04 23:59:59.0000012"); 7897 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1), hnsecs(507890)).toSimpleString() == 7898 "+10000-Oct-20 01:01:01.050789"); 7899 7900 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 7901 new immutable SimpleTimeZone(dur!"minutes"(-360))).toSimpleString() == 7902 "2012-Dec-21 12:12:12-06:00"); 7903 7904 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 7905 new immutable SimpleTimeZone(dur!"minutes"(420))).toSimpleString() == 7906 "2012-Dec-21 12:12:12+07:00"); 7907 7908 // Test B.C. 7909 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toSimpleString() == 7910 "0000-Dec-31 23:59:59.9999999Z"); 7911 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC()).toSimpleString() == 7912 "0000-Dec-31 23:59:59.0000001Z"); 7913 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), UTC()).toSimpleString() == "0000-Dec-31 23:59:59Z"); 7914 7915 assert(SysTime(DateTime(0, 12, 4, 0, 12, 4)).toSimpleString() == "0000-Dec-04 00:12:04"); 7916 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0)).toSimpleString() == "-0009-Dec-04 00:00:00"); 7917 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12)).toSimpleString() == "-0099-Dec-04 05:06:12"); 7918 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59)).toSimpleString() == "-0999-Dec-04 13:44:59"); 7919 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59)).toSimpleString() == "-9999-Jul-04 23:59:59"); 7920 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1)).toSimpleString() == "-10000-Oct-20 01:01:01"); 7921 7922 assert(SysTime(DateTime(0, 12, 4, 0, 0, 0), msecs(7)).toSimpleString() == "0000-Dec-04 00:00:00.007"); 7923 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0), msecs(42)).toSimpleString() == "-0009-Dec-04 00:00:00.042"); 7924 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12), msecs(100)).toSimpleString() == "-0099-Dec-04 05:06:12.1"); 7925 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59), usecs(45020)).toSimpleString() == 7926 "-0999-Dec-04 13:44:59.04502"); 7927 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59), hnsecs(12)).toSimpleString() == 7928 "-9999-Jul-04 23:59:59.0000012"); 7929 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1), hnsecs(507890)).toSimpleString() == 7930 "-10000-Oct-20 01:01:01.050789"); 7931 7932 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7933 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7934 assert(cast(TimeOfDay) cst != TimeOfDay.init); 7935 //assert(cast(TimeOfDay) ist != TimeOfDay.init); 7936 } 7937 7938 7939 /++ 7940 Converts this $(LREF SysTime) to a string. 7941 7942 This function exists to make it easy to convert a $(LREF SysTime) to a 7943 string for code that does not care what the exact format is - just that 7944 it presents the information in a clear manner. It also makes it easy to 7945 simply convert a $(LREF SysTime) to a string when using functions such 7946 as `to!string`, `format`, or `writeln` which use toString to convert 7947 user-defined types. So, it is unlikely that much code will call 7948 toString directly. 7949 7950 The format of the string is purposefully unspecified, and code that 7951 cares about the format of the string should use `toISOString`, 7952 `toISOExtString`, `toSimpleString`, or some other custom formatting 7953 function that explicitly generates the format that the code needs. The 7954 reason is that the code is then clear about what format it's using, 7955 making it less error-prone to maintain the code and interact with other 7956 software that consumes the generated strings. It's for this same reason 7957 that $(LREF SysTime) has no `fromString` function, whereas it does have 7958 `fromISOString`, `fromISOExtString`, and `fromSimpleString`. 7959 7960 The format returned by toString may or may not change in the future. 7961 +/ 7962 string toString() @safe const nothrow 7963 { 7964 return toSimpleString(); 7965 } 7966 7967 @safe unittest 7968 { 7969 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7970 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7971 //immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7972 assert(st.toString()); 7973 assert(cst.toString()); 7974 //assert(ist.toString()); 7975 } 7976 7977 7978 /++ 7979 Creates a $(LREF SysTime) from a string with the format 7980 YYYYMMDDTHHMMSS.FFFFFFFTZ (where F is fractional seconds is the time 7981 zone). Whitespace is stripped from the given string. 7982 7983 The exact format is exactly as described in $(D toISOString) except that 7984 trailing zeroes are permitted - including having fractional seconds with 7985 all zeroes. However, a decimal point with nothing following it is 7986 invalid. Also, while $(LREF toISOString) will never generate a string 7987 with more than 7 digits in the fractional seconds (because that's the 7988 limit with hecto-nanosecond precision), it will allow more than 7 digits 7989 in order to read strings from other sources that have higher precision 7990 (however, any digits beyond 7 will be truncated). 7991 7992 If there is no time zone in the string, then 7993 $(REF LocalTime,std,datetime,timezone) is used. If the time zone is "Z", 7994 then $(D UTC) is used. Otherwise, a 7995 $(REF SimpleTimeZone,std,datetime,timezone) which corresponds to the 7996 given offset from UTC is used. To get the returned $(LREF SysTime) to be 7997 a particular time zone, pass in that time zone and the $(LREF SysTime) 7998 to be returned will be converted to that time zone (though it will still 7999 be read in as whatever time zone is in its string). 8000 8001 The accepted formats for time zone offsets are +HH, -HH, +HHMM, and 8002 -HHMM. 8003 8004 $(RED Warning: 8005 Previously, $(LREF toISOString) did the same as 8006 $(LREF toISOExtString) and generated +HH:MM or -HH:MM for the time 8007 zone when it was not $(REF LocalTime,std,datetime,timezone) or 8008 $(REF UTC,std,datetime,timezone), which is not in conformance with 8009 ISO 8601 for the non-extended string format. This has now been 8010 fixed. However, for now, fromISOString will continue to accept the 8011 extended format for the time zone so that any code which has been 8012 writing out the result of toISOString to read in later will continue 8013 to work. The current behavior will be kept until July 2019 at which 8014 point, fromISOString will be fixed to be standards compliant.) 8015 8016 Params: 8017 isoString = A string formatted in the ISO format for dates and times. 8018 tz = The time zone to convert the given time to (no 8019 conversion occurs if null). 8020 8021 Throws: 8022 $(REF DateTimeException,std,datetime,date) if the given string is 8023 not in the ISO format or if the resulting $(LREF SysTime) would not 8024 be valid. 8025 +/ 8026 static SysTime fromISOString(S)(in S isoString, immutable TimeZone tz = null) @safe 8027 if (isSomeString!S) 8028 { 8029 import std.algorithm.searching : startsWith, find; 8030 import std.conv : to; 8031 import std.string : strip; 8032 8033 auto dstr = to!dstring(strip(isoString)); 8034 immutable skipFirst = dstr.startsWith('+', '-') != 0; 8035 8036 auto found = (skipFirst ? dstr[1..$] : dstr).find('.', 'Z', '+', '-'); 8037 auto dateTimeStr = dstr[0 .. $ - found[0].length]; 8038 8039 dstring fracSecStr; 8040 dstring zoneStr; 8041 8042 if (found[1] != 0) 8043 { 8044 if (found[1] == 1) 8045 { 8046 auto foundTZ = found[0].find('Z', '+', '-'); 8047 8048 if (foundTZ[1] != 0) 8049 { 8050 fracSecStr = found[0][0 .. $ - foundTZ[0].length]; 8051 zoneStr = foundTZ[0]; 8052 } 8053 else 8054 fracSecStr = found[0]; 8055 } 8056 else 8057 zoneStr = found[0]; 8058 } 8059 8060 try 8061 { 8062 auto dateTime = DateTime.fromISOString(dateTimeStr); 8063 auto fracSec = fracSecsFromISOString(fracSecStr); 8064 Rebindable!(immutable TimeZone) parsedZone; 8065 8066 if (zoneStr.empty) 8067 parsedZone = LocalTime(); 8068 else if (zoneStr == "Z") 8069 parsedZone = UTC(); 8070 else 8071 { 8072 try 8073 parsedZone = SimpleTimeZone.fromISOString(zoneStr); 8074 catch (DateTimeException dte) 8075 parsedZone = SimpleTimeZone.fromISOExtString(zoneStr); 8076 } 8077 8078 auto retval = SysTime(dateTime, fracSec, parsedZone); 8079 8080 if (tz !is null) 8081 retval.timezone = tz; 8082 8083 return retval; 8084 } 8085 catch (DateTimeException dte) 8086 throw new DateTimeException(format("Invalid ISO String: %s", isoString)); 8087 } 8088 8089 /// 8090 @safe unittest 8091 { 8092 import core.time : hours, msecs, usecs, hnsecs; 8093 import std.datetime.date : DateTime; 8094 import std.datetime.timezone : SimpleTimeZone, UTC; 8095 8096 assert(SysTime.fromISOString("20100704T070612") == 8097 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 8098 8099 assert(SysTime.fromISOString("19981225T021500.007") == 8100 SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(7))); 8101 8102 assert(SysTime.fromISOString("00000105T230959.00002") == 8103 SysTime(DateTime(0, 1, 5, 23, 9, 59), usecs(20))); 8104 8105 assert(SysTime.fromISOString("20130207T043937.000050392") == 8106 SysTime(DateTime(2013, 2, 7, 4, 39, 37), hnsecs(503))); 8107 8108 assert(SysTime.fromISOString("-00040105T000002") == 8109 SysTime(DateTime(-4, 1, 5, 0, 0, 2))); 8110 8111 assert(SysTime.fromISOString(" 20100704T070612 ") == 8112 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 8113 8114 assert(SysTime.fromISOString("20100704T070612Z") == 8115 SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC())); 8116 8117 assert(SysTime.fromISOString("20100704T070612-0800") == 8118 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 8119 new immutable SimpleTimeZone(hours(-8)))); 8120 8121 assert(SysTime.fromISOString("20100704T070612+0800") == 8122 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 8123 new immutable SimpleTimeZone(hours(8)))); 8124 } 8125 8126 @safe unittest 8127 { 8128 foreach (str; ["", "20100704000000", "20100704 000000", "20100704t000000", 8129 "20100704T000000.", "20100704T000000.A", "20100704T000000.Z", 8130 "20100704T000000.0000000A", "20100704T000000.00000000A", 8131 "20100704T000000+", "20100704T000000-", "20100704T000000:", 8132 "20100704T000000-:", "20100704T000000+:", "20100704T000000-1:", 8133 "20100704T000000+1:", "20100704T000000+1:0", 8134 "20100704T000000-12.00", "20100704T000000+12.00", 8135 "20100704T000000-8", "20100704T000000+8", 8136 "20100704T000000-800", "20100704T000000+800", 8137 "20100704T000000-080", "20100704T000000+080", 8138 "20100704T000000-2400", "20100704T000000+2400", 8139 "20100704T000000-1260", "20100704T000000+1260", 8140 "20100704T000000.0-8", "20100704T000000.0+8", 8141 "20100704T000000.0-800", "20100704T000000.0+800", 8142 "20100704T000000.0-080", "20100704T000000.0+080", 8143 "20100704T000000.0-2400", "20100704T000000.0+2400", 8144 "20100704T000000.0-1260", "20100704T000000.0+1260", 8145 "20100704T000000-8:00", "20100704T000000+8:00", 8146 "20100704T000000-08:0", "20100704T000000+08:0", 8147 "20100704T000000-24:00", "20100704T000000+24:00", 8148 "20100704T000000-12:60", "20100704T000000+12:60", 8149 "20100704T000000.0-8:00", "20100704T000000.0+8:00", 8150 "20100704T000000.0-08:0", "20100704T000000.0+08:0", 8151 "20100704T000000.0-24:00", "20100704T000000.0+24:00", 8152 "20100704T000000.0-12:60", "20100704T000000.0+12:60", 8153 "2010-07-0400:00:00", "2010-07-04 00:00:00", 8154 "2010-07-04t00:00:00", "2010-07-04T00:00:00.", 8155 "2010-Jul-0400:00:00", "2010-Jul-04 00:00:00", "2010-Jul-04t00:00:00", 8156 "2010-Jul-04T00:00:00", "2010-Jul-04 00:00:00.", 8157 "2010-12-22T172201", "2010-Dec-22 17:22:01"]) 8158 { 8159 assertThrown!DateTimeException(SysTime.fromISOString(str), format("[%s]", str)); 8160 } 8161 8162 static void test(string str, SysTime st, size_t line = __LINE__) 8163 { 8164 if (SysTime.fromISOString(str) != st) 8165 throw new AssertError("unittest failure", __FILE__, line); 8166 } 8167 8168 test("20101222T172201", SysTime(DateTime(2010, 12, 22, 17, 22, 01))); 8169 test("19990706T123033", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8170 test("-19990706T123033", SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 8171 test("+019990706T123033", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8172 test("19990706T123033 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8173 test(" 19990706T123033", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8174 test(" 19990706T123033 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8175 8176 test("19070707T121212.0", SysTime(DateTime(1907, 07, 07, 12, 12, 12))); 8177 test("19070707T121212.0000000", SysTime(DateTime(1907, 07, 07, 12, 12, 12))); 8178 test("19070707T121212.0000001", SysTime(DateTime(1907, 07, 07, 12, 12, 12), hnsecs(1))); 8179 test("20100704T000000.00000000", SysTime(Date(2010, 07, 04))); 8180 test("20100704T000000.00000009", SysTime(Date(2010, 07, 04))); 8181 test("20100704T000000.00000019", SysTime(DateTime(2010, 07, 04), hnsecs(1))); 8182 test("19070707T121212.000001", SysTime(DateTime(1907, 07, 07, 12, 12, 12), usecs(1))); 8183 test("19070707T121212.0000010", SysTime(DateTime(1907, 07, 07, 12, 12, 12), usecs(1))); 8184 test("19070707T121212.001", SysTime(DateTime(1907, 07, 07, 12, 12, 12), msecs(1))); 8185 test("19070707T121212.0010000", SysTime(DateTime(1907, 07, 07, 12, 12, 12), msecs(1))); 8186 8187 auto west60 = new immutable SimpleTimeZone(hours(-1)); 8188 auto west90 = new immutable SimpleTimeZone(minutes(-90)); 8189 auto west480 = new immutable SimpleTimeZone(hours(-8)); 8190 auto east60 = new immutable SimpleTimeZone(hours(1)); 8191 auto east90 = new immutable SimpleTimeZone(minutes(90)); 8192 auto east480 = new immutable SimpleTimeZone(hours(8)); 8193 8194 test("20101222T172201Z", SysTime(DateTime(2010, 12, 22, 17, 22, 01), UTC())); 8195 test("20101222T172201-0100", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west60)); 8196 test("20101222T172201-01", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west60)); 8197 test("20101222T172201-0130", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west90)); 8198 test("20101222T172201-0800", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west480)); 8199 test("20101222T172201+0100", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60)); 8200 test("20101222T172201+01", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60)); 8201 test("20101222T172201+0130", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east90)); 8202 test("20101222T172201+0800", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east480)); 8203 8204 test("20101103T065106.57159Z", SysTime(DateTime(2010, 11, 3, 6, 51, 6), hnsecs(5715900), UTC())); 8205 test("20101222T172201.23412Z", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(2_341_200), UTC())); 8206 test("20101222T172201.23112-0100", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(2_311_200), west60)); 8207 test("20101222T172201.45-01", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(4_500_000), west60)); 8208 test("20101222T172201.1-0130", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(1_000_000), west90)); 8209 test("20101222T172201.55-0800", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(5_500_000), west480)); 8210 test("20101222T172201.1234567+0100", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(1_234_567), east60)); 8211 test("20101222T172201.0+01", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60)); 8212 test("20101222T172201.0000000+0130", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east90)); 8213 test("20101222T172201.45+0800", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(4_500_000), east480)); 8214 8215 // @@@DEPRECATED_2019-07@@@ 8216 // This isn't deprecated per se, but that text will make it so that it 8217 // pops up when deprecations are moved along around July 2019. At that 8218 // time, we will update fromISOString so that it is conformant with ISO 8219 // 8601, and it will no longer accept ISO extended time zones (it does 8220 // currently because of issue #15654 - toISOString used to incorrectly 8221 // use the ISO extended time zone format). These tests will then start 8222 // failing will need to be updated accordingly. Also, the notes about 8223 // this issue in toISOString and fromISOString's documentation will need 8224 // to be removed. 8225 test("20101222T172201-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west60)); 8226 test("20101222T172201-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west90)); 8227 test("20101222T172201-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west480)); 8228 test("20101222T172201+01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60)); 8229 test("20101222T172201+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east90)); 8230 test("20101222T172201+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east480)); 8231 8232 test("20101222T172201.23112-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(2_311_200), west60)); 8233 test("20101222T172201.1-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(1_000_000), west90)); 8234 test("20101222T172201.55-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(5_500_000), west480)); 8235 test("20101222T172201.1234567+01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(1_234_567), east60)); 8236 test("20101222T172201.0000000+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east90)); 8237 test("20101222T172201.45+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(4_500_000), east480)); 8238 } 8239 8240 // bug# 17801 8241 @safe unittest 8242 { 8243 import std.conv : to; 8244 import std.meta : AliasSeq; 8245 foreach (C; AliasSeq!(char, wchar, dchar)) 8246 { 8247 foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) 8248 { 8249 assert(SysTime.fromISOString(to!S("20121221T141516Z")) == 8250 SysTime(DateTime(2012, 12, 21, 14, 15, 16), UTC())); 8251 } 8252 } 8253 } 8254 8255 8256 /++ 8257 Creates a $(LREF SysTime) from a string with the format 8258 YYYY-MM-DDTHH:MM:SS.FFFFFFFTZ (where F is fractional seconds is the 8259 time zone). Whitespace is stripped from the given string. 8260 8261 The exact format is exactly as described in $(D toISOExtString) 8262 except that trailing zeroes are permitted - including having fractional 8263 seconds with all zeroes. However, a decimal point with nothing following 8264 it is invalid. Also, while $(LREF toISOExtString) will never generate a 8265 string with more than 7 digits in the fractional seconds (because that's 8266 the limit with hecto-nanosecond precision), it will allow more than 7 8267 digits in order to read strings from other sources that have higher 8268 precision (however, any digits beyond 7 will be truncated). 8269 8270 If there is no time zone in the string, then 8271 $(REF LocalTime,std,datetime,timezone) is used. If the time zone is "Z", 8272 then $(D UTC) is used. Otherwise, a 8273 $(REF SimpleTimeZone,std,datetime,timezone) which corresponds to the 8274 given offset from UTC is used. To get the returned $(LREF SysTime) to be 8275 a particular time zone, pass in that time zone and the $(LREF SysTime) 8276 to be returned will be converted to that time zone (though it will still 8277 be read in as whatever time zone is in its string). 8278 8279 The accepted formats for time zone offsets are +HH, -HH, +HH:MM, and 8280 -HH:MM. 8281 8282 Params: 8283 isoExtString = A string formatted in the ISO Extended format for 8284 dates and times. 8285 tz = The time zone to convert the given time to (no 8286 conversion occurs if null). 8287 8288 Throws: 8289 $(REF DateTimeException,std,datetime,date) if the given string is 8290 not in the ISO format or if the resulting $(LREF SysTime) would not 8291 be valid. 8292 +/ 8293 static SysTime fromISOExtString(S)(in S isoExtString, immutable TimeZone tz = null) @safe 8294 if (isSomeString!(S)) 8295 { 8296 import std.algorithm.searching : countUntil, find; 8297 import std.conv : to; 8298 import std.string : strip; 8299 8300 auto dstr = to!dstring(strip(isoExtString)); 8301 8302 auto tIndex = dstr.countUntil('T'); 8303 enforce(tIndex != -1, new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString))); 8304 8305 auto found = dstr[tIndex + 1 .. $].find('.', 'Z', '+', '-'); 8306 auto dateTimeStr = dstr[0 .. $ - found[0].length]; 8307 8308 dstring fracSecStr; 8309 dstring zoneStr; 8310 8311 if (found[1] != 0) 8312 { 8313 if (found[1] == 1) 8314 { 8315 auto foundTZ = found[0].find('Z', '+', '-'); 8316 8317 if (foundTZ[1] != 0) 8318 { 8319 fracSecStr = found[0][0 .. $ - foundTZ[0].length]; 8320 zoneStr = foundTZ[0]; 8321 } 8322 else 8323 fracSecStr = found[0]; 8324 } 8325 else 8326 zoneStr = found[0]; 8327 } 8328 8329 try 8330 { 8331 auto dateTime = DateTime.fromISOExtString(dateTimeStr); 8332 auto fracSec = fracSecsFromISOString(fracSecStr); 8333 Rebindable!(immutable TimeZone) parsedZone; 8334 8335 if (zoneStr.empty) 8336 parsedZone = LocalTime(); 8337 else if (zoneStr == "Z") 8338 parsedZone = UTC(); 8339 else 8340 parsedZone = SimpleTimeZone.fromISOExtString(zoneStr); 8341 8342 auto retval = SysTime(dateTime, fracSec, parsedZone); 8343 8344 if (tz !is null) 8345 retval.timezone = tz; 8346 8347 return retval; 8348 } 8349 catch (DateTimeException dte) 8350 throw new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)); 8351 } 8352 8353 /// 8354 @safe unittest 8355 { 8356 import core.time : hours, msecs, usecs, hnsecs; 8357 import std.datetime.date : DateTime; 8358 import std.datetime.timezone : SimpleTimeZone, UTC; 8359 8360 assert(SysTime.fromISOExtString("2010-07-04T07:06:12") == 8361 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 8362 8363 assert(SysTime.fromISOExtString("1998-12-25T02:15:00.007") == 8364 SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(7))); 8365 8366 assert(SysTime.fromISOExtString("0000-01-05T23:09:59.00002") == 8367 SysTime(DateTime(0, 1, 5, 23, 9, 59), usecs(20))); 8368 8369 assert(SysTime.fromISOExtString("2013-02-07T04:39:37.000050392") == 8370 SysTime(DateTime(2013, 2, 7, 4, 39, 37), hnsecs(503))); 8371 8372 assert(SysTime.fromISOExtString("-0004-01-05T00:00:02") == 8373 SysTime(DateTime(-4, 1, 5, 0, 0, 2))); 8374 8375 assert(SysTime.fromISOExtString(" 2010-07-04T07:06:12 ") == 8376 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 8377 8378 assert(SysTime.fromISOExtString("2010-07-04T07:06:12Z") == 8379 SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC())); 8380 8381 assert(SysTime.fromISOExtString("2010-07-04T07:06:12-08:00") == 8382 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 8383 new immutable SimpleTimeZone(hours(-8)))); 8384 assert(SysTime.fromISOExtString("2010-07-04T07:06:12+08:00") == 8385 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 8386 new immutable SimpleTimeZone(hours(8)))); 8387 } 8388 8389 @safe unittest 8390 { 8391 foreach (str; ["", "20100704000000", "20100704 000000", 8392 "20100704t000000", "20100704T000000.", "20100704T000000.0", 8393 "2010-07:0400:00:00", "2010-07-04 00:00:00", 8394 "2010-07-04 00:00:00", "2010-07-04t00:00:00", 8395 "2010-07-04T00:00:00.", "2010-07-04T00:00:00.A", "2010-07-04T00:00:00.Z", 8396 "2010-07-04T00:00:00.0000000A", "2010-07-04T00:00:00.00000000A", 8397 "2010-07-04T00:00:00+", "2010-07-04T00:00:00-", 8398 "2010-07-04T00:00:00:", "2010-07-04T00:00:00-:", "2010-07-04T00:00:00+:", 8399 "2010-07-04T00:00:00-1:", "2010-07-04T00:00:00+1:", "2010-07-04T00:00:00+1:0", 8400 "2010-07-04T00:00:00-12.00", "2010-07-04T00:00:00+12.00", 8401 "2010-07-04T00:00:00-8", "2010-07-04T00:00:00+8", 8402 "20100704T000000-800", "20100704T000000+800", 8403 "20100704T000000-080", "20100704T000000+080", 8404 "20100704T000000-2400", "20100704T000000+2400", 8405 "20100704T000000-1260", "20100704T000000+1260", 8406 "20100704T000000.0-800", "20100704T000000.0+800", 8407 "20100704T000000.0-8", "20100704T000000.0+8", 8408 "20100704T000000.0-080", "20100704T000000.0+080", 8409 "20100704T000000.0-2400", "20100704T000000.0+2400", 8410 "20100704T000000.0-1260", "20100704T000000.0+1260", 8411 "2010-07-04T00:00:00-8:00", "2010-07-04T00:00:00+8:00", 8412 "2010-07-04T00:00:00-24:00", "2010-07-04T00:00:00+24:00", 8413 "2010-07-04T00:00:00-12:60", "2010-07-04T00:00:00+12:60", 8414 "2010-07-04T00:00:00.0-8:00", "2010-07-04T00:00:00.0+8:00", 8415 "2010-07-04T00:00:00.0-8", "2010-07-04T00:00:00.0+8", 8416 "2010-07-04T00:00:00.0-24:00", "2010-07-04T00:00:00.0+24:00", 8417 "2010-07-04T00:00:00.0-12:60", "2010-07-04T00:00:00.0+12:60", 8418 "2010-Jul-0400:00:00", "2010-Jul-04t00:00:00", 8419 "2010-Jul-04 00:00:00.", "2010-Jul-04 00:00:00.0", 8420 "20101222T172201", "2010-Dec-22 17:22:01"]) 8421 { 8422 assertThrown!DateTimeException(SysTime.fromISOExtString(str), format("[%s]", str)); 8423 } 8424 8425 static void test(string str, SysTime st, size_t line = __LINE__) 8426 { 8427 if (SysTime.fromISOExtString(str) != st) 8428 throw new AssertError("unittest failure", __FILE__, line); 8429 } 8430 8431 test("2010-12-22T17:22:01", SysTime(DateTime(2010, 12, 22, 17, 22, 01))); 8432 test("1999-07-06T12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8433 test("-1999-07-06T12:30:33", SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 8434 test("+01999-07-06T12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8435 test("1999-07-06T12:30:33 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8436 test(" 1999-07-06T12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8437 test(" 1999-07-06T12:30:33 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8438 8439 test("1907-07-07T12:12:12.0", SysTime(DateTime(1907, 07, 07, 12, 12, 12))); 8440 test("1907-07-07T12:12:12.0000000", SysTime(DateTime(1907, 07, 07, 12, 12, 12))); 8441 test("1907-07-07T12:12:12.0000001", SysTime(DateTime(1907, 07, 07, 12, 12, 12), hnsecs(1))); 8442 test("2010-07-04T00:00:00.00000000", SysTime(Date(2010, 07, 04))); 8443 test("2010-07-04T00:00:00.00000009", SysTime(Date(2010, 07, 04))); 8444 test("2010-07-04T00:00:00.00000019", SysTime(DateTime(2010, 07, 04), hnsecs(1))); 8445 test("1907-07-07T12:12:12.000001", SysTime(DateTime(1907, 07, 07, 12, 12, 12), usecs(1))); 8446 test("1907-07-07T12:12:12.0000010", SysTime(DateTime(1907, 07, 07, 12, 12, 12), usecs(1))); 8447 test("1907-07-07T12:12:12.001", SysTime(DateTime(1907, 07, 07, 12, 12, 12), msecs(1))); 8448 test("1907-07-07T12:12:12.0010000", SysTime(DateTime(1907, 07, 07, 12, 12, 12), msecs(1))); 8449 8450 auto west60 = new immutable SimpleTimeZone(hours(-1)); 8451 auto west90 = new immutable SimpleTimeZone(minutes(-90)); 8452 auto west480 = new immutable SimpleTimeZone(hours(-8)); 8453 auto east60 = new immutable SimpleTimeZone(hours(1)); 8454 auto east90 = new immutable SimpleTimeZone(minutes(90)); 8455 auto east480 = new immutable SimpleTimeZone(hours(8)); 8456 8457 test("2010-12-22T17:22:01Z", SysTime(DateTime(2010, 12, 22, 17, 22, 01), UTC())); 8458 test("2010-12-22T17:22:01-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west60)); 8459 test("2010-12-22T17:22:01-01", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west60)); 8460 test("2010-12-22T17:22:01-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west90)); 8461 test("2010-12-22T17:22:01-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west480)); 8462 test("2010-12-22T17:22:01+01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60)); 8463 test("2010-12-22T17:22:01+01", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60)); 8464 test("2010-12-22T17:22:01+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east90)); 8465 test("2010-12-22T17:22:01+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east480)); 8466 8467 test("2010-11-03T06:51:06.57159Z", SysTime(DateTime(2010, 11, 3, 6, 51, 6), hnsecs(5715900), UTC())); 8468 test("2010-12-22T17:22:01.23412Z", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(2_341_200), UTC())); 8469 test("2010-12-22T17:22:01.23112-01:00", 8470 SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(2_311_200), west60)); 8471 test("2010-12-22T17:22:01.45-01", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(4_500_000), west60)); 8472 test("2010-12-22T17:22:01.1-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(1_000_000), west90)); 8473 test("2010-12-22T17:22:01.55-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(5_500_000), west480)); 8474 test("2010-12-22T17:22:01.1234567+01:00", 8475 SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(1_234_567), east60)); 8476 test("2010-12-22T17:22:01.0+01", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60)); 8477 test("2010-12-22T17:22:01.0000000+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east90)); 8478 test("2010-12-22T17:22:01.45+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(4_500_000), east480)); 8479 } 8480 8481 // bug# 17801 8482 @safe unittest 8483 { 8484 import std.conv : to; 8485 import std.meta : AliasSeq; 8486 foreach (C; AliasSeq!(char, wchar, dchar)) 8487 { 8488 foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) 8489 { 8490 assert(SysTime.fromISOExtString(to!S("2012-12-21T14:15:16Z")) == 8491 SysTime(DateTime(2012, 12, 21, 14, 15, 16), UTC())); 8492 } 8493 } 8494 } 8495 8496 8497 /++ 8498 Creates a $(LREF SysTime) from a string with the format 8499 YYYY-MM-DD HH:MM:SS.FFFFFFFTZ (where F is fractional seconds is the 8500 time zone). Whitespace is stripped from the given string. 8501 8502 The exact format is exactly as described in $(D toSimpleString) except 8503 that trailing zeroes are permitted - including having fractional seconds 8504 with all zeroes. However, a decimal point with nothing following it is 8505 invalid. Also, while $(LREF toSimpleString) will never generate a 8506 string with more than 7 digits in the fractional seconds (because that's 8507 the limit with hecto-nanosecond precision), it will allow more than 7 8508 digits in order to read strings from other sources that have higher 8509 precision (however, any digits beyond 7 will be truncated). 8510 8511 If there is no time zone in the string, then 8512 $(REF LocalTime,std,datetime,timezone) is used. If the time zone is "Z", 8513 then $(D UTC) is used. Otherwise, a 8514 $(REF SimpleTimeZone,std,datetime,timezone) which corresponds to the 8515 given offset from UTC is used. To get the returned $(LREF SysTime) to be 8516 a particular time zone, pass in that time zone and the $(LREF SysTime) 8517 to be returned will be converted to that time zone (though it will still 8518 be read in as whatever time zone is in its string). 8519 8520 The accepted formats for time zone offsets are +HH, -HH, +HH:MM, and 8521 -HH:MM. 8522 8523 Params: 8524 simpleString = A string formatted in the way that 8525 $(D toSimpleString) formats dates and times. 8526 tz = The time zone to convert the given time to (no 8527 conversion occurs if null). 8528 8529 Throws: 8530 $(REF DateTimeException,std,datetime,date) if the given string is 8531 not in the ISO format or if the resulting $(LREF SysTime) would not 8532 be valid. 8533 +/ 8534 static SysTime fromSimpleString(S)(in S simpleString, immutable TimeZone tz = null) @safe 8535 if (isSomeString!(S)) 8536 { 8537 import std.algorithm.searching : countUntil, find; 8538 import std.conv : to; 8539 import std.string : strip; 8540 8541 auto dstr = to!dstring(strip(simpleString)); 8542 8543 auto spaceIndex = dstr.countUntil(' '); 8544 enforce(spaceIndex != -1, new DateTimeException(format("Invalid Simple String: %s", simpleString))); 8545 8546 auto found = dstr[spaceIndex + 1 .. $].find('.', 'Z', '+', '-'); 8547 auto dateTimeStr = dstr[0 .. $ - found[0].length]; 8548 8549 dstring fracSecStr; 8550 dstring zoneStr; 8551 8552 if (found[1] != 0) 8553 { 8554 if (found[1] == 1) 8555 { 8556 auto foundTZ = found[0].find('Z', '+', '-'); 8557 8558 if (foundTZ[1] != 0) 8559 { 8560 fracSecStr = found[0][0 .. $ - foundTZ[0].length]; 8561 zoneStr = foundTZ[0]; 8562 } 8563 else 8564 fracSecStr = found[0]; 8565 } 8566 else 8567 zoneStr = found[0]; 8568 } 8569 8570 try 8571 { 8572 auto dateTime = DateTime.fromSimpleString(dateTimeStr); 8573 auto fracSec = fracSecsFromISOString(fracSecStr); 8574 Rebindable!(immutable TimeZone) parsedZone; 8575 8576 if (zoneStr.empty) 8577 parsedZone = LocalTime(); 8578 else if (zoneStr == "Z") 8579 parsedZone = UTC(); 8580 else 8581 parsedZone = SimpleTimeZone.fromISOExtString(zoneStr); 8582 8583 auto retval = SysTime(dateTime, fracSec, parsedZone); 8584 8585 if (tz !is null) 8586 retval.timezone = tz; 8587 8588 return retval; 8589 } 8590 catch (DateTimeException dte) 8591 throw new DateTimeException(format("Invalid Simple String: %s", simpleString)); 8592 } 8593 8594 /// 8595 @safe unittest 8596 { 8597 import core.time : hours, msecs, usecs, hnsecs; 8598 import std.datetime.date : DateTime; 8599 import std.datetime.timezone : SimpleTimeZone, UTC; 8600 8601 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12") == 8602 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 8603 8604 assert(SysTime.fromSimpleString("1998-Dec-25 02:15:00.007") == 8605 SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(7))); 8606 8607 assert(SysTime.fromSimpleString("0000-Jan-05 23:09:59.00002") == 8608 SysTime(DateTime(0, 1, 5, 23, 9, 59), usecs(20))); 8609 8610 assert(SysTime.fromSimpleString("2013-Feb-07 04:39:37.000050392") == 8611 SysTime(DateTime(2013, 2, 7, 4, 39, 37), hnsecs(503))); 8612 8613 assert(SysTime.fromSimpleString("-0004-Jan-05 00:00:02") == 8614 SysTime(DateTime(-4, 1, 5, 0, 0, 2))); 8615 8616 assert(SysTime.fromSimpleString(" 2010-Jul-04 07:06:12 ") == 8617 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 8618 8619 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12Z") == 8620 SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC())); 8621 8622 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12-08:00") == 8623 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 8624 new immutable SimpleTimeZone(hours(-8)))); 8625 8626 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12+08:00") == 8627 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 8628 new immutable SimpleTimeZone(hours(8)))); 8629 } 8630 8631 @safe unittest 8632 { 8633 foreach (str; ["", "20100704000000", "20100704 000000", 8634 "20100704t000000", "20100704T000000.", "20100704T000000.0", 8635 "2010-07-0400:00:00", "2010-07-04 00:00:00", "2010-07-04t00:00:00", 8636 "2010-07-04T00:00:00.", "2010-07-04T00:00:00.0", 8637 "2010-Jul-0400:00:00", "2010-Jul-04t00:00:00", "2010-Jul-04T00:00:00", 8638 "2010-Jul-04 00:00:00.", "2010-Jul-04 00:00:00.A", "2010-Jul-04 00:00:00.Z", 8639 "2010-Jul-04 00:00:00.0000000A", "2010-Jul-04 00:00:00.00000000A", 8640 "2010-Jul-04 00:00:00+", "2010-Jul-04 00:00:00-", 8641 "2010-Jul-04 00:00:00:", "2010-Jul-04 00:00:00-:", 8642 "2010-Jul-04 00:00:00+:", "2010-Jul-04 00:00:00-1:", 8643 "2010-Jul-04 00:00:00+1:", "2010-Jul-04 00:00:00+1:0", 8644 "2010-Jul-04 00:00:00-12.00", "2010-Jul-04 00:00:00+12.00", 8645 "2010-Jul-04 00:00:00-8", "2010-Jul-04 00:00:00+8", 8646 "20100704T000000-800", "20100704T000000+800", 8647 "20100704T000000-080", "20100704T000000+080", 8648 "20100704T000000-2400", "20100704T000000+2400", 8649 "20100704T000000-1260", "20100704T000000+1260", 8650 "20100704T000000.0-800", "20100704T000000.0+800", 8651 "20100704T000000.0-8", "20100704T000000.0+8", 8652 "20100704T000000.0-080", "20100704T000000.0+080", 8653 "20100704T000000.0-2400", "20100704T000000.0+2400", 8654 "20100704T000000.0-1260", "20100704T000000.0+1260", 8655 "2010-Jul-04 00:00:00-8:00", "2010-Jul-04 00:00:00+8:00", 8656 "2010-Jul-04 00:00:00-08:0", "2010-Jul-04 00:00:00+08:0", 8657 "2010-Jul-04 00:00:00-24:00", "2010-Jul-04 00:00:00+24:00", 8658 "2010-Jul-04 00:00:00-12:60", "2010-Jul-04 00:00:00+24:60", 8659 "2010-Jul-04 00:00:00.0-8:00", "2010-Jul-04 00:00:00+8:00", 8660 "2010-Jul-04 00:00:00.0-8", "2010-Jul-04 00:00:00.0+8", 8661 "2010-Jul-04 00:00:00.0-08:0", "2010-Jul-04 00:00:00.0+08:0", 8662 "2010-Jul-04 00:00:00.0-24:00", "2010-Jul-04 00:00:00.0+24:00", 8663 "2010-Jul-04 00:00:00.0-12:60", "2010-Jul-04 00:00:00.0+24:60", 8664 "20101222T172201", "2010-12-22T172201"]) 8665 { 8666 assertThrown!DateTimeException(SysTime.fromSimpleString(str), format("[%s]", str)); 8667 } 8668 8669 static void test(string str, SysTime st, size_t line = __LINE__) 8670 { 8671 if (SysTime.fromSimpleString(str) != st) 8672 throw new AssertError("unittest failure", __FILE__, line); 8673 } 8674 8675 test("2010-Dec-22 17:22:01", SysTime(DateTime(2010, 12, 22, 17, 22, 01))); 8676 test("1999-Jul-06 12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8677 test("-1999-Jul-06 12:30:33", SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 8678 test("+01999-Jul-06 12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8679 test("1999-Jul-06 12:30:33 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8680 test(" 1999-Jul-06 12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8681 test(" 1999-Jul-06 12:30:33 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8682 8683 test("1907-Jul-07 12:12:12.0", SysTime(DateTime(1907, 07, 07, 12, 12, 12))); 8684 test("1907-Jul-07 12:12:12.0000000", SysTime(DateTime(1907, 07, 07, 12, 12, 12))); 8685 test("2010-Jul-04 00:00:00.00000000", SysTime(Date(2010, 07, 04))); 8686 test("2010-Jul-04 00:00:00.00000009", SysTime(Date(2010, 07, 04))); 8687 test("2010-Jul-04 00:00:00.00000019", SysTime(DateTime(2010, 07, 04), hnsecs(1))); 8688 test("1907-Jul-07 12:12:12.0000001", SysTime(DateTime(1907, 07, 07, 12, 12, 12), hnsecs(1))); 8689 test("1907-Jul-07 12:12:12.000001", SysTime(DateTime(1907, 07, 07, 12, 12, 12), usecs(1))); 8690 test("1907-Jul-07 12:12:12.0000010", SysTime(DateTime(1907, 07, 07, 12, 12, 12), usecs(1))); 8691 test("1907-Jul-07 12:12:12.001", SysTime(DateTime(1907, 07, 07, 12, 12, 12), msecs(1))); 8692 test("1907-Jul-07 12:12:12.0010000", SysTime(DateTime(1907, 07, 07, 12, 12, 12), msecs(1))); 8693 8694 auto west60 = new immutable SimpleTimeZone(hours(-1)); 8695 auto west90 = new immutable SimpleTimeZone(minutes(-90)); 8696 auto west480 = new immutable SimpleTimeZone(hours(-8)); 8697 auto east60 = new immutable SimpleTimeZone(hours(1)); 8698 auto east90 = new immutable SimpleTimeZone(minutes(90)); 8699 auto east480 = new immutable SimpleTimeZone(hours(8)); 8700 8701 test("2010-Dec-22 17:22:01Z", SysTime(DateTime(2010, 12, 22, 17, 22, 01), UTC())); 8702 test("2010-Dec-22 17:22:01-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west60)); 8703 test("2010-Dec-22 17:22:01-01", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west60)); 8704 test("2010-Dec-22 17:22:01-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west90)); 8705 test("2010-Dec-22 17:22:01-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west480)); 8706 test("2010-Dec-22 17:22:01+01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60)); 8707 test("2010-Dec-22 17:22:01+01", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60)); 8708 test("2010-Dec-22 17:22:01+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east90)); 8709 test("2010-Dec-22 17:22:01+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east480)); 8710 8711 test("2010-Nov-03 06:51:06.57159Z", SysTime(DateTime(2010, 11, 3, 6, 51, 6), hnsecs(5715900), UTC())); 8712 test("2010-Dec-22 17:22:01.23412Z", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(2_341_200), UTC())); 8713 test("2010-Dec-22 17:22:01.23112-01:00", 8714 SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(2_311_200), west60)); 8715 test("2010-Dec-22 17:22:01.45-01", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(4_500_000), west60)); 8716 test("2010-Dec-22 17:22:01.1-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(1_000_000), west90)); 8717 test("2010-Dec-22 17:22:01.55-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(5_500_000), west480)); 8718 test("2010-Dec-22 17:22:01.1234567+01:00", 8719 SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(1_234_567), east60)); 8720 test("2010-Dec-22 17:22:01.0+01", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60)); 8721 test("2010-Dec-22 17:22:01.0000000+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east90)); 8722 test("2010-Dec-22 17:22:01.45+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(4_500_000), east480)); 8723 } 8724 8725 // bug# 17801 8726 @safe unittest 8727 { 8728 import std.conv : to; 8729 import std.meta : AliasSeq; 8730 foreach (C; AliasSeq!(char, wchar, dchar)) 8731 { 8732 foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) 8733 { 8734 assert(SysTime.fromSimpleString(to!S("2012-Dec-21 14:15:16Z")) == 8735 SysTime(DateTime(2012, 12, 21, 14, 15, 16), UTC())); 8736 } 8737 } 8738 } 8739 8740 8741 /++ 8742 Returns the $(LREF SysTime) farthest in the past which is representable 8743 by $(LREF SysTime). 8744 8745 The $(LREF SysTime) which is returned is in UTC. 8746 +/ 8747 @property static SysTime min() @safe pure nothrow 8748 { 8749 return SysTime(long.min, UTC()); 8750 } 8751 8752 @safe unittest 8753 { 8754 assert(SysTime.min.year < 0); 8755 assert(SysTime.min < SysTime.max); 8756 } 8757 8758 8759 /++ 8760 Returns the $(LREF SysTime) farthest in the future which is representable 8761 by $(LREF SysTime). 8762 8763 The $(LREF SysTime) which is returned is in UTC. 8764 +/ 8765 @property static SysTime max() @safe pure nothrow 8766 { 8767 return SysTime(long.max, UTC()); 8768 } 8769 8770 @safe unittest 8771 { 8772 assert(SysTime.max.year > 0); 8773 assert(SysTime.max > SysTime.min); 8774 } 8775 8776 8777 private: 8778 8779 /+ 8780 Returns $(D stdTime) converted to $(LREF SysTime)'s time zone. 8781 +/ 8782 @property long adjTime() @safe const nothrow 8783 { 8784 return _timezone.utcToTZ(_stdTime); 8785 } 8786 8787 8788 /+ 8789 Converts the given hnsecs from $(LREF SysTime)'s time zone to std time. 8790 +/ 8791 @property void adjTime(long adjTime) @safe nothrow 8792 { 8793 _stdTime = _timezone.tzToUTC(adjTime); 8794 } 8795 8796 8797 // Commented out due to bug http://d.puremagic.com/issues/show_bug.cgi?id=5058 8798 /+ 8799 invariant() 8800 { 8801 assert(_timezone !is null, "Invariant Failure: timezone is null. Were you foolish enough to use " ~ 8802 "SysTime.init? (since timezone for SysTime.init can't be set at compile time)."); 8803 } 8804 +/ 8805 8806 8807 long _stdTime; 8808 Rebindable!(immutable TimeZone) _timezone; 8809 } 8810 8811 8812 /++ 8813 Converts from unix time (which uses midnight, January 1st, 1970 UTC as its 8814 epoch and seconds as its units) to "std time" (which uses midnight, 8815 January 1st, 1 A.D. UTC and hnsecs as its units). 8816 8817 The C standard does not specify the representation of time_t, so it is 8818 implementation defined. On POSIX systems, unix time is equivalent to 8819 time_t, but that's not necessarily true on other systems (e.g. it is 8820 not true for the Digital Mars C runtime). So, be careful when using unix 8821 time with C functions on non-POSIX systems. 8822 8823 "std time"'s epoch is based on the Proleptic Gregorian Calendar per ISO 8824 8601 and is what $(LREF SysTime) uses internally. However, holding the time 8825 as an integer in hnescs since that epoch technically isn't actually part of 8826 the standard, much as it's based on it, so the name "std time" isn't 8827 particularly good, but there isn't an official name for it. C# uses "ticks" 8828 for the same thing, but they aren't actually clock ticks, and the term 8829 "ticks" $(I is) used for actual clock ticks for $(REF MonoTime, core,time), 8830 so it didn't make sense to use the term ticks here. So, for better or worse, 8831 std.datetime uses the term "std time" for this. 8832 8833 Params: 8834 unixTime = The unix time to convert. 8835 8836 See_Also: 8837 SysTime.fromUnixTime 8838 +/ 8839 long unixTimeToStdTime(long unixTime) @safe pure nothrow 8840 { 8841 return 621_355_968_000_000_000L + convert!("seconds", "hnsecs")(unixTime); 8842 } 8843 8844 /// 8845 @safe unittest 8846 { 8847 import std.datetime.date : DateTime; 8848 import std.datetime.timezone : UTC; 8849 8850 // Midnight, January 1st, 1970 8851 assert(unixTimeToStdTime(0) == 621_355_968_000_000_000L); 8852 assert(SysTime(unixTimeToStdTime(0)) == 8853 SysTime(DateTime(1970, 1, 1), UTC())); 8854 8855 assert(unixTimeToStdTime(int.max) == 642_830_804_470_000_000L); 8856 assert(SysTime(unixTimeToStdTime(int.max)) == 8857 SysTime(DateTime(2038, 1, 19, 3, 14, 07), UTC())); 8858 8859 assert(unixTimeToStdTime(-127_127) == 621_354_696_730_000_000L); 8860 assert(SysTime(unixTimeToStdTime(-127_127)) == 8861 SysTime(DateTime(1969, 12, 30, 12, 41, 13), UTC())); 8862 } 8863 8864 @safe unittest 8865 { 8866 // Midnight, January 2nd, 1970 8867 assert(unixTimeToStdTime(86_400) == 621_355_968_000_000_000L + 864_000_000_000L); 8868 // Midnight, December 31st, 1969 8869 assert(unixTimeToStdTime(-86_400) == 621_355_968_000_000_000L - 864_000_000_000L); 8870 8871 assert(unixTimeToStdTime(0) == (Date(1970, 1, 1) - Date(1, 1, 1)).total!"hnsecs"); 8872 assert(unixTimeToStdTime(0) == (DateTime(1970, 1, 1) - DateTime(1, 1, 1)).total!"hnsecs"); 8873 8874 foreach (dt; [DateTime(2010, 11, 1, 19, 5, 22), DateTime(1952, 7, 6, 2, 17, 9)]) 8875 assert(unixTimeToStdTime((dt - DateTime(1970, 1, 1)).total!"seconds") == (dt - DateTime.init).total!"hnsecs"); 8876 } 8877 8878 8879 /++ 8880 Converts std time (which uses midnight, January 1st, 1 A.D. UTC as its epoch 8881 and hnsecs as its units) to unix time (which uses midnight, January 1st, 8882 1970 UTC as its epoch and seconds as its units). 8883 8884 The C standard does not specify the representation of time_t, so it is 8885 implementation defined. On POSIX systems, unix time is equivalent to 8886 time_t, but that's not necessarily true on other systems (e.g. it is 8887 not true for the Digital Mars C runtime). So, be careful when using unix 8888 time with C functions on non-POSIX systems. 8889 8890 "std time"'s epoch is based on the Proleptic Gregorian Calendar per ISO 8891 8601 and is what $(LREF SysTime) uses internally. However, holding the time 8892 as an integer in hnescs since that epoch technically isn't actually part of 8893 the standard, much as it's based on it, so the name "std time" isn't 8894 particularly good, but there isn't an official name for it. C# uses "ticks" 8895 for the same thing, but they aren't actually clock ticks, and the term 8896 "ticks" $(I is) used for actual clock ticks for $(REF MonoTime, core,time), 8897 so it didn't make sense to use the term ticks here. So, for better or worse, 8898 std.datetime uses the term "std time" for this. 8899 8900 By default, the return type is time_t (which is normally an alias for 8901 int on 32-bit systems and long on 64-bit systems), but if a different 8902 size is required than either int or long can be passed as a template 8903 argument to get the desired size. 8904 8905 If the return type is int, and the result can't fit in an int, then the 8906 closest value that can be held in 32 bits will be used (so $(D int.max) 8907 if it goes over and $(D int.min) if it goes under). However, no attempt 8908 is made to deal with integer overflow if the return type is long. 8909 8910 Params: 8911 T = The return type (int or long). It defaults to time_t, which is 8912 normally 32 bits on a 32-bit system and 64 bits on a 64-bit 8913 system. 8914 stdTime = The std time to convert. 8915 8916 Returns: 8917 A signed integer representing the unix time which is equivalent to 8918 the given std time. 8919 8920 See_Also: 8921 SysTime.toUnixTime 8922 +/ 8923 T stdTimeToUnixTime(T = time_t)(long stdTime) @safe pure nothrow 8924 if (is(T == int) || is(T == long)) 8925 { 8926 immutable unixTime = convert!("hnsecs", "seconds")(stdTime - 621_355_968_000_000_000L); 8927 8928 static assert(is(time_t == int) || is(time_t == long), 8929 "Currently, std.datetime only supports systems where time_t is int or long"); 8930 8931 static if (is(T == long)) 8932 return unixTime; 8933 else static if (is(T == int)) 8934 { 8935 if (unixTime > int.max) 8936 return int.max; 8937 return unixTime < int.min ? int.min : cast(int) unixTime; 8938 } 8939 else 8940 static assert(0, "Bug in template constraint. Only int and long allowed."); 8941 } 8942 8943 /// 8944 @safe unittest 8945 { 8946 // Midnight, January 1st, 1970 UTC 8947 assert(stdTimeToUnixTime(621_355_968_000_000_000L) == 0); 8948 8949 // 2038-01-19 03:14:07 UTC 8950 assert(stdTimeToUnixTime(642_830_804_470_000_000L) == int.max); 8951 } 8952 8953 @safe unittest 8954 { 8955 enum unixEpochAsStdTime = (Date(1970, 1, 1) - Date.init).total!"hnsecs"; 8956 8957 assert(stdTimeToUnixTime(unixEpochAsStdTime) == 0); // Midnight, January 1st, 1970 8958 assert(stdTimeToUnixTime(unixEpochAsStdTime + 864_000_000_000L) == 86_400); // Midnight, January 2nd, 1970 8959 assert(stdTimeToUnixTime(unixEpochAsStdTime - 864_000_000_000L) == -86_400); // Midnight, December 31st, 1969 8960 8961 assert(stdTimeToUnixTime((Date(1970, 1, 1) - Date(1, 1, 1)).total!"hnsecs") == 0); 8962 assert(stdTimeToUnixTime((DateTime(1970, 1, 1) - DateTime(1, 1, 1)).total!"hnsecs") == 0); 8963 8964 foreach (dt; [DateTime(2010, 11, 1, 19, 5, 22), DateTime(1952, 7, 6, 2, 17, 9)]) 8965 assert(stdTimeToUnixTime((dt - DateTime.init).total!"hnsecs") == (dt - DateTime(1970, 1, 1)).total!"seconds"); 8966 8967 enum max = convert!("seconds", "hnsecs")(int.max); 8968 enum min = convert!("seconds", "hnsecs")(int.min); 8969 enum one = convert!("seconds", "hnsecs")(1); 8970 8971 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + max) == int.max); 8972 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + max) == int.max); 8973 8974 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + max + one) == int.max + 1L); 8975 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + max + one) == int.max); 8976 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + max + 9_999_999) == int.max); 8977 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + max + 9_999_999) == int.max); 8978 8979 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + min) == int.min); 8980 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + min) == int.min); 8981 8982 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + min - one) == int.min - 1L); 8983 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + min - one) == int.min); 8984 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + min - 9_999_999) == int.min); 8985 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + min - 9_999_999) == int.min); 8986 } 8987 8988 8989 version (StdDdoc) 8990 { 8991 version (Windows) 8992 {} 8993 else 8994 { 8995 alias SYSTEMTIME = void*; 8996 alias FILETIME = void*; 8997 } 8998 8999 /++ 9000 $(BLUE This function is Windows-Only.) 9001 9002 Converts a $(D SYSTEMTIME) struct to a $(LREF SysTime). 9003 9004 Params: 9005 st = The $(D SYSTEMTIME) struct to convert. 9006 tz = The time zone that the time in the $(D SYSTEMTIME) struct is 9007 assumed to be (if the $(D SYSTEMTIME) was supplied by a Windows 9008 system call, the $(D SYSTEMTIME) will either be in local time 9009 or UTC, depending on the call). 9010 9011 Throws: 9012 $(REF DateTimeException,std,datetime,date) if the given 9013 $(D SYSTEMTIME) will not fit in a $(LREF SysTime), which is highly 9014 unlikely to happen given that $(D SysTime.max) is in 29,228 A.D. and 9015 the maximum $(D SYSTEMTIME) is in 30,827 A.D. 9016 +/ 9017 SysTime SYSTEMTIMEToSysTime(const SYSTEMTIME* st, immutable TimeZone tz = LocalTime()) @safe; 9018 9019 9020 /++ 9021 $(BLUE This function is Windows-Only.) 9022 9023 Converts a $(LREF SysTime) to a $(D SYSTEMTIME) struct. 9024 9025 The $(D SYSTEMTIME) which is returned will be set using the given 9026 $(LREF SysTime)'s time zone, so to get the $(D SYSTEMTIME) in 9027 UTC, set the $(LREF SysTime)'s time zone to UTC. 9028 9029 Params: 9030 sysTime = The $(LREF SysTime) to convert. 9031 9032 Throws: 9033 $(REF DateTimeException,std,datetime,date) if the given 9034 $(LREF SysTime) will not fit in a $(D SYSTEMTIME). This will only 9035 happen if the $(LREF SysTime)'s date is prior to 1601 A.D. 9036 +/ 9037 SYSTEMTIME SysTimeToSYSTEMTIME(in SysTime sysTime) @safe; 9038 9039 9040 /++ 9041 $(BLUE This function is Windows-Only.) 9042 9043 Converts a $(D FILETIME) struct to the number of hnsecs since midnight, 9044 January 1st, 1 A.D. 9045 9046 Params: 9047 ft = The $(D FILETIME) struct to convert. 9048 9049 Throws: 9050 $(REF DateTimeException,std,datetime,date) if the given 9051 $(D FILETIME) cannot be represented as the return value. 9052 +/ 9053 long FILETIMEToStdTime(scope const FILETIME* ft) @safe; 9054 9055 9056 /++ 9057 $(BLUE This function is Windows-Only.) 9058 9059 Converts a $(D FILETIME) struct to a $(LREF SysTime). 9060 9061 Params: 9062 ft = The $(D FILETIME) struct to convert. 9063 tz = The time zone that the $(LREF SysTime) will be in 9064 ($(D FILETIME)s are in UTC). 9065 9066 Throws: 9067 $(REF DateTimeException,std,datetime,date) if the given 9068 $(D FILETIME) will not fit in a $(LREF SysTime). 9069 +/ 9070 SysTime FILETIMEToSysTime(scope const FILETIME* ft, immutable TimeZone tz = LocalTime()) @safe; 9071 9072 9073 /++ 9074 $(BLUE This function is Windows-Only.) 9075 9076 Converts a number of hnsecs since midnight, January 1st, 1 A.D. to a 9077 $(D FILETIME) struct. 9078 9079 Params: 9080 stdTime = The number of hnsecs since midnight, January 1st, 1 A.D. 9081 UTC. 9082 9083 Throws: 9084 $(REF DateTimeException,std,datetime,date) if the given value will 9085 not fit in a $(D FILETIME). 9086 +/ 9087 FILETIME stdTimeToFILETIME(long stdTime) @safe; 9088 9089 9090 /++ 9091 $(BLUE This function is Windows-Only.) 9092 9093 Converts a $(LREF SysTime) to a $(D FILETIME) struct. 9094 9095 $(D FILETIME)s are always in UTC. 9096 9097 Params: 9098 sysTime = The $(LREF SysTime) to convert. 9099 9100 Throws: 9101 $(REF DateTimeException,std,datetime,date) if the given 9102 $(LREF SysTime) will not fit in a $(D FILETIME). 9103 +/ 9104 FILETIME SysTimeToFILETIME(SysTime sysTime) @safe; 9105 } 9106 else version (Windows) 9107 { 9108 SysTime SYSTEMTIMEToSysTime(const SYSTEMTIME* st, immutable TimeZone tz = LocalTime()) @safe 9109 { 9110 const max = SysTime.max; 9111 9112 static void throwLaterThanMax() 9113 { 9114 throw new DateTimeException("The given SYSTEMTIME is for a date greater than SysTime.max."); 9115 } 9116 9117 if (st.wYear > max.year) 9118 throwLaterThanMax(); 9119 else if (st.wYear == max.year) 9120 { 9121 if (st.wMonth > max.month) 9122 throwLaterThanMax(); 9123 else if (st.wMonth == max.month) 9124 { 9125 if (st.wDay > max.day) 9126 throwLaterThanMax(); 9127 else if (st.wDay == max.day) 9128 { 9129 if (st.wHour > max.hour) 9130 throwLaterThanMax(); 9131 else if (st.wHour == max.hour) 9132 { 9133 if (st.wMinute > max.minute) 9134 throwLaterThanMax(); 9135 else if (st.wMinute == max.minute) 9136 { 9137 if (st.wSecond > max.second) 9138 throwLaterThanMax(); 9139 else if (st.wSecond == max.second) 9140 { 9141 if (st.wMilliseconds > max.fracSecs.total!"msecs") 9142 throwLaterThanMax(); 9143 } 9144 } 9145 } 9146 } 9147 } 9148 } 9149 9150 auto dt = DateTime(st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); 9151 9152 return SysTime(dt, msecs(st.wMilliseconds), tz); 9153 } 9154 9155 @system unittest 9156 { 9157 auto sysTime = Clock.currTime(UTC()); 9158 SYSTEMTIME st = void; 9159 GetSystemTime(&st); 9160 auto converted = SYSTEMTIMEToSysTime(&st, UTC()); 9161 9162 assert(abs((converted - sysTime)) <= dur!"seconds"(2)); 9163 } 9164 9165 9166 SYSTEMTIME SysTimeToSYSTEMTIME(in SysTime sysTime) @safe 9167 { 9168 immutable dt = cast(DateTime) sysTime; 9169 9170 if (dt.year < 1601) 9171 throw new DateTimeException("SYSTEMTIME cannot hold dates prior to the year 1601."); 9172 9173 SYSTEMTIME st; 9174 9175 st.wYear = dt.year; 9176 st.wMonth = dt.month; 9177 st.wDayOfWeek = dt.dayOfWeek; 9178 st.wDay = dt.day; 9179 st.wHour = dt.hour; 9180 st.wMinute = dt.minute; 9181 st.wSecond = dt.second; 9182 st.wMilliseconds = cast(ushort) sysTime.fracSecs.total!"msecs"; 9183 9184 return st; 9185 } 9186 9187 @system unittest 9188 { 9189 SYSTEMTIME st = void; 9190 GetSystemTime(&st); 9191 auto sysTime = SYSTEMTIMEToSysTime(&st, UTC()); 9192 9193 SYSTEMTIME result = SysTimeToSYSTEMTIME(sysTime); 9194 9195 assert(st.wYear == result.wYear); 9196 assert(st.wMonth == result.wMonth); 9197 assert(st.wDayOfWeek == result.wDayOfWeek); 9198 assert(st.wDay == result.wDay); 9199 assert(st.wHour == result.wHour); 9200 assert(st.wMinute == result.wMinute); 9201 assert(st.wSecond == result.wSecond); 9202 assert(st.wMilliseconds == result.wMilliseconds); 9203 } 9204 9205 private enum hnsecsFrom1601 = 504_911_232_000_000_000L; 9206 9207 long FILETIMEToStdTime(scope const FILETIME* ft) @safe 9208 { 9209 ULARGE_INTEGER ul; 9210 ul.HighPart = ft.dwHighDateTime; 9211 ul.LowPart = ft.dwLowDateTime; 9212 ulong tempHNSecs = ul.QuadPart; 9213 9214 if (tempHNSecs > long.max - hnsecsFrom1601) 9215 throw new DateTimeException("The given FILETIME cannot be represented as a stdTime value."); 9216 9217 return cast(long) tempHNSecs + hnsecsFrom1601; 9218 } 9219 9220 SysTime FILETIMEToSysTime(scope const FILETIME* ft, immutable TimeZone tz = LocalTime()) @safe 9221 { 9222 auto sysTime = SysTime(FILETIMEToStdTime(ft), UTC()); 9223 sysTime.timezone = tz; 9224 return sysTime; 9225 } 9226 9227 @system unittest 9228 { 9229 auto sysTime = Clock.currTime(UTC()); 9230 SYSTEMTIME st = void; 9231 GetSystemTime(&st); 9232 9233 FILETIME ft = void; 9234 SystemTimeToFileTime(&st, &ft); 9235 9236 auto converted = FILETIMEToSysTime(&ft); 9237 9238 assert(abs((converted - sysTime)) <= dur!"seconds"(2)); 9239 } 9240 9241 9242 FILETIME stdTimeToFILETIME(long stdTime) @safe 9243 { 9244 if (stdTime < hnsecsFrom1601) 9245 throw new DateTimeException("The given stdTime value cannot be represented as a FILETIME."); 9246 9247 ULARGE_INTEGER ul; 9248 ul.QuadPart = cast(ulong) stdTime - hnsecsFrom1601; 9249 9250 FILETIME ft; 9251 ft.dwHighDateTime = ul.HighPart; 9252 ft.dwLowDateTime = ul.LowPart; 9253 9254 return ft; 9255 } 9256 9257 FILETIME SysTimeToFILETIME(SysTime sysTime) @safe 9258 { 9259 return stdTimeToFILETIME(sysTime.stdTime); 9260 } 9261 9262 @system unittest 9263 { 9264 SYSTEMTIME st = void; 9265 GetSystemTime(&st); 9266 9267 FILETIME ft = void; 9268 SystemTimeToFileTime(&st, &ft); 9269 auto sysTime = FILETIMEToSysTime(&ft, UTC()); 9270 9271 FILETIME result = SysTimeToFILETIME(sysTime); 9272 9273 assert(ft.dwLowDateTime == result.dwLowDateTime); 9274 assert(ft.dwHighDateTime == result.dwHighDateTime); 9275 } 9276 } 9277 9278 9279 /++ 9280 Type representing the DOS file date/time format. 9281 +/ 9282 alias DosFileTime = uint; 9283 9284 /++ 9285 Converts from DOS file date/time to $(LREF SysTime). 9286 9287 Params: 9288 dft = The DOS file time to convert. 9289 tz = The time zone which the DOS file time is assumed to be in. 9290 9291 Throws: 9292 $(REF DateTimeException,std,datetime,date) if the $(D DosFileTime) is 9293 invalid. 9294 +/ 9295 SysTime DosFileTimeToSysTime(DosFileTime dft, immutable TimeZone tz = LocalTime()) @safe 9296 { 9297 uint dt = cast(uint) dft; 9298 9299 if (dt == 0) 9300 throw new DateTimeException("Invalid DosFileTime."); 9301 9302 int year = ((dt >> 25) & 0x7F) + 1980; 9303 int month = ((dt >> 21) & 0x0F); // 1 .. 12 9304 int dayOfMonth = ((dt >> 16) & 0x1F); // 1 .. 31 9305 int hour = (dt >> 11) & 0x1F; // 0 .. 23 9306 int minute = (dt >> 5) & 0x3F; // 0 .. 59 9307 int second = (dt << 1) & 0x3E; // 0 .. 58 (in 2 second increments) 9308 9309 try 9310 return SysTime(DateTime(year, month, dayOfMonth, hour, minute, second), tz); 9311 catch (DateTimeException dte) 9312 throw new DateTimeException("Invalid DosFileTime", __FILE__, __LINE__, dte); 9313 } 9314 9315 @safe unittest 9316 { 9317 assert(DosFileTimeToSysTime(0b00000000001000010000000000000000) == SysTime(DateTime(1980, 1, 1, 0, 0, 0))); 9318 assert(DosFileTimeToSysTime(0b11111111100111111011111101111101) == SysTime(DateTime(2107, 12, 31, 23, 59, 58))); 9319 assert(DosFileTimeToSysTime(0x3E3F8456) == SysTime(DateTime(2011, 1, 31, 16, 34, 44))); 9320 } 9321 9322 9323 /++ 9324 Converts from $(LREF SysTime) to DOS file date/time. 9325 9326 Params: 9327 sysTime = The $(LREF SysTime) to convert. 9328 9329 Throws: 9330 $(REF DateTimeException,std,datetime,date) if the given 9331 $(LREF SysTime) cannot be converted to a $(D DosFileTime). 9332 +/ 9333 DosFileTime SysTimeToDosFileTime(SysTime sysTime) @safe 9334 { 9335 auto dateTime = cast(DateTime) sysTime; 9336 9337 if (dateTime.year < 1980) 9338 throw new DateTimeException("DOS File Times cannot hold dates prior to 1980."); 9339 9340 if (dateTime.year > 2107) 9341 throw new DateTimeException("DOS File Times cannot hold dates past 2107."); 9342 9343 uint retval = 0; 9344 retval = (dateTime.year - 1980) << 25; 9345 retval |= (dateTime.month & 0x0F) << 21; 9346 retval |= (dateTime.day & 0x1F) << 16; 9347 retval |= (dateTime.hour & 0x1F) << 11; 9348 retval |= (dateTime.minute & 0x3F) << 5; 9349 retval |= (dateTime.second >> 1) & 0x1F; 9350 9351 return cast(DosFileTime) retval; 9352 } 9353 9354 @safe unittest 9355 { 9356 assert(SysTimeToDosFileTime(SysTime(DateTime(1980, 1, 1, 0, 0, 0))) == 0b00000000001000010000000000000000); 9357 assert(SysTimeToDosFileTime(SysTime(DateTime(2107, 12, 31, 23, 59, 58))) == 0b11111111100111111011111101111101); 9358 assert(SysTimeToDosFileTime(SysTime(DateTime(2011, 1, 31, 16, 34, 44))) == 0x3E3F8456); 9359 } 9360 9361 9362 /++ 9363 The given array of $(D char) or random-access range of $(D char) or 9364 $(D ubyte) is expected to be in the format specified in 9365 $(HTTP tools.ietf.org/html/rfc5322, RFC 5322) section 3.3 with the 9366 grammar rule $(I date-time). It is the date-time format commonly used in 9367 internet messages such as e-mail and HTTP. The corresponding 9368 $(LREF SysTime) will be returned. 9369 9370 RFC 822 was the original spec (hence the function's name), whereas RFC 5322 9371 is the current spec. 9372 9373 The day of the week is ignored beyond verifying that it's a valid day of the 9374 week, as the day of the week can be inferred from the date. It is not 9375 checked whether the given day of the week matches the actual day of the week 9376 of the given date (though it is technically invalid per the spec if the 9377 day of the week doesn't match the actual day of the week of the given date). 9378 9379 If the time zone is $(D "-0000") (or considered to be equivalent to 9380 $(D "-0000") by section 4.3 of the spec), a 9381 $(REF SimpleTimeZone,std,datetime,timezone) with a utc offset of $(D 0) is 9382 used rather than $(REF UTC,std,datetime,timezone), whereas $(D "+0000") uses 9383 $(REF UTC,std,datetime,timezone). 9384 9385 Note that because $(LREF SysTime) does not currently support having a second 9386 value of 60 (as is sometimes done for leap seconds), if the date-time value 9387 does have a value of 60 for the seconds, it is treated as 59. 9388 9389 The one area in which this function violates RFC 5322 is that it accepts 9390 $(D "\n") in folding whitespace in the place of $(D "\r\n"), because the 9391 HTTP spec requires it. 9392 9393 Throws: 9394 $(REF DateTimeException,std,datetime,date) if the given string doesn't 9395 follow the grammar for a date-time field or if the resulting 9396 $(LREF SysTime) is invalid. 9397 +/ 9398 SysTime parseRFC822DateTime()(in char[] value) @safe 9399 { 9400 import std.string : representation; 9401 return parseRFC822DateTime(value.representation); 9402 } 9403 9404 /++ Ditto +/ 9405 SysTime parseRFC822DateTime(R)(R value) @safe 9406 if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && 9407 (is(Unqual!(ElementType!R) == char) || is(Unqual!(ElementType!R) == ubyte))) 9408 { 9409 import std.algorithm.searching : find, all; 9410 import std.ascii : isDigit, isAlpha, isPrintable; 9411 import std.conv : to; 9412 import std.functional : not; 9413 import std.string : capitalize, format; 9414 import std.traits : EnumMembers, isArray; 9415 import std.typecons : Rebindable; 9416 9417 void stripAndCheckLen(R valueBefore, size_t minLen, size_t line = __LINE__) 9418 { 9419 value = _stripCFWS(valueBefore); 9420 if (value.length < minLen) 9421 throw new DateTimeException("date-time value too short", __FILE__, line); 9422 } 9423 stripAndCheckLen(value, "7Dec1200:00A".length); 9424 9425 static if (isArray!R && (is(ElementEncodingType!R == char) || is(ElementEncodingType!R == ubyte))) 9426 { 9427 static string sliceAsString(R str) @trusted 9428 { 9429 return cast(string) str; 9430 } 9431 } 9432 else 9433 { 9434 char[4] temp; 9435 char[] sliceAsString(R str) @trusted 9436 { 9437 size_t i = 0; 9438 foreach (c; str) 9439 temp[i++] = cast(char) c; 9440 return temp[0 .. str.length]; 9441 } 9442 } 9443 9444 // day-of-week 9445 if (isAlpha(value[0])) 9446 { 9447 auto dowStr = sliceAsString(value[0 .. 3]); 9448 switch (dowStr) 9449 { 9450 foreach (dow; EnumMembers!DayOfWeek) 9451 { 9452 enum dowC = capitalize(to!string(dow)); 9453 case dowC: 9454 goto afterDoW; 9455 } 9456 default: throw new DateTimeException(format("Invalid day-of-week: %s", dowStr)); 9457 } 9458 afterDoW: stripAndCheckLen(value[3 .. value.length], ",7Dec1200:00A".length); 9459 if (value[0] != ',') 9460 throw new DateTimeException("day-of-week missing comma"); 9461 stripAndCheckLen(value[1 .. value.length], "7Dec1200:00A".length); 9462 } 9463 9464 // day 9465 immutable digits = isDigit(value[1]) ? 2 : 1; 9466 immutable day = _convDigits!short(value[0 .. digits]); 9467 if (day == -1) 9468 throw new DateTimeException("Invalid day"); 9469 stripAndCheckLen(value[digits .. value.length], "Dec1200:00A".length); 9470 9471 // month 9472 Month month; 9473 { 9474 auto monStr = sliceAsString(value[0 .. 3]); 9475 switch (monStr) 9476 { 9477 foreach (mon; EnumMembers!Month) 9478 { 9479 enum monC = capitalize(to!string(mon)); 9480 case monC: 9481 { 9482 month = mon; 9483 goto afterMon; 9484 } 9485 } 9486 default: throw new DateTimeException(format("Invalid month: %s", monStr)); 9487 } 9488 afterMon: stripAndCheckLen(value[3 .. value.length], "1200:00A".length); 9489 } 9490 9491 // year 9492 auto found = value[2 .. value.length].find!(not!(std.ascii.isDigit))(); 9493 size_t yearLen = value.length - found.length; 9494 if (found.length == 0) 9495 throw new DateTimeException("Invalid year"); 9496 if (found[0] == ':') 9497 yearLen -= 2; 9498 auto year = _convDigits!short(value[0 .. yearLen]); 9499 if (year < 1900) 9500 { 9501 if (year == -1) 9502 throw new DateTimeException("Invalid year"); 9503 if (yearLen < 4) 9504 { 9505 if (yearLen == 3) 9506 year += 1900; 9507 else if (yearLen == 2) 9508 year += year < 50 ? 2000 : 1900; 9509 else 9510 throw new DateTimeException("Invalid year. Too few digits."); 9511 } 9512 else 9513 throw new DateTimeException("Invalid year. Cannot be earlier than 1900."); 9514 } 9515 stripAndCheckLen(value[yearLen .. value.length], "00:00A".length); 9516 9517 // hour 9518 immutable hour = _convDigits!short(value[0 .. 2]); 9519 stripAndCheckLen(value[2 .. value.length], ":00A".length); 9520 if (value[0] != ':') 9521 throw new DateTimeException("Invalid hour"); 9522 stripAndCheckLen(value[1 .. value.length], "00A".length); 9523 9524 // minute 9525 immutable minute = _convDigits!short(value[0 .. 2]); 9526 stripAndCheckLen(value[2 .. value.length], "A".length); 9527 9528 // second 9529 short second; 9530 if (value[0] == ':') 9531 { 9532 stripAndCheckLen(value[1 .. value.length], "00A".length); 9533 second = _convDigits!short(value[0 .. 2]); 9534 // this is just if/until SysTime is sorted out to fully support leap seconds 9535 if (second == 60) 9536 second = 59; 9537 stripAndCheckLen(value[2 .. value.length], "A".length); 9538 } 9539 9540 immutable(TimeZone) parseTZ(int sign) 9541 { 9542 if (value.length < 5) 9543 throw new DateTimeException("Invalid timezone"); 9544 immutable zoneHours = _convDigits!short(value[1 .. 3]); 9545 immutable zoneMinutes = _convDigits!short(value[3 .. 5]); 9546 if (zoneHours == -1 || zoneMinutes == -1 || zoneMinutes > 59) 9547 throw new DateTimeException("Invalid timezone"); 9548 value = value[5 .. value.length]; 9549 immutable utcOffset = (dur!"hours"(zoneHours) + dur!"minutes"(zoneMinutes)) * sign; 9550 if (utcOffset == Duration.zero) 9551 { 9552 return sign == 1 ? cast(immutable(TimeZone))UTC() 9553 : cast(immutable(TimeZone))new immutable SimpleTimeZone(Duration.zero); 9554 } 9555 return new immutable(SimpleTimeZone)(utcOffset); 9556 } 9557 9558 // zone 9559 Rebindable!(immutable TimeZone) tz; 9560 if (value[0] == '-') 9561 tz = parseTZ(-1); 9562 else if (value[0] == '+') 9563 tz = parseTZ(1); 9564 else 9565 { 9566 // obs-zone 9567 immutable tzLen = value.length - find(value, ' ', '\t', '(')[0].length; 9568 switch (sliceAsString(value[0 .. tzLen <= 4 ? tzLen : 4])) 9569 { 9570 case "UT": case "GMT": tz = UTC(); break; 9571 case "EST": tz = new immutable SimpleTimeZone(dur!"hours"(-5)); break; 9572 case "EDT": tz = new immutable SimpleTimeZone(dur!"hours"(-4)); break; 9573 case "CST": tz = new immutable SimpleTimeZone(dur!"hours"(-6)); break; 9574 case "CDT": tz = new immutable SimpleTimeZone(dur!"hours"(-5)); break; 9575 case "MST": tz = new immutable SimpleTimeZone(dur!"hours"(-7)); break; 9576 case "MDT": tz = new immutable SimpleTimeZone(dur!"hours"(-6)); break; 9577 case "PST": tz = new immutable SimpleTimeZone(dur!"hours"(-8)); break; 9578 case "PDT": tz = new immutable SimpleTimeZone(dur!"hours"(-7)); break; 9579 case "J": case "j": throw new DateTimeException("Invalid timezone"); 9580 default: 9581 { 9582 if (all!(std.ascii.isAlpha)(value[0 .. tzLen])) 9583 { 9584 tz = new immutable SimpleTimeZone(Duration.zero); 9585 break; 9586 } 9587 throw new DateTimeException("Invalid timezone"); 9588 } 9589 } 9590 value = value[tzLen .. value.length]; 9591 } 9592 9593 // This is kind of arbitrary. Technically, nothing but CFWS is legal past 9594 // the end of the timezone, but we don't want to be picky about that in a 9595 // function that's just parsing rather than validating. So, the idea here is 9596 // that if the next character is printable (and not part of CFWS), then it 9597 // might be part of the timezone and thus affect what the timezone was 9598 // supposed to be, so we'll throw, but otherwise, we'll just ignore it. 9599 if (!value.empty && isPrintable(value[0]) && value[0] != ' ' && value[0] != '(') 9600 throw new DateTimeException("Invalid timezone"); 9601 9602 try 9603 return SysTime(DateTime(year, month, day, hour, minute, second), tz); 9604 catch (DateTimeException dte) 9605 throw new DateTimeException("date-time format is correct, but the resulting SysTime is invalid.", dte); 9606 } 9607 9608 /// 9609 @safe unittest 9610 { 9611 import core.time : hours; 9612 import std.datetime.date : DateTime, DateTimeException; 9613 import std.datetime.timezone : SimpleTimeZone, UTC; 9614 import std.exception : assertThrown; 9615 9616 auto tz = new immutable SimpleTimeZone(hours(-8)); 9617 assert(parseRFC822DateTime("Sat, 6 Jan 1990 12:14:19 -0800") == 9618 SysTime(DateTime(1990, 1, 6, 12, 14, 19), tz)); 9619 9620 assert(parseRFC822DateTime("9 Jul 2002 13:11 +0000") == 9621 SysTime(DateTime(2002, 7, 9, 13, 11, 0), UTC())); 9622 9623 auto badStr = "29 Feb 2001 12:17:16 +0200"; 9624 assertThrown!DateTimeException(parseRFC822DateTime(badStr)); 9625 } 9626 9627 version (unittest) void testParse822(alias cr)(string str, SysTime expected, size_t line = __LINE__) 9628 { 9629 import std.format : format; 9630 auto value = cr(str); 9631 auto result = parseRFC822DateTime(value); 9632 if (result != expected) 9633 throw new AssertError(format("wrong result. expected [%s], actual[%s]", expected, result), __FILE__, line); 9634 } 9635 9636 version (unittest) void testBadParse822(alias cr)(string str, size_t line = __LINE__) 9637 { 9638 try 9639 parseRFC822DateTime(cr(str)); 9640 catch (DateTimeException) 9641 return; 9642 throw new AssertError("No DateTimeException was thrown", __FILE__, line); 9643 } 9644 9645 @system unittest 9646 { 9647 import std.algorithm.iteration : filter, map; 9648 import std.algorithm.searching : canFind; 9649 import std.array : array; 9650 import std.ascii : letters; 9651 import std.format : format; 9652 import std.meta : AliasSeq; 9653 import std.range : chain, iota, take; 9654 import std.stdio : writefln, writeln; 9655 import std.string : representation; 9656 9657 static struct Rand3Letters 9658 { 9659 enum empty = false; 9660 @property auto front() { return _mon; } 9661 void popFront() 9662 { 9663 import std.exception : assumeUnique; 9664 import std.random : rndGen; 9665 _mon = rndGen.map!(a => letters[a % letters.length])().take(3).array().assumeUnique(); 9666 } 9667 string _mon; 9668 static auto start() { Rand3Letters retval; retval.popFront(); return retval; } 9669 } 9670 9671 foreach (cr; AliasSeq!(function(string a){return cast(char[]) a;}, 9672 function(string a){return cast(ubyte[]) a;}, 9673 function(string a){return a;}, 9674 function(string a){return map!(b => cast(char) b)(a.representation);})) 9675 (){ // avoid slow optimizations for large functions @@@BUG@@@ 2396 9676 scope(failure) writeln(typeof(cr).stringof); 9677 alias test = testParse822!cr; 9678 alias testBad = testBadParse822!cr; 9679 9680 immutable std1 = DateTime(2012, 12, 21, 13, 14, 15); 9681 immutable std2 = DateTime(2012, 12, 21, 13, 14, 0); 9682 immutable dst1 = DateTime(1976, 7, 4, 5, 4, 22); 9683 immutable dst2 = DateTime(1976, 7, 4, 5, 4, 0); 9684 9685 test("21 Dec 2012 13:14:15 +0000", SysTime(std1, UTC())); 9686 test("21 Dec 2012 13:14 +0000", SysTime(std2, UTC())); 9687 test("Fri, 21 Dec 2012 13:14 +0000", SysTime(std2, UTC())); 9688 test("Fri, 21 Dec 2012 13:14:15 +0000", SysTime(std1, UTC())); 9689 9690 test("04 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC())); 9691 test("04 Jul 1976 05:04 +0000", SysTime(dst2, UTC())); 9692 test("Sun, 04 Jul 1976 05:04 +0000", SysTime(dst2, UTC())); 9693 test("Sun, 04 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC())); 9694 9695 test("4 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC())); 9696 test("4 Jul 1976 05:04 +0000", SysTime(dst2, UTC())); 9697 test("Sun, 4 Jul 1976 05:04 +0000", SysTime(dst2, UTC())); 9698 test("Sun, 4 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC())); 9699 9700 auto badTZ = new immutable SimpleTimeZone(Duration.zero); 9701 test("21 Dec 2012 13:14:15 -0000", SysTime(std1, badTZ)); 9702 test("21 Dec 2012 13:14 -0000", SysTime(std2, badTZ)); 9703 test("Fri, 21 Dec 2012 13:14 -0000", SysTime(std2, badTZ)); 9704 test("Fri, 21 Dec 2012 13:14:15 -0000", SysTime(std1, badTZ)); 9705 9706 test("04 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ)); 9707 test("04 Jul 1976 05:04 -0000", SysTime(dst2, badTZ)); 9708 test("Sun, 04 Jul 1976 05:04 -0000", SysTime(dst2, badTZ)); 9709 test("Sun, 04 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ)); 9710 9711 test("4 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ)); 9712 test("4 Jul 1976 05:04 -0000", SysTime(dst2, badTZ)); 9713 test("Sun, 4 Jul 1976 05:04 -0000", SysTime(dst2, badTZ)); 9714 test("Sun, 4 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ)); 9715 9716 auto pst = new immutable SimpleTimeZone(dur!"hours"(-8)); 9717 auto pdt = new immutable SimpleTimeZone(dur!"hours"(-7)); 9718 test("21 Dec 2012 13:14:15 -0800", SysTime(std1, pst)); 9719 test("21 Dec 2012 13:14 -0800", SysTime(std2, pst)); 9720 test("Fri, 21 Dec 2012 13:14 -0800", SysTime(std2, pst)); 9721 test("Fri, 21 Dec 2012 13:14:15 -0800", SysTime(std1, pst)); 9722 9723 test("04 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt)); 9724 test("04 Jul 1976 05:04 -0700", SysTime(dst2, pdt)); 9725 test("Sun, 04 Jul 1976 05:04 -0700", SysTime(dst2, pdt)); 9726 test("Sun, 04 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt)); 9727 9728 test("4 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt)); 9729 test("4 Jul 1976 05:04 -0700", SysTime(dst2, pdt)); 9730 test("Sun, 4 Jul 1976 05:04 -0700", SysTime(dst2, pdt)); 9731 test("Sun, 4 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt)); 9732 9733 auto cet = new immutable SimpleTimeZone(dur!"hours"(1)); 9734 auto cest = new immutable SimpleTimeZone(dur!"hours"(2)); 9735 test("21 Dec 2012 13:14:15 +0100", SysTime(std1, cet)); 9736 test("21 Dec 2012 13:14 +0100", SysTime(std2, cet)); 9737 test("Fri, 21 Dec 2012 13:14 +0100", SysTime(std2, cet)); 9738 test("Fri, 21 Dec 2012 13:14:15 +0100", SysTime(std1, cet)); 9739 9740 test("04 Jul 1976 05:04:22 +0200", SysTime(dst1, cest)); 9741 test("04 Jul 1976 05:04 +0200", SysTime(dst2, cest)); 9742 test("Sun, 04 Jul 1976 05:04 +0200", SysTime(dst2, cest)); 9743 test("Sun, 04 Jul 1976 05:04:22 +0200", SysTime(dst1, cest)); 9744 9745 test("4 Jul 1976 05:04:22 +0200", SysTime(dst1, cest)); 9746 test("4 Jul 1976 05:04 +0200", SysTime(dst2, cest)); 9747 test("Sun, 4 Jul 1976 05:04 +0200", SysTime(dst2, cest)); 9748 test("Sun, 4 Jul 1976 05:04:22 +0200", SysTime(dst1, cest)); 9749 9750 // dst and std times are switched in the Southern Hemisphere which is why the 9751 // time zone names and DateTime variables don't match. 9752 auto cstStd = new immutable SimpleTimeZone(dur!"hours"(9) + dur!"minutes"(30)); 9753 auto cstDST = new immutable SimpleTimeZone(dur!"hours"(10) + dur!"minutes"(30)); 9754 test("21 Dec 2012 13:14:15 +1030", SysTime(std1, cstDST)); 9755 test("21 Dec 2012 13:14 +1030", SysTime(std2, cstDST)); 9756 test("Fri, 21 Dec 2012 13:14 +1030", SysTime(std2, cstDST)); 9757 test("Fri, 21 Dec 2012 13:14:15 +1030", SysTime(std1, cstDST)); 9758 9759 test("04 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 9760 test("04 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 9761 test("Sun, 04 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 9762 test("Sun, 04 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 9763 9764 test("4 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 9765 test("4 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 9766 test("Sun, 4 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 9767 test("Sun, 4 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 9768 9769 foreach (int i, mon; _monthNames) 9770 { 9771 test(format("17 %s 2012 00:05:02 +0000", mon), SysTime(DateTime(2012, i + 1, 17, 0, 5, 2), UTC())); 9772 test(format("17 %s 2012 00:05 +0000", mon), SysTime(DateTime(2012, i + 1, 17, 0, 5, 0), UTC())); 9773 } 9774 9775 import std.uni : toLower, toUpper; 9776 foreach (mon; chain(_monthNames[].map!(a => toLower(a))(), 9777 _monthNames[].map!(a => toUpper(a))(), 9778 ["Jam", "Jen", "Fec", "Fdb", "Mas", "Mbr", "Aps", "Aqr", "Mai", "Miy", 9779 "Jum", "Jbn", "Jup", "Jal", "Aur", "Apg", "Sem", "Sap", "Ocm", "Odt", 9780 "Nom", "Nav", "Dem", "Dac"], 9781 Rand3Letters.start().filter!(a => !_monthNames[].canFind(a)).take(20))) 9782 { 9783 scope(failure) writefln("Month: %s", mon); 9784 testBad(format("17 %s 2012 00:05:02 +0000", mon)); 9785 testBad(format("17 %s 2012 00:05 +0000", mon)); 9786 } 9787 9788 immutable string[7] daysOfWeekNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; 9789 9790 { 9791 auto start = SysTime(DateTime(2012, 11, 11, 9, 42, 0), UTC()); 9792 int day = 11; 9793 9794 foreach (int i, dow; daysOfWeekNames) 9795 { 9796 auto curr = start + dur!"days"(i); 9797 test(format("%s, %s Nov 2012 09:42:00 +0000", dow, day), curr); 9798 test(format("%s, %s Nov 2012 09:42 +0000", dow, day++), curr); 9799 9800 // Whether the day of the week matches the date is ignored. 9801 test(format("%s, 11 Nov 2012 09:42:00 +0000", dow), start); 9802 test(format("%s, 11 Nov 2012 09:42 +0000", dow), start); 9803 } 9804 } 9805 9806 foreach (dow; chain(daysOfWeekNames[].map!(a => toLower(a))(), 9807 daysOfWeekNames[].map!(a => toUpper(a))(), 9808 ["Sum", "Spn", "Mom", "Man", "Tuf", "Tae", "Wem", "Wdd", "The", "Tur", 9809 "Fro", "Fai", "San", "Sut"], 9810 Rand3Letters.start().filter!(a => !daysOfWeekNames[].canFind(a)).take(20))) 9811 { 9812 scope(failure) writefln("Day of Week: %s", dow); 9813 testBad(format("%s, 11 Nov 2012 09:42:00 +0000", dow)); 9814 testBad(format("%s, 11 Nov 2012 09:42 +0000", dow)); 9815 } 9816 9817 testBad("31 Dec 1899 23:59:59 +0000"); 9818 test("01 Jan 1900 00:00:00 +0000", SysTime(Date(1900, 1, 1), UTC())); 9819 test("01 Jan 1900 00:00:00 -0000", SysTime(Date(1900, 1, 1), 9820 new immutable SimpleTimeZone(Duration.zero))); 9821 test("01 Jan 1900 00:00:00 -0700", SysTime(Date(1900, 1, 1), 9822 new immutable SimpleTimeZone(dur!"hours"(-7)))); 9823 9824 { 9825 auto st1 = SysTime(Date(1900, 1, 1), UTC()); 9826 auto st2 = SysTime(Date(1900, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-11))); 9827 foreach (i; 1900 .. 2102) 9828 { 9829 test(format("1 Jan %05d 00:00 +0000", i), st1); 9830 test(format("1 Jan %05d 00:00 -1100", i), st2); 9831 st1.add!"years"(1); 9832 st2.add!"years"(1); 9833 } 9834 st1.year = 9998; 9835 st2.year = 9998; 9836 foreach (i; 9998 .. 11_002) 9837 { 9838 test(format("1 Jan %05d 00:00 +0000", i), st1); 9839 test(format("1 Jan %05d 00:00 -1100", i), st2); 9840 st1.add!"years"(1); 9841 st2.add!"years"(1); 9842 } 9843 } 9844 9845 testBad("12 Feb 1907 23:17:09 0000"); 9846 testBad("12 Feb 1907 23:17:09 +000"); 9847 testBad("12 Feb 1907 23:17:09 -000"); 9848 testBad("12 Feb 1907 23:17:09 +00000"); 9849 testBad("12 Feb 1907 23:17:09 -00000"); 9850 testBad("12 Feb 1907 23:17:09 +A"); 9851 testBad("12 Feb 1907 23:17:09 +PST"); 9852 testBad("12 Feb 1907 23:17:09 -A"); 9853 testBad("12 Feb 1907 23:17:09 -PST"); 9854 9855 // test trailing stuff that gets ignored 9856 { 9857 foreach (c; chain(iota(0, 33), ['('], iota(127, ubyte.max + 1))) 9858 { 9859 scope(failure) writefln("c: %d", c); 9860 test(format("21 Dec 2012 13:14:15 +0000%c", cast(char) c), SysTime(std1, UTC())); 9861 test(format("21 Dec 2012 13:14:15 +0000%c ", cast(char) c), SysTime(std1, UTC())); 9862 test(format("21 Dec 2012 13:14:15 +0000%chello", cast(char) c), SysTime(std1, UTC())); 9863 } 9864 } 9865 9866 // test trailing stuff that doesn't get ignored 9867 { 9868 foreach (c; chain(iota(33, '('), iota('(' + 1, 127))) 9869 { 9870 scope(failure) writefln("c: %d", c); 9871 testBad(format("21 Dec 2012 13:14:15 +0000%c", cast(char) c)); 9872 testBad(format("21 Dec 2012 13:14:15 +0000%c ", cast(char) c)); 9873 testBad(format("21 Dec 2012 13:14:15 +0000%chello", cast(char) c)); 9874 } 9875 } 9876 9877 testBad("32 Jan 2012 12:13:14 -0800"); 9878 testBad("31 Jan 2012 24:13:14 -0800"); 9879 testBad("31 Jan 2012 12:60:14 -0800"); 9880 testBad("31 Jan 2012 12:13:61 -0800"); 9881 testBad("31 Jan 2012 12:13:14 -0860"); 9882 test("31 Jan 2012 12:13:14 -0859", 9883 SysTime(DateTime(2012, 1, 31, 12, 13, 14), 9884 new immutable SimpleTimeZone(dur!"hours"(-8) + dur!"minutes"(-59)))); 9885 9886 // leap-seconds 9887 test("21 Dec 2012 15:59:60 -0800", SysTime(DateTime(2012, 12, 21, 15, 59, 59), pst)); 9888 9889 // FWS 9890 test("Sun,4 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 9891 test("Sun,4 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 9892 test("Sun,4 Jul 1976 05:04 +0930 (foo)", SysTime(dst2, cstStd)); 9893 test("Sun,4 Jul 1976 05:04:22 +0930 (foo)", SysTime(dst1, cstStd)); 9894 test("Sun,4 \r\n Jul \r\n 1976 \r\n 05:04 \r\n +0930 \r\n (foo)", SysTime(dst2, cstStd)); 9895 test("Sun,4 \r\n Jul \r\n 1976 \r\n 05:04:22 \r\n +0930 \r\n (foo)", SysTime(dst1, cstStd)); 9896 9897 auto str = "01 Jan 2012 12:13:14 -0800 "; 9898 test(str, SysTime(DateTime(2012, 1, 1, 12, 13, 14), new immutable SimpleTimeZone(hours(-8)))); 9899 foreach (i; 0 .. str.length) 9900 { 9901 auto currStr = str.dup; 9902 currStr[i] = 'x'; 9903 scope(failure) writefln("failed: %s", currStr); 9904 testBad(cast(string) currStr); 9905 } 9906 foreach (i; 2 .. str.length) 9907 { 9908 auto currStr = str[0 .. $ - i]; 9909 scope(failure) writefln("failed: %s", currStr); 9910 testBad(cast(string) currStr); 9911 testBad((cast(string) currStr) ~ " "); 9912 } 9913 }(); 9914 } 9915 9916 // Obsolete Format per section 4.3 of RFC 5322. 9917 @system unittest 9918 { 9919 import std.algorithm.iteration : filter, map; 9920 import std.ascii : letters; 9921 import std.exception : collectExceptionMsg; 9922 import std.format : format; 9923 import std.meta : AliasSeq; 9924 import std.range : chain, iota; 9925 import std.stdio : writefln, writeln; 9926 import std.string : representation; 9927 9928 auto std1 = SysTime(DateTime(2012, 12, 21, 13, 14, 15), UTC()); 9929 auto std2 = SysTime(DateTime(2012, 12, 21, 13, 14, 0), UTC()); 9930 auto std3 = SysTime(DateTime(1912, 12, 21, 13, 14, 15), UTC()); 9931 auto std4 = SysTime(DateTime(1912, 12, 21, 13, 14, 0), UTC()); 9932 auto dst1 = SysTime(DateTime(1976, 7, 4, 5, 4, 22), UTC()); 9933 auto dst2 = SysTime(DateTime(1976, 7, 4, 5, 4, 0), UTC()); 9934 auto tooLate1 = SysTime(Date(10_000, 1, 1), UTC()); 9935 auto tooLate2 = SysTime(DateTime(12_007, 12, 31, 12, 22, 19), UTC()); 9936 9937 foreach (cr; AliasSeq!(function(string a){return cast(char[]) a;}, 9938 function(string a){return cast(ubyte[]) a;}, 9939 function(string a){return a;}, 9940 function(string a){return map!(b => cast(char) b)(a.representation);})) 9941 (){ // avoid slow optimizations for large functions @@@BUG@@@ 2396 9942 scope(failure) writeln(typeof(cr).stringof); 9943 alias test = testParse822!cr; 9944 { 9945 auto list = ["", " ", " \r\n\t", "\t\r\n (hello world( frien(dog)) silly \r\n ) \t\t \r\n ()", 9946 " \n ", "\t\n\t", " \n\t (foo) \n (bar) \r\n (baz) \n "]; 9947 9948 foreach (i, cfws; list) 9949 { 9950 scope(failure) writefln("i: %s", i); 9951 9952 test(format("%1$s21%1$sDec%1$s2012%1$s13:14:15%1$s+0000%1$s", cfws), std1); 9953 test(format("%1$s21%1$sDec%1$s2012%1$s13:14%1$s+0000%1$s", cfws), std2); 9954 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s2012%1$s13:14%1$s+0000%1$s", cfws), std2); 9955 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s2012%1$s13:14:15%1$s+0000%1$s", cfws), std1); 9956 9957 test(format("%1$s04%1$sJul%1$s1976%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 9958 test(format("%1$s04%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2); 9959 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2); 9960 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s1976%1$s05:04:22 +0000%1$s", cfws), dst1); 9961 9962 test(format("%1$s4%1$sJul%1$s1976%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 9963 test(format("%1$s4%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2); 9964 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2); 9965 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s1976%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 9966 9967 test(format("%1$s21%1$sDec%1$s12%1$s13:14:15%1$s+0000%1$s", cfws), std1); 9968 test(format("%1$s21%1$sDec%1$s12%1$s13:14%1$s+0000%1$s", cfws), std2); 9969 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s12%1$s13:14%1$s+0000%1$s", cfws), std2); 9970 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s12%1$s13:14:15%1$s+0000%1$s", cfws), std1); 9971 9972 test(format("%1$s04%1$sJul%1$s76%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 9973 test(format("%1$s04%1$sJul%1$s76%1$s05:04%1$s+0000%1$s", cfws), dst2); 9974 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s76%1$s05:04%1$s+0000%1$s", cfws), dst2); 9975 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s76%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 9976 9977 test(format("%1$s4%1$sJul%1$s76 05:04:22%1$s+0000%1$s", cfws), dst1); 9978 test(format("%1$s4%1$sJul%1$s76 05:04%1$s+0000%1$s", cfws), dst2); 9979 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s76%1$s05:04%1$s+0000%1$s", cfws), dst2); 9980 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s76%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 9981 9982 test(format("%1$s21%1$sDec%1$s012%1$s13:14:15%1$s+0000%1$s", cfws), std3); 9983 test(format("%1$s21%1$sDec%1$s012%1$s13:14%1$s+0000%1$s", cfws), std4); 9984 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s012%1$s13:14%1$s+0000%1$s", cfws), std4); 9985 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s012%1$s13:14:15%1$s+0000%1$s", cfws), std3); 9986 9987 test(format("%1$s04%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 9988 test(format("%1$s04%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2); 9989 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2); 9990 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 9991 9992 test(format("%1$s4%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 9993 test(format("%1$s4%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2); 9994 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2); 9995 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 9996 9997 test(format("%1$s1%1$sJan%1$s10000%1$s00:00:00%1$s+0000%1$s", cfws), tooLate1); 9998 test(format("%1$s31%1$sDec%1$s12007%1$s12:22:19%1$s+0000%1$s", cfws), tooLate2); 9999 test(format("%1$sSat%1$s,%1$s1%1$sJan%1$s10000%1$s00:00:00%1$s+0000%1$s", cfws), tooLate1); 10000 test(format("%1$sSun%1$s,%1$s31%1$sDec%1$s12007%1$s12:22:19%1$s+0000%1$s", cfws), tooLate2); 10001 } 10002 } 10003 10004 // test years of 1, 2, and 3 digits. 10005 { 10006 auto st1 = SysTime(Date(2000, 1, 1), UTC()); 10007 auto st2 = SysTime(Date(2000, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-12))); 10008 foreach (i; 0 .. 50) 10009 { 10010 test(format("1 Jan %02d 00:00 GMT", i), st1); 10011 test(format("1 Jan %02d 00:00 -1200", i), st2); 10012 st1.add!"years"(1); 10013 st2.add!"years"(1); 10014 } 10015 } 10016 10017 { 10018 auto st1 = SysTime(Date(1950, 1, 1), UTC()); 10019 auto st2 = SysTime(Date(1950, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-12))); 10020 foreach (i; 50 .. 100) 10021 { 10022 test(format("1 Jan %02d 00:00 GMT", i), st1); 10023 test(format("1 Jan %02d 00:00 -1200", i), st2); 10024 st1.add!"years"(1); 10025 st2.add!"years"(1); 10026 } 10027 } 10028 10029 { 10030 auto st1 = SysTime(Date(1900, 1, 1), UTC()); 10031 auto st2 = SysTime(Date(1900, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-11))); 10032 foreach (i; 0 .. 1000) 10033 { 10034 test(format("1 Jan %03d 00:00 GMT", i), st1); 10035 test(format("1 Jan %03d 00:00 -1100", i), st2); 10036 st1.add!"years"(1); 10037 st2.add!"years"(1); 10038 } 10039 } 10040 10041 foreach (i; 0 .. 10) 10042 { 10043 auto str1 = cr(format("1 Jan %d 00:00 GMT", i)); 10044 auto str2 = cr(format("1 Jan %d 00:00 -1200", i)); 10045 assertThrown!DateTimeException(parseRFC822DateTime(str1)); 10046 assertThrown!DateTimeException(parseRFC822DateTime(str1)); 10047 } 10048 10049 // test time zones 10050 { 10051 auto dt = DateTime(1982, 05, 03, 12, 22, 04); 10052 test("Wed, 03 May 1982 12:22:04 UT", SysTime(dt, UTC())); 10053 test("Wed, 03 May 1982 12:22:04 GMT", SysTime(dt, UTC())); 10054 test("Wed, 03 May 1982 12:22:04 EST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-5)))); 10055 test("Wed, 03 May 1982 12:22:04 EDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-4)))); 10056 test("Wed, 03 May 1982 12:22:04 CST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-6)))); 10057 test("Wed, 03 May 1982 12:22:04 CDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-5)))); 10058 test("Wed, 03 May 1982 12:22:04 MST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-7)))); 10059 test("Wed, 03 May 1982 12:22:04 MDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-6)))); 10060 test("Wed, 03 May 1982 12:22:04 PST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-8)))); 10061 test("Wed, 03 May 1982 12:22:04 PDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-7)))); 10062 10063 auto badTZ = new immutable SimpleTimeZone(Duration.zero); 10064 foreach (dchar c; filter!(a => a != 'j' && a != 'J')(letters)) 10065 { 10066 scope(failure) writefln("c: %s", c); 10067 test(format("Wed, 03 May 1982 12:22:04 %s", c), SysTime(dt, badTZ)); 10068 test(format("Wed, 03 May 1982 12:22:04%s", c), SysTime(dt, badTZ)); 10069 } 10070 10071 foreach (dchar c; ['j', 'J']) 10072 { 10073 scope(failure) writefln("c: %s", c); 10074 assertThrown!DateTimeException(parseRFC822DateTime(cr(format("Wed, 03 May 1982 12:22:04 %s", c)))); 10075 assertThrown!DateTimeException(parseRFC822DateTime(cr(format("Wed, 03 May 1982 12:22:04%s", c)))); 10076 } 10077 10078 foreach (string s; ["AAA", "GQW", "DDT", "PDA", "GT", "GM"]) 10079 { 10080 scope(failure) writefln("s: %s", s); 10081 test(format("Wed, 03 May 1982 12:22:04 %s", s), SysTime(dt, badTZ)); 10082 } 10083 10084 // test trailing stuff that gets ignored 10085 { 10086 foreach (c; chain(iota(0, 33), ['('], iota(127, ubyte.max + 1))) 10087 { 10088 scope(failure) writefln("c: %d", c); 10089 test(format("21Dec1213:14:15+0000%c", cast(char) c), std1); 10090 test(format("21Dec1213:14:15+0000%c ", cast(char) c), std1); 10091 test(format("21Dec1213:14:15+0000%chello", cast(char) c), std1); 10092 } 10093 } 10094 10095 // test trailing stuff that doesn't get ignored 10096 { 10097 foreach (c; chain(iota(33, '('), iota('(' + 1, 127))) 10098 { 10099 scope(failure) writefln("c: %d", c); 10100 assertThrown!DateTimeException( 10101 parseRFC822DateTime(cr(format("21Dec1213:14:15+0000%c", cast(char) c)))); 10102 assertThrown!DateTimeException( 10103 parseRFC822DateTime(cr(format("21Dec1213:14:15+0000%c ", cast(char) c)))); 10104 assertThrown!DateTimeException( 10105 parseRFC822DateTime(cr(format("21Dec1213:14:15+0000%chello", cast(char) c)))); 10106 } 10107 } 10108 } 10109 10110 // test that the checks for minimum length work correctly and avoid 10111 // any RangeErrors. 10112 test("7Dec1200:00A", SysTime(DateTime(2012, 12, 7, 00, 00, 00), 10113 new immutable SimpleTimeZone(Duration.zero))); 10114 test("Fri,7Dec1200:00A", SysTime(DateTime(2012, 12, 7, 00, 00, 00), 10115 new immutable SimpleTimeZone(Duration.zero))); 10116 test("7Dec1200:00:00A", SysTime(DateTime(2012, 12, 7, 00, 00, 00), 10117 new immutable SimpleTimeZone(Duration.zero))); 10118 test("Fri,7Dec1200:00:00A", SysTime(DateTime(2012, 12, 7, 00, 00, 00), 10119 new immutable SimpleTimeZone(Duration.zero))); 10120 10121 auto tooShortMsg = collectExceptionMsg!DateTimeException(parseRFC822DateTime("")); 10122 foreach (str; ["Fri,7Dec1200:00:00", "7Dec1200:00:00"]) 10123 { 10124 foreach (i; 0 .. str.length) 10125 { 10126 auto value = str[0 .. $ - i]; 10127 scope(failure) writeln(value); 10128 assert(collectExceptionMsg!DateTimeException(parseRFC822DateTime(value)) == tooShortMsg); 10129 } 10130 } 10131 }(); 10132 } 10133 10134 10135 private: 10136 10137 /+ 10138 Returns the given hnsecs as an ISO string of fractional seconds. 10139 +/ 10140 static string fracSecsToISOString(int hnsecs) @safe pure nothrow 10141 { 10142 assert(hnsecs >= 0); 10143 10144 try 10145 { 10146 if (hnsecs == 0) 10147 return ""; 10148 10149 string isoString = format(".%07d", hnsecs); 10150 10151 while (isoString[$ - 1] == '0') 10152 isoString.popBack(); 10153 10154 return isoString; 10155 } 10156 catch (Exception e) 10157 assert(0, "format() threw."); 10158 } 10159 10160 @safe unittest 10161 { 10162 assert(fracSecsToISOString(0) == ""); 10163 assert(fracSecsToISOString(1) == ".0000001"); 10164 assert(fracSecsToISOString(10) == ".000001"); 10165 assert(fracSecsToISOString(100) == ".00001"); 10166 assert(fracSecsToISOString(1000) == ".0001"); 10167 assert(fracSecsToISOString(10_000) == ".001"); 10168 assert(fracSecsToISOString(100_000) == ".01"); 10169 assert(fracSecsToISOString(1_000_000) == ".1"); 10170 assert(fracSecsToISOString(1_000_001) == ".1000001"); 10171 assert(fracSecsToISOString(1_001_001) == ".1001001"); 10172 assert(fracSecsToISOString(1_071_601) == ".1071601"); 10173 assert(fracSecsToISOString(1_271_641) == ".1271641"); 10174 assert(fracSecsToISOString(9_999_999) == ".9999999"); 10175 assert(fracSecsToISOString(9_999_990) == ".999999"); 10176 assert(fracSecsToISOString(9_999_900) == ".99999"); 10177 assert(fracSecsToISOString(9_999_000) == ".9999"); 10178 assert(fracSecsToISOString(9_990_000) == ".999"); 10179 assert(fracSecsToISOString(9_900_000) == ".99"); 10180 assert(fracSecsToISOString(9_000_000) == ".9"); 10181 assert(fracSecsToISOString(999) == ".0000999"); 10182 assert(fracSecsToISOString(9990) == ".000999"); 10183 assert(fracSecsToISOString(99_900) == ".00999"); 10184 assert(fracSecsToISOString(999_000) == ".0999"); 10185 } 10186 10187 10188 /+ 10189 Returns a Duration corresponding to to the given ISO string of 10190 fractional seconds. 10191 +/ 10192 static Duration fracSecsFromISOString(S)(in S isoString) @trusted pure 10193 if (isSomeString!S) 10194 { 10195 import std.algorithm.searching : all; 10196 import std.ascii : isDigit; 10197 import std.conv : to; 10198 import std.string : representation; 10199 10200 if (isoString.empty) 10201 return Duration.zero; 10202 10203 auto str = isoString.representation; 10204 10205 enforce(str[0] == '.', new DateTimeException("Invalid ISO String")); 10206 str.popFront(); 10207 10208 enforce(!str.empty && all!isDigit(str), new DateTimeException("Invalid ISO String")); 10209 10210 dchar[7] fullISOString = void; 10211 foreach (i, ref dchar c; fullISOString) 10212 { 10213 if (i < str.length) 10214 c = str[i]; 10215 else 10216 c = '0'; 10217 } 10218 10219 return hnsecs(to!int(fullISOString[])); 10220 } 10221 10222 @safe unittest 10223 { 10224 static void testFSInvalid(string isoString) 10225 { 10226 fracSecsFromISOString(isoString); 10227 } 10228 10229 assertThrown!DateTimeException(testFSInvalid(".")); 10230 assertThrown!DateTimeException(testFSInvalid("0.")); 10231 assertThrown!DateTimeException(testFSInvalid("0")); 10232 assertThrown!DateTimeException(testFSInvalid("0000000")); 10233 assertThrown!DateTimeException(testFSInvalid("T")); 10234 assertThrown!DateTimeException(testFSInvalid("T.")); 10235 assertThrown!DateTimeException(testFSInvalid(".T")); 10236 assertThrown!DateTimeException(testFSInvalid(".00000Q0")); 10237 assertThrown!DateTimeException(testFSInvalid(".000000Q")); 10238 assertThrown!DateTimeException(testFSInvalid(".0000000Q")); 10239 assertThrown!DateTimeException(testFSInvalid(".0000000000Q")); 10240 10241 assert(fracSecsFromISOString("") == Duration.zero); 10242 assert(fracSecsFromISOString(".0000001") == hnsecs(1)); 10243 assert(fracSecsFromISOString(".000001") == hnsecs(10)); 10244 assert(fracSecsFromISOString(".00001") == hnsecs(100)); 10245 assert(fracSecsFromISOString(".0001") == hnsecs(1000)); 10246 assert(fracSecsFromISOString(".001") == hnsecs(10_000)); 10247 assert(fracSecsFromISOString(".01") == hnsecs(100_000)); 10248 assert(fracSecsFromISOString(".1") == hnsecs(1_000_000)); 10249 assert(fracSecsFromISOString(".1000001") == hnsecs(1_000_001)); 10250 assert(fracSecsFromISOString(".1001001") == hnsecs(1_001_001)); 10251 assert(fracSecsFromISOString(".1071601") == hnsecs(1_071_601)); 10252 assert(fracSecsFromISOString(".1271641") == hnsecs(1_271_641)); 10253 assert(fracSecsFromISOString(".9999999") == hnsecs(9_999_999)); 10254 assert(fracSecsFromISOString(".9999990") == hnsecs(9_999_990)); 10255 assert(fracSecsFromISOString(".999999") == hnsecs(9_999_990)); 10256 assert(fracSecsFromISOString(".9999900") == hnsecs(9_999_900)); 10257 assert(fracSecsFromISOString(".99999") == hnsecs(9_999_900)); 10258 assert(fracSecsFromISOString(".9999000") == hnsecs(9_999_000)); 10259 assert(fracSecsFromISOString(".9999") == hnsecs(9_999_000)); 10260 assert(fracSecsFromISOString(".9990000") == hnsecs(9_990_000)); 10261 assert(fracSecsFromISOString(".999") == hnsecs(9_990_000)); 10262 assert(fracSecsFromISOString(".9900000") == hnsecs(9_900_000)); 10263 assert(fracSecsFromISOString(".9900") == hnsecs(9_900_000)); 10264 assert(fracSecsFromISOString(".99") == hnsecs(9_900_000)); 10265 assert(fracSecsFromISOString(".9000000") == hnsecs(9_000_000)); 10266 assert(fracSecsFromISOString(".9") == hnsecs(9_000_000)); 10267 assert(fracSecsFromISOString(".0000999") == hnsecs(999)); 10268 assert(fracSecsFromISOString(".0009990") == hnsecs(9990)); 10269 assert(fracSecsFromISOString(".000999") == hnsecs(9990)); 10270 assert(fracSecsFromISOString(".0099900") == hnsecs(99_900)); 10271 assert(fracSecsFromISOString(".00999") == hnsecs(99_900)); 10272 assert(fracSecsFromISOString(".0999000") == hnsecs(999_000)); 10273 assert(fracSecsFromISOString(".0999") == hnsecs(999_000)); 10274 assert(fracSecsFromISOString(".00000000") == Duration.zero); 10275 assert(fracSecsFromISOString(".00000001") == Duration.zero); 10276 assert(fracSecsFromISOString(".00000009") == Duration.zero); 10277 assert(fracSecsFromISOString(".1234567890") == hnsecs(1_234_567)); 10278 assert(fracSecsFromISOString(".12345678901234567890") == hnsecs(1_234_567)); 10279 } 10280 10281 10282 /+ 10283 This function is used to split out the units without getting the remaining 10284 hnsecs. 10285 10286 Params: 10287 units = The units to split out. 10288 hnsecs = The current total hnsecs. 10289 10290 Returns: 10291 The split out value. 10292 +/ 10293 long getUnitsFromHNSecs(string units)(long hnsecs) @safe pure nothrow 10294 if (validTimeUnits(units) && 10295 CmpTimeUnits!(units, "months") < 0) 10296 { 10297 return convert!("hnsecs", units)(hnsecs); 10298 } 10299 10300 @safe unittest 10301 { 10302 auto hnsecs = 2595000000007L; 10303 immutable days = getUnitsFromHNSecs!"days"(hnsecs); 10304 assert(days == 3); 10305 assert(hnsecs == 2595000000007L); 10306 } 10307 10308 10309 /+ 10310 This function is used to split out the units without getting the units but 10311 just the remaining hnsecs. 10312 10313 Params: 10314 units = The units to split out. 10315 hnsecs = The current total hnsecs. 10316 10317 Returns: 10318 The remaining hnsecs. 10319 +/ 10320 long removeUnitsFromHNSecs(string units)(long hnsecs) @safe pure nothrow 10321 if (validTimeUnits(units) && 10322 CmpTimeUnits!(units, "months") < 0) 10323 { 10324 immutable value = convert!("hnsecs", units)(hnsecs); 10325 return hnsecs - convert!(units, "hnsecs")(value); 10326 } 10327 10328 @safe unittest 10329 { 10330 auto hnsecs = 2595000000007L; 10331 auto returned = removeUnitsFromHNSecs!"days"(hnsecs); 10332 assert(returned == 3000000007); 10333 assert(hnsecs == 2595000000007L); 10334 } 10335 10336 10337 /+ 10338 Strips what RFC 5322, section 3.2.2 refers to as CFWS from the left-hand 10339 side of the given range (it strips comments delimited by $(D '(') and 10340 $(D ')') as well as folding whitespace). 10341 10342 It is assumed that the given range contains the value of a header field and 10343 no terminating CRLF for the line (though the CRLF for folding whitespace is 10344 of course expected and stripped) and thus that the only case of CR or LF is 10345 in folding whitespace. 10346 10347 If a comment does not terminate correctly (e.g. mismatched parens) or if the 10348 the FWS is malformed, then the range will be empty when stripCWFS is done. 10349 However, only minimal validation of the content is done (e.g. quoted pairs 10350 within a comment aren't validated beyond \$LPAREN or \$RPAREN, because 10351 they're inside a comment, and thus their value doesn't matter anyway). It's 10352 only when the content does not conform to the grammar rules for FWS and thus 10353 literally cannot be parsed that content is considered invalid, and an empty 10354 range is returned. 10355 10356 Note that _stripCFWS is eager, not lazy. It does not create a new range. 10357 Rather, it pops off the CFWS from the range and returns it. 10358 +/ 10359 R _stripCFWS(R)(R range) 10360 if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && 10361 (is(Unqual!(ElementType!R) == char) || is(Unqual!(ElementType!R) == ubyte))) 10362 { 10363 immutable e = range.length; 10364 outer: for (size_t i = 0; i < e; ) 10365 { 10366 switch (range[i]) 10367 { 10368 case ' ': case '\t': 10369 { 10370 ++i; 10371 break; 10372 } 10373 case '\r': 10374 { 10375 if (i + 2 < e && range[i + 1] == '\n' && (range[i + 2] == ' ' || range[i + 2] == '\t')) 10376 { 10377 i += 3; 10378 break; 10379 } 10380 break outer; 10381 } 10382 case '\n': 10383 { 10384 if (i + 1 < e && (range[i + 1] == ' ' || range[i + 1] == '\t')) 10385 { 10386 i += 2; 10387 break; 10388 } 10389 break outer; 10390 } 10391 case '(': 10392 { 10393 ++i; 10394 size_t commentLevel = 1; 10395 while (i < e) 10396 { 10397 if (range[i] == '(') 10398 ++commentLevel; 10399 else if (range[i] == ')') 10400 { 10401 ++i; 10402 if (--commentLevel == 0) 10403 continue outer; 10404 continue; 10405 } 10406 else if (range[i] == '\\') 10407 { 10408 if (++i == e) 10409 break outer; 10410 } 10411 ++i; 10412 } 10413 break outer; 10414 } 10415 default: return range[i .. e]; 10416 } 10417 } 10418 return range[e .. e]; 10419 } 10420 10421 @system unittest 10422 { 10423 import std.algorithm.comparison : equal; 10424 import std.algorithm.iteration : map; 10425 import std.meta : AliasSeq; 10426 import std.stdio : writeln; 10427 import std.string : representation; 10428 10429 foreach (cr; AliasSeq!(function(string a){return cast(ubyte[]) a;}, 10430 function(string a){return map!(b => cast(char) b)(a.representation);})) 10431 (){ // avoid slow optimizations for large functions @@@BUG@@@ 2396 10432 scope(failure) writeln(typeof(cr).stringof); 10433 10434 assert(_stripCFWS(cr("")).empty); 10435 assert(_stripCFWS(cr("\r")).empty); 10436 assert(_stripCFWS(cr("\r\n")).empty); 10437 assert(_stripCFWS(cr("\r\n ")).empty); 10438 assert(_stripCFWS(cr(" \t\r\n")).empty); 10439 assert(equal(_stripCFWS(cr(" \t\r\n hello")), cr("hello"))); 10440 assert(_stripCFWS(cr(" \t\r\nhello")).empty); 10441 assert(_stripCFWS(cr(" \t\r\n\v")).empty); 10442 assert(equal(_stripCFWS(cr("\v \t\r\n\v")), cr("\v \t\r\n\v"))); 10443 assert(_stripCFWS(cr("()")).empty); 10444 assert(_stripCFWS(cr("(hello world)")).empty); 10445 assert(_stripCFWS(cr("(hello world)(hello world)")).empty); 10446 assert(_stripCFWS(cr("(hello world\r\n foo\r where's\nwaldo)")).empty); 10447 assert(_stripCFWS(cr(" \t (hello \tworld\r\n foo\r where's\nwaldo)\t\t ")).empty); 10448 assert(_stripCFWS(cr(" ")).empty); 10449 assert(_stripCFWS(cr("\t\t\t")).empty); 10450 assert(_stripCFWS(cr("\t \r\n\r \n")).empty); 10451 assert(_stripCFWS(cr("(hello world) (can't find waldo) (he's lost)")).empty); 10452 assert(_stripCFWS(cr("(hello\\) world) (can't \\(find waldo) (he's \\(\\)lost)")).empty); 10453 assert(_stripCFWS(cr("(((((")).empty); 10454 assert(_stripCFWS(cr("(((()))")).empty); 10455 assert(_stripCFWS(cr("(((())))")).empty); 10456 assert(equal(_stripCFWS(cr("(((()))))")), cr(")"))); 10457 assert(equal(_stripCFWS(cr(")))))")), cr(")))))"))); 10458 assert(equal(_stripCFWS(cr("()))))")), cr("))))"))); 10459 assert(equal(_stripCFWS(cr(" hello hello ")), cr("hello hello "))); 10460 assert(equal(_stripCFWS(cr("\thello (world)")), cr("hello (world)"))); 10461 assert(equal(_stripCFWS(cr(" \r\n \\((\\)) foo")), cr("\\((\\)) foo"))); 10462 assert(equal(_stripCFWS(cr(" \r\n (\\((\\))) foo")), cr("foo"))); 10463 assert(equal(_stripCFWS(cr(" \r\n (\\(())) foo")), cr(") foo"))); 10464 assert(_stripCFWS(cr(" \r\n (((\\))) foo")).empty); 10465 10466 assert(_stripCFWS(cr("(hello)(hello)")).empty); 10467 assert(_stripCFWS(cr(" \r\n (hello)\r\n (hello)")).empty); 10468 assert(_stripCFWS(cr(" \r\n (hello) \r\n (hello) \r\n ")).empty); 10469 assert(_stripCFWS(cr("\t\t\t\t(hello)\t\t\t\t(hello)\t\t\t\t")).empty); 10470 assert(equal(_stripCFWS(cr(" \r\n (hello)\r\n (hello) \r\n hello")), cr("hello"))); 10471 assert(equal(_stripCFWS(cr(" \r\n (hello) \r\n (hello) \r\n hello")), cr("hello"))); 10472 assert(equal(_stripCFWS(cr("\t\r\n\t(hello)\r\n\t(hello)\t\r\n hello")), cr("hello"))); 10473 assert(equal(_stripCFWS(cr("\t\r\n\t(hello)\t\r\n\t(hello)\t\r\n hello")), cr("hello"))); 10474 assert(equal(_stripCFWS(cr(" \r\n (hello) \r\n \r\n (hello) \r\n hello")), cr("hello"))); 10475 assert(equal(_stripCFWS(cr(" \r\n (hello) \r\n (hello) \r\n \r\n hello")), cr("hello"))); 10476 assert(equal(_stripCFWS(cr(" \r\n \r\n (hello)\t\r\n (hello) \r\n hello")), cr("hello"))); 10477 assert(equal(_stripCFWS(cr(" \r\n\t\r\n\t(hello)\t\r\n (hello) \r\n hello")), cr("hello"))); 10478 10479 assert(equal(_stripCFWS(cr(" (\r\n ( \r\n ) \r\n ) foo")), cr("foo"))); 10480 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n ) foo")), cr("foo"))); 10481 assert(equal(_stripCFWS(cr(" (\t\r\n ( \r\n ) \r\n ) foo")), cr("foo"))); 10482 assert(equal(_stripCFWS(cr(" (\r\n\t( \r\n ) \r\n ) foo")), cr("foo"))); 10483 assert(equal(_stripCFWS(cr(" ( \r\n (\t\r\n ) \r\n ) foo")), cr("foo"))); 10484 assert(equal(_stripCFWS(cr(" ( \r\n (\r\n ) \r\n ) foo")), cr("foo"))); 10485 assert(equal(_stripCFWS(cr(" ( \r\n (\r\n\t) \r\n ) foo")), cr("foo"))); 10486 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n) \r\n ) foo")), cr("foo"))); 10487 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n )\t\r\n ) foo")), cr("foo"))); 10488 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n )\r\n ) foo")), cr("foo"))); 10489 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n) foo")), cr("foo"))); 10490 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n\t) foo")), cr("foo"))); 10491 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n ) \r\n foo")), cr("foo"))); 10492 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n )\t\r\n foo")), cr("foo"))); 10493 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n )\r\n foo")), cr("foo"))); 10494 10495 assert(equal(_stripCFWS(cr(" ( \r\n \r\n ( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 10496 assert(equal(_stripCFWS(cr(" ( \r\n \r\n ( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 10497 assert(equal(_stripCFWS(cr(" (\t\r\n \r\n ( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 10498 assert(equal(_stripCFWS(cr(" (\r\n \r\n\t( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 10499 assert(equal(_stripCFWS(cr(" (\r\n \r\n( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 10500 assert(equal(_stripCFWS(cr(" (\r\n \r\n ( \r\n \r\n\t) \r\n ) foo")), cr("foo"))); 10501 assert(equal(_stripCFWS(cr(" (\r\n \r\n ( \r\n \r\n )\t\r\n ) foo")), cr("foo"))); 10502 assert(equal(_stripCFWS(cr(" (\r\n \r\n ( \r\n \r\n )\r\n ) foo")), cr("foo"))); 10503 10504 assert(equal(_stripCFWS(cr(" ( \r\n bar \r\n ( \r\n bar \r\n ) \r\n ) foo")), cr("foo"))); 10505 assert(equal(_stripCFWS(cr(" ( \r\n () \r\n ( \r\n () \r\n ) \r\n ) foo")), cr("foo"))); 10506 assert(equal(_stripCFWS(cr(" ( \r\n \\\\ \r\n ( \r\n \\\\ \r\n ) \r\n ) foo")), cr("foo"))); 10507 10508 assert(_stripCFWS(cr("(hello)(hello)")).empty); 10509 assert(_stripCFWS(cr(" \n (hello)\n (hello) \n ")).empty); 10510 assert(_stripCFWS(cr(" \n (hello) \n (hello) \n ")).empty); 10511 assert(equal(_stripCFWS(cr(" \n (hello)\n (hello) \n hello")), cr("hello"))); 10512 assert(equal(_stripCFWS(cr(" \n (hello) \n (hello) \n hello")), cr("hello"))); 10513 assert(equal(_stripCFWS(cr("\t\n\t(hello)\n\t(hello)\t\n hello")), cr("hello"))); 10514 assert(equal(_stripCFWS(cr("\t\n\t(hello)\t\n\t(hello)\t\n hello")), cr("hello"))); 10515 assert(equal(_stripCFWS(cr(" \n (hello) \n \n (hello) \n hello")), cr("hello"))); 10516 assert(equal(_stripCFWS(cr(" \n (hello) \n (hello) \n \n hello")), cr("hello"))); 10517 assert(equal(_stripCFWS(cr(" \n \n (hello)\t\n (hello) \n hello")), cr("hello"))); 10518 assert(equal(_stripCFWS(cr(" \n\t\n\t(hello)\t\n (hello) \n hello")), cr("hello"))); 10519 }(); 10520 } 10521 10522 // This is so that we don't have to worry about std.conv.to throwing. It also 10523 // doesn't have to worry about quite as many cases as std.conv.to, since it 10524 // doesn't have to worry about a sign on the value or about whether it fits. 10525 T _convDigits(T, R)(R str) 10526 if (isIntegral!T && isSigned!T) // The constraints on R were already covered by parseRFC822DateTime. 10527 { 10528 import std.ascii : isDigit; 10529 10530 assert(!str.empty); 10531 T num = 0; 10532 foreach (i; 0 .. str.length) 10533 { 10534 if (i != 0) 10535 num *= 10; 10536 if (!isDigit(str[i])) 10537 return -1; 10538 num += str[i] - '0'; 10539 } 10540 return num; 10541 } 10542 10543 @safe unittest 10544 { 10545 import std.conv : to; 10546 import std.range : chain, iota; 10547 import std.stdio : writeln; 10548 foreach (i; chain(iota(0, 101), [250, 999, 1000, 1001, 2345, 9999])) 10549 { 10550 scope(failure) writeln(i); 10551 assert(_convDigits!int(to!string(i)) == i); 10552 } 10553 foreach (str; ["-42", "+42", "1a", "1 ", " ", " 42 "]) 10554 { 10555 scope(failure) writeln(str); 10556 assert(_convDigits!int(str) == -1); 10557 } 10558 } 10559 10560 10561 version (unittest) 10562 { 10563 // Variables to help in testing. 10564 Duration currLocalDiffFromUTC; 10565 immutable (TimeZone)[] testTZs; 10566 10567 // All of these helper arrays are sorted in ascending order. 10568 auto testYearsBC = [-1999, -1200, -600, -4, -1, 0]; 10569 auto testYearsAD = [1, 4, 1000, 1999, 2000, 2012]; 10570 10571 // I'd use a Tuple, but I get forward reference errors if I try. 10572 struct MonthDay 10573 { 10574 Month month; 10575 short day; 10576 10577 this(int m, short d) 10578 { 10579 month = cast(Month) m; 10580 day = d; 10581 } 10582 } 10583 10584 MonthDay[] testMonthDays = [MonthDay(1, 1), 10585 MonthDay(1, 2), 10586 MonthDay(3, 17), 10587 MonthDay(7, 4), 10588 MonthDay(10, 27), 10589 MonthDay(12, 30), 10590 MonthDay(12, 31)]; 10591 10592 auto testDays = [1, 2, 9, 10, 16, 20, 25, 28, 29, 30, 31]; 10593 10594 auto testTODs = [TimeOfDay(0, 0, 0), 10595 TimeOfDay(0, 0, 1), 10596 TimeOfDay(0, 1, 0), 10597 TimeOfDay(1, 0, 0), 10598 TimeOfDay(13, 13, 13), 10599 TimeOfDay(23, 59, 59)]; 10600 10601 auto testHours = [0, 1, 12, 22, 23]; 10602 auto testMinSecs = [0, 1, 30, 58, 59]; 10603 10604 // Throwing exceptions is incredibly expensive, so we want to use a smaller 10605 // set of values for tests using assertThrown. 10606 auto testTODsThrown = [TimeOfDay(0, 0, 0), 10607 TimeOfDay(13, 13, 13), 10608 TimeOfDay(23, 59, 59)]; 10609 10610 Date[] testDatesBC; 10611 Date[] testDatesAD; 10612 10613 DateTime[] testDateTimesBC; 10614 DateTime[] testDateTimesAD; 10615 10616 Duration[] testFracSecs; 10617 10618 SysTime[] testSysTimesBC; 10619 SysTime[] testSysTimesAD; 10620 10621 // I'd use a Tuple, but I get forward reference errors if I try. 10622 struct GregDay { int day; Date date; } 10623 auto testGregDaysBC = [GregDay(-1_373_427, Date(-3760, 9, 7)), // Start of the Hebrew Calendar 10624 GregDay(-735_233, Date(-2012, 1, 1)), 10625 GregDay(-735_202, Date(-2012, 2, 1)), 10626 GregDay(-735_175, Date(-2012, 2, 28)), 10627 GregDay(-735_174, Date(-2012, 2, 29)), 10628 GregDay(-735_173, Date(-2012, 3, 1)), 10629 GregDay(-734_502, Date(-2010, 1, 1)), 10630 GregDay(-734_472, Date(-2010, 1, 31)), 10631 GregDay(-734_471, Date(-2010, 2, 1)), 10632 GregDay(-734_444, Date(-2010, 2, 28)), 10633 GregDay(-734_443, Date(-2010, 3, 1)), 10634 GregDay(-734_413, Date(-2010, 3, 31)), 10635 GregDay(-734_412, Date(-2010, 4, 1)), 10636 GregDay(-734_383, Date(-2010, 4, 30)), 10637 GregDay(-734_382, Date(-2010, 5, 1)), 10638 GregDay(-734_352, Date(-2010, 5, 31)), 10639 GregDay(-734_351, Date(-2010, 6, 1)), 10640 GregDay(-734_322, Date(-2010, 6, 30)), 10641 GregDay(-734_321, Date(-2010, 7, 1)), 10642 GregDay(-734_291, Date(-2010, 7, 31)), 10643 GregDay(-734_290, Date(-2010, 8, 1)), 10644 GregDay(-734_260, Date(-2010, 8, 31)), 10645 GregDay(-734_259, Date(-2010, 9, 1)), 10646 GregDay(-734_230, Date(-2010, 9, 30)), 10647 GregDay(-734_229, Date(-2010, 10, 1)), 10648 GregDay(-734_199, Date(-2010, 10, 31)), 10649 GregDay(-734_198, Date(-2010, 11, 1)), 10650 GregDay(-734_169, Date(-2010, 11, 30)), 10651 GregDay(-734_168, Date(-2010, 12, 1)), 10652 GregDay(-734_139, Date(-2010, 12, 30)), 10653 GregDay(-734_138, Date(-2010, 12, 31)), 10654 GregDay(-731_215, Date(-2001, 1, 1)), 10655 GregDay(-730_850, Date(-2000, 1, 1)), 10656 GregDay(-730_849, Date(-2000, 1, 2)), 10657 GregDay(-730_486, Date(-2000, 12, 30)), 10658 GregDay(-730_485, Date(-2000, 12, 31)), 10659 GregDay(-730_484, Date(-1999, 1, 1)), 10660 GregDay(-694_690, Date(-1901, 1, 1)), 10661 GregDay(-694_325, Date(-1900, 1, 1)), 10662 GregDay(-585_118, Date(-1601, 1, 1)), 10663 GregDay(-584_753, Date(-1600, 1, 1)), 10664 GregDay(-584_388, Date(-1600, 12, 31)), 10665 GregDay(-584_387, Date(-1599, 1, 1)), 10666 GregDay(-365_972, Date(-1001, 1, 1)), 10667 GregDay(-365_607, Date(-1000, 1, 1)), 10668 GregDay(-183_351, Date(-501, 1, 1)), 10669 GregDay(-182_986, Date(-500, 1, 1)), 10670 GregDay(-182_621, Date(-499, 1, 1)), 10671 GregDay(-146_827, Date(-401, 1, 1)), 10672 GregDay(-146_462, Date(-400, 1, 1)), 10673 GregDay(-146_097, Date(-400, 12, 31)), 10674 GregDay(-110_302, Date(-301, 1, 1)), 10675 GregDay(-109_937, Date(-300, 1, 1)), 10676 GregDay(-73_778, Date(-201, 1, 1)), 10677 GregDay(-73_413, Date(-200, 1, 1)), 10678 GregDay(-38_715, Date(-105, 1, 1)), 10679 GregDay(-37_254, Date(-101, 1, 1)), 10680 GregDay(-36_889, Date(-100, 1, 1)), 10681 GregDay(-36_524, Date(-99, 1, 1)), 10682 GregDay(-36_160, Date(-99, 12, 31)), 10683 GregDay(-35_794, Date(-97, 1, 1)), 10684 GregDay(-18_627, Date(-50, 1, 1)), 10685 GregDay(-18_262, Date(-49, 1, 1)), 10686 GregDay(-3652, Date(-9, 1, 1)), 10687 GregDay(-2191, Date(-5, 1, 1)), 10688 GregDay(-1827, Date(-5, 12, 31)), 10689 GregDay(-1826, Date(-4, 1, 1)), 10690 GregDay(-1825, Date(-4, 1, 2)), 10691 GregDay(-1462, Date(-4, 12, 30)), 10692 GregDay(-1461, Date(-4, 12, 31)), 10693 GregDay(-1460, Date(-3, 1, 1)), 10694 GregDay(-1096, Date(-3, 12, 31)), 10695 GregDay(-1095, Date(-2, 1, 1)), 10696 GregDay(-731, Date(-2, 12, 31)), 10697 GregDay(-730, Date(-1, 1, 1)), 10698 GregDay(-367, Date(-1, 12, 30)), 10699 GregDay(-366, Date(-1, 12, 31)), 10700 GregDay(-365, Date(0, 1, 1)), 10701 GregDay(-31, Date(0, 11, 30)), 10702 GregDay(-30, Date(0, 12, 1)), 10703 GregDay(-1, Date(0, 12, 30)), 10704 GregDay(0, Date(0, 12, 31))]; 10705 10706 auto testGregDaysAD = [GregDay(1, Date(1, 1, 1)), 10707 GregDay(2, Date(1, 1, 2)), 10708 GregDay(32, Date(1, 2, 1)), 10709 GregDay(365, Date(1, 12, 31)), 10710 GregDay(366, Date(2, 1, 1)), 10711 GregDay(731, Date(3, 1, 1)), 10712 GregDay(1096, Date(4, 1, 1)), 10713 GregDay(1097, Date(4, 1, 2)), 10714 GregDay(1460, Date(4, 12, 30)), 10715 GregDay(1461, Date(4, 12, 31)), 10716 GregDay(1462, Date(5, 1, 1)), 10717 GregDay(17_898, Date(50, 1, 1)), 10718 GregDay(35_065, Date(97, 1, 1)), 10719 GregDay(36_160, Date(100, 1, 1)), 10720 GregDay(36_525, Date(101, 1, 1)), 10721 GregDay(37_986, Date(105, 1, 1)), 10722 GregDay(72_684, Date(200, 1, 1)), 10723 GregDay(73_049, Date(201, 1, 1)), 10724 GregDay(109_208, Date(300, 1, 1)), 10725 GregDay(109_573, Date(301, 1, 1)), 10726 GregDay(145_732, Date(400, 1, 1)), 10727 GregDay(146_098, Date(401, 1, 1)), 10728 GregDay(182_257, Date(500, 1, 1)), 10729 GregDay(182_622, Date(501, 1, 1)), 10730 GregDay(364_878, Date(1000, 1, 1)), 10731 GregDay(365_243, Date(1001, 1, 1)), 10732 GregDay(584_023, Date(1600, 1, 1)), 10733 GregDay(584_389, Date(1601, 1, 1)), 10734 GregDay(693_596, Date(1900, 1, 1)), 10735 GregDay(693_961, Date(1901, 1, 1)), 10736 GregDay(729_755, Date(1999, 1, 1)), 10737 GregDay(730_120, Date(2000, 1, 1)), 10738 GregDay(730_121, Date(2000, 1, 2)), 10739 GregDay(730_484, Date(2000, 12, 30)), 10740 GregDay(730_485, Date(2000, 12, 31)), 10741 GregDay(730_486, Date(2001, 1, 1)), 10742 GregDay(733_773, Date(2010, 1, 1)), 10743 GregDay(733_774, Date(2010, 1, 2)), 10744 GregDay(733_803, Date(2010, 1, 31)), 10745 GregDay(733_804, Date(2010, 2, 1)), 10746 GregDay(733_831, Date(2010, 2, 28)), 10747 GregDay(733_832, Date(2010, 3, 1)), 10748 GregDay(733_862, Date(2010, 3, 31)), 10749 GregDay(733_863, Date(2010, 4, 1)), 10750 GregDay(733_892, Date(2010, 4, 30)), 10751 GregDay(733_893, Date(2010, 5, 1)), 10752 GregDay(733_923, Date(2010, 5, 31)), 10753 GregDay(733_924, Date(2010, 6, 1)), 10754 GregDay(733_953, Date(2010, 6, 30)), 10755 GregDay(733_954, Date(2010, 7, 1)), 10756 GregDay(733_984, Date(2010, 7, 31)), 10757 GregDay(733_985, Date(2010, 8, 1)), 10758 GregDay(734_015, Date(2010, 8, 31)), 10759 GregDay(734_016, Date(2010, 9, 1)), 10760 GregDay(734_045, Date(2010, 9, 30)), 10761 GregDay(734_046, Date(2010, 10, 1)), 10762 GregDay(734_076, Date(2010, 10, 31)), 10763 GregDay(734_077, Date(2010, 11, 1)), 10764 GregDay(734_106, Date(2010, 11, 30)), 10765 GregDay(734_107, Date(2010, 12, 1)), 10766 GregDay(734_136, Date(2010, 12, 30)), 10767 GregDay(734_137, Date(2010, 12, 31)), 10768 GregDay(734_503, Date(2012, 1, 1)), 10769 GregDay(734_534, Date(2012, 2, 1)), 10770 GregDay(734_561, Date(2012, 2, 28)), 10771 GregDay(734_562, Date(2012, 2, 29)), 10772 GregDay(734_563, Date(2012, 3, 1)), 10773 GregDay(734_858, Date(2012, 12, 21))]; 10774 10775 // I'd use a Tuple, but I get forward reference errors if I try. 10776 struct DayOfYear { int day; MonthDay md; } 10777 auto testDaysOfYear = [DayOfYear(1, MonthDay(1, 1)), 10778 DayOfYear(2, MonthDay(1, 2)), 10779 DayOfYear(3, MonthDay(1, 3)), 10780 DayOfYear(31, MonthDay(1, 31)), 10781 DayOfYear(32, MonthDay(2, 1)), 10782 DayOfYear(59, MonthDay(2, 28)), 10783 DayOfYear(60, MonthDay(3, 1)), 10784 DayOfYear(90, MonthDay(3, 31)), 10785 DayOfYear(91, MonthDay(4, 1)), 10786 DayOfYear(120, MonthDay(4, 30)), 10787 DayOfYear(121, MonthDay(5, 1)), 10788 DayOfYear(151, MonthDay(5, 31)), 10789 DayOfYear(152, MonthDay(6, 1)), 10790 DayOfYear(181, MonthDay(6, 30)), 10791 DayOfYear(182, MonthDay(7, 1)), 10792 DayOfYear(212, MonthDay(7, 31)), 10793 DayOfYear(213, MonthDay(8, 1)), 10794 DayOfYear(243, MonthDay(8, 31)), 10795 DayOfYear(244, MonthDay(9, 1)), 10796 DayOfYear(273, MonthDay(9, 30)), 10797 DayOfYear(274, MonthDay(10, 1)), 10798 DayOfYear(304, MonthDay(10, 31)), 10799 DayOfYear(305, MonthDay(11, 1)), 10800 DayOfYear(334, MonthDay(11, 30)), 10801 DayOfYear(335, MonthDay(12, 1)), 10802 DayOfYear(363, MonthDay(12, 29)), 10803 DayOfYear(364, MonthDay(12, 30)), 10804 DayOfYear(365, MonthDay(12, 31))]; 10805 10806 auto testDaysOfLeapYear = [DayOfYear(1, MonthDay(1, 1)), 10807 DayOfYear(2, MonthDay(1, 2)), 10808 DayOfYear(3, MonthDay(1, 3)), 10809 DayOfYear(31, MonthDay(1, 31)), 10810 DayOfYear(32, MonthDay(2, 1)), 10811 DayOfYear(59, MonthDay(2, 28)), 10812 DayOfYear(60, MonthDay(2, 29)), 10813 DayOfYear(61, MonthDay(3, 1)), 10814 DayOfYear(91, MonthDay(3, 31)), 10815 DayOfYear(92, MonthDay(4, 1)), 10816 DayOfYear(121, MonthDay(4, 30)), 10817 DayOfYear(122, MonthDay(5, 1)), 10818 DayOfYear(152, MonthDay(5, 31)), 10819 DayOfYear(153, MonthDay(6, 1)), 10820 DayOfYear(182, MonthDay(6, 30)), 10821 DayOfYear(183, MonthDay(7, 1)), 10822 DayOfYear(213, MonthDay(7, 31)), 10823 DayOfYear(214, MonthDay(8, 1)), 10824 DayOfYear(244, MonthDay(8, 31)), 10825 DayOfYear(245, MonthDay(9, 1)), 10826 DayOfYear(274, MonthDay(9, 30)), 10827 DayOfYear(275, MonthDay(10, 1)), 10828 DayOfYear(305, MonthDay(10, 31)), 10829 DayOfYear(306, MonthDay(11, 1)), 10830 DayOfYear(335, MonthDay(11, 30)), 10831 DayOfYear(336, MonthDay(12, 1)), 10832 DayOfYear(364, MonthDay(12, 29)), 10833 DayOfYear(365, MonthDay(12, 30)), 10834 DayOfYear(366, MonthDay(12, 31))]; 10835 10836 void initializeTests() @safe 10837 { 10838 import std.algorithm.sorting : sort; 10839 import std.typecons : Rebindable; 10840 immutable lt = LocalTime().utcToTZ(0); 10841 currLocalDiffFromUTC = dur!"hnsecs"(lt); 10842 10843 version (Posix) 10844 { 10845 immutable otherTZ = lt < 0 ? PosixTimeZone.getTimeZone("Australia/Sydney") 10846 : PosixTimeZone.getTimeZone("America/Denver"); 10847 } 10848 else version (Windows) 10849 { 10850 immutable otherTZ = lt < 0 ? WindowsTimeZone.getTimeZone("AUS Eastern Standard Time") 10851 : WindowsTimeZone.getTimeZone("Mountain Standard Time"); 10852 } 10853 10854 immutable ot = otherTZ.utcToTZ(0); 10855 10856 auto diffs = [0L, lt, ot]; 10857 auto diffAA = [0L : Rebindable!(immutable TimeZone)(UTC())]; 10858 diffAA[lt] = Rebindable!(immutable TimeZone)(LocalTime()); 10859 diffAA[ot] = Rebindable!(immutable TimeZone)(otherTZ); 10860 10861 sort(diffs); 10862 testTZs = [diffAA[diffs[0]], diffAA[diffs[1]], diffAA[diffs[2]]]; 10863 10864 testFracSecs = [Duration.zero, hnsecs(1), hnsecs(5007), hnsecs(9_999_999)]; 10865 10866 foreach (year; testYearsBC) 10867 { 10868 foreach (md; testMonthDays) 10869 testDatesBC ~= Date(year, md.month, md.day); 10870 } 10871 10872 foreach (year; testYearsAD) 10873 { 10874 foreach (md; testMonthDays) 10875 testDatesAD ~= Date(year, md.month, md.day); 10876 } 10877 10878 foreach (dt; testDatesBC) 10879 { 10880 foreach (tod; testTODs) 10881 testDateTimesBC ~= DateTime(dt, tod); 10882 } 10883 10884 foreach (dt; testDatesAD) 10885 { 10886 foreach (tod; testTODs) 10887 testDateTimesAD ~= DateTime(dt, tod); 10888 } 10889 10890 foreach (dt; testDateTimesBC) 10891 { 10892 foreach (tz; testTZs) 10893 { 10894 foreach (fs; testFracSecs) 10895 testSysTimesBC ~= SysTime(dt, fs, tz); 10896 } 10897 } 10898 10899 foreach (dt; testDateTimesAD) 10900 { 10901 foreach (tz; testTZs) 10902 { 10903 foreach (fs; testFracSecs) 10904 testSysTimesAD ~= SysTime(dt, fs, tz); 10905 } 10906 } 10907 } 10908 } 10909