1 // Written in the D programming language 2 3 /++ 4 5 $(DIVC quickindex, 6 $(BOOKTABLE, 7 $(TR $(TH Category) $(TH Functions)) 8 $(TR $(TD Types) $(TD 9 $(LREF Clock) 10 $(LREF SysTime) 11 $(LREF DosFileTime) 12 )) 13 $(TR $(TD Conversion) $(TD 14 $(LREF parseRFC822DateTime) 15 $(LREF DosFileTimeToSysTime) 16 $(LREF FILETIMEToStdTime) 17 $(LREF FILETIMEToSysTime) 18 $(LREF stdTimeToFILETIME) 19 $(LREF stdTimeToUnixTime) 20 $(LREF SYSTEMTIMEToSysTime) 21 $(LREF SysTimeToDosFileTime) 22 $(LREF SysTimeToFILETIME) 23 $(LREF SysTimeToSYSTEMTIME) 24 $(LREF unixTimeToStdTime) 25 )) 26 )) 27 28 License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). 29 Authors: $(HTTP jmdavisprog.com, Jonathan M Davis) 30 Source: $(PHOBOSSRC std/datetime/systime.d) 31 +/ 32 module std.datetime.systime; 33 34 version (OSX) 35 version = Darwin; 36 else version (iOS) 37 version = Darwin; 38 else version (TVOS) 39 version = Darwin; 40 else version (WatchOS) 41 version = Darwin; 42 43 /// Get the current time as a $(LREF SysTime) 44 @safe unittest 45 { 46 import std.datetime.timezone : LocalTime; 47 SysTime today = Clock.currTime(); 48 assert(today.timezone is LocalTime()); 49 } 50 51 /// Construct a $(LREF SysTime) from a ISO time string 52 @safe unittest 53 { 54 import std.datetime.date : DateTime; 55 import std.datetime.timezone : UTC; 56 57 auto st = SysTime.fromISOExtString("2018-01-01T10:30:00Z"); 58 assert(st == SysTime(DateTime(2018, 1, 1, 10, 30, 0), UTC())); 59 } 60 61 /// Make a specific point in time in the New York timezone 62 @safe unittest 63 { 64 import core.time : hours; 65 import std.datetime.date : DateTime; 66 import std.datetime.timezone : SimpleTimeZone; 67 68 auto ny = SysTime( 69 DateTime(2018, 1, 1, 10, 30, 0), 70 new immutable SimpleTimeZone(-5.hours, "America/New_York") 71 ); 72 73 // ISO standard time strings 74 assert(ny.toISOString() == "20180101T103000-05:00"); 75 assert(ny.toISOExtString() == "2018-01-01T10:30:00-05:00"); 76 } 77 78 // Note: reconsider using specific imports below after 79 // https://issues.dlang.org/show_bug.cgi?id=17630 has been fixed 80 import core.time;// : ClockType, convert, dur, Duration, seconds, TimeException; 81 import std.datetime.date;// : _monthNames, AllowDayOverflow, CmpTimeUnits, Date, 82 //DateTime, DateTimeException, DayOfWeek, enforceValid, getDayOfWeek, maxDay, 83 //Month, splitUnitsFromHNSecs, TimeOfDay, validTimeUnits, yearIsLeapYear; 84 import std.datetime.timezone;// : LocalTime, SimpleTimeZone, TimeZone, UTC; 85 import std.exception : enforce; 86 import std.format : format; 87 import std.range.primitives; 88 import std.traits : isIntegral, isSigned, isSomeString, isNarrowString; 89 90 version (Windows) 91 { 92 import core.stdc.time : time_t; 93 import core.sys.windows.winbase; 94 import core.sys.windows.winnt; 95 import core.sys.windows.winsock2; 96 } 97 else version (Posix) 98 { 99 import core.sys.posix.signal : timespec; 100 import core.sys.posix.sys.types : time_t; 101 } 102 103 version (StdUnittest) 104 { 105 import core.exception : AssertError; 106 import std.exception : assertThrown; 107 } 108 109 110 @safe unittest 111 { 112 initializeTests(); 113 } 114 115 version (unittest) private bool clockSupported(ClockType c) 116 { 117 // Skip unsupported clocks on older linux kernels, assume that only 118 // CLOCK_MONOTONIC and CLOCK_REALTIME exist, as that is the lowest 119 // common denominator supported by all versions of Linux pre-2.6.12. 120 version (Linux_Pre_2639) 121 return c == ClockType.normal || c == ClockType.precise; 122 else 123 return true; 124 } 125 126 /++ 127 Effectively a namespace to make it clear that the methods it contains are 128 getting the time from the system clock. It cannot be instantiated. 129 +/ 130 final class Clock 131 { 132 public: 133 134 /++ 135 Returns the current time in the given time zone. 136 137 Params: 138 clockType = The $(REF ClockType, core,time) indicates which system 139 clock to use to get the current time. Very few programs 140 need to use anything other than the default. 141 tz = The time zone for the SysTime that's returned. 142 143 Throws: 144 $(REF DateTimeException,std,datetime,date) if it fails to get the 145 time. 146 +/ 147 static SysTime currTime(ClockType clockType = ClockType.normal)(immutable TimeZone tz = LocalTime()) @safe 148 { 149 return SysTime(currStdTime!clockType, tz); 150 } 151 152 @safe unittest 153 { 154 import std.format : format; 155 import core.time; 156 assert(currTime().timezone is LocalTime()); 157 assert(currTime(UTC()).timezone is UTC()); 158 159 // core.stdc.time.time does not always use unix time on Windows systems. 160 // In particular, dmc does not use unix time. If we can guarantee that 161 // the MS runtime uses unix time, then we may be able run this test 162 // then, but for now, we're just not going to run this test on Windows. 163 version (Posix) 164 { 165 static import core.stdc.time; 166 static import std.math; 167 immutable unixTimeD = currTime().toUnixTime(); 168 immutable unixTimeC = core.stdc.time.time(null); 169 assert(std.math.abs(unixTimeC - unixTimeD) <= 2); 170 } 171 172 auto norm1 = Clock.currTime; 173 auto norm2 = Clock.currTime(UTC()); 174 assert(norm1 <= norm2, format("%s %s", norm1, norm2)); 175 assert(abs(norm1 - norm2) <= seconds(2)); 176 177 import std.meta : AliasSeq; 178 static foreach (ct; AliasSeq!(ClockType.coarse, ClockType.precise, ClockType.second)) 179 {{ 180 static if (clockSupported(ct)) 181 { 182 auto value1 = Clock.currTime!ct; 183 auto value2 = Clock.currTime!ct(UTC()); 184 assert(value1 <= value2, format("%s %s (ClockType: %s)", value1, value2, ct)); 185 assert(abs(value1 - value2) <= seconds(2), format("ClockType.%s", ct)); 186 } 187 }} 188 } 189 190 191 /++ 192 Returns the number of hnsecs since midnight, January 1st, 1 A.D. for the 193 current time. 194 195 Params: 196 clockType = The $(REF ClockType, core,time) indicates which system 197 clock to use to get the current time. Very few programs 198 need to use anything other than the default. 199 200 Throws: 201 $(REF DateTimeException,std,datetime,date) if it fails to get the 202 time. 203 +/ 204 static @property long currStdTime(ClockType clockType = ClockType.normal)() @trusted 205 { 206 static if (clockType != ClockType.coarse && 207 clockType != ClockType.normal && 208 clockType != ClockType.precise && 209 clockType != ClockType.second) 210 { 211 static assert(0, format("ClockType.%s is not supported by Clock.currTime or Clock.currStdTime", clockType)); 212 } 213 214 version (Windows) 215 { 216 FILETIME fileTime; 217 GetSystemTimeAsFileTime(&fileTime); 218 immutable result = FILETIMEToStdTime(&fileTime); 219 static if (clockType == ClockType.second) 220 { 221 // Ideally, this would use core.std.time.time, but the C runtime 222 // has to be using unix time for that to work, and that's not 223 // guaranteed on Windows. Digital Mars does not use unix time. 224 // MS may or may not. If it does, then this can be made to use 225 // core.stdc.time for MS, but for now, we'll leave it like this. 226 return convert!("seconds", "hnsecs")(convert!("hnsecs", "seconds")(result)); 227 } 228 else 229 return result; 230 } 231 else version (Posix) 232 { 233 static import core.stdc.time; 234 enum hnsecsToUnixEpoch = unixTimeToStdTime(0); 235 236 version (Darwin) 237 { 238 static if (clockType == ClockType.second) 239 return unixTimeToStdTime(core.stdc.time.time(null)); 240 else 241 { 242 import core.sys.posix.sys.time : gettimeofday, timeval; 243 timeval tv = void; 244 // Posix gettimeofday called with a valid timeval address 245 // and a null second parameter doesn't fail. 246 gettimeofday(&tv, null); 247 return convert!("seconds", "hnsecs")(tv.tv_sec) + 248 tv.tv_usec * 10 + 249 hnsecsToUnixEpoch; 250 } 251 } 252 else version (linux) 253 { 254 static if (clockType == ClockType.second) 255 return unixTimeToStdTime(core.stdc.time.time(null)); 256 else 257 { 258 import core.sys.linux.time : CLOCK_REALTIME_COARSE; 259 import core.sys.posix.time : clock_gettime, CLOCK_REALTIME; 260 static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME_COARSE; 261 else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME; 262 else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME; 263 else static assert(0, "Previous static if is wrong."); 264 timespec ts = void; 265 immutable error = clock_gettime(clockArg, &ts); 266 // Posix clock_gettime called with a valid address and valid clock_id is only 267 // permitted to fail if the number of seconds does not fit in time_t. If tv_sec 268 // is long or larger overflow won't happen before 292 billion years A.D. 269 static if (ts.tv_sec.max < long.max) 270 { 271 if (error) 272 throw new TimeException("Call to clock_gettime() failed"); 273 } 274 return convert!("seconds", "hnsecs")(ts.tv_sec) + 275 ts.tv_nsec / 100 + 276 hnsecsToUnixEpoch; 277 } 278 } 279 else version (FreeBSD) 280 { 281 import core.sys.freebsd.time : clock_gettime, CLOCK_REALTIME, 282 CLOCK_REALTIME_FAST, CLOCK_REALTIME_PRECISE, CLOCK_SECOND; 283 static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME_FAST; 284 else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME; 285 else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME_PRECISE; 286 else static if (clockType == ClockType.second) alias clockArg = CLOCK_SECOND; 287 else static assert(0, "Previous static if is wrong."); 288 timespec ts = void; 289 immutable error = clock_gettime(clockArg, &ts); 290 // Posix clock_gettime called with a valid address and valid clock_id is only 291 // permitted to fail if the number of seconds does not fit in time_t. If tv_sec 292 // is long or larger overflow won't happen before 292 billion years A.D. 293 static if (ts.tv_sec.max < long.max) 294 { 295 if (error) 296 throw new TimeException("Call to clock_gettime() failed"); 297 } 298 return convert!("seconds", "hnsecs")(ts.tv_sec) + 299 ts.tv_nsec / 100 + 300 hnsecsToUnixEpoch; 301 } 302 else version (NetBSD) 303 { 304 static if (clockType == ClockType.second) 305 return unixTimeToStdTime(core.stdc.time.time(null)); 306 else 307 { 308 import core.sys.netbsd.time : clock_gettime, CLOCK_REALTIME; 309 timespec ts = void; 310 immutable error = clock_gettime(CLOCK_REALTIME, &ts); 311 // Posix clock_gettime called with a valid address and valid clock_id is only 312 // permitted to fail if the number of seconds does not fit in time_t. If tv_sec 313 // is long or larger overflow won't happen before 292 billion years A.D. 314 static if (ts.tv_sec.max < long.max) 315 { 316 if (error) 317 throw new TimeException("Call to clock_gettime() failed"); 318 } 319 return convert!("seconds", "hnsecs")(ts.tv_sec) + 320 ts.tv_nsec / 100 + 321 hnsecsToUnixEpoch; 322 } 323 } 324 else version (OpenBSD) 325 { 326 static if (clockType == ClockType.second) 327 return unixTimeToStdTime(core.stdc.time.time(null)); 328 else 329 { 330 import core.sys.openbsd.time : clock_gettime, CLOCK_REALTIME; 331 static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME; 332 else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME; 333 else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME; 334 else static assert(0, "Previous static if is wrong."); 335 timespec ts; 336 if (clock_gettime(clockArg, &ts) != 0) 337 throw new TimeException("Call to clock_gettime() failed"); 338 return convert!("seconds", "hnsecs")(ts.tv_sec) + 339 ts.tv_nsec / 100 + 340 hnsecsToUnixEpoch; 341 } 342 } 343 else version (DragonFlyBSD) 344 { 345 import core.sys.dragonflybsd.time : clock_gettime, CLOCK_REALTIME, 346 CLOCK_REALTIME_FAST, CLOCK_REALTIME_PRECISE, CLOCK_SECOND; 347 static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME_FAST; 348 else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME; 349 else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME_PRECISE; 350 else static if (clockType == ClockType.second) alias clockArg = CLOCK_SECOND; 351 else static assert(0, "Previous static if is wrong."); 352 timespec ts = void; 353 immutable error = clock_gettime(clockArg, &ts); 354 // Posix clock_gettime called with a valid address and valid clock_id is only 355 // permitted to fail if the number of seconds does not fit in time_t. If tv_sec 356 // is long or larger overflow won't happen before 292 billion years A.D. 357 static if (ts.tv_sec.max < long.max) 358 { 359 if (error) 360 throw new TimeException("Call to clock_gettime() failed"); 361 } 362 return convert!("seconds", "hnsecs")(ts.tv_sec) + 363 ts.tv_nsec / 100 + 364 hnsecsToUnixEpoch; 365 } 366 else version (Solaris) 367 { 368 static if (clockType == ClockType.second) 369 return unixTimeToStdTime(core.stdc.time.time(null)); 370 else 371 { 372 import core.sys.solaris.time : clock_gettime, CLOCK_REALTIME; 373 static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME; 374 else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME; 375 else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME; 376 else static assert(0, "Previous static if is wrong."); 377 timespec ts = void; 378 immutable error = clock_gettime(clockArg, &ts); 379 // Posix clock_gettime called with a valid address and valid clock_id is only 380 // permitted to fail if the number of seconds does not fit in time_t. If tv_sec 381 // is long or larger overflow won't happen before 292 billion years A.D. 382 static if (ts.tv_sec.max < long.max) 383 { 384 if (error) 385 throw new TimeException("Call to clock_gettime() failed"); 386 } 387 return convert!("seconds", "hnsecs")(ts.tv_sec) + 388 ts.tv_nsec / 100 + 389 hnsecsToUnixEpoch; 390 } 391 } 392 else version (Hurd) 393 { 394 static if (clockType == ClockType.second) 395 return unixTimeToStdTime(core.stdc.time.time(null)); 396 else 397 { 398 import core.sys.hurd.time : CLOCK_REALTIME_COARSE; 399 import core.sys.posix.time : clock_gettime, CLOCK_REALTIME; 400 static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME_COARSE; 401 else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME; 402 else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME; 403 else static assert(0, "Previous static if is wrong."); 404 timespec ts = void; 405 immutable error = clock_gettime(clockArg, &ts); 406 // Posix clock_gettime called with a valid address and valid clock_id is only 407 // permitted to fail if the number of seconds does not fit in time_t. If tv_sec 408 // is long or larger overflow won't happen before 292 billion years A.D. 409 static if (ts.tv_sec.max < long.max) 410 { 411 if (error) 412 throw new TimeException("Call to clock_gettime() failed"); 413 } 414 return convert!("seconds", "hnsecs")(ts.tv_sec) + 415 ts.tv_nsec / 100 + 416 hnsecsToUnixEpoch; 417 } 418 } 419 else static assert(0, "Unsupported OS"); 420 } 421 else static assert(0, "Unsupported OS"); 422 } 423 424 @safe unittest 425 { 426 import std.format : format; 427 import std.math.algebraic : abs; 428 import std.meta : AliasSeq; 429 enum limit = convert!("seconds", "hnsecs")(2); 430 431 auto norm1 = Clock.currStdTime; 432 auto norm2 = Clock.currStdTime; 433 assert(norm1 <= norm2, format("%s %s", norm1, norm2)); 434 assert(abs(norm1 - norm2) <= limit); 435 436 static foreach (ct; AliasSeq!(ClockType.coarse, ClockType.precise, ClockType.second)) 437 {{ 438 static if (clockSupported(ct)) 439 { 440 auto value1 = Clock.currStdTime!ct; 441 auto value2 = Clock.currStdTime!ct; 442 assert(value1 <= value2, format("%s %s (ClockType: %s)", value1, value2, ct)); 443 assert(abs(value1 - value2) <= limit); 444 } 445 }} 446 } 447 448 449 private: 450 451 @disable this(); 452 } 453 454 /// Get the current time as a $(LREF SysTime) 455 @safe unittest 456 { 457 import std.datetime.timezone : LocalTime; 458 SysTime today = Clock.currTime(); 459 assert(today.timezone is LocalTime()); 460 } 461 462 463 /++ 464 `SysTime` is the type used to get the current time from the 465 system or doing anything that involves time zones. Unlike 466 $(REF DateTime,std,datetime,date), the time zone is an integral part of 467 `SysTime` (though for local time applications, time zones can be ignored 468 and it will work, since it defaults to using the local time zone). It holds 469 its internal time in std time (hnsecs since midnight, January 1st, 1 A.D. 470 UTC), so it interfaces well with the system time. 471 472 An $(I hnsec) (hecto-nanosecond) is 100 nanoseconds. There are 10,000,000 hnsecs in a second. 473 474 $(PANEL 475 Unlike $(REF_SHORT DateTime,std,datetime,date), `SysTime` is not optimized for 476 calendar-based operations, and getting individual units from it such as 477 years or days is going to involve conversions and be less efficient. 478 479 For calendar-based operations that don't 480 care about time zones, then $(REF_SHORT DateTime,std,datetime,date) would be 481 the type to use. For system time, use `SysTime`. 482 ) 483 $(P 484 Casting a `SysTime` to one of the following types will perform a conversion: 485 ) 486 * $(REF Date,std,datetime,date) 487 * $(REF_SHORT DateTime,std,datetime,date) 488 * $(REF_SHORT TimeOfDay,std,datetime,date) 489 $(P 490 To convert a 491 $(REF_SHORT Date,std,datetime,date) or $(REF_SHORT DateTime,std,datetime,date) to a 492 `SysTime`, use `SysTime`'s constructor, and pass in the intended time 493 zone with it (or don't pass in a $(REF TimeZone,std,datetime,timezone), and 494 the local time zone will be used). Be aware, however, that converting from a 495 $(REF_SHORT DateTime,std,datetime,date) to a `SysTime` will not necessarily 496 be 100% accurate due to DST (one hour of the year doesn't exist and another 497 occurs twice). To not risk any conversion errors, keep times as 498 `SysTime`s. Aside from DST though, there shouldn't be any conversion 499 problems. 500 ) 501 $(PANEL 502 For using time zones other than local time or UTC, use 503 $(REF PosixTimeZone,std,datetime,timezone) on Posix systems (or on Windows, 504 if providing the TZ Database files), and use 505 $(REF WindowsTimeZone,std,datetime,timezone) on Windows systems. The time in 506 `SysTime` is kept internally in hnsecs from midnight, January 1st, 1 A.D. 507 UTC. Conversion error cannot happen when changing the time zone of a 508 `SysTime`. $(REF LocalTime,std,datetime,timezone) is the 509 $(REF_SHORT TimeZone,std,datetime,timezone) class which represents the local time, 510 and `UTC` is the $(REF_SHORT TimeZone,std,datetime,timezone) class which 511 represents UTC. `SysTime` uses $(REF_SHORT LocalTime,std,datetime,timezone) if 512 no $(REF_SHORT TimeZone,std,datetime,timezone) is provided. For more details on 513 time zones, see the documentation for $(REF_SHORT TimeZone,std,datetime,timezone), 514 $(REF_SHORT PosixTimeZone,std,datetime,timezone), and 515 $(REF_SHORT WindowsTimeZone,std,datetime,timezone). 516 ) 517 $(P 518 `SysTime`'s range is from approximately 29,000 B.C. to approximately 519 29,000 A.D. 520 ) 521 See_Also: 522 $(RELATIVE_LINK2 .Clock.currTime, `Clock.currTime`) will return the current time as a `SysTime`. 523 +/ 524 struct SysTime 525 { 526 import core.stdc.time : tm; 527 version (Posix) import core.sys.posix.sys.time : timeval; 528 import std.typecons : Rebindable; 529 530 public: 531 532 /++ 533 Params: 534 dateTime = The $(REF DateTime,std,datetime,date) to use to set 535 this $(LREF SysTime)'s internal std time. As 536 $(REF DateTime,std,datetime,date) has no concept of 537 time zone, tz is used as its time zone. 538 tz = The $(REF TimeZone,std,datetime,timezone) to use for this 539 $(LREF SysTime). If null, 540 $(REF LocalTime,std,datetime,timezone) will be used. The 541 given $(REF DateTime,std,datetime,date) is assumed to 542 be in the given time zone. 543 +/ 544 this(DateTime dateTime, return scope immutable TimeZone tz = null) return scope @safe nothrow 545 { 546 try 547 this(dateTime, Duration.zero, tz); 548 catch (Exception e) 549 assert(0, "SysTime's constructor threw when it shouldn't have."); 550 } 551 552 @safe unittest 553 { 554 static void test(DateTime dt, immutable TimeZone tz, long expected) 555 { 556 auto sysTime = SysTime(dt, tz); 557 assert(sysTime._stdTime == expected); 558 assert(sysTime._timezone is (tz is null ? LocalTime() : tz), format("Given DateTime: %s", dt)); 559 } 560 561 test(DateTime.init, UTC(), 0); 562 test(DateTime(1, 1, 1, 12, 30, 33), UTC(), 450_330_000_000L); 563 test(DateTime(0, 12, 31, 12, 30, 33), UTC(), -413_670_000_000L); 564 test(DateTime(1, 1, 1, 0, 0, 0), UTC(), 0); 565 test(DateTime(1, 1, 1, 0, 0, 1), UTC(), 10_000_000L); 566 test(DateTime(0, 12, 31, 23, 59, 59), UTC(), -10_000_000L); 567 568 test(DateTime(1, 1, 1, 0, 0, 0), new immutable SimpleTimeZone(dur!"minutes"(-60)), 36_000_000_000L); 569 test(DateTime(1, 1, 1, 0, 0, 0), new immutable SimpleTimeZone(Duration.zero), 0); 570 test(DateTime(1, 1, 1, 0, 0, 0), new immutable SimpleTimeZone(dur!"minutes"(60)), -36_000_000_000L); 571 572 static void testScope(scope ref DateTime dt) @safe 573 { 574 auto st = SysTime(dt); 575 } 576 } 577 578 /++ 579 Params: 580 dateTime = The $(REF DateTime,std,datetime,date) to use to set 581 this $(LREF SysTime)'s internal std time. As 582 $(REF DateTime,std,datetime,date) has no concept of 583 time zone, tz is used as its time zone. 584 fracSecs = The fractional seconds portion of the time. 585 tz = The $(REF TimeZone,std,datetime,timezone) to use for this 586 $(LREF SysTime). If null, 587 $(REF LocalTime,std,datetime,timezone) will be used. The 588 given $(REF DateTime,std,datetime,date) is assumed to 589 be in the given time zone. 590 591 Throws: 592 $(REF DateTimeException,std,datetime,date) if `fracSecs` is negative or if it's 593 greater than or equal to one second. 594 +/ 595 this(DateTime dateTime, Duration fracSecs, return scope immutable TimeZone tz = null) return scope @safe 596 { 597 enforce(fracSecs >= Duration.zero, new DateTimeException("A SysTime cannot have negative fractional seconds.")); 598 enforce(fracSecs < seconds(1), new DateTimeException("Fractional seconds must be less than one second.")); 599 auto nonNullTZ = tz is null ? LocalTime() : tz; 600 601 immutable dateDiff = dateTime.date - Date.init; 602 immutable todDiff = dateTime.timeOfDay - TimeOfDay.init; 603 604 immutable adjustedTime = dateDiff + todDiff + fracSecs; 605 immutable standardTime = nonNullTZ.tzToUTC(adjustedTime.total!"hnsecs"); 606 607 this(standardTime, nonNullTZ); 608 } 609 610 @safe unittest 611 { 612 import core.time; 613 static void test(DateTime dt, Duration fracSecs, immutable TimeZone tz, long expected) 614 { 615 auto sysTime = SysTime(dt, fracSecs, tz); 616 assert(sysTime._stdTime == expected); 617 assert(sysTime._timezone is (tz is null ? LocalTime() : tz), 618 format("Given DateTime: %s, Given Duration: %s", dt, fracSecs)); 619 } 620 621 test(DateTime.init, Duration.zero, UTC(), 0); 622 test(DateTime(1, 1, 1, 12, 30, 33), Duration.zero, UTC(), 450_330_000_000L); 623 test(DateTime(0, 12, 31, 12, 30, 33), Duration.zero, UTC(), -413_670_000_000L); 624 test(DateTime(1, 1, 1, 0, 0, 0), msecs(1), UTC(), 10_000L); 625 test(DateTime(0, 12, 31, 23, 59, 59), msecs(999), UTC(), -10_000L); 626 627 test(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC(), -1); 628 test(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC(), -9_999_999); 629 test(DateTime(0, 12, 31, 23, 59, 59), Duration.zero, UTC(), -10_000_000); 630 631 assertThrown!DateTimeException(SysTime(DateTime.init, hnsecs(-1), UTC())); 632 assertThrown!DateTimeException(SysTime(DateTime.init, seconds(1), UTC())); 633 634 static void testScope(scope ref DateTime dt, scope ref Duration d) @safe 635 { 636 auto st = SysTime(dt, d); 637 } 638 } 639 640 /++ 641 Params: 642 date = The $(REF Date,std,datetime,date) to use to set this 643 $(LREF SysTime)'s internal std time. As 644 $(REF Date,std,datetime,date) has no concept of time zone, tz 645 is used as its time zone. 646 tz = The $(REF TimeZone,std,datetime,timezone) to use for this 647 $(LREF SysTime). If null, 648 $(REF LocalTime,std,datetime,timezone) will be used. The 649 given $(REF Date,std,datetime,date) is assumed to be in the 650 given time zone. 651 +/ 652 this(Date date, return scope immutable TimeZone tz = null) return scope @safe nothrow 653 { 654 _timezone = tz is null ? LocalTime() : tz; 655 656 try 657 { 658 immutable adjustedTime = (date - Date(1, 1, 1)).total!"hnsecs"; 659 immutable standardTime = _timezone.tzToUTC(adjustedTime); 660 661 this(standardTime, _timezone); 662 } 663 catch (Exception e) 664 assert(0, "Date's constructor through when it shouldn't have."); 665 } 666 667 @safe unittest 668 { 669 static void test(Date d, immutable TimeZone tz, long expected) 670 { 671 auto sysTime = SysTime(d, tz); 672 assert(sysTime._stdTime == expected); 673 assert(sysTime._timezone is (tz is null ? LocalTime() : tz), format("Given Date: %s", d)); 674 } 675 676 test(Date.init, UTC(), 0); 677 test(Date(1, 1, 1), UTC(), 0); 678 test(Date(1, 1, 2), UTC(), 864000000000); 679 test(Date(0, 12, 31), UTC(), -864000000000); 680 681 static void testScope(scope ref Date d) @safe 682 { 683 auto st = SysTime(d); 684 } 685 } 686 687 /++ 688 Note: 689 Whereas the other constructors take in the given date/time, assume 690 that it's in the given time zone, and convert it to hnsecs in UTC 691 since midnight, January 1st, 1 A.D. UTC - i.e. std time - this 692 constructor takes a std time, which is specifically already in UTC, 693 so no conversion takes place. Of course, the various getter 694 properties and functions will use the given time zone's conversion 695 function to convert the results to that time zone, but no conversion 696 of the arguments to this constructor takes place. 697 698 Params: 699 stdTime = The number of hnsecs since midnight, January 1st, 1 A.D. 700 UTC. 701 tz = The $(REF TimeZone,std,datetime,timezone) to use for this 702 $(LREF SysTime). If null, 703 $(REF LocalTime,std,datetime,timezone) will be used. 704 +/ 705 this(long stdTime, return scope immutable TimeZone tz = null) return scope @safe pure nothrow 706 { 707 _stdTime = stdTime; 708 _timezone = tz is null ? LocalTime() : tz; 709 } 710 711 @safe unittest 712 { 713 static void test(long stdTime, immutable TimeZone tz) 714 { 715 auto sysTime = SysTime(stdTime, tz); 716 assert(sysTime._stdTime == stdTime); 717 assert(sysTime._timezone is (tz is null ? LocalTime() : tz), format("Given stdTime: %s", stdTime)); 718 } 719 720 foreach (stdTime; [-1234567890L, -250, 0, 250, 1235657390L]) 721 { 722 foreach (tz; testTZs) 723 test(stdTime, tz); 724 } 725 } 726 727 728 /++ 729 Params: 730 rhs = The $(LREF SysTime) to assign to this one. 731 732 Returns: The `this` of this `SysTime`. 733 +/ 734 ref SysTime opAssign()(auto ref const(SysTime) rhs) scope return @safe pure nothrow 735 { 736 _stdTime = rhs._stdTime; 737 _timezone = rhs._timezone; 738 return this; 739 } 740 741 @safe unittest 742 { 743 SysTime st; 744 st = SysTime(DateTime(2012, 12, 21, 1, 2, 3), UTC()); 745 assert(st == SysTime(DateTime(2012, 12, 21, 1, 2, 3), UTC())); 746 747 const other = SysTime(DateTime(19, 1, 7, 13, 14, 15), LocalTime()); 748 st = other; 749 assert(st == other); 750 751 version (none) // https://issues.dlang.org/show_bug.cgi?id=21175 752 static void testScope(scope ref SysTime left, const scope SysTime right) @safe 753 { 754 left = right; 755 } 756 } 757 758 759 /++ 760 Checks for equality between this $(LREF SysTime) and the given 761 $(LREF SysTime). 762 763 Note that the time zone is ignored. Only the internal 764 std times (which are in UTC) are compared. 765 +/ 766 bool opEquals()(auto ref const(SysTime) rhs) @safe const pure nothrow scope 767 { 768 return _stdTime == rhs._stdTime; 769 } 770 771 @safe unittest 772 { 773 import std.range : chain; 774 775 assert(SysTime(DateTime.init, UTC()) == SysTime(0, UTC())); 776 assert(SysTime(DateTime.init, UTC()) == SysTime(0)); 777 assert(SysTime(Date.init, UTC()) == SysTime(0)); 778 assert(SysTime(0) == SysTime(0)); 779 780 static void test(DateTime dt, immutable TimeZone tz1, immutable TimeZone tz2) 781 { 782 auto st1 = SysTime(dt); 783 st1.timezone = tz1; 784 785 auto st2 = SysTime(dt); 786 st2.timezone = tz2; 787 788 assert(st1 == st2); 789 } 790 791 foreach (tz1; testTZs) 792 { 793 foreach (tz2; testTZs) 794 { 795 foreach (dt; chain(testDateTimesBC, testDateTimesAD)) 796 test(dt, tz1, tz2); 797 } 798 } 799 800 auto st = SysTime(DateTime(1999, 7, 6, 12, 33, 30)); 801 const cst = SysTime(DateTime(1999, 7, 6, 12, 33, 30)); 802 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 33, 30)); 803 assert(st == st); 804 assert(st == cst); 805 assert(st == ist); 806 assert(cst == st); 807 assert(cst == cst); 808 assert(cst == ist); 809 assert(ist == st); 810 assert(ist == cst); 811 assert(ist == ist); 812 813 static void testScope(scope ref SysTime left, const scope SysTime right) @safe 814 { 815 assert(left == right); 816 assert(right == left); 817 } 818 } 819 820 821 /++ 822 Compares this $(LREF SysTime) with the given $(LREF SysTime). 823 824 Time zone is irrelevant when comparing $(LREF SysTime)s. 825 826 Returns: 827 $(BOOKTABLE, 828 $(TR $(TD this < rhs) $(TD < 0)) 829 $(TR $(TD this == rhs) $(TD 0)) 830 $(TR $(TD this > rhs) $(TD > 0)) 831 ) 832 +/ 833 int opCmp()(auto ref const(SysTime) rhs) @safe const pure nothrow scope 834 { 835 if (_stdTime < rhs._stdTime) 836 return -1; 837 if (_stdTime > rhs._stdTime) 838 return 1; 839 return 0; 840 } 841 842 @safe unittest 843 { 844 import std.algorithm.iteration : map; 845 import std.array : array; 846 import std.range : chain; 847 848 assert(SysTime(DateTime.init, UTC()).opCmp(SysTime(0, UTC())) == 0); 849 assert(SysTime(DateTime.init, UTC()).opCmp(SysTime(0)) == 0); 850 assert(SysTime(Date.init, UTC()).opCmp(SysTime(0)) == 0); 851 assert(SysTime(0).opCmp(SysTime(0)) == 0); 852 853 static void testEqual(SysTime st, immutable TimeZone tz1, immutable TimeZone tz2) 854 { 855 auto st1 = st; 856 st1.timezone = tz1; 857 858 auto st2 = st; 859 st2.timezone = tz2; 860 861 assert(st1.opCmp(st2) == 0); 862 } 863 864 auto sts = array(map!SysTime(chain(testDateTimesBC, testDateTimesAD))); 865 866 foreach (st; sts) 867 { 868 foreach (tz1; testTZs) 869 { 870 foreach (tz2; testTZs) 871 testEqual(st, tz1, tz2); 872 } 873 } 874 875 static void testCmp(SysTime st1, immutable TimeZone tz1, SysTime st2, immutable TimeZone tz2) 876 { 877 st1.timezone = tz1; 878 st2.timezone = tz2; 879 assert(st1.opCmp(st2) < 0); 880 assert(st2.opCmp(st1) > 0); 881 } 882 883 foreach (si, st1; sts) 884 { 885 foreach (st2; sts[si + 1 .. $]) 886 { 887 foreach (tz1; testTZs) 888 { 889 foreach (tz2; testTZs) 890 testCmp(st1, tz1, st2, tz2); 891 } 892 } 893 } 894 895 auto st = SysTime(DateTime(1999, 7, 6, 12, 33, 30)); 896 const cst = SysTime(DateTime(1999, 7, 6, 12, 33, 30)); 897 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 33, 30)); 898 assert(st.opCmp(st) == 0); 899 assert(st.opCmp(cst) == 0); 900 assert(st.opCmp(ist) == 0); 901 assert(cst.opCmp(st) == 0); 902 assert(cst.opCmp(cst) == 0); 903 assert(cst.opCmp(ist) == 0); 904 assert(ist.opCmp(st) == 0); 905 assert(ist.opCmp(cst) == 0); 906 assert(ist.opCmp(ist) == 0); 907 908 static void testScope(scope ref SysTime left, const scope SysTime right) @safe 909 { 910 assert(left < right); 911 assert(right > left); 912 } 913 } 914 915 916 /++ 917 Returns: A hash of the $(LREF SysTime). 918 +/ 919 size_t toHash() const @nogc pure nothrow @safe scope 920 { 921 static if (is(size_t == ulong)) 922 return _stdTime; 923 else 924 { 925 // MurmurHash2 926 enum ulong m = 0xc6a4a7935bd1e995UL; 927 enum ulong n = m * 16; 928 enum uint r = 47; 929 930 ulong k = _stdTime; 931 k *= m; 932 k ^= k >> r; 933 k *= m; 934 935 ulong h = n; 936 h ^= k; 937 h *= m; 938 939 return cast(size_t) h; 940 } 941 } 942 943 @safe unittest 944 { 945 assert(SysTime(0).toHash == SysTime(0).toHash); 946 assert(SysTime(DateTime(2000, 1, 1)).toHash == SysTime(DateTime(2000, 1, 1)).toHash); 947 assert(SysTime(DateTime(2000, 1, 1)).toHash != SysTime(DateTime(2000, 1, 2)).toHash); 948 949 // test that timezones aren't taken into account 950 assert(SysTime(0, LocalTime()).toHash == SysTime(0, LocalTime()).toHash); 951 assert(SysTime(0, LocalTime()).toHash == SysTime(0, UTC()).toHash); 952 assert(SysTime(DateTime(2000, 1, 1), LocalTime()).toHash == SysTime(DateTime(2000, 1, 1), LocalTime()).toHash); 953 immutable zone = new SimpleTimeZone(dur!"minutes"(60)); 954 assert(SysTime(DateTime(2000, 1, 1, 1), zone).toHash == SysTime(DateTime(2000, 1, 1), UTC()).toHash); 955 assert(SysTime(DateTime(2000, 1, 1), zone).toHash != SysTime(DateTime(2000, 1, 1), UTC()).toHash); 956 957 static void testScope(scope ref SysTime st) @safe 958 { 959 auto result = st.toHash(); 960 } 961 } 962 963 964 /++ 965 Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive 966 are B.C. 967 +/ 968 @property short year() @safe const nothrow scope 969 { 970 return (cast(Date) this).year; 971 } 972 973 @safe unittest 974 { 975 import std.range : chain; 976 static void test(SysTime sysTime, long expected) 977 { 978 assert(sysTime.year == expected, format("Value given: %s", sysTime)); 979 } 980 981 test(SysTime(0, UTC()), 1); 982 test(SysTime(1, UTC()), 1); 983 test(SysTime(-1, UTC()), 0); 984 985 foreach (year; chain(testYearsBC, testYearsAD)) 986 { 987 foreach (md; testMonthDays) 988 { 989 foreach (tod; testTODs) 990 { 991 auto dt = DateTime(Date(year, md.month, md.day), tod); 992 foreach (tz; testTZs) 993 { 994 foreach (fs; testFracSecs) 995 test(SysTime(dt, fs, tz), year); 996 } 997 } 998 } 999 } 1000 1001 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1002 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1003 assert(cst.year == 1999); 1004 assert(ist.year == 1999); 1005 1006 static void testScope(scope ref SysTime st) @safe 1007 { 1008 auto result = st.year; 1009 } 1010 } 1011 1012 /++ 1013 Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive 1014 are B.C. 1015 1016 Params: 1017 year = The year to set this $(LREF SysTime)'s year to. 1018 1019 Throws: 1020 $(REF DateTimeException,std,datetime,date) if the new year is not 1021 a leap year and the resulting date would be on February 29th. 1022 +/ 1023 @property void year(int year) @safe scope 1024 { 1025 auto hnsecs = adjTime; 1026 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 1027 1028 if (hnsecs < 0) 1029 { 1030 hnsecs += convert!("hours", "hnsecs")(24); 1031 --days; 1032 } 1033 1034 auto date = Date(cast(int) days); 1035 date.year = year; 1036 1037 immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1); 1038 adjTime = newDaysHNSecs + hnsecs; 1039 } 1040 1041 /// 1042 @safe unittest 1043 { 1044 import std.datetime.date : DateTime; 1045 1046 assert(SysTime(DateTime(1999, 7, 6, 9, 7, 5)).year == 1999); 1047 assert(SysTime(DateTime(2010, 10, 4, 0, 0, 30)).year == 2010); 1048 assert(SysTime(DateTime(-7, 4, 5, 7, 45, 2)).year == -7); 1049 } 1050 1051 @safe unittest 1052 { 1053 import std.range : chain; 1054 1055 static void test(SysTime st, int year, SysTime expected) 1056 { 1057 st.year = year; 1058 assert(st == expected); 1059 } 1060 1061 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 1062 { 1063 auto dt = cast(DateTime) st; 1064 1065 foreach (year; chain(testYearsBC, testYearsAD)) 1066 { 1067 auto e = SysTime(DateTime(year, dt.month, dt.day, dt.hour, dt.minute, dt.second), 1068 st.fracSecs, 1069 st.timezone); 1070 test(st, year, e); 1071 } 1072 } 1073 1074 foreach (fs; testFracSecs) 1075 { 1076 foreach (tz; testTZs) 1077 { 1078 foreach (tod; testTODs) 1079 { 1080 test(SysTime(DateTime(Date(1999, 2, 28), tod), fs, tz), 2000, 1081 SysTime(DateTime(Date(2000, 2, 28), tod), fs, tz)); 1082 test(SysTime(DateTime(Date(2000, 2, 28), tod), fs, tz), 1999, 1083 SysTime(DateTime(Date(1999, 2, 28), tod), fs, tz)); 1084 } 1085 1086 foreach (tod; testTODsThrown) 1087 { 1088 auto st = SysTime(DateTime(Date(2000, 2, 29), tod), fs, tz); 1089 assertThrown!DateTimeException(st.year = 1999); 1090 } 1091 } 1092 } 1093 1094 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1095 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1096 static assert(!__traits(compiles, cst.year = 7)); 1097 static assert(!__traits(compiles, ist.year = 7)); 1098 1099 static void testScope(scope ref SysTime st) @safe 1100 { 1101 st.year = 42; 1102 } 1103 } 1104 1105 /++ 1106 Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C. 1107 1108 Throws: 1109 $(REF DateTimeException,std,datetime,date) if `isAD` is true. 1110 +/ 1111 @property ushort yearBC() @safe const scope 1112 { 1113 return (cast(Date) this).yearBC; 1114 } 1115 1116 /// 1117 @safe unittest 1118 { 1119 import std.datetime.date : DateTime; 1120 1121 assert(SysTime(DateTime(0, 1, 1, 12, 30, 33)).yearBC == 1); 1122 assert(SysTime(DateTime(-1, 1, 1, 10, 7, 2)).yearBC == 2); 1123 assert(SysTime(DateTime(-100, 1, 1, 4, 59, 0)).yearBC == 101); 1124 } 1125 1126 @safe unittest 1127 { 1128 import std.exception : assertNotThrown; 1129 foreach (st; testSysTimesBC) 1130 { 1131 auto msg = format("SysTime: %s", st); 1132 assertNotThrown!DateTimeException(st.yearBC, msg); 1133 assert(st.yearBC == (st.year * -1) + 1, msg); 1134 } 1135 1136 foreach (st; [testSysTimesAD[0], testSysTimesAD[$/2], testSysTimesAD[$-1]]) 1137 assertThrown!DateTimeException(st.yearBC, format("SysTime: %s", st)); 1138 1139 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1140 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1141 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1142 st.year = 12; 1143 assert(st.year == 12); 1144 static assert(!__traits(compiles, cst.year = 12)); 1145 static assert(!__traits(compiles, ist.year = 12)); 1146 1147 static void testScope(scope ref SysTime st) @safe 1148 { 1149 auto result = st.yearBC; 1150 } 1151 } 1152 1153 1154 /++ 1155 Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C. 1156 1157 Params: 1158 year = The year B.C. to set this $(LREF SysTime)'s year to. 1159 1160 Throws: 1161 $(REF DateTimeException,std,datetime,date) if a non-positive value 1162 is given. 1163 +/ 1164 @property void yearBC(int year) @safe scope 1165 { 1166 auto hnsecs = adjTime; 1167 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 1168 1169 if (hnsecs < 0) 1170 { 1171 hnsecs += convert!("hours", "hnsecs")(24); 1172 --days; 1173 } 1174 1175 auto date = Date(cast(int) days); 1176 date.yearBC = year; 1177 1178 immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1); 1179 adjTime = newDaysHNSecs + hnsecs; 1180 } 1181 1182 @safe unittest 1183 { 1184 auto st = SysTime(DateTime(2010, 1, 1, 7, 30, 0)); 1185 st.yearBC = 1; 1186 assert(st == SysTime(DateTime(0, 1, 1, 7, 30, 0))); 1187 1188 st.yearBC = 10; 1189 assert(st == SysTime(DateTime(-9, 1, 1, 7, 30, 0))); 1190 } 1191 1192 @safe unittest 1193 { 1194 import std.range : chain; 1195 static void test(SysTime st, int year, SysTime expected) 1196 { 1197 st.yearBC = year; 1198 assert(st == expected, format("SysTime: %s", st)); 1199 } 1200 1201 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 1202 { 1203 auto dt = cast(DateTime) st; 1204 1205 foreach (year; testYearsBC) 1206 { 1207 auto e = SysTime(DateTime(year, dt.month, dt.day, dt.hour, dt.minute, dt.second), 1208 st.fracSecs, 1209 st.timezone); 1210 test(st, (year * -1) + 1, e); 1211 } 1212 } 1213 1214 foreach (st; [testSysTimesBC[0], testSysTimesBC[$ - 1], testSysTimesAD[0], testSysTimesAD[$ - 1]]) 1215 { 1216 foreach (year; testYearsBC) 1217 assertThrown!DateTimeException(st.yearBC = year); 1218 } 1219 1220 foreach (fs; testFracSecs) 1221 { 1222 foreach (tz; testTZs) 1223 { 1224 foreach (tod; testTODs) 1225 { 1226 test(SysTime(DateTime(Date(-1999, 2, 28), tod), fs, tz), 2001, 1227 SysTime(DateTime(Date(-2000, 2, 28), tod), fs, tz)); 1228 test(SysTime(DateTime(Date(-2000, 2, 28), tod), fs, tz), 2000, 1229 SysTime(DateTime(Date(-1999, 2, 28), tod), fs, tz)); 1230 } 1231 1232 foreach (tod; testTODsThrown) 1233 { 1234 auto st = SysTime(DateTime(Date(-2000, 2, 29), tod), fs, tz); 1235 assertThrown!DateTimeException(st.year = -1999); 1236 } 1237 } 1238 } 1239 1240 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1241 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1242 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1243 st.yearBC = 12; 1244 assert(st.yearBC == 12); 1245 static assert(!__traits(compiles, cst.yearBC = 12)); 1246 static assert(!__traits(compiles, ist.yearBC = 12)); 1247 1248 static void testScope(scope ref SysTime st) @safe 1249 { 1250 st.yearBC = 42; 1251 } 1252 } 1253 1254 1255 /++ 1256 Month of a Gregorian Year. 1257 +/ 1258 @property Month month() @safe const nothrow scope 1259 { 1260 return (cast(Date) this).month; 1261 } 1262 1263 /// 1264 @safe unittest 1265 { 1266 import std.datetime.date : DateTime; 1267 1268 assert(SysTime(DateTime(1999, 7, 6, 9, 7, 5)).month == 7); 1269 assert(SysTime(DateTime(2010, 10, 4, 0, 0, 30)).month == 10); 1270 assert(SysTime(DateTime(-7, 4, 5, 7, 45, 2)).month == 4); 1271 } 1272 1273 @safe unittest 1274 { 1275 import std.range : chain; 1276 1277 static void test(SysTime sysTime, Month expected) 1278 { 1279 assert(sysTime.month == expected, format("Value given: %s", sysTime)); 1280 } 1281 1282 test(SysTime(0, UTC()), Month.jan); 1283 test(SysTime(1, UTC()), Month.jan); 1284 test(SysTime(-1, UTC()), Month.dec); 1285 1286 foreach (year; chain(testYearsBC, testYearsAD)) 1287 { 1288 foreach (md; testMonthDays) 1289 { 1290 foreach (tod; testTODs) 1291 { 1292 auto dt = DateTime(Date(year, md.month, md.day), tod); 1293 foreach (fs; testFracSecs) 1294 { 1295 foreach (tz; testTZs) 1296 test(SysTime(dt, fs, tz), md.month); 1297 } 1298 } 1299 } 1300 } 1301 1302 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1303 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1304 assert(cst.month == 7); 1305 assert(ist.month == 7); 1306 1307 static void testScope(scope ref SysTime st) @safe 1308 { 1309 auto result = st.month; 1310 } 1311 } 1312 1313 1314 /++ 1315 Month of a Gregorian Year. 1316 1317 Params: 1318 month = The month to set this $(LREF SysTime)'s month to. 1319 1320 Throws: 1321 $(REF DateTimeException,std,datetime,date) if the given month is 1322 not a valid month. 1323 +/ 1324 @property void month(Month month) @safe scope 1325 { 1326 auto hnsecs = adjTime; 1327 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 1328 1329 if (hnsecs < 0) 1330 { 1331 hnsecs += convert!("hours", "hnsecs")(24); 1332 --days; 1333 } 1334 1335 auto date = Date(cast(int) days); 1336 date.month = month; 1337 1338 immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1); 1339 adjTime = newDaysHNSecs + hnsecs; 1340 } 1341 1342 @safe unittest 1343 { 1344 import std.algorithm.iteration : filter; 1345 import std.range : chain; 1346 1347 static void test(SysTime st, Month month, SysTime expected) 1348 { 1349 st.month = cast(Month) month; 1350 assert(st == expected); 1351 } 1352 1353 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 1354 { 1355 auto dt = cast(DateTime) st; 1356 1357 foreach (md; testMonthDays) 1358 { 1359 if (st.day > maxDay(dt.year, md.month)) 1360 continue; 1361 auto e = SysTime(DateTime(dt.year, md.month, dt.day, dt.hour, dt.minute, dt.second), 1362 st.fracSecs, 1363 st.timezone); 1364 test(st, md.month, e); 1365 } 1366 } 1367 1368 foreach (fs; testFracSecs) 1369 { 1370 foreach (tz; testTZs) 1371 { 1372 foreach (tod; testTODs) 1373 { 1374 foreach (year; filter!((a){return yearIsLeapYear(a);}) (chain(testYearsBC, testYearsAD))) 1375 { 1376 test(SysTime(DateTime(Date(year, 1, 29), tod), fs, tz), 1377 Month.feb, 1378 SysTime(DateTime(Date(year, 2, 29), tod), fs, tz)); 1379 } 1380 1381 foreach (year; chain(testYearsBC, testYearsAD)) 1382 { 1383 test(SysTime(DateTime(Date(year, 1, 28), tod), fs, tz), 1384 Month.feb, 1385 SysTime(DateTime(Date(year, 2, 28), tod), fs, tz)); 1386 test(SysTime(DateTime(Date(year, 7, 30), tod), fs, tz), 1387 Month.jun, 1388 SysTime(DateTime(Date(year, 6, 30), tod), fs, tz)); 1389 } 1390 } 1391 } 1392 } 1393 1394 foreach (fs; [testFracSecs[0], testFracSecs[$-1]]) 1395 { 1396 foreach (tz; testTZs) 1397 { 1398 foreach (tod; testTODsThrown) 1399 { 1400 foreach (year; [testYearsBC[$-3], testYearsBC[$-2], 1401 testYearsBC[$-2], testYearsAD[0], 1402 testYearsAD[$-2], testYearsAD[$-1]]) 1403 { 1404 auto day = yearIsLeapYear(year) ? 30 : 29; 1405 auto st1 = SysTime(DateTime(Date(year, 1, day), tod), fs, tz); 1406 assertThrown!DateTimeException(st1.month = Month.feb); 1407 1408 auto st2 = SysTime(DateTime(Date(year, 7, 31), tod), fs, tz); 1409 assertThrown!DateTimeException(st2.month = Month.jun); 1410 } 1411 } 1412 } 1413 } 1414 1415 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1416 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1417 static assert(!__traits(compiles, cst.month = Month.dec)); 1418 static assert(!__traits(compiles, ist.month = Month.dec)); 1419 1420 static void testScope(scope ref SysTime st) @safe 1421 { 1422 st.month = Month.dec; 1423 } 1424 } 1425 1426 /++ 1427 Day of a Gregorian Month. 1428 +/ 1429 @property ubyte day() @safe const nothrow scope 1430 { 1431 return (cast(Date) this).day; 1432 } 1433 1434 /// 1435 @safe unittest 1436 { 1437 import std.datetime.date : DateTime; 1438 1439 assert(SysTime(DateTime(1999, 7, 6, 9, 7, 5)).day == 6); 1440 assert(SysTime(DateTime(2010, 10, 4, 0, 0, 30)).day == 4); 1441 assert(SysTime(DateTime(-7, 4, 5, 7, 45, 2)).day == 5); 1442 } 1443 1444 @safe unittest 1445 { 1446 import std.range : chain; 1447 1448 static void test(SysTime sysTime, int expected) 1449 { 1450 assert(sysTime.day == expected, format("Value given: %s", sysTime)); 1451 } 1452 1453 test(SysTime(0, UTC()), 1); 1454 test(SysTime(1, UTC()), 1); 1455 test(SysTime(-1, UTC()), 31); 1456 1457 foreach (year; chain(testYearsBC, testYearsAD)) 1458 { 1459 foreach (md; testMonthDays) 1460 { 1461 foreach (tod; testTODs) 1462 { 1463 auto dt = DateTime(Date(year, md.month, md.day), tod); 1464 1465 foreach (tz; testTZs) 1466 { 1467 foreach (fs; testFracSecs) 1468 test(SysTime(dt, fs, tz), md.day); 1469 } 1470 } 1471 } 1472 } 1473 1474 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1475 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1476 assert(cst.day == 6); 1477 assert(ist.day == 6); 1478 1479 static void testScope(scope ref SysTime st) @safe 1480 { 1481 auto result = st.day; 1482 } 1483 } 1484 1485 1486 /++ 1487 Day of a Gregorian Month. 1488 1489 Params: 1490 day = The day of the month to set this $(LREF SysTime)'s day to. 1491 1492 Throws: 1493 $(REF DateTimeException,std,datetime,date) if the given day is not 1494 a valid day of the current month. 1495 +/ 1496 @property void day(int day) @safe scope 1497 { 1498 auto hnsecs = adjTime; 1499 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 1500 1501 if (hnsecs < 0) 1502 { 1503 hnsecs += convert!("hours", "hnsecs")(24); 1504 --days; 1505 } 1506 1507 auto date = Date(cast(int) days); 1508 date.day = day; 1509 1510 immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1); 1511 adjTime = newDaysHNSecs + hnsecs; 1512 } 1513 1514 @safe unittest 1515 { 1516 import std.range : chain; 1517 import std.traits : EnumMembers; 1518 1519 foreach (day; chain(testDays)) 1520 { 1521 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 1522 { 1523 auto dt = cast(DateTime) st; 1524 1525 if (day > maxDay(dt.year, dt.month)) 1526 continue; 1527 auto expected = SysTime(DateTime(dt.year, dt.month, day, dt.hour, dt.minute, dt.second), 1528 st.fracSecs, 1529 st.timezone); 1530 st.day = day; 1531 assert(st == expected, format("[%s] [%s]", st, expected)); 1532 } 1533 } 1534 1535 foreach (tz; testTZs) 1536 { 1537 foreach (tod; testTODs) 1538 { 1539 foreach (fs; testFracSecs) 1540 { 1541 foreach (year; chain(testYearsBC, testYearsAD)) 1542 { 1543 foreach (month; EnumMembers!Month) 1544 { 1545 auto st = SysTime(DateTime(Date(year, month, 1), tod), fs, tz); 1546 immutable max = maxDay(year, month); 1547 auto expected = SysTime(DateTime(Date(year, month, max), tod), fs, tz); 1548 1549 st.day = max; 1550 assert(st == expected, format("[%s] [%s]", st, expected)); 1551 } 1552 } 1553 } 1554 } 1555 } 1556 1557 foreach (tz; testTZs) 1558 { 1559 foreach (tod; testTODsThrown) 1560 { 1561 foreach (fs; [testFracSecs[0], testFracSecs[$-1]]) 1562 { 1563 foreach (year; [testYearsBC[$-3], testYearsBC[$-2], 1564 testYearsBC[$-2], testYearsAD[0], 1565 testYearsAD[$-2], testYearsAD[$-1]]) 1566 { 1567 foreach (month; EnumMembers!Month) 1568 { 1569 auto st = SysTime(DateTime(Date(year, month, 1), tod), fs, tz); 1570 immutable max = maxDay(year, month); 1571 1572 assertThrown!DateTimeException(st.day = max + 1); 1573 } 1574 } 1575 } 1576 } 1577 } 1578 1579 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1580 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1581 static assert(!__traits(compiles, cst.day = 27)); 1582 static assert(!__traits(compiles, ist.day = 27)); 1583 1584 static void testScope(scope ref SysTime st) @safe 1585 { 1586 st.day = 12; 1587 } 1588 } 1589 1590 1591 /++ 1592 Hours past midnight. 1593 +/ 1594 @property ubyte hour() @safe const nothrow scope 1595 { 1596 auto hnsecs = adjTime; 1597 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 1598 1599 if (hnsecs < 0) 1600 { 1601 hnsecs += convert!("hours", "hnsecs")(24); 1602 --days; 1603 } 1604 1605 return cast(ubyte) getUnitsFromHNSecs!"hours"(hnsecs); 1606 } 1607 1608 @safe unittest 1609 { 1610 import std.range : chain; 1611 1612 static void test(SysTime sysTime, int expected) 1613 { 1614 assert(sysTime.hour == expected, format("Value given: %s", sysTime)); 1615 } 1616 1617 test(SysTime(0, UTC()), 0); 1618 test(SysTime(1, UTC()), 0); 1619 test(SysTime(-1, UTC()), 23); 1620 1621 foreach (tz; testTZs) 1622 { 1623 foreach (year; chain(testYearsBC, testYearsAD)) 1624 { 1625 foreach (md; testMonthDays) 1626 { 1627 foreach (hour; testHours) 1628 { 1629 foreach (minute; testMinSecs) 1630 { 1631 foreach (second; testMinSecs) 1632 { 1633 auto dt = DateTime(Date(year, md.month, md.day), TimeOfDay(hour, minute, second)); 1634 foreach (fs; testFracSecs) 1635 test(SysTime(dt, fs, tz), hour); 1636 } 1637 } 1638 } 1639 } 1640 } 1641 } 1642 1643 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1644 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1645 assert(cst.hour == 12); 1646 assert(ist.hour == 12); 1647 1648 static void testScope(scope ref SysTime st) @safe 1649 { 1650 auto result = st.hour; 1651 } 1652 } 1653 1654 1655 /++ 1656 Hours past midnight. 1657 1658 Params: 1659 hour = The hours to set this $(LREF SysTime)'s hour to. 1660 1661 Throws: 1662 $(REF DateTimeException,std,datetime,date) if the given hour are 1663 not a valid hour of the day. 1664 +/ 1665 @property void hour(int hour) @safe scope 1666 { 1667 enforceValid!"hours"(hour); 1668 1669 auto hnsecs = adjTime; 1670 auto days = splitUnitsFromHNSecs!"days"(hnsecs); 1671 immutable daysHNSecs = convert!("days", "hnsecs")(days); 1672 immutable negative = hnsecs < 0; 1673 1674 if (negative) 1675 hnsecs += convert!("hours", "hnsecs")(24); 1676 1677 hnsecs = removeUnitsFromHNSecs!"hours"(hnsecs); 1678 hnsecs += convert!("hours", "hnsecs")(hour); 1679 1680 if (negative) 1681 hnsecs -= convert!("hours", "hnsecs")(24); 1682 1683 adjTime = daysHNSecs + hnsecs; 1684 } 1685 1686 @safe unittest 1687 { 1688 import std.range : chain; 1689 1690 foreach (hour; chain(testHours)) 1691 { 1692 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 1693 { 1694 auto dt = cast(DateTime) st; 1695 auto expected = SysTime(DateTime(dt.year, dt.month, dt.day, hour, dt.minute, dt.second), 1696 st.fracSecs, 1697 st.timezone); 1698 st.hour = hour; 1699 assert(st == expected, format("[%s] [%s]", st, expected)); 1700 } 1701 } 1702 1703 auto st = testSysTimesAD[0]; 1704 assertThrown!DateTimeException(st.hour = -1); 1705 assertThrown!DateTimeException(st.hour = 60); 1706 1707 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1708 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1709 static assert(!__traits(compiles, cst.hour = 27)); 1710 static assert(!__traits(compiles, ist.hour = 27)); 1711 1712 static void testScope(scope ref SysTime st) @safe 1713 { 1714 st.hour = 12; 1715 } 1716 } 1717 1718 1719 /++ 1720 Minutes past the current hour. 1721 +/ 1722 @property ubyte minute() @safe const nothrow scope 1723 { 1724 auto hnsecs = adjTime; 1725 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 1726 1727 if (hnsecs < 0) 1728 { 1729 hnsecs += convert!("hours", "hnsecs")(24); 1730 --days; 1731 } 1732 1733 hnsecs = removeUnitsFromHNSecs!"hours"(hnsecs); 1734 1735 return cast(ubyte) getUnitsFromHNSecs!"minutes"(hnsecs); 1736 } 1737 1738 @safe unittest 1739 { 1740 import std.range : chain; 1741 1742 static void test(SysTime sysTime, int expected) 1743 { 1744 assert(sysTime.minute == expected, format("Value given: %s", sysTime)); 1745 } 1746 1747 test(SysTime(0, UTC()), 0); 1748 test(SysTime(1, UTC()), 0); 1749 test(SysTime(-1, UTC()), 59); 1750 1751 foreach (tz; testTZs) 1752 { 1753 foreach (year; chain(testYearsBC, testYearsAD)) 1754 { 1755 foreach (md; testMonthDays) 1756 { 1757 foreach (hour; testHours) 1758 { 1759 foreach (minute; testMinSecs) 1760 { 1761 foreach (second; testMinSecs) 1762 { 1763 auto dt = DateTime(Date(year, md.month, md.day), TimeOfDay(hour, minute, second)); 1764 foreach (fs; testFracSecs) 1765 test(SysTime(dt, fs, tz), minute); 1766 } 1767 } 1768 } 1769 } 1770 } 1771 } 1772 1773 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1774 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1775 assert(cst.minute == 30); 1776 assert(ist.minute == 30); 1777 1778 static void testScope(scope ref SysTime st) @safe 1779 { 1780 auto result = st.minute; 1781 } 1782 } 1783 1784 1785 /++ 1786 Minutes past the current hour. 1787 1788 Params: 1789 minute = The minute to set this $(LREF SysTime)'s minute to. 1790 1791 Throws: 1792 $(REF DateTimeException,std,datetime,date) if the given minute are 1793 not a valid minute of an hour. 1794 +/ 1795 @property void minute(int minute) @safe scope 1796 { 1797 enforceValid!"minutes"(minute); 1798 1799 auto hnsecs = adjTime; 1800 auto days = splitUnitsFromHNSecs!"days"(hnsecs); 1801 immutable daysHNSecs = convert!("days", "hnsecs")(days); 1802 immutable negative = hnsecs < 0; 1803 1804 if (negative) 1805 hnsecs += convert!("hours", "hnsecs")(24); 1806 1807 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 1808 hnsecs = removeUnitsFromHNSecs!"minutes"(hnsecs); 1809 1810 hnsecs += convert!("hours", "hnsecs")(hour); 1811 hnsecs += convert!("minutes", "hnsecs")(minute); 1812 1813 if (negative) 1814 hnsecs -= convert!("hours", "hnsecs")(24); 1815 1816 adjTime = daysHNSecs + hnsecs; 1817 } 1818 1819 @safe unittest 1820 { 1821 import std.range : chain; 1822 1823 foreach (minute; testMinSecs) 1824 { 1825 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 1826 { 1827 auto dt = cast(DateTime) st; 1828 auto expected = SysTime(DateTime(dt.year, dt.month, dt.day, dt.hour, minute, dt.second), 1829 st.fracSecs, 1830 st.timezone); 1831 st.minute = minute; 1832 assert(st == expected, format("[%s] [%s]", st, expected)); 1833 } 1834 } 1835 1836 auto st = testSysTimesAD[0]; 1837 assertThrown!DateTimeException(st.minute = -1); 1838 assertThrown!DateTimeException(st.minute = 60); 1839 1840 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1841 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1842 static assert(!__traits(compiles, cst.minute = 27)); 1843 static assert(!__traits(compiles, ist.minute = 27)); 1844 1845 static void testScope(scope ref SysTime st) @safe 1846 { 1847 st.minute = 12; 1848 } 1849 } 1850 1851 1852 /++ 1853 Seconds past the current minute. 1854 +/ 1855 @property ubyte second() @safe const nothrow scope 1856 { 1857 auto hnsecs = adjTime; 1858 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 1859 1860 if (hnsecs < 0) 1861 { 1862 hnsecs += convert!("hours", "hnsecs")(24); 1863 --days; 1864 } 1865 1866 hnsecs = removeUnitsFromHNSecs!"hours"(hnsecs); 1867 hnsecs = removeUnitsFromHNSecs!"minutes"(hnsecs); 1868 1869 return cast(ubyte) getUnitsFromHNSecs!"seconds"(hnsecs); 1870 } 1871 1872 @safe unittest 1873 { 1874 import std.range : chain; 1875 1876 static void test(SysTime sysTime, int expected) 1877 { 1878 assert(sysTime.second == expected, format("Value given: %s", sysTime)); 1879 } 1880 1881 test(SysTime(0, UTC()), 0); 1882 test(SysTime(1, UTC()), 0); 1883 test(SysTime(-1, UTC()), 59); 1884 1885 foreach (tz; testTZs) 1886 { 1887 foreach (year; chain(testYearsBC, testYearsAD)) 1888 { 1889 foreach (md; testMonthDays) 1890 { 1891 foreach (hour; testHours) 1892 { 1893 foreach (minute; testMinSecs) 1894 { 1895 foreach (second; testMinSecs) 1896 { 1897 auto dt = DateTime(Date(year, md.month, md.day), TimeOfDay(hour, minute, second)); 1898 foreach (fs; testFracSecs) 1899 test(SysTime(dt, fs, tz), second); 1900 } 1901 } 1902 } 1903 } 1904 } 1905 } 1906 1907 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1908 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1909 assert(cst.second == 33); 1910 assert(ist.second == 33); 1911 1912 static void testScope(scope ref SysTime st) @safe 1913 { 1914 auto result = st.second; 1915 } 1916 } 1917 1918 1919 /++ 1920 Seconds past the current minute. 1921 1922 Params: 1923 second = The second to set this $(LREF SysTime)'s second to. 1924 1925 Throws: 1926 $(REF DateTimeException,std,datetime,date) if the given second are 1927 not a valid second of a minute. 1928 +/ 1929 @property void second(int second) @safe scope 1930 { 1931 enforceValid!"seconds"(second); 1932 1933 auto hnsecs = adjTime; 1934 auto days = splitUnitsFromHNSecs!"days"(hnsecs); 1935 immutable daysHNSecs = convert!("days", "hnsecs")(days); 1936 immutable negative = hnsecs < 0; 1937 1938 if (negative) 1939 hnsecs += convert!("hours", "hnsecs")(24); 1940 1941 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 1942 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 1943 hnsecs = removeUnitsFromHNSecs!"seconds"(hnsecs); 1944 1945 hnsecs += convert!("hours", "hnsecs")(hour); 1946 hnsecs += convert!("minutes", "hnsecs")(minute); 1947 hnsecs += convert!("seconds", "hnsecs")(second); 1948 1949 if (negative) 1950 hnsecs -= convert!("hours", "hnsecs")(24); 1951 1952 adjTime = daysHNSecs + hnsecs; 1953 } 1954 1955 @safe unittest 1956 { 1957 import std.range : chain; 1958 1959 foreach (second; testMinSecs) 1960 { 1961 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 1962 { 1963 auto dt = cast(DateTime) st; 1964 auto expected = SysTime(DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, second), 1965 st.fracSecs, 1966 st.timezone); 1967 st.second = second; 1968 assert(st == expected, format("[%s] [%s]", st, expected)); 1969 } 1970 } 1971 1972 auto st = testSysTimesAD[0]; 1973 assertThrown!DateTimeException(st.second = -1); 1974 assertThrown!DateTimeException(st.second = 60); 1975 1976 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1977 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1978 static assert(!__traits(compiles, cst.seconds = 27)); 1979 static assert(!__traits(compiles, ist.seconds = 27)); 1980 1981 static void testScope(scope ref SysTime st) @safe 1982 { 1983 st.second = 12; 1984 } 1985 } 1986 1987 1988 /++ 1989 Fractional seconds past the second (i.e. the portion of a 1990 $(LREF SysTime) which is less than a second). 1991 +/ 1992 @property Duration fracSecs() @safe const nothrow scope 1993 { 1994 auto hnsecs = removeUnitsFromHNSecs!"days"(adjTime); 1995 1996 if (hnsecs < 0) 1997 hnsecs += convert!("hours", "hnsecs")(24); 1998 1999 return dur!"hnsecs"(removeUnitsFromHNSecs!"seconds"(hnsecs)); 2000 } 2001 2002 /// 2003 @safe unittest 2004 { 2005 import core.time : msecs, usecs, hnsecs, nsecs; 2006 import std.datetime.date : DateTime; 2007 2008 auto dt = DateTime(1982, 4, 1, 20, 59, 22); 2009 assert(SysTime(dt, msecs(213)).fracSecs == msecs(213)); 2010 assert(SysTime(dt, usecs(5202)).fracSecs == usecs(5202)); 2011 assert(SysTime(dt, hnsecs(1234567)).fracSecs == hnsecs(1234567)); 2012 2013 // SysTime and Duration both have a precision of hnsecs (100 ns), 2014 // so nsecs are going to be truncated. 2015 assert(SysTime(dt, nsecs(123456789)).fracSecs == nsecs(123456700)); 2016 } 2017 2018 @safe unittest 2019 { 2020 import std.range : chain; 2021 import core.time; 2022 2023 assert(SysTime(0, UTC()).fracSecs == Duration.zero); 2024 assert(SysTime(1, UTC()).fracSecs == hnsecs(1)); 2025 assert(SysTime(-1, UTC()).fracSecs == hnsecs(9_999_999)); 2026 2027 foreach (tz; testTZs) 2028 { 2029 foreach (year; chain(testYearsBC, testYearsAD)) 2030 { 2031 foreach (md; testMonthDays) 2032 { 2033 foreach (hour; testHours) 2034 { 2035 foreach (minute; testMinSecs) 2036 { 2037 foreach (second; testMinSecs) 2038 { 2039 auto dt = DateTime(Date(year, md.month, md.day), TimeOfDay(hour, minute, second)); 2040 foreach (fs; testFracSecs) 2041 assert(SysTime(dt, fs, tz).fracSecs == fs); 2042 } 2043 } 2044 } 2045 } 2046 } 2047 } 2048 2049 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 2050 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 2051 assert(cst.fracSecs == Duration.zero); 2052 assert(ist.fracSecs == Duration.zero); 2053 2054 static void testScope(scope ref SysTime st) @safe 2055 { 2056 auto result = st.fracSecs; 2057 } 2058 } 2059 2060 2061 /++ 2062 Fractional seconds past the second (i.e. the portion of a 2063 $(LREF SysTime) which is less than a second). 2064 2065 Params: 2066 fracSecs = The duration to set this $(LREF SysTime)'s fractional 2067 seconds to. 2068 2069 Throws: 2070 $(REF DateTimeException,std,datetime,date) if the given duration 2071 is negative or if it's greater than or equal to one second. 2072 +/ 2073 @property void fracSecs(Duration fracSecs) @safe scope 2074 { 2075 enforce(fracSecs >= Duration.zero, new DateTimeException("A SysTime cannot have negative fractional seconds.")); 2076 enforce(fracSecs < seconds(1), new DateTimeException("Fractional seconds must be less than one second.")); 2077 2078 auto oldHNSecs = adjTime; 2079 auto days = splitUnitsFromHNSecs!"days"(oldHNSecs); 2080 immutable daysHNSecs = convert!("days", "hnsecs")(days); 2081 immutable negative = oldHNSecs < 0; 2082 2083 if (negative) 2084 oldHNSecs += convert!("hours", "hnsecs")(24); 2085 2086 immutable seconds = splitUnitsFromHNSecs!"seconds"(oldHNSecs); 2087 immutable secondsHNSecs = convert!("seconds", "hnsecs")(seconds); 2088 auto newHNSecs = fracSecs.total!"hnsecs" + secondsHNSecs; 2089 2090 if (negative) 2091 newHNSecs -= convert!("hours", "hnsecs")(24); 2092 2093 adjTime = daysHNSecs + newHNSecs; 2094 } 2095 2096 /// 2097 @safe unittest 2098 { 2099 import core.time : Duration, msecs, hnsecs, nsecs; 2100 import std.datetime.date : DateTime; 2101 2102 auto st = SysTime(DateTime(1982, 4, 1, 20, 59, 22)); 2103 assert(st.fracSecs == Duration.zero); 2104 2105 st.fracSecs = msecs(213); 2106 assert(st.fracSecs == msecs(213)); 2107 2108 st.fracSecs = hnsecs(1234567); 2109 assert(st.fracSecs == hnsecs(1234567)); 2110 2111 // SysTime has a precision of hnsecs (100 ns), so nsecs are 2112 // going to be truncated. 2113 st.fracSecs = nsecs(123456789); 2114 assert(st.fracSecs == hnsecs(1234567)); 2115 } 2116 2117 @safe unittest 2118 { 2119 import std.range : chain; 2120 import core.time; 2121 2122 foreach (fracSec; testFracSecs) 2123 { 2124 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 2125 { 2126 auto dt = cast(DateTime) st; 2127 auto expected = SysTime(dt, fracSec, st.timezone); 2128 st.fracSecs = fracSec; 2129 assert(st == expected, format("[%s] [%s]", st, expected)); 2130 } 2131 } 2132 2133 auto st = testSysTimesAD[0]; 2134 assertThrown!DateTimeException(st.fracSecs = hnsecs(-1)); 2135 assertThrown!DateTimeException(st.fracSecs = seconds(1)); 2136 2137 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 2138 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 2139 static assert(!__traits(compiles, cst.fracSecs = msecs(7))); 2140 static assert(!__traits(compiles, ist.fracSecs = msecs(7))); 2141 2142 static void testScope(scope ref SysTime st) @safe 2143 { 2144 st.fracSecs = Duration.zero; 2145 } 2146 } 2147 2148 2149 /++ 2150 The total hnsecs from midnight, January 1st, 1 A.D. UTC. This is the 2151 internal representation of $(LREF SysTime). 2152 +/ 2153 @property long stdTime() @safe const pure nothrow scope @nogc 2154 { 2155 return _stdTime; 2156 } 2157 2158 @safe unittest 2159 { 2160 import core.time; 2161 assert(SysTime(0).stdTime == 0); 2162 assert(SysTime(1).stdTime == 1); 2163 assert(SysTime(-1).stdTime == -1); 2164 assert(SysTime(DateTime(1, 1, 1, 0, 0, 33), hnsecs(502), UTC()).stdTime == 330_000_502L); 2165 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 0), UTC()).stdTime == 621_355_968_000_000_000L); 2166 2167 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 2168 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 2169 assert(cst.stdTime > 0); 2170 assert(ist.stdTime > 0); 2171 2172 static void testScope(scope ref SysTime st) @safe 2173 { 2174 auto result = st.stdTime; 2175 } 2176 } 2177 2178 2179 /++ 2180 The total hnsecs from midnight, January 1st, 1 A.D. UTC. This is the 2181 internal representation of $(LREF SysTime). 2182 2183 Params: 2184 stdTime = The number of hnsecs since January 1st, 1 A.D. UTC. 2185 +/ 2186 @property void stdTime(long stdTime) @safe pure nothrow scope 2187 { 2188 _stdTime = stdTime; 2189 } 2190 2191 @safe unittest 2192 { 2193 import core.time; 2194 static void test(long stdTime, SysTime expected, size_t line = __LINE__) 2195 { 2196 auto st = SysTime(0, UTC()); 2197 st.stdTime = stdTime; 2198 assert(st == expected); 2199 } 2200 2201 test(0, SysTime(Date(1, 1, 1), UTC())); 2202 test(1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC())); 2203 test(-1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC())); 2204 test(330_000_502L, SysTime(DateTime(1, 1, 1, 0, 0, 33), hnsecs(502), UTC())); 2205 test(621_355_968_000_000_000L, SysTime(DateTime(1970, 1, 1, 0, 0, 0), UTC())); 2206 2207 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 2208 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 2209 static assert(!__traits(compiles, cst.stdTime = 27)); 2210 static assert(!__traits(compiles, ist.stdTime = 27)); 2211 2212 static void testScope(scope ref SysTime st) @safe 2213 { 2214 st.stdTime = 42; 2215 } 2216 } 2217 2218 2219 /++ 2220 The current time zone of this $(LREF SysTime). Its internal time is 2221 always kept in UTC, so there are no conversion issues between time zones 2222 due to DST. Functions which return all or part of the time - such as 2223 hours - adjust the time to this $(LREF SysTime)'s time zone before 2224 returning. 2225 +/ 2226 @property immutable(TimeZone) timezone() @safe const pure nothrow return scope 2227 { 2228 return _timezone; 2229 } 2230 2231 @safe unittest 2232 { 2233 assert(SysTime.init.timezone is InitTimeZone()); 2234 assert(SysTime(DateTime.init, UTC()).timezone is UTC()); 2235 2236 static void testScope(scope ref SysTime st) @safe 2237 { 2238 auto result = st.timezone; 2239 } 2240 } 2241 2242 2243 /++ 2244 The current time zone of this $(LREF SysTime). It's internal time is 2245 always kept in UTC, so there are no conversion issues between time zones 2246 due to DST. Functions which return all or part of the time - such as 2247 hours - adjust the time to this $(LREF SysTime)'s time zone before 2248 returning. 2249 2250 Params: 2251 timezone = The $(REF _TimeZone,std,datetime,_timezone) to set this 2252 $(LREF SysTime)'s time zone to. 2253 +/ 2254 @property void timezone(immutable TimeZone timezone) @safe pure nothrow scope 2255 { 2256 if (timezone is null) 2257 _timezone = LocalTime(); 2258 else 2259 _timezone = timezone; 2260 } 2261 2262 @safe unittest 2263 { 2264 SysTime st; 2265 st.timezone = null; 2266 assert(st.timezone is LocalTime()); 2267 st.timezone = UTC(); 2268 assert(st.timezone is UTC()); 2269 2270 static void testScope(scope ref SysTime st) @safe 2271 { 2272 st.timezone = UTC(); 2273 } 2274 } 2275 2276 2277 /++ 2278 Returns whether DST is in effect for this $(LREF SysTime). 2279 +/ 2280 @property bool dstInEffect() @safe const nothrow return scope 2281 { 2282 return _timezone.dstInEffect(_stdTime); 2283 } 2284 2285 // This function's full unit testing is done in the time zone classes, but 2286 // this verifies that SysTime.init works correctly, since historically, it 2287 // has segfaulted due to a null _timezone. 2288 @safe unittest 2289 { 2290 assert(!SysTime.init.dstInEffect); 2291 2292 static void testScope(scope ref SysTime st) @safe 2293 { 2294 auto result = st.dstInEffect; 2295 } 2296 } 2297 2298 2299 /++ 2300 Returns what the offset from UTC is for this $(LREF SysTime). 2301 It includes the DST offset in effect at that time (if any). 2302 +/ 2303 @property Duration utcOffset() @safe const nothrow return scope 2304 { 2305 return _timezone.utcOffsetAt(_stdTime); 2306 } 2307 2308 // This function's full unit testing is done in the time zone classes, but 2309 // this verifies that SysTime.init works correctly, since historically, it 2310 // has segfaulted due to a null _timezone. 2311 @safe unittest 2312 { 2313 assert(SysTime.init.utcOffset == Duration.zero); 2314 2315 static void testScope(scope ref SysTime st) @safe 2316 { 2317 auto result = st.utcOffset; 2318 } 2319 } 2320 2321 2322 /++ 2323 Returns a $(LREF SysTime) with the same std time as this one, but with 2324 $(REF LocalTime,std,datetime,timezone) as its time zone. 2325 +/ 2326 SysTime toLocalTime() @safe const pure nothrow scope 2327 { 2328 return SysTime(_stdTime, LocalTime()); 2329 } 2330 2331 @safe unittest 2332 { 2333 import core.time; 2334 { 2335 auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), hnsecs(27)); 2336 assert(sysTime == sysTime.toLocalTime()); 2337 assert(sysTime._stdTime == sysTime.toLocalTime()._stdTime); 2338 assert(sysTime.toLocalTime().timezone is LocalTime()); 2339 assert(sysTime.toLocalTime().timezone is sysTime.timezone); 2340 assert(sysTime.toLocalTime().timezone !is UTC()); 2341 } 2342 2343 { 2344 auto stz = new immutable SimpleTimeZone(dur!"minutes"(-3 * 60)); 2345 auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), hnsecs(27), stz); 2346 assert(sysTime == sysTime.toLocalTime()); 2347 assert(sysTime._stdTime == sysTime.toLocalTime()._stdTime); 2348 assert(sysTime.toLocalTime().timezone is LocalTime()); 2349 assert(sysTime.toLocalTime().timezone !is UTC()); 2350 assert(sysTime.toLocalTime().timezone !is stz); 2351 } 2352 2353 static void testScope(scope ref SysTime st) @safe 2354 { 2355 auto result = st.toLocalTime(); 2356 } 2357 } 2358 2359 2360 /++ 2361 Returns a $(LREF SysTime) with the same std time as this one, but with 2362 `UTC` as its time zone. 2363 +/ 2364 SysTime toUTC() @safe const pure nothrow scope 2365 { 2366 return SysTime(_stdTime, UTC()); 2367 } 2368 2369 @safe unittest 2370 { 2371 import core.time; 2372 auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), hnsecs(27)); 2373 assert(sysTime == sysTime.toUTC()); 2374 assert(sysTime._stdTime == sysTime.toUTC()._stdTime); 2375 assert(sysTime.toUTC().timezone is UTC()); 2376 assert(sysTime.toUTC().timezone !is LocalTime()); 2377 assert(sysTime.toUTC().timezone !is sysTime.timezone); 2378 2379 static void testScope(scope ref SysTime st) @safe 2380 { 2381 auto result = st.toUTC(); 2382 } 2383 } 2384 2385 2386 /++ 2387 Returns a $(LREF SysTime) with the same std time as this one, but with 2388 given time zone as its time zone. 2389 +/ 2390 SysTime toOtherTZ(immutable TimeZone tz) @safe const pure nothrow scope 2391 { 2392 if (tz is null) 2393 return SysTime(_stdTime, LocalTime()); 2394 else 2395 return SysTime(_stdTime, tz); 2396 } 2397 2398 @safe unittest 2399 { 2400 import core.time; 2401 auto stz = new immutable SimpleTimeZone(dur!"minutes"(11 * 60)); 2402 auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), hnsecs(27)); 2403 assert(sysTime == sysTime.toOtherTZ(stz)); 2404 assert(sysTime._stdTime == sysTime.toOtherTZ(stz)._stdTime); 2405 assert(sysTime.toOtherTZ(stz).timezone is stz); 2406 assert(sysTime.toOtherTZ(stz).timezone !is LocalTime()); 2407 assert(sysTime.toOtherTZ(stz).timezone !is UTC()); 2408 assert(sysTime.toOtherTZ(null).timezone is LocalTime()); 2409 2410 static void testScope(scope ref SysTime st) @safe 2411 { 2412 auto result = st.toOtherTZ(null); 2413 } 2414 } 2415 2416 2417 /++ 2418 Converts this $(LREF SysTime) to unix time (i.e. seconds from midnight, 2419 January 1st, 1970 in UTC). 2420 2421 The C standard does not specify the representation of time_t, so it is 2422 implementation defined. On POSIX systems, unix time is equivalent to 2423 time_t, but that's not necessarily true on other systems (e.g. it is 2424 not true for the Digital Mars C runtime). So, be careful when using unix 2425 time with C functions on non-POSIX systems. 2426 2427 By default, the return type is time_t (which is normally an alias for 2428 int on 32-bit systems and long on 64-bit systems), but if a different 2429 size is required than either int or long can be passed as a template 2430 argument to get the desired size. 2431 2432 If the return type is int, and the result can't fit in an int, then the 2433 closest value that can be held in 32 bits will be used (so `int.max` 2434 if it goes over and `int.min` if it goes under). However, no attempt 2435 is made to deal with integer overflow if the return type is long. 2436 2437 Params: 2438 T = The return type (int or long). It defaults to time_t, which is 2439 normally 32 bits on a 32-bit system and 64 bits on a 64-bit 2440 system. 2441 2442 Returns: 2443 A signed integer representing the unix time which is equivalent to 2444 this SysTime. 2445 +/ 2446 T toUnixTime(T = time_t)() @safe const pure nothrow scope 2447 if (is(T == int) || is(T == long)) 2448 { 2449 return stdTimeToUnixTime!T(_stdTime); 2450 } 2451 2452 /// 2453 @safe unittest 2454 { 2455 import core.time : hours; 2456 import std.datetime.date : DateTime; 2457 import std.datetime.timezone : SimpleTimeZone, UTC; 2458 2459 assert(SysTime(DateTime(1970, 1, 1), UTC()).toUnixTime() == 0); 2460 2461 auto pst = new immutable SimpleTimeZone(hours(-8)); 2462 assert(SysTime(DateTime(1970, 1, 1), pst).toUnixTime() == 28800); 2463 2464 auto utc = SysTime(DateTime(2007, 12, 22, 8, 14, 45), UTC()); 2465 assert(utc.toUnixTime() == 1_198_311_285); 2466 2467 auto ca = SysTime(DateTime(2007, 12, 22, 8, 14, 45), pst); 2468 assert(ca.toUnixTime() == 1_198_340_085); 2469 2470 static void testScope(scope ref SysTime st) @safe 2471 { 2472 auto result = st.toUnixTime(); 2473 } 2474 } 2475 2476 @safe unittest 2477 { 2478 import std.meta : AliasSeq; 2479 import core.time; 2480 assert(SysTime(DateTime(1970, 1, 1), UTC()).toUnixTime() == 0); 2481 static foreach (units; ["hnsecs", "usecs", "msecs"]) 2482 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 0), dur!units(1), UTC()).toUnixTime() == 0); 2483 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), UTC()).toUnixTime() == 1); 2484 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toUnixTime() == 0); 2485 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999_999), UTC()).toUnixTime() == 0); 2486 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), msecs(999), UTC()).toUnixTime() == 0); 2487 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), UTC()).toUnixTime() == -1); 2488 } 2489 2490 2491 /++ 2492 Converts from unix time (i.e. seconds from midnight, January 1st, 1970 2493 in UTC) to a $(LREF SysTime). 2494 2495 The C standard does not specify the representation of time_t, so it is 2496 implementation defined. On POSIX systems, unix time is equivalent to 2497 time_t, but that's not necessarily true on other systems (e.g. it is 2498 not true for the Digital Mars C runtime). So, be careful when using unix 2499 time with C functions on non-POSIX systems. 2500 2501 Params: 2502 unixTime = Seconds from midnight, January 1st, 1970 in UTC. 2503 tz = The time zone for the SysTime that's returned. 2504 +/ 2505 static SysTime fromUnixTime(long unixTime, immutable TimeZone tz = LocalTime()) @safe pure nothrow 2506 { 2507 return SysTime(unixTimeToStdTime(unixTime), tz); 2508 } 2509 2510 /// 2511 @safe unittest 2512 { 2513 import core.time : hours; 2514 import std.datetime.date : DateTime; 2515 import std.datetime.timezone : SimpleTimeZone, UTC; 2516 2517 assert(SysTime.fromUnixTime(0) == 2518 SysTime(DateTime(1970, 1, 1), UTC())); 2519 2520 auto pst = new immutable SimpleTimeZone(hours(-8)); 2521 assert(SysTime.fromUnixTime(28800) == 2522 SysTime(DateTime(1970, 1, 1), pst)); 2523 2524 auto st1 = SysTime.fromUnixTime(1_198_311_285, UTC()); 2525 assert(st1 == SysTime(DateTime(2007, 12, 22, 8, 14, 45), UTC())); 2526 assert(st1.timezone is UTC()); 2527 assert(st1 == SysTime(DateTime(2007, 12, 22, 0, 14, 45), pst)); 2528 2529 auto st2 = SysTime.fromUnixTime(1_198_311_285, pst); 2530 assert(st2 == SysTime(DateTime(2007, 12, 22, 8, 14, 45), UTC())); 2531 assert(st2.timezone is pst); 2532 assert(st2 == SysTime(DateTime(2007, 12, 22, 0, 14, 45), pst)); 2533 } 2534 2535 @safe unittest 2536 { 2537 import core.time; 2538 assert(SysTime.fromUnixTime(0) == SysTime(DateTime(1970, 1, 1), UTC())); 2539 assert(SysTime.fromUnixTime(1) == SysTime(DateTime(1970, 1, 1, 0, 0, 1), UTC())); 2540 assert(SysTime.fromUnixTime(-1) == SysTime(DateTime(1969, 12, 31, 23, 59, 59), UTC())); 2541 2542 auto st = SysTime.fromUnixTime(0); 2543 auto dt = cast(DateTime) st; 2544 assert(dt <= DateTime(1970, 2, 1) && dt >= DateTime(1969, 12, 31)); 2545 assert(st.timezone is LocalTime()); 2546 2547 auto aest = new immutable SimpleTimeZone(hours(10)); 2548 assert(SysTime.fromUnixTime(-36000) == SysTime(DateTime(1970, 1, 1), aest)); 2549 } 2550 2551 2552 /++ 2553 Returns a `timeval` which represents this $(LREF SysTime). 2554 2555 Note that like all conversions in std.datetime, this is a truncating 2556 conversion. 2557 2558 If `timeval.tv_sec` is int, and the result can't fit in an int, then 2559 the closest value that can be held in 32 bits will be used for 2560 `tv_sec`. (so `int.max` if it goes over and `int.min` if it 2561 goes under). 2562 +/ 2563 timeval toTimeVal() @safe const pure nothrow scope 2564 { 2565 immutable tv_sec = toUnixTime!(typeof(timeval.tv_sec))(); 2566 immutable fracHNSecs = removeUnitsFromHNSecs!"seconds"(_stdTime - 621_355_968_000_000_000L); 2567 immutable tv_usec = cast(typeof(timeval.tv_usec))convert!("hnsecs", "usecs")(fracHNSecs); 2568 return timeval(tv_sec, tv_usec); 2569 } 2570 2571 @safe unittest 2572 { 2573 import core.time; 2574 assert(SysTime(DateTime(1970, 1, 1), UTC()).toTimeVal() == timeval(0, 0)); 2575 assert(SysTime(DateTime(1970, 1, 1), hnsecs(9), UTC()).toTimeVal() == timeval(0, 0)); 2576 assert(SysTime(DateTime(1970, 1, 1), hnsecs(10), UTC()).toTimeVal() == timeval(0, 1)); 2577 assert(SysTime(DateTime(1970, 1, 1), usecs(7), UTC()).toTimeVal() == timeval(0, 7)); 2578 2579 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), UTC()).toTimeVal() == timeval(1, 0)); 2580 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), hnsecs(9), UTC()).toTimeVal() == timeval(1, 0)); 2581 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), hnsecs(10), UTC()).toTimeVal() == timeval(1, 1)); 2582 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), usecs(7), UTC()).toTimeVal() == timeval(1, 7)); 2583 2584 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toTimeVal() == timeval(0, 0)); 2585 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_990), UTC()).toTimeVal() == timeval(0, -1)); 2586 2587 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999_999), UTC()).toTimeVal() == timeval(0, -1)); 2588 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999), UTC()).toTimeVal() == timeval(0, -999_001)); 2589 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), msecs(999), UTC()).toTimeVal() == timeval(0, -1000)); 2590 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), UTC()).toTimeVal() == timeval(-1, 0)); 2591 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 58), usecs(17), UTC()).toTimeVal() == timeval(-1, -999_983)); 2592 2593 static void testScope(scope ref SysTime st) @safe 2594 { 2595 auto result = st.toTimeVal(); 2596 } 2597 } 2598 2599 2600 version (StdDdoc) 2601 { 2602 version (Windows) private struct timespec {} 2603 /++ 2604 Returns a `timespec` which represents this $(LREF SysTime). 2605 2606 $(BLUE This function is Posix-Only.) 2607 +/ 2608 timespec toTimeSpec() @safe const pure nothrow scope; 2609 } 2610 else version (Posix) 2611 { 2612 timespec toTimeSpec() @safe const pure nothrow scope 2613 { 2614 immutable tv_sec = toUnixTime!(typeof(timespec.tv_sec))(); 2615 immutable fracHNSecs = removeUnitsFromHNSecs!"seconds"(_stdTime - 621_355_968_000_000_000L); 2616 immutable tv_nsec = cast(typeof(timespec.tv_nsec))convert!("hnsecs", "nsecs")(fracHNSecs); 2617 return timespec(tv_sec, tv_nsec); 2618 } 2619 2620 @safe unittest 2621 { 2622 import core.time; 2623 assert(SysTime(DateTime(1970, 1, 1), UTC()).toTimeSpec() == timespec(0, 0)); 2624 assert(SysTime(DateTime(1970, 1, 1), hnsecs(9), UTC()).toTimeSpec() == timespec(0, 900)); 2625 assert(SysTime(DateTime(1970, 1, 1), hnsecs(10), UTC()).toTimeSpec() == timespec(0, 1000)); 2626 assert(SysTime(DateTime(1970, 1, 1), usecs(7), UTC()).toTimeSpec() == timespec(0, 7000)); 2627 2628 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), UTC()).toTimeSpec() == timespec(1, 0)); 2629 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), hnsecs(9), UTC()).toTimeSpec() == timespec(1, 900)); 2630 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), hnsecs(10), UTC()).toTimeSpec() == timespec(1, 1000)); 2631 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), usecs(7), UTC()).toTimeSpec() == timespec(1, 7000)); 2632 2633 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toTimeSpec() == 2634 timespec(0, -100)); 2635 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_990), UTC()).toTimeSpec() == 2636 timespec(0, -1000)); 2637 2638 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999_999), UTC()).toTimeSpec() == 2639 timespec(0, -1_000)); 2640 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999), UTC()).toTimeSpec() == 2641 timespec(0, -999_001_000)); 2642 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), msecs(999), UTC()).toTimeSpec() == 2643 timespec(0, -1_000_000)); 2644 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), UTC()).toTimeSpec() == 2645 timespec(-1, 0)); 2646 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 58), usecs(17), UTC()).toTimeSpec() == 2647 timespec(-1, -999_983_000)); 2648 2649 static void testScope(scope ref SysTime st) @safe 2650 { 2651 auto result = st.toTimeSpec(); 2652 } 2653 } 2654 } 2655 2656 /++ 2657 Returns a `tm` which represents this $(LREF SysTime). 2658 +/ 2659 tm toTM() @safe const nothrow scope 2660 { 2661 auto dateTime = cast(DateTime) this; 2662 tm timeInfo; 2663 2664 timeInfo.tm_sec = dateTime.second; 2665 timeInfo.tm_min = dateTime.minute; 2666 timeInfo.tm_hour = dateTime.hour; 2667 timeInfo.tm_mday = dateTime.day; 2668 timeInfo.tm_mon = dateTime.month - 1; 2669 timeInfo.tm_year = dateTime.year - 1900; 2670 timeInfo.tm_wday = dateTime.dayOfWeek; 2671 timeInfo.tm_yday = dateTime.dayOfYear - 1; 2672 timeInfo.tm_isdst = _timezone.dstInEffect(_stdTime); 2673 2674 version (Posix) 2675 { 2676 import std.utf : toUTFz; 2677 timeInfo.tm_gmtoff = cast(int) convert!("hnsecs", "seconds")(adjTime - _stdTime); 2678 auto zone = timeInfo.tm_isdst ? _timezone.dstName : _timezone.stdName; 2679 timeInfo.tm_zone = zone.toUTFz!(char*)(); 2680 } 2681 2682 return timeInfo; 2683 } 2684 2685 @system unittest 2686 { 2687 import std.conv : to; 2688 import core.time; 2689 2690 version (Posix) 2691 { 2692 import std.datetime.timezone : clearTZEnvVar, setTZEnvVar; 2693 setTZEnvVar("America/Los_Angeles"); 2694 scope(exit) clearTZEnvVar(); 2695 } 2696 2697 { 2698 auto timeInfo = SysTime(DateTime(1970, 1, 1)).toTM(); 2699 2700 assert(timeInfo.tm_sec == 0); 2701 assert(timeInfo.tm_min == 0); 2702 assert(timeInfo.tm_hour == 0); 2703 assert(timeInfo.tm_mday == 1); 2704 assert(timeInfo.tm_mon == 0); 2705 assert(timeInfo.tm_year == 70); 2706 assert(timeInfo.tm_wday == 4); 2707 assert(timeInfo.tm_yday == 0); 2708 2709 version (Posix) 2710 assert(timeInfo.tm_isdst == 0); 2711 else version (Windows) 2712 assert(timeInfo.tm_isdst == 0 || timeInfo.tm_isdst == 1); 2713 2714 version (Posix) 2715 { 2716 assert(timeInfo.tm_gmtoff == -8 * 60 * 60); 2717 assert(to!string(timeInfo.tm_zone) == "PST"); 2718 } 2719 } 2720 2721 { 2722 auto timeInfo = SysTime(DateTime(2010, 7, 4, 12, 15, 7), hnsecs(15)).toTM(); 2723 2724 assert(timeInfo.tm_sec == 7); 2725 assert(timeInfo.tm_min == 15); 2726 assert(timeInfo.tm_hour == 12); 2727 assert(timeInfo.tm_mday == 4); 2728 assert(timeInfo.tm_mon == 6); 2729 assert(timeInfo.tm_year == 110); 2730 assert(timeInfo.tm_wday == 0); 2731 assert(timeInfo.tm_yday == 184); 2732 2733 version (Posix) 2734 assert(timeInfo.tm_isdst == 1); 2735 else version (Windows) 2736 assert(timeInfo.tm_isdst == 0 || timeInfo.tm_isdst == 1); 2737 2738 version (Posix) 2739 { 2740 assert(timeInfo.tm_gmtoff == -7 * 60 * 60); 2741 assert(to!string(timeInfo.tm_zone) == "PDT"); 2742 } 2743 } 2744 2745 // This is more to verify that SysTime.init.toTM() doesn't segfault and 2746 // does something sane rather than that the value is anything 2747 // particularly useful. 2748 { 2749 auto timeInfo = SysTime.init.toTM(); 2750 2751 assert(timeInfo.tm_sec == 0); 2752 assert(timeInfo.tm_min == 0); 2753 assert(timeInfo.tm_hour == 0); 2754 assert(timeInfo.tm_mday == 1); 2755 assert(timeInfo.tm_mon == 0); 2756 assert(timeInfo.tm_year == -1899); 2757 assert(timeInfo.tm_wday == 1); 2758 assert(timeInfo.tm_yday == 0); 2759 assert(timeInfo.tm_isdst == 0); 2760 2761 version (Posix) 2762 { 2763 assert(timeInfo.tm_gmtoff == 0); 2764 assert(to!string(timeInfo.tm_zone) == "SysTime.init's timezone"); 2765 } 2766 } 2767 2768 static void testScope(scope ref SysTime st) @safe 2769 { 2770 auto result = st.toTM(); 2771 } 2772 } 2773 2774 2775 /++ 2776 Adds the given number of years or months to this $(LREF SysTime). A 2777 negative number will subtract. 2778 2779 Note that if day overflow is allowed, and the date with the adjusted 2780 year/month overflows the number of days in the new month, then the month 2781 will be incremented by one, and the day set to the number of days 2782 overflowed. (e.g. if the day were 31 and the new month were June, then 2783 the month would be incremented to July, and the new day would be 1). If 2784 day overflow is not allowed, then the day will be set to the last valid 2785 day in the month (e.g. June 31st would become June 30th). 2786 2787 Params: 2788 units = The type of units to add ("years" or "months"). 2789 value = The number of months or years to add to this 2790 $(LREF SysTime). 2791 allowOverflow = Whether the days should be allowed to overflow, 2792 causing the month to increment. 2793 +/ 2794 ref SysTime add(string units)(long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe nothrow scope 2795 if (units == "years" || units == "months") 2796 { 2797 auto hnsecs = adjTime; 2798 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 2799 2800 if (hnsecs < 0) 2801 { 2802 hnsecs += convert!("hours", "hnsecs")(24); 2803 --days; 2804 } 2805 2806 auto date = Date(cast(int) days); 2807 date.add!units(value, allowOverflow); 2808 days = date.dayOfGregorianCal - 1; 2809 2810 if (days < 0) 2811 { 2812 hnsecs -= convert!("hours", "hnsecs")(24); 2813 ++days; 2814 } 2815 2816 immutable newDaysHNSecs = convert!("days", "hnsecs")(days); 2817 2818 adjTime = newDaysHNSecs + hnsecs; 2819 2820 return this; 2821 } 2822 2823 @safe unittest 2824 { 2825 auto st1 = SysTime(DateTime(2010, 1, 1, 12, 30, 33)); 2826 st1.add!"months"(11); 2827 assert(st1 == SysTime(DateTime(2010, 12, 1, 12, 30, 33))); 2828 2829 auto st2 = SysTime(DateTime(2010, 1, 1, 12, 30, 33)); 2830 st2.add!"months"(-11); 2831 assert(st2 == SysTime(DateTime(2009, 2, 1, 12, 30, 33))); 2832 2833 auto st3 = SysTime(DateTime(2000, 2, 29, 12, 30, 33)); 2834 st3.add!"years"(1); 2835 assert(st3 == SysTime(DateTime(2001, 3, 1, 12, 30, 33))); 2836 2837 auto st4 = SysTime(DateTime(2000, 2, 29, 12, 30, 33)); 2838 st4.add!"years"(1, AllowDayOverflow.no); 2839 assert(st4 == SysTime(DateTime(2001, 2, 28, 12, 30, 33))); 2840 } 2841 2842 // Test add!"years"() with AllowDayOverflow.yes 2843 @safe unittest 2844 { 2845 import core.time; 2846 // Test A.D. 2847 { 2848 auto sysTime = SysTime(Date(1999, 7, 6)); 2849 sysTime.add!"years"(7); 2850 assert(sysTime == SysTime(Date(2006, 7, 6))); 2851 sysTime.add!"years"(-9); 2852 assert(sysTime == SysTime(Date(1997, 7, 6))); 2853 } 2854 2855 { 2856 auto sysTime = SysTime(Date(1999, 2, 28)); 2857 sysTime.add!"years"(1); 2858 assert(sysTime == SysTime(Date(2000, 2, 28))); 2859 } 2860 2861 { 2862 auto sysTime = SysTime(Date(2000, 2, 29)); 2863 sysTime.add!"years"(-1); 2864 assert(sysTime == SysTime(Date(1999, 3, 1))); 2865 } 2866 2867 { 2868 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 7, 3), msecs(234)); 2869 sysTime.add!"years"(7); 2870 assert(sysTime == SysTime(DateTime(2006, 7, 6, 12, 7, 3), msecs(234))); 2871 sysTime.add!"years"(-9); 2872 assert(sysTime == SysTime(DateTime(1997, 7, 6, 12, 7, 3), msecs(234))); 2873 } 2874 2875 { 2876 auto sysTime = SysTime(DateTime(1999, 2, 28, 0, 7, 2), usecs(1207)); 2877 sysTime.add!"years"(1); 2878 assert(sysTime == SysTime(DateTime(2000, 2, 28, 0, 7, 2), usecs(1207))); 2879 } 2880 2881 { 2882 auto sysTime = SysTime(DateTime(2000, 2, 29, 0, 7, 2), usecs(1207)); 2883 sysTime.add!"years"(-1); 2884 assert(sysTime == SysTime(DateTime(1999, 3, 1, 0, 7, 2), usecs(1207))); 2885 } 2886 2887 // Test B.C. 2888 { 2889 auto sysTime = SysTime(Date(-1999, 7, 6)); 2890 sysTime.add!"years"(-7); 2891 assert(sysTime == SysTime(Date(-2006, 7, 6))); 2892 sysTime.add!"years"(9); 2893 assert(sysTime == SysTime(Date(-1997, 7, 6))); 2894 } 2895 2896 { 2897 auto sysTime = SysTime(Date(-1999, 2, 28)); 2898 sysTime.add!"years"(-1); 2899 assert(sysTime == SysTime(Date(-2000, 2, 28))); 2900 } 2901 2902 { 2903 auto sysTime = SysTime(Date(-2000, 2, 29)); 2904 sysTime.add!"years"(1); 2905 assert(sysTime == SysTime(Date(-1999, 3, 1))); 2906 } 2907 2908 { 2909 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 7, 3), msecs(234)); 2910 sysTime.add!"years"(-7); 2911 assert(sysTime == SysTime(DateTime(-2006, 7, 6, 12, 7, 3), msecs(234))); 2912 sysTime.add!"years"(9); 2913 assert(sysTime == SysTime(DateTime(-1997, 7, 6, 12, 7, 3), msecs(234))); 2914 } 2915 2916 { 2917 auto sysTime = SysTime(DateTime(-1999, 2, 28, 3, 3, 3), hnsecs(3)); 2918 sysTime.add!"years"(-1); 2919 assert(sysTime == SysTime(DateTime(-2000, 2, 28, 3, 3, 3), hnsecs(3))); 2920 } 2921 2922 { 2923 auto sysTime = SysTime(DateTime(-2000, 2, 29, 3, 3, 3), hnsecs(3)); 2924 sysTime.add!"years"(1); 2925 assert(sysTime == SysTime(DateTime(-1999, 3, 1, 3, 3, 3), hnsecs(3))); 2926 } 2927 2928 // Test Both 2929 { 2930 auto sysTime = SysTime(Date(4, 7, 6)); 2931 sysTime.add!"years"(-5); 2932 assert(sysTime == SysTime(Date(-1, 7, 6))); 2933 sysTime.add!"years"(5); 2934 assert(sysTime == SysTime(Date(4, 7, 6))); 2935 } 2936 2937 { 2938 auto sysTime = SysTime(Date(-4, 7, 6)); 2939 sysTime.add!"years"(5); 2940 assert(sysTime == SysTime(Date(1, 7, 6))); 2941 sysTime.add!"years"(-5); 2942 assert(sysTime == SysTime(Date(-4, 7, 6))); 2943 } 2944 2945 { 2946 auto sysTime = SysTime(Date(4, 7, 6)); 2947 sysTime.add!"years"(-8); 2948 assert(sysTime == SysTime(Date(-4, 7, 6))); 2949 sysTime.add!"years"(8); 2950 assert(sysTime == SysTime(Date(4, 7, 6))); 2951 } 2952 2953 { 2954 auto sysTime = SysTime(Date(-4, 7, 6)); 2955 sysTime.add!"years"(8); 2956 assert(sysTime == SysTime(Date(4, 7, 6))); 2957 sysTime.add!"years"(-8); 2958 assert(sysTime == SysTime(Date(-4, 7, 6))); 2959 } 2960 2961 { 2962 auto sysTime = SysTime(Date(-4, 2, 29)); 2963 sysTime.add!"years"(5); 2964 assert(sysTime == SysTime(Date(1, 3, 1))); 2965 } 2966 2967 { 2968 auto sysTime = SysTime(Date(4, 2, 29)); 2969 sysTime.add!"years"(-5); 2970 assert(sysTime == SysTime(Date(-1, 3, 1))); 2971 } 2972 2973 { 2974 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 2975 sysTime.add!"years"(-1); 2976 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0))); 2977 sysTime.add!"years"(1); 2978 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 2979 } 2980 2981 { 2982 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 2983 sysTime.add!"years"(-1); 2984 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 2985 sysTime.add!"years"(1); 2986 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 2987 } 2988 2989 { 2990 auto sysTime = SysTime(DateTime(0, 1, 1, 0, 0, 0)); 2991 sysTime.add!"years"(1); 2992 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 2993 sysTime.add!"years"(-1); 2994 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0))); 2995 } 2996 2997 { 2998 auto sysTime = SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 2999 sysTime.add!"years"(1); 3000 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3001 sysTime.add!"years"(-1); 3002 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3003 } 3004 3005 { 3006 auto sysTime = SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329)); 3007 sysTime.add!"years"(-5); 3008 assert(sysTime == SysTime(DateTime(-1, 7, 6, 14, 7, 1), usecs(54329))); 3009 sysTime.add!"years"(5); 3010 assert(sysTime == SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329))); 3011 } 3012 3013 { 3014 auto sysTime = SysTime(DateTime(-4, 7, 6, 14, 7, 1), usecs(54329)); 3015 sysTime.add!"years"(5); 3016 assert(sysTime == SysTime(DateTime(1, 7, 6, 14, 7, 1), usecs(54329))); 3017 sysTime.add!"years"(-5); 3018 assert(sysTime == SysTime(DateTime(-4, 7, 6, 14, 7, 1), usecs(54329))); 3019 } 3020 3021 { 3022 auto sysTime = SysTime(DateTime(-4, 2, 29, 5, 5, 5), msecs(555)); 3023 sysTime.add!"years"(5); 3024 assert(sysTime == SysTime(DateTime(1, 3, 1, 5, 5, 5), msecs(555))); 3025 } 3026 3027 { 3028 auto sysTime = SysTime(DateTime(4, 2, 29, 5, 5, 5), msecs(555)); 3029 sysTime.add!"years"(-5); 3030 assert(sysTime == SysTime(DateTime(-1, 3, 1, 5, 5, 5), msecs(555))); 3031 } 3032 3033 { 3034 auto sysTime = SysTime(DateTime(4, 2, 29, 5, 5, 5), msecs(555)); 3035 sysTime.add!"years"(-5).add!"years"(7); 3036 assert(sysTime == SysTime(DateTime(6, 3, 1, 5, 5, 5), msecs(555))); 3037 } 3038 3039 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 3040 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 3041 static assert(!__traits(compiles, cst.add!"years"(4))); 3042 static assert(!__traits(compiles, ist.add!"years"(4))); 3043 3044 static void testScope(scope ref SysTime st) @safe 3045 { 3046 auto result = st.add!"years"(42); 3047 } 3048 } 3049 3050 // Test add!"years"() with AllowDayOverflow.no 3051 @safe unittest 3052 { 3053 import core.time; 3054 // Test A.D. 3055 { 3056 auto sysTime = SysTime(Date(1999, 7, 6)); 3057 sysTime.add!"years"(7, AllowDayOverflow.no); 3058 assert(sysTime == SysTime(Date(2006, 7, 6))); 3059 sysTime.add!"years"(-9, AllowDayOverflow.no); 3060 assert(sysTime == SysTime(Date(1997, 7, 6))); 3061 } 3062 3063 { 3064 auto sysTime = SysTime(Date(1999, 2, 28)); 3065 sysTime.add!"years"(1, AllowDayOverflow.no); 3066 assert(sysTime == SysTime(Date(2000, 2, 28))); 3067 } 3068 3069 { 3070 auto sysTime = SysTime(Date(2000, 2, 29)); 3071 sysTime.add!"years"(-1, AllowDayOverflow.no); 3072 assert(sysTime == SysTime(Date(1999, 2, 28))); 3073 } 3074 3075 { 3076 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 7, 3), msecs(234)); 3077 sysTime.add!"years"(7, AllowDayOverflow.no); 3078 assert(sysTime == SysTime(DateTime(2006, 7, 6, 12, 7, 3), msecs(234))); 3079 sysTime.add!"years"(-9, AllowDayOverflow.no); 3080 assert(sysTime == SysTime(DateTime(1997, 7, 6, 12, 7, 3), msecs(234))); 3081 } 3082 3083 { 3084 auto sysTime = SysTime(DateTime(1999, 2, 28, 0, 7, 2), usecs(1207)); 3085 sysTime.add!"years"(1, AllowDayOverflow.no); 3086 assert(sysTime == SysTime(DateTime(2000, 2, 28, 0, 7, 2), usecs(1207))); 3087 } 3088 3089 { 3090 auto sysTime = SysTime(DateTime(2000, 2, 29, 0, 7, 2), usecs(1207)); 3091 sysTime.add!"years"(-1, AllowDayOverflow.no); 3092 assert(sysTime == SysTime(DateTime(1999, 2, 28, 0, 7, 2), usecs(1207))); 3093 } 3094 3095 // Test B.C. 3096 { 3097 auto sysTime = SysTime(Date(-1999, 7, 6)); 3098 sysTime.add!"years"(-7, AllowDayOverflow.no); 3099 assert(sysTime == SysTime(Date(-2006, 7, 6))); 3100 sysTime.add!"years"(9, AllowDayOverflow.no); 3101 assert(sysTime == SysTime(Date(-1997, 7, 6))); 3102 } 3103 3104 { 3105 auto sysTime = SysTime(Date(-1999, 2, 28)); 3106 sysTime.add!"years"(-1, AllowDayOverflow.no); 3107 assert(sysTime == SysTime(Date(-2000, 2, 28))); 3108 } 3109 3110 { 3111 auto sysTime = SysTime(Date(-2000, 2, 29)); 3112 sysTime.add!"years"(1, AllowDayOverflow.no); 3113 assert(sysTime == SysTime(Date(-1999, 2, 28))); 3114 } 3115 3116 { 3117 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 7, 3), msecs(234)); 3118 sysTime.add!"years"(-7, AllowDayOverflow.no); 3119 assert(sysTime == SysTime(DateTime(-2006, 7, 6, 12, 7, 3), msecs(234))); 3120 sysTime.add!"years"(9, AllowDayOverflow.no); 3121 assert(sysTime == SysTime(DateTime(-1997, 7, 6, 12, 7, 3), msecs(234))); 3122 } 3123 3124 { 3125 auto sysTime = SysTime(DateTime(-1999, 2, 28, 3, 3, 3), hnsecs(3)); 3126 sysTime.add!"years"(-1, AllowDayOverflow.no); 3127 assert(sysTime == SysTime(DateTime(-2000, 2, 28, 3, 3, 3), hnsecs(3))); 3128 } 3129 3130 { 3131 auto sysTime = SysTime(DateTime(-2000, 2, 29, 3, 3, 3), hnsecs(3)); 3132 sysTime.add!"years"(1, AllowDayOverflow.no); 3133 assert(sysTime == SysTime(DateTime(-1999, 2, 28, 3, 3, 3), hnsecs(3))); 3134 } 3135 3136 // Test Both 3137 { 3138 auto sysTime = SysTime(Date(4, 7, 6)); 3139 sysTime.add!"years"(-5, AllowDayOverflow.no); 3140 assert(sysTime == SysTime(Date(-1, 7, 6))); 3141 sysTime.add!"years"(5, AllowDayOverflow.no); 3142 assert(sysTime == SysTime(Date(4, 7, 6))); 3143 } 3144 3145 { 3146 auto sysTime = SysTime(Date(-4, 7, 6)); 3147 sysTime.add!"years"(5, AllowDayOverflow.no); 3148 assert(sysTime == SysTime(Date(1, 7, 6))); 3149 sysTime.add!"years"(-5, AllowDayOverflow.no); 3150 assert(sysTime == SysTime(Date(-4, 7, 6))); 3151 } 3152 3153 { 3154 auto sysTime = SysTime(Date(4, 7, 6)); 3155 sysTime.add!"years"(-8, AllowDayOverflow.no); 3156 assert(sysTime == SysTime(Date(-4, 7, 6))); 3157 sysTime.add!"years"(8, AllowDayOverflow.no); 3158 assert(sysTime == SysTime(Date(4, 7, 6))); 3159 } 3160 3161 { 3162 auto sysTime = SysTime(Date(-4, 7, 6)); 3163 sysTime.add!"years"(8, AllowDayOverflow.no); 3164 assert(sysTime == SysTime(Date(4, 7, 6))); 3165 sysTime.add!"years"(-8, AllowDayOverflow.no); 3166 assert(sysTime == SysTime(Date(-4, 7, 6))); 3167 } 3168 3169 { 3170 auto sysTime = SysTime(Date(-4, 2, 29)); 3171 sysTime.add!"years"(5, AllowDayOverflow.no); 3172 assert(sysTime == SysTime(Date(1, 2, 28))); 3173 } 3174 3175 { 3176 auto sysTime = SysTime(Date(4, 2, 29)); 3177 sysTime.add!"years"(-5, AllowDayOverflow.no); 3178 assert(sysTime == SysTime(Date(-1, 2, 28))); 3179 } 3180 3181 { 3182 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 3183 sysTime.add!"years"(-1, AllowDayOverflow.no); 3184 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0))); 3185 sysTime.add!"years"(1, AllowDayOverflow.no); 3186 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 3187 } 3188 3189 { 3190 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 3191 sysTime.add!"years"(-1, AllowDayOverflow.no); 3192 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3193 sysTime.add!"years"(1, AllowDayOverflow.no); 3194 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3195 } 3196 3197 { 3198 auto sysTime = SysTime(DateTime(0, 1, 1, 0, 0, 0)); 3199 sysTime.add!"years"(1, AllowDayOverflow.no); 3200 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 3201 sysTime.add!"years"(-1, AllowDayOverflow.no); 3202 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0))); 3203 } 3204 3205 { 3206 auto sysTime = SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 3207 sysTime.add!"years"(1, AllowDayOverflow.no); 3208 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3209 sysTime.add!"years"(-1, AllowDayOverflow.no); 3210 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3211 } 3212 3213 { 3214 auto sysTime = SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329)); 3215 sysTime.add!"years"(-5); 3216 assert(sysTime == SysTime(DateTime(-1, 7, 6, 14, 7, 1), usecs(54329))); 3217 sysTime.add!"years"(5); 3218 assert(sysTime == SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329))); 3219 } 3220 3221 { 3222 auto sysTime = SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329)); 3223 sysTime.add!"years"(-5, AllowDayOverflow.no); 3224 assert(sysTime == SysTime(DateTime(-1, 7, 6, 14, 7, 1), usecs(54329))); 3225 sysTime.add!"years"(5, AllowDayOverflow.no); 3226 assert(sysTime == SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329))); 3227 } 3228 3229 { 3230 auto sysTime = SysTime(DateTime(-4, 7, 6, 14, 7, 1), usecs(54329)); 3231 sysTime.add!"years"(5, AllowDayOverflow.no); 3232 assert(sysTime == SysTime(DateTime(1, 7, 6, 14, 7, 1), usecs(54329))); 3233 sysTime.add!"years"(-5, AllowDayOverflow.no); 3234 assert(sysTime == SysTime(DateTime(-4, 7, 6, 14, 7, 1), usecs(54329))); 3235 } 3236 3237 { 3238 auto sysTime = SysTime(DateTime(-4, 2, 29, 5, 5, 5), msecs(555)); 3239 sysTime.add!"years"(5, AllowDayOverflow.no); 3240 assert(sysTime == SysTime(DateTime(1, 2, 28, 5, 5, 5), msecs(555))); 3241 } 3242 3243 { 3244 auto sysTime = SysTime(DateTime(4, 2, 29, 5, 5, 5), msecs(555)); 3245 sysTime.add!"years"(-5, AllowDayOverflow.no); 3246 assert(sysTime == SysTime(DateTime(-1, 2, 28, 5, 5, 5), msecs(555))); 3247 } 3248 3249 { 3250 auto sysTime = SysTime(DateTime(4, 2, 29, 5, 5, 5), msecs(555)); 3251 sysTime.add!"years"(-5, AllowDayOverflow.no).add!"years"(7, AllowDayOverflow.no); 3252 assert(sysTime == SysTime(DateTime(6, 2, 28, 5, 5, 5), msecs(555))); 3253 } 3254 } 3255 3256 // Test add!"months"() with AllowDayOverflow.yes 3257 @safe unittest 3258 { 3259 import core.time; 3260 // Test A.D. 3261 { 3262 auto sysTime = SysTime(Date(1999, 7, 6)); 3263 sysTime.add!"months"(3); 3264 assert(sysTime == SysTime(Date(1999, 10, 6))); 3265 sysTime.add!"months"(-4); 3266 assert(sysTime == SysTime(Date(1999, 6, 6))); 3267 } 3268 3269 { 3270 auto sysTime = SysTime(Date(1999, 7, 6)); 3271 sysTime.add!"months"(6); 3272 assert(sysTime == SysTime(Date(2000, 1, 6))); 3273 sysTime.add!"months"(-6); 3274 assert(sysTime == SysTime(Date(1999, 7, 6))); 3275 } 3276 3277 { 3278 auto sysTime = SysTime(Date(1999, 7, 6)); 3279 sysTime.add!"months"(27); 3280 assert(sysTime == SysTime(Date(2001, 10, 6))); 3281 sysTime.add!"months"(-28); 3282 assert(sysTime == SysTime(Date(1999, 6, 6))); 3283 } 3284 3285 { 3286 auto sysTime = SysTime(Date(1999, 5, 31)); 3287 sysTime.add!"months"(1); 3288 assert(sysTime == SysTime(Date(1999, 7, 1))); 3289 } 3290 3291 { 3292 auto sysTime = SysTime(Date(1999, 5, 31)); 3293 sysTime.add!"months"(-1); 3294 assert(sysTime == SysTime(Date(1999, 5, 1))); 3295 } 3296 3297 { 3298 auto sysTime = SysTime(Date(1999, 2, 28)); 3299 sysTime.add!"months"(12); 3300 assert(sysTime == SysTime(Date(2000, 2, 28))); 3301 } 3302 3303 { 3304 auto sysTime = SysTime(Date(2000, 2, 29)); 3305 sysTime.add!"months"(12); 3306 assert(sysTime == SysTime(Date(2001, 3, 1))); 3307 } 3308 3309 { 3310 auto sysTime = SysTime(Date(1999, 7, 31)); 3311 sysTime.add!"months"(1); 3312 assert(sysTime == SysTime(Date(1999, 8, 31))); 3313 sysTime.add!"months"(1); 3314 assert(sysTime == SysTime(Date(1999, 10, 1))); 3315 } 3316 3317 { 3318 auto sysTime = SysTime(Date(1998, 8, 31)); 3319 sysTime.add!"months"(13); 3320 assert(sysTime == SysTime(Date(1999, 10, 1))); 3321 sysTime.add!"months"(-13); 3322 assert(sysTime == SysTime(Date(1998, 9, 1))); 3323 } 3324 3325 { 3326 auto sysTime = SysTime(Date(1997, 12, 31)); 3327 sysTime.add!"months"(13); 3328 assert(sysTime == SysTime(Date(1999, 1, 31))); 3329 sysTime.add!"months"(-13); 3330 assert(sysTime == SysTime(Date(1997, 12, 31))); 3331 } 3332 3333 { 3334 auto sysTime = SysTime(Date(1997, 12, 31)); 3335 sysTime.add!"months"(14); 3336 assert(sysTime == SysTime(Date(1999, 3, 3))); 3337 sysTime.add!"months"(-14); 3338 assert(sysTime == SysTime(Date(1998, 1, 3))); 3339 } 3340 3341 { 3342 auto sysTime = SysTime(Date(1998, 12, 31)); 3343 sysTime.add!"months"(14); 3344 assert(sysTime == SysTime(Date(2000, 3, 2))); 3345 sysTime.add!"months"(-14); 3346 assert(sysTime == SysTime(Date(1999, 1, 2))); 3347 } 3348 3349 { 3350 auto sysTime = SysTime(Date(1999, 12, 31)); 3351 sysTime.add!"months"(14); 3352 assert(sysTime == SysTime(Date(2001, 3, 3))); 3353 sysTime.add!"months"(-14); 3354 assert(sysTime == SysTime(Date(2000, 1, 3))); 3355 } 3356 3357 { 3358 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), usecs(5007)); 3359 sysTime.add!"months"(3); 3360 assert(sysTime == SysTime(DateTime(1999, 10, 6, 12, 2, 7), usecs(5007))); 3361 sysTime.add!"months"(-4); 3362 assert(sysTime == SysTime(DateTime(1999, 6, 6, 12, 2, 7), usecs(5007))); 3363 } 3364 3365 { 3366 auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), hnsecs(422202)); 3367 sysTime.add!"months"(14); 3368 assert(sysTime == SysTime(DateTime(2000, 3, 2, 7, 7, 7), hnsecs(422202))); 3369 sysTime.add!"months"(-14); 3370 assert(sysTime == SysTime(DateTime(1999, 1, 2, 7, 7, 7), hnsecs(422202))); 3371 } 3372 3373 { 3374 auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), hnsecs(422202)); 3375 sysTime.add!"months"(14); 3376 assert(sysTime == SysTime(DateTime(2001, 3, 3, 7, 7, 7), hnsecs(422202))); 3377 sysTime.add!"months"(-14); 3378 assert(sysTime == SysTime(DateTime(2000, 1, 3, 7, 7, 7), hnsecs(422202))); 3379 } 3380 3381 // Test B.C. 3382 { 3383 auto sysTime = SysTime(Date(-1999, 7, 6)); 3384 sysTime.add!"months"(3); 3385 assert(sysTime == SysTime(Date(-1999, 10, 6))); 3386 sysTime.add!"months"(-4); 3387 assert(sysTime == SysTime(Date(-1999, 6, 6))); 3388 } 3389 3390 { 3391 auto sysTime = SysTime(Date(-1999, 7, 6)); 3392 sysTime.add!"months"(6); 3393 assert(sysTime == SysTime(Date(-1998, 1, 6))); 3394 sysTime.add!"months"(-6); 3395 assert(sysTime == SysTime(Date(-1999, 7, 6))); 3396 } 3397 3398 { 3399 auto sysTime = SysTime(Date(-1999, 7, 6)); 3400 sysTime.add!"months"(-27); 3401 assert(sysTime == SysTime(Date(-2001, 4, 6))); 3402 sysTime.add!"months"(28); 3403 assert(sysTime == SysTime(Date(-1999, 8, 6))); 3404 } 3405 3406 { 3407 auto sysTime = SysTime(Date(-1999, 5, 31)); 3408 sysTime.add!"months"(1); 3409 assert(sysTime == SysTime(Date(-1999, 7, 1))); 3410 } 3411 3412 { 3413 auto sysTime = SysTime(Date(-1999, 5, 31)); 3414 sysTime.add!"months"(-1); 3415 assert(sysTime == SysTime(Date(-1999, 5, 1))); 3416 } 3417 3418 { 3419 auto sysTime = SysTime(Date(-1999, 2, 28)); 3420 sysTime.add!"months"(-12); 3421 assert(sysTime == SysTime(Date(-2000, 2, 28))); 3422 } 3423 3424 { 3425 auto sysTime = SysTime(Date(-2000, 2, 29)); 3426 sysTime.add!"months"(-12); 3427 assert(sysTime == SysTime(Date(-2001, 3, 1))); 3428 } 3429 3430 { 3431 auto sysTime = SysTime(Date(-1999, 7, 31)); 3432 sysTime.add!"months"(1); 3433 assert(sysTime == SysTime(Date(-1999, 8, 31))); 3434 sysTime.add!"months"(1); 3435 assert(sysTime == SysTime(Date(-1999, 10, 1))); 3436 } 3437 3438 { 3439 auto sysTime = SysTime(Date(-1998, 8, 31)); 3440 sysTime.add!"months"(13); 3441 assert(sysTime == SysTime(Date(-1997, 10, 1))); 3442 sysTime.add!"months"(-13); 3443 assert(sysTime == SysTime(Date(-1998, 9, 1))); 3444 } 3445 3446 { 3447 auto sysTime = SysTime(Date(-1997, 12, 31)); 3448 sysTime.add!"months"(13); 3449 assert(sysTime == SysTime(Date(-1995, 1, 31))); 3450 sysTime.add!"months"(-13); 3451 assert(sysTime == SysTime(Date(-1997, 12, 31))); 3452 } 3453 3454 { 3455 auto sysTime = SysTime(Date(-1997, 12, 31)); 3456 sysTime.add!"months"(14); 3457 assert(sysTime == SysTime(Date(-1995, 3, 3))); 3458 sysTime.add!"months"(-14); 3459 assert(sysTime == SysTime(Date(-1996, 1, 3))); 3460 } 3461 3462 { 3463 auto sysTime = SysTime(Date(-2002, 12, 31)); 3464 sysTime.add!"months"(14); 3465 assert(sysTime == SysTime(Date(-2000, 3, 2))); 3466 sysTime.add!"months"(-14); 3467 assert(sysTime == SysTime(Date(-2001, 1, 2))); 3468 } 3469 3470 { 3471 auto sysTime = SysTime(Date(-2001, 12, 31)); 3472 sysTime.add!"months"(14); 3473 assert(sysTime == SysTime(Date(-1999, 3, 3))); 3474 sysTime.add!"months"(-14); 3475 assert(sysTime == SysTime(Date(-2000, 1, 3))); 3476 } 3477 3478 { 3479 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), usecs(5007)); 3480 sysTime.add!"months"(3); 3481 assert(sysTime == SysTime(DateTime(-1999, 10, 6, 12, 2, 7), usecs(5007))); 3482 sysTime.add!"months"(-4); 3483 assert(sysTime == SysTime(DateTime(-1999, 6, 6, 12, 2, 7), usecs(5007))); 3484 } 3485 3486 { 3487 auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), hnsecs(422202)); 3488 sysTime.add!"months"(14); 3489 assert(sysTime == SysTime(DateTime(-2000, 3, 2, 7, 7, 7), hnsecs(422202))); 3490 sysTime.add!"months"(-14); 3491 assert(sysTime == SysTime(DateTime(-2001, 1, 2, 7, 7, 7), hnsecs(422202))); 3492 } 3493 3494 { 3495 auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), hnsecs(422202)); 3496 sysTime.add!"months"(14); 3497 assert(sysTime == SysTime(DateTime(-1999, 3, 3, 7, 7, 7), hnsecs(422202))); 3498 sysTime.add!"months"(-14); 3499 assert(sysTime == SysTime(DateTime(-2000, 1, 3, 7, 7, 7), hnsecs(422202))); 3500 } 3501 3502 // Test Both 3503 { 3504 auto sysTime = SysTime(Date(1, 1, 1)); 3505 sysTime.add!"months"(-1); 3506 assert(sysTime == SysTime(Date(0, 12, 1))); 3507 sysTime.add!"months"(1); 3508 assert(sysTime == SysTime(Date(1, 1, 1))); 3509 } 3510 3511 { 3512 auto sysTime = SysTime(Date(4, 1, 1)); 3513 sysTime.add!"months"(-48); 3514 assert(sysTime == SysTime(Date(0, 1, 1))); 3515 sysTime.add!"months"(48); 3516 assert(sysTime == SysTime(Date(4, 1, 1))); 3517 } 3518 3519 { 3520 auto sysTime = SysTime(Date(4, 3, 31)); 3521 sysTime.add!"months"(-49); 3522 assert(sysTime == SysTime(Date(0, 3, 2))); 3523 sysTime.add!"months"(49); 3524 assert(sysTime == SysTime(Date(4, 4, 2))); 3525 } 3526 3527 { 3528 auto sysTime = SysTime(Date(4, 3, 31)); 3529 sysTime.add!"months"(-85); 3530 assert(sysTime == SysTime(Date(-3, 3, 3))); 3531 sysTime.add!"months"(85); 3532 assert(sysTime == SysTime(Date(4, 4, 3))); 3533 } 3534 3535 { 3536 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 3537 sysTime.add!"months"(-1); 3538 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 3539 sysTime.add!"months"(1); 3540 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 3541 } 3542 3543 { 3544 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 3545 sysTime.add!"months"(-1); 3546 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 3547 sysTime.add!"months"(1); 3548 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3549 } 3550 3551 { 3552 auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0)); 3553 sysTime.add!"months"(1); 3554 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 3555 sysTime.add!"months"(-1); 3556 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 3557 } 3558 3559 { 3560 auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)); 3561 sysTime.add!"months"(1); 3562 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3563 sysTime.add!"months"(-1); 3564 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 3565 } 3566 3567 { 3568 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17)); 3569 sysTime.add!"months"(-1); 3570 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 7, 9), hnsecs(17))); 3571 sysTime.add!"months"(1); 3572 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17))); 3573 } 3574 3575 { 3576 auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), msecs(9)); 3577 sysTime.add!"months"(-85); 3578 assert(sysTime == SysTime(DateTime(-3, 3, 3, 12, 11, 10), msecs(9))); 3579 sysTime.add!"months"(85); 3580 assert(sysTime == SysTime(DateTime(4, 4, 3, 12, 11, 10), msecs(9))); 3581 } 3582 3583 { 3584 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 3585 sysTime.add!"months"(85); 3586 assert(sysTime == SysTime(DateTime(4, 5, 1, 12, 11, 10), msecs(9))); 3587 sysTime.add!"months"(-85); 3588 assert(sysTime == SysTime(DateTime(-3, 4, 1, 12, 11, 10), msecs(9))); 3589 } 3590 3591 { 3592 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 3593 sysTime.add!"months"(85).add!"months"(-83); 3594 assert(sysTime == SysTime(DateTime(-3, 6, 1, 12, 11, 10), msecs(9))); 3595 } 3596 3597 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 3598 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 3599 static assert(!__traits(compiles, cst.add!"months"(4))); 3600 static assert(!__traits(compiles, ist.add!"months"(4))); 3601 3602 static void testScope(scope ref SysTime st) @safe 3603 { 3604 auto result = st.add!"months"(42); 3605 } 3606 } 3607 3608 // Test add!"months"() with AllowDayOverflow.no 3609 @safe unittest 3610 { 3611 import core.time; 3612 // Test A.D. 3613 { 3614 auto sysTime = SysTime(Date(1999, 7, 6)); 3615 sysTime.add!"months"(3, AllowDayOverflow.no); 3616 assert(sysTime == SysTime(Date(1999, 10, 6))); 3617 sysTime.add!"months"(-4, AllowDayOverflow.no); 3618 assert(sysTime == SysTime(Date(1999, 6, 6))); 3619 } 3620 3621 { 3622 auto sysTime = SysTime(Date(1999, 7, 6)); 3623 sysTime.add!"months"(6, AllowDayOverflow.no); 3624 assert(sysTime == SysTime(Date(2000, 1, 6))); 3625 sysTime.add!"months"(-6, AllowDayOverflow.no); 3626 assert(sysTime == SysTime(Date(1999, 7, 6))); 3627 } 3628 3629 { 3630 auto sysTime = SysTime(Date(1999, 7, 6)); 3631 sysTime.add!"months"(27, AllowDayOverflow.no); 3632 assert(sysTime == SysTime(Date(2001, 10, 6))); 3633 sysTime.add!"months"(-28, AllowDayOverflow.no); 3634 assert(sysTime == SysTime(Date(1999, 6, 6))); 3635 } 3636 3637 { 3638 auto sysTime = SysTime(Date(1999, 5, 31)); 3639 sysTime.add!"months"(1, AllowDayOverflow.no); 3640 assert(sysTime == SysTime(Date(1999, 6, 30))); 3641 } 3642 3643 { 3644 auto sysTime = SysTime(Date(1999, 5, 31)); 3645 sysTime.add!"months"(-1, AllowDayOverflow.no); 3646 assert(sysTime == SysTime(Date(1999, 4, 30))); 3647 } 3648 3649 { 3650 auto sysTime = SysTime(Date(1999, 2, 28)); 3651 sysTime.add!"months"(12, AllowDayOverflow.no); 3652 assert(sysTime == SysTime(Date(2000, 2, 28))); 3653 } 3654 3655 { 3656 auto sysTime = SysTime(Date(2000, 2, 29)); 3657 sysTime.add!"months"(12, AllowDayOverflow.no); 3658 assert(sysTime == SysTime(Date(2001, 2, 28))); 3659 } 3660 3661 { 3662 auto sysTime = SysTime(Date(1999, 7, 31)); 3663 sysTime.add!"months"(1, AllowDayOverflow.no); 3664 assert(sysTime == SysTime(Date(1999, 8, 31))); 3665 sysTime.add!"months"(1, AllowDayOverflow.no); 3666 assert(sysTime == SysTime(Date(1999, 9, 30))); 3667 } 3668 3669 { 3670 auto sysTime = SysTime(Date(1998, 8, 31)); 3671 sysTime.add!"months"(13, AllowDayOverflow.no); 3672 assert(sysTime == SysTime(Date(1999, 9, 30))); 3673 sysTime.add!"months"(-13, AllowDayOverflow.no); 3674 assert(sysTime == SysTime(Date(1998, 8, 30))); 3675 } 3676 3677 { 3678 auto sysTime = SysTime(Date(1997, 12, 31)); 3679 sysTime.add!"months"(13, AllowDayOverflow.no); 3680 assert(sysTime == SysTime(Date(1999, 1, 31))); 3681 sysTime.add!"months"(-13, AllowDayOverflow.no); 3682 assert(sysTime == SysTime(Date(1997, 12, 31))); 3683 } 3684 3685 { 3686 auto sysTime = SysTime(Date(1997, 12, 31)); 3687 sysTime.add!"months"(14, AllowDayOverflow.no); 3688 assert(sysTime == SysTime(Date(1999, 2, 28))); 3689 sysTime.add!"months"(-14, AllowDayOverflow.no); 3690 assert(sysTime == SysTime(Date(1997, 12, 28))); 3691 } 3692 3693 { 3694 auto sysTime = SysTime(Date(1998, 12, 31)); 3695 sysTime.add!"months"(14, AllowDayOverflow.no); 3696 assert(sysTime == SysTime(Date(2000, 2, 29))); 3697 sysTime.add!"months"(-14, AllowDayOverflow.no); 3698 assert(sysTime == SysTime(Date(1998, 12, 29))); 3699 } 3700 3701 { 3702 auto sysTime = SysTime(Date(1999, 12, 31)); 3703 sysTime.add!"months"(14, AllowDayOverflow.no); 3704 assert(sysTime == SysTime(Date(2001, 2, 28))); 3705 sysTime.add!"months"(-14, AllowDayOverflow.no); 3706 assert(sysTime == SysTime(Date(1999, 12, 28))); 3707 } 3708 3709 { 3710 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), usecs(5007)); 3711 sysTime.add!"months"(3, AllowDayOverflow.no); 3712 assert(sysTime == SysTime(DateTime(1999, 10, 6, 12, 2, 7), usecs(5007))); 3713 sysTime.add!"months"(-4, AllowDayOverflow.no); 3714 assert(sysTime == SysTime(DateTime(1999, 6, 6, 12, 2, 7), usecs(5007))); 3715 } 3716 3717 { 3718 auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), hnsecs(422202)); 3719 sysTime.add!"months"(14, AllowDayOverflow.no); 3720 assert(sysTime == SysTime(DateTime(2000, 2, 29, 7, 7, 7), hnsecs(422202))); 3721 sysTime.add!"months"(-14, AllowDayOverflow.no); 3722 assert(sysTime == SysTime(DateTime(1998, 12, 29, 7, 7, 7), hnsecs(422202))); 3723 } 3724 3725 { 3726 auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), hnsecs(422202)); 3727 sysTime.add!"months"(14, AllowDayOverflow.no); 3728 assert(sysTime == SysTime(DateTime(2001, 2, 28, 7, 7, 7), hnsecs(422202))); 3729 sysTime.add!"months"(-14, AllowDayOverflow.no); 3730 assert(sysTime == SysTime(DateTime(1999, 12, 28, 7, 7, 7), hnsecs(422202))); 3731 } 3732 3733 // Test B.C. 3734 { 3735 auto sysTime = SysTime(Date(-1999, 7, 6)); 3736 sysTime.add!"months"(3, AllowDayOverflow.no); 3737 assert(sysTime == SysTime(Date(-1999, 10, 6))); 3738 sysTime.add!"months"(-4, AllowDayOverflow.no); 3739 assert(sysTime == SysTime(Date(-1999, 6, 6))); 3740 } 3741 3742 { 3743 auto sysTime = SysTime(Date(-1999, 7, 6)); 3744 sysTime.add!"months"(6, AllowDayOverflow.no); 3745 assert(sysTime == SysTime(Date(-1998, 1, 6))); 3746 sysTime.add!"months"(-6, AllowDayOverflow.no); 3747 assert(sysTime == SysTime(Date(-1999, 7, 6))); 3748 } 3749 3750 { 3751 auto sysTime = SysTime(Date(-1999, 7, 6)); 3752 sysTime.add!"months"(-27, AllowDayOverflow.no); 3753 assert(sysTime == SysTime(Date(-2001, 4, 6))); 3754 sysTime.add!"months"(28, AllowDayOverflow.no); 3755 assert(sysTime == SysTime(Date(-1999, 8, 6))); 3756 } 3757 3758 { 3759 auto sysTime = SysTime(Date(-1999, 5, 31)); 3760 sysTime.add!"months"(1, AllowDayOverflow.no); 3761 assert(sysTime == SysTime(Date(-1999, 6, 30))); 3762 } 3763 3764 { 3765 auto sysTime = SysTime(Date(-1999, 5, 31)); 3766 sysTime.add!"months"(-1, AllowDayOverflow.no); 3767 assert(sysTime == SysTime(Date(-1999, 4, 30))); 3768 } 3769 3770 { 3771 auto sysTime = SysTime(Date(-1999, 2, 28)); 3772 sysTime.add!"months"(-12, AllowDayOverflow.no); 3773 assert(sysTime == SysTime(Date(-2000, 2, 28))); 3774 } 3775 3776 { 3777 auto sysTime = SysTime(Date(-2000, 2, 29)); 3778 sysTime.add!"months"(-12, AllowDayOverflow.no); 3779 assert(sysTime == SysTime(Date(-2001, 2, 28))); 3780 } 3781 3782 { 3783 auto sysTime = SysTime(Date(-1999, 7, 31)); 3784 sysTime.add!"months"(1, AllowDayOverflow.no); 3785 assert(sysTime == SysTime(Date(-1999, 8, 31))); 3786 sysTime.add!"months"(1, AllowDayOverflow.no); 3787 assert(sysTime == SysTime(Date(-1999, 9, 30))); 3788 } 3789 3790 { 3791 auto sysTime = SysTime(Date(-1998, 8, 31)); 3792 sysTime.add!"months"(13, AllowDayOverflow.no); 3793 assert(sysTime == SysTime(Date(-1997, 9, 30))); 3794 sysTime.add!"months"(-13, AllowDayOverflow.no); 3795 assert(sysTime == SysTime(Date(-1998, 8, 30))); 3796 } 3797 3798 { 3799 auto sysTime = SysTime(Date(-1997, 12, 31)); 3800 sysTime.add!"months"(13, AllowDayOverflow.no); 3801 assert(sysTime == SysTime(Date(-1995, 1, 31))); 3802 sysTime.add!"months"(-13, AllowDayOverflow.no); 3803 assert(sysTime == SysTime(Date(-1997, 12, 31))); 3804 } 3805 3806 { 3807 auto sysTime = SysTime(Date(-1997, 12, 31)); 3808 sysTime.add!"months"(14, AllowDayOverflow.no); 3809 assert(sysTime == SysTime(Date(-1995, 2, 28))); 3810 sysTime.add!"months"(-14, AllowDayOverflow.no); 3811 assert(sysTime == SysTime(Date(-1997, 12, 28))); 3812 } 3813 3814 { 3815 auto sysTime = SysTime(Date(-2002, 12, 31)); 3816 sysTime.add!"months"(14, AllowDayOverflow.no); 3817 assert(sysTime == SysTime(Date(-2000, 2, 29))); 3818 sysTime.add!"months"(-14, AllowDayOverflow.no); 3819 assert(sysTime == SysTime(Date(-2002, 12, 29))); 3820 } 3821 3822 { 3823 auto sysTime = SysTime(Date(-2001, 12, 31)); 3824 sysTime.add!"months"(14, AllowDayOverflow.no); 3825 assert(sysTime == SysTime(Date(-1999, 2, 28))); 3826 sysTime.add!"months"(-14, AllowDayOverflow.no); 3827 assert(sysTime == SysTime(Date(-2001, 12, 28))); 3828 } 3829 3830 { 3831 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), usecs(5007)); 3832 sysTime.add!"months"(3, AllowDayOverflow.no); 3833 assert(sysTime == SysTime(DateTime(-1999, 10, 6, 12, 2, 7), usecs(5007))); 3834 sysTime.add!"months"(-4, AllowDayOverflow.no); 3835 assert(sysTime == SysTime(DateTime(-1999, 6, 6, 12, 2, 7), usecs(5007))); 3836 } 3837 3838 { 3839 auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), hnsecs(422202)); 3840 sysTime.add!"months"(14, AllowDayOverflow.no); 3841 assert(sysTime == SysTime(DateTime(-2000, 2, 29, 7, 7, 7), hnsecs(422202))); 3842 sysTime.add!"months"(-14, AllowDayOverflow.no); 3843 assert(sysTime == SysTime(DateTime(-2002, 12, 29, 7, 7, 7), hnsecs(422202))); 3844 } 3845 3846 { 3847 auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), hnsecs(422202)); 3848 sysTime.add!"months"(14, AllowDayOverflow.no); 3849 assert(sysTime == SysTime(DateTime(-1999, 2, 28, 7, 7, 7), hnsecs(422202))); 3850 sysTime.add!"months"(-14, AllowDayOverflow.no); 3851 assert(sysTime == SysTime(DateTime(-2001, 12, 28, 7, 7, 7), hnsecs(422202))); 3852 } 3853 3854 // Test Both 3855 { 3856 auto sysTime = SysTime(Date(1, 1, 1)); 3857 sysTime.add!"months"(-1, AllowDayOverflow.no); 3858 assert(sysTime == SysTime(Date(0, 12, 1))); 3859 sysTime.add!"months"(1, AllowDayOverflow.no); 3860 assert(sysTime == SysTime(Date(1, 1, 1))); 3861 } 3862 3863 { 3864 auto sysTime = SysTime(Date(4, 1, 1)); 3865 sysTime.add!"months"(-48, AllowDayOverflow.no); 3866 assert(sysTime == SysTime(Date(0, 1, 1))); 3867 sysTime.add!"months"(48, AllowDayOverflow.no); 3868 assert(sysTime == SysTime(Date(4, 1, 1))); 3869 } 3870 3871 { 3872 auto sysTime = SysTime(Date(4, 3, 31)); 3873 sysTime.add!"months"(-49, AllowDayOverflow.no); 3874 assert(sysTime == SysTime(Date(0, 2, 29))); 3875 sysTime.add!"months"(49, AllowDayOverflow.no); 3876 assert(sysTime == SysTime(Date(4, 3, 29))); 3877 } 3878 3879 { 3880 auto sysTime = SysTime(Date(4, 3, 31)); 3881 sysTime.add!"months"(-85, AllowDayOverflow.no); 3882 assert(sysTime == SysTime(Date(-3, 2, 28))); 3883 sysTime.add!"months"(85, AllowDayOverflow.no); 3884 assert(sysTime == SysTime(Date(4, 3, 28))); 3885 } 3886 3887 { 3888 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 3889 sysTime.add!"months"(-1, AllowDayOverflow.no); 3890 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 3891 sysTime.add!"months"(1, AllowDayOverflow.no); 3892 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 3893 } 3894 3895 { 3896 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 3897 sysTime.add!"months"(-1, AllowDayOverflow.no); 3898 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 3899 sysTime.add!"months"(1, AllowDayOverflow.no); 3900 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3901 } 3902 3903 { 3904 auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0)); 3905 sysTime.add!"months"(1, AllowDayOverflow.no); 3906 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 3907 sysTime.add!"months"(-1, AllowDayOverflow.no); 3908 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 3909 } 3910 3911 { 3912 auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)); 3913 sysTime.add!"months"(1, AllowDayOverflow.no); 3914 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3915 sysTime.add!"months"(-1, AllowDayOverflow.no); 3916 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 3917 } 3918 3919 { 3920 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17)); 3921 sysTime.add!"months"(-1, AllowDayOverflow.no); 3922 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 7, 9), hnsecs(17))); 3923 sysTime.add!"months"(1, AllowDayOverflow.no); 3924 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17))); 3925 } 3926 3927 { 3928 auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), msecs(9)); 3929 sysTime.add!"months"(-85, AllowDayOverflow.no); 3930 assert(sysTime == SysTime(DateTime(-3, 2, 28, 12, 11, 10), msecs(9))); 3931 sysTime.add!"months"(85, AllowDayOverflow.no); 3932 assert(sysTime == SysTime(DateTime(4, 3, 28, 12, 11, 10), msecs(9))); 3933 } 3934 3935 { 3936 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 3937 sysTime.add!"months"(85, AllowDayOverflow.no); 3938 assert(sysTime == SysTime(DateTime(4, 4, 30, 12, 11, 10), msecs(9))); 3939 sysTime.add!"months"(-85, AllowDayOverflow.no); 3940 assert(sysTime == SysTime(DateTime(-3, 3, 30, 12, 11, 10), msecs(9))); 3941 } 3942 3943 { 3944 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 3945 sysTime.add!"months"(85, AllowDayOverflow.no).add!"months"(-83, AllowDayOverflow.no); 3946 assert(sysTime == SysTime(DateTime(-3, 5, 30, 12, 11, 10), msecs(9))); 3947 } 3948 } 3949 3950 3951 /++ 3952 Adds the given number of years or months to this $(LREF SysTime). A 3953 negative number will subtract. 3954 3955 The difference between rolling and adding is that rolling does not 3956 affect larger units. Rolling a $(LREF SysTime) 12 months 3957 gets the exact same $(LREF SysTime). However, the days can still be 3958 affected due to the differing number of days in each month. 3959 3960 Because there are no units larger than years, there is no difference 3961 between adding and rolling years. 3962 3963 Params: 3964 units = The type of units to add ("years" or "months"). 3965 value = The number of months or years to add to this 3966 $(LREF SysTime). 3967 allowOverflow = Whether the days should be allowed to overflow, 3968 causing the month to increment. 3969 +/ 3970 ref SysTime roll(string units) 3971 (long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe nothrow scope 3972 if (units == "years") 3973 { 3974 return add!"years"(value, allowOverflow); 3975 } 3976 3977 /// 3978 @safe unittest 3979 { 3980 import std.datetime.date : AllowDayOverflow, DateTime; 3981 3982 auto st1 = SysTime(DateTime(2010, 1, 1, 12, 33, 33)); 3983 st1.roll!"months"(1); 3984 assert(st1 == SysTime(DateTime(2010, 2, 1, 12, 33, 33))); 3985 3986 auto st2 = SysTime(DateTime(2010, 1, 1, 12, 33, 33)); 3987 st2.roll!"months"(-1); 3988 assert(st2 == SysTime(DateTime(2010, 12, 1, 12, 33, 33))); 3989 3990 auto st3 = SysTime(DateTime(1999, 1, 29, 12, 33, 33)); 3991 st3.roll!"months"(1); 3992 assert(st3 == SysTime(DateTime(1999, 3, 1, 12, 33, 33))); 3993 3994 auto st4 = SysTime(DateTime(1999, 1, 29, 12, 33, 33)); 3995 st4.roll!"months"(1, AllowDayOverflow.no); 3996 assert(st4 == SysTime(DateTime(1999, 2, 28, 12, 33, 33))); 3997 3998 auto st5 = SysTime(DateTime(2000, 2, 29, 12, 30, 33)); 3999 st5.roll!"years"(1); 4000 assert(st5 == SysTime(DateTime(2001, 3, 1, 12, 30, 33))); 4001 4002 auto st6 = SysTime(DateTime(2000, 2, 29, 12, 30, 33)); 4003 st6.roll!"years"(1, AllowDayOverflow.no); 4004 assert(st6 == SysTime(DateTime(2001, 2, 28, 12, 30, 33))); 4005 } 4006 4007 @safe unittest 4008 { 4009 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 4010 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 4011 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 4012 st.roll!"years"(4); 4013 static assert(!__traits(compiles, cst.roll!"years"(4))); 4014 static assert(!__traits(compiles, ist.roll!"years"(4))); 4015 4016 static void testScope(scope ref SysTime st) @safe 4017 { 4018 auto result = st.roll!"years"(42); 4019 } 4020 } 4021 4022 4023 // Shares documentation with "years" overload. 4024 ref SysTime roll(string units) 4025 (long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe nothrow scope 4026 if (units == "months") 4027 { 4028 auto hnsecs = adjTime; 4029 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 4030 4031 if (hnsecs < 0) 4032 { 4033 hnsecs += convert!("hours", "hnsecs")(24); 4034 --days; 4035 } 4036 4037 auto date = Date(cast(int) days); 4038 date.roll!"months"(value, allowOverflow); 4039 days = date.dayOfGregorianCal - 1; 4040 4041 if (days < 0) 4042 { 4043 hnsecs -= convert!("hours", "hnsecs")(24); 4044 ++days; 4045 } 4046 4047 immutable newDaysHNSecs = convert!("days", "hnsecs")(days); 4048 adjTime = newDaysHNSecs + hnsecs; 4049 return this; 4050 } 4051 4052 // Test roll!"months"() with AllowDayOverflow.yes 4053 @safe unittest 4054 { 4055 import core.time; 4056 // Test A.D. 4057 { 4058 auto sysTime = SysTime(Date(1999, 7, 6)); 4059 sysTime.roll!"months"(3); 4060 assert(sysTime == SysTime(Date(1999, 10, 6))); 4061 sysTime.roll!"months"(-4); 4062 assert(sysTime == SysTime(Date(1999, 6, 6))); 4063 } 4064 4065 { 4066 auto sysTime = SysTime(Date(1999, 7, 6)); 4067 sysTime.roll!"months"(6); 4068 assert(sysTime == SysTime(Date(1999, 1, 6))); 4069 sysTime.roll!"months"(-6); 4070 assert(sysTime == SysTime(Date(1999, 7, 6))); 4071 } 4072 4073 { 4074 auto sysTime = SysTime(Date(1999, 7, 6)); 4075 sysTime.roll!"months"(27); 4076 assert(sysTime == SysTime(Date(1999, 10, 6))); 4077 sysTime.roll!"months"(-28); 4078 assert(sysTime == SysTime(Date(1999, 6, 6))); 4079 } 4080 4081 { 4082 auto sysTime = SysTime(Date(1999, 5, 31)); 4083 sysTime.roll!"months"(1); 4084 assert(sysTime == SysTime(Date(1999, 7, 1))); 4085 } 4086 4087 { 4088 auto sysTime = SysTime(Date(1999, 5, 31)); 4089 sysTime.roll!"months"(-1); 4090 assert(sysTime == SysTime(Date(1999, 5, 1))); 4091 } 4092 4093 { 4094 auto sysTime = SysTime(Date(1999, 2, 28)); 4095 sysTime.roll!"months"(12); 4096 assert(sysTime == SysTime(Date(1999, 2, 28))); 4097 } 4098 4099 { 4100 auto sysTime = SysTime(Date(2000, 2, 29)); 4101 sysTime.roll!"months"(12); 4102 assert(sysTime == SysTime(Date(2000, 2, 29))); 4103 } 4104 4105 { 4106 auto sysTime = SysTime(Date(1999, 7, 31)); 4107 sysTime.roll!"months"(1); 4108 assert(sysTime == SysTime(Date(1999, 8, 31))); 4109 sysTime.roll!"months"(1); 4110 assert(sysTime == SysTime(Date(1999, 10, 1))); 4111 } 4112 4113 { 4114 auto sysTime = SysTime(Date(1998, 8, 31)); 4115 sysTime.roll!"months"(13); 4116 assert(sysTime == SysTime(Date(1998, 10, 1))); 4117 sysTime.roll!"months"(-13); 4118 assert(sysTime == SysTime(Date(1998, 9, 1))); 4119 } 4120 4121 { 4122 auto sysTime = SysTime(Date(1997, 12, 31)); 4123 sysTime.roll!"months"(13); 4124 assert(sysTime == SysTime(Date(1997, 1, 31))); 4125 sysTime.roll!"months"(-13); 4126 assert(sysTime == SysTime(Date(1997, 12, 31))); 4127 } 4128 4129 { 4130 auto sysTime = SysTime(Date(1997, 12, 31)); 4131 sysTime.roll!"months"(14); 4132 assert(sysTime == SysTime(Date(1997, 3, 3))); 4133 sysTime.roll!"months"(-14); 4134 assert(sysTime == SysTime(Date(1997, 1, 3))); 4135 } 4136 4137 { 4138 auto sysTime = SysTime(Date(1998, 12, 31)); 4139 sysTime.roll!"months"(14); 4140 assert(sysTime == SysTime(Date(1998, 3, 3))); 4141 sysTime.roll!"months"(-14); 4142 assert(sysTime == SysTime(Date(1998, 1, 3))); 4143 } 4144 4145 { 4146 auto sysTime = SysTime(Date(1999, 12, 31)); 4147 sysTime.roll!"months"(14); 4148 assert(sysTime == SysTime(Date(1999, 3, 3))); 4149 sysTime.roll!"months"(-14); 4150 assert(sysTime == SysTime(Date(1999, 1, 3))); 4151 } 4152 4153 { 4154 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), usecs(5007)); 4155 sysTime.roll!"months"(3); 4156 assert(sysTime == SysTime(DateTime(1999, 10, 6, 12, 2, 7), usecs(5007))); 4157 sysTime.roll!"months"(-4); 4158 assert(sysTime == SysTime(DateTime(1999, 6, 6, 12, 2, 7), usecs(5007))); 4159 } 4160 4161 { 4162 auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), hnsecs(422202)); 4163 sysTime.roll!"months"(14); 4164 assert(sysTime == SysTime(DateTime(1998, 3, 3, 7, 7, 7), hnsecs(422202))); 4165 sysTime.roll!"months"(-14); 4166 assert(sysTime == SysTime(DateTime(1998, 1, 3, 7, 7, 7), hnsecs(422202))); 4167 } 4168 4169 { 4170 auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), hnsecs(422202)); 4171 sysTime.roll!"months"(14); 4172 assert(sysTime == SysTime(DateTime(1999, 3, 3, 7, 7, 7), hnsecs(422202))); 4173 sysTime.roll!"months"(-14); 4174 assert(sysTime == SysTime(DateTime(1999, 1, 3, 7, 7, 7), hnsecs(422202))); 4175 } 4176 4177 // Test B.C. 4178 { 4179 auto sysTime = SysTime(Date(-1999, 7, 6)); 4180 sysTime.roll!"months"(3); 4181 assert(sysTime == SysTime(Date(-1999, 10, 6))); 4182 sysTime.roll!"months"(-4); 4183 assert(sysTime == SysTime(Date(-1999, 6, 6))); 4184 } 4185 4186 { 4187 auto sysTime = SysTime(Date(-1999, 7, 6)); 4188 sysTime.roll!"months"(6); 4189 assert(sysTime == SysTime(Date(-1999, 1, 6))); 4190 sysTime.roll!"months"(-6); 4191 assert(sysTime == SysTime(Date(-1999, 7, 6))); 4192 } 4193 4194 { 4195 auto sysTime = SysTime(Date(-1999, 7, 6)); 4196 sysTime.roll!"months"(-27); 4197 assert(sysTime == SysTime(Date(-1999, 4, 6))); 4198 sysTime.roll!"months"(28); 4199 assert(sysTime == SysTime(Date(-1999, 8, 6))); 4200 } 4201 4202 { 4203 auto sysTime = SysTime(Date(-1999, 5, 31)); 4204 sysTime.roll!"months"(1); 4205 assert(sysTime == SysTime(Date(-1999, 7, 1))); 4206 } 4207 4208 { 4209 auto sysTime = SysTime(Date(-1999, 5, 31)); 4210 sysTime.roll!"months"(-1); 4211 assert(sysTime == SysTime(Date(-1999, 5, 1))); 4212 } 4213 4214 { 4215 auto sysTime = SysTime(Date(-1999, 2, 28)); 4216 sysTime.roll!"months"(-12); 4217 assert(sysTime == SysTime(Date(-1999, 2, 28))); 4218 } 4219 4220 { 4221 auto sysTime = SysTime(Date(-2000, 2, 29)); 4222 sysTime.roll!"months"(-12); 4223 assert(sysTime == SysTime(Date(-2000, 2, 29))); 4224 } 4225 4226 { 4227 auto sysTime = SysTime(Date(-1999, 7, 31)); 4228 sysTime.roll!"months"(1); 4229 assert(sysTime == SysTime(Date(-1999, 8, 31))); 4230 sysTime.roll!"months"(1); 4231 assert(sysTime == SysTime(Date(-1999, 10, 1))); 4232 } 4233 4234 { 4235 auto sysTime = SysTime(Date(-1998, 8, 31)); 4236 sysTime.roll!"months"(13); 4237 assert(sysTime == SysTime(Date(-1998, 10, 1))); 4238 sysTime.roll!"months"(-13); 4239 assert(sysTime == SysTime(Date(-1998, 9, 1))); 4240 } 4241 4242 { 4243 auto sysTime = SysTime(Date(-1997, 12, 31)); 4244 sysTime.roll!"months"(13); 4245 assert(sysTime == SysTime(Date(-1997, 1, 31))); 4246 sysTime.roll!"months"(-13); 4247 assert(sysTime == SysTime(Date(-1997, 12, 31))); 4248 } 4249 4250 { 4251 auto sysTime = SysTime(Date(-1997, 12, 31)); 4252 sysTime.roll!"months"(14); 4253 assert(sysTime == SysTime(Date(-1997, 3, 3))); 4254 sysTime.roll!"months"(-14); 4255 assert(sysTime == SysTime(Date(-1997, 1, 3))); 4256 } 4257 4258 { 4259 auto sysTime = SysTime(Date(-2002, 12, 31)); 4260 sysTime.roll!"months"(14); 4261 assert(sysTime == SysTime(Date(-2002, 3, 3))); 4262 sysTime.roll!"months"(-14); 4263 assert(sysTime == SysTime(Date(-2002, 1, 3))); 4264 } 4265 4266 { 4267 auto sysTime = SysTime(Date(-2001, 12, 31)); 4268 sysTime.roll!"months"(14); 4269 assert(sysTime == SysTime(Date(-2001, 3, 3))); 4270 sysTime.roll!"months"(-14); 4271 assert(sysTime == SysTime(Date(-2001, 1, 3))); 4272 } 4273 4274 { 4275 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 4276 sysTime.roll!"months"(-1); 4277 assert(sysTime == SysTime(DateTime(1, 12, 1, 0, 0, 0))); 4278 sysTime.roll!"months"(1); 4279 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 4280 } 4281 4282 { 4283 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 4284 sysTime.roll!"months"(-1); 4285 assert(sysTime == SysTime(DateTime(1, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 4286 sysTime.roll!"months"(1); 4287 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 4288 } 4289 4290 { 4291 auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0)); 4292 sysTime.roll!"months"(1); 4293 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0))); 4294 sysTime.roll!"months"(-1); 4295 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 4296 } 4297 4298 { 4299 auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)); 4300 sysTime.roll!"months"(1); 4301 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 4302 sysTime.roll!"months"(-1); 4303 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 4304 } 4305 4306 { 4307 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), hnsecs(5007)); 4308 sysTime.roll!"months"(3); 4309 assert(sysTime == SysTime(DateTime(-1999, 10, 6, 12, 2, 7), hnsecs(5007))); 4310 sysTime.roll!"months"(-4); 4311 assert(sysTime == SysTime(DateTime(-1999, 6, 6, 12, 2, 7), hnsecs(5007))); 4312 } 4313 4314 { 4315 auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), hnsecs(422202)); 4316 sysTime.roll!"months"(14); 4317 assert(sysTime == SysTime(DateTime(-2002, 3, 3, 7, 7, 7), hnsecs(422202))); 4318 sysTime.roll!"months"(-14); 4319 assert(sysTime == SysTime(DateTime(-2002, 1, 3, 7, 7, 7), hnsecs(422202))); 4320 } 4321 4322 { 4323 auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), hnsecs(422202)); 4324 sysTime.roll!"months"(14); 4325 assert(sysTime == SysTime(DateTime(-2001, 3, 3, 7, 7, 7), hnsecs(422202))); 4326 sysTime.roll!"months"(-14); 4327 assert(sysTime == SysTime(DateTime(-2001, 1, 3, 7, 7, 7), hnsecs(422202))); 4328 } 4329 4330 // Test Both 4331 { 4332 auto sysTime = SysTime(Date(1, 1, 1)); 4333 sysTime.roll!"months"(-1); 4334 assert(sysTime == SysTime(Date(1, 12, 1))); 4335 sysTime.roll!"months"(1); 4336 assert(sysTime == SysTime(Date(1, 1, 1))); 4337 } 4338 4339 { 4340 auto sysTime = SysTime(Date(4, 1, 1)); 4341 sysTime.roll!"months"(-48); 4342 assert(sysTime == SysTime(Date(4, 1, 1))); 4343 sysTime.roll!"months"(48); 4344 assert(sysTime == SysTime(Date(4, 1, 1))); 4345 } 4346 4347 { 4348 auto sysTime = SysTime(Date(4, 3, 31)); 4349 sysTime.roll!"months"(-49); 4350 assert(sysTime == SysTime(Date(4, 3, 2))); 4351 sysTime.roll!"months"(49); 4352 assert(sysTime == SysTime(Date(4, 4, 2))); 4353 } 4354 4355 { 4356 auto sysTime = SysTime(Date(4, 3, 31)); 4357 sysTime.roll!"months"(-85); 4358 assert(sysTime == SysTime(Date(4, 3, 2))); 4359 sysTime.roll!"months"(85); 4360 assert(sysTime == SysTime(Date(4, 4, 2))); 4361 } 4362 4363 { 4364 auto sysTime = SysTime(Date(-1, 1, 1)); 4365 sysTime.roll!"months"(-1); 4366 assert(sysTime == SysTime(Date(-1, 12, 1))); 4367 sysTime.roll!"months"(1); 4368 assert(sysTime == SysTime(Date(-1, 1, 1))); 4369 } 4370 4371 { 4372 auto sysTime = SysTime(Date(-4, 1, 1)); 4373 sysTime.roll!"months"(-48); 4374 assert(sysTime == SysTime(Date(-4, 1, 1))); 4375 sysTime.roll!"months"(48); 4376 assert(sysTime == SysTime(Date(-4, 1, 1))); 4377 } 4378 4379 { 4380 auto sysTime = SysTime(Date(-4, 3, 31)); 4381 sysTime.roll!"months"(-49); 4382 assert(sysTime == SysTime(Date(-4, 3, 2))); 4383 sysTime.roll!"months"(49); 4384 assert(sysTime == SysTime(Date(-4, 4, 2))); 4385 } 4386 4387 { 4388 auto sysTime = SysTime(Date(-4, 3, 31)); 4389 sysTime.roll!"months"(-85); 4390 assert(sysTime == SysTime(Date(-4, 3, 2))); 4391 sysTime.roll!"months"(85); 4392 assert(sysTime == SysTime(Date(-4, 4, 2))); 4393 } 4394 4395 { 4396 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17)); 4397 sysTime.roll!"months"(-1); 4398 assert(sysTime == SysTime(DateTime(1, 12, 1, 0, 7, 9), hnsecs(17))); 4399 sysTime.roll!"months"(1); 4400 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17))); 4401 } 4402 4403 { 4404 auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), msecs(9)); 4405 sysTime.roll!"months"(-85); 4406 assert(sysTime == SysTime(DateTime(4, 3, 2, 12, 11, 10), msecs(9))); 4407 sysTime.roll!"months"(85); 4408 assert(sysTime == SysTime(DateTime(4, 4, 2, 12, 11, 10), msecs(9))); 4409 } 4410 4411 { 4412 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 4413 sysTime.roll!"months"(85); 4414 assert(sysTime == SysTime(DateTime(-3, 5, 1, 12, 11, 10), msecs(9))); 4415 sysTime.roll!"months"(-85); 4416 assert(sysTime == SysTime(DateTime(-3, 4, 1, 12, 11, 10), msecs(9))); 4417 } 4418 4419 { 4420 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 4421 sysTime.roll!"months"(85).roll!"months"(-83); 4422 assert(sysTime == SysTime(DateTime(-3, 6, 1, 12, 11, 10), msecs(9))); 4423 } 4424 4425 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 4426 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 4427 static assert(!__traits(compiles, cst.roll!"months"(4))); 4428 static assert(!__traits(compiles, ist.roll!"months"(4))); 4429 4430 static void testScope(scope ref SysTime st) @safe 4431 { 4432 auto result = st.roll!"months"(42); 4433 } 4434 } 4435 4436 // Test roll!"months"() with AllowDayOverflow.no 4437 @safe unittest 4438 { 4439 import core.time; 4440 // Test A.D. 4441 { 4442 auto sysTime = SysTime(Date(1999, 7, 6)); 4443 sysTime.roll!"months"(3, AllowDayOverflow.no); 4444 assert(sysTime == SysTime(Date(1999, 10, 6))); 4445 sysTime.roll!"months"(-4, AllowDayOverflow.no); 4446 assert(sysTime == SysTime(Date(1999, 6, 6))); 4447 } 4448 4449 { 4450 auto sysTime = SysTime(Date(1999, 7, 6)); 4451 sysTime.roll!"months"(6, AllowDayOverflow.no); 4452 assert(sysTime == SysTime(Date(1999, 1, 6))); 4453 sysTime.roll!"months"(-6, AllowDayOverflow.no); 4454 assert(sysTime == SysTime(Date(1999, 7, 6))); 4455 } 4456 4457 { 4458 auto sysTime = SysTime(Date(1999, 7, 6)); 4459 sysTime.roll!"months"(27, AllowDayOverflow.no); 4460 assert(sysTime == SysTime(Date(1999, 10, 6))); 4461 sysTime.roll!"months"(-28, AllowDayOverflow.no); 4462 assert(sysTime == SysTime(Date(1999, 6, 6))); 4463 } 4464 4465 { 4466 auto sysTime = SysTime(Date(1999, 5, 31)); 4467 sysTime.roll!"months"(1, AllowDayOverflow.no); 4468 assert(sysTime == SysTime(Date(1999, 6, 30))); 4469 } 4470 4471 { 4472 auto sysTime = SysTime(Date(1999, 5, 31)); 4473 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4474 assert(sysTime == SysTime(Date(1999, 4, 30))); 4475 } 4476 4477 { 4478 auto sysTime = SysTime(Date(1999, 2, 28)); 4479 sysTime.roll!"months"(12, AllowDayOverflow.no); 4480 assert(sysTime == SysTime(Date(1999, 2, 28))); 4481 } 4482 4483 { 4484 auto sysTime = SysTime(Date(2000, 2, 29)); 4485 sysTime.roll!"months"(12, AllowDayOverflow.no); 4486 assert(sysTime == SysTime(Date(2000, 2, 29))); 4487 } 4488 4489 { 4490 auto sysTime = SysTime(Date(1999, 7, 31)); 4491 sysTime.roll!"months"(1, AllowDayOverflow.no); 4492 assert(sysTime == SysTime(Date(1999, 8, 31))); 4493 sysTime.roll!"months"(1, AllowDayOverflow.no); 4494 assert(sysTime == SysTime(Date(1999, 9, 30))); 4495 } 4496 4497 { 4498 auto sysTime = SysTime(Date(1998, 8, 31)); 4499 sysTime.roll!"months"(13, AllowDayOverflow.no); 4500 assert(sysTime == SysTime(Date(1998, 9, 30))); 4501 sysTime.roll!"months"(-13, AllowDayOverflow.no); 4502 assert(sysTime == SysTime(Date(1998, 8, 30))); 4503 } 4504 4505 { 4506 auto sysTime = SysTime(Date(1997, 12, 31)); 4507 sysTime.roll!"months"(13, AllowDayOverflow.no); 4508 assert(sysTime == SysTime(Date(1997, 1, 31))); 4509 sysTime.roll!"months"(-13, AllowDayOverflow.no); 4510 assert(sysTime == SysTime(Date(1997, 12, 31))); 4511 } 4512 4513 { 4514 auto sysTime = SysTime(Date(1997, 12, 31)); 4515 sysTime.roll!"months"(14, AllowDayOverflow.no); 4516 assert(sysTime == SysTime(Date(1997, 2, 28))); 4517 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4518 assert(sysTime == SysTime(Date(1997, 12, 28))); 4519 } 4520 4521 { 4522 auto sysTime = SysTime(Date(1998, 12, 31)); 4523 sysTime.roll!"months"(14, AllowDayOverflow.no); 4524 assert(sysTime == SysTime(Date(1998, 2, 28))); 4525 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4526 assert(sysTime == SysTime(Date(1998, 12, 28))); 4527 } 4528 4529 { 4530 auto sysTime = SysTime(Date(1999, 12, 31)); 4531 sysTime.roll!"months"(14, AllowDayOverflow.no); 4532 assert(sysTime == SysTime(Date(1999, 2, 28))); 4533 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4534 assert(sysTime == SysTime(Date(1999, 12, 28))); 4535 } 4536 4537 { 4538 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), usecs(5007)); 4539 sysTime.roll!"months"(3, AllowDayOverflow.no); 4540 assert(sysTime == SysTime(DateTime(1999, 10, 6, 12, 2, 7), usecs(5007))); 4541 sysTime.roll!"months"(-4, AllowDayOverflow.no); 4542 assert(sysTime == SysTime(DateTime(1999, 6, 6, 12, 2, 7), usecs(5007))); 4543 } 4544 4545 { 4546 auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), hnsecs(422202)); 4547 sysTime.roll!"months"(14, AllowDayOverflow.no); 4548 assert(sysTime == SysTime(DateTime(1998, 2, 28, 7, 7, 7), hnsecs(422202))); 4549 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4550 assert(sysTime == SysTime(DateTime(1998, 12, 28, 7, 7, 7), hnsecs(422202))); 4551 } 4552 4553 { 4554 auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), hnsecs(422202)); 4555 sysTime.roll!"months"(14, AllowDayOverflow.no); 4556 assert(sysTime == SysTime(DateTime(1999, 2, 28, 7, 7, 7), hnsecs(422202))); 4557 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4558 assert(sysTime == SysTime(DateTime(1999, 12, 28, 7, 7, 7), hnsecs(422202))); 4559 } 4560 4561 // Test B.C. 4562 { 4563 auto sysTime = SysTime(Date(-1999, 7, 6)); 4564 sysTime.roll!"months"(3, AllowDayOverflow.no); 4565 assert(sysTime == SysTime(Date(-1999, 10, 6))); 4566 sysTime.roll!"months"(-4, AllowDayOverflow.no); 4567 assert(sysTime == SysTime(Date(-1999, 6, 6))); 4568 } 4569 4570 { 4571 auto sysTime = SysTime(Date(-1999, 7, 6)); 4572 sysTime.roll!"months"(6, AllowDayOverflow.no); 4573 assert(sysTime == SysTime(Date(-1999, 1, 6))); 4574 sysTime.roll!"months"(-6, AllowDayOverflow.no); 4575 assert(sysTime == SysTime(Date(-1999, 7, 6))); 4576 } 4577 4578 { 4579 auto sysTime = SysTime(Date(-1999, 7, 6)); 4580 sysTime.roll!"months"(-27, AllowDayOverflow.no); 4581 assert(sysTime == SysTime(Date(-1999, 4, 6))); 4582 sysTime.roll!"months"(28, AllowDayOverflow.no); 4583 assert(sysTime == SysTime(Date(-1999, 8, 6))); 4584 } 4585 4586 { 4587 auto sysTime = SysTime(Date(-1999, 5, 31)); 4588 sysTime.roll!"months"(1, AllowDayOverflow.no); 4589 assert(sysTime == SysTime(Date(-1999, 6, 30))); 4590 } 4591 4592 { 4593 auto sysTime = SysTime(Date(-1999, 5, 31)); 4594 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4595 assert(sysTime == SysTime(Date(-1999, 4, 30))); 4596 } 4597 4598 { 4599 auto sysTime = SysTime(Date(-1999, 2, 28)); 4600 sysTime.roll!"months"(-12, AllowDayOverflow.no); 4601 assert(sysTime == SysTime(Date(-1999, 2, 28))); 4602 } 4603 4604 { 4605 auto sysTime = SysTime(Date(-2000, 2, 29)); 4606 sysTime.roll!"months"(-12, AllowDayOverflow.no); 4607 assert(sysTime == SysTime(Date(-2000, 2, 29))); 4608 } 4609 4610 { 4611 auto sysTime = SysTime(Date(-1999, 7, 31)); 4612 sysTime.roll!"months"(1, AllowDayOverflow.no); 4613 assert(sysTime == SysTime(Date(-1999, 8, 31))); 4614 sysTime.roll!"months"(1, AllowDayOverflow.no); 4615 assert(sysTime == SysTime(Date(-1999, 9, 30))); 4616 } 4617 4618 { 4619 auto sysTime = SysTime(Date(-1998, 8, 31)); 4620 sysTime.roll!"months"(13, AllowDayOverflow.no); 4621 assert(sysTime == SysTime(Date(-1998, 9, 30))); 4622 sysTime.roll!"months"(-13, AllowDayOverflow.no); 4623 assert(sysTime == SysTime(Date(-1998, 8, 30))); 4624 } 4625 4626 { 4627 auto sysTime = SysTime(Date(-1997, 12, 31)); 4628 sysTime.roll!"months"(13, AllowDayOverflow.no); 4629 assert(sysTime == SysTime(Date(-1997, 1, 31))); 4630 sysTime.roll!"months"(-13, AllowDayOverflow.no); 4631 assert(sysTime == SysTime(Date(-1997, 12, 31))); 4632 } 4633 4634 { 4635 auto sysTime = SysTime(Date(-1997, 12, 31)); 4636 sysTime.roll!"months"(14, AllowDayOverflow.no); 4637 assert(sysTime == SysTime(Date(-1997, 2, 28))); 4638 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4639 assert(sysTime == SysTime(Date(-1997, 12, 28))); 4640 } 4641 4642 { 4643 auto sysTime = SysTime(Date(-2002, 12, 31)); 4644 sysTime.roll!"months"(14, AllowDayOverflow.no); 4645 assert(sysTime == SysTime(Date(-2002, 2, 28))); 4646 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4647 assert(sysTime == SysTime(Date(-2002, 12, 28))); 4648 } 4649 4650 { 4651 auto sysTime = SysTime(Date(-2001, 12, 31)); 4652 sysTime.roll!"months"(14, AllowDayOverflow.no); 4653 assert(sysTime == SysTime(Date(-2001, 2, 28))); 4654 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4655 assert(sysTime == SysTime(Date(-2001, 12, 28))); 4656 } 4657 4658 { 4659 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), usecs(5007)); 4660 sysTime.roll!"months"(3, AllowDayOverflow.no); 4661 assert(sysTime == SysTime(DateTime(-1999, 10, 6, 12, 2, 7), usecs(5007))); 4662 sysTime.roll!"months"(-4, AllowDayOverflow.no); 4663 assert(sysTime == SysTime(DateTime(-1999, 6, 6, 12, 2, 7), usecs(5007))); 4664 } 4665 4666 { 4667 auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), hnsecs(422202)); 4668 sysTime.roll!"months"(14, AllowDayOverflow.no); 4669 assert(sysTime == SysTime(DateTime(-2002, 2, 28, 7, 7, 7), hnsecs(422202))); 4670 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4671 assert(sysTime == SysTime(DateTime(-2002, 12, 28, 7, 7, 7), hnsecs(422202))); 4672 } 4673 4674 { 4675 auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), hnsecs(422202)); 4676 sysTime.roll!"months"(14, AllowDayOverflow.no); 4677 assert(sysTime == SysTime(DateTime(-2001, 2, 28, 7, 7, 7), hnsecs(422202))); 4678 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4679 assert(sysTime == SysTime(DateTime(-2001, 12, 28, 7, 7, 7), hnsecs(422202))); 4680 } 4681 4682 // Test Both 4683 { 4684 auto sysTime = SysTime(Date(1, 1, 1)); 4685 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4686 assert(sysTime == SysTime(Date(1, 12, 1))); 4687 sysTime.roll!"months"(1, AllowDayOverflow.no); 4688 assert(sysTime == SysTime(Date(1, 1, 1))); 4689 } 4690 4691 { 4692 auto sysTime = SysTime(Date(4, 1, 1)); 4693 sysTime.roll!"months"(-48, AllowDayOverflow.no); 4694 assert(sysTime == SysTime(Date(4, 1, 1))); 4695 sysTime.roll!"months"(48, AllowDayOverflow.no); 4696 assert(sysTime == SysTime(Date(4, 1, 1))); 4697 } 4698 4699 { 4700 auto sysTime = SysTime(Date(4, 3, 31)); 4701 sysTime.roll!"months"(-49, AllowDayOverflow.no); 4702 assert(sysTime == SysTime(Date(4, 2, 29))); 4703 sysTime.roll!"months"(49, AllowDayOverflow.no); 4704 assert(sysTime == SysTime(Date(4, 3, 29))); 4705 } 4706 4707 { 4708 auto sysTime = SysTime(Date(4, 3, 31)); 4709 sysTime.roll!"months"(-85, AllowDayOverflow.no); 4710 assert(sysTime == SysTime(Date(4, 2, 29))); 4711 sysTime.roll!"months"(85, AllowDayOverflow.no); 4712 assert(sysTime == SysTime(Date(4, 3, 29))); 4713 } 4714 4715 { 4716 auto sysTime = SysTime(Date(-1, 1, 1)); 4717 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4718 assert(sysTime == SysTime(Date(-1, 12, 1))); 4719 sysTime.roll!"months"(1, AllowDayOverflow.no); 4720 assert(sysTime == SysTime(Date(-1, 1, 1))); 4721 } 4722 4723 { 4724 auto sysTime = SysTime(Date(-4, 1, 1)); 4725 sysTime.roll!"months"(-48, AllowDayOverflow.no); 4726 assert(sysTime == SysTime(Date(-4, 1, 1))); 4727 sysTime.roll!"months"(48, AllowDayOverflow.no); 4728 assert(sysTime == SysTime(Date(-4, 1, 1))); 4729 } 4730 4731 { 4732 auto sysTime = SysTime(Date(-4, 3, 31)); 4733 sysTime.roll!"months"(-49, AllowDayOverflow.no); 4734 assert(sysTime == SysTime(Date(-4, 2, 29))); 4735 sysTime.roll!"months"(49, AllowDayOverflow.no); 4736 assert(sysTime == SysTime(Date(-4, 3, 29))); 4737 } 4738 4739 { 4740 auto sysTime = SysTime(Date(-4, 3, 31)); 4741 sysTime.roll!"months"(-85, AllowDayOverflow.no); 4742 assert(sysTime == SysTime(Date(-4, 2, 29))); 4743 sysTime.roll!"months"(85, AllowDayOverflow.no); 4744 assert(sysTime == SysTime(Date(-4, 3, 29))); 4745 } 4746 4747 { 4748 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 4749 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4750 assert(sysTime == SysTime(DateTime(1, 12, 1, 0, 0, 0))); 4751 sysTime.roll!"months"(1, AllowDayOverflow.no); 4752 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 4753 } 4754 4755 { 4756 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 4757 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4758 assert(sysTime == SysTime(DateTime(1, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 4759 sysTime.roll!"months"(1, AllowDayOverflow.no); 4760 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 4761 } 4762 4763 { 4764 auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0)); 4765 sysTime.roll!"months"(1, AllowDayOverflow.no); 4766 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0))); 4767 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4768 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 4769 } 4770 4771 { 4772 auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)); 4773 sysTime.roll!"months"(1, AllowDayOverflow.no); 4774 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 4775 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4776 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 4777 } 4778 4779 { 4780 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17)); 4781 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4782 assert(sysTime == SysTime(DateTime(1, 12, 1, 0, 7, 9), hnsecs(17))); 4783 sysTime.roll!"months"(1, AllowDayOverflow.no); 4784 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17))); 4785 } 4786 4787 { 4788 auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), msecs(9)); 4789 sysTime.roll!"months"(-85, AllowDayOverflow.no); 4790 assert(sysTime == SysTime(DateTime(4, 2, 29, 12, 11, 10), msecs(9))); 4791 sysTime.roll!"months"(85, AllowDayOverflow.no); 4792 assert(sysTime == SysTime(DateTime(4, 3, 29, 12, 11, 10), msecs(9))); 4793 } 4794 4795 { 4796 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 4797 sysTime.roll!"months"(85, AllowDayOverflow.no); 4798 assert(sysTime == SysTime(DateTime(-3, 4, 30, 12, 11, 10), msecs(9))); 4799 sysTime.roll!"months"(-85, AllowDayOverflow.no); 4800 assert(sysTime == SysTime(DateTime(-3, 3, 30, 12, 11, 10), msecs(9))); 4801 } 4802 4803 { 4804 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 4805 sysTime.roll!"months"(85, AllowDayOverflow.no).roll!"months"(-83, AllowDayOverflow.no); 4806 assert(sysTime == SysTime(DateTime(-3, 5, 30, 12, 11, 10), msecs(9))); 4807 } 4808 } 4809 4810 4811 /++ 4812 Adds the given number of units to this $(LREF SysTime). A negative number 4813 will subtract. 4814 4815 The difference between rolling and adding is that rolling does not 4816 affect larger units. For instance, rolling a $(LREF SysTime) one 4817 year's worth of days gets the exact same $(LREF SysTime). 4818 4819 Accepted units are `"days"`, `"minutes"`, `"hours"`, 4820 `"minutes"`, `"seconds"`, `"msecs"`, `"usecs"`, and 4821 `"hnsecs"`. 4822 4823 Note that when rolling msecs, usecs or hnsecs, they all add up to a 4824 second. So, for example, rolling 1000 msecs is exactly the same as 4825 rolling 100,000 usecs. 4826 4827 Params: 4828 units = The units to add. 4829 value = The number of $(D_PARAM units) to add to this 4830 $(LREF SysTime). 4831 +/ 4832 ref SysTime roll(string units)(long value) @safe nothrow scope 4833 if (units == "days") 4834 { 4835 auto hnsecs = adjTime; 4836 auto gdays = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 4837 4838 if (hnsecs < 0) 4839 { 4840 hnsecs += convert!("hours", "hnsecs")(24); 4841 --gdays; 4842 } 4843 4844 auto date = Date(cast(int) gdays); 4845 date.roll!"days"(value); 4846 gdays = date.dayOfGregorianCal - 1; 4847 4848 if (gdays < 0) 4849 { 4850 hnsecs -= convert!("hours", "hnsecs")(24); 4851 ++gdays; 4852 } 4853 4854 immutable newDaysHNSecs = convert!("days", "hnsecs")(gdays); 4855 adjTime = newDaysHNSecs + hnsecs; 4856 return this; 4857 } 4858 4859 /// 4860 @safe unittest 4861 { 4862 import core.time : msecs, hnsecs; 4863 import std.datetime.date : DateTime; 4864 4865 auto st1 = SysTime(DateTime(2010, 1, 1, 11, 23, 12)); 4866 st1.roll!"days"(1); 4867 assert(st1 == SysTime(DateTime(2010, 1, 2, 11, 23, 12))); 4868 st1.roll!"days"(365); 4869 assert(st1 == SysTime(DateTime(2010, 1, 26, 11, 23, 12))); 4870 st1.roll!"days"(-32); 4871 assert(st1 == SysTime(DateTime(2010, 1, 25, 11, 23, 12))); 4872 4873 auto st2 = SysTime(DateTime(2010, 7, 4, 12, 0, 0)); 4874 st2.roll!"hours"(1); 4875 assert(st2 == SysTime(DateTime(2010, 7, 4, 13, 0, 0))); 4876 4877 auto st3 = SysTime(DateTime(2010, 2, 12, 12, 0, 0)); 4878 st3.roll!"hours"(-1); 4879 assert(st3 == SysTime(DateTime(2010, 2, 12, 11, 0, 0))); 4880 4881 auto st4 = SysTime(DateTime(2009, 12, 31, 0, 0, 0)); 4882 st4.roll!"minutes"(1); 4883 assert(st4 == SysTime(DateTime(2009, 12, 31, 0, 1, 0))); 4884 4885 auto st5 = SysTime(DateTime(2010, 1, 1, 0, 0, 0)); 4886 st5.roll!"minutes"(-1); 4887 assert(st5 == SysTime(DateTime(2010, 1, 1, 0, 59, 0))); 4888 4889 auto st6 = SysTime(DateTime(2009, 12, 31, 0, 0, 0)); 4890 st6.roll!"seconds"(1); 4891 assert(st6 == SysTime(DateTime(2009, 12, 31, 0, 0, 1))); 4892 4893 auto st7 = SysTime(DateTime(2010, 1, 1, 0, 0, 0)); 4894 st7.roll!"seconds"(-1); 4895 assert(st7 == SysTime(DateTime(2010, 1, 1, 0, 0, 59))); 4896 4897 auto dt = DateTime(2010, 1, 1, 0, 0, 0); 4898 auto st8 = SysTime(dt); 4899 st8.roll!"msecs"(1); 4900 assert(st8 == SysTime(dt, msecs(1))); 4901 4902 auto st9 = SysTime(dt); 4903 st9.roll!"msecs"(-1); 4904 assert(st9 == SysTime(dt, msecs(999))); 4905 4906 auto st10 = SysTime(dt); 4907 st10.roll!"hnsecs"(1); 4908 assert(st10 == SysTime(dt, hnsecs(1))); 4909 4910 auto st11 = SysTime(dt); 4911 st11.roll!"hnsecs"(-1); 4912 assert(st11 == SysTime(dt, hnsecs(9_999_999))); 4913 } 4914 4915 @safe unittest 4916 { 4917 import core.time; 4918 // Test A.D. 4919 { 4920 auto sysTime = SysTime(Date(1999, 2, 28)); 4921 sysTime.roll!"days"(1); 4922 assert(sysTime == SysTime(Date(1999, 2, 1))); 4923 sysTime.roll!"days"(-1); 4924 assert(sysTime == SysTime(Date(1999, 2, 28))); 4925 } 4926 4927 { 4928 auto sysTime = SysTime(Date(2000, 2, 28)); 4929 sysTime.roll!"days"(1); 4930 assert(sysTime == SysTime(Date(2000, 2, 29))); 4931 sysTime.roll!"days"(1); 4932 assert(sysTime == SysTime(Date(2000, 2, 1))); 4933 sysTime.roll!"days"(-1); 4934 assert(sysTime == SysTime(Date(2000, 2, 29))); 4935 } 4936 4937 { 4938 auto sysTime = SysTime(Date(1999, 6, 30)); 4939 sysTime.roll!"days"(1); 4940 assert(sysTime == SysTime(Date(1999, 6, 1))); 4941 sysTime.roll!"days"(-1); 4942 assert(sysTime == SysTime(Date(1999, 6, 30))); 4943 } 4944 4945 { 4946 auto sysTime = SysTime(Date(1999, 7, 31)); 4947 sysTime.roll!"days"(1); 4948 assert(sysTime == SysTime(Date(1999, 7, 1))); 4949 sysTime.roll!"days"(-1); 4950 assert(sysTime == SysTime(Date(1999, 7, 31))); 4951 } 4952 4953 { 4954 auto sysTime = SysTime(Date(1999, 1, 1)); 4955 sysTime.roll!"days"(-1); 4956 assert(sysTime == SysTime(Date(1999, 1, 31))); 4957 sysTime.roll!"days"(1); 4958 assert(sysTime == SysTime(Date(1999, 1, 1))); 4959 } 4960 4961 { 4962 auto sysTime = SysTime(Date(1999, 7, 6)); 4963 sysTime.roll!"days"(9); 4964 assert(sysTime == SysTime(Date(1999, 7, 15))); 4965 sysTime.roll!"days"(-11); 4966 assert(sysTime == SysTime(Date(1999, 7, 4))); 4967 sysTime.roll!"days"(30); 4968 assert(sysTime == SysTime(Date(1999, 7, 3))); 4969 sysTime.roll!"days"(-3); 4970 assert(sysTime == SysTime(Date(1999, 7, 31))); 4971 } 4972 4973 { 4974 auto sysTime = SysTime(Date(1999, 7, 6)); 4975 sysTime.roll!"days"(365); 4976 assert(sysTime == SysTime(Date(1999, 7, 30))); 4977 sysTime.roll!"days"(-365); 4978 assert(sysTime == SysTime(Date(1999, 7, 6))); 4979 sysTime.roll!"days"(366); 4980 assert(sysTime == SysTime(Date(1999, 7, 31))); 4981 sysTime.roll!"days"(730); 4982 assert(sysTime == SysTime(Date(1999, 7, 17))); 4983 sysTime.roll!"days"(-1096); 4984 assert(sysTime == SysTime(Date(1999, 7, 6))); 4985 } 4986 4987 { 4988 auto sysTime = SysTime(Date(1999, 2, 6)); 4989 sysTime.roll!"days"(365); 4990 assert(sysTime == SysTime(Date(1999, 2, 7))); 4991 sysTime.roll!"days"(-365); 4992 assert(sysTime == SysTime(Date(1999, 2, 6))); 4993 sysTime.roll!"days"(366); 4994 assert(sysTime == SysTime(Date(1999, 2, 8))); 4995 sysTime.roll!"days"(730); 4996 assert(sysTime == SysTime(Date(1999, 2, 10))); 4997 sysTime.roll!"days"(-1096); 4998 assert(sysTime == SysTime(Date(1999, 2, 6))); 4999 } 5000 5001 { 5002 auto sysTime = SysTime(DateTime(1999, 2, 28, 7, 9, 2), usecs(234578)); 5003 sysTime.roll!"days"(1); 5004 assert(sysTime == SysTime(DateTime(1999, 2, 1, 7, 9, 2), usecs(234578))); 5005 sysTime.roll!"days"(-1); 5006 assert(sysTime == SysTime(DateTime(1999, 2, 28, 7, 9, 2), usecs(234578))); 5007 } 5008 5009 { 5010 auto sysTime = SysTime(DateTime(1999, 7, 6, 7, 9, 2), usecs(234578)); 5011 sysTime.roll!"days"(9); 5012 assert(sysTime == SysTime(DateTime(1999, 7, 15, 7, 9, 2), usecs(234578))); 5013 sysTime.roll!"days"(-11); 5014 assert(sysTime == SysTime(DateTime(1999, 7, 4, 7, 9, 2), usecs(234578))); 5015 sysTime.roll!"days"(30); 5016 assert(sysTime == SysTime(DateTime(1999, 7, 3, 7, 9, 2), usecs(234578))); 5017 sysTime.roll!"days"(-3); 5018 assert(sysTime == SysTime(DateTime(1999, 7, 31, 7, 9, 2), usecs(234578))); 5019 } 5020 5021 // Test B.C. 5022 { 5023 auto sysTime = SysTime(Date(-1999, 2, 28)); 5024 sysTime.roll!"days"(1); 5025 assert(sysTime == SysTime(Date(-1999, 2, 1))); 5026 sysTime.roll!"days"(-1); 5027 assert(sysTime == SysTime(Date(-1999, 2, 28))); 5028 } 5029 5030 { 5031 auto sysTime = SysTime(Date(-2000, 2, 28)); 5032 sysTime.roll!"days"(1); 5033 assert(sysTime == SysTime(Date(-2000, 2, 29))); 5034 sysTime.roll!"days"(1); 5035 assert(sysTime == SysTime(Date(-2000, 2, 1))); 5036 sysTime.roll!"days"(-1); 5037 assert(sysTime == SysTime(Date(-2000, 2, 29))); 5038 } 5039 5040 { 5041 auto sysTime = SysTime(Date(-1999, 6, 30)); 5042 sysTime.roll!"days"(1); 5043 assert(sysTime == SysTime(Date(-1999, 6, 1))); 5044 sysTime.roll!"days"(-1); 5045 assert(sysTime == SysTime(Date(-1999, 6, 30))); 5046 } 5047 5048 { 5049 auto sysTime = SysTime(Date(-1999, 7, 31)); 5050 sysTime.roll!"days"(1); 5051 assert(sysTime == SysTime(Date(-1999, 7, 1))); 5052 sysTime.roll!"days"(-1); 5053 assert(sysTime == SysTime(Date(-1999, 7, 31))); 5054 } 5055 5056 { 5057 auto sysTime = SysTime(Date(-1999, 1, 1)); 5058 sysTime.roll!"days"(-1); 5059 assert(sysTime == SysTime(Date(-1999, 1, 31))); 5060 sysTime.roll!"days"(1); 5061 assert(sysTime == SysTime(Date(-1999, 1, 1))); 5062 } 5063 5064 { 5065 auto sysTime = SysTime(Date(-1999, 7, 6)); 5066 sysTime.roll!"days"(9); 5067 assert(sysTime == SysTime(Date(-1999, 7, 15))); 5068 sysTime.roll!"days"(-11); 5069 assert(sysTime == SysTime(Date(-1999, 7, 4))); 5070 sysTime.roll!"days"(30); 5071 assert(sysTime == SysTime(Date(-1999, 7, 3))); 5072 sysTime.roll!"days"(-3); 5073 assert(sysTime == SysTime(Date(-1999, 7, 31))); 5074 } 5075 5076 { 5077 auto sysTime = SysTime(Date(-1999, 7, 6)); 5078 sysTime.roll!"days"(365); 5079 assert(sysTime == SysTime(Date(-1999, 7, 30))); 5080 sysTime.roll!"days"(-365); 5081 assert(sysTime == SysTime(Date(-1999, 7, 6))); 5082 sysTime.roll!"days"(366); 5083 assert(sysTime == SysTime(Date(-1999, 7, 31))); 5084 sysTime.roll!"days"(730); 5085 assert(sysTime == SysTime(Date(-1999, 7, 17))); 5086 sysTime.roll!"days"(-1096); 5087 assert(sysTime == SysTime(Date(-1999, 7, 6))); 5088 } 5089 5090 { 5091 auto sysTime = SysTime(DateTime(-1999, 2, 28, 7, 9, 2), usecs(234578)); 5092 sysTime.roll!"days"(1); 5093 assert(sysTime == SysTime(DateTime(-1999, 2, 1, 7, 9, 2), usecs(234578))); 5094 sysTime.roll!"days"(-1); 5095 assert(sysTime == SysTime(DateTime(-1999, 2, 28, 7, 9, 2), usecs(234578))); 5096 } 5097 5098 { 5099 auto sysTime = SysTime(DateTime(-1999, 7, 6, 7, 9, 2), usecs(234578)); 5100 sysTime.roll!"days"(9); 5101 assert(sysTime == SysTime(DateTime(-1999, 7, 15, 7, 9, 2), usecs(234578))); 5102 sysTime.roll!"days"(-11); 5103 assert(sysTime == SysTime(DateTime(-1999, 7, 4, 7, 9, 2), usecs(234578))); 5104 sysTime.roll!"days"(30); 5105 assert(sysTime == SysTime(DateTime(-1999, 7, 3, 7, 9, 2), usecs(234578))); 5106 sysTime.roll!"days"(-3); 5107 } 5108 5109 // Test Both 5110 { 5111 auto sysTime = SysTime(Date(1, 7, 6)); 5112 sysTime.roll!"days"(-365); 5113 assert(sysTime == SysTime(Date(1, 7, 13))); 5114 sysTime.roll!"days"(365); 5115 assert(sysTime == SysTime(Date(1, 7, 6))); 5116 sysTime.roll!"days"(-731); 5117 assert(sysTime == SysTime(Date(1, 7, 19))); 5118 sysTime.roll!"days"(730); 5119 assert(sysTime == SysTime(Date(1, 7, 5))); 5120 } 5121 5122 { 5123 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 5124 sysTime.roll!"days"(-1); 5125 assert(sysTime == SysTime(DateTime(1, 1, 31, 0, 0, 0))); 5126 sysTime.roll!"days"(1); 5127 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5128 } 5129 5130 { 5131 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 5132 sysTime.roll!"days"(-1); 5133 assert(sysTime == SysTime(DateTime(1, 1, 31, 23, 59, 59), hnsecs(9_999_999))); 5134 sysTime.roll!"days"(1); 5135 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 5136 } 5137 5138 { 5139 auto sysTime = SysTime(DateTime(0, 12, 31, 0, 0, 0)); 5140 sysTime.roll!"days"(1); 5141 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 5142 sysTime.roll!"days"(-1); 5143 assert(sysTime == SysTime(DateTime(0, 12, 31, 0, 0, 0))); 5144 } 5145 5146 { 5147 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5148 sysTime.roll!"days"(1); 5149 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 5150 sysTime.roll!"days"(-1); 5151 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5152 } 5153 5154 { 5155 auto sysTime = SysTime(DateTime(1, 7, 6, 13, 13, 9), msecs(22)); 5156 sysTime.roll!"days"(-365); 5157 assert(sysTime == SysTime(DateTime(1, 7, 13, 13, 13, 9), msecs(22))); 5158 sysTime.roll!"days"(365); 5159 assert(sysTime == SysTime(DateTime(1, 7, 6, 13, 13, 9), msecs(22))); 5160 sysTime.roll!"days"(-731); 5161 assert(sysTime == SysTime(DateTime(1, 7, 19, 13, 13, 9), msecs(22))); 5162 sysTime.roll!"days"(730); 5163 assert(sysTime == SysTime(DateTime(1, 7, 5, 13, 13, 9), msecs(22))); 5164 } 5165 5166 { 5167 auto sysTime = SysTime(DateTime(0, 7, 6, 13, 13, 9), msecs(22)); 5168 sysTime.roll!"days"(-365); 5169 assert(sysTime == SysTime(DateTime(0, 7, 13, 13, 13, 9), msecs(22))); 5170 sysTime.roll!"days"(365); 5171 assert(sysTime == SysTime(DateTime(0, 7, 6, 13, 13, 9), msecs(22))); 5172 sysTime.roll!"days"(-731); 5173 assert(sysTime == SysTime(DateTime(0, 7, 19, 13, 13, 9), msecs(22))); 5174 sysTime.roll!"days"(730); 5175 assert(sysTime == SysTime(DateTime(0, 7, 5, 13, 13, 9), msecs(22))); 5176 } 5177 5178 { 5179 auto sysTime = SysTime(DateTime(0, 7, 6, 13, 13, 9), msecs(22)); 5180 sysTime.roll!"days"(-365).roll!"days"(362).roll!"days"(-12).roll!"days"(730); 5181 assert(sysTime == SysTime(DateTime(0, 7, 8, 13, 13, 9), msecs(22))); 5182 } 5183 5184 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5185 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5186 static assert(!__traits(compiles, cst.roll!"days"(4))); 5187 static assert(!__traits(compiles, ist.roll!"days"(4))); 5188 5189 static void testScope(scope ref SysTime st) @safe 5190 { 5191 auto result = st.roll!"days"(42); 5192 } 5193 } 5194 5195 5196 // Shares documentation with "days" version. 5197 ref SysTime roll(string units)(long value) @safe nothrow scope 5198 if (units == "hours" || units == "minutes" || units == "seconds") 5199 { 5200 try 5201 { 5202 auto hnsecs = adjTime; 5203 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 5204 5205 if (hnsecs < 0) 5206 { 5207 hnsecs += convert!("hours", "hnsecs")(24); 5208 --days; 5209 } 5210 5211 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 5212 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 5213 immutable second = splitUnitsFromHNSecs!"seconds"(hnsecs); 5214 5215 auto dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour, 5216 cast(int) minute, cast(int) second)); 5217 dateTime.roll!units(value); 5218 --days; 5219 5220 hnsecs += convert!("hours", "hnsecs")(dateTime.hour); 5221 hnsecs += convert!("minutes", "hnsecs")(dateTime.minute); 5222 hnsecs += convert!("seconds", "hnsecs")(dateTime.second); 5223 5224 if (days < 0) 5225 { 5226 hnsecs -= convert!("hours", "hnsecs")(24); 5227 ++days; 5228 } 5229 5230 immutable newDaysHNSecs = convert!("days", "hnsecs")(days); 5231 adjTime = newDaysHNSecs + hnsecs; 5232 return this; 5233 } 5234 catch (Exception e) 5235 assert(0, "Either DateTime's constructor or TimeOfDay's constructor threw."); 5236 } 5237 5238 // Test roll!"hours"(). 5239 @safe unittest 5240 { 5241 import core.time; 5242 static void testST(SysTime orig, int hours, SysTime expected, size_t line = __LINE__) @safe 5243 { 5244 orig.roll!"hours"(hours); 5245 if (orig != expected) 5246 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 5247 } 5248 5249 // Test A.D. 5250 immutable d = msecs(45); 5251 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), d); 5252 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5253 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 13, 30, 33), d)); 5254 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 14, 30, 33), d)); 5255 testST(beforeAD, 3, SysTime(DateTime(1999, 7, 6, 15, 30, 33), d)); 5256 testST(beforeAD, 4, SysTime(DateTime(1999, 7, 6, 16, 30, 33), d)); 5257 testST(beforeAD, 5, SysTime(DateTime(1999, 7, 6, 17, 30, 33), d)); 5258 testST(beforeAD, 6, SysTime(DateTime(1999, 7, 6, 18, 30, 33), d)); 5259 testST(beforeAD, 7, SysTime(DateTime(1999, 7, 6, 19, 30, 33), d)); 5260 testST(beforeAD, 8, SysTime(DateTime(1999, 7, 6, 20, 30, 33), d)); 5261 testST(beforeAD, 9, SysTime(DateTime(1999, 7, 6, 21, 30, 33), d)); 5262 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 22, 30, 33), d)); 5263 testST(beforeAD, 11, SysTime(DateTime(1999, 7, 6, 23, 30, 33), d)); 5264 testST(beforeAD, 12, SysTime(DateTime(1999, 7, 6, 0, 30, 33), d)); 5265 testST(beforeAD, 13, SysTime(DateTime(1999, 7, 6, 1, 30, 33), d)); 5266 testST(beforeAD, 14, SysTime(DateTime(1999, 7, 6, 2, 30, 33), d)); 5267 testST(beforeAD, 15, SysTime(DateTime(1999, 7, 6, 3, 30, 33), d)); 5268 testST(beforeAD, 16, SysTime(DateTime(1999, 7, 6, 4, 30, 33), d)); 5269 testST(beforeAD, 17, SysTime(DateTime(1999, 7, 6, 5, 30, 33), d)); 5270 testST(beforeAD, 18, SysTime(DateTime(1999, 7, 6, 6, 30, 33), d)); 5271 testST(beforeAD, 19, SysTime(DateTime(1999, 7, 6, 7, 30, 33), d)); 5272 testST(beforeAD, 20, SysTime(DateTime(1999, 7, 6, 8, 30, 33), d)); 5273 testST(beforeAD, 21, SysTime(DateTime(1999, 7, 6, 9, 30, 33), d)); 5274 testST(beforeAD, 22, SysTime(DateTime(1999, 7, 6, 10, 30, 33), d)); 5275 testST(beforeAD, 23, SysTime(DateTime(1999, 7, 6, 11, 30, 33), d)); 5276 testST(beforeAD, 24, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5277 testST(beforeAD, 25, SysTime(DateTime(1999, 7, 6, 13, 30, 33), d)); 5278 testST(beforeAD, 50, SysTime(DateTime(1999, 7, 6, 14, 30, 33), d)); 5279 testST(beforeAD, 10_000, SysTime(DateTime(1999, 7, 6, 4, 30, 33), d)); 5280 5281 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 11, 30, 33), d)); 5282 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 10, 30, 33), d)); 5283 testST(beforeAD, -3, SysTime(DateTime(1999, 7, 6, 9, 30, 33), d)); 5284 testST(beforeAD, -4, SysTime(DateTime(1999, 7, 6, 8, 30, 33), d)); 5285 testST(beforeAD, -5, SysTime(DateTime(1999, 7, 6, 7, 30, 33), d)); 5286 testST(beforeAD, -6, SysTime(DateTime(1999, 7, 6, 6, 30, 33), d)); 5287 testST(beforeAD, -7, SysTime(DateTime(1999, 7, 6, 5, 30, 33), d)); 5288 testST(beforeAD, -8, SysTime(DateTime(1999, 7, 6, 4, 30, 33), d)); 5289 testST(beforeAD, -9, SysTime(DateTime(1999, 7, 6, 3, 30, 33), d)); 5290 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 2, 30, 33), d)); 5291 testST(beforeAD, -11, SysTime(DateTime(1999, 7, 6, 1, 30, 33), d)); 5292 testST(beforeAD, -12, SysTime(DateTime(1999, 7, 6, 0, 30, 33), d)); 5293 testST(beforeAD, -13, SysTime(DateTime(1999, 7, 6, 23, 30, 33), d)); 5294 testST(beforeAD, -14, SysTime(DateTime(1999, 7, 6, 22, 30, 33), d)); 5295 testST(beforeAD, -15, SysTime(DateTime(1999, 7, 6, 21, 30, 33), d)); 5296 testST(beforeAD, -16, SysTime(DateTime(1999, 7, 6, 20, 30, 33), d)); 5297 testST(beforeAD, -17, SysTime(DateTime(1999, 7, 6, 19, 30, 33), d)); 5298 testST(beforeAD, -18, SysTime(DateTime(1999, 7, 6, 18, 30, 33), d)); 5299 testST(beforeAD, -19, SysTime(DateTime(1999, 7, 6, 17, 30, 33), d)); 5300 testST(beforeAD, -20, SysTime(DateTime(1999, 7, 6, 16, 30, 33), d)); 5301 testST(beforeAD, -21, SysTime(DateTime(1999, 7, 6, 15, 30, 33), d)); 5302 testST(beforeAD, -22, SysTime(DateTime(1999, 7, 6, 14, 30, 33), d)); 5303 testST(beforeAD, -23, SysTime(DateTime(1999, 7, 6, 13, 30, 33), d)); 5304 testST(beforeAD, -24, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5305 testST(beforeAD, -25, SysTime(DateTime(1999, 7, 6, 11, 30, 33), d)); 5306 testST(beforeAD, -50, SysTime(DateTime(1999, 7, 6, 10, 30, 33), d)); 5307 testST(beforeAD, -10_000, SysTime(DateTime(1999, 7, 6, 20, 30, 33), d)); 5308 5309 testST(SysTime(DateTime(1999, 7, 6, 0, 30, 33), d), 1, SysTime(DateTime(1999, 7, 6, 1, 30, 33), d)); 5310 testST(SysTime(DateTime(1999, 7, 6, 0, 30, 33), d), 0, SysTime(DateTime(1999, 7, 6, 0, 30, 33), d)); 5311 testST(SysTime(DateTime(1999, 7, 6, 0, 30, 33), d), -1, SysTime(DateTime(1999, 7, 6, 23, 30, 33), d)); 5312 5313 testST(SysTime(DateTime(1999, 7, 6, 23, 30, 33), d), 1, SysTime(DateTime(1999, 7, 6, 0, 30, 33), d)); 5314 testST(SysTime(DateTime(1999, 7, 6, 23, 30, 33), d), 0, SysTime(DateTime(1999, 7, 6, 23, 30, 33), d)); 5315 testST(SysTime(DateTime(1999, 7, 6, 23, 30, 33), d), -1, SysTime(DateTime(1999, 7, 6, 22, 30, 33), d)); 5316 5317 testST(SysTime(DateTime(1999, 7, 31, 23, 30, 33), d), 1, SysTime(DateTime(1999, 7, 31, 0, 30, 33), d)); 5318 testST(SysTime(DateTime(1999, 8, 1, 0, 30, 33), d), -1, SysTime(DateTime(1999, 8, 1, 23, 30, 33), d)); 5319 5320 testST(SysTime(DateTime(1999, 12, 31, 23, 30, 33), d), 1, SysTime(DateTime(1999, 12, 31, 0, 30, 33), d)); 5321 testST(SysTime(DateTime(2000, 1, 1, 0, 30, 33), d), -1, SysTime(DateTime(2000, 1, 1, 23, 30, 33), d)); 5322 5323 testST(SysTime(DateTime(1999, 2, 28, 23, 30, 33), d), 25, SysTime(DateTime(1999, 2, 28, 0, 30, 33), d)); 5324 testST(SysTime(DateTime(1999, 3, 2, 0, 30, 33), d), -25, SysTime(DateTime(1999, 3, 2, 23, 30, 33), d)); 5325 5326 testST(SysTime(DateTime(2000, 2, 28, 23, 30, 33), d), 25, SysTime(DateTime(2000, 2, 28, 0, 30, 33), d)); 5327 testST(SysTime(DateTime(2000, 3, 1, 0, 30, 33), d), -25, SysTime(DateTime(2000, 3, 1, 23, 30, 33), d)); 5328 5329 // Test B.C. 5330 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d); 5331 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5332 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), d)); 5333 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 14, 30, 33), d)); 5334 testST(beforeBC, 3, SysTime(DateTime(-1999, 7, 6, 15, 30, 33), d)); 5335 testST(beforeBC, 4, SysTime(DateTime(-1999, 7, 6, 16, 30, 33), d)); 5336 testST(beforeBC, 5, SysTime(DateTime(-1999, 7, 6, 17, 30, 33), d)); 5337 testST(beforeBC, 6, SysTime(DateTime(-1999, 7, 6, 18, 30, 33), d)); 5338 testST(beforeBC, 7, SysTime(DateTime(-1999, 7, 6, 19, 30, 33), d)); 5339 testST(beforeBC, 8, SysTime(DateTime(-1999, 7, 6, 20, 30, 33), d)); 5340 testST(beforeBC, 9, SysTime(DateTime(-1999, 7, 6, 21, 30, 33), d)); 5341 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 22, 30, 33), d)); 5342 testST(beforeBC, 11, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d)); 5343 testST(beforeBC, 12, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d)); 5344 testST(beforeBC, 13, SysTime(DateTime(-1999, 7, 6, 1, 30, 33), d)); 5345 testST(beforeBC, 14, SysTime(DateTime(-1999, 7, 6, 2, 30, 33), d)); 5346 testST(beforeBC, 15, SysTime(DateTime(-1999, 7, 6, 3, 30, 33), d)); 5347 testST(beforeBC, 16, SysTime(DateTime(-1999, 7, 6, 4, 30, 33), d)); 5348 testST(beforeBC, 17, SysTime(DateTime(-1999, 7, 6, 5, 30, 33), d)); 5349 testST(beforeBC, 18, SysTime(DateTime(-1999, 7, 6, 6, 30, 33), d)); 5350 testST(beforeBC, 19, SysTime(DateTime(-1999, 7, 6, 7, 30, 33), d)); 5351 testST(beforeBC, 20, SysTime(DateTime(-1999, 7, 6, 8, 30, 33), d)); 5352 testST(beforeBC, 21, SysTime(DateTime(-1999, 7, 6, 9, 30, 33), d)); 5353 testST(beforeBC, 22, SysTime(DateTime(-1999, 7, 6, 10, 30, 33), d)); 5354 testST(beforeBC, 23, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), d)); 5355 testST(beforeBC, 24, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5356 testST(beforeBC, 25, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), d)); 5357 testST(beforeBC, 50, SysTime(DateTime(-1999, 7, 6, 14, 30, 33), d)); 5358 testST(beforeBC, 10_000, SysTime(DateTime(-1999, 7, 6, 4, 30, 33), d)); 5359 5360 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), d)); 5361 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 10, 30, 33), d)); 5362 testST(beforeBC, -3, SysTime(DateTime(-1999, 7, 6, 9, 30, 33), d)); 5363 testST(beforeBC, -4, SysTime(DateTime(-1999, 7, 6, 8, 30, 33), d)); 5364 testST(beforeBC, -5, SysTime(DateTime(-1999, 7, 6, 7, 30, 33), d)); 5365 testST(beforeBC, -6, SysTime(DateTime(-1999, 7, 6, 6, 30, 33), d)); 5366 testST(beforeBC, -7, SysTime(DateTime(-1999, 7, 6, 5, 30, 33), d)); 5367 testST(beforeBC, -8, SysTime(DateTime(-1999, 7, 6, 4, 30, 33), d)); 5368 testST(beforeBC, -9, SysTime(DateTime(-1999, 7, 6, 3, 30, 33), d)); 5369 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 2, 30, 33), d)); 5370 testST(beforeBC, -11, SysTime(DateTime(-1999, 7, 6, 1, 30, 33), d)); 5371 testST(beforeBC, -12, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d)); 5372 testST(beforeBC, -13, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d)); 5373 testST(beforeBC, -14, SysTime(DateTime(-1999, 7, 6, 22, 30, 33), d)); 5374 testST(beforeBC, -15, SysTime(DateTime(-1999, 7, 6, 21, 30, 33), d)); 5375 testST(beforeBC, -16, SysTime(DateTime(-1999, 7, 6, 20, 30, 33), d)); 5376 testST(beforeBC, -17, SysTime(DateTime(-1999, 7, 6, 19, 30, 33), d)); 5377 testST(beforeBC, -18, SysTime(DateTime(-1999, 7, 6, 18, 30, 33), d)); 5378 testST(beforeBC, -19, SysTime(DateTime(-1999, 7, 6, 17, 30, 33), d)); 5379 testST(beforeBC, -20, SysTime(DateTime(-1999, 7, 6, 16, 30, 33), d)); 5380 testST(beforeBC, -21, SysTime(DateTime(-1999, 7, 6, 15, 30, 33), d)); 5381 testST(beforeBC, -22, SysTime(DateTime(-1999, 7, 6, 14, 30, 33), d)); 5382 testST(beforeBC, -23, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), d)); 5383 testST(beforeBC, -24, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5384 testST(beforeBC, -25, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), d)); 5385 testST(beforeBC, -50, SysTime(DateTime(-1999, 7, 6, 10, 30, 33), d)); 5386 testST(beforeBC, -10_000, SysTime(DateTime(-1999, 7, 6, 20, 30, 33), d)); 5387 5388 testST(SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 1, 30, 33), d)); 5389 testST(SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d)); 5390 testST(SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d)); 5391 5392 testST(SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d)); 5393 testST(SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d)); 5394 testST(SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 22, 30, 33), d)); 5395 5396 testST(SysTime(DateTime(-1999, 7, 31, 23, 30, 33), d), 1, SysTime(DateTime(-1999, 7, 31, 0, 30, 33), d)); 5397 testST(SysTime(DateTime(-1999, 8, 1, 0, 30, 33), d), -1, SysTime(DateTime(-1999, 8, 1, 23, 30, 33), d)); 5398 5399 testST(SysTime(DateTime(-2001, 12, 31, 23, 30, 33), d), 1, SysTime(DateTime(-2001, 12, 31, 0, 30, 33), d)); 5400 testST(SysTime(DateTime(-2000, 1, 1, 0, 30, 33), d), -1, SysTime(DateTime(-2000, 1, 1, 23, 30, 33), d)); 5401 5402 testST(SysTime(DateTime(-2001, 2, 28, 23, 30, 33), d), 25, SysTime(DateTime(-2001, 2, 28, 0, 30, 33), d)); 5403 testST(SysTime(DateTime(-2001, 3, 2, 0, 30, 33), d), -25, SysTime(DateTime(-2001, 3, 2, 23, 30, 33), d)); 5404 5405 testST(SysTime(DateTime(-2000, 2, 28, 23, 30, 33), d), 25, SysTime(DateTime(-2000, 2, 28, 0, 30, 33), d)); 5406 testST(SysTime(DateTime(-2000, 3, 1, 0, 30, 33), d), -25, SysTime(DateTime(-2000, 3, 1, 23, 30, 33), d)); 5407 5408 // Test Both 5409 testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 17_546, SysTime(DateTime(-1, 1, 1, 13, 30, 33), d)); 5410 testST(SysTime(DateTime(1, 1, 1, 13, 30, 33), d), -17_546, SysTime(DateTime(1, 1, 1, 11, 30, 33), d)); 5411 5412 { 5413 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 5414 sysTime.roll!"hours"(-1); 5415 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 0, 0))); 5416 sysTime.roll!"hours"(1); 5417 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5418 } 5419 5420 { 5421 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 59, 59), hnsecs(9_999_999)); 5422 sysTime.roll!"hours"(-1); 5423 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 5424 sysTime.roll!"hours"(1); 5425 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 59, 59), hnsecs(9_999_999))); 5426 } 5427 5428 { 5429 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 0, 0)); 5430 sysTime.roll!"hours"(1); 5431 assert(sysTime == SysTime(DateTime(0, 12, 31, 0, 0, 0))); 5432 sysTime.roll!"hours"(-1); 5433 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 0, 0))); 5434 } 5435 5436 { 5437 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5438 sysTime.roll!"hours"(1); 5439 assert(sysTime == SysTime(DateTime(0, 12, 31, 0, 59, 59), hnsecs(9_999_999))); 5440 sysTime.roll!"hours"(-1); 5441 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5442 } 5443 5444 { 5445 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5446 sysTime.roll!"hours"(1).roll!"hours"(-67); 5447 assert(sysTime == SysTime(DateTime(0, 12, 31, 5, 59, 59), hnsecs(9_999_999))); 5448 } 5449 5450 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5451 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5452 static assert(!__traits(compiles, cst.roll!"hours"(4))); 5453 static assert(!__traits(compiles, ist.roll!"hours"(4))); 5454 5455 static void testScope(scope ref SysTime st) @safe 5456 { 5457 auto result = st.roll!"hours"(42); 5458 } 5459 } 5460 5461 // Test roll!"minutes"(). 5462 @safe unittest 5463 { 5464 import core.time; 5465 static void testST(SysTime orig, int minutes, SysTime expected, size_t line = __LINE__) @safe 5466 { 5467 orig.roll!"minutes"(minutes); 5468 if (orig != expected) 5469 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 5470 } 5471 5472 // Test A.D. 5473 immutable d = usecs(7203); 5474 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), d); 5475 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5476 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 31, 33), d)); 5477 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 32, 33), d)); 5478 testST(beforeAD, 3, SysTime(DateTime(1999, 7, 6, 12, 33, 33), d)); 5479 testST(beforeAD, 4, SysTime(DateTime(1999, 7, 6, 12, 34, 33), d)); 5480 testST(beforeAD, 5, SysTime(DateTime(1999, 7, 6, 12, 35, 33), d)); 5481 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 40, 33), d)); 5482 testST(beforeAD, 15, SysTime(DateTime(1999, 7, 6, 12, 45, 33), d)); 5483 testST(beforeAD, 29, SysTime(DateTime(1999, 7, 6, 12, 59, 33), d)); 5484 testST(beforeAD, 30, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5485 testST(beforeAD, 45, SysTime(DateTime(1999, 7, 6, 12, 15, 33), d)); 5486 testST(beforeAD, 60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5487 testST(beforeAD, 75, SysTime(DateTime(1999, 7, 6, 12, 45, 33), d)); 5488 testST(beforeAD, 90, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5489 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 10, 33), d)); 5490 5491 testST(beforeAD, 689, SysTime(DateTime(1999, 7, 6, 12, 59, 33), d)); 5492 testST(beforeAD, 690, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5493 testST(beforeAD, 691, SysTime(DateTime(1999, 7, 6, 12, 1, 33), d)); 5494 testST(beforeAD, 960, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5495 testST(beforeAD, 1439, SysTime(DateTime(1999, 7, 6, 12, 29, 33), d)); 5496 testST(beforeAD, 1440, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5497 testST(beforeAD, 1441, SysTime(DateTime(1999, 7, 6, 12, 31, 33), d)); 5498 testST(beforeAD, 2880, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5499 5500 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 29, 33), d)); 5501 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 28, 33), d)); 5502 testST(beforeAD, -3, SysTime(DateTime(1999, 7, 6, 12, 27, 33), d)); 5503 testST(beforeAD, -4, SysTime(DateTime(1999, 7, 6, 12, 26, 33), d)); 5504 testST(beforeAD, -5, SysTime(DateTime(1999, 7, 6, 12, 25, 33), d)); 5505 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 20, 33), d)); 5506 testST(beforeAD, -15, SysTime(DateTime(1999, 7, 6, 12, 15, 33), d)); 5507 testST(beforeAD, -29, SysTime(DateTime(1999, 7, 6, 12, 1, 33), d)); 5508 testST(beforeAD, -30, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5509 testST(beforeAD, -45, SysTime(DateTime(1999, 7, 6, 12, 45, 33), d)); 5510 testST(beforeAD, -60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5511 testST(beforeAD, -75, SysTime(DateTime(1999, 7, 6, 12, 15, 33), d)); 5512 testST(beforeAD, -90, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5513 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 50, 33), d)); 5514 5515 testST(beforeAD, -749, SysTime(DateTime(1999, 7, 6, 12, 1, 33), d)); 5516 testST(beforeAD, -750, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5517 testST(beforeAD, -751, SysTime(DateTime(1999, 7, 6, 12, 59, 33), d)); 5518 testST(beforeAD, -960, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5519 testST(beforeAD, -1439, SysTime(DateTime(1999, 7, 6, 12, 31, 33), d)); 5520 testST(beforeAD, -1440, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5521 testST(beforeAD, -1441, SysTime(DateTime(1999, 7, 6, 12, 29, 33), d)); 5522 testST(beforeAD, -2880, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5523 5524 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 33), d), 1, SysTime(DateTime(1999, 7, 6, 12, 1, 33), d)); 5525 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 33), d), 0, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5526 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 33), d), -1, SysTime(DateTime(1999, 7, 6, 12, 59, 33), d)); 5527 5528 testST(SysTime(DateTime(1999, 7, 6, 11, 59, 33), d), 1, SysTime(DateTime(1999, 7, 6, 11, 0, 33), d)); 5529 testST(SysTime(DateTime(1999, 7, 6, 11, 59, 33), d), 0, SysTime(DateTime(1999, 7, 6, 11, 59, 33), d)); 5530 testST(SysTime(DateTime(1999, 7, 6, 11, 59, 33), d), -1, SysTime(DateTime(1999, 7, 6, 11, 58, 33), d)); 5531 5532 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 33), d), 1, SysTime(DateTime(1999, 7, 6, 0, 1, 33), d)); 5533 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 33), d), 0, SysTime(DateTime(1999, 7, 6, 0, 0, 33), d)); 5534 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 33), d), -1, SysTime(DateTime(1999, 7, 6, 0, 59, 33), d)); 5535 5536 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 33), d), 1, SysTime(DateTime(1999, 7, 5, 23, 0, 33), d)); 5537 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 33), d), 0, SysTime(DateTime(1999, 7, 5, 23, 59, 33), d)); 5538 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 33), d), -1, SysTime(DateTime(1999, 7, 5, 23, 58, 33), d)); 5539 5540 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 33), d), 1, SysTime(DateTime(1998, 12, 31, 23, 0, 33), d)); 5541 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 33), d), 0, SysTime(DateTime(1998, 12, 31, 23, 59, 33), d)); 5542 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 33), d), -1, SysTime(DateTime(1998, 12, 31, 23, 58, 33), d)); 5543 5544 // Test B.C. 5545 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d); 5546 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5547 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), d)); 5548 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 32, 33), d)); 5549 testST(beforeBC, 3, SysTime(DateTime(-1999, 7, 6, 12, 33, 33), d)); 5550 testST(beforeBC, 4, SysTime(DateTime(-1999, 7, 6, 12, 34, 33), d)); 5551 testST(beforeBC, 5, SysTime(DateTime(-1999, 7, 6, 12, 35, 33), d)); 5552 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 40, 33), d)); 5553 testST(beforeBC, 15, SysTime(DateTime(-1999, 7, 6, 12, 45, 33), d)); 5554 testST(beforeBC, 29, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), d)); 5555 testST(beforeBC, 30, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5556 testST(beforeBC, 45, SysTime(DateTime(-1999, 7, 6, 12, 15, 33), d)); 5557 testST(beforeBC, 60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5558 testST(beforeBC, 75, SysTime(DateTime(-1999, 7, 6, 12, 45, 33), d)); 5559 testST(beforeBC, 90, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5560 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 10, 33), d)); 5561 5562 testST(beforeBC, 689, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), d)); 5563 testST(beforeBC, 690, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5564 testST(beforeBC, 691, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), d)); 5565 testST(beforeBC, 960, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5566 testST(beforeBC, 1439, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), d)); 5567 testST(beforeBC, 1440, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5568 testST(beforeBC, 1441, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), d)); 5569 testST(beforeBC, 2880, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5570 5571 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), d)); 5572 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 28, 33), d)); 5573 testST(beforeBC, -3, SysTime(DateTime(-1999, 7, 6, 12, 27, 33), d)); 5574 testST(beforeBC, -4, SysTime(DateTime(-1999, 7, 6, 12, 26, 33), d)); 5575 testST(beforeBC, -5, SysTime(DateTime(-1999, 7, 6, 12, 25, 33), d)); 5576 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 20, 33), d)); 5577 testST(beforeBC, -15, SysTime(DateTime(-1999, 7, 6, 12, 15, 33), d)); 5578 testST(beforeBC, -29, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), d)); 5579 testST(beforeBC, -30, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5580 testST(beforeBC, -45, SysTime(DateTime(-1999, 7, 6, 12, 45, 33), d)); 5581 testST(beforeBC, -60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5582 testST(beforeBC, -75, SysTime(DateTime(-1999, 7, 6, 12, 15, 33), d)); 5583 testST(beforeBC, -90, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5584 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 50, 33), d)); 5585 5586 testST(beforeBC, -749, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), d)); 5587 testST(beforeBC, -750, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5588 testST(beforeBC, -751, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), d)); 5589 testST(beforeBC, -960, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5590 testST(beforeBC, -1439, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), d)); 5591 testST(beforeBC, -1440, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5592 testST(beforeBC, -1441, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), d)); 5593 testST(beforeBC, -2880, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5594 5595 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), d)); 5596 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5597 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), d)); 5598 5599 testST(SysTime(DateTime(-1999, 7, 6, 11, 59, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 11, 0, 33), d)); 5600 testST(SysTime(DateTime(-1999, 7, 6, 11, 59, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 11, 59, 33), d)); 5601 testST(SysTime(DateTime(-1999, 7, 6, 11, 59, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 11, 58, 33), d)); 5602 5603 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 0, 1, 33), d)); 5604 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 0, 0, 33), d)); 5605 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 0, 59, 33), d)); 5606 5607 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 33), d), 1, SysTime(DateTime(-1999, 7, 5, 23, 0, 33), d)); 5608 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 33), d), 0, SysTime(DateTime(-1999, 7, 5, 23, 59, 33), d)); 5609 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 33), d), -1, SysTime(DateTime(-1999, 7, 5, 23, 58, 33), d)); 5610 5611 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 33), d), 1, SysTime(DateTime(-2000, 12, 31, 23, 0, 33), d)); 5612 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 33), d), 0, SysTime(DateTime(-2000, 12, 31, 23, 59, 33), d)); 5613 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 33), d), -1, SysTime(DateTime(-2000, 12, 31, 23, 58, 33), d)); 5614 5615 // Test Both 5616 testST(SysTime(DateTime(1, 1, 1, 0, 0, 0)), -1, SysTime(DateTime(1, 1, 1, 0, 59, 0))); 5617 testST(SysTime(DateTime(0, 12, 31, 23, 59, 0)), 1, SysTime(DateTime(0, 12, 31, 23, 0, 0))); 5618 5619 testST(SysTime(DateTime(0, 1, 1, 0, 0, 0)), -1, SysTime(DateTime(0, 1, 1, 0, 59, 0))); 5620 testST(SysTime(DateTime(-1, 12, 31, 23, 59, 0)), 1, SysTime(DateTime(-1, 12, 31, 23, 0, 0))); 5621 5622 testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 1_052_760, SysTime(DateTime(-1, 1, 1, 11, 30, 33), d)); 5623 testST(SysTime(DateTime(1, 1, 1, 13, 30, 33), d), -1_052_760, SysTime(DateTime(1, 1, 1, 13, 30, 33), d)); 5624 5625 testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 1_052_782, SysTime(DateTime(-1, 1, 1, 11, 52, 33), d)); 5626 testST(SysTime(DateTime(1, 1, 1, 13, 52, 33), d), -1_052_782, SysTime(DateTime(1, 1, 1, 13, 30, 33), d)); 5627 5628 { 5629 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 5630 sysTime.roll!"minutes"(-1); 5631 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 59, 0))); 5632 sysTime.roll!"minutes"(1); 5633 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5634 } 5635 5636 { 5637 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 59), hnsecs(9_999_999)); 5638 sysTime.roll!"minutes"(-1); 5639 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 59, 59), hnsecs(9_999_999))); 5640 sysTime.roll!"minutes"(1); 5641 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 59), hnsecs(9_999_999))); 5642 } 5643 5644 { 5645 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 0)); 5646 sysTime.roll!"minutes"(1); 5647 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 0, 0))); 5648 sysTime.roll!"minutes"(-1); 5649 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 0))); 5650 } 5651 5652 { 5653 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5654 sysTime.roll!"minutes"(1); 5655 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 0, 59), hnsecs(9_999_999))); 5656 sysTime.roll!"minutes"(-1); 5657 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5658 } 5659 5660 { 5661 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5662 sysTime.roll!"minutes"(1).roll!"minutes"(-79); 5663 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 41, 59), hnsecs(9_999_999))); 5664 } 5665 5666 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5667 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5668 static assert(!__traits(compiles, cst.roll!"minutes"(4))); 5669 static assert(!__traits(compiles, ist.roll!"minutes"(4))); 5670 5671 static void testScope(scope ref SysTime st) @safe 5672 { 5673 auto result = st.roll!"minutes"(42); 5674 } 5675 } 5676 5677 // Test roll!"seconds"(). 5678 @safe unittest 5679 { 5680 import core.time; 5681 static void testST(SysTime orig, int seconds, SysTime expected, size_t line = __LINE__) @safe 5682 { 5683 orig.roll!"seconds"(seconds); 5684 if (orig != expected) 5685 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 5686 } 5687 5688 // Test A.D. 5689 immutable d = msecs(274); 5690 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), d); 5691 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5692 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 34), d)); 5693 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 35), d)); 5694 testST(beforeAD, 3, SysTime(DateTime(1999, 7, 6, 12, 30, 36), d)); 5695 testST(beforeAD, 4, SysTime(DateTime(1999, 7, 6, 12, 30, 37), d)); 5696 testST(beforeAD, 5, SysTime(DateTime(1999, 7, 6, 12, 30, 38), d)); 5697 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 43), d)); 5698 testST(beforeAD, 15, SysTime(DateTime(1999, 7, 6, 12, 30, 48), d)); 5699 testST(beforeAD, 26, SysTime(DateTime(1999, 7, 6, 12, 30, 59), d)); 5700 testST(beforeAD, 27, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d)); 5701 testST(beforeAD, 30, SysTime(DateTime(1999, 7, 6, 12, 30, 3), d)); 5702 testST(beforeAD, 59, SysTime(DateTime(1999, 7, 6, 12, 30, 32), d)); 5703 testST(beforeAD, 60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5704 testST(beforeAD, 61, SysTime(DateTime(1999, 7, 6, 12, 30, 34), d)); 5705 5706 testST(beforeAD, 1766, SysTime(DateTime(1999, 7, 6, 12, 30, 59), d)); 5707 testST(beforeAD, 1767, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d)); 5708 testST(beforeAD, 1768, SysTime(DateTime(1999, 7, 6, 12, 30, 1), d)); 5709 testST(beforeAD, 2007, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d)); 5710 testST(beforeAD, 3599, SysTime(DateTime(1999, 7, 6, 12, 30, 32), d)); 5711 testST(beforeAD, 3600, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5712 testST(beforeAD, 3601, SysTime(DateTime(1999, 7, 6, 12, 30, 34), d)); 5713 testST(beforeAD, 7200, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5714 5715 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 32), d)); 5716 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 31), d)); 5717 testST(beforeAD, -3, SysTime(DateTime(1999, 7, 6, 12, 30, 30), d)); 5718 testST(beforeAD, -4, SysTime(DateTime(1999, 7, 6, 12, 30, 29), d)); 5719 testST(beforeAD, -5, SysTime(DateTime(1999, 7, 6, 12, 30, 28), d)); 5720 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 23), d)); 5721 testST(beforeAD, -15, SysTime(DateTime(1999, 7, 6, 12, 30, 18), d)); 5722 testST(beforeAD, -33, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d)); 5723 testST(beforeAD, -34, SysTime(DateTime(1999, 7, 6, 12, 30, 59), d)); 5724 testST(beforeAD, -35, SysTime(DateTime(1999, 7, 6, 12, 30, 58), d)); 5725 testST(beforeAD, -59, SysTime(DateTime(1999, 7, 6, 12, 30, 34), d)); 5726 testST(beforeAD, -60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5727 testST(beforeAD, -61, SysTime(DateTime(1999, 7, 6, 12, 30, 32), d)); 5728 5729 testST(SysTime(DateTime(1999, 7, 6, 12, 30, 0), d), 1, SysTime(DateTime(1999, 7, 6, 12, 30, 1), d)); 5730 testST(SysTime(DateTime(1999, 7, 6, 12, 30, 0), d), 0, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d)); 5731 testST(SysTime(DateTime(1999, 7, 6, 12, 30, 0), d), -1, SysTime(DateTime(1999, 7, 6, 12, 30, 59), d)); 5732 5733 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 0), d), 1, SysTime(DateTime(1999, 7, 6, 12, 0, 1), d)); 5734 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 0), d), 0, SysTime(DateTime(1999, 7, 6, 12, 0, 0), d)); 5735 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 0), d), -1, SysTime(DateTime(1999, 7, 6, 12, 0, 59), d)); 5736 5737 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 0), d), 1, SysTime(DateTime(1999, 7, 6, 0, 0, 1), d)); 5738 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 0), d), 0, SysTime(DateTime(1999, 7, 6, 0, 0, 0), d)); 5739 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 0), d), -1, SysTime(DateTime(1999, 7, 6, 0, 0, 59), d)); 5740 5741 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 59), d), 1, SysTime(DateTime(1999, 7, 5, 23, 59, 0), d)); 5742 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 59), d), 0, SysTime(DateTime(1999, 7, 5, 23, 59, 59), d)); 5743 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 59), d), -1, SysTime(DateTime(1999, 7, 5, 23, 59, 58), d)); 5744 5745 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 59), d), 1, SysTime(DateTime(1998, 12, 31, 23, 59, 0), d)); 5746 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 59), d), 0, SysTime(DateTime(1998, 12, 31, 23, 59, 59), d)); 5747 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 59), d), -1, SysTime(DateTime(1998, 12, 31, 23, 59, 58), d)); 5748 5749 // Test B.C. 5750 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d); 5751 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5752 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), d)); 5753 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 35), d)); 5754 testST(beforeBC, 3, SysTime(DateTime(-1999, 7, 6, 12, 30, 36), d)); 5755 testST(beforeBC, 4, SysTime(DateTime(-1999, 7, 6, 12, 30, 37), d)); 5756 testST(beforeBC, 5, SysTime(DateTime(-1999, 7, 6, 12, 30, 38), d)); 5757 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 43), d)); 5758 testST(beforeBC, 15, SysTime(DateTime(-1999, 7, 6, 12, 30, 48), d)); 5759 testST(beforeBC, 26, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), d)); 5760 testST(beforeBC, 27, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d)); 5761 testST(beforeBC, 30, SysTime(DateTime(-1999, 7, 6, 12, 30, 3), d)); 5762 testST(beforeBC, 59, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), d)); 5763 testST(beforeBC, 60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5764 testST(beforeBC, 61, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), d)); 5765 5766 testST(beforeBC, 1766, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), d)); 5767 testST(beforeBC, 1767, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d)); 5768 testST(beforeBC, 1768, SysTime(DateTime(-1999, 7, 6, 12, 30, 1), d)); 5769 testST(beforeBC, 2007, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d)); 5770 testST(beforeBC, 3599, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), d)); 5771 testST(beforeBC, 3600, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5772 testST(beforeBC, 3601, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), d)); 5773 testST(beforeBC, 7200, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5774 5775 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), d)); 5776 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 31), d)); 5777 testST(beforeBC, -3, SysTime(DateTime(-1999, 7, 6, 12, 30, 30), d)); 5778 testST(beforeBC, -4, SysTime(DateTime(-1999, 7, 6, 12, 30, 29), d)); 5779 testST(beforeBC, -5, SysTime(DateTime(-1999, 7, 6, 12, 30, 28), d)); 5780 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 23), d)); 5781 testST(beforeBC, -15, SysTime(DateTime(-1999, 7, 6, 12, 30, 18), d)); 5782 testST(beforeBC, -33, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d)); 5783 testST(beforeBC, -34, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), d)); 5784 testST(beforeBC, -35, SysTime(DateTime(-1999, 7, 6, 12, 30, 58), d)); 5785 testST(beforeBC, -59, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), d)); 5786 testST(beforeBC, -60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5787 testST(beforeBC, -61, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), d)); 5788 5789 testST(SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d), 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 1), d)); 5790 testST(SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d), 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d)); 5791 testST(SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d), -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), d)); 5792 5793 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 0), d), 1, SysTime(DateTime(-1999, 7, 6, 12, 0, 1), d)); 5794 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 0), d), 0, SysTime(DateTime(-1999, 7, 6, 12, 0, 0), d)); 5795 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 0), d), -1, SysTime(DateTime(-1999, 7, 6, 12, 0, 59), d)); 5796 5797 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 0), d), 1, SysTime(DateTime(-1999, 7, 6, 0, 0, 1), d)); 5798 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 0), d), 0, SysTime(DateTime(-1999, 7, 6, 0, 0, 0), d)); 5799 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 0), d), -1, SysTime(DateTime(-1999, 7, 6, 0, 0, 59), d)); 5800 5801 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 59), d), 1, SysTime(DateTime(-1999, 7, 5, 23, 59, 0), d)); 5802 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 59), d), 0, SysTime(DateTime(-1999, 7, 5, 23, 59, 59), d)); 5803 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 59), d), -1, SysTime(DateTime(-1999, 7, 5, 23, 59, 58), d)); 5804 5805 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 59), d), 1, SysTime(DateTime(-2000, 12, 31, 23, 59, 0), d)); 5806 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 59), d), 0, SysTime(DateTime(-2000, 12, 31, 23, 59, 59), d)); 5807 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 59), d), -1, SysTime(DateTime(-2000, 12, 31, 23, 59, 58), d)); 5808 5809 // Test Both 5810 testST(SysTime(DateTime(1, 1, 1, 0, 0, 0), d), -1, SysTime(DateTime(1, 1, 1, 0, 0, 59), d)); 5811 testST(SysTime(DateTime(0, 12, 31, 23, 59, 59), d), 1, SysTime(DateTime(0, 12, 31, 23, 59, 0), d)); 5812 5813 testST(SysTime(DateTime(0, 1, 1, 0, 0, 0), d), -1, SysTime(DateTime(0, 1, 1, 0, 0, 59), d)); 5814 testST(SysTime(DateTime(-1, 12, 31, 23, 59, 59), d), 1, SysTime(DateTime(-1, 12, 31, 23, 59, 0), d)); 5815 5816 testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 63_165_600L, SysTime(DateTime(-1, 1, 1, 11, 30, 33), d)); 5817 testST(SysTime(DateTime(1, 1, 1, 13, 30, 33), d), -63_165_600L, SysTime(DateTime(1, 1, 1, 13, 30, 33), d)); 5818 5819 testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 63_165_617L, SysTime(DateTime(-1, 1, 1, 11, 30, 50), d)); 5820 testST(SysTime(DateTime(1, 1, 1, 13, 30, 50), d), -63_165_617L, SysTime(DateTime(1, 1, 1, 13, 30, 33), d)); 5821 5822 { 5823 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 5824 sysTime.roll!"seconds"(-1); 5825 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 59))); 5826 sysTime.roll!"seconds"(1); 5827 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5828 } 5829 5830 { 5831 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(9_999_999)); 5832 sysTime.roll!"seconds"(-1); 5833 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 59), hnsecs(9_999_999))); 5834 sysTime.roll!"seconds"(1); 5835 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 5836 } 5837 5838 { 5839 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59)); 5840 sysTime.roll!"seconds"(1); 5841 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 0))); 5842 sysTime.roll!"seconds"(-1); 5843 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59))); 5844 } 5845 5846 { 5847 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5848 sysTime.roll!"seconds"(1); 5849 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 0), hnsecs(9_999_999))); 5850 sysTime.roll!"seconds"(-1); 5851 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5852 } 5853 5854 { 5855 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5856 sysTime.roll!"seconds"(1).roll!"seconds"(-102); 5857 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 18), hnsecs(9_999_999))); 5858 } 5859 5860 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5861 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5862 static assert(!__traits(compiles, cst.roll!"seconds"(4))); 5863 static assert(!__traits(compiles, ist.roll!"seconds"(4))); 5864 5865 static void testScope(scope ref SysTime st) @safe 5866 { 5867 auto result = st.roll!"seconds"(42); 5868 } 5869 } 5870 5871 5872 // Shares documentation with "days" version. 5873 ref SysTime roll(string units)(long value) @safe nothrow scope 5874 if (units == "msecs" || units == "usecs" || units == "hnsecs") 5875 { 5876 auto hnsecs = adjTime; 5877 immutable days = splitUnitsFromHNSecs!"days"(hnsecs); 5878 immutable negative = hnsecs < 0; 5879 5880 if (negative) 5881 hnsecs += convert!("hours", "hnsecs")(24); 5882 5883 immutable seconds = splitUnitsFromHNSecs!"seconds"(hnsecs); 5884 hnsecs += convert!(units, "hnsecs")(value); 5885 hnsecs %= convert!("seconds", "hnsecs")(1); 5886 5887 if (hnsecs < 0) 5888 hnsecs += convert!("seconds", "hnsecs")(1); 5889 hnsecs += convert!("seconds", "hnsecs")(seconds); 5890 5891 if (negative) 5892 hnsecs -= convert!("hours", "hnsecs")(24); 5893 5894 immutable newDaysHNSecs = convert!("days", "hnsecs")(days); 5895 adjTime = newDaysHNSecs + hnsecs; 5896 return this; 5897 } 5898 5899 5900 // Test roll!"msecs"(). 5901 @safe unittest 5902 { 5903 import core.time; 5904 static void testST(SysTime orig, int milliseconds, SysTime expected, size_t line = __LINE__) @safe 5905 { 5906 orig.roll!"msecs"(milliseconds); 5907 if (orig != expected) 5908 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 5909 } 5910 5911 // Test A.D. 5912 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274)); 5913 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274))); 5914 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(275))); 5915 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(276))); 5916 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(284))); 5917 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(374))); 5918 testST(beforeAD, 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999))); 5919 testST(beforeAD, 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5920 testST(beforeAD, 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274))); 5921 testST(beforeAD, 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(275))); 5922 testST(beforeAD, 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274))); 5923 testST(beforeAD, 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999))); 5924 testST(beforeAD, 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5925 testST(beforeAD, 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(1))); 5926 testST(beforeAD, 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999))); 5927 testST(beforeAD, 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5928 5929 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(273))); 5930 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(272))); 5931 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(264))); 5932 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(174))); 5933 testST(beforeAD, -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5934 testST(beforeAD, -275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999))); 5935 testST(beforeAD, -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274))); 5936 testST(beforeAD, -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(273))); 5937 testST(beforeAD, -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274))); 5938 testST(beforeAD, -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5939 testST(beforeAD, -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999))); 5940 testST(beforeAD, -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5941 testST(beforeAD, -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999))); 5942 5943 // Test B.C. 5944 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274)); 5945 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274))); 5946 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(275))); 5947 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(276))); 5948 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(284))); 5949 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(374))); 5950 testST(beforeBC, 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999))); 5951 testST(beforeBC, 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 5952 testST(beforeBC, 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274))); 5953 testST(beforeBC, 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(275))); 5954 testST(beforeBC, 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274))); 5955 testST(beforeBC, 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999))); 5956 testST(beforeBC, 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 5957 testST(beforeBC, 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(1))); 5958 testST(beforeBC, 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999))); 5959 testST(beforeBC, 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 5960 5961 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(273))); 5962 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(272))); 5963 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(264))); 5964 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(174))); 5965 testST(beforeBC, -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 5966 testST(beforeBC, -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999))); 5967 testST(beforeBC, -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274))); 5968 testST(beforeBC, -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(273))); 5969 testST(beforeBC, -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274))); 5970 testST(beforeBC, -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 5971 testST(beforeBC, -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999))); 5972 testST(beforeBC, -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 5973 testST(beforeBC, -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999))); 5974 5975 // Test Both 5976 auto beforeBoth1 = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 5977 testST(beforeBoth1, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), msecs(1))); 5978 testST(beforeBoth1, 0, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5979 testST(beforeBoth1, -1, SysTime(DateTime(1, 1, 1, 0, 0, 0), msecs(999))); 5980 testST(beforeBoth1, -2, SysTime(DateTime(1, 1, 1, 0, 0, 0), msecs(998))); 5981 testST(beforeBoth1, -1000, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5982 testST(beforeBoth1, -2000, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5983 testST(beforeBoth1, -2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), msecs(445))); 5984 5985 auto beforeBoth2 = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5986 testST(beforeBoth2, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_989_999))); 5987 testST(beforeBoth2, 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5988 testST(beforeBoth2, 1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9999))); 5989 testST(beforeBoth2, 2, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(19_999))); 5990 testST(beforeBoth2, 1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5991 testST(beforeBoth2, 2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5992 testST(beforeBoth2, 2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(5_549_999))); 5993 5994 { 5995 auto st = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5996 st.roll!"msecs"(1202).roll!"msecs"(-703); 5997 assert(st == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(4_989_999))); 5998 } 5999 6000 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6001 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6002 static assert(!__traits(compiles, cst.roll!"msecs"(4))); 6003 static assert(!__traits(compiles, ist.roll!"msecs"(4))); 6004 6005 static void testScope(scope ref SysTime st) @safe 6006 { 6007 auto result = st.roll!"msecs"(42); 6008 } 6009 } 6010 6011 // Test roll!"usecs"(). 6012 @safe unittest 6013 { 6014 import core.time; 6015 static void testST(SysTime orig, long microseconds, SysTime expected, size_t line = __LINE__) @safe 6016 { 6017 orig.roll!"usecs"(microseconds); 6018 if (orig != expected) 6019 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 6020 } 6021 6022 // Test A.D. 6023 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274)); 6024 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 6025 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(275))); 6026 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(276))); 6027 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(284))); 6028 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(374))); 6029 testST(beforeAD, 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(999))); 6030 testST(beforeAD, 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(1000))); 6031 testST(beforeAD, 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(1274))); 6032 testST(beforeAD, 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(1275))); 6033 testST(beforeAD, 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(2274))); 6034 testST(beforeAD, 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(26_999))); 6035 testST(beforeAD, 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(27_000))); 6036 testST(beforeAD, 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(27_001))); 6037 testST(beforeAD, 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(766_999))); 6038 testST(beforeAD, 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(767_000))); 6039 testST(beforeAD, 1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 6040 testST(beforeAD, 60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 6041 testST(beforeAD, 3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 6042 6043 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(273))); 6044 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(272))); 6045 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(264))); 6046 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(174))); 6047 testST(beforeAD, -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 6048 testST(beforeAD, -275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(999_999))); 6049 testST(beforeAD, -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(999_274))); 6050 testST(beforeAD, -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(999_273))); 6051 testST(beforeAD, -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(998_274))); 6052 testST(beforeAD, -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(967_000))); 6053 testST(beforeAD, -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(966_999))); 6054 testST(beforeAD, -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(167_000))); 6055 testST(beforeAD, -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(166_999))); 6056 testST(beforeAD, -1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 6057 testST(beforeAD, -60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 6058 testST(beforeAD, -3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 6059 6060 // Test B.C. 6061 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274)); 6062 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 6063 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(275))); 6064 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(276))); 6065 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(284))); 6066 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(374))); 6067 testST(beforeBC, 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(999))); 6068 testST(beforeBC, 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(1000))); 6069 testST(beforeBC, 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(1274))); 6070 testST(beforeBC, 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(1275))); 6071 testST(beforeBC, 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(2274))); 6072 testST(beforeBC, 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(26_999))); 6073 testST(beforeBC, 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(27_000))); 6074 testST(beforeBC, 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(27_001))); 6075 testST(beforeBC, 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(766_999))); 6076 testST(beforeBC, 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(767_000))); 6077 testST(beforeBC, 1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 6078 testST(beforeBC, 60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 6079 testST(beforeBC, 3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 6080 6081 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(273))); 6082 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(272))); 6083 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(264))); 6084 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(174))); 6085 testST(beforeBC, -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 6086 testST(beforeBC, -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(999_999))); 6087 testST(beforeBC, -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(999_274))); 6088 testST(beforeBC, -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(999_273))); 6089 testST(beforeBC, -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(998_274))); 6090 testST(beforeBC, -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(967_000))); 6091 testST(beforeBC, -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(966_999))); 6092 testST(beforeBC, -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(167_000))); 6093 testST(beforeBC, -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(166_999))); 6094 testST(beforeBC, -1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 6095 testST(beforeBC, -60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 6096 testST(beforeBC, -3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 6097 6098 // Test Both 6099 auto beforeBoth1 = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 6100 testST(beforeBoth1, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(1))); 6101 testST(beforeBoth1, 0, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6102 testST(beforeBoth1, -1, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(999_999))); 6103 testST(beforeBoth1, -2, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(999_998))); 6104 testST(beforeBoth1, -1000, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(999_000))); 6105 testST(beforeBoth1, -2000, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(998_000))); 6106 testST(beforeBoth1, -2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(997_445))); 6107 testST(beforeBoth1, -1_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6108 testST(beforeBoth1, -2_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6109 testST(beforeBoth1, -2_333_333, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(666_667))); 6110 6111 auto beforeBoth2 = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 6112 testST(beforeBoth2, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_989))); 6113 testST(beforeBoth2, 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6114 testST(beforeBoth2, 1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9))); 6115 testST(beforeBoth2, 2, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(19))); 6116 testST(beforeBoth2, 1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9999))); 6117 testST(beforeBoth2, 2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(19_999))); 6118 testST(beforeBoth2, 2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(25_549))); 6119 testST(beforeBoth2, 1_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6120 testST(beforeBoth2, 2_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6121 testST(beforeBoth2, 2_333_333, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(3_333_329))); 6122 6123 { 6124 auto st = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 6125 st.roll!"usecs"(9_020_027); 6126 assert(st == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(200_269))); 6127 } 6128 6129 { 6130 auto st = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 6131 st.roll!"usecs"(9_020_027).roll!"usecs"(-70_034); 6132 assert(st == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_499_929))); 6133 } 6134 6135 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6136 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6137 static assert(!__traits(compiles, cst.roll!"usecs"(4))); 6138 static assert(!__traits(compiles, ist.roll!"usecs"(4))); 6139 6140 static void testScope(scope ref SysTime st) @safe 6141 { 6142 auto result = st.roll!"usecs"(42); 6143 } 6144 } 6145 6146 // Test roll!"hnsecs"(). 6147 @safe unittest 6148 { 6149 import core.time; 6150 static void testST(SysTime orig, long hnsecs, SysTime expected, size_t line = __LINE__) @safe 6151 { 6152 orig.roll!"hnsecs"(hnsecs); 6153 if (orig != expected) 6154 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 6155 } 6156 6157 // Test A.D. 6158 auto dtAD = DateTime(1999, 7, 6, 12, 30, 33); 6159 auto beforeAD = SysTime(dtAD, hnsecs(274)); 6160 testST(beforeAD, 0, SysTime(dtAD, hnsecs(274))); 6161 testST(beforeAD, 1, SysTime(dtAD, hnsecs(275))); 6162 testST(beforeAD, 2, SysTime(dtAD, hnsecs(276))); 6163 testST(beforeAD, 10, SysTime(dtAD, hnsecs(284))); 6164 testST(beforeAD, 100, SysTime(dtAD, hnsecs(374))); 6165 testST(beforeAD, 725, SysTime(dtAD, hnsecs(999))); 6166 testST(beforeAD, 726, SysTime(dtAD, hnsecs(1000))); 6167 testST(beforeAD, 1000, SysTime(dtAD, hnsecs(1274))); 6168 testST(beforeAD, 1001, SysTime(dtAD, hnsecs(1275))); 6169 testST(beforeAD, 2000, SysTime(dtAD, hnsecs(2274))); 6170 testST(beforeAD, 26_725, SysTime(dtAD, hnsecs(26_999))); 6171 testST(beforeAD, 26_726, SysTime(dtAD, hnsecs(27_000))); 6172 testST(beforeAD, 26_727, SysTime(dtAD, hnsecs(27_001))); 6173 testST(beforeAD, 1_766_725, SysTime(dtAD, hnsecs(1_766_999))); 6174 testST(beforeAD, 1_766_726, SysTime(dtAD, hnsecs(1_767_000))); 6175 testST(beforeAD, 1_000_000, SysTime(dtAD, hnsecs(1_000_274))); 6176 testST(beforeAD, 60_000_000L, SysTime(dtAD, hnsecs(274))); 6177 testST(beforeAD, 3_600_000_000L, SysTime(dtAD, hnsecs(274))); 6178 testST(beforeAD, 600_000_000L, SysTime(dtAD, hnsecs(274))); 6179 testST(beforeAD, 36_000_000_000L, SysTime(dtAD, hnsecs(274))); 6180 6181 testST(beforeAD, -1, SysTime(dtAD, hnsecs(273))); 6182 testST(beforeAD, -2, SysTime(dtAD, hnsecs(272))); 6183 testST(beforeAD, -10, SysTime(dtAD, hnsecs(264))); 6184 testST(beforeAD, -100, SysTime(dtAD, hnsecs(174))); 6185 testST(beforeAD, -274, SysTime(dtAD)); 6186 testST(beforeAD, -275, SysTime(dtAD, hnsecs(9_999_999))); 6187 testST(beforeAD, -1000, SysTime(dtAD, hnsecs(9_999_274))); 6188 testST(beforeAD, -1001, SysTime(dtAD, hnsecs(9_999_273))); 6189 testST(beforeAD, -2000, SysTime(dtAD, hnsecs(9_998_274))); 6190 testST(beforeAD, -33_274, SysTime(dtAD, hnsecs(9_967_000))); 6191 testST(beforeAD, -33_275, SysTime(dtAD, hnsecs(9_966_999))); 6192 testST(beforeAD, -1_833_274, SysTime(dtAD, hnsecs(8_167_000))); 6193 testST(beforeAD, -1_833_275, SysTime(dtAD, hnsecs(8_166_999))); 6194 testST(beforeAD, -1_000_000, SysTime(dtAD, hnsecs(9_000_274))); 6195 testST(beforeAD, -60_000_000L, SysTime(dtAD, hnsecs(274))); 6196 testST(beforeAD, -3_600_000_000L, SysTime(dtAD, hnsecs(274))); 6197 testST(beforeAD, -600_000_000L, SysTime(dtAD, hnsecs(274))); 6198 testST(beforeAD, -36_000_000_000L, SysTime(dtAD, hnsecs(274))); 6199 6200 // Test B.C. 6201 auto dtBC = DateTime(-1999, 7, 6, 12, 30, 33); 6202 auto beforeBC = SysTime(dtBC, hnsecs(274)); 6203 testST(beforeBC, 0, SysTime(dtBC, hnsecs(274))); 6204 testST(beforeBC, 1, SysTime(dtBC, hnsecs(275))); 6205 testST(beforeBC, 2, SysTime(dtBC, hnsecs(276))); 6206 testST(beforeBC, 10, SysTime(dtBC, hnsecs(284))); 6207 testST(beforeBC, 100, SysTime(dtBC, hnsecs(374))); 6208 testST(beforeBC, 725, SysTime(dtBC, hnsecs(999))); 6209 testST(beforeBC, 726, SysTime(dtBC, hnsecs(1000))); 6210 testST(beforeBC, 1000, SysTime(dtBC, hnsecs(1274))); 6211 testST(beforeBC, 1001, SysTime(dtBC, hnsecs(1275))); 6212 testST(beforeBC, 2000, SysTime(dtBC, hnsecs(2274))); 6213 testST(beforeBC, 26_725, SysTime(dtBC, hnsecs(26_999))); 6214 testST(beforeBC, 26_726, SysTime(dtBC, hnsecs(27_000))); 6215 testST(beforeBC, 26_727, SysTime(dtBC, hnsecs(27_001))); 6216 testST(beforeBC, 1_766_725, SysTime(dtBC, hnsecs(1_766_999))); 6217 testST(beforeBC, 1_766_726, SysTime(dtBC, hnsecs(1_767_000))); 6218 testST(beforeBC, 1_000_000, SysTime(dtBC, hnsecs(1_000_274))); 6219 testST(beforeBC, 60_000_000L, SysTime(dtBC, hnsecs(274))); 6220 testST(beforeBC, 3_600_000_000L, SysTime(dtBC, hnsecs(274))); 6221 testST(beforeBC, 600_000_000L, SysTime(dtBC, hnsecs(274))); 6222 testST(beforeBC, 36_000_000_000L, SysTime(dtBC, hnsecs(274))); 6223 6224 testST(beforeBC, -1, SysTime(dtBC, hnsecs(273))); 6225 testST(beforeBC, -2, SysTime(dtBC, hnsecs(272))); 6226 testST(beforeBC, -10, SysTime(dtBC, hnsecs(264))); 6227 testST(beforeBC, -100, SysTime(dtBC, hnsecs(174))); 6228 testST(beforeBC, -274, SysTime(dtBC)); 6229 testST(beforeBC, -275, SysTime(dtBC, hnsecs(9_999_999))); 6230 testST(beforeBC, -1000, SysTime(dtBC, hnsecs(9_999_274))); 6231 testST(beforeBC, -1001, SysTime(dtBC, hnsecs(9_999_273))); 6232 testST(beforeBC, -2000, SysTime(dtBC, hnsecs(9_998_274))); 6233 testST(beforeBC, -33_274, SysTime(dtBC, hnsecs(9_967_000))); 6234 testST(beforeBC, -33_275, SysTime(dtBC, hnsecs(9_966_999))); 6235 testST(beforeBC, -1_833_274, SysTime(dtBC, hnsecs(8_167_000))); 6236 testST(beforeBC, -1_833_275, SysTime(dtBC, hnsecs(8_166_999))); 6237 testST(beforeBC, -1_000_000, SysTime(dtBC, hnsecs(9_000_274))); 6238 testST(beforeBC, -60_000_000L, SysTime(dtBC, hnsecs(274))); 6239 testST(beforeBC, -3_600_000_000L, SysTime(dtBC, hnsecs(274))); 6240 testST(beforeBC, -600_000_000L, SysTime(dtBC, hnsecs(274))); 6241 testST(beforeBC, -36_000_000_000L, SysTime(dtBC, hnsecs(274))); 6242 6243 // Test Both 6244 auto dtBoth1 = DateTime(1, 1, 1, 0, 0, 0); 6245 auto beforeBoth1 = SysTime(dtBoth1); 6246 testST(beforeBoth1, 1, SysTime(dtBoth1, hnsecs(1))); 6247 testST(beforeBoth1, 0, SysTime(dtBoth1)); 6248 testST(beforeBoth1, -1, SysTime(dtBoth1, hnsecs(9_999_999))); 6249 testST(beforeBoth1, -2, SysTime(dtBoth1, hnsecs(9_999_998))); 6250 testST(beforeBoth1, -1000, SysTime(dtBoth1, hnsecs(9_999_000))); 6251 testST(beforeBoth1, -2000, SysTime(dtBoth1, hnsecs(9_998_000))); 6252 testST(beforeBoth1, -2555, SysTime(dtBoth1, hnsecs(9_997_445))); 6253 testST(beforeBoth1, -1_000_000, SysTime(dtBoth1, hnsecs(9_000_000))); 6254 testST(beforeBoth1, -2_000_000, SysTime(dtBoth1, hnsecs(8_000_000))); 6255 testST(beforeBoth1, -2_333_333, SysTime(dtBoth1, hnsecs(7_666_667))); 6256 testST(beforeBoth1, -10_000_000, SysTime(dtBoth1)); 6257 testST(beforeBoth1, -20_000_000, SysTime(dtBoth1)); 6258 testST(beforeBoth1, -20_888_888, SysTime(dtBoth1, hnsecs(9_111_112))); 6259 6260 auto dtBoth2 = DateTime(0, 12, 31, 23, 59, 59); 6261 auto beforeBoth2 = SysTime(dtBoth2, hnsecs(9_999_999)); 6262 testST(beforeBoth2, -1, SysTime(dtBoth2, hnsecs(9_999_998))); 6263 testST(beforeBoth2, 0, SysTime(dtBoth2, hnsecs(9_999_999))); 6264 testST(beforeBoth2, 1, SysTime(dtBoth2)); 6265 testST(beforeBoth2, 2, SysTime(dtBoth2, hnsecs(1))); 6266 testST(beforeBoth2, 1000, SysTime(dtBoth2, hnsecs(999))); 6267 testST(beforeBoth2, 2000, SysTime(dtBoth2, hnsecs(1999))); 6268 testST(beforeBoth2, 2555, SysTime(dtBoth2, hnsecs(2554))); 6269 testST(beforeBoth2, 1_000_000, SysTime(dtBoth2, hnsecs(999_999))); 6270 testST(beforeBoth2, 2_000_000, SysTime(dtBoth2, hnsecs(1_999_999))); 6271 testST(beforeBoth2, 2_333_333, SysTime(dtBoth2, hnsecs(2_333_332))); 6272 testST(beforeBoth2, 10_000_000, SysTime(dtBoth2, hnsecs(9_999_999))); 6273 testST(beforeBoth2, 20_000_000, SysTime(dtBoth2, hnsecs(9_999_999))); 6274 testST(beforeBoth2, 20_888_888, SysTime(dtBoth2, hnsecs(888_887))); 6275 6276 { 6277 auto st = SysTime(dtBoth2, hnsecs(9_999_999)); 6278 st.roll!"hnsecs"(70_777_222).roll!"hnsecs"(-222_555_292); 6279 assert(st == SysTime(dtBoth2, hnsecs(8_221_929))); 6280 } 6281 6282 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6283 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6284 static assert(!__traits(compiles, cst.roll!"hnsecs"(4))); 6285 static assert(!__traits(compiles, ist.roll!"hnsecs"(4))); 6286 6287 static void testScope(scope ref SysTime st) @safe 6288 { 6289 auto result = st.roll!"hnsecs"(42); 6290 } 6291 } 6292 6293 6294 /++ 6295 Gives the result of adding or subtracting a $(REF Duration, core,time) 6296 from this $(LREF SysTime). 6297 6298 The legal types of arithmetic for $(LREF SysTime) using this operator 6299 are 6300 6301 $(BOOKTABLE, 6302 $(TR $(TD SysTime) $(TD +) $(TD Duration) $(TD -->) $(TD SysTime)) 6303 $(TR $(TD SysTime) $(TD -) $(TD Duration) $(TD -->) $(TD SysTime)) 6304 ) 6305 6306 Params: 6307 duration = The $(REF Duration, core,time) to add to or subtract from 6308 this $(LREF SysTime). 6309 +/ 6310 SysTime opBinary(string op)(Duration duration) @safe const pure nothrow return scope 6311 if (op == "+" || op == "-") 6312 { 6313 SysTime retval = SysTime(this._stdTime, this._timezone); 6314 immutable hnsecs = duration.total!"hnsecs"; 6315 mixin("retval._stdTime " ~ op ~ "= hnsecs;"); 6316 return retval; 6317 } 6318 6319 /// 6320 @safe unittest 6321 { 6322 import core.time : hours, seconds; 6323 import std.datetime.date : DateTime; 6324 6325 assert(SysTime(DateTime(2015, 12, 31, 23, 59, 59)) + seconds(1) == 6326 SysTime(DateTime(2016, 1, 1, 0, 0, 0))); 6327 6328 assert(SysTime(DateTime(2015, 12, 31, 23, 59, 59)) + hours(1) == 6329 SysTime(DateTime(2016, 1, 1, 0, 59, 59))); 6330 6331 assert(SysTime(DateTime(2016, 1, 1, 0, 0, 0)) - seconds(1) == 6332 SysTime(DateTime(2015, 12, 31, 23, 59, 59))); 6333 6334 assert(SysTime(DateTime(2016, 1, 1, 0, 59, 59)) - hours(1) == 6335 SysTime(DateTime(2015, 12, 31, 23, 59, 59))); 6336 } 6337 6338 @safe unittest 6339 { 6340 import core.time; 6341 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_678)); 6342 6343 assert(st + dur!"weeks"(7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33), hnsecs(2_345_678))); 6344 assert(st + dur!"weeks"(-7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33), hnsecs(2_345_678))); 6345 assert(st + dur!"days"(7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33), hnsecs(2_345_678))); 6346 assert(st + dur!"days"(-7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33), hnsecs(2_345_678))); 6347 assert(st + dur!"hours"(7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33), hnsecs(2_345_678))); 6348 assert(st + dur!"hours"(-7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33), hnsecs(2_345_678))); 6349 assert(st + dur!"minutes"(7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33), hnsecs(2_345_678))); 6350 assert(st + dur!"minutes"(-7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33), hnsecs(2_345_678))); 6351 assert(st + dur!"seconds"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40), hnsecs(2_345_678))); 6352 assert(st + dur!"seconds"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26), hnsecs(2_345_678))); 6353 assert(st + dur!"msecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_415_678))); 6354 assert(st + dur!"msecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_275_678))); 6355 assert(st + dur!"usecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_748))); 6356 assert(st + dur!"usecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_608))); 6357 assert(st + dur!"hnsecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_685))); 6358 assert(st + dur!"hnsecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_671))); 6359 6360 assert(st - dur!"weeks"(-7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33), hnsecs(2_345_678))); 6361 assert(st - dur!"weeks"(7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33), hnsecs(2_345_678))); 6362 assert(st - dur!"days"(-7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33), hnsecs(2_345_678))); 6363 assert(st - dur!"days"(7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33), hnsecs(2_345_678))); 6364 assert(st - dur!"hours"(-7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33), hnsecs(2_345_678))); 6365 assert(st - dur!"hours"(7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33), hnsecs(2_345_678))); 6366 assert(st - dur!"minutes"(-7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33), hnsecs(2_345_678))); 6367 assert(st - dur!"minutes"(7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33), hnsecs(2_345_678))); 6368 assert(st - dur!"seconds"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40), hnsecs(2_345_678))); 6369 assert(st - dur!"seconds"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26), hnsecs(2_345_678))); 6370 assert(st - dur!"msecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_415_678))); 6371 assert(st - dur!"msecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_275_678))); 6372 assert(st - dur!"usecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_748))); 6373 assert(st - dur!"usecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_608))); 6374 assert(st - dur!"hnsecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_685))); 6375 assert(st - dur!"hnsecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_671))); 6376 6377 static void testST(SysTime orig, long hnsecs, SysTime expected, size_t line = __LINE__) @safe 6378 { 6379 auto result = orig + dur!"hnsecs"(hnsecs); 6380 if (result != expected) 6381 throw new AssertError(format("Failed. actual [%s] != expected [%s]", result, expected), __FILE__, line); 6382 } 6383 6384 // Test A.D. 6385 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274)); 6386 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274))); 6387 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(275))); 6388 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(276))); 6389 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(284))); 6390 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(374))); 6391 testST(beforeAD, 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(999))); 6392 testST(beforeAD, 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1000))); 6393 testST(beforeAD, 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1274))); 6394 testST(beforeAD, 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1275))); 6395 testST(beforeAD, 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2274))); 6396 testST(beforeAD, 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(26_999))); 6397 testST(beforeAD, 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_000))); 6398 testST(beforeAD, 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_001))); 6399 testST(beforeAD, 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_766_999))); 6400 testST(beforeAD, 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_767_000))); 6401 testST(beforeAD, 1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_000_274))); 6402 testST(beforeAD, 60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 39), hnsecs(274))); 6403 testST(beforeAD, 3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 36, 33), hnsecs(274))); 6404 testST(beforeAD, 600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 31, 33), hnsecs(274))); 6405 testST(beforeAD, 36_000_000_000L, SysTime(DateTime(1999, 7, 6, 13, 30, 33), hnsecs(274))); 6406 6407 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(273))); 6408 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(272))); 6409 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(264))); 6410 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(174))); 6411 testST(beforeAD, -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 6412 testST(beforeAD, -275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_999))); 6413 testST(beforeAD, -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_274))); 6414 testST(beforeAD, -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_273))); 6415 testST(beforeAD, -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_998_274))); 6416 testST(beforeAD, -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_967_000))); 6417 testST(beforeAD, -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_966_999))); 6418 testST(beforeAD, -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_167_000))); 6419 testST(beforeAD, -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_166_999))); 6420 testST(beforeAD, -1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_000_274))); 6421 testST(beforeAD, -60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 27), hnsecs(274))); 6422 testST(beforeAD, -3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 24, 33), hnsecs(274))); 6423 testST(beforeAD, -600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 29, 33), hnsecs(274))); 6424 testST(beforeAD, -36_000_000_000L, SysTime(DateTime(1999, 7, 6, 11, 30, 33), hnsecs(274))); 6425 6426 // Test B.C. 6427 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274)); 6428 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274))); 6429 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(275))); 6430 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(276))); 6431 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(284))); 6432 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(374))); 6433 testST(beforeBC, 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(999))); 6434 testST(beforeBC, 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1000))); 6435 testST(beforeBC, 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1274))); 6436 testST(beforeBC, 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1275))); 6437 testST(beforeBC, 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(2274))); 6438 testST(beforeBC, 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(26_999))); 6439 testST(beforeBC, 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_000))); 6440 testST(beforeBC, 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_001))); 6441 testST(beforeBC, 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_766_999))); 6442 testST(beforeBC, 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_767_000))); 6443 testST(beforeBC, 1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_000_274))); 6444 testST(beforeBC, 60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 39), hnsecs(274))); 6445 testST(beforeBC, 3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 36, 33), hnsecs(274))); 6446 testST(beforeBC, 600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), hnsecs(274))); 6447 testST(beforeBC, 36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), hnsecs(274))); 6448 6449 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(273))); 6450 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(272))); 6451 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(264))); 6452 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(174))); 6453 testST(beforeBC, -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 6454 testST(beforeBC, -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_999))); 6455 testST(beforeBC, -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_274))); 6456 testST(beforeBC, -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_273))); 6457 testST(beforeBC, -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_998_274))); 6458 testST(beforeBC, -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_967_000))); 6459 testST(beforeBC, -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_966_999))); 6460 testST(beforeBC, -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_167_000))); 6461 testST(beforeBC, -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_166_999))); 6462 testST(beforeBC, -1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_000_274))); 6463 testST(beforeBC, -60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 27), hnsecs(274))); 6464 testST(beforeBC, -3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 24, 33), hnsecs(274))); 6465 testST(beforeBC, -600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), hnsecs(274))); 6466 testST(beforeBC, -36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), hnsecs(274))); 6467 6468 // Test Both 6469 auto beforeBoth1 = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 6470 testST(beforeBoth1, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 6471 testST(beforeBoth1, 0, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6472 testST(beforeBoth1, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6473 testST(beforeBoth1, -2, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998))); 6474 testST(beforeBoth1, -1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_000))); 6475 testST(beforeBoth1, -2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_998_000))); 6476 testST(beforeBoth1, -2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_997_445))); 6477 testST(beforeBoth1, -1_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_000_000))); 6478 testST(beforeBoth1, -2_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(8_000_000))); 6479 testST(beforeBoth1, -2_333_333, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(7_666_667))); 6480 testST(beforeBoth1, -10_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59))); 6481 testST(beforeBoth1, -20_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 58))); 6482 testST(beforeBoth1, -20_888_888, SysTime(DateTime(0, 12, 31, 23, 59, 57), hnsecs(9_111_112))); 6483 6484 auto beforeBoth2 = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 6485 testST(beforeBoth2, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998))); 6486 testST(beforeBoth2, 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6487 testST(beforeBoth2, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6488 testST(beforeBoth2, 2, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 6489 testST(beforeBoth2, 1000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999))); 6490 testST(beforeBoth2, 2000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1999))); 6491 testST(beforeBoth2, 2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2554))); 6492 testST(beforeBoth2, 1_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999_999))); 6493 testST(beforeBoth2, 2_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1_999_999))); 6494 testST(beforeBoth2, 2_333_333, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2_333_332))); 6495 testST(beforeBoth2, 10_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 6496 testST(beforeBoth2, 20_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 1), hnsecs(9_999_999))); 6497 testST(beforeBoth2, 20_888_888, SysTime(DateTime(1, 1, 1, 0, 0, 2), hnsecs(888_887))); 6498 6499 auto duration = dur!"seconds"(12); 6500 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6501 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6502 assert(cst + duration == SysTime(DateTime(1999, 7, 6, 12, 30, 45))); 6503 assert(ist + duration == SysTime(DateTime(1999, 7, 6, 12, 30, 45))); 6504 assert(cst - duration == SysTime(DateTime(1999, 7, 6, 12, 30, 21))); 6505 assert(ist - duration == SysTime(DateTime(1999, 7, 6, 12, 30, 21))); 6506 6507 static void testScope(scope ref SysTime st, scope ref Duration d) @safe 6508 { 6509 auto result = st + d; 6510 } 6511 } 6512 6513 6514 /++ 6515 Gives the result of adding or subtracting a $(REF Duration, core,time) from 6516 this $(LREF SysTime), as well as assigning the result to this 6517 $(LREF SysTime). 6518 6519 The legal types of arithmetic for $(LREF SysTime) using this operator are 6520 6521 $(BOOKTABLE, 6522 $(TR $(TD SysTime) $(TD +) $(TD Duration) $(TD -->) $(TD SysTime)) 6523 $(TR $(TD SysTime) $(TD -) $(TD Duration) $(TD -->) $(TD SysTime)) 6524 ) 6525 6526 Params: 6527 duration = The $(REF Duration, core,time) to add to or subtract from 6528 this $(LREF SysTime). 6529 +/ 6530 ref SysTime opOpAssign(string op)(Duration duration) @safe pure nothrow scope 6531 if (op == "+" || op == "-") 6532 { 6533 immutable hnsecs = duration.total!"hnsecs"; 6534 mixin("_stdTime " ~ op ~ "= hnsecs;"); 6535 return this; 6536 } 6537 6538 @safe unittest 6539 { 6540 import core.time; 6541 auto before = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6542 assert(before + dur!"weeks"(7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33))); 6543 assert(before + dur!"weeks"(-7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33))); 6544 assert(before + dur!"days"(7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33))); 6545 assert(before + dur!"days"(-7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33))); 6546 6547 assert(before + dur!"hours"(7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33))); 6548 assert(before + dur!"hours"(-7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33))); 6549 assert(before + dur!"minutes"(7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33))); 6550 assert(before + dur!"minutes"(-7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33))); 6551 assert(before + dur!"seconds"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40))); 6552 assert(before + dur!"seconds"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26))); 6553 assert(before + dur!"msecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(7))); 6554 assert(before + dur!"msecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), msecs(993))); 6555 assert(before + dur!"usecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(7))); 6556 assert(before + dur!"usecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), usecs(999_993))); 6557 assert(before + dur!"hnsecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(7))); 6558 assert(before + dur!"hnsecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_993))); 6559 6560 assert(before - dur!"weeks"(-7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33))); 6561 assert(before - dur!"weeks"(7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33))); 6562 assert(before - dur!"days"(-7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33))); 6563 assert(before - dur!"days"(7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33))); 6564 6565 assert(before - dur!"hours"(-7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33))); 6566 assert(before - dur!"hours"(7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33))); 6567 assert(before - dur!"minutes"(-7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33))); 6568 assert(before - dur!"minutes"(7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33))); 6569 assert(before - dur!"seconds"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40))); 6570 assert(before - dur!"seconds"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26))); 6571 assert(before - dur!"msecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(7))); 6572 assert(before - dur!"msecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), msecs(993))); 6573 assert(before - dur!"usecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(7))); 6574 assert(before - dur!"usecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), usecs(999_993))); 6575 assert(before - dur!"hnsecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(7))); 6576 assert(before - dur!"hnsecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_993))); 6577 6578 static void testST(SysTime orig, long hnsecs, SysTime expected, size_t line = __LINE__) @safe 6579 { 6580 auto r = orig += dur!"hnsecs"(hnsecs); 6581 if (orig != expected) 6582 throw new AssertError(format("Failed 1. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 6583 if (r != expected) 6584 throw new AssertError(format("Failed 2. actual [%s] != expected [%s]", r, expected), __FILE__, line); 6585 } 6586 6587 // Test A.D. 6588 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274)); 6589 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274))); 6590 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(275))); 6591 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(276))); 6592 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(284))); 6593 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(374))); 6594 testST(beforeAD, 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(999))); 6595 testST(beforeAD, 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1000))); 6596 testST(beforeAD, 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1274))); 6597 testST(beforeAD, 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1275))); 6598 testST(beforeAD, 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2274))); 6599 testST(beforeAD, 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(26_999))); 6600 testST(beforeAD, 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_000))); 6601 testST(beforeAD, 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_001))); 6602 testST(beforeAD, 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_766_999))); 6603 testST(beforeAD, 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_767_000))); 6604 testST(beforeAD, 1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_000_274))); 6605 testST(beforeAD, 60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 39), hnsecs(274))); 6606 testST(beforeAD, 3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 36, 33), hnsecs(274))); 6607 testST(beforeAD, 600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 31, 33), hnsecs(274))); 6608 testST(beforeAD, 36_000_000_000L, SysTime(DateTime(1999, 7, 6, 13, 30, 33), hnsecs(274))); 6609 6610 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(273))); 6611 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(272))); 6612 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(264))); 6613 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(174))); 6614 testST(beforeAD, -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 6615 testST(beforeAD, -275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_999))); 6616 testST(beforeAD, -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_274))); 6617 testST(beforeAD, -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_273))); 6618 testST(beforeAD, -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_998_274))); 6619 testST(beforeAD, -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_967_000))); 6620 testST(beforeAD, -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_966_999))); 6621 testST(beforeAD, -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_167_000))); 6622 testST(beforeAD, -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_166_999))); 6623 testST(beforeAD, -1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_000_274))); 6624 testST(beforeAD, -60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 27), hnsecs(274))); 6625 testST(beforeAD, -3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 24, 33), hnsecs(274))); 6626 testST(beforeAD, -600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 29, 33), hnsecs(274))); 6627 testST(beforeAD, -36_000_000_000L, SysTime(DateTime(1999, 7, 6, 11, 30, 33), hnsecs(274))); 6628 6629 // Test B.C. 6630 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274)); 6631 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274))); 6632 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(275))); 6633 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(276))); 6634 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(284))); 6635 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(374))); 6636 testST(beforeBC, 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(999))); 6637 testST(beforeBC, 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1000))); 6638 testST(beforeBC, 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1274))); 6639 testST(beforeBC, 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1275))); 6640 testST(beforeBC, 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(2274))); 6641 testST(beforeBC, 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(26_999))); 6642 testST(beforeBC, 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_000))); 6643 testST(beforeBC, 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_001))); 6644 testST(beforeBC, 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_766_999))); 6645 testST(beforeBC, 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_767_000))); 6646 testST(beforeBC, 1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_000_274))); 6647 testST(beforeBC, 60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 39), hnsecs(274))); 6648 testST(beforeBC, 3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 36, 33), hnsecs(274))); 6649 testST(beforeBC, 600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), hnsecs(274))); 6650 testST(beforeBC, 36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), hnsecs(274))); 6651 6652 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(273))); 6653 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(272))); 6654 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(264))); 6655 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(174))); 6656 testST(beforeBC, -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 6657 testST(beforeBC, -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_999))); 6658 testST(beforeBC, -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_274))); 6659 testST(beforeBC, -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_273))); 6660 testST(beforeBC, -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_998_274))); 6661 testST(beforeBC, -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_967_000))); 6662 testST(beforeBC, -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_966_999))); 6663 testST(beforeBC, -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_167_000))); 6664 testST(beforeBC, -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_166_999))); 6665 testST(beforeBC, -1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_000_274))); 6666 testST(beforeBC, -60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 27), hnsecs(274))); 6667 testST(beforeBC, -3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 24, 33), hnsecs(274))); 6668 testST(beforeBC, -600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), hnsecs(274))); 6669 testST(beforeBC, -36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), hnsecs(274))); 6670 6671 // Test Both 6672 auto beforeBoth1 = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 6673 testST(beforeBoth1, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 6674 testST(beforeBoth1, 0, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6675 testST(beforeBoth1, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6676 testST(beforeBoth1, -2, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998))); 6677 testST(beforeBoth1, -1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_000))); 6678 testST(beforeBoth1, -2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_998_000))); 6679 testST(beforeBoth1, -2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_997_445))); 6680 testST(beforeBoth1, -1_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_000_000))); 6681 testST(beforeBoth1, -2_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(8_000_000))); 6682 testST(beforeBoth1, -2_333_333, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(7_666_667))); 6683 testST(beforeBoth1, -10_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59))); 6684 testST(beforeBoth1, -20_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 58))); 6685 testST(beforeBoth1, -20_888_888, SysTime(DateTime(0, 12, 31, 23, 59, 57), hnsecs(9_111_112))); 6686 6687 auto beforeBoth2 = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 6688 testST(beforeBoth2, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998))); 6689 testST(beforeBoth2, 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6690 testST(beforeBoth2, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6691 testST(beforeBoth2, 2, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 6692 testST(beforeBoth2, 1000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999))); 6693 testST(beforeBoth2, 2000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1999))); 6694 testST(beforeBoth2, 2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2554))); 6695 testST(beforeBoth2, 1_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999_999))); 6696 testST(beforeBoth2, 2_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1_999_999))); 6697 testST(beforeBoth2, 2_333_333, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2_333_332))); 6698 testST(beforeBoth2, 10_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 6699 testST(beforeBoth2, 20_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 1), hnsecs(9_999_999))); 6700 testST(beforeBoth2, 20_888_888, SysTime(DateTime(1, 1, 1, 0, 0, 2), hnsecs(888_887))); 6701 6702 { 6703 auto st = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 6704 (st += dur!"hnsecs"(52)) += dur!"seconds"(-907); 6705 assert(st == SysTime(DateTime(0, 12, 31, 23, 44, 53), hnsecs(51))); 6706 } 6707 6708 auto duration = dur!"seconds"(12); 6709 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6710 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6711 static assert(!__traits(compiles, cst += duration)); 6712 static assert(!__traits(compiles, ist += duration)); 6713 static assert(!__traits(compiles, cst -= duration)); 6714 static assert(!__traits(compiles, ist -= duration)); 6715 6716 static void testScope(scope ref SysTime st, scope ref Duration d) @safe 6717 { 6718 auto result1 = st += d; 6719 auto result2 = st -= d; 6720 } 6721 } 6722 6723 6724 /++ 6725 Gives the difference between two $(LREF SysTime)s. 6726 6727 The legal types of arithmetic for $(LREF SysTime) using this operator 6728 are 6729 6730 $(BOOKTABLE, 6731 $(TR $(TD SysTime) $(TD -) $(TD SysTime) $(TD -->) $(TD duration)) 6732 ) 6733 +/ 6734 Duration opBinary(string op)(SysTime rhs) @safe const pure nothrow scope 6735 if (op == "-") 6736 { 6737 return dur!"hnsecs"(_stdTime - rhs._stdTime); 6738 } 6739 6740 @safe unittest 6741 { 6742 import core.time; 6743 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1998, 7, 6, 12, 30, 33)) == 6744 dur!"seconds"(31_536_000)); 6745 assert(SysTime(DateTime(1998, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6746 dur!"seconds"(-31_536_000)); 6747 6748 assert(SysTime(DateTime(1999, 8, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6749 dur!"seconds"(26_78_400)); 6750 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 8, 6, 12, 30, 33)) == 6751 dur!"seconds"(-26_78_400)); 6752 6753 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 5, 12, 30, 33)) == 6754 dur!"seconds"(86_400)); 6755 assert(SysTime(DateTime(1999, 7, 5, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6756 dur!"seconds"(-86_400)); 6757 6758 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 11, 30, 33)) == 6759 dur!"seconds"(3600)); 6760 assert(SysTime(DateTime(1999, 7, 6, 11, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6761 dur!"seconds"(-3600)); 6762 6763 assert(SysTime(DateTime(1999, 7, 6, 12, 31, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6764 dur!"seconds"(60)); 6765 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 31, 33)) == 6766 dur!"seconds"(-60)); 6767 6768 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 34)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6769 dur!"seconds"(1)); 6770 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 34)) == 6771 dur!"seconds"(-1)); 6772 6773 { 6774 auto dt = DateTime(1999, 7, 6, 12, 30, 33); 6775 assert(SysTime(dt, msecs(532)) - SysTime(dt) == msecs(532)); 6776 assert(SysTime(dt) - SysTime(dt, msecs(532)) == msecs(-532)); 6777 6778 assert(SysTime(dt, usecs(333_347)) - SysTime(dt) == usecs(333_347)); 6779 assert(SysTime(dt) - SysTime(dt, usecs(333_347)) == usecs(-333_347)); 6780 6781 assert(SysTime(dt, hnsecs(1_234_567)) - SysTime(dt) == hnsecs(1_234_567)); 6782 assert(SysTime(dt) - SysTime(dt, hnsecs(1_234_567)) == hnsecs(-1_234_567)); 6783 } 6784 6785 assert(SysTime(DateTime(1, 1, 1, 12, 30, 33)) - SysTime(DateTime(1, 1, 1, 0, 0, 0)) == dur!"seconds"(45033)); 6786 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)) - SysTime(DateTime(1, 1, 1, 12, 30, 33)) == dur!"seconds"(-45033)); 6787 assert(SysTime(DateTime(0, 12, 31, 12, 30, 33)) - SysTime(DateTime(1, 1, 1, 0, 0, 0)) == dur!"seconds"(-41367)); 6788 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)) - SysTime(DateTime(0, 12, 31, 12, 30, 33)) == dur!"seconds"(41367)); 6789 6790 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)) - SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)) == 6791 dur!"hnsecs"(1)); 6792 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)) - SysTime(DateTime(1, 1, 1, 0, 0, 0)) == 6793 dur!"hnsecs"(-1)); 6794 6795 version (Posix) 6796 { 6797 import std.datetime.timezone : PosixTimeZone; 6798 immutable tz = PosixTimeZone.getTimeZone("America/Los_Angeles"); 6799 } 6800 else version (Windows) 6801 { 6802 import std.datetime.timezone : WindowsTimeZone; 6803 immutable tz = WindowsTimeZone.getTimeZone("Pacific Standard Time"); 6804 } 6805 6806 { 6807 auto dt = DateTime(2011, 1, 13, 8, 17, 2); 6808 auto d = msecs(296); 6809 assert(SysTime(dt, d, tz) - SysTime(dt, d, tz) == Duration.zero); 6810 assert(SysTime(dt, d, tz) - SysTime(dt, d, UTC()) == hours(8)); 6811 assert(SysTime(dt, d, UTC()) - SysTime(dt, d, tz) == hours(-8)); 6812 } 6813 6814 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6815 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6816 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6817 assert(st - st == Duration.zero); 6818 assert(cst - st == Duration.zero); 6819 assert(ist - st == Duration.zero); 6820 6821 assert(st - cst == Duration.zero); 6822 assert(cst - cst == Duration.zero); 6823 assert(ist - cst == Duration.zero); 6824 6825 assert(st - ist == Duration.zero); 6826 assert(cst - ist == Duration.zero); 6827 assert(ist - ist == Duration.zero); 6828 6829 static void testScope(scope ref SysTime left, scope ref SysTime right) @safe 6830 { 6831 auto result = left - right; 6832 } 6833 } 6834 6835 6836 /++ 6837 Returns the difference between the two $(LREF SysTime)s in months. 6838 6839 To get the difference in years, subtract the year property 6840 of two $(LREF SysTime)s. To get the difference in days or weeks, 6841 subtract the $(LREF SysTime)s themselves and use the 6842 $(REF Duration, core,time) that results. Because converting between 6843 months and smaller units requires a specific date (which 6844 $(REF Duration, core,time)s don't have), getting the difference in 6845 months requires some math using both the year and month properties, so 6846 this is a convenience function for getting the difference in months. 6847 6848 Note that the number of days in the months or how far into the month 6849 either date is is irrelevant. It is the difference in the month property 6850 combined with the difference in years * 12. So, for instance, 6851 December 31st and January 1st are one month apart just as December 1st 6852 and January 31st are one month apart. 6853 6854 Params: 6855 rhs = The $(LREF SysTime) to subtract from this one. 6856 +/ 6857 int diffMonths(scope SysTime rhs) @safe const nothrow scope 6858 { 6859 return (cast(Date) this).diffMonths(cast(Date) rhs); 6860 } 6861 6862 /// 6863 @safe unittest 6864 { 6865 import core.time; 6866 import std.datetime.date : Date; 6867 6868 assert(SysTime(Date(1999, 2, 1)).diffMonths( 6869 SysTime(Date(1999, 1, 31))) == 1); 6870 6871 assert(SysTime(Date(1999, 1, 31)).diffMonths( 6872 SysTime(Date(1999, 2, 1))) == -1); 6873 6874 assert(SysTime(Date(1999, 3, 1)).diffMonths( 6875 SysTime(Date(1999, 1, 1))) == 2); 6876 6877 assert(SysTime(Date(1999, 1, 1)).diffMonths( 6878 SysTime(Date(1999, 3, 31))) == -2); 6879 } 6880 6881 @safe unittest 6882 { 6883 import core.time; 6884 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6885 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6886 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6887 assert(st.diffMonths(st) == 0); 6888 assert(cst.diffMonths(st) == 0); 6889 assert(ist.diffMonths(st) == 0); 6890 6891 assert(st.diffMonths(cst) == 0); 6892 assert(cst.diffMonths(cst) == 0); 6893 assert(ist.diffMonths(cst) == 0); 6894 6895 assert(st.diffMonths(ist) == 0); 6896 assert(cst.diffMonths(ist) == 0); 6897 assert(ist.diffMonths(ist) == 0); 6898 6899 static void testScope(scope ref SysTime left, scope ref SysTime right) @safe 6900 { 6901 auto result = left.diffMonths(right); 6902 } 6903 } 6904 6905 6906 /++ 6907 Whether this $(LREF SysTime) is in a leap year. 6908 +/ 6909 @property bool isLeapYear() @safe const nothrow scope 6910 { 6911 return (cast(Date) this).isLeapYear; 6912 } 6913 6914 @safe unittest 6915 { 6916 import core.time; 6917 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6918 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6919 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6920 assert(!st.isLeapYear); 6921 assert(!cst.isLeapYear); 6922 assert(!ist.isLeapYear); 6923 6924 static void testScope(scope ref SysTime st) @safe 6925 { 6926 auto result = st.isLeapYear; 6927 } 6928 } 6929 6930 6931 /++ 6932 Day of the week this $(LREF SysTime) is on. 6933 +/ 6934 @property DayOfWeek dayOfWeek() @safe const nothrow scope 6935 { 6936 return getDayOfWeek(dayOfGregorianCal); 6937 } 6938 6939 @safe unittest 6940 { 6941 import core.time; 6942 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6943 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6944 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6945 assert(st.dayOfWeek == DayOfWeek.tue); 6946 assert(cst.dayOfWeek == DayOfWeek.tue); 6947 assert(ist.dayOfWeek == DayOfWeek.tue); 6948 6949 static void testScope(scope ref SysTime st) @safe 6950 { 6951 auto result = st.dayOfWeek; 6952 } 6953 } 6954 6955 6956 /++ 6957 Day of the year this $(LREF SysTime) is on. 6958 +/ 6959 @property ushort dayOfYear() @safe const nothrow scope 6960 { 6961 return (cast(Date) this).dayOfYear; 6962 } 6963 6964 /// 6965 @safe unittest 6966 { 6967 import core.time; 6968 import std.datetime.date : DateTime; 6969 6970 assert(SysTime(DateTime(1999, 1, 1, 12, 22, 7)).dayOfYear == 1); 6971 assert(SysTime(DateTime(1999, 12, 31, 7, 2, 59)).dayOfYear == 365); 6972 assert(SysTime(DateTime(2000, 12, 31, 21, 20, 0)).dayOfYear == 366); 6973 } 6974 6975 @safe unittest 6976 { 6977 import core.time; 6978 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6979 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6980 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6981 assert(st.dayOfYear == 187); 6982 assert(cst.dayOfYear == 187); 6983 assert(ist.dayOfYear == 187); 6984 6985 static void testScope(scope ref SysTime st) @safe 6986 { 6987 auto result = st.dayOfYear; 6988 } 6989 } 6990 6991 6992 /++ 6993 Day of the year. 6994 6995 Params: 6996 day = The day of the year to set which day of the year this 6997 $(LREF SysTime) is on. 6998 +/ 6999 @property void dayOfYear(int day) @safe scope 7000 { 7001 immutable hnsecs = adjTime; 7002 immutable days = convert!("hnsecs", "days")(hnsecs); 7003 immutable theRest = hnsecs - convert!("days", "hnsecs")(days); 7004 7005 auto date = Date(cast(int) days); 7006 date.dayOfYear = day; 7007 7008 immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1); 7009 7010 adjTime = newDaysHNSecs + theRest; 7011 } 7012 7013 @safe unittest 7014 { 7015 import core.time; 7016 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7017 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7018 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7019 st.dayOfYear = 12; 7020 assert(st.dayOfYear == 12); 7021 static assert(!__traits(compiles, cst.dayOfYear = 12)); 7022 static assert(!__traits(compiles, ist.dayOfYear = 12)); 7023 7024 static void testScope(scope ref SysTime st) @safe 7025 { 7026 st.dayOfYear = 42; 7027 } 7028 } 7029 7030 7031 /++ 7032 The Xth day of the Gregorian Calendar that this $(LREF SysTime) is on. 7033 +/ 7034 @property int dayOfGregorianCal() @safe const nothrow scope 7035 { 7036 immutable adjustedTime = adjTime; 7037 7038 // We have to add one because 0 would be midnight, January 1st, 1 A.D., 7039 // which would be the 1st day of the Gregorian Calendar, not the 0th. So, 7040 // simply casting to days is one day off. 7041 if (adjustedTime > 0) 7042 return cast(int) getUnitsFromHNSecs!"days"(adjustedTime) + 1; 7043 7044 long hnsecs = adjustedTime; 7045 immutable days = cast(int) splitUnitsFromHNSecs!"days"(hnsecs); 7046 7047 return hnsecs == 0 ? days + 1 : days; 7048 } 7049 7050 /// 7051 @safe unittest 7052 { 7053 import core.time; 7054 import std.datetime.date : DateTime; 7055 7056 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).dayOfGregorianCal == 1); 7057 assert(SysTime(DateTime(1, 12, 31, 23, 59, 59)).dayOfGregorianCal == 365); 7058 assert(SysTime(DateTime(2, 1, 1, 2, 2, 2)).dayOfGregorianCal == 366); 7059 7060 assert(SysTime(DateTime(0, 12, 31, 7, 7, 7)).dayOfGregorianCal == 0); 7061 assert(SysTime(DateTime(0, 1, 1, 19, 30, 0)).dayOfGregorianCal == -365); 7062 assert(SysTime(DateTime(-1, 12, 31, 4, 7, 0)).dayOfGregorianCal == -366); 7063 7064 assert(SysTime(DateTime(2000, 1, 1, 9, 30, 20)).dayOfGregorianCal == 730_120); 7065 assert(SysTime(DateTime(2010, 12, 31, 15, 45, 50)).dayOfGregorianCal == 734_137); 7066 } 7067 7068 @safe unittest 7069 { 7070 import core.time; 7071 // Test A.D. 7072 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).dayOfGregorianCal == 1); 7073 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1)).dayOfGregorianCal == 1); 7074 assert(SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)).dayOfGregorianCal == 1); 7075 7076 assert(SysTime(DateTime(1, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 1); 7077 assert(SysTime(DateTime(1, 1, 2, 12, 2, 9), msecs(212)).dayOfGregorianCal == 2); 7078 assert(SysTime(DateTime(1, 2, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 32); 7079 assert(SysTime(DateTime(2, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 366); 7080 assert(SysTime(DateTime(3, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 731); 7081 assert(SysTime(DateTime(4, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 1096); 7082 assert(SysTime(DateTime(5, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 1462); 7083 assert(SysTime(DateTime(50, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 17_898); 7084 assert(SysTime(DateTime(97, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 35_065); 7085 assert(SysTime(DateTime(100, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 36_160); 7086 assert(SysTime(DateTime(101, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 36_525); 7087 assert(SysTime(DateTime(105, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 37_986); 7088 assert(SysTime(DateTime(200, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 72_684); 7089 assert(SysTime(DateTime(201, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 73_049); 7090 assert(SysTime(DateTime(300, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 109_208); 7091 assert(SysTime(DateTime(301, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 109_573); 7092 assert(SysTime(DateTime(400, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 145_732); 7093 assert(SysTime(DateTime(401, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 146_098); 7094 assert(SysTime(DateTime(500, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 182_257); 7095 assert(SysTime(DateTime(501, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 182_622); 7096 assert(SysTime(DateTime(1000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 364_878); 7097 assert(SysTime(DateTime(1001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 365_243); 7098 assert(SysTime(DateTime(1600, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 584_023); 7099 assert(SysTime(DateTime(1601, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 584_389); 7100 assert(SysTime(DateTime(1900, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 693_596); 7101 assert(SysTime(DateTime(1901, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 693_961); 7102 assert(SysTime(DateTime(1945, 11, 12, 12, 2, 9), msecs(212)).dayOfGregorianCal == 710_347); 7103 assert(SysTime(DateTime(1999, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 729_755); 7104 assert(SysTime(DateTime(2000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 730_120); 7105 assert(SysTime(DateTime(2001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 730_486); 7106 7107 assert(SysTime(DateTime(2010, 1, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_773); 7108 assert(SysTime(DateTime(2010, 1, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_803); 7109 assert(SysTime(DateTime(2010, 2, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_804); 7110 assert(SysTime(DateTime(2010, 2, 28, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_831); 7111 assert(SysTime(DateTime(2010, 3, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_832); 7112 assert(SysTime(DateTime(2010, 3, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_862); 7113 assert(SysTime(DateTime(2010, 4, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_863); 7114 assert(SysTime(DateTime(2010, 4, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_892); 7115 assert(SysTime(DateTime(2010, 5, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_893); 7116 assert(SysTime(DateTime(2010, 5, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_923); 7117 assert(SysTime(DateTime(2010, 6, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_924); 7118 assert(SysTime(DateTime(2010, 6, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_953); 7119 assert(SysTime(DateTime(2010, 7, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_954); 7120 assert(SysTime(DateTime(2010, 7, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_984); 7121 assert(SysTime(DateTime(2010, 8, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_985); 7122 assert(SysTime(DateTime(2010, 8, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_015); 7123 assert(SysTime(DateTime(2010, 9, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_016); 7124 assert(SysTime(DateTime(2010, 9, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_045); 7125 assert(SysTime(DateTime(2010, 10, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_046); 7126 assert(SysTime(DateTime(2010, 10, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_076); 7127 assert(SysTime(DateTime(2010, 11, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_077); 7128 assert(SysTime(DateTime(2010, 11, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_106); 7129 assert(SysTime(DateTime(2010, 12, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_107); 7130 assert(SysTime(DateTime(2010, 12, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_137); 7131 7132 assert(SysTime(DateTime(2012, 2, 1, 0, 0, 0)).dayOfGregorianCal == 734_534); 7133 assert(SysTime(DateTime(2012, 2, 28, 0, 0, 0)).dayOfGregorianCal == 734_561); 7134 assert(SysTime(DateTime(2012, 2, 29, 0, 0, 0)).dayOfGregorianCal == 734_562); 7135 assert(SysTime(DateTime(2012, 3, 1, 0, 0, 0)).dayOfGregorianCal == 734_563); 7136 7137 // Test B.C. 7138 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)).dayOfGregorianCal == 0); 7139 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998)).dayOfGregorianCal == 0); 7140 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59)).dayOfGregorianCal == 0); 7141 assert(SysTime(DateTime(0, 12, 31, 0, 0, 0), hnsecs(1)).dayOfGregorianCal == 0); 7142 assert(SysTime(DateTime(0, 12, 31, 0, 0, 0)).dayOfGregorianCal == 0); 7143 7144 assert(SysTime(DateTime(-1, 12, 31, 23, 59, 59), hnsecs(9_999_999)).dayOfGregorianCal == -366); 7145 assert(SysTime(DateTime(-1, 12, 31, 23, 59, 59), hnsecs(9_999_998)).dayOfGregorianCal == -366); 7146 assert(SysTime(DateTime(-1, 12, 31, 23, 59, 59)).dayOfGregorianCal == -366); 7147 assert(SysTime(DateTime(-1, 12, 31, 0, 0, 0)).dayOfGregorianCal == -366); 7148 7149 assert(SysTime(DateTime(0, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == 0); 7150 assert(SysTime(DateTime(0, 12, 30, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1); 7151 assert(SysTime(DateTime(0, 12, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -30); 7152 assert(SysTime(DateTime(0, 11, 30, 12, 2, 9), msecs(212)).dayOfGregorianCal == -31); 7153 7154 assert(SysTime(DateTime(-1, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -366); 7155 assert(SysTime(DateTime(-1, 12, 30, 12, 2, 9), msecs(212)).dayOfGregorianCal == -367); 7156 assert(SysTime(DateTime(-1, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730); 7157 assert(SysTime(DateTime(-2, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -731); 7158 assert(SysTime(DateTime(-2, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1095); 7159 assert(SysTime(DateTime(-3, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1096); 7160 assert(SysTime(DateTime(-3, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1460); 7161 assert(SysTime(DateTime(-4, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1461); 7162 assert(SysTime(DateTime(-4, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1826); 7163 assert(SysTime(DateTime(-5, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1827); 7164 assert(SysTime(DateTime(-5, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -2191); 7165 assert(SysTime(DateTime(-9, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -3652); 7166 7167 assert(SysTime(DateTime(-49, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -18_262); 7168 assert(SysTime(DateTime(-50, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -18_627); 7169 assert(SysTime(DateTime(-97, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -35_794); 7170 assert(SysTime(DateTime(-99, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -36_160); 7171 assert(SysTime(DateTime(-99, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -36_524); 7172 assert(SysTime(DateTime(-100, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -36_889); 7173 assert(SysTime(DateTime(-101, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -37_254); 7174 assert(SysTime(DateTime(-105, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -38_715); 7175 assert(SysTime(DateTime(-200, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -73_413); 7176 assert(SysTime(DateTime(-201, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -73_778); 7177 assert(SysTime(DateTime(-300, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -109_937); 7178 assert(SysTime(DateTime(-301, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -110_302); 7179 assert(SysTime(DateTime(-400, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -146_097); 7180 assert(SysTime(DateTime(-400, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -146_462); 7181 assert(SysTime(DateTime(-401, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -146_827); 7182 assert(SysTime(DateTime(-499, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -182_621); 7183 assert(SysTime(DateTime(-500, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -182_986); 7184 assert(SysTime(DateTime(-501, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -183_351); 7185 assert(SysTime(DateTime(-1000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -365_607); 7186 assert(SysTime(DateTime(-1001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -365_972); 7187 assert(SysTime(DateTime(-1599, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -584_387); 7188 assert(SysTime(DateTime(-1600, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -584_388); 7189 assert(SysTime(DateTime(-1600, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -584_753); 7190 assert(SysTime(DateTime(-1601, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -585_118); 7191 assert(SysTime(DateTime(-1900, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -694_325); 7192 assert(SysTime(DateTime(-1901, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -694_690); 7193 assert(SysTime(DateTime(-1999, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730_484); 7194 assert(SysTime(DateTime(-2000, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730_485); 7195 assert(SysTime(DateTime(-2000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730_850); 7196 assert(SysTime(DateTime(-2001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -731_215); 7197 7198 assert(SysTime(DateTime(-2010, 1, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_502); 7199 assert(SysTime(DateTime(-2010, 1, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_472); 7200 assert(SysTime(DateTime(-2010, 2, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_471); 7201 assert(SysTime(DateTime(-2010, 2, 28, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_444); 7202 assert(SysTime(DateTime(-2010, 3, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_443); 7203 assert(SysTime(DateTime(-2010, 3, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_413); 7204 assert(SysTime(DateTime(-2010, 4, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_412); 7205 assert(SysTime(DateTime(-2010, 4, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_383); 7206 assert(SysTime(DateTime(-2010, 5, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_382); 7207 assert(SysTime(DateTime(-2010, 5, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_352); 7208 assert(SysTime(DateTime(-2010, 6, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_351); 7209 assert(SysTime(DateTime(-2010, 6, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_322); 7210 assert(SysTime(DateTime(-2010, 7, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_321); 7211 assert(SysTime(DateTime(-2010, 7, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_291); 7212 assert(SysTime(DateTime(-2010, 8, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_290); 7213 assert(SysTime(DateTime(-2010, 8, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_260); 7214 assert(SysTime(DateTime(-2010, 9, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_259); 7215 assert(SysTime(DateTime(-2010, 9, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_230); 7216 assert(SysTime(DateTime(-2010, 10, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_229); 7217 assert(SysTime(DateTime(-2010, 10, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_199); 7218 assert(SysTime(DateTime(-2010, 11, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_198); 7219 assert(SysTime(DateTime(-2010, 11, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_169); 7220 assert(SysTime(DateTime(-2010, 12, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_168); 7221 assert(SysTime(DateTime(-2010, 12, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_138); 7222 7223 assert(SysTime(DateTime(-2012, 2, 1, 0, 0, 0)).dayOfGregorianCal == -735_202); 7224 assert(SysTime(DateTime(-2012, 2, 28, 0, 0, 0)).dayOfGregorianCal == -735_175); 7225 assert(SysTime(DateTime(-2012, 2, 29, 0, 0, 0)).dayOfGregorianCal == -735_174); 7226 assert(SysTime(DateTime(-2012, 3, 1, 0, 0, 0)).dayOfGregorianCal == -735_173); 7227 7228 // Start of Hebrew Calendar 7229 assert(SysTime(DateTime(-3760, 9, 7, 0, 0, 0)).dayOfGregorianCal == -1_373_427); 7230 7231 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7232 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7233 assert(cst.dayOfGregorianCal == 729_941); 7234 assert(ist.dayOfGregorianCal == 729_941); 7235 7236 static void testScope(scope ref SysTime st) @safe 7237 { 7238 auto result = st.dayOfGregorianCal; 7239 } 7240 } 7241 7242 7243 // Test that the logic for the day of the Gregorian Calendar is consistent 7244 // between Date and SysTime. 7245 @safe unittest 7246 { 7247 import core.time; 7248 void test(Date date, SysTime st, size_t line = __LINE__) 7249 { 7250 if (date.dayOfGregorianCal != st.dayOfGregorianCal) 7251 { 7252 throw new AssertError(format("Date [%s] SysTime [%s]", date.dayOfGregorianCal, st.dayOfGregorianCal), 7253 __FILE__, line); 7254 } 7255 } 7256 7257 // Test A.D. 7258 test(Date(1, 1, 1), SysTime(DateTime(1, 1, 1, 0, 0, 0))); 7259 test(Date(1, 1, 2), SysTime(DateTime(1, 1, 2, 0, 0, 0), hnsecs(500))); 7260 test(Date(1, 2, 1), SysTime(DateTime(1, 2, 1, 0, 0, 0), hnsecs(50_000))); 7261 test(Date(2, 1, 1), SysTime(DateTime(2, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 7262 test(Date(3, 1, 1), SysTime(DateTime(3, 1, 1, 12, 13, 14))); 7263 test(Date(4, 1, 1), SysTime(DateTime(4, 1, 1, 12, 13, 14), hnsecs(500))); 7264 test(Date(5, 1, 1), SysTime(DateTime(5, 1, 1, 12, 13, 14), hnsecs(50_000))); 7265 test(Date(50, 1, 1), SysTime(DateTime(50, 1, 1, 12, 13, 14), hnsecs(9_999_999))); 7266 test(Date(97, 1, 1), SysTime(DateTime(97, 1, 1, 23, 59, 59))); 7267 test(Date(100, 1, 1), SysTime(DateTime(100, 1, 1, 23, 59, 59), hnsecs(500))); 7268 test(Date(101, 1, 1), SysTime(DateTime(101, 1, 1, 23, 59, 59), hnsecs(50_000))); 7269 test(Date(105, 1, 1), SysTime(DateTime(105, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7270 test(Date(200, 1, 1), SysTime(DateTime(200, 1, 1, 0, 0, 0))); 7271 test(Date(201, 1, 1), SysTime(DateTime(201, 1, 1, 0, 0, 0), hnsecs(500))); 7272 test(Date(300, 1, 1), SysTime(DateTime(300, 1, 1, 0, 0, 0), hnsecs(50_000))); 7273 test(Date(301, 1, 1), SysTime(DateTime(301, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 7274 test(Date(400, 1, 1), SysTime(DateTime(400, 1, 1, 12, 13, 14))); 7275 test(Date(401, 1, 1), SysTime(DateTime(401, 1, 1, 12, 13, 14), hnsecs(500))); 7276 test(Date(500, 1, 1), SysTime(DateTime(500, 1, 1, 12, 13, 14), hnsecs(50_000))); 7277 test(Date(501, 1, 1), SysTime(DateTime(501, 1, 1, 12, 13, 14), hnsecs(9_999_999))); 7278 test(Date(1000, 1, 1), SysTime(DateTime(1000, 1, 1, 23, 59, 59))); 7279 test(Date(1001, 1, 1), SysTime(DateTime(1001, 1, 1, 23, 59, 59), hnsecs(500))); 7280 test(Date(1600, 1, 1), SysTime(DateTime(1600, 1, 1, 23, 59, 59), hnsecs(50_000))); 7281 test(Date(1601, 1, 1), SysTime(DateTime(1601, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7282 test(Date(1900, 1, 1), SysTime(DateTime(1900, 1, 1, 0, 0, 0))); 7283 test(Date(1901, 1, 1), SysTime(DateTime(1901, 1, 1, 0, 0, 0), hnsecs(500))); 7284 test(Date(1945, 11, 12), SysTime(DateTime(1945, 11, 12, 0, 0, 0), hnsecs(50_000))); 7285 test(Date(1999, 1, 1), SysTime(DateTime(1999, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 7286 test(Date(1999, 7, 6), SysTime(DateTime(1999, 7, 6, 12, 13, 14))); 7287 test(Date(2000, 1, 1), SysTime(DateTime(2000, 1, 1, 12, 13, 14), hnsecs(500))); 7288 test(Date(2001, 1, 1), SysTime(DateTime(2001, 1, 1, 12, 13, 14), hnsecs(50_000))); 7289 7290 test(Date(2010, 1, 1), SysTime(DateTime(2010, 1, 1, 12, 13, 14), hnsecs(9_999_999))); 7291 test(Date(2010, 1, 31), SysTime(DateTime(2010, 1, 31, 23, 0, 0))); 7292 test(Date(2010, 2, 1), SysTime(DateTime(2010, 2, 1, 23, 59, 59), hnsecs(500))); 7293 test(Date(2010, 2, 28), SysTime(DateTime(2010, 2, 28, 23, 59, 59), hnsecs(50_000))); 7294 test(Date(2010, 3, 1), SysTime(DateTime(2010, 3, 1, 23, 59, 59), hnsecs(9_999_999))); 7295 test(Date(2010, 3, 31), SysTime(DateTime(2010, 3, 31, 0, 0, 0))); 7296 test(Date(2010, 4, 1), SysTime(DateTime(2010, 4, 1, 0, 0, 0), hnsecs(500))); 7297 test(Date(2010, 4, 30), SysTime(DateTime(2010, 4, 30, 0, 0, 0), hnsecs(50_000))); 7298 test(Date(2010, 5, 1), SysTime(DateTime(2010, 5, 1, 0, 0, 0), hnsecs(9_999_999))); 7299 test(Date(2010, 5, 31), SysTime(DateTime(2010, 5, 31, 12, 13, 14))); 7300 test(Date(2010, 6, 1), SysTime(DateTime(2010, 6, 1, 12, 13, 14), hnsecs(500))); 7301 test(Date(2010, 6, 30), SysTime(DateTime(2010, 6, 30, 12, 13, 14), hnsecs(50_000))); 7302 test(Date(2010, 7, 1), SysTime(DateTime(2010, 7, 1, 12, 13, 14), hnsecs(9_999_999))); 7303 test(Date(2010, 7, 31), SysTime(DateTime(2010, 7, 31, 23, 59, 59))); 7304 test(Date(2010, 8, 1), SysTime(DateTime(2010, 8, 1, 23, 59, 59), hnsecs(500))); 7305 test(Date(2010, 8, 31), SysTime(DateTime(2010, 8, 31, 23, 59, 59), hnsecs(50_000))); 7306 test(Date(2010, 9, 1), SysTime(DateTime(2010, 9, 1, 23, 59, 59), hnsecs(9_999_999))); 7307 test(Date(2010, 9, 30), SysTime(DateTime(2010, 9, 30, 12, 0, 0))); 7308 test(Date(2010, 10, 1), SysTime(DateTime(2010, 10, 1, 0, 12, 0), hnsecs(500))); 7309 test(Date(2010, 10, 31), SysTime(DateTime(2010, 10, 31, 0, 0, 12), hnsecs(50_000))); 7310 test(Date(2010, 11, 1), SysTime(DateTime(2010, 11, 1, 23, 0, 0), hnsecs(9_999_999))); 7311 test(Date(2010, 11, 30), SysTime(DateTime(2010, 11, 30, 0, 59, 0))); 7312 test(Date(2010, 12, 1), SysTime(DateTime(2010, 12, 1, 0, 0, 59), hnsecs(500))); 7313 test(Date(2010, 12, 31), SysTime(DateTime(2010, 12, 31, 0, 59, 59), hnsecs(50_000))); 7314 7315 test(Date(2012, 2, 1), SysTime(DateTime(2012, 2, 1, 23, 0, 59), hnsecs(9_999_999))); 7316 test(Date(2012, 2, 28), SysTime(DateTime(2012, 2, 28, 23, 59, 0))); 7317 test(Date(2012, 2, 29), SysTime(DateTime(2012, 2, 29, 7, 7, 7), hnsecs(7))); 7318 test(Date(2012, 3, 1), SysTime(DateTime(2012, 3, 1, 7, 7, 7), hnsecs(7))); 7319 7320 // Test B.C. 7321 test(Date(0, 12, 31), SysTime(DateTime(0, 12, 31, 0, 0, 0))); 7322 test(Date(0, 12, 30), SysTime(DateTime(0, 12, 30, 0, 0, 0), hnsecs(500))); 7323 test(Date(0, 12, 1), SysTime(DateTime(0, 12, 1, 0, 0, 0), hnsecs(50_000))); 7324 test(Date(0, 11, 30), SysTime(DateTime(0, 11, 30, 0, 0, 0), hnsecs(9_999_999))); 7325 7326 test(Date(-1, 12, 31), SysTime(DateTime(-1, 12, 31, 12, 13, 14))); 7327 test(Date(-1, 12, 30), SysTime(DateTime(-1, 12, 30, 12, 13, 14), hnsecs(500))); 7328 test(Date(-1, 1, 1), SysTime(DateTime(-1, 1, 1, 12, 13, 14), hnsecs(50_000))); 7329 test(Date(-2, 12, 31), SysTime(DateTime(-2, 12, 31, 12, 13, 14), hnsecs(9_999_999))); 7330 test(Date(-2, 1, 1), SysTime(DateTime(-2, 1, 1, 23, 59, 59))); 7331 test(Date(-3, 12, 31), SysTime(DateTime(-3, 12, 31, 23, 59, 59), hnsecs(500))); 7332 test(Date(-3, 1, 1), SysTime(DateTime(-3, 1, 1, 23, 59, 59), hnsecs(50_000))); 7333 test(Date(-4, 12, 31), SysTime(DateTime(-4, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 7334 test(Date(-4, 1, 1), SysTime(DateTime(-4, 1, 1, 0, 0, 0))); 7335 test(Date(-5, 12, 31), SysTime(DateTime(-5, 12, 31, 0, 0, 0), hnsecs(500))); 7336 test(Date(-5, 1, 1), SysTime(DateTime(-5, 1, 1, 0, 0, 0), hnsecs(50_000))); 7337 test(Date(-9, 1, 1), SysTime(DateTime(-9, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 7338 7339 test(Date(-49, 1, 1), SysTime(DateTime(-49, 1, 1, 12, 13, 14))); 7340 test(Date(-50, 1, 1), SysTime(DateTime(-50, 1, 1, 12, 13, 14), hnsecs(500))); 7341 test(Date(-97, 1, 1), SysTime(DateTime(-97, 1, 1, 12, 13, 14), hnsecs(50_000))); 7342 test(Date(-99, 12, 31), SysTime(DateTime(-99, 12, 31, 12, 13, 14), hnsecs(9_999_999))); 7343 test(Date(-99, 1, 1), SysTime(DateTime(-99, 1, 1, 23, 59, 59))); 7344 test(Date(-100, 1, 1), SysTime(DateTime(-100, 1, 1, 23, 59, 59), hnsecs(500))); 7345 test(Date(-101, 1, 1), SysTime(DateTime(-101, 1, 1, 23, 59, 59), hnsecs(50_000))); 7346 test(Date(-105, 1, 1), SysTime(DateTime(-105, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7347 test(Date(-200, 1, 1), SysTime(DateTime(-200, 1, 1, 0, 0, 0))); 7348 test(Date(-201, 1, 1), SysTime(DateTime(-201, 1, 1, 0, 0, 0), hnsecs(500))); 7349 test(Date(-300, 1, 1), SysTime(DateTime(-300, 1, 1, 0, 0, 0), hnsecs(50_000))); 7350 test(Date(-301, 1, 1), SysTime(DateTime(-301, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 7351 test(Date(-400, 12, 31), SysTime(DateTime(-400, 12, 31, 12, 13, 14))); 7352 test(Date(-400, 1, 1), SysTime(DateTime(-400, 1, 1, 12, 13, 14), hnsecs(500))); 7353 test(Date(-401, 1, 1), SysTime(DateTime(-401, 1, 1, 12, 13, 14), hnsecs(50_000))); 7354 test(Date(-499, 1, 1), SysTime(DateTime(-499, 1, 1, 12, 13, 14), hnsecs(9_999_999))); 7355 test(Date(-500, 1, 1), SysTime(DateTime(-500, 1, 1, 23, 59, 59))); 7356 test(Date(-501, 1, 1), SysTime(DateTime(-501, 1, 1, 23, 59, 59), hnsecs(500))); 7357 test(Date(-1000, 1, 1), SysTime(DateTime(-1000, 1, 1, 23, 59, 59), hnsecs(50_000))); 7358 test(Date(-1001, 1, 1), SysTime(DateTime(-1001, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7359 test(Date(-1599, 1, 1), SysTime(DateTime(-1599, 1, 1, 0, 0, 0))); 7360 test(Date(-1600, 12, 31), SysTime(DateTime(-1600, 12, 31, 0, 0, 0), hnsecs(500))); 7361 test(Date(-1600, 1, 1), SysTime(DateTime(-1600, 1, 1, 0, 0, 0), hnsecs(50_000))); 7362 test(Date(-1601, 1, 1), SysTime(DateTime(-1601, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 7363 test(Date(-1900, 1, 1), SysTime(DateTime(-1900, 1, 1, 12, 13, 14))); 7364 test(Date(-1901, 1, 1), SysTime(DateTime(-1901, 1, 1, 12, 13, 14), hnsecs(500))); 7365 test(Date(-1999, 1, 1), SysTime(DateTime(-1999, 1, 1, 12, 13, 14), hnsecs(50_000))); 7366 test(Date(-1999, 7, 6), SysTime(DateTime(-1999, 7, 6, 12, 13, 14), hnsecs(9_999_999))); 7367 test(Date(-2000, 12, 31), SysTime(DateTime(-2000, 12, 31, 23, 59, 59))); 7368 test(Date(-2000, 1, 1), SysTime(DateTime(-2000, 1, 1, 23, 59, 59), hnsecs(500))); 7369 test(Date(-2001, 1, 1), SysTime(DateTime(-2001, 1, 1, 23, 59, 59), hnsecs(50_000))); 7370 7371 test(Date(-2010, 1, 1), SysTime(DateTime(-2010, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7372 test(Date(-2010, 1, 31), SysTime(DateTime(-2010, 1, 31, 0, 0, 0))); 7373 test(Date(-2010, 2, 1), SysTime(DateTime(-2010, 2, 1, 0, 0, 0), hnsecs(500))); 7374 test(Date(-2010, 2, 28), SysTime(DateTime(-2010, 2, 28, 0, 0, 0), hnsecs(50_000))); 7375 test(Date(-2010, 3, 1), SysTime(DateTime(-2010, 3, 1, 0, 0, 0), hnsecs(9_999_999))); 7376 test(Date(-2010, 3, 31), SysTime(DateTime(-2010, 3, 31, 12, 13, 14))); 7377 test(Date(-2010, 4, 1), SysTime(DateTime(-2010, 4, 1, 12, 13, 14), hnsecs(500))); 7378 test(Date(-2010, 4, 30), SysTime(DateTime(-2010, 4, 30, 12, 13, 14), hnsecs(50_000))); 7379 test(Date(-2010, 5, 1), SysTime(DateTime(-2010, 5, 1, 12, 13, 14), hnsecs(9_999_999))); 7380 test(Date(-2010, 5, 31), SysTime(DateTime(-2010, 5, 31, 23, 59, 59))); 7381 test(Date(-2010, 6, 1), SysTime(DateTime(-2010, 6, 1, 23, 59, 59), hnsecs(500))); 7382 test(Date(-2010, 6, 30), SysTime(DateTime(-2010, 6, 30, 23, 59, 59), hnsecs(50_000))); 7383 test(Date(-2010, 7, 1), SysTime(DateTime(-2010, 7, 1, 23, 59, 59), hnsecs(9_999_999))); 7384 test(Date(-2010, 7, 31), SysTime(DateTime(-2010, 7, 31, 0, 0, 0))); 7385 test(Date(-2010, 8, 1), SysTime(DateTime(-2010, 8, 1, 0, 0, 0), hnsecs(500))); 7386 test(Date(-2010, 8, 31), SysTime(DateTime(-2010, 8, 31, 0, 0, 0), hnsecs(50_000))); 7387 test(Date(-2010, 9, 1), SysTime(DateTime(-2010, 9, 1, 0, 0, 0), hnsecs(9_999_999))); 7388 test(Date(-2010, 9, 30), SysTime(DateTime(-2010, 9, 30, 12, 0, 0))); 7389 test(Date(-2010, 10, 1), SysTime(DateTime(-2010, 10, 1, 0, 12, 0), hnsecs(500))); 7390 test(Date(-2010, 10, 31), SysTime(DateTime(-2010, 10, 31, 0, 0, 12), hnsecs(50_000))); 7391 test(Date(-2010, 11, 1), SysTime(DateTime(-2010, 11, 1, 23, 0, 0), hnsecs(9_999_999))); 7392 test(Date(-2010, 11, 30), SysTime(DateTime(-2010, 11, 30, 0, 59, 0))); 7393 test(Date(-2010, 12, 1), SysTime(DateTime(-2010, 12, 1, 0, 0, 59), hnsecs(500))); 7394 test(Date(-2010, 12, 31), SysTime(DateTime(-2010, 12, 31, 0, 59, 59), hnsecs(50_000))); 7395 7396 test(Date(-2012, 2, 1), SysTime(DateTime(-2012, 2, 1, 23, 0, 59), hnsecs(9_999_999))); 7397 test(Date(-2012, 2, 28), SysTime(DateTime(-2012, 2, 28, 23, 59, 0))); 7398 test(Date(-2012, 2, 29), SysTime(DateTime(-2012, 2, 29, 7, 7, 7), hnsecs(7))); 7399 test(Date(-2012, 3, 1), SysTime(DateTime(-2012, 3, 1, 7, 7, 7), hnsecs(7))); 7400 7401 test(Date(-3760, 9, 7), SysTime(DateTime(-3760, 9, 7, 0, 0, 0))); 7402 } 7403 7404 7405 /++ 7406 The Xth day of the Gregorian Calendar that this $(LREF SysTime) is on. 7407 Setting this property does not affect the time portion of $(LREF SysTime). 7408 7409 Params: 7410 days = The day of the Gregorian Calendar to set this $(LREF SysTime) 7411 to. 7412 +/ 7413 @property void dayOfGregorianCal(int days) @safe nothrow scope 7414 { 7415 auto hnsecs = adjTime; 7416 hnsecs = removeUnitsFromHNSecs!"days"(hnsecs); 7417 7418 if (hnsecs < 0) 7419 hnsecs += convert!("hours", "hnsecs")(24); 7420 7421 if (--days < 0) 7422 { 7423 hnsecs -= convert!("hours", "hnsecs")(24); 7424 ++days; 7425 } 7426 7427 immutable newDaysHNSecs = convert!("days", "hnsecs")(days); 7428 7429 adjTime = newDaysHNSecs + hnsecs; 7430 } 7431 7432 /// 7433 @safe unittest 7434 { 7435 import core.time; 7436 import std.datetime.date : DateTime; 7437 7438 auto st = SysTime(DateTime(0, 1, 1, 12, 0, 0)); 7439 st.dayOfGregorianCal = 1; 7440 assert(st == SysTime(DateTime(1, 1, 1, 12, 0, 0))); 7441 7442 st.dayOfGregorianCal = 365; 7443 assert(st == SysTime(DateTime(1, 12, 31, 12, 0, 0))); 7444 7445 st.dayOfGregorianCal = 366; 7446 assert(st == SysTime(DateTime(2, 1, 1, 12, 0, 0))); 7447 7448 st.dayOfGregorianCal = 0; 7449 assert(st == SysTime(DateTime(0, 12, 31, 12, 0, 0))); 7450 7451 st.dayOfGregorianCal = -365; 7452 assert(st == SysTime(DateTime(-0, 1, 1, 12, 0, 0))); 7453 7454 st.dayOfGregorianCal = -366; 7455 assert(st == SysTime(DateTime(-1, 12, 31, 12, 0, 0))); 7456 7457 st.dayOfGregorianCal = 730_120; 7458 assert(st == SysTime(DateTime(2000, 1, 1, 12, 0, 0))); 7459 7460 st.dayOfGregorianCal = 734_137; 7461 assert(st == SysTime(DateTime(2010, 12, 31, 12, 0, 0))); 7462 } 7463 7464 @safe unittest 7465 { 7466 import core.time; 7467 void testST(SysTime orig, int day, SysTime expected, size_t line = __LINE__) @safe 7468 { 7469 orig.dayOfGregorianCal = day; 7470 if (orig != expected) 7471 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 7472 } 7473 7474 // Test A.D. 7475 testST(SysTime(DateTime(1, 1, 1, 0, 0, 0)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 7476 testST(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 7477 testST(SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)), 1, 7478 SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7479 7480 // Test B.C. 7481 testST(SysTime(DateTime(0, 1, 1, 0, 0, 0)), 0, SysTime(DateTime(0, 12, 31, 0, 0, 0))); 7482 testST(SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)), 0, 7483 SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 7484 testST(SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(1)), 0, 7485 SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1))); 7486 testST(SysTime(DateTime(0, 1, 1, 23, 59, 59)), 0, SysTime(DateTime(0, 12, 31, 23, 59, 59))); 7487 7488 // Test Both. 7489 testST(SysTime(DateTime(-512, 7, 20, 0, 0, 0)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 7490 testST(SysTime(DateTime(-513, 6, 6, 0, 0, 0), hnsecs(1)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 7491 testST(SysTime(DateTime(-511, 5, 7, 23, 59, 59), hnsecs(9_999_999)), 1, 7492 SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7493 7494 testST(SysTime(DateTime(1607, 4, 8, 0, 0, 0)), 0, SysTime(DateTime(0, 12, 31, 0, 0, 0))); 7495 testST(SysTime(DateTime(1500, 3, 9, 23, 59, 59), hnsecs(9_999_999)), 0, 7496 SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 7497 testST(SysTime(DateTime(999, 2, 10, 23, 59, 59), hnsecs(1)), 0, 7498 SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1))); 7499 testST(SysTime(DateTime(2007, 12, 11, 23, 59, 59)), 0, SysTime(DateTime(0, 12, 31, 23, 59, 59))); 7500 7501 7502 auto st = SysTime(DateTime(1, 1, 1, 12, 2, 9), msecs(212)); 7503 7504 void testST2(int day, SysTime expected, size_t line = __LINE__) @safe 7505 { 7506 st.dayOfGregorianCal = day; 7507 if (st != expected) 7508 throw new AssertError(format("Failed. actual [%s] != expected [%s]", st, expected), __FILE__, line); 7509 } 7510 7511 // Test A.D. 7512 testST2(1, SysTime(DateTime(1, 1, 1, 12, 2, 9), msecs(212))); 7513 testST2(2, SysTime(DateTime(1, 1, 2, 12, 2, 9), msecs(212))); 7514 testST2(32, SysTime(DateTime(1, 2, 1, 12, 2, 9), msecs(212))); 7515 testST2(366, SysTime(DateTime(2, 1, 1, 12, 2, 9), msecs(212))); 7516 testST2(731, SysTime(DateTime(3, 1, 1, 12, 2, 9), msecs(212))); 7517 testST2(1096, SysTime(DateTime(4, 1, 1, 12, 2, 9), msecs(212))); 7518 testST2(1462, SysTime(DateTime(5, 1, 1, 12, 2, 9), msecs(212))); 7519 testST2(17_898, SysTime(DateTime(50, 1, 1, 12, 2, 9), msecs(212))); 7520 testST2(35_065, SysTime(DateTime(97, 1, 1, 12, 2, 9), msecs(212))); 7521 testST2(36_160, SysTime(DateTime(100, 1, 1, 12, 2, 9), msecs(212))); 7522 testST2(36_525, SysTime(DateTime(101, 1, 1, 12, 2, 9), msecs(212))); 7523 testST2(37_986, SysTime(DateTime(105, 1, 1, 12, 2, 9), msecs(212))); 7524 testST2(72_684, SysTime(DateTime(200, 1, 1, 12, 2, 9), msecs(212))); 7525 testST2(73_049, SysTime(DateTime(201, 1, 1, 12, 2, 9), msecs(212))); 7526 testST2(109_208, SysTime(DateTime(300, 1, 1, 12, 2, 9), msecs(212))); 7527 testST2(109_573, SysTime(DateTime(301, 1, 1, 12, 2, 9), msecs(212))); 7528 testST2(145_732, SysTime(DateTime(400, 1, 1, 12, 2, 9), msecs(212))); 7529 testST2(146_098, SysTime(DateTime(401, 1, 1, 12, 2, 9), msecs(212))); 7530 testST2(182_257, SysTime(DateTime(500, 1, 1, 12, 2, 9), msecs(212))); 7531 testST2(182_622, SysTime(DateTime(501, 1, 1, 12, 2, 9), msecs(212))); 7532 testST2(364_878, SysTime(DateTime(1000, 1, 1, 12, 2, 9), msecs(212))); 7533 testST2(365_243, SysTime(DateTime(1001, 1, 1, 12, 2, 9), msecs(212))); 7534 testST2(584_023, SysTime(DateTime(1600, 1, 1, 12, 2, 9), msecs(212))); 7535 testST2(584_389, SysTime(DateTime(1601, 1, 1, 12, 2, 9), msecs(212))); 7536 testST2(693_596, SysTime(DateTime(1900, 1, 1, 12, 2, 9), msecs(212))); 7537 testST2(693_961, SysTime(DateTime(1901, 1, 1, 12, 2, 9), msecs(212))); 7538 testST2(729_755, SysTime(DateTime(1999, 1, 1, 12, 2, 9), msecs(212))); 7539 testST2(730_120, SysTime(DateTime(2000, 1, 1, 12, 2, 9), msecs(212))); 7540 testST2(730_486, SysTime(DateTime(2001, 1, 1, 12, 2, 9), msecs(212))); 7541 7542 testST2(733_773, SysTime(DateTime(2010, 1, 1, 12, 2, 9), msecs(212))); 7543 testST2(733_803, SysTime(DateTime(2010, 1, 31, 12, 2, 9), msecs(212))); 7544 testST2(733_804, SysTime(DateTime(2010, 2, 1, 12, 2, 9), msecs(212))); 7545 testST2(733_831, SysTime(DateTime(2010, 2, 28, 12, 2, 9), msecs(212))); 7546 testST2(733_832, SysTime(DateTime(2010, 3, 1, 12, 2, 9), msecs(212))); 7547 testST2(733_862, SysTime(DateTime(2010, 3, 31, 12, 2, 9), msecs(212))); 7548 testST2(733_863, SysTime(DateTime(2010, 4, 1, 12, 2, 9), msecs(212))); 7549 testST2(733_892, SysTime(DateTime(2010, 4, 30, 12, 2, 9), msecs(212))); 7550 testST2(733_893, SysTime(DateTime(2010, 5, 1, 12, 2, 9), msecs(212))); 7551 testST2(733_923, SysTime(DateTime(2010, 5, 31, 12, 2, 9), msecs(212))); 7552 testST2(733_924, SysTime(DateTime(2010, 6, 1, 12, 2, 9), msecs(212))); 7553 testST2(733_953, SysTime(DateTime(2010, 6, 30, 12, 2, 9), msecs(212))); 7554 testST2(733_954, SysTime(DateTime(2010, 7, 1, 12, 2, 9), msecs(212))); 7555 testST2(733_984, SysTime(DateTime(2010, 7, 31, 12, 2, 9), msecs(212))); 7556 testST2(733_985, SysTime(DateTime(2010, 8, 1, 12, 2, 9), msecs(212))); 7557 testST2(734_015, SysTime(DateTime(2010, 8, 31, 12, 2, 9), msecs(212))); 7558 testST2(734_016, SysTime(DateTime(2010, 9, 1, 12, 2, 9), msecs(212))); 7559 testST2(734_045, SysTime(DateTime(2010, 9, 30, 12, 2, 9), msecs(212))); 7560 testST2(734_046, SysTime(DateTime(2010, 10, 1, 12, 2, 9), msecs(212))); 7561 testST2(734_076, SysTime(DateTime(2010, 10, 31, 12, 2, 9), msecs(212))); 7562 testST2(734_077, SysTime(DateTime(2010, 11, 1, 12, 2, 9), msecs(212))); 7563 testST2(734_106, SysTime(DateTime(2010, 11, 30, 12, 2, 9), msecs(212))); 7564 testST2(734_107, SysTime(DateTime(2010, 12, 1, 12, 2, 9), msecs(212))); 7565 testST2(734_137, SysTime(DateTime(2010, 12, 31, 12, 2, 9), msecs(212))); 7566 7567 testST2(734_534, SysTime(DateTime(2012, 2, 1, 12, 2, 9), msecs(212))); 7568 testST2(734_561, SysTime(DateTime(2012, 2, 28, 12, 2, 9), msecs(212))); 7569 testST2(734_562, SysTime(DateTime(2012, 2, 29, 12, 2, 9), msecs(212))); 7570 testST2(734_563, SysTime(DateTime(2012, 3, 1, 12, 2, 9), msecs(212))); 7571 7572 testST2(734_534, SysTime(DateTime(2012, 2, 1, 12, 2, 9), msecs(212))); 7573 7574 testST2(734_561, SysTime(DateTime(2012, 2, 28, 12, 2, 9), msecs(212))); 7575 testST2(734_562, SysTime(DateTime(2012, 2, 29, 12, 2, 9), msecs(212))); 7576 testST2(734_563, SysTime(DateTime(2012, 3, 1, 12, 2, 9), msecs(212))); 7577 7578 // Test B.C. 7579 testST2(0, SysTime(DateTime(0, 12, 31, 12, 2, 9), msecs(212))); 7580 testST2(-1, SysTime(DateTime(0, 12, 30, 12, 2, 9), msecs(212))); 7581 testST2(-30, SysTime(DateTime(0, 12, 1, 12, 2, 9), msecs(212))); 7582 testST2(-31, SysTime(DateTime(0, 11, 30, 12, 2, 9), msecs(212))); 7583 7584 testST2(-366, SysTime(DateTime(-1, 12, 31, 12, 2, 9), msecs(212))); 7585 testST2(-367, SysTime(DateTime(-1, 12, 30, 12, 2, 9), msecs(212))); 7586 testST2(-730, SysTime(DateTime(-1, 1, 1, 12, 2, 9), msecs(212))); 7587 testST2(-731, SysTime(DateTime(-2, 12, 31, 12, 2, 9), msecs(212))); 7588 testST2(-1095, SysTime(DateTime(-2, 1, 1, 12, 2, 9), msecs(212))); 7589 testST2(-1096, SysTime(DateTime(-3, 12, 31, 12, 2, 9), msecs(212))); 7590 testST2(-1460, SysTime(DateTime(-3, 1, 1, 12, 2, 9), msecs(212))); 7591 testST2(-1461, SysTime(DateTime(-4, 12, 31, 12, 2, 9), msecs(212))); 7592 testST2(-1826, SysTime(DateTime(-4, 1, 1, 12, 2, 9), msecs(212))); 7593 testST2(-1827, SysTime(DateTime(-5, 12, 31, 12, 2, 9), msecs(212))); 7594 testST2(-2191, SysTime(DateTime(-5, 1, 1, 12, 2, 9), msecs(212))); 7595 testST2(-3652, SysTime(DateTime(-9, 1, 1, 12, 2, 9), msecs(212))); 7596 7597 testST2(-18_262, SysTime(DateTime(-49, 1, 1, 12, 2, 9), msecs(212))); 7598 testST2(-18_627, SysTime(DateTime(-50, 1, 1, 12, 2, 9), msecs(212))); 7599 testST2(-35_794, SysTime(DateTime(-97, 1, 1, 12, 2, 9), msecs(212))); 7600 testST2(-36_160, SysTime(DateTime(-99, 12, 31, 12, 2, 9), msecs(212))); 7601 testST2(-36_524, SysTime(DateTime(-99, 1, 1, 12, 2, 9), msecs(212))); 7602 testST2(-36_889, SysTime(DateTime(-100, 1, 1, 12, 2, 9), msecs(212))); 7603 testST2(-37_254, SysTime(DateTime(-101, 1, 1, 12, 2, 9), msecs(212))); 7604 testST2(-38_715, SysTime(DateTime(-105, 1, 1, 12, 2, 9), msecs(212))); 7605 testST2(-73_413, SysTime(DateTime(-200, 1, 1, 12, 2, 9), msecs(212))); 7606 testST2(-73_778, SysTime(DateTime(-201, 1, 1, 12, 2, 9), msecs(212))); 7607 testST2(-109_937, SysTime(DateTime(-300, 1, 1, 12, 2, 9), msecs(212))); 7608 testST2(-110_302, SysTime(DateTime(-301, 1, 1, 12, 2, 9), msecs(212))); 7609 testST2(-146_097, SysTime(DateTime(-400, 12, 31, 12, 2, 9), msecs(212))); 7610 testST2(-146_462, SysTime(DateTime(-400, 1, 1, 12, 2, 9), msecs(212))); 7611 testST2(-146_827, SysTime(DateTime(-401, 1, 1, 12, 2, 9), msecs(212))); 7612 testST2(-182_621, SysTime(DateTime(-499, 1, 1, 12, 2, 9), msecs(212))); 7613 testST2(-182_986, SysTime(DateTime(-500, 1, 1, 12, 2, 9), msecs(212))); 7614 testST2(-183_351, SysTime(DateTime(-501, 1, 1, 12, 2, 9), msecs(212))); 7615 testST2(-365_607, SysTime(DateTime(-1000, 1, 1, 12, 2, 9), msecs(212))); 7616 testST2(-365_972, SysTime(DateTime(-1001, 1, 1, 12, 2, 9), msecs(212))); 7617 testST2(-584_387, SysTime(DateTime(-1599, 1, 1, 12, 2, 9), msecs(212))); 7618 testST2(-584_388, SysTime(DateTime(-1600, 12, 31, 12, 2, 9), msecs(212))); 7619 testST2(-584_753, SysTime(DateTime(-1600, 1, 1, 12, 2, 9), msecs(212))); 7620 testST2(-585_118, SysTime(DateTime(-1601, 1, 1, 12, 2, 9), msecs(212))); 7621 testST2(-694_325, SysTime(DateTime(-1900, 1, 1, 12, 2, 9), msecs(212))); 7622 testST2(-694_690, SysTime(DateTime(-1901, 1, 1, 12, 2, 9), msecs(212))); 7623 testST2(-730_484, SysTime(DateTime(-1999, 1, 1, 12, 2, 9), msecs(212))); 7624 testST2(-730_485, SysTime(DateTime(-2000, 12, 31, 12, 2, 9), msecs(212))); 7625 testST2(-730_850, SysTime(DateTime(-2000, 1, 1, 12, 2, 9), msecs(212))); 7626 testST2(-731_215, SysTime(DateTime(-2001, 1, 1, 12, 2, 9), msecs(212))); 7627 7628 testST2(-734_502, SysTime(DateTime(-2010, 1, 1, 12, 2, 9), msecs(212))); 7629 testST2(-734_472, SysTime(DateTime(-2010, 1, 31, 12, 2, 9), msecs(212))); 7630 testST2(-734_471, SysTime(DateTime(-2010, 2, 1, 12, 2, 9), msecs(212))); 7631 testST2(-734_444, SysTime(DateTime(-2010, 2, 28, 12, 2, 9), msecs(212))); 7632 testST2(-734_443, SysTime(DateTime(-2010, 3, 1, 12, 2, 9), msecs(212))); 7633 testST2(-734_413, SysTime(DateTime(-2010, 3, 31, 12, 2, 9), msecs(212))); 7634 testST2(-734_412, SysTime(DateTime(-2010, 4, 1, 12, 2, 9), msecs(212))); 7635 testST2(-734_383, SysTime(DateTime(-2010, 4, 30, 12, 2, 9), msecs(212))); 7636 testST2(-734_382, SysTime(DateTime(-2010, 5, 1, 12, 2, 9), msecs(212))); 7637 testST2(-734_352, SysTime(DateTime(-2010, 5, 31, 12, 2, 9), msecs(212))); 7638 testST2(-734_351, SysTime(DateTime(-2010, 6, 1, 12, 2, 9), msecs(212))); 7639 testST2(-734_322, SysTime(DateTime(-2010, 6, 30, 12, 2, 9), msecs(212))); 7640 testST2(-734_321, SysTime(DateTime(-2010, 7, 1, 12, 2, 9), msecs(212))); 7641 testST2(-734_291, SysTime(DateTime(-2010, 7, 31, 12, 2, 9), msecs(212))); 7642 testST2(-734_290, SysTime(DateTime(-2010, 8, 1, 12, 2, 9), msecs(212))); 7643 testST2(-734_260, SysTime(DateTime(-2010, 8, 31, 12, 2, 9), msecs(212))); 7644 testST2(-734_259, SysTime(DateTime(-2010, 9, 1, 12, 2, 9), msecs(212))); 7645 testST2(-734_230, SysTime(DateTime(-2010, 9, 30, 12, 2, 9), msecs(212))); 7646 testST2(-734_229, SysTime(DateTime(-2010, 10, 1, 12, 2, 9), msecs(212))); 7647 testST2(-734_199, SysTime(DateTime(-2010, 10, 31, 12, 2, 9), msecs(212))); 7648 testST2(-734_198, SysTime(DateTime(-2010, 11, 1, 12, 2, 9), msecs(212))); 7649 testST2(-734_169, SysTime(DateTime(-2010, 11, 30, 12, 2, 9), msecs(212))); 7650 testST2(-734_168, SysTime(DateTime(-2010, 12, 1, 12, 2, 9), msecs(212))); 7651 testST2(-734_138, SysTime(DateTime(-2010, 12, 31, 12, 2, 9), msecs(212))); 7652 7653 testST2(-735_202, SysTime(DateTime(-2012, 2, 1, 12, 2, 9), msecs(212))); 7654 testST2(-735_175, SysTime(DateTime(-2012, 2, 28, 12, 2, 9), msecs(212))); 7655 testST2(-735_174, SysTime(DateTime(-2012, 2, 29, 12, 2, 9), msecs(212))); 7656 testST2(-735_173, SysTime(DateTime(-2012, 3, 1, 12, 2, 9), msecs(212))); 7657 7658 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7659 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7660 static assert(!__traits(compiles, cst.dayOfGregorianCal = 7)); 7661 static assert(!__traits(compiles, ist.dayOfGregorianCal = 7)); 7662 7663 static void testScope(scope ref SysTime st) @safe 7664 { 7665 st.dayOfGregorianCal = 42; 7666 } 7667 } 7668 7669 7670 /++ 7671 The ISO 8601 week of the year that this $(LREF SysTime) is in. 7672 7673 See_Also: 7674 $(HTTP en.wikipedia.org/wiki/ISO_week_date, ISO Week Date). 7675 +/ 7676 @property ubyte isoWeek() @safe const nothrow scope 7677 { 7678 return (cast(Date) this).isoWeek; 7679 } 7680 7681 /// 7682 @safe unittest 7683 { 7684 import core.time; 7685 import std.datetime.date : Date; 7686 7687 auto st = SysTime(Date(1999, 7, 6)); 7688 const cst = SysTime(Date(2010, 5, 1)); 7689 immutable ist = SysTime(Date(2015, 10, 10)); 7690 7691 assert(st.isoWeek == 27); 7692 assert(cst.isoWeek == 17); 7693 assert(ist.isoWeek == 41); 7694 } 7695 7696 @safe unittest 7697 { 7698 static void testScope(scope ref SysTime st) @safe 7699 { 7700 auto result = st.isoWeek; 7701 } 7702 } 7703 7704 7705 /++ 7706 $(LREF SysTime) for the last day in the month that this Date is in. 7707 The time portion of endOfMonth is always 23:59:59.9999999. 7708 +/ 7709 @property SysTime endOfMonth() @safe const nothrow return scope 7710 { 7711 immutable hnsecs = adjTime; 7712 immutable days = getUnitsFromHNSecs!"days"(hnsecs); 7713 7714 auto date = Date(cast(int) days + 1).endOfMonth; 7715 auto newDays = date.dayOfGregorianCal - 1; 7716 long theTimeHNSecs; 7717 7718 if (newDays < 0) 7719 { 7720 theTimeHNSecs = -1; 7721 ++newDays; 7722 } 7723 else 7724 theTimeHNSecs = convert!("days", "hnsecs")(1) - 1; 7725 7726 immutable newDaysHNSecs = convert!("days", "hnsecs")(newDays); 7727 7728 auto retval = SysTime(this._stdTime, this._timezone); 7729 retval.adjTime = newDaysHNSecs + theTimeHNSecs; 7730 7731 return retval; 7732 } 7733 7734 /// 7735 @safe unittest 7736 { 7737 import core.time : msecs, usecs, hnsecs; 7738 import std.datetime.date : DateTime; 7739 7740 assert(SysTime(DateTime(1999, 1, 6, 0, 0, 0)).endOfMonth == 7741 SysTime(DateTime(1999, 1, 31, 23, 59, 59), hnsecs(9_999_999))); 7742 7743 assert(SysTime(DateTime(1999, 2, 7, 19, 30, 0), msecs(24)).endOfMonth == 7744 SysTime(DateTime(1999, 2, 28, 23, 59, 59), hnsecs(9_999_999))); 7745 7746 assert(SysTime(DateTime(2000, 2, 7, 5, 12, 27), usecs(5203)).endOfMonth == 7747 SysTime(DateTime(2000, 2, 29, 23, 59, 59), hnsecs(9_999_999))); 7748 7749 assert(SysTime(DateTime(2000, 6, 4, 12, 22, 9), hnsecs(12345)).endOfMonth == 7750 SysTime(DateTime(2000, 6, 30, 23, 59, 59), hnsecs(9_999_999))); 7751 } 7752 7753 @safe unittest 7754 { 7755 import core.time; 7756 // Test A.D. 7757 assert(SysTime(Date(1999, 1, 1)).endOfMonth == SysTime(DateTime(1999, 1, 31, 23, 59, 59), hnsecs(9_999_999))); 7758 assert(SysTime(Date(1999, 2, 1)).endOfMonth == SysTime(DateTime(1999, 2, 28, 23, 59, 59), hnsecs(9_999_999))); 7759 assert(SysTime(Date(2000, 2, 1)).endOfMonth == SysTime(DateTime(2000, 2, 29, 23, 59, 59), hnsecs(9_999_999))); 7760 assert(SysTime(Date(1999, 3, 1)).endOfMonth == SysTime(DateTime(1999, 3, 31, 23, 59, 59), hnsecs(9_999_999))); 7761 assert(SysTime(Date(1999, 4, 1)).endOfMonth == SysTime(DateTime(1999, 4, 30, 23, 59, 59), hnsecs(9_999_999))); 7762 assert(SysTime(Date(1999, 5, 1)).endOfMonth == SysTime(DateTime(1999, 5, 31, 23, 59, 59), hnsecs(9_999_999))); 7763 assert(SysTime(Date(1999, 6, 1)).endOfMonth == SysTime(DateTime(1999, 6, 30, 23, 59, 59), hnsecs(9_999_999))); 7764 assert(SysTime(Date(1999, 7, 1)).endOfMonth == SysTime(DateTime(1999, 7, 31, 23, 59, 59), hnsecs(9_999_999))); 7765 assert(SysTime(Date(1999, 8, 1)).endOfMonth == SysTime(DateTime(1999, 8, 31, 23, 59, 59), hnsecs(9_999_999))); 7766 assert(SysTime(Date(1999, 9, 1)).endOfMonth == SysTime(DateTime(1999, 9, 30, 23, 59, 59), hnsecs(9_999_999))); 7767 assert(SysTime(Date(1999, 10, 1)).endOfMonth == SysTime(DateTime(1999, 10, 31, 23, 59, 59), hnsecs(9_999_999))); 7768 assert(SysTime(Date(1999, 11, 1)).endOfMonth == SysTime(DateTime(1999, 11, 30, 23, 59, 59), hnsecs(9_999_999))); 7769 assert(SysTime(Date(1999, 12, 1)).endOfMonth == SysTime(DateTime(1999, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 7770 7771 // Test B.C. 7772 assert(SysTime(Date(-1999, 1, 1)).endOfMonth == SysTime(DateTime(-1999, 1, 31, 23, 59, 59), hnsecs(9_999_999))); 7773 assert(SysTime(Date(-1999, 2, 1)).endOfMonth == SysTime(DateTime(-1999, 2, 28, 23, 59, 59), hnsecs(9_999_999))); 7774 assert(SysTime(Date(-2000, 2, 1)).endOfMonth == SysTime(DateTime(-2000, 2, 29, 23, 59, 59), hnsecs(9_999_999))); 7775 assert(SysTime(Date(-1999, 3, 1)).endOfMonth == SysTime(DateTime(-1999, 3, 31, 23, 59, 59), hnsecs(9_999_999))); 7776 assert(SysTime(Date(-1999, 4, 1)).endOfMonth == SysTime(DateTime(-1999, 4, 30, 23, 59, 59), hnsecs(9_999_999))); 7777 assert(SysTime(Date(-1999, 5, 1)).endOfMonth == SysTime(DateTime(-1999, 5, 31, 23, 59, 59), hnsecs(9_999_999))); 7778 assert(SysTime(Date(-1999, 6, 1)).endOfMonth == SysTime(DateTime(-1999, 6, 30, 23, 59, 59), hnsecs(9_999_999))); 7779 assert(SysTime(Date(-1999, 7, 1)).endOfMonth == SysTime(DateTime(-1999, 7, 31, 23, 59, 59), hnsecs(9_999_999))); 7780 assert(SysTime(Date(-1999, 8, 1)).endOfMonth == SysTime(DateTime(-1999, 8, 31, 23, 59, 59), hnsecs(9_999_999))); 7781 assert(SysTime(Date(-1999, 9, 1)).endOfMonth == SysTime(DateTime(-1999, 9, 30, 23, 59, 59), hnsecs(9_999_999))); 7782 assert(SysTime(Date(-1999, 10, 1)).endOfMonth == 7783 SysTime(DateTime(-1999, 10, 31, 23, 59, 59), hnsecs(9_999_999))); 7784 assert(SysTime(Date(-1999, 11, 1)).endOfMonth == 7785 SysTime(DateTime(-1999, 11, 30, 23, 59, 59), hnsecs(9_999_999))); 7786 assert(SysTime(Date(-1999, 12, 1)).endOfMonth == 7787 SysTime(DateTime(-1999, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 7788 7789 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7790 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7791 assert(cst.endOfMonth == SysTime(DateTime(1999, 7, 31, 23, 59, 59), hnsecs(9_999_999))); 7792 assert(ist.endOfMonth == SysTime(DateTime(1999, 7, 31, 23, 59, 59), hnsecs(9_999_999))); 7793 7794 static void testScope(scope ref SysTime st) @safe 7795 { 7796 auto result = st.endOfMonth; 7797 } 7798 } 7799 7800 7801 /++ 7802 The last day in the month that this $(LREF SysTime) is in. 7803 +/ 7804 @property ubyte daysInMonth() @safe const nothrow scope 7805 { 7806 return Date(dayOfGregorianCal).daysInMonth; 7807 } 7808 7809 /// 7810 @safe unittest 7811 { 7812 import core.time; 7813 import std.datetime.date : DateTime; 7814 7815 assert(SysTime(DateTime(1999, 1, 6, 0, 0, 0)).daysInMonth == 31); 7816 assert(SysTime(DateTime(1999, 2, 7, 19, 30, 0)).daysInMonth == 28); 7817 assert(SysTime(DateTime(2000, 2, 7, 5, 12, 27)).daysInMonth == 29); 7818 assert(SysTime(DateTime(2000, 6, 4, 12, 22, 9)).daysInMonth == 30); 7819 } 7820 7821 @safe unittest 7822 { 7823 import core.time; 7824 // Test A.D. 7825 assert(SysTime(DateTime(1999, 1, 1, 12, 1, 13)).daysInMonth == 31); 7826 assert(SysTime(DateTime(1999, 2, 1, 17, 13, 12)).daysInMonth == 28); 7827 assert(SysTime(DateTime(2000, 2, 1, 13, 2, 12)).daysInMonth == 29); 7828 assert(SysTime(DateTime(1999, 3, 1, 12, 13, 12)).daysInMonth == 31); 7829 assert(SysTime(DateTime(1999, 4, 1, 12, 6, 13)).daysInMonth == 30); 7830 assert(SysTime(DateTime(1999, 5, 1, 15, 13, 12)).daysInMonth == 31); 7831 assert(SysTime(DateTime(1999, 6, 1, 13, 7, 12)).daysInMonth == 30); 7832 assert(SysTime(DateTime(1999, 7, 1, 12, 13, 17)).daysInMonth == 31); 7833 assert(SysTime(DateTime(1999, 8, 1, 12, 3, 13)).daysInMonth == 31); 7834 assert(SysTime(DateTime(1999, 9, 1, 12, 13, 12)).daysInMonth == 30); 7835 assert(SysTime(DateTime(1999, 10, 1, 13, 19, 12)).daysInMonth == 31); 7836 assert(SysTime(DateTime(1999, 11, 1, 12, 13, 17)).daysInMonth == 30); 7837 assert(SysTime(DateTime(1999, 12, 1, 12, 52, 13)).daysInMonth == 31); 7838 7839 // Test B.C. 7840 assert(SysTime(DateTime(-1999, 1, 1, 12, 1, 13)).daysInMonth == 31); 7841 assert(SysTime(DateTime(-1999, 2, 1, 7, 13, 12)).daysInMonth == 28); 7842 assert(SysTime(DateTime(-2000, 2, 1, 13, 2, 12)).daysInMonth == 29); 7843 assert(SysTime(DateTime(-1999, 3, 1, 12, 13, 12)).daysInMonth == 31); 7844 assert(SysTime(DateTime(-1999, 4, 1, 12, 6, 13)).daysInMonth == 30); 7845 assert(SysTime(DateTime(-1999, 5, 1, 5, 13, 12)).daysInMonth == 31); 7846 assert(SysTime(DateTime(-1999, 6, 1, 13, 7, 12)).daysInMonth == 30); 7847 assert(SysTime(DateTime(-1999, 7, 1, 12, 13, 17)).daysInMonth == 31); 7848 assert(SysTime(DateTime(-1999, 8, 1, 12, 3, 13)).daysInMonth == 31); 7849 assert(SysTime(DateTime(-1999, 9, 1, 12, 13, 12)).daysInMonth == 30); 7850 assert(SysTime(DateTime(-1999, 10, 1, 13, 19, 12)).daysInMonth == 31); 7851 assert(SysTime(DateTime(-1999, 11, 1, 12, 13, 17)).daysInMonth == 30); 7852 assert(SysTime(DateTime(-1999, 12, 1, 12, 52, 13)).daysInMonth == 31); 7853 7854 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7855 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7856 assert(cst.daysInMonth == 31); 7857 assert(ist.daysInMonth == 31); 7858 7859 static void testScope(scope ref SysTime st) @safe 7860 { 7861 auto result = st.daysInMonth; 7862 } 7863 } 7864 7865 7866 /++ 7867 Whether the current year is a date in A.D. 7868 +/ 7869 @property bool isAD() @safe const nothrow scope 7870 { 7871 return adjTime >= 0; 7872 } 7873 7874 /// 7875 @safe unittest 7876 { 7877 import core.time; 7878 import std.datetime.date : DateTime; 7879 7880 assert(SysTime(DateTime(1, 1, 1, 12, 7, 0)).isAD); 7881 assert(SysTime(DateTime(2010, 12, 31, 0, 0, 0)).isAD); 7882 assert(!SysTime(DateTime(0, 12, 31, 23, 59, 59)).isAD); 7883 assert(!SysTime(DateTime(-2010, 1, 1, 2, 2, 2)).isAD); 7884 } 7885 7886 @safe unittest 7887 { 7888 import core.time; 7889 assert(SysTime(DateTime(2010, 7, 4, 12, 0, 9)).isAD); 7890 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).isAD); 7891 assert(!SysTime(DateTime(0, 12, 31, 23, 59, 59)).isAD); 7892 assert(!SysTime(DateTime(0, 1, 1, 23, 59, 59)).isAD); 7893 assert(!SysTime(DateTime(-1, 1, 1, 23 ,59 ,59)).isAD); 7894 assert(!SysTime(DateTime(-2010, 7, 4, 12, 2, 2)).isAD); 7895 7896 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7897 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7898 assert(cst.isAD); 7899 assert(ist.isAD); 7900 7901 static void testScope(scope ref SysTime st) @safe 7902 { 7903 auto result = st.isAD; 7904 } 7905 } 7906 7907 7908 /++ 7909 The $(HTTP en.wikipedia.org/wiki/Julian_day, Julian day) 7910 for this $(LREF SysTime) at the given time. For example, 7911 prior to noon, 1996-03-31 would be the Julian day number 2_450_173, so 7912 this function returns 2_450_173, while from noon onward, the Julian 7913 day number would be 2_450_174, so this function returns 2_450_174. 7914 +/ 7915 @property long julianDay() @safe const nothrow scope 7916 { 7917 immutable jd = dayOfGregorianCal + 1_721_425; 7918 return hour < 12 ? jd - 1 : jd; 7919 } 7920 7921 @safe unittest 7922 { 7923 import core.time; 7924 assert(SysTime(DateTime(-4713, 11, 24, 0, 0, 0)).julianDay == -1); 7925 assert(SysTime(DateTime(-4713, 11, 24, 12, 0, 0)).julianDay == 0); 7926 7927 assert(SysTime(DateTime(0, 12, 31, 0, 0, 0)).julianDay == 1_721_424); 7928 assert(SysTime(DateTime(0, 12, 31, 12, 0, 0)).julianDay == 1_721_425); 7929 7930 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).julianDay == 1_721_425); 7931 assert(SysTime(DateTime(1, 1, 1, 12, 0, 0)).julianDay == 1_721_426); 7932 7933 assert(SysTime(DateTime(1582, 10, 15, 0, 0, 0)).julianDay == 2_299_160); 7934 assert(SysTime(DateTime(1582, 10, 15, 12, 0, 0)).julianDay == 2_299_161); 7935 7936 assert(SysTime(DateTime(1858, 11, 17, 0, 0, 0)).julianDay == 2_400_000); 7937 assert(SysTime(DateTime(1858, 11, 17, 12, 0, 0)).julianDay == 2_400_001); 7938 7939 assert(SysTime(DateTime(1982, 1, 4, 0, 0, 0)).julianDay == 2_444_973); 7940 assert(SysTime(DateTime(1982, 1, 4, 12, 0, 0)).julianDay == 2_444_974); 7941 7942 assert(SysTime(DateTime(1996, 3, 31, 0, 0, 0)).julianDay == 2_450_173); 7943 assert(SysTime(DateTime(1996, 3, 31, 12, 0, 0)).julianDay == 2_450_174); 7944 7945 assert(SysTime(DateTime(2010, 8, 24, 0, 0, 0)).julianDay == 2_455_432); 7946 assert(SysTime(DateTime(2010, 8, 24, 12, 0, 0)).julianDay == 2_455_433); 7947 7948 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7949 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7950 assert(cst.julianDay == 2_451_366); 7951 assert(ist.julianDay == 2_451_366); 7952 7953 static void testScope(scope ref SysTime st) @safe 7954 { 7955 auto result = st.julianDay; 7956 } 7957 } 7958 7959 7960 /++ 7961 The modified $(HTTP en.wikipedia.org/wiki/Julian_day, Julian day) for 7962 any time on this date (since, the modified Julian day changes at 7963 midnight). 7964 +/ 7965 @property long modJulianDay() @safe const nothrow scope 7966 { 7967 return dayOfGregorianCal + 1_721_425 - 2_400_001; 7968 } 7969 7970 @safe unittest 7971 { 7972 import core.time; 7973 assert(SysTime(DateTime(1858, 11, 17, 0, 0, 0)).modJulianDay == 0); 7974 assert(SysTime(DateTime(1858, 11, 17, 12, 0, 0)).modJulianDay == 0); 7975 7976 assert(SysTime(DateTime(2010, 8, 24, 0, 0, 0)).modJulianDay == 55_432); 7977 assert(SysTime(DateTime(2010, 8, 24, 12, 0, 0)).modJulianDay == 55_432); 7978 7979 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7980 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7981 assert(cst.modJulianDay == 51_365); 7982 assert(ist.modJulianDay == 51_365); 7983 7984 static void testScope(scope ref SysTime st) @safe 7985 { 7986 auto result = st.modJulianDay; 7987 } 7988 } 7989 7990 7991 /++ 7992 Returns a $(REF Date,std,datetime,date) equivalent to this $(LREF SysTime). 7993 +/ 7994 Date opCast(T)() @safe const nothrow scope 7995 if (is(immutable T == immutable Date)) 7996 { 7997 return Date(dayOfGregorianCal); 7998 } 7999 8000 @safe unittest 8001 { 8002 import core.time; 8003 assert(cast(Date) SysTime(Date(1999, 7, 6)) == Date(1999, 7, 6)); 8004 assert(cast(Date) SysTime(Date(2000, 12, 31)) == Date(2000, 12, 31)); 8005 assert(cast(Date) SysTime(Date(2001, 1, 1)) == Date(2001, 1, 1)); 8006 8007 assert(cast(Date) SysTime(DateTime(1999, 7, 6, 12, 10, 9)) == Date(1999, 7, 6)); 8008 assert(cast(Date) SysTime(DateTime(2000, 12, 31, 13, 11, 10)) == Date(2000, 12, 31)); 8009 assert(cast(Date) SysTime(DateTime(2001, 1, 1, 14, 12, 11)) == Date(2001, 1, 1)); 8010 8011 assert(cast(Date) SysTime(Date(-1999, 7, 6)) == Date(-1999, 7, 6)); 8012 assert(cast(Date) SysTime(Date(-2000, 12, 31)) == Date(-2000, 12, 31)); 8013 assert(cast(Date) SysTime(Date(-2001, 1, 1)) == Date(-2001, 1, 1)); 8014 8015 assert(cast(Date) SysTime(DateTime(-1999, 7, 6, 12, 10, 9)) == Date(-1999, 7, 6)); 8016 assert(cast(Date) SysTime(DateTime(-2000, 12, 31, 13, 11, 10)) == Date(-2000, 12, 31)); 8017 assert(cast(Date) SysTime(DateTime(-2001, 1, 1, 14, 12, 11)) == Date(-2001, 1, 1)); 8018 8019 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8020 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8021 assert(cast(Date) cst != Date.init); 8022 assert(cast(Date) ist != Date.init); 8023 8024 static void testScope(scope ref SysTime st) @safe 8025 { 8026 auto result = cast(Date) st; 8027 } 8028 } 8029 8030 8031 /++ 8032 Returns a $(REF DateTime,std,datetime,date) equivalent to this 8033 $(LREF SysTime). 8034 +/ 8035 DateTime opCast(T)() @safe const nothrow scope 8036 if (is(immutable T == immutable DateTime)) 8037 { 8038 try 8039 { 8040 auto hnsecs = adjTime; 8041 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 8042 8043 if (hnsecs < 0) 8044 { 8045 hnsecs += convert!("hours", "hnsecs")(24); 8046 --days; 8047 } 8048 8049 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 8050 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 8051 immutable second = getUnitsFromHNSecs!"seconds"(hnsecs); 8052 8053 return DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour, cast(int) minute, cast(int) second)); 8054 } 8055 catch (Exception e) 8056 assert(0, "Either DateTime's constructor or TimeOfDay's constructor threw."); 8057 } 8058 8059 @safe unittest 8060 { 8061 import core.time; 8062 assert(cast(DateTime) SysTime(DateTime(1, 1, 6, 7, 12, 22)) == DateTime(1, 1, 6, 7, 12, 22)); 8063 assert(cast(DateTime) SysTime(DateTime(1, 1, 6, 7, 12, 22), msecs(22)) == DateTime(1, 1, 6, 7, 12, 22)); 8064 assert(cast(DateTime) SysTime(Date(1999, 7, 6)) == DateTime(1999, 7, 6, 0, 0, 0)); 8065 assert(cast(DateTime) SysTime(Date(2000, 12, 31)) == DateTime(2000, 12, 31, 0, 0, 0)); 8066 assert(cast(DateTime) SysTime(Date(2001, 1, 1)) == DateTime(2001, 1, 1, 0, 0, 0)); 8067 8068 assert(cast(DateTime) SysTime(DateTime(1999, 7, 6, 12, 10, 9)) == DateTime(1999, 7, 6, 12, 10, 9)); 8069 assert(cast(DateTime) SysTime(DateTime(2000, 12, 31, 13, 11, 10)) == DateTime(2000, 12, 31, 13, 11, 10)); 8070 assert(cast(DateTime) SysTime(DateTime(2001, 1, 1, 14, 12, 11)) == DateTime(2001, 1, 1, 14, 12, 11)); 8071 8072 assert(cast(DateTime) SysTime(DateTime(-1, 1, 6, 7, 12, 22)) == DateTime(-1, 1, 6, 7, 12, 22)); 8073 assert(cast(DateTime) SysTime(DateTime(-1, 1, 6, 7, 12, 22), msecs(22)) == DateTime(-1, 1, 6, 7, 12, 22)); 8074 assert(cast(DateTime) SysTime(Date(-1999, 7, 6)) == DateTime(-1999, 7, 6, 0, 0, 0)); 8075 assert(cast(DateTime) SysTime(Date(-2000, 12, 31)) == DateTime(-2000, 12, 31, 0, 0, 0)); 8076 assert(cast(DateTime) SysTime(Date(-2001, 1, 1)) == DateTime(-2001, 1, 1, 0, 0, 0)); 8077 8078 assert(cast(DateTime) SysTime(DateTime(-1999, 7, 6, 12, 10, 9)) == DateTime(-1999, 7, 6, 12, 10, 9)); 8079 assert(cast(DateTime) SysTime(DateTime(-2000, 12, 31, 13, 11, 10)) == DateTime(-2000, 12, 31, 13, 11, 10)); 8080 assert(cast(DateTime) SysTime(DateTime(-2001, 1, 1, 14, 12, 11)) == DateTime(-2001, 1, 1, 14, 12, 11)); 8081 8082 assert(cast(DateTime) SysTime(DateTime(2011, 1, 13, 8, 17, 2), msecs(296), LocalTime()) == 8083 DateTime(2011, 1, 13, 8, 17, 2)); 8084 8085 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8086 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8087 assert(cast(DateTime) cst != DateTime.init); 8088 assert(cast(DateTime) ist != DateTime.init); 8089 8090 static void testScope(scope ref SysTime st) @safe 8091 { 8092 auto result = cast(DateTime) st; 8093 } 8094 } 8095 8096 8097 /++ 8098 Returns a $(REF TimeOfDay,std,datetime,date) equivalent to this 8099 $(LREF SysTime). 8100 +/ 8101 TimeOfDay opCast(T)() @safe const nothrow scope 8102 if (is(immutable T == immutable TimeOfDay)) 8103 { 8104 try 8105 { 8106 auto hnsecs = adjTime; 8107 hnsecs = removeUnitsFromHNSecs!"days"(hnsecs); 8108 8109 if (hnsecs < 0) 8110 hnsecs += convert!("hours", "hnsecs")(24); 8111 8112 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 8113 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 8114 immutable second = getUnitsFromHNSecs!"seconds"(hnsecs); 8115 8116 return TimeOfDay(cast(int) hour, cast(int) minute, cast(int) second); 8117 } 8118 catch (Exception e) 8119 assert(0, "TimeOfDay's constructor threw."); 8120 } 8121 8122 @safe unittest 8123 { 8124 import core.time; 8125 assert(cast(TimeOfDay) SysTime(Date(1999, 7, 6)) == TimeOfDay(0, 0, 0)); 8126 assert(cast(TimeOfDay) SysTime(Date(2000, 12, 31)) == TimeOfDay(0, 0, 0)); 8127 assert(cast(TimeOfDay) SysTime(Date(2001, 1, 1)) == TimeOfDay(0, 0, 0)); 8128 8129 assert(cast(TimeOfDay) SysTime(DateTime(1999, 7, 6, 12, 10, 9)) == TimeOfDay(12, 10, 9)); 8130 assert(cast(TimeOfDay) SysTime(DateTime(2000, 12, 31, 13, 11, 10)) == TimeOfDay(13, 11, 10)); 8131 assert(cast(TimeOfDay) SysTime(DateTime(2001, 1, 1, 14, 12, 11)) == TimeOfDay(14, 12, 11)); 8132 8133 assert(cast(TimeOfDay) SysTime(Date(-1999, 7, 6)) == TimeOfDay(0, 0, 0)); 8134 assert(cast(TimeOfDay) SysTime(Date(-2000, 12, 31)) == TimeOfDay(0, 0, 0)); 8135 assert(cast(TimeOfDay) SysTime(Date(-2001, 1, 1)) == TimeOfDay(0, 0, 0)); 8136 8137 assert(cast(TimeOfDay) SysTime(DateTime(-1999, 7, 6, 12, 10, 9)) == TimeOfDay(12, 10, 9)); 8138 assert(cast(TimeOfDay) SysTime(DateTime(-2000, 12, 31, 13, 11, 10)) == TimeOfDay(13, 11, 10)); 8139 assert(cast(TimeOfDay) SysTime(DateTime(-2001, 1, 1, 14, 12, 11)) == TimeOfDay(14, 12, 11)); 8140 8141 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8142 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8143 assert(cast(TimeOfDay) cst != TimeOfDay.init); 8144 assert(cast(TimeOfDay) ist != TimeOfDay.init); 8145 8146 static void testScope(scope ref SysTime st) @safe 8147 { 8148 auto result = cast(TimeOfDay) st; 8149 } 8150 } 8151 8152 8153 // Temporary hack until bug https://issues.dlang.org/show_bug.cgi?id=4867 is fixed. 8154 // This allows assignment from const(SysTime) to SysTime. 8155 // It may be a good idea to keep it though, since casting from a type to itself 8156 // should be allowed, and it doesn't work without this opCast() since opCast() 8157 // has already been defined for other types. 8158 SysTime opCast(T)() @safe const pure nothrow scope 8159 if (is(immutable T == immutable SysTime)) 8160 { 8161 return SysTime(_stdTime, _timezone); 8162 } 8163 8164 @safe unittest 8165 { 8166 static void testScope(scope ref SysTime st) @safe 8167 { 8168 auto result = cast(SysTime) st; 8169 } 8170 } 8171 8172 8173 /++ 8174 Converts this $(LREF SysTime) to a string with the format 8175 YYYYMMDDTHHMMSS.FFFFFFFTZ (where F is fractional seconds and TZ is time 8176 zone). 8177 8178 Note that the number of digits in the fractional seconds varies with the 8179 number of fractional seconds. It's a maximum of 7 (which would be 8180 hnsecs), but only has as many as are necessary to hold the correct value 8181 (so no trailing zeroes), and if there are no fractional seconds, then 8182 there is no decimal point. 8183 8184 If this $(LREF SysTime)'s time zone is 8185 $(REF LocalTime,std,datetime,timezone), then TZ is empty. If its time 8186 zone is `UTC`, then it is "Z". Otherwise, it is the offset from UTC 8187 (e.g. +0100 or -0700). Note that the offset from UTC is $(I not) enough 8188 to uniquely identify the time zone. 8189 8190 Time zone offsets will be in the form +HHMM or -HHMM. 8191 8192 $(RED Warning: 8193 Previously, toISOString did the same as $(LREF toISOExtString) and 8194 generated +HH:MM or -HH:MM for the time zone when it was not 8195 $(REF LocalTime,std,datetime,timezone) or 8196 $(REF UTC,std,datetime,timezone), which is not in conformance with 8197 ISO 8601 for the non-extended string format. This has now been 8198 fixed. However, for now, fromISOString will continue to accept the 8199 extended format for the time zone so that any code which has been 8200 writing out the result of toISOString to read in later will continue 8201 to work. The current behavior will be kept until July 2019 at which 8202 point, fromISOString will be fixed to be standards compliant.) 8203 8204 Params: 8205 writer = A `char` accepting 8206 $(REF_ALTTEXT output range, isOutputRange, std, range, primitives) 8207 Returns: 8208 A `string` when not using an output range; `void` otherwise. 8209 +/ 8210 string toISOString() @safe const nothrow scope 8211 { 8212 import std.array : appender; 8213 auto app = appender!string(); 8214 app.reserve(30); 8215 try 8216 toISOString(app); 8217 catch (Exception e) 8218 assert(0, "toISOString() threw."); 8219 return app.data; 8220 } 8221 8222 /// ditto 8223 void toISOString(W)(ref W writer) const scope 8224 if (isOutputRange!(W, char)) 8225 { 8226 immutable adjustedTime = adjTime; 8227 long hnsecs = adjustedTime; 8228 8229 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 8230 8231 if (hnsecs < 0) 8232 { 8233 hnsecs += convert!("hours", "hnsecs")(24); 8234 --days; 8235 } 8236 8237 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 8238 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 8239 immutable second = splitUnitsFromHNSecs!"seconds"(hnsecs); 8240 8241 auto dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour, 8242 cast(int) minute, cast(int) second)); 8243 8244 if (_timezone is LocalTime()) 8245 { 8246 dateTime.toISOString(writer); 8247 fracSecsToISOString(writer, cast(int) hnsecs); 8248 return; 8249 } 8250 8251 if (_timezone is UTC()) 8252 { 8253 dateTime.toISOString(writer); 8254 fracSecsToISOString(writer, cast(int) hnsecs); 8255 put(writer, 'Z'); 8256 return; 8257 } 8258 8259 immutable utcOffset = dur!"hnsecs"(adjustedTime - stdTime); 8260 8261 dateTime.toISOString(writer); 8262 fracSecsToISOString(writer, cast(int) hnsecs); 8263 SimpleTimeZone.toISOExtString(writer, utcOffset); 8264 } 8265 8266 /// 8267 @safe unittest 8268 { 8269 import core.time : msecs, hnsecs; 8270 import std.datetime.date : DateTime; 8271 8272 assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toISOString() == 8273 "20100704T070612"); 8274 8275 assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(24)).toISOString() == 8276 "19981225T021500.024"); 8277 8278 assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toISOString() == 8279 "00000105T230959"); 8280 8281 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toISOString() == 8282 "-00040105T000002.052092"); 8283 } 8284 8285 @safe unittest 8286 { 8287 import core.time; 8288 // Test A.D. 8289 assert(SysTime(DateTime.init, UTC()).toISOString() == "00010101T000000Z"); 8290 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC()).toISOString() == "00010101T000000.0000001Z"); 8291 8292 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0)).toISOString() == "00091204T000000"); 8293 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12)).toISOString() == "00991204T050612"); 8294 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59)).toISOString() == "09991204T134459"); 8295 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59)).toISOString() == "99990704T235959"); 8296 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1)).toISOString() == "+100001020T010101"); 8297 8298 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0), msecs(42)).toISOString() == "00091204T000000.042"); 8299 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12), msecs(100)).toISOString() == "00991204T050612.1"); 8300 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59), usecs(45020)).toISOString() == "09991204T134459.04502"); 8301 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOString() == "99990704T235959.0000012"); 8302 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOString() == "+100001020T010101.050789"); 8303 8304 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 8305 new immutable SimpleTimeZone(dur!"minutes"(-360))).toISOString() == 8306 "20121221T121212-06:00"); 8307 8308 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 8309 new immutable SimpleTimeZone(dur!"minutes"(420))).toISOString() == 8310 "20121221T121212+07:00"); 8311 8312 // Test B.C. 8313 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toISOString() == 8314 "00001231T235959.9999999Z"); 8315 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC()).toISOString() == "00001231T235959.0000001Z"); 8316 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), UTC()).toISOString() == "00001231T235959Z"); 8317 8318 assert(SysTime(DateTime(0, 12, 4, 0, 12, 4)).toISOString() == "00001204T001204"); 8319 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0)).toISOString() == "-00091204T000000"); 8320 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12)).toISOString() == "-00991204T050612"); 8321 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59)).toISOString() == "-09991204T134459"); 8322 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59)).toISOString() == "-99990704T235959"); 8323 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1)).toISOString() == "-100001020T010101"); 8324 8325 assert(SysTime(DateTime(0, 12, 4, 0, 0, 0), msecs(7)).toISOString() == "00001204T000000.007"); 8326 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0), msecs(42)).toISOString() == "-00091204T000000.042"); 8327 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12), msecs(100)).toISOString() == "-00991204T050612.1"); 8328 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59), usecs(45020)).toISOString() == "-09991204T134459.04502"); 8329 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOString() == "-99990704T235959.0000012"); 8330 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOString() == "-100001020T010101.050789"); 8331 8332 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8333 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8334 assert(cst.toISOString() == "19990706T123033"); 8335 assert(ist.toISOString() == "19990706T123033"); 8336 8337 static void testScope(scope ref SysTime st) @safe 8338 { 8339 auto result = st.toISOString(); 8340 } 8341 } 8342 8343 8344 8345 /++ 8346 Converts this $(LREF SysTime) to a string with the format 8347 YYYY-MM-DDTHH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ 8348 is the time zone). 8349 8350 Default behaviour: 8351 Note that the number of digits in the fractional seconds varies with the 8352 number of fractional seconds. It's a maximum of 7 (which would be 8353 hnsecs), but only has as many as are necessary to hold the correct value 8354 (so no trailing zeroes), and if there are no fractional seconds, then 8355 there is no decimal point. 8356 8357 The optional parameter "prec" allows to change the default behavior by 8358 specifying the precision of the fractional seconds. The accepted values 8359 are in the range [-1, 7], where -1 represents the default behavior. 8360 8361 If this $(LREF SysTime)'s time zone is 8362 $(REF LocalTime,std,datetime,timezone), then TZ is empty. If its time 8363 zone is `UTC`, then it is "Z". Otherwise, it is the offset from UTC 8364 (e.g. +01:00 or -07:00). Note that the offset from UTC is $(I not) 8365 enough to uniquely identify the time zone. 8366 8367 Time zone offsets will be in the form +HH:MM or -HH:MM. 8368 8369 Params: 8370 writer = A `char` accepting 8371 $(REF_ALTTEXT output range, isOutputRange, std, range, primitives) 8372 prec = An `int` representing the desired precision. Acceptable values range from -1 to 7, where -1 represents the default behavior. 8373 Returns: 8374 A `string` when not using an output range; `void` otherwise. 8375 +/ 8376 string toISOExtString(int prec = -1) @safe const nothrow scope 8377 { 8378 assert(prec >= -1 && prec <= 7, "Precision must be in the range [-1, 7]"); 8379 8380 import std.array : appender; 8381 auto app = appender!string(); 8382 app.reserve(35); 8383 try 8384 toISOExtString(app, prec); 8385 catch (Exception e) 8386 assert(0, "toISOExtString() threw."); 8387 return app.data; 8388 } 8389 8390 /// ditto 8391 void toISOExtString(W)(ref W writer, int prec = -1) const scope 8392 if (isOutputRange!(W, char)) 8393 { 8394 assert(prec >= -1 && prec <= 7, "Precision must be in the range [-1, 7]"); 8395 8396 immutable adjustedTime = adjTime; 8397 long hnsecs = adjustedTime; 8398 8399 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 8400 8401 if (hnsecs < 0) 8402 { 8403 hnsecs += convert!("hours", "hnsecs")(24); 8404 --days; 8405 } 8406 8407 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 8408 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 8409 immutable second = splitUnitsFromHNSecs!"seconds"(hnsecs); 8410 8411 immutable dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour, 8412 cast(int) minute, cast(int) second)); 8413 8414 if (_timezone is LocalTime()) 8415 { 8416 dateTime.toISOExtString(writer); 8417 fracSecsToISOString(writer, cast(int) hnsecs, prec); 8418 return; 8419 } 8420 8421 if (_timezone is UTC()) 8422 { 8423 dateTime.toISOExtString(writer); 8424 fracSecsToISOString(writer, cast(int) hnsecs, prec); 8425 put(writer, 'Z'); 8426 return; 8427 } 8428 8429 immutable utcOffset = dur!"hnsecs"(adjustedTime - stdTime); 8430 8431 dateTime.toISOExtString(writer); 8432 fracSecsToISOString(writer, cast(int) hnsecs, prec); 8433 SimpleTimeZone.toISOExtString(writer, utcOffset); 8434 } 8435 8436 /// 8437 @safe unittest 8438 { 8439 import core.time : msecs, hnsecs; 8440 import std.datetime.date : DateTime; 8441 8442 assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toISOExtString() == 8443 "2010-07-04T07:06:12"); 8444 8445 assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(24)).toISOExtString() == 8446 "1998-12-25T02:15:00.024"); 8447 8448 assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toISOExtString() == 8449 "0000-01-05T23:09:59"); 8450 8451 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toISOExtString() == 8452 "-0004-01-05T00:00:02.052092"); 8453 8454 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toISOExtString(4) == 8455 "-0004-01-05T00:00:02.0520"); 8456 8457 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toISOExtString(2) == 8458 "-0004-01-05T00:00:02.05"); 8459 8460 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toISOExtString(7) == 8461 "-0004-01-05T00:00:02.0520920"); 8462 } 8463 8464 @safe unittest 8465 { 8466 import core.time; 8467 // Test A.D. 8468 assert(SysTime(DateTime.init, UTC()).toISOExtString() == "0001-01-01T00:00:00Z"); 8469 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC()).toISOExtString() == 8470 "0001-01-01T00:00:00.0000001Z"); 8471 8472 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0)).toISOExtString() == "0009-12-04T00:00:00"); 8473 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12)).toISOExtString() == "0099-12-04T05:06:12"); 8474 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59)).toISOExtString() == "0999-12-04T13:44:59"); 8475 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59)).toISOExtString() == "9999-07-04T23:59:59"); 8476 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1)).toISOExtString() == "+10000-10-20T01:01:01"); 8477 8478 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0), msecs(42)).toISOExtString() == "0009-12-04T00:00:00.042"); 8479 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12), msecs(100)).toISOExtString() == "0099-12-04T05:06:12.1"); 8480 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59), usecs(45020)).toISOExtString() == "0999-12-04T13:44:59.04502"); 8481 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOExtString() == "9999-07-04T23:59:59.0000012"); 8482 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOExtString() == 8483 "+10000-10-20T01:01:01.050789"); 8484 8485 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 8486 new immutable SimpleTimeZone(dur!"minutes"(-360))).toISOExtString() == 8487 "2012-12-21T12:12:12-06:00"); 8488 8489 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 8490 new immutable SimpleTimeZone(dur!"minutes"(420))).toISOExtString() == 8491 "2012-12-21T12:12:12+07:00"); 8492 8493 // Test B.C. 8494 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toISOExtString() == 8495 "0000-12-31T23:59:59.9999999Z"); 8496 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC()).toISOExtString() == 8497 "0000-12-31T23:59:59.0000001Z"); 8498 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), UTC()).toISOExtString() == "0000-12-31T23:59:59Z"); 8499 8500 assert(SysTime(DateTime(0, 12, 4, 0, 12, 4)).toISOExtString() == "0000-12-04T00:12:04"); 8501 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0)).toISOExtString() == "-0009-12-04T00:00:00"); 8502 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12)).toISOExtString() == "-0099-12-04T05:06:12"); 8503 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59)).toISOExtString() == "-0999-12-04T13:44:59"); 8504 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59)).toISOExtString() == "-9999-07-04T23:59:59"); 8505 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1)).toISOExtString() == "-10000-10-20T01:01:01"); 8506 8507 assert(SysTime(DateTime(0, 12, 4, 0, 0, 0), msecs(7)).toISOExtString() == "0000-12-04T00:00:00.007"); 8508 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0), msecs(42)).toISOExtString() == "-0009-12-04T00:00:00.042"); 8509 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12), msecs(100)).toISOExtString() == "-0099-12-04T05:06:12.1"); 8510 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59), usecs(45020)).toISOExtString() == 8511 "-0999-12-04T13:44:59.04502"); 8512 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOExtString() == 8513 "-9999-07-04T23:59:59.0000012"); 8514 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOExtString() == 8515 "-10000-10-20T01:01:01.050789"); 8516 8517 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8518 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8519 assert(cst.toISOExtString() == "1999-07-06T12:30:33"); 8520 assert(ist.toISOExtString() == "1999-07-06T12:30:33"); 8521 8522 static void testScope(scope ref SysTime st) @safe 8523 { 8524 auto result = st.toISOExtString(); 8525 } 8526 } 8527 8528 /++ 8529 Converts this $(LREF SysTime) to a string with the format 8530 YYYY-Mon-DD HH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ 8531 is the time zone). 8532 8533 Note that the number of digits in the fractional seconds varies with the 8534 number of fractional seconds. It's a maximum of 7 (which would be 8535 hnsecs), but only has as many as are necessary to hold the correct value 8536 (so no trailing zeroes), and if there are no fractional seconds, then 8537 there is no decimal point. 8538 8539 If this $(LREF SysTime)'s time zone is 8540 $(REF LocalTime,std,datetime,timezone), then TZ is empty. If its time 8541 zone is `UTC`, then it is "Z". Otherwise, it is the offset from UTC 8542 (e.g. +01:00 or -07:00). Note that the offset from UTC is $(I not) 8543 enough to uniquely identify the time zone. 8544 8545 Time zone offsets will be in the form +HH:MM or -HH:MM. 8546 8547 Params: 8548 writer = A `char` accepting 8549 $(REF_ALTTEXT output range, isOutputRange, std, range, primitives) 8550 Returns: 8551 A `string` when not using an output range; `void` otherwise. 8552 +/ 8553 string toSimpleString() @safe const nothrow scope 8554 { 8555 import std.array : appender; 8556 auto app = appender!string(); 8557 app.reserve(35); 8558 try 8559 toSimpleString(app); 8560 catch (Exception e) 8561 assert(0, "toSimpleString() threw."); 8562 return app.data; 8563 } 8564 8565 /// ditto 8566 void toSimpleString(W)(ref W writer) const scope 8567 if (isOutputRange!(W, char)) 8568 { 8569 immutable adjustedTime = adjTime; 8570 long hnsecs = adjustedTime; 8571 8572 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 8573 8574 if (hnsecs < 0) 8575 { 8576 hnsecs += convert!("hours", "hnsecs")(24); 8577 --days; 8578 } 8579 8580 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 8581 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 8582 immutable second = splitUnitsFromHNSecs!"seconds"(hnsecs); 8583 8584 immutable dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour, 8585 cast(int) minute, cast(int) second)); 8586 8587 if (_timezone is LocalTime()) 8588 { 8589 dateTime.toSimpleString(writer); 8590 fracSecsToISOString(writer, cast(int) hnsecs); 8591 return; 8592 } 8593 8594 if (_timezone is UTC()) 8595 { 8596 dateTime.toSimpleString(writer); 8597 fracSecsToISOString(writer, cast(int) hnsecs); 8598 put(writer, 'Z'); 8599 return; 8600 } 8601 8602 immutable utcOffset = dur!"hnsecs"(adjustedTime - stdTime); 8603 8604 dateTime.toSimpleString(writer); 8605 fracSecsToISOString(writer, cast(int) hnsecs); 8606 SimpleTimeZone.toISOExtString(writer, utcOffset); 8607 } 8608 8609 /// 8610 @safe unittest 8611 { 8612 import core.time : msecs, hnsecs; 8613 import std.datetime.date : DateTime; 8614 8615 assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toSimpleString() == 8616 "2010-Jul-04 07:06:12"); 8617 8618 assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(24)).toSimpleString() == 8619 "1998-Dec-25 02:15:00.024"); 8620 8621 assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toSimpleString() == 8622 "0000-Jan-05 23:09:59"); 8623 8624 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toSimpleString() == 8625 "-0004-Jan-05 00:00:02.052092"); 8626 } 8627 8628 @safe unittest 8629 { 8630 import core.time; 8631 // Test A.D. 8632 assert(SysTime(DateTime.init, UTC()).toString() == "0001-Jan-01 00:00:00Z"); 8633 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC()).toString() == "0001-Jan-01 00:00:00.0000001Z"); 8634 8635 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0)).toSimpleString() == "0009-Dec-04 00:00:00"); 8636 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12)).toSimpleString() == "0099-Dec-04 05:06:12"); 8637 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59)).toSimpleString() == "0999-Dec-04 13:44:59"); 8638 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59)).toSimpleString() == "9999-Jul-04 23:59:59"); 8639 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1)).toSimpleString() == "+10000-Oct-20 01:01:01"); 8640 8641 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0), msecs(42)).toSimpleString() == "0009-Dec-04 00:00:00.042"); 8642 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12), msecs(100)).toSimpleString() == "0099-Dec-04 05:06:12.1"); 8643 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59), usecs(45020)).toSimpleString() == 8644 "0999-Dec-04 13:44:59.04502"); 8645 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59), hnsecs(12)).toSimpleString() == 8646 "9999-Jul-04 23:59:59.0000012"); 8647 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1), hnsecs(507890)).toSimpleString() == 8648 "+10000-Oct-20 01:01:01.050789"); 8649 8650 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 8651 new immutable SimpleTimeZone(dur!"minutes"(-360))).toSimpleString() == 8652 "2012-Dec-21 12:12:12-06:00"); 8653 8654 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 8655 new immutable SimpleTimeZone(dur!"minutes"(420))).toSimpleString() == 8656 "2012-Dec-21 12:12:12+07:00"); 8657 8658 // Test B.C. 8659 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toSimpleString() == 8660 "0000-Dec-31 23:59:59.9999999Z"); 8661 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC()).toSimpleString() == 8662 "0000-Dec-31 23:59:59.0000001Z"); 8663 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), UTC()).toSimpleString() == "0000-Dec-31 23:59:59Z"); 8664 8665 assert(SysTime(DateTime(0, 12, 4, 0, 12, 4)).toSimpleString() == "0000-Dec-04 00:12:04"); 8666 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0)).toSimpleString() == "-0009-Dec-04 00:00:00"); 8667 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12)).toSimpleString() == "-0099-Dec-04 05:06:12"); 8668 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59)).toSimpleString() == "-0999-Dec-04 13:44:59"); 8669 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59)).toSimpleString() == "-9999-Jul-04 23:59:59"); 8670 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1)).toSimpleString() == "-10000-Oct-20 01:01:01"); 8671 8672 assert(SysTime(DateTime(0, 12, 4, 0, 0, 0), msecs(7)).toSimpleString() == "0000-Dec-04 00:00:00.007"); 8673 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0), msecs(42)).toSimpleString() == "-0009-Dec-04 00:00:00.042"); 8674 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12), msecs(100)).toSimpleString() == "-0099-Dec-04 05:06:12.1"); 8675 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59), usecs(45020)).toSimpleString() == 8676 "-0999-Dec-04 13:44:59.04502"); 8677 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59), hnsecs(12)).toSimpleString() == 8678 "-9999-Jul-04 23:59:59.0000012"); 8679 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1), hnsecs(507890)).toSimpleString() == 8680 "-10000-Oct-20 01:01:01.050789"); 8681 8682 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8683 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8684 assert(cst.toSimpleString() == "1999-Jul-06 12:30:33"); 8685 assert(ist.toSimpleString() == "1999-Jul-06 12:30:33"); 8686 8687 static void testScope(scope ref SysTime st) @safe 8688 { 8689 auto result = st.toSimpleString(); 8690 } 8691 } 8692 8693 8694 /++ 8695 Converts this $(LREF SysTime) to a string. 8696 8697 This function exists to make it easy to convert a $(LREF SysTime) to a 8698 string for code that does not care what the exact format is - just that 8699 it presents the information in a clear manner. It also makes it easy to 8700 simply convert a $(LREF SysTime) to a string when using functions such 8701 as `to!string`, `format`, or `writeln` which use toString to convert 8702 user-defined types. So, it is unlikely that much code will call 8703 toString directly. 8704 8705 The format of the string is purposefully unspecified, and code that 8706 cares about the format of the string should use `toISOString`, 8707 `toISOExtString`, `toSimpleString`, or some other custom formatting 8708 function that explicitly generates the format that the code needs. The 8709 reason is that the code is then clear about what format it's using, 8710 making it less error-prone to maintain the code and interact with other 8711 software that consumes the generated strings. It's for this same reason 8712 that $(LREF SysTime) has no `fromString` function, whereas it does have 8713 `fromISOString`, `fromISOExtString`, and `fromSimpleString`. 8714 8715 The format returned by toString may or may not change in the future. 8716 8717 Params: 8718 writer = A `char` accepting 8719 $(REF_ALTTEXT output range, isOutputRange, std, range, primitives) 8720 Returns: 8721 A `string` when not using an output range; `void` otherwise. 8722 +/ 8723 string toString() @safe const nothrow scope 8724 { 8725 return toSimpleString(); 8726 } 8727 8728 /// ditto 8729 void toString(W)(ref W writer) const scope 8730 if (isOutputRange!(W, char)) 8731 { 8732 toSimpleString(writer); 8733 } 8734 8735 @safe unittest 8736 { 8737 import core.time; 8738 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8739 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8740 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8741 static assert(__traits(compiles, st.toString())); 8742 static assert(__traits(compiles, cst.toString())); 8743 static assert(__traits(compiles, ist.toString())); 8744 8745 static void testScope(scope ref SysTime st) @safe 8746 { 8747 auto result = st.toString(); 8748 } 8749 } 8750 8751 8752 /++ 8753 Creates a $(LREF SysTime) from a string with the format 8754 YYYYMMDDTHHMMSS.FFFFFFFTZ (where F is fractional seconds and TZ 8755 is the time zone). Whitespace is stripped from the given string. 8756 8757 The exact format is exactly as described in $(LREF toISOString) except 8758 that trailing zeroes are permitted - including having fractional seconds 8759 with all zeroes. The time zone and fractional seconds are optional, 8760 however, a decimal point with nothing following it is invalid. 8761 Also, while $(LREF toISOString) will never generate a string 8762 with more than 7 digits in the fractional seconds (because that's the 8763 limit with hecto-nanosecond precision), it will allow more than 7 digits 8764 in order to read strings from other sources that have higher precision 8765 (however, any digits beyond 7 will be truncated). 8766 8767 If there is no time zone in the string, then 8768 $(REF LocalTime,std,datetime,timezone) is used. If the time zone is "Z", 8769 then `UTC` is used. Otherwise, a 8770 $(REF SimpleTimeZone,std,datetime,timezone) which corresponds to the 8771 given offset from UTC is used. To get the returned $(LREF SysTime) to be 8772 a particular time zone, pass in that time zone and the $(LREF SysTime) 8773 to be returned will be converted to that time zone (though it will still 8774 be read in as whatever time zone is in its string). 8775 8776 The accepted formats for time zone offsets are +HH, -HH, +HHMM, and 8777 -HHMM. 8778 8779 $(RED Warning: 8780 Previously, $(LREF toISOString) did the same as 8781 $(LREF toISOExtString) and generated +HH:MM or -HH:MM for the time 8782 zone when it was not $(REF LocalTime,std,datetime,timezone) or 8783 $(REF UTC,std,datetime,timezone), which is not in conformance with 8784 ISO 8601 for the non-extended string format. This has now been 8785 fixed. However, for now, fromISOString will continue to accept the 8786 extended format for the time zone so that any code which has been 8787 writing out the result of toISOString to read in later will continue 8788 to work. The current behavior will be kept until July 2019 at which 8789 point, fromISOString will be fixed to be standards compliant.) 8790 8791 Params: 8792 isoString = A string formatted in the ISO format for dates and times. 8793 tz = The time zone to convert the given time to (no 8794 conversion occurs if null). 8795 8796 Throws: 8797 $(REF DateTimeException,std,datetime,date) if the given string is 8798 not in the ISO format or if the resulting $(LREF SysTime) would not 8799 be valid. 8800 +/ 8801 static SysTime fromISOString(S)(scope const S isoString, immutable TimeZone tz = null) @safe 8802 if (isSomeString!S) 8803 { 8804 import std.algorithm.searching : startsWith, find; 8805 import std.conv : to; 8806 import std.string : strip; 8807 import std.utf : byCodeUnit; 8808 8809 auto str = strip(isoString); 8810 immutable skipFirst = str.startsWith('+', '-'); 8811 8812 auto found = (skipFirst ? str[1..$] : str).byCodeUnit.find('.', 'Z', '+', '-'); 8813 auto dateTimeStr = str[0 .. $ - found[0].length]; 8814 8815 typeof(str.byCodeUnit) foundTZ; // needs to have longer lifetime than zoneStr 8816 typeof(str) fracSecStr; 8817 typeof(str) zoneStr; 8818 8819 if (found[1] != 0) 8820 { 8821 if (found[1] == 1) 8822 { 8823 foundTZ = found[0].find('Z', '+', '-')[0]; 8824 8825 if (foundTZ.length != 0) 8826 { 8827 static if (isNarrowString!S) 8828 { 8829 fracSecStr = found[0][0 .. $ - foundTZ.length].source; 8830 zoneStr = foundTZ.source; 8831 } 8832 else 8833 { 8834 fracSecStr = found[0][0 .. $ - foundTZ.length]; 8835 zoneStr = foundTZ; 8836 } 8837 } 8838 else 8839 { 8840 static if (isNarrowString!S) 8841 fracSecStr = found[0].source; 8842 else 8843 fracSecStr = found[0]; 8844 } 8845 } 8846 else 8847 { 8848 static if (isNarrowString!S) 8849 zoneStr = found[0].source; 8850 else 8851 zoneStr = found[0]; 8852 } 8853 } 8854 8855 try 8856 { 8857 auto dateTime = DateTime.fromISOString(dateTimeStr); 8858 auto fracSec = fracSecsFromISOString(fracSecStr); 8859 8860 Rebindable!(immutable TimeZone) parsedZone; 8861 8862 if (zoneStr.empty) 8863 parsedZone = LocalTime(); 8864 else if (zoneStr == "Z") 8865 parsedZone = UTC(); 8866 else 8867 { 8868 try 8869 parsedZone = SimpleTimeZone.fromISOString(zoneStr); 8870 catch (DateTimeException dte) 8871 parsedZone = SimpleTimeZone.fromISOExtString(zoneStr); 8872 } 8873 8874 auto retval = SysTime(dateTime, fracSec, parsedZone); 8875 8876 if (tz !is null) 8877 retval.timezone = tz; 8878 8879 return retval; 8880 } 8881 catch (DateTimeException dte) 8882 throw new DateTimeException(format("Invalid ISO String: %s", isoString)); 8883 } 8884 8885 /// 8886 @safe unittest 8887 { 8888 import core.time : hours, msecs, usecs, hnsecs; 8889 import std.datetime.date : DateTime; 8890 import std.datetime.timezone : SimpleTimeZone, UTC; 8891 8892 assert(SysTime.fromISOString("20100704T070612") == 8893 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 8894 8895 assert(SysTime.fromISOString("19981225T021500.007") == 8896 SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(7))); 8897 8898 assert(SysTime.fromISOString("00000105T230959.00002") == 8899 SysTime(DateTime(0, 1, 5, 23, 9, 59), usecs(20))); 8900 8901 assert(SysTime.fromISOString("20130207T043937.000050392") == 8902 SysTime(DateTime(2013, 2, 7, 4, 39, 37), hnsecs(503))); 8903 8904 assert(SysTime.fromISOString("-00040105T000002") == 8905 SysTime(DateTime(-4, 1, 5, 0, 0, 2))); 8906 8907 assert(SysTime.fromISOString(" 20100704T070612 ") == 8908 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 8909 8910 assert(SysTime.fromISOString("20100704T070612Z") == 8911 SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC())); 8912 8913 assert(SysTime.fromISOString("20100704T070612-0800") == 8914 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 8915 new immutable SimpleTimeZone(hours(-8)))); 8916 8917 assert(SysTime.fromISOString("20100704T070612+0800") == 8918 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 8919 new immutable SimpleTimeZone(hours(8)))); 8920 } 8921 8922 @safe unittest 8923 { 8924 import core.time; 8925 foreach (str; ["", "20100704000000", "20100704 000000", "20100704t000000", 8926 "20100704T000000.", "20100704T000000.A", "20100704T000000.Z", 8927 "20100704T000000.0000000A", "20100704T000000.00000000A", 8928 "20100704T000000+", "20100704T000000-", "20100704T000000:", 8929 "20100704T000000-:", "20100704T000000+:", "20100704T000000-1:", 8930 "20100704T000000+1:", "20100704T000000+1:0", 8931 "20100704T000000-12.00", "20100704T000000+12.00", 8932 "20100704T000000-8", "20100704T000000+8", 8933 "20100704T000000-800", "20100704T000000+800", 8934 "20100704T000000-080", "20100704T000000+080", 8935 "20100704T000000-2400", "20100704T000000+2400", 8936 "20100704T000000-1260", "20100704T000000+1260", 8937 "20100704T000000.0-8", "20100704T000000.0+8", 8938 "20100704T000000.0-800", "20100704T000000.0+800", 8939 "20100704T000000.0-080", "20100704T000000.0+080", 8940 "20100704T000000.0-2400", "20100704T000000.0+2400", 8941 "20100704T000000.0-1260", "20100704T000000.0+1260", 8942 "20100704T000000-8:00", "20100704T000000+8:00", 8943 "20100704T000000-08:0", "20100704T000000+08:0", 8944 "20100704T000000-24:00", "20100704T000000+24:00", 8945 "20100704T000000-12:60", "20100704T000000+12:60", 8946 "20100704T000000.0-8:00", "20100704T000000.0+8:00", 8947 "20100704T000000.0-08:0", "20100704T000000.0+08:0", 8948 "20100704T000000.0-24:00", "20100704T000000.0+24:00", 8949 "20100704T000000.0-12:60", "20100704T000000.0+12:60", 8950 "2010-07-0400:00:00", "2010-07-04 00:00:00", 8951 "2010-07-04t00:00:00", "2010-07-04T00:00:00.", 8952 "2010-Jul-0400:00:00", "2010-Jul-04 00:00:00", "2010-Jul-04t00:00:00", 8953 "2010-Jul-04T00:00:00", "2010-Jul-04 00:00:00.", 8954 "2010-12-22T172201", "2010-Dec-22 17:22:01"]) 8955 { 8956 assertThrown!DateTimeException(SysTime.fromISOString(str), format("[%s]", str)); 8957 } 8958 8959 static void test(string str, SysTime st, size_t line = __LINE__) 8960 { 8961 if (SysTime.fromISOString(str) != st) 8962 throw new AssertError("unittest failure", __FILE__, line); 8963 } 8964 8965 test("20101222T172201", SysTime(DateTime(2010, 12, 22, 17, 22, 1))); 8966 test("19990706T123033", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8967 test("-19990706T123033", SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 8968 test("+019990706T123033", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8969 test("19990706T123033 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8970 test(" 19990706T123033", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8971 test(" 19990706T123033 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8972 8973 test("19070707T121212.0", SysTime(DateTime(1907, 7, 7, 12, 12, 12))); 8974 test("19070707T121212.0000000", SysTime(DateTime(1907, 7, 7, 12, 12, 12))); 8975 test("19070707T121212.0000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), hnsecs(1))); 8976 test("20100704T000000.00000000", SysTime(Date(2010, 7, 4))); 8977 test("20100704T000000.00000009", SysTime(Date(2010, 7, 4))); 8978 test("20100704T000000.00000019", SysTime(DateTime(2010, 7, 4), hnsecs(1))); 8979 test("19070707T121212.000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1))); 8980 test("19070707T121212.0000010", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1))); 8981 test("19070707T121212.001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1))); 8982 test("19070707T121212.0010000", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1))); 8983 8984 auto west60 = new immutable SimpleTimeZone(hours(-1)); 8985 auto west90 = new immutable SimpleTimeZone(minutes(-90)); 8986 auto west480 = new immutable SimpleTimeZone(hours(-8)); 8987 auto east60 = new immutable SimpleTimeZone(hours(1)); 8988 auto east90 = new immutable SimpleTimeZone(minutes(90)); 8989 auto east480 = new immutable SimpleTimeZone(hours(8)); 8990 8991 test("20101222T172201Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), UTC())); 8992 test("20101222T172201-0100", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60)); 8993 test("20101222T172201-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60)); 8994 test("20101222T172201-0130", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west90)); 8995 test("20101222T172201-0800", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west480)); 8996 test("20101222T172201+0100", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 8997 test("20101222T172201+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 8998 test("20101222T172201+0130", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 8999 test("20101222T172201+0800", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east480)); 9000 9001 test("20101103T065106.57159Z", SysTime(DateTime(2010, 11, 3, 6, 51, 6), hnsecs(5715900), UTC())); 9002 test("20101222T172201.23412Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_341_200), UTC())); 9003 test("20101222T172201.23112-0100", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_311_200), west60)); 9004 test("20101222T172201.45-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), west60)); 9005 test("20101222T172201.1-0130", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_000_000), west90)); 9006 test("20101222T172201.55-0800", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(5_500_000), west480)); 9007 test("20101222T172201.1234567+0100", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_234_567), east60)); 9008 test("20101222T172201.0+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9009 test("20101222T172201.0000000+0130", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 9010 test("20101222T172201.45+0800", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), east480)); 9011 9012 // for dstring coverage 9013 assert(SysTime.fromISOString("20101222T172201.23112-0100"d) == SysTime( 9014 DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_311_200), west60)); 9015 assert(SysTime.fromISOString("19070707T121212.0010000"d) == SysTime( 9016 DateTime(1907, 7, 7, 12, 12, 12), msecs(1))); 9017 9018 // @@@DEPRECATED_2019-07@@@ 9019 // This isn't deprecated per se, but that text will make it so that it 9020 // pops up when deprecations are moved along around July 2019. At that 9021 // time, we will update fromISOString so that it is conformant with ISO 9022 // 8601, and it will no longer accept ISO extended time zones (it does 9023 // currently because of https://issues.dlang.org/show_bug.cgi?id=15654 9024 // toISOString used to incorrectly use the ISO extended time zone format). 9025 // These tests will then start failing will need to be updated accordingly. 9026 // Also, the notes about this issue in toISOString and fromISOString's 9027 // documentation will need to be removed. 9028 test("20101222T172201-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60)); 9029 test("20101222T172201-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west90)); 9030 test("20101222T172201-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west480)); 9031 test("20101222T172201+01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9032 test("20101222T172201+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 9033 test("20101222T172201+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east480)); 9034 9035 test("20101222T172201.23112-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_311_200), west60)); 9036 test("20101222T172201.1-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_000_000), west90)); 9037 test("20101222T172201.55-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(5_500_000), west480)); 9038 test("20101222T172201.1234567+01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_234_567), east60)); 9039 test("20101222T172201.0000000+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 9040 test("20101222T172201.45+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), east480)); 9041 9042 static void testScope(scope ref string str) @safe 9043 { 9044 auto result = SysTime.fromISOString(str); 9045 } 9046 } 9047 9048 // https://issues.dlang.org/show_bug.cgi?id=17801 9049 @safe unittest 9050 { 9051 import std.conv : to; 9052 import std.meta : AliasSeq; 9053 static foreach (C; AliasSeq!(char, wchar, dchar)) 9054 { 9055 static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) 9056 { 9057 assert(SysTime.fromISOString(to!S("20121221T141516Z")) == 9058 SysTime(DateTime(2012, 12, 21, 14, 15, 16), UTC())); 9059 } 9060 } 9061 } 9062 9063 9064 /++ 9065 Creates a $(LREF SysTime) from a string with the format 9066 YYYY-MM-DDTHH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ 9067 is the time zone). Whitespace is stripped from the given string. 9068 9069 The exact format is exactly as described in $(LREF toISOExtString) 9070 except that trailing zeroes are permitted - including having fractional 9071 seconds with all zeroes. The time zone and fractional seconds are 9072 optional, however, a decimal point with nothing following it is invalid. 9073 Also, while $(LREF toISOExtString) will never generate a 9074 string with more than 7 digits in the fractional seconds (because that's 9075 the limit with hecto-nanosecond precision), it will allow more than 7 9076 digits in order to read strings from other sources that have higher 9077 precision (however, any digits beyond 7 will be truncated). 9078 9079 If there is no time zone in the string, then 9080 $(REF LocalTime,std,datetime,timezone) is used. If the time zone is "Z", 9081 then `UTC` is used. Otherwise, a 9082 $(REF SimpleTimeZone,std,datetime,timezone) which corresponds to the 9083 given offset from UTC is used. To get the returned $(LREF SysTime) to be 9084 a particular time zone, pass in that time zone and the $(LREF SysTime) 9085 to be returned will be converted to that time zone (though it will still 9086 be read in as whatever time zone is in its string). 9087 9088 The accepted formats for time zone offsets are +HH, -HH, +HH:MM, and 9089 -HH:MM. 9090 9091 Params: 9092 isoExtString = A string formatted in the ISO Extended format for 9093 dates and times. 9094 tz = The time zone to convert the given time to (no 9095 conversion occurs if null). 9096 9097 Throws: 9098 $(REF DateTimeException,std,datetime,date) if the given string is 9099 not in the ISO format or if the resulting $(LREF SysTime) would not 9100 be valid. 9101 +/ 9102 static SysTime fromISOExtString(S)(scope const S isoExtString, immutable TimeZone tz = null) @safe 9103 if (isSomeString!(S)) 9104 { 9105 import std.algorithm.searching : countUntil, find; 9106 import std.conv : to; 9107 import std.string : strip, indexOf; 9108 9109 auto str = strip(isoExtString); 9110 9111 auto tIndex = str.indexOf('T'); 9112 enforce(tIndex != -1, new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString))); 9113 9114 auto found = str[tIndex + 1 .. $].find('.', 'Z', '+', '-'); 9115 auto dateTimeStr = str[0 .. $ - found[0].length]; 9116 9117 typeof(str) foundTZ; // needs to have longer lifetime than zoneStr 9118 typeof(str) fracSecStr; 9119 typeof(str) zoneStr; 9120 9121 if (found[1] != 0) 9122 { 9123 if (found[1] == 1) 9124 { 9125 foundTZ = found[0].find('Z', '+', '-')[0]; 9126 9127 if (foundTZ.length != 0) 9128 { 9129 fracSecStr = found[0][0 .. $ - foundTZ.length]; 9130 zoneStr = foundTZ; 9131 } 9132 else 9133 fracSecStr = found[0]; 9134 } 9135 else 9136 zoneStr = found[0]; 9137 } 9138 9139 try 9140 { 9141 auto dateTime = DateTime.fromISOExtString(dateTimeStr); 9142 auto fracSec = fracSecsFromISOString(fracSecStr); 9143 Rebindable!(immutable TimeZone) parsedZone; 9144 9145 if (zoneStr.empty) 9146 parsedZone = LocalTime(); 9147 else if (zoneStr == "Z") 9148 parsedZone = UTC(); 9149 else 9150 parsedZone = SimpleTimeZone.fromISOExtString(zoneStr); 9151 9152 auto retval = SysTime(dateTime, fracSec, parsedZone); 9153 9154 if (tz !is null) 9155 retval.timezone = tz; 9156 9157 return retval; 9158 } 9159 catch (DateTimeException dte) 9160 throw new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)); 9161 } 9162 9163 /// 9164 @safe unittest 9165 { 9166 import core.time : hours, msecs, usecs, hnsecs; 9167 import std.datetime.date : DateTime; 9168 import std.datetime.timezone : SimpleTimeZone, UTC; 9169 9170 assert(SysTime.fromISOExtString("2010-07-04T07:06:12") == 9171 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 9172 9173 assert(SysTime.fromISOExtString("1998-12-25T02:15:00.007") == 9174 SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(7))); 9175 9176 assert(SysTime.fromISOExtString("0000-01-05T23:09:59.00002") == 9177 SysTime(DateTime(0, 1, 5, 23, 9, 59), usecs(20))); 9178 9179 assert(SysTime.fromISOExtString("2013-02-07T04:39:37.000050392") == 9180 SysTime(DateTime(2013, 2, 7, 4, 39, 37), hnsecs(503))); 9181 9182 assert(SysTime.fromISOExtString("-0004-01-05T00:00:02") == 9183 SysTime(DateTime(-4, 1, 5, 0, 0, 2))); 9184 9185 assert(SysTime.fromISOExtString(" 2010-07-04T07:06:12 ") == 9186 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 9187 9188 assert(SysTime.fromISOExtString("2010-07-04T07:06:12Z") == 9189 SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC())); 9190 9191 assert(SysTime.fromISOExtString("2010-07-04T07:06:12-08:00") == 9192 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 9193 new immutable SimpleTimeZone(hours(-8)))); 9194 assert(SysTime.fromISOExtString("2010-07-04T07:06:12+08:00") == 9195 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 9196 new immutable SimpleTimeZone(hours(8)))); 9197 } 9198 9199 @safe unittest 9200 { 9201 import core.time; 9202 foreach (str; ["", "20100704000000", "20100704 000000", 9203 "20100704t000000", "20100704T000000.", "20100704T000000.0", 9204 "2010-07:0400:00:00", "2010-07-04 00:00:00", 9205 "2010-07-04 00:00:00", "2010-07-04t00:00:00", 9206 "2010-07-04T00:00:00.", "2010-07-04T00:00:00.A", "2010-07-04T00:00:00.Z", 9207 "2010-07-04T00:00:00.0000000A", "2010-07-04T00:00:00.00000000A", 9208 "2010-07-04T00:00:00+", "2010-07-04T00:00:00-", 9209 "2010-07-04T00:00:00:", "2010-07-04T00:00:00-:", "2010-07-04T00:00:00+:", 9210 "2010-07-04T00:00:00-1:", "2010-07-04T00:00:00+1:", "2010-07-04T00:00:00+1:0", 9211 "2010-07-04T00:00:00-12.00", "2010-07-04T00:00:00+12.00", 9212 "2010-07-04T00:00:00-8", "2010-07-04T00:00:00+8", 9213 "20100704T000000-800", "20100704T000000+800", 9214 "20100704T000000-080", "20100704T000000+080", 9215 "20100704T000000-2400", "20100704T000000+2400", 9216 "20100704T000000-1260", "20100704T000000+1260", 9217 "20100704T000000.0-800", "20100704T000000.0+800", 9218 "20100704T000000.0-8", "20100704T000000.0+8", 9219 "20100704T000000.0-080", "20100704T000000.0+080", 9220 "20100704T000000.0-2400", "20100704T000000.0+2400", 9221 "20100704T000000.0-1260", "20100704T000000.0+1260", 9222 "2010-07-04T00:00:00-8:00", "2010-07-04T00:00:00+8:00", 9223 "2010-07-04T00:00:00-24:00", "2010-07-04T00:00:00+24:00", 9224 "2010-07-04T00:00:00-12:60", "2010-07-04T00:00:00+12:60", 9225 "2010-07-04T00:00:00.0-8:00", "2010-07-04T00:00:00.0+8:00", 9226 "2010-07-04T00:00:00.0-8", "2010-07-04T00:00:00.0+8", 9227 "2010-07-04T00:00:00.0-24:00", "2010-07-04T00:00:00.0+24:00", 9228 "2010-07-04T00:00:00.0-12:60", "2010-07-04T00:00:00.0+12:60", 9229 "2010-Jul-0400:00:00", "2010-Jul-04t00:00:00", 9230 "2010-Jul-04 00:00:00.", "2010-Jul-04 00:00:00.0", 9231 "20101222T172201", "2010-Dec-22 17:22:01"]) 9232 { 9233 assertThrown!DateTimeException(SysTime.fromISOExtString(str), format("[%s]", str)); 9234 } 9235 9236 static void test(string str, SysTime st, size_t line = __LINE__) 9237 { 9238 if (SysTime.fromISOExtString(str) != st) 9239 throw new AssertError("unittest failure", __FILE__, line); 9240 } 9241 9242 test("2010-12-22T17:22:01", SysTime(DateTime(2010, 12, 22, 17, 22, 1))); 9243 test("1999-07-06T12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9244 test("-1999-07-06T12:30:33", SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 9245 test("+01999-07-06T12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9246 test("1999-07-06T12:30:33 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9247 test(" 1999-07-06T12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9248 test(" 1999-07-06T12:30:33 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9249 9250 test("1907-07-07T12:12:12.0", SysTime(DateTime(1907, 7, 7, 12, 12, 12))); 9251 test("1907-07-07T12:12:12.0000000", SysTime(DateTime(1907, 7, 7, 12, 12, 12))); 9252 test("1907-07-07T12:12:12.0000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), hnsecs(1))); 9253 test("2010-07-04T00:00:00.00000000", SysTime(Date(2010, 7, 4))); 9254 test("2010-07-04T00:00:00.00000009", SysTime(Date(2010, 7, 4))); 9255 test("2010-07-04T00:00:00.00000019", SysTime(DateTime(2010, 7, 4), hnsecs(1))); 9256 test("1907-07-07T12:12:12.000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1))); 9257 test("1907-07-07T12:12:12.0000010", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1))); 9258 test("1907-07-07T12:12:12.001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1))); 9259 test("1907-07-07T12:12:12.0010000", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1))); 9260 9261 auto west60 = new immutable SimpleTimeZone(hours(-1)); 9262 auto west90 = new immutable SimpleTimeZone(minutes(-90)); 9263 auto west480 = new immutable SimpleTimeZone(hours(-8)); 9264 auto east60 = new immutable SimpleTimeZone(hours(1)); 9265 auto east90 = new immutable SimpleTimeZone(minutes(90)); 9266 auto east480 = new immutable SimpleTimeZone(hours(8)); 9267 9268 test("2010-12-22T17:22:01Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), UTC())); 9269 test("2010-12-22T17:22:01-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60)); 9270 test("2010-12-22T17:22:01-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60)); 9271 test("2010-12-22T17:22:01-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west90)); 9272 test("2010-12-22T17:22:01-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west480)); 9273 test("2010-12-22T17:22:01+01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9274 test("2010-12-22T17:22:01+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9275 test("2010-12-22T17:22:01+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 9276 test("2010-12-22T17:22:01+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east480)); 9277 9278 test("2010-11-03T06:51:06.57159Z", SysTime(DateTime(2010, 11, 3, 6, 51, 6), hnsecs(5715900), UTC())); 9279 test("2010-12-22T17:22:01.23412Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_341_200), UTC())); 9280 test("2010-12-22T17:22:01.23112-01:00", 9281 SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_311_200), west60)); 9282 test("2010-12-22T17:22:01.45-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), west60)); 9283 test("2010-12-22T17:22:01.1-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_000_000), west90)); 9284 test("2010-12-22T17:22:01.55-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(5_500_000), west480)); 9285 test("2010-12-22T17:22:01.1234567+01:00", 9286 SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_234_567), east60)); 9287 test("2010-12-22T17:22:01.0+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9288 test("2010-12-22T17:22:01.0000000+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 9289 test("2010-12-22T17:22:01.45+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), east480)); 9290 9291 static void testScope(scope ref string str) @safe 9292 { 9293 auto result = SysTime.fromISOExtString(str); 9294 } 9295 } 9296 9297 // https://issues.dlang.org/show_bug.cgi?id=17801 9298 @safe unittest 9299 { 9300 import core.time; 9301 import std.conv : to; 9302 import std.meta : AliasSeq; 9303 static foreach (C; AliasSeq!(char, wchar, dchar)) 9304 { 9305 static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) 9306 { 9307 assert(SysTime.fromISOExtString(to!S("2012-12-21T14:15:16Z")) == 9308 SysTime(DateTime(2012, 12, 21, 14, 15, 16), UTC())); 9309 } 9310 } 9311 } 9312 9313 9314 /++ 9315 Creates a $(LREF SysTime) from a string with the format 9316 YYYY-Mon-DD HH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ 9317 is the time zone). Whitespace is stripped from the given string. 9318 9319 The exact format is exactly as described in $(LREF toSimpleString) except 9320 that trailing zeroes are permitted - including having fractional seconds 9321 with all zeroes. The time zone and fractional seconds are optional, 9322 however, a decimal point with nothing following it is invalid. 9323 Also, while $(LREF toSimpleString) will never generate a 9324 string with more than 7 digits in the fractional seconds (because that's 9325 the limit with hecto-nanosecond precision), it will allow more than 7 9326 digits in order to read strings from other sources that have higher 9327 precision (however, any digits beyond 7 will be truncated). 9328 9329 If there is no time zone in the string, then 9330 $(REF LocalTime,std,datetime,timezone) is used. If the time zone is "Z", 9331 then `UTC` is used. Otherwise, a 9332 $(REF SimpleTimeZone,std,datetime,timezone) which corresponds to the 9333 given offset from UTC is used. To get the returned $(LREF SysTime) to be 9334 a particular time zone, pass in that time zone and the $(LREF SysTime) 9335 to be returned will be converted to that time zone (though it will still 9336 be read in as whatever time zone is in its string). 9337 9338 The accepted formats for time zone offsets are +HH, -HH, +HH:MM, and 9339 -HH:MM. 9340 9341 Params: 9342 simpleString = A string formatted in the way that 9343 `toSimpleString` formats dates and times. 9344 tz = The time zone to convert the given time to (no 9345 conversion occurs if null). 9346 9347 Throws: 9348 $(REF DateTimeException,std,datetime,date) if the given string is 9349 not in the ISO format or if the resulting $(LREF SysTime) would not 9350 be valid. 9351 +/ 9352 static SysTime fromSimpleString(S)(scope const S simpleString, immutable TimeZone tz = null) @safe 9353 if (isSomeString!(S)) 9354 { 9355 import std.algorithm.searching : find; 9356 import std.conv : to; 9357 import std.string : strip, indexOf; 9358 9359 auto str = strip(simpleString); 9360 9361 auto spaceIndex = str.indexOf(' '); 9362 enforce(spaceIndex != -1, new DateTimeException(format("Invalid Simple String: %s", simpleString))); 9363 9364 auto found = str[spaceIndex + 1 .. $].find('.', 'Z', '+', '-'); 9365 auto dateTimeStr = str[0 .. $ - found[0].length]; 9366 9367 typeof(str) foundTZ; // needs to have longer lifetime than zoneStr 9368 typeof(str) fracSecStr; 9369 typeof(str) zoneStr; 9370 9371 if (found[1] != 0) 9372 { 9373 if (found[1] == 1) 9374 { 9375 foundTZ = found[0].find('Z', '+', '-')[0]; 9376 9377 if (foundTZ.length != 0) 9378 { 9379 fracSecStr = found[0][0 .. $ - foundTZ.length]; 9380 zoneStr = foundTZ; 9381 } 9382 else 9383 fracSecStr = found[0]; 9384 } 9385 else 9386 zoneStr = found[0]; 9387 } 9388 9389 try 9390 { 9391 auto dateTime = DateTime.fromSimpleString(dateTimeStr); 9392 auto fracSec = fracSecsFromISOString(fracSecStr); 9393 Rebindable!(immutable TimeZone) parsedZone; 9394 9395 if (zoneStr.empty) 9396 parsedZone = LocalTime(); 9397 else if (zoneStr == "Z") 9398 parsedZone = UTC(); 9399 else 9400 parsedZone = SimpleTimeZone.fromISOExtString(zoneStr); 9401 9402 auto retval = SysTime(dateTime, fracSec, parsedZone); 9403 9404 if (tz !is null) 9405 retval.timezone = tz; 9406 9407 return retval; 9408 } 9409 catch (DateTimeException dte) 9410 throw new DateTimeException(format("Invalid Simple String: %s", simpleString)); 9411 } 9412 9413 /// 9414 @safe unittest 9415 { 9416 import core.time : hours, msecs, usecs, hnsecs; 9417 import std.datetime.date : DateTime; 9418 import std.datetime.timezone : SimpleTimeZone, UTC; 9419 9420 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12") == 9421 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 9422 9423 assert(SysTime.fromSimpleString("1998-Dec-25 02:15:00.007") == 9424 SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(7))); 9425 9426 assert(SysTime.fromSimpleString("0000-Jan-05 23:09:59.00002") == 9427 SysTime(DateTime(0, 1, 5, 23, 9, 59), usecs(20))); 9428 9429 assert(SysTime.fromSimpleString("2013-Feb-07 04:39:37.000050392") == 9430 SysTime(DateTime(2013, 2, 7, 4, 39, 37), hnsecs(503))); 9431 9432 assert(SysTime.fromSimpleString("-0004-Jan-05 00:00:02") == 9433 SysTime(DateTime(-4, 1, 5, 0, 0, 2))); 9434 9435 assert(SysTime.fromSimpleString(" 2010-Jul-04 07:06:12 ") == 9436 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 9437 9438 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12Z") == 9439 SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC())); 9440 9441 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12-08:00") == 9442 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 9443 new immutable SimpleTimeZone(hours(-8)))); 9444 9445 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12+08:00") == 9446 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 9447 new immutable SimpleTimeZone(hours(8)))); 9448 } 9449 9450 @safe unittest 9451 { 9452 import core.time; 9453 foreach (str; ["", "20100704000000", "20100704 000000", 9454 "20100704t000000", "20100704T000000.", "20100704T000000.0", 9455 "2010-07-0400:00:00", "2010-07-04 00:00:00", "2010-07-04t00:00:00", 9456 "2010-07-04T00:00:00.", "2010-07-04T00:00:00.0", 9457 "2010-Jul-0400:00:00", "2010-Jul-04t00:00:00", "2010-Jul-04T00:00:00", 9458 "2010-Jul-04 00:00:00.", "2010-Jul-04 00:00:00.A", "2010-Jul-04 00:00:00.Z", 9459 "2010-Jul-04 00:00:00.0000000A", "2010-Jul-04 00:00:00.00000000A", 9460 "2010-Jul-04 00:00:00+", "2010-Jul-04 00:00:00-", 9461 "2010-Jul-04 00:00:00:", "2010-Jul-04 00:00:00-:", 9462 "2010-Jul-04 00:00:00+:", "2010-Jul-04 00:00:00-1:", 9463 "2010-Jul-04 00:00:00+1:", "2010-Jul-04 00:00:00+1:0", 9464 "2010-Jul-04 00:00:00-12.00", "2010-Jul-04 00:00:00+12.00", 9465 "2010-Jul-04 00:00:00-8", "2010-Jul-04 00:00:00+8", 9466 "20100704T000000-800", "20100704T000000+800", 9467 "20100704T000000-080", "20100704T000000+080", 9468 "20100704T000000-2400", "20100704T000000+2400", 9469 "20100704T000000-1260", "20100704T000000+1260", 9470 "20100704T000000.0-800", "20100704T000000.0+800", 9471 "20100704T000000.0-8", "20100704T000000.0+8", 9472 "20100704T000000.0-080", "20100704T000000.0+080", 9473 "20100704T000000.0-2400", "20100704T000000.0+2400", 9474 "20100704T000000.0-1260", "20100704T000000.0+1260", 9475 "2010-Jul-04 00:00:00-8:00", "2010-Jul-04 00:00:00+8:00", 9476 "2010-Jul-04 00:00:00-08:0", "2010-Jul-04 00:00:00+08:0", 9477 "2010-Jul-04 00:00:00-24:00", "2010-Jul-04 00:00:00+24:00", 9478 "2010-Jul-04 00:00:00-12:60", "2010-Jul-04 00:00:00+24:60", 9479 "2010-Jul-04 00:00:00.0-8:00", "2010-Jul-04 00:00:00+8:00", 9480 "2010-Jul-04 00:00:00.0-8", "2010-Jul-04 00:00:00.0+8", 9481 "2010-Jul-04 00:00:00.0-08:0", "2010-Jul-04 00:00:00.0+08:0", 9482 "2010-Jul-04 00:00:00.0-24:00", "2010-Jul-04 00:00:00.0+24:00", 9483 "2010-Jul-04 00:00:00.0-12:60", "2010-Jul-04 00:00:00.0+24:60", 9484 "20101222T172201", "2010-12-22T172201"]) 9485 { 9486 assertThrown!DateTimeException(SysTime.fromSimpleString(str), format("[%s]", str)); 9487 } 9488 9489 static void test(string str, SysTime st, size_t line = __LINE__) 9490 { 9491 if (SysTime.fromSimpleString(str) != st) 9492 throw new AssertError("unittest failure", __FILE__, line); 9493 } 9494 9495 test("2010-Dec-22 17:22:01", SysTime(DateTime(2010, 12, 22, 17, 22, 1))); 9496 test("1999-Jul-06 12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9497 test("-1999-Jul-06 12:30:33", SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 9498 test("+01999-Jul-06 12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9499 test("1999-Jul-06 12:30:33 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9500 test(" 1999-Jul-06 12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9501 test(" 1999-Jul-06 12:30:33 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9502 9503 test("1907-Jul-07 12:12:12.0", SysTime(DateTime(1907, 7, 7, 12, 12, 12))); 9504 test("1907-Jul-07 12:12:12.0000000", SysTime(DateTime(1907, 7, 7, 12, 12, 12))); 9505 test("2010-Jul-04 00:00:00.00000000", SysTime(Date(2010, 7, 4))); 9506 test("2010-Jul-04 00:00:00.00000009", SysTime(Date(2010, 7, 4))); 9507 test("2010-Jul-04 00:00:00.00000019", SysTime(DateTime(2010, 7, 4), hnsecs(1))); 9508 test("1907-Jul-07 12:12:12.0000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), hnsecs(1))); 9509 test("1907-Jul-07 12:12:12.000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1))); 9510 test("1907-Jul-07 12:12:12.0000010", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1))); 9511 test("1907-Jul-07 12:12:12.001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1))); 9512 test("1907-Jul-07 12:12:12.0010000", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1))); 9513 9514 auto west60 = new immutable SimpleTimeZone(hours(-1)); 9515 auto west90 = new immutable SimpleTimeZone(minutes(-90)); 9516 auto west480 = new immutable SimpleTimeZone(hours(-8)); 9517 auto east60 = new immutable SimpleTimeZone(hours(1)); 9518 auto east90 = new immutable SimpleTimeZone(minutes(90)); 9519 auto east480 = new immutable SimpleTimeZone(hours(8)); 9520 9521 test("2010-Dec-22 17:22:01Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), UTC())); 9522 test("2010-Dec-22 17:22:01-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60)); 9523 test("2010-Dec-22 17:22:01-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60)); 9524 test("2010-Dec-22 17:22:01-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west90)); 9525 test("2010-Dec-22 17:22:01-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west480)); 9526 test("2010-Dec-22 17:22:01+01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9527 test("2010-Dec-22 17:22:01+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9528 test("2010-Dec-22 17:22:01+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 9529 test("2010-Dec-22 17:22:01+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east480)); 9530 9531 test("2010-Nov-03 06:51:06.57159Z", SysTime(DateTime(2010, 11, 3, 6, 51, 6), hnsecs(5715900), UTC())); 9532 test("2010-Dec-22 17:22:01.23412Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_341_200), UTC())); 9533 test("2010-Dec-22 17:22:01.23112-01:00", 9534 SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_311_200), west60)); 9535 test("2010-Dec-22 17:22:01.45-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), west60)); 9536 test("2010-Dec-22 17:22:01.1-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_000_000), west90)); 9537 test("2010-Dec-22 17:22:01.55-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(5_500_000), west480)); 9538 test("2010-Dec-22 17:22:01.1234567+01:00", 9539 SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_234_567), east60)); 9540 test("2010-Dec-22 17:22:01.0+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9541 test("2010-Dec-22 17:22:01.0000000+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 9542 test("2010-Dec-22 17:22:01.45+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), east480)); 9543 9544 static void testScope(scope ref string str) @safe 9545 { 9546 auto result = SysTime.fromSimpleString(str); 9547 } 9548 } 9549 9550 // https://issues.dlang.org/show_bug.cgi?id=17801 9551 @safe unittest 9552 { 9553 import core.time; 9554 import std.conv : to; 9555 import std.meta : AliasSeq; 9556 static foreach (C; AliasSeq!(char, wchar, dchar)) 9557 { 9558 static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) 9559 { 9560 assert(SysTime.fromSimpleString(to!S("2012-Dec-21 14:15:16Z")) == 9561 SysTime(DateTime(2012, 12, 21, 14, 15, 16), UTC())); 9562 } 9563 } 9564 } 9565 9566 9567 /++ 9568 Returns the $(LREF SysTime) farthest in the past which is representable 9569 by $(LREF SysTime). 9570 9571 The $(LREF SysTime) which is returned is in UTC. 9572 +/ 9573 @property static SysTime min() @safe pure nothrow 9574 { 9575 return SysTime(long.min, UTC()); 9576 } 9577 9578 @safe unittest 9579 { 9580 assert(SysTime.min.year < 0); 9581 assert(SysTime.min < SysTime.max); 9582 } 9583 9584 9585 /++ 9586 Returns the $(LREF SysTime) farthest in the future which is representable 9587 by $(LREF SysTime). 9588 9589 The $(LREF SysTime) which is returned is in UTC. 9590 +/ 9591 @property static SysTime max() @safe pure nothrow 9592 { 9593 return SysTime(long.max, UTC()); 9594 } 9595 9596 @safe unittest 9597 { 9598 assert(SysTime.max.year > 0); 9599 assert(SysTime.max > SysTime.min); 9600 } 9601 9602 9603 private: 9604 9605 /+ 9606 Returns `stdTime` converted to $(LREF SysTime)'s time zone. 9607 +/ 9608 @property long adjTime() @safe const nothrow scope 9609 { 9610 return _timezone.utcToTZ(_stdTime); 9611 } 9612 9613 9614 /+ 9615 Converts the given hnsecs from $(LREF SysTime)'s time zone to std time. 9616 +/ 9617 @property void adjTime(long adjTime) @safe nothrow scope 9618 { 9619 _stdTime = _timezone.tzToUTC(adjTime); 9620 } 9621 9622 9623 final class InitTimeZone : TimeZone 9624 { 9625 public: 9626 9627 static immutable(InitTimeZone) opCall() @safe pure nothrow @nogc { return _initTimeZone; } 9628 9629 @property override bool hasDST() @safe const nothrow @nogc { return false; } 9630 9631 override bool dstInEffect(long stdTime) @safe const scope nothrow @nogc { return false; } 9632 9633 override long utcToTZ(long stdTime) @safe const scope nothrow @nogc { return 0; } 9634 9635 override long tzToUTC(long adjTime) @safe const scope nothrow @nogc { return 0; } 9636 9637 override Duration utcOffsetAt(long stdTime) @safe const scope nothrow @nogc { return Duration.zero; } 9638 9639 private: 9640 9641 this() @safe immutable pure 9642 { 9643 super("SysTime.init's timezone", "SysTime.init's timezone", "SysTime.init's timezone"); 9644 } 9645 9646 static immutable InitTimeZone _initTimeZone = new immutable(InitTimeZone); 9647 } 9648 9649 // https://issues.dlang.org/show_bug.cgi?id=17732 9650 @safe unittest 9651 { 9652 assert(SysTime.init.timezone is InitTimeZone()); 9653 assert(SysTime.init.toISOString() == "00010101T000000+00:00"); 9654 assert(SysTime.init.toISOExtString() == "0001-01-01T00:00:00+00:00"); 9655 assert(SysTime.init.toSimpleString() == "0001-Jan-01 00:00:00+00:00"); 9656 assert(SysTime.init.toString() == "0001-Jan-01 00:00:00+00:00"); 9657 } 9658 9659 // Assigning a value to _timezone in SysTime.init currently doesn't work due 9660 // to https://issues.dlang.org/show_bug.cgi?id=17740. So, to hack around 9661 // that problem, these accessors have been added so that we can insert a 9662 // runtime check for null and then use InitTimeZone for SysTime.init (which 9663 // which is the only case where _timezone would be null). This thus fixes 9664 // the problem with segfaulting when using SysTime.init but at the cost of 9665 // what should be an unnecessary null check. Once 17740 has finally been 9666 // fixed, _timezoneStorage should be removed, these accessors should be 9667 // removed, and the _timezone variable declaration should be restored. 9668 pragma(inline, true) @property _timezone() @safe const pure nothrow @nogc 9669 { 9670 return _timezoneStorage is null ? InitTimeZone() : _timezoneStorage; 9671 } 9672 9673 pragma(inline, true) @property void _timezone(return scope immutable TimeZone tz) @safe pure nothrow @nogc scope 9674 { 9675 _timezoneStorage = tz; 9676 } 9677 9678 9679 long _stdTime; 9680 Rebindable!(immutable TimeZone) _timezoneStorage; 9681 //Rebindable!(immutable TimeZone) _timezone = InitTimeZone(); 9682 } 9683 9684 /// 9685 @safe unittest 9686 { 9687 import core.time : days, hours, seconds; 9688 import std.datetime.date : Date, DateTime; 9689 import std.datetime.timezone : SimpleTimeZone, UTC; 9690 9691 const dt = DateTime(2018, 1, 1, 10, 30, 0); 9692 // make a specific point in time in the UTC timezone 9693 auto st = SysTime(dt, UTC()); 9694 assert(st.year == 2018); 9695 assert(st.hour == 10); 9696 9697 // cast to convert 9698 assert(cast(DateTime) st == dt); 9699 assert(cast(Date) st == Date(2018, 1, 1)); 9700 9701 // make a specific point in time in the New York timezone 9702 const ny = SysTime(dt, 9703 new immutable SimpleTimeZone(-5.hours, "America/New_York") 9704 ); 9705 assert(ny != st); 9706 assert(ny.hour == 10); 9707 9708 // ISO standard time strings 9709 assert(st.toISOString() == "20180101T103000Z"); 9710 assert(st.toISOExtString() == "2018-01-01T10:30:00Z"); 9711 9712 // add two days and 30 seconds 9713 st += 2.days + 30.seconds; 9714 assert(st.toISOExtString() == "2018-01-03T10:30:30Z"); 9715 } 9716 9717 9718 /++ 9719 Converts from unix time (which uses midnight, January 1st, 1970 UTC as its 9720 epoch and seconds as its units) to "std time" (which uses midnight, 9721 January 1st, 1 A.D. UTC and hnsecs as its units). 9722 9723 The C standard does not specify the representation of time_t, so it is 9724 implementation defined. On POSIX systems, unix time is equivalent to 9725 time_t, but that's not necessarily true on other systems (e.g. it is 9726 not true for the Digital Mars C runtime). So, be careful when using unix 9727 time with C functions on non-POSIX systems. 9728 9729 "std time"'s epoch is based on the Proleptic Gregorian Calendar per ISO 9730 8601 and is what $(LREF SysTime) uses internally. However, holding the time 9731 as an integer in hnsecs since that epoch technically isn't actually part of 9732 the standard, much as it's based on it, so the name "std time" isn't 9733 particularly good, but there isn't an official name for it. C# uses "ticks" 9734 for the same thing, but they aren't actually clock ticks, and the term 9735 "ticks" $(I is) used for actual clock ticks for $(REF MonoTime, core,time), 9736 so it didn't make sense to use the term ticks here. So, for better or worse, 9737 std.datetime uses the term "std time" for this. 9738 9739 Params: 9740 unixTime = The unix time to convert. 9741 9742 See_Also: 9743 SysTime.fromUnixTime 9744 +/ 9745 long unixTimeToStdTime(long unixTime) @safe pure nothrow @nogc 9746 { 9747 return 621_355_968_000_000_000L + convert!("seconds", "hnsecs")(unixTime); 9748 } 9749 9750 /// 9751 @safe unittest 9752 { 9753 import std.datetime.date : DateTime; 9754 import std.datetime.timezone : UTC; 9755 9756 // Midnight, January 1st, 1970 9757 assert(unixTimeToStdTime(0) == 621_355_968_000_000_000L); 9758 assert(SysTime(unixTimeToStdTime(0)) == 9759 SysTime(DateTime(1970, 1, 1), UTC())); 9760 9761 assert(unixTimeToStdTime(int.max) == 642_830_804_470_000_000L); 9762 assert(SysTime(unixTimeToStdTime(int.max)) == 9763 SysTime(DateTime(2038, 1, 19, 3, 14, 7), UTC())); 9764 9765 assert(unixTimeToStdTime(-127_127) == 621_354_696_730_000_000L); 9766 assert(SysTime(unixTimeToStdTime(-127_127)) == 9767 SysTime(DateTime(1969, 12, 30, 12, 41, 13), UTC())); 9768 } 9769 9770 @safe unittest 9771 { 9772 // Midnight, January 2nd, 1970 9773 assert(unixTimeToStdTime(86_400) == 621_355_968_000_000_000L + 864_000_000_000L); 9774 // Midnight, December 31st, 1969 9775 assert(unixTimeToStdTime(-86_400) == 621_355_968_000_000_000L - 864_000_000_000L); 9776 9777 assert(unixTimeToStdTime(0) == (Date(1970, 1, 1) - Date(1, 1, 1)).total!"hnsecs"); 9778 assert(unixTimeToStdTime(0) == (DateTime(1970, 1, 1) - DateTime(1, 1, 1)).total!"hnsecs"); 9779 9780 foreach (dt; [DateTime(2010, 11, 1, 19, 5, 22), DateTime(1952, 7, 6, 2, 17, 9)]) 9781 assert(unixTimeToStdTime((dt - DateTime(1970, 1, 1)).total!"seconds") == (dt - DateTime.init).total!"hnsecs"); 9782 } 9783 9784 9785 /++ 9786 Converts std time (which uses midnight, January 1st, 1 A.D. UTC as its epoch 9787 and hnsecs as its units) to unix time (which uses midnight, January 1st, 9788 1970 UTC as its epoch and seconds as its units). 9789 9790 The C standard does not specify the representation of time_t, so it is 9791 implementation defined. On POSIX systems, unix time is equivalent to 9792 time_t, but that's not necessarily true on other systems (e.g. it is 9793 not true for the Digital Mars C runtime). So, be careful when using unix 9794 time with C functions on non-POSIX systems. 9795 9796 "std time"'s epoch is based on the Proleptic Gregorian Calendar per ISO 9797 8601 and is what $(LREF SysTime) uses internally. However, holding the time 9798 as an integer in hnsecs since that epoch technically isn't actually part of 9799 the standard, much as it's based on it, so the name "std time" isn't 9800 particularly good, but there isn't an official name for it. C# uses "ticks" 9801 for the same thing, but they aren't actually clock ticks, and the term 9802 "ticks" $(I is) used for actual clock ticks for $(REF MonoTime, core,time), 9803 so it didn't make sense to use the term ticks here. So, for better or worse, 9804 std.datetime uses the term "std time" for this. 9805 9806 By default, the return type is time_t (which is normally an alias for 9807 int on 32-bit systems and long on 64-bit systems), but if a different 9808 size is required than either int or long can be passed as a template 9809 argument to get the desired size. 9810 9811 If the return type is int, and the result can't fit in an int, then the 9812 closest value that can be held in 32 bits will be used (so `int.max` 9813 if it goes over and `int.min` if it goes under). However, no attempt 9814 is made to deal with integer overflow if the return type is long. 9815 9816 Params: 9817 T = The return type (int or long). It defaults to time_t, which is 9818 normally 32 bits on a 32-bit system and 64 bits on a 64-bit 9819 system. 9820 stdTime = The std time to convert. 9821 9822 Returns: 9823 A signed integer representing the unix time which is equivalent to 9824 the given std time. 9825 9826 See_Also: 9827 SysTime.toUnixTime 9828 +/ 9829 T stdTimeToUnixTime(T = time_t)(long stdTime) @safe pure nothrow 9830 if (is(T == int) || is(T == long)) 9831 { 9832 immutable unixTime = convert!("hnsecs", "seconds")(stdTime - 621_355_968_000_000_000L); 9833 9834 static assert(is(time_t == int) || is(time_t == long), 9835 "Currently, std.datetime only supports systems where time_t is int or long"); 9836 9837 static if (is(T == long)) 9838 return unixTime; 9839 else static if (is(T == int)) 9840 { 9841 if (unixTime > int.max) 9842 return int.max; 9843 return unixTime < int.min ? int.min : cast(int) unixTime; 9844 } 9845 else 9846 static assert(0, "Bug in template constraint. Only int and long allowed."); 9847 } 9848 9849 /// 9850 @safe unittest 9851 { 9852 // Midnight, January 1st, 1970 UTC 9853 assert(stdTimeToUnixTime(621_355_968_000_000_000L) == 0); 9854 9855 // 2038-01-19 03:14:07 UTC 9856 assert(stdTimeToUnixTime(642_830_804_470_000_000L) == int.max); 9857 } 9858 9859 @safe unittest 9860 { 9861 enum unixEpochAsStdTime = (Date(1970, 1, 1) - Date.init).total!"hnsecs"; 9862 9863 assert(stdTimeToUnixTime(unixEpochAsStdTime) == 0); // Midnight, January 1st, 1970 9864 assert(stdTimeToUnixTime(unixEpochAsStdTime + 864_000_000_000L) == 86_400); // Midnight, January 2nd, 1970 9865 assert(stdTimeToUnixTime(unixEpochAsStdTime - 864_000_000_000L) == -86_400); // Midnight, December 31st, 1969 9866 9867 assert(stdTimeToUnixTime((Date(1970, 1, 1) - Date(1, 1, 1)).total!"hnsecs") == 0); 9868 assert(stdTimeToUnixTime((DateTime(1970, 1, 1) - DateTime(1, 1, 1)).total!"hnsecs") == 0); 9869 9870 foreach (dt; [DateTime(2010, 11, 1, 19, 5, 22), DateTime(1952, 7, 6, 2, 17, 9)]) 9871 assert(stdTimeToUnixTime((dt - DateTime.init).total!"hnsecs") == (dt - DateTime(1970, 1, 1)).total!"seconds"); 9872 9873 enum max = convert!("seconds", "hnsecs")(int.max); 9874 enum min = convert!("seconds", "hnsecs")(int.min); 9875 enum one = convert!("seconds", "hnsecs")(1); 9876 9877 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + max) == int.max); 9878 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + max) == int.max); 9879 9880 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + max + one) == int.max + 1L); 9881 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + max + one) == int.max); 9882 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + max + 9_999_999) == int.max); 9883 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + max + 9_999_999) == int.max); 9884 9885 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + min) == int.min); 9886 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + min) == int.min); 9887 9888 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + min - one) == int.min - 1L); 9889 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + min - one) == int.min); 9890 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + min - 9_999_999) == int.min); 9891 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + min - 9_999_999) == int.min); 9892 } 9893 9894 9895 version (StdDdoc) 9896 { 9897 version (Windows) 9898 {} 9899 else 9900 { 9901 alias SYSTEMTIME = void*; 9902 alias FILETIME = void*; 9903 } 9904 9905 /++ 9906 $(BLUE This function is Windows-Only.) 9907 9908 Converts a `SYSTEMTIME` struct to a $(LREF SysTime). 9909 9910 Params: 9911 st = The `SYSTEMTIME` struct to convert. 9912 tz = The time zone that the time in the `SYSTEMTIME` struct is 9913 assumed to be (if the `SYSTEMTIME` was supplied by a Windows 9914 system call, the `SYSTEMTIME` will either be in local time 9915 or UTC, depending on the call). 9916 9917 Throws: 9918 $(REF DateTimeException,std,datetime,date) if the given 9919 `SYSTEMTIME` will not fit in a $(LREF SysTime), which is highly 9920 unlikely to happen given that `SysTime.max` is in 29,228 A.D. and 9921 the maximum `SYSTEMTIME` is in 30,827 A.D. 9922 +/ 9923 SysTime SYSTEMTIMEToSysTime(const scope SYSTEMTIME* st, immutable TimeZone tz = LocalTime()) @safe; 9924 9925 9926 /++ 9927 $(BLUE This function is Windows-Only.) 9928 9929 Converts a $(LREF SysTime) to a `SYSTEMTIME` struct. 9930 9931 The `SYSTEMTIME` which is returned will be set using the given 9932 $(LREF SysTime)'s time zone, so to get the `SYSTEMTIME` in 9933 UTC, set the $(LREF SysTime)'s time zone to UTC. 9934 9935 Params: 9936 sysTime = The $(LREF SysTime) to convert. 9937 9938 Throws: 9939 $(REF DateTimeException,std,datetime,date) if the given 9940 $(LREF SysTime) will not fit in a `SYSTEMTIME`. This will only 9941 happen if the $(LREF SysTime)'s date is prior to 1601 A.D. 9942 +/ 9943 SYSTEMTIME SysTimeToSYSTEMTIME(scope SysTime sysTime) @safe; 9944 9945 9946 /++ 9947 $(BLUE This function is Windows-Only.) 9948 9949 Converts a `FILETIME` struct to the number of hnsecs since midnight, 9950 January 1st, 1 A.D. 9951 9952 Params: 9953 ft = The `FILETIME` struct to convert. 9954 9955 Throws: 9956 $(REF DateTimeException,std,datetime,date) if the given 9957 `FILETIME` cannot be represented as the return value. 9958 +/ 9959 long FILETIMEToStdTime(scope const FILETIME* ft) @safe; 9960 9961 9962 /++ 9963 $(BLUE This function is Windows-Only.) 9964 9965 Converts a `FILETIME` struct to a $(LREF SysTime). 9966 9967 Params: 9968 ft = The `FILETIME` struct to convert. 9969 tz = The time zone that the $(LREF SysTime) will be in 9970 (`FILETIME`s are in UTC). 9971 9972 Throws: 9973 $(REF DateTimeException,std,datetime,date) if the given 9974 `FILETIME` will not fit in a $(LREF SysTime). 9975 +/ 9976 SysTime FILETIMEToSysTime(scope const FILETIME* ft, immutable TimeZone tz = LocalTime()) @safe; 9977 9978 9979 /++ 9980 $(BLUE This function is Windows-Only.) 9981 9982 Converts a number of hnsecs since midnight, January 1st, 1 A.D. to a 9983 `FILETIME` struct. 9984 9985 Params: 9986 stdTime = The number of hnsecs since midnight, January 1st, 1 A.D. 9987 UTC. 9988 9989 Throws: 9990 $(REF DateTimeException,std,datetime,date) if the given value will 9991 not fit in a `FILETIME`. 9992 +/ 9993 FILETIME stdTimeToFILETIME(long stdTime) @safe; 9994 9995 9996 /++ 9997 $(BLUE This function is Windows-Only.) 9998 9999 Converts a $(LREF SysTime) to a `FILETIME` struct. 10000 10001 `FILETIME`s are always in UTC. 10002 10003 Params: 10004 sysTime = The $(LREF SysTime) to convert. 10005 10006 Throws: 10007 $(REF DateTimeException,std,datetime,date) if the given 10008 $(LREF SysTime) will not fit in a `FILETIME`. 10009 +/ 10010 FILETIME SysTimeToFILETIME(scope SysTime sysTime) @safe; 10011 } 10012 else version (Windows) 10013 { 10014 SysTime SYSTEMTIMEToSysTime(const scope SYSTEMTIME* st, immutable TimeZone tz = LocalTime()) @safe 10015 { 10016 const max = SysTime.max; 10017 10018 static void throwLaterThanMax() 10019 { 10020 throw new DateTimeException("The given SYSTEMTIME is for a date greater than SysTime.max."); 10021 } 10022 10023 if (st.wYear > max.year) 10024 throwLaterThanMax(); 10025 else if (st.wYear == max.year) 10026 { 10027 if (st.wMonth > max.month) 10028 throwLaterThanMax(); 10029 else if (st.wMonth == max.month) 10030 { 10031 if (st.wDay > max.day) 10032 throwLaterThanMax(); 10033 else if (st.wDay == max.day) 10034 { 10035 if (st.wHour > max.hour) 10036 throwLaterThanMax(); 10037 else if (st.wHour == max.hour) 10038 { 10039 if (st.wMinute > max.minute) 10040 throwLaterThanMax(); 10041 else if (st.wMinute == max.minute) 10042 { 10043 if (st.wSecond > max.second) 10044 throwLaterThanMax(); 10045 else if (st.wSecond == max.second) 10046 { 10047 if (st.wMilliseconds > max.fracSecs.total!"msecs") 10048 throwLaterThanMax(); 10049 } 10050 } 10051 } 10052 } 10053 } 10054 } 10055 10056 auto dt = DateTime(st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); 10057 10058 import core.time : msecs; 10059 return SysTime(dt, msecs(st.wMilliseconds), tz); 10060 } 10061 10062 @system unittest 10063 { 10064 auto sysTime = Clock.currTime(UTC()); 10065 SYSTEMTIME st = void; 10066 GetSystemTime(&st); 10067 auto converted = SYSTEMTIMEToSysTime(&st, UTC()); 10068 import core.time : abs; 10069 assert(abs((converted - sysTime)) <= dur!"seconds"(2)); 10070 10071 static void testScope(scope SYSTEMTIME* st) @safe 10072 { 10073 auto result = SYSTEMTIMEToSysTime(st); 10074 } 10075 } 10076 10077 10078 SYSTEMTIME SysTimeToSYSTEMTIME(scope SysTime sysTime) @safe 10079 { 10080 immutable dt = cast(DateTime) sysTime; 10081 10082 if (dt.year < 1601) 10083 throw new DateTimeException("SYSTEMTIME cannot hold dates prior to the year 1601."); 10084 10085 SYSTEMTIME st; 10086 10087 st.wYear = dt.year; 10088 st.wMonth = dt.month; 10089 st.wDayOfWeek = dt.dayOfWeek; 10090 st.wDay = dt.day; 10091 st.wHour = dt.hour; 10092 st.wMinute = dt.minute; 10093 st.wSecond = dt.second; 10094 st.wMilliseconds = cast(ushort) sysTime.fracSecs.total!"msecs"; 10095 10096 return st; 10097 } 10098 10099 @system unittest 10100 { 10101 SYSTEMTIME st = void; 10102 GetSystemTime(&st); 10103 auto sysTime = SYSTEMTIMEToSysTime(&st, UTC()); 10104 10105 SYSTEMTIME result = SysTimeToSYSTEMTIME(sysTime); 10106 10107 assert(st.wYear == result.wYear); 10108 assert(st.wMonth == result.wMonth); 10109 assert(st.wDayOfWeek == result.wDayOfWeek); 10110 assert(st.wDay == result.wDay); 10111 assert(st.wHour == result.wHour); 10112 assert(st.wMinute == result.wMinute); 10113 assert(st.wSecond == result.wSecond); 10114 assert(st.wMilliseconds == result.wMilliseconds); 10115 10116 static void testScope(scope ref SysTime st) @safe 10117 { 10118 auto localResult = SysTimeToSYSTEMTIME(st); 10119 } 10120 } 10121 10122 private enum hnsecsFrom1601 = 504_911_232_000_000_000L; 10123 10124 long FILETIMEToStdTime(scope const FILETIME* ft) @safe 10125 { 10126 ULARGE_INTEGER ul; 10127 ul.HighPart = ft.dwHighDateTime; 10128 ul.LowPart = ft.dwLowDateTime; 10129 ulong tempHNSecs = ul.QuadPart; 10130 10131 if (tempHNSecs > long.max - hnsecsFrom1601) 10132 throw new DateTimeException("The given FILETIME cannot be represented as a stdTime value."); 10133 10134 return cast(long) tempHNSecs + hnsecsFrom1601; 10135 } 10136 10137 SysTime FILETIMEToSysTime(scope const FILETIME* ft, immutable TimeZone tz = LocalTime()) @safe 10138 { 10139 auto sysTime = SysTime(FILETIMEToStdTime(ft), UTC()); 10140 sysTime.timezone = tz; 10141 return sysTime; 10142 } 10143 10144 @system unittest 10145 { 10146 auto sysTime = Clock.currTime(UTC()); 10147 SYSTEMTIME st = void; 10148 GetSystemTime(&st); 10149 10150 FILETIME ft = void; 10151 SystemTimeToFileTime(&st, &ft); 10152 10153 auto converted = FILETIMEToSysTime(&ft); 10154 10155 import core.time : abs; 10156 assert(abs((converted - sysTime)) <= dur!"seconds"(2)); 10157 10158 static void testScope(scope FILETIME* ft) @safe 10159 { 10160 auto result = FILETIMEToSysTime(ft); 10161 } 10162 } 10163 10164 10165 FILETIME stdTimeToFILETIME(long stdTime) @safe 10166 { 10167 if (stdTime < hnsecsFrom1601) 10168 throw new DateTimeException("The given stdTime value cannot be represented as a FILETIME."); 10169 10170 ULARGE_INTEGER ul; 10171 ul.QuadPart = cast(ulong) stdTime - hnsecsFrom1601; 10172 10173 FILETIME ft; 10174 ft.dwHighDateTime = ul.HighPart; 10175 ft.dwLowDateTime = ul.LowPart; 10176 10177 return ft; 10178 } 10179 10180 FILETIME SysTimeToFILETIME(scope SysTime sysTime) @safe 10181 { 10182 return stdTimeToFILETIME(sysTime.stdTime); 10183 } 10184 10185 @system unittest 10186 { 10187 SYSTEMTIME st = void; 10188 GetSystemTime(&st); 10189 10190 FILETIME ft = void; 10191 SystemTimeToFileTime(&st, &ft); 10192 auto sysTime = FILETIMEToSysTime(&ft, UTC()); 10193 10194 FILETIME result = SysTimeToFILETIME(sysTime); 10195 10196 assert(ft.dwLowDateTime == result.dwLowDateTime); 10197 assert(ft.dwHighDateTime == result.dwHighDateTime); 10198 10199 static void testScope(scope ref SysTime st) @safe 10200 { 10201 auto local_result = SysTimeToFILETIME(st); 10202 } 10203 } 10204 } 10205 10206 10207 /++ 10208 Type representing the DOS file date/time format. 10209 +/ 10210 alias DosFileTime = uint; 10211 10212 /++ 10213 Converts from DOS file date/time to $(LREF SysTime). 10214 10215 Params: 10216 dft = The DOS file time to convert. 10217 tz = The time zone which the DOS file time is assumed to be in. 10218 10219 Throws: 10220 $(REF DateTimeException,std,datetime,date) if the `DosFileTime` is 10221 invalid. 10222 +/ 10223 SysTime DosFileTimeToSysTime(DosFileTime dft, immutable TimeZone tz = LocalTime()) @safe 10224 { 10225 uint dt = cast(uint) dft; 10226 10227 if (dt == 0) 10228 throw new DateTimeException("Invalid DosFileTime."); 10229 10230 int year = ((dt >> 25) & 0x7F) + 1980; 10231 int month = ((dt >> 21) & 0x0F); // 1 .. 12 10232 int dayOfMonth = ((dt >> 16) & 0x1F); // 1 .. 31 10233 int hour = (dt >> 11) & 0x1F; // 0 .. 23 10234 int minute = (dt >> 5) & 0x3F; // 0 .. 59 10235 int second = (dt << 1) & 0x3E; // 0 .. 58 (in 2 second increments) 10236 10237 try 10238 return SysTime(DateTime(year, month, dayOfMonth, hour, minute, second), tz); 10239 catch (DateTimeException dte) 10240 throw new DateTimeException("Invalid DosFileTime", __FILE__, __LINE__, dte); 10241 } 10242 10243 /// 10244 @safe unittest 10245 { 10246 import std.datetime.date : DateTime; 10247 10248 assert(DosFileTimeToSysTime(0b00000000001000010000000000000000) == SysTime(DateTime(1980, 1, 1, 0, 0, 0))); 10249 assert(DosFileTimeToSysTime(0b11111111100111111011111101111101) == SysTime(DateTime(2107, 12, 31, 23, 59, 58))); 10250 assert(DosFileTimeToSysTime(0x3E3F8456) == SysTime(DateTime(2011, 1, 31, 16, 34, 44))); 10251 } 10252 10253 @safe unittest 10254 { 10255 static void testScope(scope ref DosFileTime dft) @safe 10256 { 10257 auto result = DosFileTimeToSysTime(dft); 10258 } 10259 } 10260 10261 10262 /++ 10263 Converts from $(LREF SysTime) to DOS file date/time. 10264 10265 Params: 10266 sysTime = The $(LREF SysTime) to convert. 10267 10268 Throws: 10269 $(REF DateTimeException,std,datetime,date) if the given 10270 $(LREF SysTime) cannot be converted to a `DosFileTime`. 10271 +/ 10272 DosFileTime SysTimeToDosFileTime(scope SysTime sysTime) @safe 10273 { 10274 auto dateTime = cast(DateTime) sysTime; 10275 10276 if (dateTime.year < 1980) 10277 throw new DateTimeException("DOS File Times cannot hold dates prior to 1980."); 10278 10279 if (dateTime.year > 2107) 10280 throw new DateTimeException("DOS File Times cannot hold dates past 2107."); 10281 10282 uint retval = 0; 10283 retval = (dateTime.year - 1980) << 25; 10284 retval |= (dateTime.month & 0x0F) << 21; 10285 retval |= (dateTime.day & 0x1F) << 16; 10286 retval |= (dateTime.hour & 0x1F) << 11; 10287 retval |= (dateTime.minute & 0x3F) << 5; 10288 retval |= (dateTime.second >> 1) & 0x1F; 10289 10290 return cast(DosFileTime) retval; 10291 } 10292 10293 /// 10294 @safe unittest 10295 { 10296 import std.datetime.date : DateTime; 10297 10298 assert(SysTimeToDosFileTime(SysTime(DateTime(1980, 1, 1, 0, 0, 0))) == 0b00000000001000010000000000000000); 10299 assert(SysTimeToDosFileTime(SysTime(DateTime(2107, 12, 31, 23, 59, 58))) == 0b11111111100111111011111101111101); 10300 assert(SysTimeToDosFileTime(SysTime(DateTime(2011, 1, 31, 16, 34, 44))) == 0x3E3F8456); 10301 } 10302 10303 @safe unittest 10304 { 10305 static void testScope(scope ref SysTime st) @safe 10306 { 10307 auto result = SysTimeToDosFileTime(st); 10308 } 10309 } 10310 10311 10312 /++ 10313 The given array of `char` or random-access range of `char` or 10314 `ubyte` is expected to be in the format specified in 10315 $(HTTP tools.ietf.org/html/rfc5322, RFC 5322) section 3.3 with the 10316 grammar rule $(I date-time). It is the date-time format commonly used in 10317 internet messages such as e-mail and HTTP. The corresponding 10318 $(LREF SysTime) will be returned. 10319 10320 RFC 822 was the original spec (hence the function's name), whereas RFC 5322 10321 is the current spec. 10322 10323 The day of the week is ignored beyond verifying that it's a valid day of the 10324 week, as the day of the week can be inferred from the date. It is not 10325 checked whether the given day of the week matches the actual day of the week 10326 of the given date (though it is technically invalid per the spec if the 10327 day of the week doesn't match the actual day of the week of the given date). 10328 10329 If the time zone is `"-0000"` (or considered to be equivalent to 10330 `"-0000"` by section 4.3 of the spec), a 10331 $(REF SimpleTimeZone,std,datetime,timezone) with a utc offset of `0` is 10332 used rather than $(REF UTC,std,datetime,timezone), whereas `"+0000"` uses 10333 $(REF UTC,std,datetime,timezone). 10334 10335 Note that because $(LREF SysTime) does not currently support having a second 10336 value of 60 (as is sometimes done for leap seconds), if the date-time value 10337 does have a value of 60 for the seconds, it is treated as 59. 10338 10339 The one area in which this function violates RFC 5322 is that it accepts 10340 `"\n"` in folding whitespace in the place of `"\r\n"`, because the 10341 HTTP spec requires it. 10342 10343 Throws: 10344 $(REF DateTimeException,std,datetime,date) if the given string doesn't 10345 follow the grammar for a date-time field or if the resulting 10346 $(LREF SysTime) is invalid. 10347 +/ 10348 SysTime parseRFC822DateTime()(scope const char[] value) @safe 10349 { 10350 import std.string : representation; 10351 return parseRFC822DateTime(value.representation); 10352 } 10353 10354 /++ Ditto +/ 10355 SysTime parseRFC822DateTime(R)(scope R value) 10356 if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && 10357 (is(immutable ElementType!R == immutable char) || is(immutable ElementType!R == immutable ubyte))) 10358 { 10359 import std.algorithm.searching : find, all; 10360 import std.ascii : isDigit, isAlpha, isPrintable; 10361 import std.conv : to; 10362 import std.functional : not; 10363 import std.string : capitalize, format; 10364 import std.traits : EnumMembers, isArray; 10365 import std.typecons : Rebindable; 10366 10367 void stripAndCheckLen(R valueBefore, size_t minLen, size_t line = __LINE__) 10368 { 10369 value = _stripCFWS(valueBefore); 10370 if (value.length < minLen) 10371 throw new DateTimeException("date-time value too short", __FILE__, line); 10372 } 10373 stripAndCheckLen(value, "7Dec1200:00A".length); 10374 10375 static if (isArray!R && (is(ElementEncodingType!R == char) || is(ElementEncodingType!R == ubyte))) 10376 { 10377 static string sliceAsString(R str) @trusted 10378 { 10379 return cast(string) str; 10380 } 10381 } 10382 else 10383 { 10384 char[4] temp; 10385 char[] sliceAsString(R str) @trusted 10386 { 10387 size_t i = 0; 10388 foreach (c; str) 10389 temp[i++] = cast(char) c; 10390 return temp[0 .. str.length]; 10391 } 10392 } 10393 10394 // day-of-week 10395 if (isAlpha(value[0])) 10396 { 10397 auto dowStr = sliceAsString(value[0 .. 3]); 10398 switch (dowStr) 10399 { 10400 foreach (dow; EnumMembers!DayOfWeek) 10401 { 10402 enum dowC = capitalize(to!string(dow)); 10403 case dowC: 10404 goto afterDoW; 10405 } 10406 default: throw new DateTimeException(format("Invalid day-of-week: %s", dowStr)); 10407 } 10408 afterDoW: stripAndCheckLen(value[3 .. value.length], ",7Dec1200:00A".length); 10409 if (value[0] != ',') 10410 throw new DateTimeException("day-of-week missing comma"); 10411 stripAndCheckLen(value[1 .. value.length], "7Dec1200:00A".length); 10412 } 10413 10414 // day 10415 immutable digits = isDigit(value[1]) ? 2 : 1; 10416 immutable day = _convDigits!short(value[0 .. digits]); 10417 if (day == -1) 10418 throw new DateTimeException("Invalid day"); 10419 stripAndCheckLen(value[digits .. value.length], "Dec1200:00A".length); 10420 10421 // month 10422 Month month; 10423 { 10424 auto monStr = sliceAsString(value[0 .. 3]); 10425 switch (monStr) 10426 { 10427 foreach (mon; EnumMembers!Month) 10428 { 10429 enum monC = capitalize(to!string(mon)); 10430 case monC: 10431 { 10432 month = mon; 10433 goto afterMon; 10434 } 10435 } 10436 default: throw new DateTimeException(format("Invalid month: %s", monStr)); 10437 } 10438 afterMon: stripAndCheckLen(value[3 .. value.length], "1200:00A".length); 10439 } 10440 10441 // year 10442 auto found = value[2 .. value.length].find!(not!(isDigit))(); 10443 size_t yearLen = value.length - found.length; 10444 if (found.length == 0) 10445 throw new DateTimeException("Invalid year"); 10446 if (found[0] == ':') 10447 yearLen -= 2; 10448 auto year = _convDigits!short(value[0 .. yearLen]); 10449 if (year < 1900) 10450 { 10451 if (year == -1) 10452 throw new DateTimeException("Invalid year"); 10453 if (yearLen < 4) 10454 { 10455 if (yearLen == 3) 10456 year += 1900; 10457 else if (yearLen == 2) 10458 year += year < 50 ? 2000 : 1900; 10459 else 10460 throw new DateTimeException("Invalid year. Too few digits."); 10461 } 10462 else 10463 throw new DateTimeException("Invalid year. Cannot be earlier than 1900."); 10464 } 10465 stripAndCheckLen(value[yearLen .. value.length], "00:00A".length); 10466 10467 // hour 10468 immutable hour = _convDigits!short(value[0 .. 2]); 10469 stripAndCheckLen(value[2 .. value.length], ":00A".length); 10470 if (value[0] != ':') 10471 throw new DateTimeException("Invalid hour"); 10472 stripAndCheckLen(value[1 .. value.length], "00A".length); 10473 10474 // minute 10475 immutable minute = _convDigits!short(value[0 .. 2]); 10476 stripAndCheckLen(value[2 .. value.length], "A".length); 10477 10478 // second 10479 short second; 10480 if (value[0] == ':') 10481 { 10482 stripAndCheckLen(value[1 .. value.length], "00A".length); 10483 second = _convDigits!short(value[0 .. 2]); 10484 // this is just if/until SysTime is sorted out to fully support leap seconds 10485 if (second == 60) 10486 second = 59; 10487 stripAndCheckLen(value[2 .. value.length], "A".length); 10488 } 10489 10490 immutable(TimeZone) parseTZ(int sign) 10491 { 10492 if (value.length < 5) 10493 throw new DateTimeException("Invalid timezone"); 10494 immutable zoneHours = _convDigits!short(value[1 .. 3]); 10495 immutable zoneMinutes = _convDigits!short(value[3 .. 5]); 10496 if (zoneHours == -1 || zoneMinutes == -1 || zoneMinutes > 59) 10497 throw new DateTimeException("Invalid timezone"); 10498 value = value[5 .. value.length]; 10499 immutable utcOffset = (dur!"hours"(zoneHours) + dur!"minutes"(zoneMinutes)) * sign; 10500 if (utcOffset == Duration.zero) 10501 { 10502 return sign == 1 ? cast(immutable(TimeZone))UTC() 10503 : cast(immutable(TimeZone))new immutable SimpleTimeZone(Duration.zero); 10504 } 10505 return new immutable(SimpleTimeZone)(utcOffset); 10506 } 10507 10508 // zone 10509 Rebindable!(immutable TimeZone) tz; 10510 if (value[0] == '-') 10511 tz = parseTZ(-1); 10512 else if (value[0] == '+') 10513 tz = parseTZ(1); 10514 else 10515 { 10516 // obs-zone 10517 immutable tzLen = value.length - find(value, ' ', '\t', '(')[0].length; 10518 switch (sliceAsString(value[0 .. tzLen <= 4 ? tzLen : 4])) 10519 { 10520 case "UT": case "GMT": tz = UTC(); break; 10521 case "EST": tz = new immutable SimpleTimeZone(dur!"hours"(-5)); break; 10522 case "EDT": tz = new immutable SimpleTimeZone(dur!"hours"(-4)); break; 10523 case "CST": tz = new immutable SimpleTimeZone(dur!"hours"(-6)); break; 10524 case "CDT": tz = new immutable SimpleTimeZone(dur!"hours"(-5)); break; 10525 case "MST": tz = new immutable SimpleTimeZone(dur!"hours"(-7)); break; 10526 case "MDT": tz = new immutable SimpleTimeZone(dur!"hours"(-6)); break; 10527 case "PST": tz = new immutable SimpleTimeZone(dur!"hours"(-8)); break; 10528 case "PDT": tz = new immutable SimpleTimeZone(dur!"hours"(-7)); break; 10529 case "J": case "j": throw new DateTimeException("Invalid timezone"); 10530 default: 10531 { 10532 if (all!(isAlpha)(value[0 .. tzLen])) 10533 { 10534 tz = new immutable SimpleTimeZone(Duration.zero); 10535 break; 10536 } 10537 throw new DateTimeException("Invalid timezone"); 10538 } 10539 } 10540 value = value[tzLen .. value.length]; 10541 } 10542 10543 // This is kind of arbitrary. Technically, nothing but CFWS is legal past 10544 // the end of the timezone, but we don't want to be picky about that in a 10545 // function that's just parsing rather than validating. So, the idea here is 10546 // that if the next character is printable (and not part of CFWS), then it 10547 // might be part of the timezone and thus affect what the timezone was 10548 // supposed to be, so we'll throw, but otherwise, we'll just ignore it. 10549 if (!value.empty && isPrintable(value[0]) && value[0] != ' ' && value[0] != '(') 10550 throw new DateTimeException("Invalid timezone"); 10551 10552 try 10553 return SysTime(DateTime(year, month, day, hour, minute, second), tz); 10554 catch (DateTimeException dte) 10555 throw new DateTimeException("date-time format is correct, but the resulting SysTime is invalid.", dte); 10556 } 10557 10558 /// 10559 @safe unittest 10560 { 10561 import core.time : hours; 10562 import std.datetime.date : DateTime, DateTimeException; 10563 import std.datetime.timezone : SimpleTimeZone, UTC; 10564 import std.exception : assertThrown; 10565 10566 auto tz = new immutable SimpleTimeZone(hours(-8)); 10567 assert(parseRFC822DateTime("Sat, 6 Jan 1990 12:14:19 -0800") == 10568 SysTime(DateTime(1990, 1, 6, 12, 14, 19), tz)); 10569 10570 assert(parseRFC822DateTime("9 Jul 2002 13:11 +0000") == 10571 SysTime(DateTime(2002, 7, 9, 13, 11, 0), UTC())); 10572 10573 auto badStr = "29 Feb 2001 12:17:16 +0200"; 10574 assertThrown!DateTimeException(parseRFC822DateTime(badStr)); 10575 } 10576 10577 version (StdUnittest) private void testParse822(alias cr)(string str, SysTime expected, size_t line = __LINE__) 10578 { 10579 import std.format : format; 10580 auto value = cr(str); 10581 auto result = parseRFC822DateTime(value); 10582 if (result != expected) 10583 throw new AssertError(format("wrong result. expected [%s], actual[%s]", expected, result), __FILE__, line); 10584 } 10585 10586 version (StdUnittest) private void testBadParse822(alias cr)(string str, size_t line = __LINE__) 10587 { 10588 try 10589 parseRFC822DateTime(cr(str)); 10590 catch (DateTimeException) 10591 return; 10592 throw new AssertError("No DateTimeException was thrown", __FILE__, line); 10593 } 10594 10595 @system unittest 10596 { 10597 import core.time; 10598 import std.algorithm.iteration : filter, map; 10599 import std.algorithm.searching : canFind; 10600 import std.array : array; 10601 import std.ascii : letters; 10602 import std.format : format; 10603 import std.meta : AliasSeq; 10604 import std.range : chain, iota, take; 10605 import std.stdio : writefln, writeln; 10606 import std.string : representation; 10607 10608 static struct Rand3Letters 10609 { 10610 enum empty = false; 10611 @property auto front() { return _mon; } 10612 void popFront() 10613 { 10614 import std.exception : assumeUnique; 10615 import std.random : rndGen; 10616 _mon = rndGen.map!(a => letters[a % letters.length])().take(3).array().assumeUnique(); 10617 } 10618 string _mon; 10619 static auto start() { Rand3Letters retval; retval.popFront(); return retval; } 10620 } 10621 10622 static foreach (cr; AliasSeq!(function(string a){return cast(char[]) a;}, 10623 function(string a){return cast(ubyte[]) a;}, 10624 function(string a){return a;}, 10625 function(string a){return map!(b => cast(char) b)(a.representation);})) 10626 {(){ // workaround slow optimizations for large functions 10627 // https://issues.dlang.org/show_bug.cgi?id=2396 10628 scope(failure) writeln(typeof(cr).stringof); 10629 alias test = testParse822!cr; 10630 alias testBad = testBadParse822!cr; 10631 10632 immutable std1 = DateTime(2012, 12, 21, 13, 14, 15); 10633 immutable std2 = DateTime(2012, 12, 21, 13, 14, 0); 10634 immutable dst1 = DateTime(1976, 7, 4, 5, 4, 22); 10635 immutable dst2 = DateTime(1976, 7, 4, 5, 4, 0); 10636 10637 test("21 Dec 2012 13:14:15 +0000", SysTime(std1, UTC())); 10638 test("21 Dec 2012 13:14 +0000", SysTime(std2, UTC())); 10639 test("Fri, 21 Dec 2012 13:14 +0000", SysTime(std2, UTC())); 10640 test("Fri, 21 Dec 2012 13:14:15 +0000", SysTime(std1, UTC())); 10641 10642 test("04 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC())); 10643 test("04 Jul 1976 05:04 +0000", SysTime(dst2, UTC())); 10644 test("Sun, 04 Jul 1976 05:04 +0000", SysTime(dst2, UTC())); 10645 test("Sun, 04 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC())); 10646 10647 test("4 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC())); 10648 test("4 Jul 1976 05:04 +0000", SysTime(dst2, UTC())); 10649 test("Sun, 4 Jul 1976 05:04 +0000", SysTime(dst2, UTC())); 10650 test("Sun, 4 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC())); 10651 10652 auto badTZ = new immutable SimpleTimeZone(Duration.zero); 10653 test("21 Dec 2012 13:14:15 -0000", SysTime(std1, badTZ)); 10654 test("21 Dec 2012 13:14 -0000", SysTime(std2, badTZ)); 10655 test("Fri, 21 Dec 2012 13:14 -0000", SysTime(std2, badTZ)); 10656 test("Fri, 21 Dec 2012 13:14:15 -0000", SysTime(std1, badTZ)); 10657 10658 test("04 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ)); 10659 test("04 Jul 1976 05:04 -0000", SysTime(dst2, badTZ)); 10660 test("Sun, 04 Jul 1976 05:04 -0000", SysTime(dst2, badTZ)); 10661 test("Sun, 04 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ)); 10662 10663 test("4 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ)); 10664 test("4 Jul 1976 05:04 -0000", SysTime(dst2, badTZ)); 10665 test("Sun, 4 Jul 1976 05:04 -0000", SysTime(dst2, badTZ)); 10666 test("Sun, 4 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ)); 10667 10668 auto pst = new immutable SimpleTimeZone(dur!"hours"(-8)); 10669 auto pdt = new immutable SimpleTimeZone(dur!"hours"(-7)); 10670 test("21 Dec 2012 13:14:15 -0800", SysTime(std1, pst)); 10671 test("21 Dec 2012 13:14 -0800", SysTime(std2, pst)); 10672 test("Fri, 21 Dec 2012 13:14 -0800", SysTime(std2, pst)); 10673 test("Fri, 21 Dec 2012 13:14:15 -0800", SysTime(std1, pst)); 10674 10675 test("04 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt)); 10676 test("04 Jul 1976 05:04 -0700", SysTime(dst2, pdt)); 10677 test("Sun, 04 Jul 1976 05:04 -0700", SysTime(dst2, pdt)); 10678 test("Sun, 04 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt)); 10679 10680 test("4 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt)); 10681 test("4 Jul 1976 05:04 -0700", SysTime(dst2, pdt)); 10682 test("Sun, 4 Jul 1976 05:04 -0700", SysTime(dst2, pdt)); 10683 test("Sun, 4 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt)); 10684 10685 auto cet = new immutable SimpleTimeZone(dur!"hours"(1)); 10686 auto cest = new immutable SimpleTimeZone(dur!"hours"(2)); 10687 test("21 Dec 2012 13:14:15 +0100", SysTime(std1, cet)); 10688 test("21 Dec 2012 13:14 +0100", SysTime(std2, cet)); 10689 test("Fri, 21 Dec 2012 13:14 +0100", SysTime(std2, cet)); 10690 test("Fri, 21 Dec 2012 13:14:15 +0100", SysTime(std1, cet)); 10691 10692 test("04 Jul 1976 05:04:22 +0200", SysTime(dst1, cest)); 10693 test("04 Jul 1976 05:04 +0200", SysTime(dst2, cest)); 10694 test("Sun, 04 Jul 1976 05:04 +0200", SysTime(dst2, cest)); 10695 test("Sun, 04 Jul 1976 05:04:22 +0200", SysTime(dst1, cest)); 10696 10697 test("4 Jul 1976 05:04:22 +0200", SysTime(dst1, cest)); 10698 test("4 Jul 1976 05:04 +0200", SysTime(dst2, cest)); 10699 test("Sun, 4 Jul 1976 05:04 +0200", SysTime(dst2, cest)); 10700 test("Sun, 4 Jul 1976 05:04:22 +0200", SysTime(dst1, cest)); 10701 10702 // dst and std times are switched in the Southern Hemisphere which is why the 10703 // time zone names and DateTime variables don't match. 10704 auto cstStd = new immutable SimpleTimeZone(dur!"hours"(9) + dur!"minutes"(30)); 10705 auto cstDST = new immutable SimpleTimeZone(dur!"hours"(10) + dur!"minutes"(30)); 10706 test("21 Dec 2012 13:14:15 +1030", SysTime(std1, cstDST)); 10707 test("21 Dec 2012 13:14 +1030", SysTime(std2, cstDST)); 10708 test("Fri, 21 Dec 2012 13:14 +1030", SysTime(std2, cstDST)); 10709 test("Fri, 21 Dec 2012 13:14:15 +1030", SysTime(std1, cstDST)); 10710 10711 test("04 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 10712 test("04 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 10713 test("Sun, 04 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 10714 test("Sun, 04 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 10715 10716 test("4 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 10717 test("4 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 10718 test("Sun, 4 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 10719 test("Sun, 4 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 10720 10721 foreach (int i, mon; _monthNames) 10722 { 10723 test(format("17 %s 2012 00:05:02 +0000", mon), SysTime(DateTime(2012, i + 1, 17, 0, 5, 2), UTC())); 10724 test(format("17 %s 2012 00:05 +0000", mon), SysTime(DateTime(2012, i + 1, 17, 0, 5, 0), UTC())); 10725 } 10726 10727 import std.uni : toLower, toUpper; 10728 foreach (mon; chain(_monthNames[].map!(a => toLower(a))(), 10729 _monthNames[].map!(a => toUpper(a))(), 10730 ["Jam", "Jen", "Fec", "Fdb", "Mas", "Mbr", "Aps", "Aqr", "Mai", "Miy", 10731 "Jum", "Jbn", "Jup", "Jal", "Aur", "Apg", "Sem", "Sap", "Ocm", "Odt", 10732 "Nom", "Nav", "Dem", "Dac"], 10733 Rand3Letters.start().filter!(a => !_monthNames[].canFind(a)).take(20))) 10734 { 10735 scope(failure) writefln("Month: %s", mon); 10736 testBad(format("17 %s 2012 00:05:02 +0000", mon)); 10737 testBad(format("17 %s 2012 00:05 +0000", mon)); 10738 } 10739 10740 immutable string[7] daysOfWeekNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; 10741 10742 { 10743 auto start = SysTime(DateTime(2012, 11, 11, 9, 42, 0), UTC()); 10744 int day = 11; 10745 10746 foreach (int i, dow; daysOfWeekNames) 10747 { 10748 auto curr = start + dur!"days"(i); 10749 test(format("%s, %s Nov 2012 09:42:00 +0000", dow, day), curr); 10750 test(format("%s, %s Nov 2012 09:42 +0000", dow, day++), curr); 10751 10752 // Whether the day of the week matches the date is ignored. 10753 test(format("%s, 11 Nov 2012 09:42:00 +0000", dow), start); 10754 test(format("%s, 11 Nov 2012 09:42 +0000", dow), start); 10755 } 10756 } 10757 10758 foreach (dow; chain(daysOfWeekNames[].map!(a => toLower(a))(), 10759 daysOfWeekNames[].map!(a => toUpper(a))(), 10760 ["Sum", "Spn", "Mom", "Man", "Tuf", "Tae", "Wem", "Wdd", "The", "Tur", 10761 "Fro", "Fai", "San", "Sut"], 10762 Rand3Letters.start().filter!(a => !daysOfWeekNames[].canFind(a)).take(20))) 10763 { 10764 scope(failure) writefln("Day of Week: %s", dow); 10765 testBad(format("%s, 11 Nov 2012 09:42:00 +0000", dow)); 10766 testBad(format("%s, 11 Nov 2012 09:42 +0000", dow)); 10767 } 10768 10769 testBad("31 Dec 1899 23:59:59 +0000"); 10770 test("01 Jan 1900 00:00:00 +0000", SysTime(Date(1900, 1, 1), UTC())); 10771 test("01 Jan 1900 00:00:00 -0000", SysTime(Date(1900, 1, 1), 10772 new immutable SimpleTimeZone(Duration.zero))); 10773 test("01 Jan 1900 00:00:00 -0700", SysTime(Date(1900, 1, 1), 10774 new immutable SimpleTimeZone(dur!"hours"(-7)))); 10775 10776 { 10777 auto st1 = SysTime(Date(1900, 1, 1), UTC()); 10778 auto st2 = SysTime(Date(1900, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-11))); 10779 foreach (i; 1900 .. 2102) 10780 { 10781 test(format("1 Jan %05d 00:00 +0000", i), st1); 10782 test(format("1 Jan %05d 00:00 -1100", i), st2); 10783 st1.add!"years"(1); 10784 st2.add!"years"(1); 10785 } 10786 st1.year = 9998; 10787 st2.year = 9998; 10788 foreach (i; 9998 .. 11_002) 10789 { 10790 test(format("1 Jan %05d 00:00 +0000", i), st1); 10791 test(format("1 Jan %05d 00:00 -1100", i), st2); 10792 st1.add!"years"(1); 10793 st2.add!"years"(1); 10794 } 10795 } 10796 10797 testBad("12 Feb 1907 23:17:09 0000"); 10798 testBad("12 Feb 1907 23:17:09 +000"); 10799 testBad("12 Feb 1907 23:17:09 -000"); 10800 testBad("12 Feb 1907 23:17:09 +00000"); 10801 testBad("12 Feb 1907 23:17:09 -00000"); 10802 testBad("12 Feb 1907 23:17:09 +A"); 10803 testBad("12 Feb 1907 23:17:09 +PST"); 10804 testBad("12 Feb 1907 23:17:09 -A"); 10805 testBad("12 Feb 1907 23:17:09 -PST"); 10806 10807 // test trailing stuff that gets ignored 10808 { 10809 foreach (c; chain(iota(0, 33), ['('], iota(127, ubyte.max + 1))) 10810 { 10811 scope(failure) writefln("c: %d", c); 10812 test(format("21 Dec 2012 13:14:15 +0000%c", cast(char) c), SysTime(std1, UTC())); 10813 test(format("21 Dec 2012 13:14:15 +0000%c ", cast(char) c), SysTime(std1, UTC())); 10814 test(format("21 Dec 2012 13:14:15 +0000%chello", cast(char) c), SysTime(std1, UTC())); 10815 } 10816 } 10817 10818 // test trailing stuff that doesn't get ignored 10819 { 10820 foreach (c; chain(iota(33, '('), iota('(' + 1, 127))) 10821 { 10822 scope(failure) writefln("c: %d", c); 10823 testBad(format("21 Dec 2012 13:14:15 +0000%c", cast(char) c)); 10824 testBad(format("21 Dec 2012 13:14:15 +0000%c ", cast(char) c)); 10825 testBad(format("21 Dec 2012 13:14:15 +0000%chello", cast(char) c)); 10826 } 10827 } 10828 10829 testBad("32 Jan 2012 12:13:14 -0800"); 10830 testBad("31 Jan 2012 24:13:14 -0800"); 10831 testBad("31 Jan 2012 12:60:14 -0800"); 10832 testBad("31 Jan 2012 12:13:61 -0800"); 10833 testBad("31 Jan 2012 12:13:14 -0860"); 10834 test("31 Jan 2012 12:13:14 -0859", 10835 SysTime(DateTime(2012, 1, 31, 12, 13, 14), 10836 new immutable SimpleTimeZone(dur!"hours"(-8) + dur!"minutes"(-59)))); 10837 10838 // leap-seconds 10839 test("21 Dec 2012 15:59:60 -0800", SysTime(DateTime(2012, 12, 21, 15, 59, 59), pst)); 10840 10841 // FWS 10842 test("Sun,4 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 10843 test("Sun,4 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 10844 test("Sun,4 Jul 1976 05:04 +0930 (foo)", SysTime(dst2, cstStd)); 10845 test("Sun,4 Jul 1976 05:04:22 +0930 (foo)", SysTime(dst1, cstStd)); 10846 test("Sun,4 \r\n Jul \r\n 1976 \r\n 05:04 \r\n +0930 \r\n (foo)", SysTime(dst2, cstStd)); 10847 test("Sun,4 \r\n Jul \r\n 1976 \r\n 05:04:22 \r\n +0930 \r\n (foo)", SysTime(dst1, cstStd)); 10848 10849 auto str = "01 Jan 2012 12:13:14 -0800 "; 10850 test(str, SysTime(DateTime(2012, 1, 1, 12, 13, 14), new immutable SimpleTimeZone(hours(-8)))); 10851 foreach (i; 0 .. str.length) 10852 { 10853 auto currStr = str.dup; 10854 currStr[i] = 'x'; 10855 scope(failure) writefln("failed: %s", currStr); 10856 testBad(cast(string) currStr); 10857 } 10858 foreach (i; 2 .. str.length) 10859 { 10860 auto currStr = str[0 .. $ - i]; 10861 scope(failure) writefln("failed: %s", currStr); 10862 testBad(cast(string) currStr); 10863 testBad((cast(string) currStr) ~ " "); 10864 } 10865 }();} 10866 10867 static void testScope(scope ref string str) @safe 10868 { 10869 auto result = parseRFC822DateTime(str); 10870 } 10871 } 10872 10873 // Obsolete Format per section 4.3 of RFC 5322. 10874 @system unittest 10875 { 10876 import std.algorithm.iteration : filter, map; 10877 import std.ascii : letters; 10878 import std.exception : collectExceptionMsg; 10879 import std.format : format; 10880 import std.meta : AliasSeq; 10881 import std.range : chain, iota; 10882 import std.stdio : writefln, writeln; 10883 import std.string : representation; 10884 10885 auto std1 = SysTime(DateTime(2012, 12, 21, 13, 14, 15), UTC()); 10886 auto std2 = SysTime(DateTime(2012, 12, 21, 13, 14, 0), UTC()); 10887 auto std3 = SysTime(DateTime(1912, 12, 21, 13, 14, 15), UTC()); 10888 auto std4 = SysTime(DateTime(1912, 12, 21, 13, 14, 0), UTC()); 10889 auto dst1 = SysTime(DateTime(1976, 7, 4, 5, 4, 22), UTC()); 10890 auto dst2 = SysTime(DateTime(1976, 7, 4, 5, 4, 0), UTC()); 10891 auto tooLate1 = SysTime(Date(10_000, 1, 1), UTC()); 10892 auto tooLate2 = SysTime(DateTime(12_007, 12, 31, 12, 22, 19), UTC()); 10893 10894 static foreach (cr; AliasSeq!(function(string a){return cast(char[]) a;}, 10895 function(string a){return cast(ubyte[]) a;}, 10896 function(string a){return a;}, 10897 function(string a){return map!(b => cast(char) b)(a.representation);})) 10898 {(){ // workaround slow optimizations for large functions 10899 // https://issues.dlang.org/show_bug.cgi?id=2396 10900 scope(failure) writeln(typeof(cr).stringof); 10901 alias test = testParse822!cr; 10902 { 10903 auto list = ["", " ", " \r\n\t", "\t\r\n (hello world( frien(dog)) silly \r\n ) \t\t \r\n ()", 10904 " \n ", "\t\n\t", " \n\t (foo) \n (bar) \r\n (baz) \n "]; 10905 10906 foreach (i, cfws; list) 10907 { 10908 scope(failure) writefln("i: %s", i); 10909 10910 test(format("%1$s21%1$sDec%1$s2012%1$s13:14:15%1$s+0000%1$s", cfws), std1); 10911 test(format("%1$s21%1$sDec%1$s2012%1$s13:14%1$s+0000%1$s", cfws), std2); 10912 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s2012%1$s13:14%1$s+0000%1$s", cfws), std2); 10913 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s2012%1$s13:14:15%1$s+0000%1$s", cfws), std1); 10914 10915 test(format("%1$s04%1$sJul%1$s1976%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10916 test(format("%1$s04%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2); 10917 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2); 10918 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s1976%1$s05:04:22 +0000%1$s", cfws), dst1); 10919 10920 test(format("%1$s4%1$sJul%1$s1976%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10921 test(format("%1$s4%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2); 10922 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2); 10923 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s1976%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10924 10925 test(format("%1$s21%1$sDec%1$s12%1$s13:14:15%1$s+0000%1$s", cfws), std1); 10926 test(format("%1$s21%1$sDec%1$s12%1$s13:14%1$s+0000%1$s", cfws), std2); 10927 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s12%1$s13:14%1$s+0000%1$s", cfws), std2); 10928 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s12%1$s13:14:15%1$s+0000%1$s", cfws), std1); 10929 10930 test(format("%1$s04%1$sJul%1$s76%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10931 test(format("%1$s04%1$sJul%1$s76%1$s05:04%1$s+0000%1$s", cfws), dst2); 10932 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s76%1$s05:04%1$s+0000%1$s", cfws), dst2); 10933 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s76%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10934 10935 test(format("%1$s4%1$sJul%1$s76 05:04:22%1$s+0000%1$s", cfws), dst1); 10936 test(format("%1$s4%1$sJul%1$s76 05:04%1$s+0000%1$s", cfws), dst2); 10937 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s76%1$s05:04%1$s+0000%1$s", cfws), dst2); 10938 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s76%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10939 10940 test(format("%1$s21%1$sDec%1$s012%1$s13:14:15%1$s+0000%1$s", cfws), std3); 10941 test(format("%1$s21%1$sDec%1$s012%1$s13:14%1$s+0000%1$s", cfws), std4); 10942 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s012%1$s13:14%1$s+0000%1$s", cfws), std4); 10943 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s012%1$s13:14:15%1$s+0000%1$s", cfws), std3); 10944 10945 test(format("%1$s04%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10946 test(format("%1$s04%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2); 10947 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2); 10948 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10949 10950 test(format("%1$s4%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10951 test(format("%1$s4%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2); 10952 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2); 10953 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10954 10955 test(format("%1$s1%1$sJan%1$s10000%1$s00:00:00%1$s+0000%1$s", cfws), tooLate1); 10956 test(format("%1$s31%1$sDec%1$s12007%1$s12:22:19%1$s+0000%1$s", cfws), tooLate2); 10957 test(format("%1$sSat%1$s,%1$s1%1$sJan%1$s10000%1$s00:00:00%1$s+0000%1$s", cfws), tooLate1); 10958 test(format("%1$sSun%1$s,%1$s31%1$sDec%1$s12007%1$s12:22:19%1$s+0000%1$s", cfws), tooLate2); 10959 } 10960 } 10961 10962 // test years of 1, 2, and 3 digits. 10963 { 10964 auto st1 = SysTime(Date(2000, 1, 1), UTC()); 10965 auto st2 = SysTime(Date(2000, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-12))); 10966 foreach (i; 0 .. 50) 10967 { 10968 test(format("1 Jan %02d 00:00 GMT", i), st1); 10969 test(format("1 Jan %02d 00:00 -1200", i), st2); 10970 st1.add!"years"(1); 10971 st2.add!"years"(1); 10972 } 10973 } 10974 10975 { 10976 auto st1 = SysTime(Date(1950, 1, 1), UTC()); 10977 auto st2 = SysTime(Date(1950, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-12))); 10978 foreach (i; 50 .. 100) 10979 { 10980 test(format("1 Jan %02d 00:00 GMT", i), st1); 10981 test(format("1 Jan %02d 00:00 -1200", i), st2); 10982 st1.add!"years"(1); 10983 st2.add!"years"(1); 10984 } 10985 } 10986 10987 { 10988 auto st1 = SysTime(Date(1900, 1, 1), UTC()); 10989 auto st2 = SysTime(Date(1900, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-11))); 10990 foreach (i; 0 .. 1000) 10991 { 10992 test(format("1 Jan %03d 00:00 GMT", i), st1); 10993 test(format("1 Jan %03d 00:00 -1100", i), st2); 10994 st1.add!"years"(1); 10995 st2.add!"years"(1); 10996 } 10997 } 10998 10999 foreach (i; 0 .. 10) 11000 { 11001 auto str1 = cr(format("1 Jan %d 00:00 GMT", i)); 11002 auto str2 = cr(format("1 Jan %d 00:00 -1200", i)); 11003 assertThrown!DateTimeException(parseRFC822DateTime(str1)); 11004 assertThrown!DateTimeException(parseRFC822DateTime(str1)); 11005 } 11006 11007 // test time zones 11008 { 11009 auto dt = DateTime(1982, 5, 3, 12, 22, 4); 11010 test("Wed, 03 May 1982 12:22:04 UT", SysTime(dt, UTC())); 11011 test("Wed, 03 May 1982 12:22:04 GMT", SysTime(dt, UTC())); 11012 test("Wed, 03 May 1982 12:22:04 EST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-5)))); 11013 test("Wed, 03 May 1982 12:22:04 EDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-4)))); 11014 test("Wed, 03 May 1982 12:22:04 CST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-6)))); 11015 test("Wed, 03 May 1982 12:22:04 CDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-5)))); 11016 test("Wed, 03 May 1982 12:22:04 MST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-7)))); 11017 test("Wed, 03 May 1982 12:22:04 MDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-6)))); 11018 test("Wed, 03 May 1982 12:22:04 PST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-8)))); 11019 test("Wed, 03 May 1982 12:22:04 PDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-7)))); 11020 11021 auto badTZ = new immutable SimpleTimeZone(Duration.zero); 11022 foreach (dchar c; filter!(a => a != 'j' && a != 'J')(letters)) 11023 { 11024 scope(failure) writefln("c: %s", c); 11025 test(format("Wed, 03 May 1982 12:22:04 %s", c), SysTime(dt, badTZ)); 11026 test(format("Wed, 03 May 1982 12:22:04%s", c), SysTime(dt, badTZ)); 11027 } 11028 11029 foreach (dchar c; ['j', 'J']) 11030 { 11031 scope(failure) writefln("c: %s", c); 11032 assertThrown!DateTimeException(parseRFC822DateTime(cr(format("Wed, 03 May 1982 12:22:04 %s", c)))); 11033 assertThrown!DateTimeException(parseRFC822DateTime(cr(format("Wed, 03 May 1982 12:22:04%s", c)))); 11034 } 11035 11036 foreach (string s; ["AAA", "GQW", "DDT", "PDA", "GT", "GM"]) 11037 { 11038 scope(failure) writefln("s: %s", s); 11039 test(format("Wed, 03 May 1982 12:22:04 %s", s), SysTime(dt, badTZ)); 11040 } 11041 11042 // test trailing stuff that gets ignored 11043 { 11044 foreach (c; chain(iota(0, 33), ['('], iota(127, ubyte.max + 1))) 11045 { 11046 scope(failure) writefln("c: %d", c); 11047 test(format("21Dec1213:14:15+0000%c", cast(char) c), std1); 11048 test(format("21Dec1213:14:15+0000%c ", cast(char) c), std1); 11049 test(format("21Dec1213:14:15+0000%chello", cast(char) c), std1); 11050 } 11051 } 11052 11053 // test trailing stuff that doesn't get ignored 11054 { 11055 foreach (c; chain(iota(33, '('), iota('(' + 1, 127))) 11056 { 11057 scope(failure) writefln("c: %d", c); 11058 assertThrown!DateTimeException( 11059 parseRFC822DateTime(cr(format("21Dec1213:14:15+0000%c", cast(char) c)))); 11060 assertThrown!DateTimeException( 11061 parseRFC822DateTime(cr(format("21Dec1213:14:15+0000%c ", cast(char) c)))); 11062 assertThrown!DateTimeException( 11063 parseRFC822DateTime(cr(format("21Dec1213:14:15+0000%chello", cast(char) c)))); 11064 } 11065 } 11066 } 11067 11068 // test that the checks for minimum length work correctly and avoid 11069 // any RangeErrors. 11070 test("7Dec1200:00A", SysTime(DateTime(2012, 12, 7, 0, 0, 0), 11071 new immutable SimpleTimeZone(Duration.zero))); 11072 test("Fri,7Dec1200:00A", SysTime(DateTime(2012, 12, 7, 0, 0, 0), 11073 new immutable SimpleTimeZone(Duration.zero))); 11074 test("7Dec1200:00:00A", SysTime(DateTime(2012, 12, 7, 0, 0, 0), 11075 new immutable SimpleTimeZone(Duration.zero))); 11076 test("Fri,7Dec1200:00:00A", SysTime(DateTime(2012, 12, 7, 0, 0, 0), 11077 new immutable SimpleTimeZone(Duration.zero))); 11078 11079 auto tooShortMsg = collectExceptionMsg!DateTimeException(parseRFC822DateTime("")); 11080 foreach (str; ["Fri,7Dec1200:00:00", "7Dec1200:00:00"]) 11081 { 11082 foreach (i; 0 .. str.length) 11083 { 11084 auto value = str[0 .. $ - i]; 11085 scope(failure) writeln(value); 11086 assert(collectExceptionMsg!DateTimeException(parseRFC822DateTime(value)) == tooShortMsg); 11087 } 11088 } 11089 }();} 11090 } 11091 11092 11093 private: 11094 11095 /+ 11096 Returns the given hnsecs as an ISO string of fractional seconds. 11097 +/ 11098 string fracSecsToISOString(int hnsecs, int prec = -1) @safe pure nothrow 11099 { 11100 import std.array : appender; 11101 auto w = appender!string(); 11102 try 11103 fracSecsToISOString(w, hnsecs, prec); 11104 catch (Exception e) 11105 assert(0, "fracSecsToISOString() threw."); 11106 return w.data; 11107 } 11108 11109 void fracSecsToISOString(W)(ref W writer, int hnsecs, int prec = -1) 11110 { 11111 import std.conv : toChars; 11112 import std.range : padLeft; 11113 11114 assert(hnsecs >= 0); 11115 11116 if (prec == 0) 11117 return; 11118 11119 if (hnsecs == 0) 11120 return; 11121 11122 put(writer, '.'); 11123 auto chars = hnsecs.toChars.padLeft('0', 7); 11124 11125 if (prec == -1) 11126 { 11127 while (chars.back == '0') 11128 chars.popBack(); 11129 put(writer, chars); 11130 } 11131 else 11132 put(writer, chars[0 .. prec]); 11133 } 11134 11135 @safe unittest 11136 { 11137 assert(fracSecsToISOString(0) == ""); 11138 assert(fracSecsToISOString(1) == ".0000001"); 11139 assert(fracSecsToISOString(10) == ".000001"); 11140 assert(fracSecsToISOString(100) == ".00001"); 11141 assert(fracSecsToISOString(1000) == ".0001"); 11142 assert(fracSecsToISOString(10_000) == ".001"); 11143 assert(fracSecsToISOString(100_000) == ".01"); 11144 assert(fracSecsToISOString(1_000_000) == ".1"); 11145 assert(fracSecsToISOString(1_000_001) == ".1000001"); 11146 assert(fracSecsToISOString(1_001_001) == ".1001001"); 11147 assert(fracSecsToISOString(1_071_601) == ".1071601"); 11148 assert(fracSecsToISOString(1_271_641) == ".1271641"); 11149 assert(fracSecsToISOString(9_999_999) == ".9999999"); 11150 assert(fracSecsToISOString(9_999_990) == ".999999"); 11151 assert(fracSecsToISOString(9_999_900) == ".99999"); 11152 assert(fracSecsToISOString(9_999_000) == ".9999"); 11153 assert(fracSecsToISOString(9_990_000) == ".999"); 11154 assert(fracSecsToISOString(9_900_000) == ".99"); 11155 assert(fracSecsToISOString(9_000_000) == ".9"); 11156 assert(fracSecsToISOString(999) == ".0000999"); 11157 assert(fracSecsToISOString(9990) == ".000999"); 11158 assert(fracSecsToISOString(99_900) == ".00999"); 11159 assert(fracSecsToISOString(999_000) == ".0999"); 11160 } 11161 11162 11163 /+ 11164 Returns a Duration corresponding to to the given ISO string of 11165 fractional seconds. 11166 +/ 11167 static Duration fracSecsFromISOString(S)(scope const S isoString) @safe pure 11168 if (isSomeString!S) 11169 { 11170 import std.algorithm.searching : all; 11171 import std.ascii : isDigit; 11172 import std.conv : to; 11173 import std.string : representation; 11174 11175 if (isoString.empty) 11176 return Duration.zero; 11177 11178 auto str = isoString.representation; 11179 11180 enforce(str[0] == '.', new DateTimeException("Invalid ISO String")); 11181 str.popFront(); 11182 11183 enforce(!str.empty && all!isDigit(str), new DateTimeException("Invalid ISO String")); 11184 11185 dchar[7] fullISOString = void; 11186 foreach (i, ref dchar c; fullISOString) 11187 { 11188 if (i < str.length) 11189 c = str[i]; 11190 else 11191 c = '0'; 11192 } 11193 11194 return hnsecs(to!int(fullISOString[])); 11195 } 11196 11197 @safe unittest 11198 { 11199 import core.time; 11200 static void testFSInvalid(string isoString) 11201 { 11202 fracSecsFromISOString(isoString); 11203 } 11204 11205 assertThrown!DateTimeException(testFSInvalid(".")); 11206 assertThrown!DateTimeException(testFSInvalid("0.")); 11207 assertThrown!DateTimeException(testFSInvalid("0")); 11208 assertThrown!DateTimeException(testFSInvalid("0000000")); 11209 assertThrown!DateTimeException(testFSInvalid("T")); 11210 assertThrown!DateTimeException(testFSInvalid("T.")); 11211 assertThrown!DateTimeException(testFSInvalid(".T")); 11212 assertThrown!DateTimeException(testFSInvalid(".00000Q0")); 11213 assertThrown!DateTimeException(testFSInvalid(".000000Q")); 11214 assertThrown!DateTimeException(testFSInvalid(".0000000Q")); 11215 assertThrown!DateTimeException(testFSInvalid(".0000000000Q")); 11216 11217 assert(fracSecsFromISOString("") == Duration.zero); 11218 assert(fracSecsFromISOString(".0000001") == hnsecs(1)); 11219 assert(fracSecsFromISOString(".000001") == hnsecs(10)); 11220 assert(fracSecsFromISOString(".00001") == hnsecs(100)); 11221 assert(fracSecsFromISOString(".0001") == hnsecs(1000)); 11222 assert(fracSecsFromISOString(".001") == hnsecs(10_000)); 11223 assert(fracSecsFromISOString(".01") == hnsecs(100_000)); 11224 assert(fracSecsFromISOString(".1") == hnsecs(1_000_000)); 11225 assert(fracSecsFromISOString(".1000001") == hnsecs(1_000_001)); 11226 assert(fracSecsFromISOString(".1001001") == hnsecs(1_001_001)); 11227 assert(fracSecsFromISOString(".1071601") == hnsecs(1_071_601)); 11228 assert(fracSecsFromISOString(".1271641") == hnsecs(1_271_641)); 11229 assert(fracSecsFromISOString(".9999999") == hnsecs(9_999_999)); 11230 assert(fracSecsFromISOString(".9999990") == hnsecs(9_999_990)); 11231 assert(fracSecsFromISOString(".999999") == hnsecs(9_999_990)); 11232 assert(fracSecsFromISOString(".9999900") == hnsecs(9_999_900)); 11233 assert(fracSecsFromISOString(".99999") == hnsecs(9_999_900)); 11234 assert(fracSecsFromISOString(".9999000") == hnsecs(9_999_000)); 11235 assert(fracSecsFromISOString(".9999") == hnsecs(9_999_000)); 11236 assert(fracSecsFromISOString(".9990000") == hnsecs(9_990_000)); 11237 assert(fracSecsFromISOString(".999") == hnsecs(9_990_000)); 11238 assert(fracSecsFromISOString(".9900000") == hnsecs(9_900_000)); 11239 assert(fracSecsFromISOString(".9900") == hnsecs(9_900_000)); 11240 assert(fracSecsFromISOString(".99") == hnsecs(9_900_000)); 11241 assert(fracSecsFromISOString(".9000000") == hnsecs(9_000_000)); 11242 assert(fracSecsFromISOString(".9") == hnsecs(9_000_000)); 11243 assert(fracSecsFromISOString(".0000999") == hnsecs(999)); 11244 assert(fracSecsFromISOString(".0009990") == hnsecs(9990)); 11245 assert(fracSecsFromISOString(".000999") == hnsecs(9990)); 11246 assert(fracSecsFromISOString(".0099900") == hnsecs(99_900)); 11247 assert(fracSecsFromISOString(".00999") == hnsecs(99_900)); 11248 assert(fracSecsFromISOString(".0999000") == hnsecs(999_000)); 11249 assert(fracSecsFromISOString(".0999") == hnsecs(999_000)); 11250 assert(fracSecsFromISOString(".00000000") == Duration.zero); 11251 assert(fracSecsFromISOString(".00000001") == Duration.zero); 11252 assert(fracSecsFromISOString(".00000009") == Duration.zero); 11253 assert(fracSecsFromISOString(".1234567890") == hnsecs(1_234_567)); 11254 assert(fracSecsFromISOString(".12345678901234567890") == hnsecs(1_234_567)); 11255 } 11256 11257 11258 /+ 11259 This function is used to split out the units without getting the remaining 11260 hnsecs. 11261 11262 Params: 11263 units = The units to split out. 11264 hnsecs = The current total hnsecs. 11265 11266 Returns: 11267 The split out value. 11268 +/ 11269 long getUnitsFromHNSecs(string units)(long hnsecs) @safe pure nothrow 11270 if (validTimeUnits(units) && 11271 CmpTimeUnits!(units, "months") < 0) 11272 { 11273 return convert!("hnsecs", units)(hnsecs); 11274 } 11275 11276 @safe unittest 11277 { 11278 auto hnsecs = 2595000000007L; 11279 immutable days = getUnitsFromHNSecs!"days"(hnsecs); 11280 assert(days == 3); 11281 assert(hnsecs == 2595000000007L); 11282 } 11283 11284 11285 /+ 11286 This function is used to split out the units without getting the units but 11287 just the remaining hnsecs. 11288 11289 Params: 11290 units = The units to split out. 11291 hnsecs = The current total hnsecs. 11292 11293 Returns: 11294 The remaining hnsecs. 11295 +/ 11296 long removeUnitsFromHNSecs(string units)(long hnsecs) @safe pure nothrow 11297 if (validTimeUnits(units) && 11298 CmpTimeUnits!(units, "months") < 0) 11299 { 11300 immutable value = convert!("hnsecs", units)(hnsecs); 11301 return hnsecs - convert!(units, "hnsecs")(value); 11302 } 11303 11304 @safe unittest 11305 { 11306 auto hnsecs = 2595000000007L; 11307 auto returned = removeUnitsFromHNSecs!"days"(hnsecs); 11308 assert(returned == 3000000007); 11309 assert(hnsecs == 2595000000007L); 11310 } 11311 11312 11313 /+ 11314 Strips what RFC 5322, section 3.2.2 refers to as CFWS from the left-hand 11315 side of the given range (it strips comments delimited by $(D '(') and 11316 `'`') as well as folding whitespace). 11317 11318 It is assumed that the given range contains the value of a header field and 11319 no terminating CRLF for the line (though the CRLF for folding whitespace is 11320 of course expected and stripped) and thus that the only case of CR or LF is 11321 in folding whitespace. 11322 11323 If a comment does not terminate correctly (e.g. mismatched parens) or if the 11324 the FWS is malformed, then the range will be empty when stripCWFS is done. 11325 However, only minimal validation of the content is done (e.g. quoted pairs 11326 within a comment aren't validated beyond \$LPAREN or \$RPAREN, because 11327 they're inside a comment, and thus their value doesn't matter anyway). It's 11328 only when the content does not conform to the grammar rules for FWS and thus 11329 literally cannot be parsed that content is considered invalid, and an empty 11330 range is returned. 11331 11332 Note that _stripCFWS is eager, not lazy. It does not create a new range. 11333 Rather, it pops off the CFWS from the range and returns it. 11334 +/ 11335 R _stripCFWS(R)(R range) 11336 if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && 11337 (is(immutable ElementType!R == immutable char) || is(immutable ElementType!R == immutable ubyte))) 11338 { 11339 immutable e = range.length; 11340 outer: for (size_t i = 0; i < e; ) 11341 { 11342 switch (range[i]) 11343 { 11344 case ' ': case '\t': 11345 { 11346 ++i; 11347 break; 11348 } 11349 case '\r': 11350 { 11351 if (i + 2 < e && range[i + 1] == '\n' && (range[i + 2] == ' ' || range[i + 2] == '\t')) 11352 { 11353 i += 3; 11354 break; 11355 } 11356 break outer; 11357 } 11358 case '\n': 11359 { 11360 if (i + 1 < e && (range[i + 1] == ' ' || range[i + 1] == '\t')) 11361 { 11362 i += 2; 11363 break; 11364 } 11365 break outer; 11366 } 11367 case '(': 11368 { 11369 ++i; 11370 size_t commentLevel = 1; 11371 while (i < e) 11372 { 11373 if (range[i] == '(') 11374 ++commentLevel; 11375 else if (range[i] == ')') 11376 { 11377 ++i; 11378 if (--commentLevel == 0) 11379 continue outer; 11380 continue; 11381 } 11382 else if (range[i] == '\\') 11383 { 11384 if (++i == e) 11385 break outer; 11386 } 11387 ++i; 11388 } 11389 break outer; 11390 } 11391 default: return range[i .. e]; 11392 } 11393 } 11394 return range[e .. e]; 11395 } 11396 11397 @system unittest 11398 { 11399 import std.algorithm.comparison : equal; 11400 import std.algorithm.iteration : map; 11401 import std.meta : AliasSeq; 11402 import std.stdio : writeln; 11403 import std.string : representation; 11404 11405 static foreach (cr; AliasSeq!(function(string a){return cast(ubyte[]) a;}, 11406 function(string a){return map!(b => cast(char) b)(a.representation);})) 11407 { 11408 scope(failure) writeln(typeof(cr).stringof); 11409 11410 assert(_stripCFWS(cr("")).empty); 11411 assert(_stripCFWS(cr("\r")).empty); 11412 assert(_stripCFWS(cr("\r\n")).empty); 11413 assert(_stripCFWS(cr("\r\n ")).empty); 11414 assert(_stripCFWS(cr(" \t\r\n")).empty); 11415 assert(equal(_stripCFWS(cr(" \t\r\n hello")), cr("hello"))); 11416 assert(_stripCFWS(cr(" \t\r\nhello")).empty); 11417 assert(_stripCFWS(cr(" \t\r\n\v")).empty); 11418 assert(equal(_stripCFWS(cr("\v \t\r\n\v")), cr("\v \t\r\n\v"))); 11419 assert(_stripCFWS(cr("()")).empty); 11420 assert(_stripCFWS(cr("(hello world)")).empty); 11421 assert(_stripCFWS(cr("(hello world)(hello world)")).empty); 11422 assert(_stripCFWS(cr("(hello world\r\n foo\r where's\nwaldo)")).empty); 11423 assert(_stripCFWS(cr(" \t (hello \tworld\r\n foo\r where's\nwaldo)\t\t ")).empty); 11424 assert(_stripCFWS(cr(" ")).empty); 11425 assert(_stripCFWS(cr("\t\t\t")).empty); 11426 assert(_stripCFWS(cr("\t \r\n\r \n")).empty); 11427 assert(_stripCFWS(cr("(hello world) (can't find waldo) (he's lost)")).empty); 11428 assert(_stripCFWS(cr("(hello\\) world) (can't \\(find waldo) (he's \\(\\)lost)")).empty); 11429 assert(_stripCFWS(cr("(((((")).empty); 11430 assert(_stripCFWS(cr("(((()))")).empty); 11431 assert(_stripCFWS(cr("(((())))")).empty); 11432 assert(equal(_stripCFWS(cr("(((()))))")), cr(")"))); 11433 assert(equal(_stripCFWS(cr(")))))")), cr(")))))"))); 11434 assert(equal(_stripCFWS(cr("()))))")), cr("))))"))); 11435 assert(equal(_stripCFWS(cr(" hello hello ")), cr("hello hello "))); 11436 assert(equal(_stripCFWS(cr("\thello (world)")), cr("hello (world)"))); 11437 assert(equal(_stripCFWS(cr(" \r\n \\((\\)) foo")), cr("\\((\\)) foo"))); 11438 assert(equal(_stripCFWS(cr(" \r\n (\\((\\))) foo")), cr("foo"))); 11439 assert(equal(_stripCFWS(cr(" \r\n (\\(())) foo")), cr(") foo"))); 11440 assert(_stripCFWS(cr(" \r\n (((\\))) foo")).empty); 11441 11442 assert(_stripCFWS(cr("(hello)(hello)")).empty); 11443 assert(_stripCFWS(cr(" \r\n (hello)\r\n (hello)")).empty); 11444 assert(_stripCFWS(cr(" \r\n (hello) \r\n (hello) \r\n ")).empty); 11445 assert(_stripCFWS(cr("\t\t\t\t(hello)\t\t\t\t(hello)\t\t\t\t")).empty); 11446 assert(equal(_stripCFWS(cr(" \r\n (hello)\r\n (hello) \r\n hello")), cr("hello"))); 11447 assert(equal(_stripCFWS(cr(" \r\n (hello) \r\n (hello) \r\n hello")), cr("hello"))); 11448 assert(equal(_stripCFWS(cr("\t\r\n\t(hello)\r\n\t(hello)\t\r\n hello")), cr("hello"))); 11449 assert(equal(_stripCFWS(cr("\t\r\n\t(hello)\t\r\n\t(hello)\t\r\n hello")), cr("hello"))); 11450 assert(equal(_stripCFWS(cr(" \r\n (hello) \r\n \r\n (hello) \r\n hello")), cr("hello"))); 11451 assert(equal(_stripCFWS(cr(" \r\n (hello) \r\n (hello) \r\n \r\n hello")), cr("hello"))); 11452 assert(equal(_stripCFWS(cr(" \r\n \r\n (hello)\t\r\n (hello) \r\n hello")), cr("hello"))); 11453 assert(equal(_stripCFWS(cr(" \r\n\t\r\n\t(hello)\t\r\n (hello) \r\n hello")), cr("hello"))); 11454 11455 assert(equal(_stripCFWS(cr(" (\r\n ( \r\n ) \r\n ) foo")), cr("foo"))); 11456 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n ) foo")), cr("foo"))); 11457 assert(equal(_stripCFWS(cr(" (\t\r\n ( \r\n ) \r\n ) foo")), cr("foo"))); 11458 assert(equal(_stripCFWS(cr(" (\r\n\t( \r\n ) \r\n ) foo")), cr("foo"))); 11459 assert(equal(_stripCFWS(cr(" ( \r\n (\t\r\n ) \r\n ) foo")), cr("foo"))); 11460 assert(equal(_stripCFWS(cr(" ( \r\n (\r\n ) \r\n ) foo")), cr("foo"))); 11461 assert(equal(_stripCFWS(cr(" ( \r\n (\r\n\t) \r\n ) foo")), cr("foo"))); 11462 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n) \r\n ) foo")), cr("foo"))); 11463 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n )\t\r\n ) foo")), cr("foo"))); 11464 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n )\r\n ) foo")), cr("foo"))); 11465 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n) foo")), cr("foo"))); 11466 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n\t) foo")), cr("foo"))); 11467 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n ) \r\n foo")), cr("foo"))); 11468 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n )\t\r\n foo")), cr("foo"))); 11469 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n )\r\n foo")), cr("foo"))); 11470 11471 assert(equal(_stripCFWS(cr(" ( \r\n \r\n ( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 11472 assert(equal(_stripCFWS(cr(" ( \r\n \r\n ( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 11473 assert(equal(_stripCFWS(cr(" (\t\r\n \r\n ( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 11474 assert(equal(_stripCFWS(cr(" (\r\n \r\n\t( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 11475 assert(equal(_stripCFWS(cr(" (\r\n \r\n( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 11476 assert(equal(_stripCFWS(cr(" (\r\n \r\n ( \r\n \r\n\t) \r\n ) foo")), cr("foo"))); 11477 assert(equal(_stripCFWS(cr(" (\r\n \r\n ( \r\n \r\n )\t\r\n ) foo")), cr("foo"))); 11478 assert(equal(_stripCFWS(cr(" (\r\n \r\n ( \r\n \r\n )\r\n ) foo")), cr("foo"))); 11479 11480 assert(equal(_stripCFWS(cr(" ( \r\n bar \r\n ( \r\n bar \r\n ) \r\n ) foo")), cr("foo"))); 11481 assert(equal(_stripCFWS(cr(" ( \r\n () \r\n ( \r\n () \r\n ) \r\n ) foo")), cr("foo"))); 11482 assert(equal(_stripCFWS(cr(" ( \r\n \\\\ \r\n ( \r\n \\\\ \r\n ) \r\n ) foo")), cr("foo"))); 11483 11484 assert(_stripCFWS(cr("(hello)(hello)")).empty); 11485 assert(_stripCFWS(cr(" \n (hello)\n (hello) \n ")).empty); 11486 assert(_stripCFWS(cr(" \n (hello) \n (hello) \n ")).empty); 11487 assert(equal(_stripCFWS(cr(" \n (hello)\n (hello) \n hello")), cr("hello"))); 11488 assert(equal(_stripCFWS(cr(" \n (hello) \n (hello) \n hello")), cr("hello"))); 11489 assert(equal(_stripCFWS(cr("\t\n\t(hello)\n\t(hello)\t\n hello")), cr("hello"))); 11490 assert(equal(_stripCFWS(cr("\t\n\t(hello)\t\n\t(hello)\t\n hello")), cr("hello"))); 11491 assert(equal(_stripCFWS(cr(" \n (hello) \n \n (hello) \n hello")), cr("hello"))); 11492 assert(equal(_stripCFWS(cr(" \n (hello) \n (hello) \n \n hello")), cr("hello"))); 11493 assert(equal(_stripCFWS(cr(" \n \n (hello)\t\n (hello) \n hello")), cr("hello"))); 11494 assert(equal(_stripCFWS(cr(" \n\t\n\t(hello)\t\n (hello) \n hello")), cr("hello"))); 11495 } 11496 } 11497 11498 // This is so that we don't have to worry about std.conv.to throwing. It also 11499 // doesn't have to worry about quite as many cases as std.conv.to, since it 11500 // doesn't have to worry about a sign on the value or about whether it fits. 11501 T _convDigits(T, R)(R str) 11502 if (isIntegral!T && isSigned!T) // The constraints on R were already covered by parseRFC822DateTime. 11503 { 11504 import std.ascii : isDigit; 11505 11506 assert(!str.empty); 11507 T num = 0; 11508 foreach (i; 0 .. str.length) 11509 { 11510 if (i != 0) 11511 num *= 10; 11512 if (!isDigit(str[i])) 11513 return -1; 11514 num += str[i] - '0'; 11515 } 11516 return num; 11517 } 11518 11519 @safe unittest 11520 { 11521 import std.conv : to; 11522 import std.range : chain, iota; 11523 foreach (i; chain(iota(0, 101), [250, 999, 1000, 1001, 2345, 9999])) 11524 { 11525 assert(_convDigits!int(to!string(i)) == i, i.to!string); 11526 } 11527 foreach (str; ["-42", "+42", "1a", "1 ", " ", " 42 "]) 11528 { 11529 assert(_convDigits!int(str) == -1, str); 11530 } 11531 } 11532 11533 11534 // NOTE: all the non-simple array literals are wrapped in functions, because 11535 // otherwise importing causes re-evaluation of the static initializers using 11536 // CTFE with unittests enabled 11537 version (StdUnittest) 11538 { 11539 private @safe: 11540 // Variables to help in testing. 11541 Duration currLocalDiffFromUTC; 11542 immutable (TimeZone)[] testTZs; 11543 11544 // All of these helper arrays are sorted in ascending order. 11545 auto testYearsBC = [-1999, -1200, -600, -4, -1, 0]; 11546 auto testYearsAD = [1, 4, 1000, 1999, 2000, 2012]; 11547 11548 // I'd use a Tuple, but I get forward reference errors if I try. 11549 struct MonthDay 11550 { 11551 Month month; 11552 short day; 11553 11554 this(int m, short d) 11555 { 11556 month = cast(Month) m; 11557 day = d; 11558 } 11559 } 11560 11561 MonthDay[] testMonthDays() 11562 { 11563 static result = [MonthDay(1, 1), 11564 MonthDay(1, 2), 11565 MonthDay(3, 17), 11566 MonthDay(7, 4), 11567 MonthDay(10, 27), 11568 MonthDay(12, 30), 11569 MonthDay(12, 31)]; 11570 return result; 11571 } 11572 11573 auto testDays = [1, 2, 9, 10, 16, 20, 25, 28, 29, 30, 31]; 11574 11575 TimeOfDay[] testTODs() 11576 { 11577 static result = [TimeOfDay(0, 0, 0), 11578 TimeOfDay(0, 0, 1), 11579 TimeOfDay(0, 1, 0), 11580 TimeOfDay(1, 0, 0), 11581 TimeOfDay(13, 13, 13), 11582 TimeOfDay(23, 59, 59)]; 11583 return result; 11584 } 11585 11586 auto testHours = [0, 1, 12, 22, 23]; 11587 auto testMinSecs = [0, 1, 30, 58, 59]; 11588 11589 // Throwing exceptions is incredibly expensive, so we want to use a smaller 11590 // set of values for tests using assertThrown. 11591 TimeOfDay[] testTODsThrown() 11592 { 11593 static result = [TimeOfDay(0, 0, 0), 11594 TimeOfDay(13, 13, 13), 11595 TimeOfDay(23, 59, 59)]; 11596 return result; 11597 } 11598 11599 Date[] testDatesBC; 11600 Date[] testDatesAD; 11601 11602 DateTime[] testDateTimesBC; 11603 DateTime[] testDateTimesAD; 11604 11605 Duration[] testFracSecs; 11606 11607 SysTime[] testSysTimesBC; 11608 SysTime[] testSysTimesAD; 11609 11610 // I'd use a Tuple, but I get forward reference errors if I try. 11611 struct GregDay { int day; Date date; } 11612 GregDay[] testGregDaysBC() 11613 { 11614 static result = [GregDay(-1_373_427, Date(-3760, 9, 7)), // Start of the Hebrew Calendar 11615 GregDay(-735_233, Date(-2012, 1, 1)), 11616 GregDay(-735_202, Date(-2012, 2, 1)), 11617 GregDay(-735_175, Date(-2012, 2, 28)), 11618 GregDay(-735_174, Date(-2012, 2, 29)), 11619 GregDay(-735_173, Date(-2012, 3, 1)), 11620 GregDay(-734_502, Date(-2010, 1, 1)), 11621 GregDay(-734_472, Date(-2010, 1, 31)), 11622 GregDay(-734_471, Date(-2010, 2, 1)), 11623 GregDay(-734_444, Date(-2010, 2, 28)), 11624 GregDay(-734_443, Date(-2010, 3, 1)), 11625 GregDay(-734_413, Date(-2010, 3, 31)), 11626 GregDay(-734_412, Date(-2010, 4, 1)), 11627 GregDay(-734_383, Date(-2010, 4, 30)), 11628 GregDay(-734_382, Date(-2010, 5, 1)), 11629 GregDay(-734_352, Date(-2010, 5, 31)), 11630 GregDay(-734_351, Date(-2010, 6, 1)), 11631 GregDay(-734_322, Date(-2010, 6, 30)), 11632 GregDay(-734_321, Date(-2010, 7, 1)), 11633 GregDay(-734_291, Date(-2010, 7, 31)), 11634 GregDay(-734_290, Date(-2010, 8, 1)), 11635 GregDay(-734_260, Date(-2010, 8, 31)), 11636 GregDay(-734_259, Date(-2010, 9, 1)), 11637 GregDay(-734_230, Date(-2010, 9, 30)), 11638 GregDay(-734_229, Date(-2010, 10, 1)), 11639 GregDay(-734_199, Date(-2010, 10, 31)), 11640 GregDay(-734_198, Date(-2010, 11, 1)), 11641 GregDay(-734_169, Date(-2010, 11, 30)), 11642 GregDay(-734_168, Date(-2010, 12, 1)), 11643 GregDay(-734_139, Date(-2010, 12, 30)), 11644 GregDay(-734_138, Date(-2010, 12, 31)), 11645 GregDay(-731_215, Date(-2001, 1, 1)), 11646 GregDay(-730_850, Date(-2000, 1, 1)), 11647 GregDay(-730_849, Date(-2000, 1, 2)), 11648 GregDay(-730_486, Date(-2000, 12, 30)), 11649 GregDay(-730_485, Date(-2000, 12, 31)), 11650 GregDay(-730_484, Date(-1999, 1, 1)), 11651 GregDay(-694_690, Date(-1901, 1, 1)), 11652 GregDay(-694_325, Date(-1900, 1, 1)), 11653 GregDay(-585_118, Date(-1601, 1, 1)), 11654 GregDay(-584_753, Date(-1600, 1, 1)), 11655 GregDay(-584_388, Date(-1600, 12, 31)), 11656 GregDay(-584_387, Date(-1599, 1, 1)), 11657 GregDay(-365_972, Date(-1001, 1, 1)), 11658 GregDay(-365_607, Date(-1000, 1, 1)), 11659 GregDay(-183_351, Date(-501, 1, 1)), 11660 GregDay(-182_986, Date(-500, 1, 1)), 11661 GregDay(-182_621, Date(-499, 1, 1)), 11662 GregDay(-146_827, Date(-401, 1, 1)), 11663 GregDay(-146_462, Date(-400, 1, 1)), 11664 GregDay(-146_097, Date(-400, 12, 31)), 11665 GregDay(-110_302, Date(-301, 1, 1)), 11666 GregDay(-109_937, Date(-300, 1, 1)), 11667 GregDay(-73_778, Date(-201, 1, 1)), 11668 GregDay(-73_413, Date(-200, 1, 1)), 11669 GregDay(-38_715, Date(-105, 1, 1)), 11670 GregDay(-37_254, Date(-101, 1, 1)), 11671 GregDay(-36_889, Date(-100, 1, 1)), 11672 GregDay(-36_524, Date(-99, 1, 1)), 11673 GregDay(-36_160, Date(-99, 12, 31)), 11674 GregDay(-35_794, Date(-97, 1, 1)), 11675 GregDay(-18_627, Date(-50, 1, 1)), 11676 GregDay(-18_262, Date(-49, 1, 1)), 11677 GregDay(-3652, Date(-9, 1, 1)), 11678 GregDay(-2191, Date(-5, 1, 1)), 11679 GregDay(-1827, Date(-5, 12, 31)), 11680 GregDay(-1826, Date(-4, 1, 1)), 11681 GregDay(-1825, Date(-4, 1, 2)), 11682 GregDay(-1462, Date(-4, 12, 30)), 11683 GregDay(-1461, Date(-4, 12, 31)), 11684 GregDay(-1460, Date(-3, 1, 1)), 11685 GregDay(-1096, Date(-3, 12, 31)), 11686 GregDay(-1095, Date(-2, 1, 1)), 11687 GregDay(-731, Date(-2, 12, 31)), 11688 GregDay(-730, Date(-1, 1, 1)), 11689 GregDay(-367, Date(-1, 12, 30)), 11690 GregDay(-366, Date(-1, 12, 31)), 11691 GregDay(-365, Date(0, 1, 1)), 11692 GregDay(-31, Date(0, 11, 30)), 11693 GregDay(-30, Date(0, 12, 1)), 11694 GregDay(-1, Date(0, 12, 30)), 11695 GregDay(0, Date(0, 12, 31))]; 11696 return result; 11697 } 11698 11699 GregDay[] testGregDaysAD() 11700 { 11701 static result = [GregDay(1, Date(1, 1, 1)), 11702 GregDay(2, Date(1, 1, 2)), 11703 GregDay(32, Date(1, 2, 1)), 11704 GregDay(365, Date(1, 12, 31)), 11705 GregDay(366, Date(2, 1, 1)), 11706 GregDay(731, Date(3, 1, 1)), 11707 GregDay(1096, Date(4, 1, 1)), 11708 GregDay(1097, Date(4, 1, 2)), 11709 GregDay(1460, Date(4, 12, 30)), 11710 GregDay(1461, Date(4, 12, 31)), 11711 GregDay(1462, Date(5, 1, 1)), 11712 GregDay(17_898, Date(50, 1, 1)), 11713 GregDay(35_065, Date(97, 1, 1)), 11714 GregDay(36_160, Date(100, 1, 1)), 11715 GregDay(36_525, Date(101, 1, 1)), 11716 GregDay(37_986, Date(105, 1, 1)), 11717 GregDay(72_684, Date(200, 1, 1)), 11718 GregDay(73_049, Date(201, 1, 1)), 11719 GregDay(109_208, Date(300, 1, 1)), 11720 GregDay(109_573, Date(301, 1, 1)), 11721 GregDay(145_732, Date(400, 1, 1)), 11722 GregDay(146_098, Date(401, 1, 1)), 11723 GregDay(182_257, Date(500, 1, 1)), 11724 GregDay(182_622, Date(501, 1, 1)), 11725 GregDay(364_878, Date(1000, 1, 1)), 11726 GregDay(365_243, Date(1001, 1, 1)), 11727 GregDay(584_023, Date(1600, 1, 1)), 11728 GregDay(584_389, Date(1601, 1, 1)), 11729 GregDay(693_596, Date(1900, 1, 1)), 11730 GregDay(693_961, Date(1901, 1, 1)), 11731 GregDay(729_755, Date(1999, 1, 1)), 11732 GregDay(730_120, Date(2000, 1, 1)), 11733 GregDay(730_121, Date(2000, 1, 2)), 11734 GregDay(730_484, Date(2000, 12, 30)), 11735 GregDay(730_485, Date(2000, 12, 31)), 11736 GregDay(730_486, Date(2001, 1, 1)), 11737 GregDay(733_773, Date(2010, 1, 1)), 11738 GregDay(733_774, Date(2010, 1, 2)), 11739 GregDay(733_803, Date(2010, 1, 31)), 11740 GregDay(733_804, Date(2010, 2, 1)), 11741 GregDay(733_831, Date(2010, 2, 28)), 11742 GregDay(733_832, Date(2010, 3, 1)), 11743 GregDay(733_862, Date(2010, 3, 31)), 11744 GregDay(733_863, Date(2010, 4, 1)), 11745 GregDay(733_892, Date(2010, 4, 30)), 11746 GregDay(733_893, Date(2010, 5, 1)), 11747 GregDay(733_923, Date(2010, 5, 31)), 11748 GregDay(733_924, Date(2010, 6, 1)), 11749 GregDay(733_953, Date(2010, 6, 30)), 11750 GregDay(733_954, Date(2010, 7, 1)), 11751 GregDay(733_984, Date(2010, 7, 31)), 11752 GregDay(733_985, Date(2010, 8, 1)), 11753 GregDay(734_015, Date(2010, 8, 31)), 11754 GregDay(734_016, Date(2010, 9, 1)), 11755 GregDay(734_045, Date(2010, 9, 30)), 11756 GregDay(734_046, Date(2010, 10, 1)), 11757 GregDay(734_076, Date(2010, 10, 31)), 11758 GregDay(734_077, Date(2010, 11, 1)), 11759 GregDay(734_106, Date(2010, 11, 30)), 11760 GregDay(734_107, Date(2010, 12, 1)), 11761 GregDay(734_136, Date(2010, 12, 30)), 11762 GregDay(734_137, Date(2010, 12, 31)), 11763 GregDay(734_503, Date(2012, 1, 1)), 11764 GregDay(734_534, Date(2012, 2, 1)), 11765 GregDay(734_561, Date(2012, 2, 28)), 11766 GregDay(734_562, Date(2012, 2, 29)), 11767 GregDay(734_563, Date(2012, 3, 1)), 11768 GregDay(734_858, Date(2012, 12, 21))]; 11769 return result; 11770 } 11771 11772 // I'd use a Tuple, but I get forward reference errors if I try. 11773 struct DayOfYear { int day; MonthDay md; } 11774 DayOfYear[] testDaysOfYear() 11775 { 11776 static result = [DayOfYear(1, MonthDay(1, 1)), 11777 DayOfYear(2, MonthDay(1, 2)), 11778 DayOfYear(3, MonthDay(1, 3)), 11779 DayOfYear(31, MonthDay(1, 31)), 11780 DayOfYear(32, MonthDay(2, 1)), 11781 DayOfYear(59, MonthDay(2, 28)), 11782 DayOfYear(60, MonthDay(3, 1)), 11783 DayOfYear(90, MonthDay(3, 31)), 11784 DayOfYear(91, MonthDay(4, 1)), 11785 DayOfYear(120, MonthDay(4, 30)), 11786 DayOfYear(121, MonthDay(5, 1)), 11787 DayOfYear(151, MonthDay(5, 31)), 11788 DayOfYear(152, MonthDay(6, 1)), 11789 DayOfYear(181, MonthDay(6, 30)), 11790 DayOfYear(182, MonthDay(7, 1)), 11791 DayOfYear(212, MonthDay(7, 31)), 11792 DayOfYear(213, MonthDay(8, 1)), 11793 DayOfYear(243, MonthDay(8, 31)), 11794 DayOfYear(244, MonthDay(9, 1)), 11795 DayOfYear(273, MonthDay(9, 30)), 11796 DayOfYear(274, MonthDay(10, 1)), 11797 DayOfYear(304, MonthDay(10, 31)), 11798 DayOfYear(305, MonthDay(11, 1)), 11799 DayOfYear(334, MonthDay(11, 30)), 11800 DayOfYear(335, MonthDay(12, 1)), 11801 DayOfYear(363, MonthDay(12, 29)), 11802 DayOfYear(364, MonthDay(12, 30)), 11803 DayOfYear(365, MonthDay(12, 31))]; 11804 return result; 11805 } 11806 11807 DayOfYear[] testDaysOfLeapYear() 11808 { 11809 static result = [DayOfYear(1, MonthDay(1, 1)), 11810 DayOfYear(2, MonthDay(1, 2)), 11811 DayOfYear(3, MonthDay(1, 3)), 11812 DayOfYear(31, MonthDay(1, 31)), 11813 DayOfYear(32, MonthDay(2, 1)), 11814 DayOfYear(59, MonthDay(2, 28)), 11815 DayOfYear(60, MonthDay(2, 29)), 11816 DayOfYear(61, MonthDay(3, 1)), 11817 DayOfYear(91, MonthDay(3, 31)), 11818 DayOfYear(92, MonthDay(4, 1)), 11819 DayOfYear(121, MonthDay(4, 30)), 11820 DayOfYear(122, MonthDay(5, 1)), 11821 DayOfYear(152, MonthDay(5, 31)), 11822 DayOfYear(153, MonthDay(6, 1)), 11823 DayOfYear(182, MonthDay(6, 30)), 11824 DayOfYear(183, MonthDay(7, 1)), 11825 DayOfYear(213, MonthDay(7, 31)), 11826 DayOfYear(214, MonthDay(8, 1)), 11827 DayOfYear(244, MonthDay(8, 31)), 11828 DayOfYear(245, MonthDay(9, 1)), 11829 DayOfYear(274, MonthDay(9, 30)), 11830 DayOfYear(275, MonthDay(10, 1)), 11831 DayOfYear(305, MonthDay(10, 31)), 11832 DayOfYear(306, MonthDay(11, 1)), 11833 DayOfYear(335, MonthDay(11, 30)), 11834 DayOfYear(336, MonthDay(12, 1)), 11835 DayOfYear(364, MonthDay(12, 29)), 11836 DayOfYear(365, MonthDay(12, 30)), 11837 DayOfYear(366, MonthDay(12, 31))]; 11838 return result; 11839 } 11840 11841 void initializeTests() 11842 { 11843 import std.algorithm.sorting : sort; 11844 import std.typecons : Rebindable; 11845 immutable lt = LocalTime().utcToTZ(0); 11846 currLocalDiffFromUTC = dur!"hnsecs"(lt); 11847 11848 version (Posix) 11849 { 11850 import std.datetime.timezone : PosixTimeZone; 11851 immutable otherTZ = lt < 0 ? PosixTimeZone.getTimeZone("Australia/Sydney") 11852 : PosixTimeZone.getTimeZone("America/Denver"); 11853 } 11854 else version (Windows) 11855 { 11856 import std.datetime.timezone : WindowsTimeZone; 11857 immutable otherTZ = lt < 0 ? WindowsTimeZone.getTimeZone("AUS Eastern Standard Time") 11858 : WindowsTimeZone.getTimeZone("Mountain Standard Time"); 11859 } 11860 11861 immutable ot = otherTZ.utcToTZ(0); 11862 11863 auto diffs = [0L, lt, ot]; 11864 auto diffAA = [0L : Rebindable!(immutable TimeZone)(UTC())]; 11865 diffAA[lt] = Rebindable!(immutable TimeZone)(LocalTime()); 11866 diffAA[ot] = Rebindable!(immutable TimeZone)(otherTZ); 11867 11868 sort(diffs); 11869 testTZs = [diffAA[diffs[0]], diffAA[diffs[1]], diffAA[diffs[2]]]; 11870 11871 testFracSecs = [Duration.zero, hnsecs(1), hnsecs(5007), hnsecs(9_999_999)]; 11872 11873 foreach (year; testYearsBC) 11874 { 11875 foreach (md; testMonthDays) 11876 testDatesBC ~= Date(year, md.month, md.day); 11877 } 11878 11879 foreach (year; testYearsAD) 11880 { 11881 foreach (md; testMonthDays) 11882 testDatesAD ~= Date(year, md.month, md.day); 11883 } 11884 11885 foreach (dt; testDatesBC) 11886 { 11887 foreach (tod; testTODs) 11888 testDateTimesBC ~= DateTime(dt, tod); 11889 } 11890 11891 foreach (dt; testDatesAD) 11892 { 11893 foreach (tod; testTODs) 11894 testDateTimesAD ~= DateTime(dt, tod); 11895 } 11896 11897 foreach (dt; testDateTimesBC) 11898 { 11899 foreach (tz; testTZs) 11900 { 11901 foreach (fs; testFracSecs) 11902 testSysTimesBC ~= SysTime(dt, fs, tz); 11903 } 11904 } 11905 11906 foreach (dt; testDateTimesAD) 11907 { 11908 foreach (tz; testTZs) 11909 { 11910 foreach (fs; testFracSecs) 11911 testSysTimesAD ~= SysTime(dt, fs, tz); 11912 } 11913 } 11914 } 11915 }