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 format for SysTime.fromISOString: %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!DateTimeException(tIndex != -1, 9113 format("Invalid format for SysTime.fromISOExtString: %s", isoExtString)); 9114 9115 auto found = str[tIndex + 1 .. $].find('.', 'Z', '+', '-'); 9116 auto dateTimeStr = str[0 .. $ - found[0].length]; 9117 9118 typeof(str) foundTZ; // needs to have longer lifetime than zoneStr 9119 typeof(str) fracSecStr; 9120 typeof(str) zoneStr; 9121 9122 if (found[1] != 0) 9123 { 9124 if (found[1] == 1) 9125 { 9126 foundTZ = found[0].find('Z', '+', '-')[0]; 9127 9128 if (foundTZ.length != 0) 9129 { 9130 fracSecStr = found[0][0 .. $ - foundTZ.length]; 9131 zoneStr = foundTZ; 9132 } 9133 else 9134 fracSecStr = found[0]; 9135 } 9136 else 9137 zoneStr = found[0]; 9138 } 9139 9140 try 9141 { 9142 auto dateTime = DateTime.fromISOExtString(dateTimeStr); 9143 auto fracSec = fracSecsFromISOString(fracSecStr); 9144 Rebindable!(immutable TimeZone) parsedZone; 9145 9146 if (zoneStr.empty) 9147 parsedZone = LocalTime(); 9148 else if (zoneStr == "Z") 9149 parsedZone = UTC(); 9150 else 9151 parsedZone = SimpleTimeZone.fromISOExtString(zoneStr); 9152 9153 auto retval = SysTime(dateTime, fracSec, parsedZone); 9154 9155 if (tz !is null) 9156 retval.timezone = tz; 9157 9158 return retval; 9159 } 9160 catch (DateTimeException dte) 9161 throw new DateTimeException(format("Invalid format for SysTime.fromISOExtString: %s", isoExtString)); 9162 } 9163 9164 /// 9165 @safe unittest 9166 { 9167 import core.time : hours, msecs, usecs, hnsecs; 9168 import std.datetime.date : DateTime; 9169 import std.datetime.timezone : SimpleTimeZone, UTC; 9170 9171 assert(SysTime.fromISOExtString("2010-07-04T07:06:12") == 9172 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 9173 9174 assert(SysTime.fromISOExtString("1998-12-25T02:15:00.007") == 9175 SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(7))); 9176 9177 assert(SysTime.fromISOExtString("0000-01-05T23:09:59.00002") == 9178 SysTime(DateTime(0, 1, 5, 23, 9, 59), usecs(20))); 9179 9180 assert(SysTime.fromISOExtString("2013-02-07T04:39:37.000050392") == 9181 SysTime(DateTime(2013, 2, 7, 4, 39, 37), hnsecs(503))); 9182 9183 assert(SysTime.fromISOExtString("-0004-01-05T00:00:02") == 9184 SysTime(DateTime(-4, 1, 5, 0, 0, 2))); 9185 9186 assert(SysTime.fromISOExtString(" 2010-07-04T07:06:12 ") == 9187 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 9188 9189 assert(SysTime.fromISOExtString("2010-07-04T07:06:12Z") == 9190 SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC())); 9191 9192 assert(SysTime.fromISOExtString("2010-07-04T07:06:12-08:00") == 9193 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 9194 new immutable SimpleTimeZone(hours(-8)))); 9195 assert(SysTime.fromISOExtString("2010-07-04T07:06:12+08:00") == 9196 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 9197 new immutable SimpleTimeZone(hours(8)))); 9198 } 9199 9200 @safe unittest 9201 { 9202 import core.time; 9203 foreach (str; ["", "20100704000000", "20100704 000000", 9204 "20100704t000000", "20100704T000000.", "20100704T000000.0", 9205 "2010-07:0400:00:00", "2010-07-04 00:00:00", 9206 "2010-07-04 00:00:00", "2010-07-04t00:00:00", 9207 "2010-07-04T00:00:00.", "2010-07-04T00:00:00.A", "2010-07-04T00:00:00.Z", 9208 "2010-07-04T00:00:00.0000000A", "2010-07-04T00:00:00.00000000A", 9209 "2010-07-04T00:00:00+", "2010-07-04T00:00:00-", 9210 "2010-07-04T00:00:00:", "2010-07-04T00:00:00-:", "2010-07-04T00:00:00+:", 9211 "2010-07-04T00:00:00-1:", "2010-07-04T00:00:00+1:", "2010-07-04T00:00:00+1:0", 9212 "2010-07-04T00:00:00-12.00", "2010-07-04T00:00:00+12.00", 9213 "2010-07-04T00:00:00-8", "2010-07-04T00:00:00+8", 9214 "20100704T000000-800", "20100704T000000+800", 9215 "20100704T000000-080", "20100704T000000+080", 9216 "20100704T000000-2400", "20100704T000000+2400", 9217 "20100704T000000-1260", "20100704T000000+1260", 9218 "20100704T000000.0-800", "20100704T000000.0+800", 9219 "20100704T000000.0-8", "20100704T000000.0+8", 9220 "20100704T000000.0-080", "20100704T000000.0+080", 9221 "20100704T000000.0-2400", "20100704T000000.0+2400", 9222 "20100704T000000.0-1260", "20100704T000000.0+1260", 9223 "2010-07-04T00:00:00-8:00", "2010-07-04T00:00:00+8:00", 9224 "2010-07-04T00:00:00-24:00", "2010-07-04T00:00:00+24:00", 9225 "2010-07-04T00:00:00-12:60", "2010-07-04T00:00:00+12:60", 9226 "2010-07-04T00:00:00.0-8:00", "2010-07-04T00:00:00.0+8:00", 9227 "2010-07-04T00:00:00.0-8", "2010-07-04T00:00:00.0+8", 9228 "2010-07-04T00:00:00.0-24:00", "2010-07-04T00:00:00.0+24:00", 9229 "2010-07-04T00:00:00.0-12:60", "2010-07-04T00:00:00.0+12:60", 9230 "2010-Jul-0400:00:00", "2010-Jul-04t00:00:00", 9231 "2010-Jul-04 00:00:00.", "2010-Jul-04 00:00:00.0", 9232 "20101222T172201", "2010-Dec-22 17:22:01"]) 9233 { 9234 assertThrown!DateTimeException(SysTime.fromISOExtString(str), format("[%s]", str)); 9235 } 9236 9237 static void test(string str, SysTime st, size_t line = __LINE__) 9238 { 9239 if (SysTime.fromISOExtString(str) != st) 9240 throw new AssertError("unittest failure", __FILE__, line); 9241 } 9242 9243 test("2010-12-22T17:22:01", SysTime(DateTime(2010, 12, 22, 17, 22, 1))); 9244 test("1999-07-06T12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9245 test("-1999-07-06T12:30:33", SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 9246 test("+01999-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 test(" 1999-07-06T12:30:33 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9250 9251 test("1907-07-07T12:12:12.0", SysTime(DateTime(1907, 7, 7, 12, 12, 12))); 9252 test("1907-07-07T12:12:12.0000000", SysTime(DateTime(1907, 7, 7, 12, 12, 12))); 9253 test("1907-07-07T12:12:12.0000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), hnsecs(1))); 9254 test("2010-07-04T00:00:00.00000000", SysTime(Date(2010, 7, 4))); 9255 test("2010-07-04T00:00:00.00000009", SysTime(Date(2010, 7, 4))); 9256 test("2010-07-04T00:00:00.00000019", SysTime(DateTime(2010, 7, 4), hnsecs(1))); 9257 test("1907-07-07T12:12:12.000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1))); 9258 test("1907-07-07T12:12:12.0000010", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1))); 9259 test("1907-07-07T12:12:12.001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1))); 9260 test("1907-07-07T12:12:12.0010000", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1))); 9261 9262 auto west60 = new immutable SimpleTimeZone(hours(-1)); 9263 auto west90 = new immutable SimpleTimeZone(minutes(-90)); 9264 auto west480 = new immutable SimpleTimeZone(hours(-8)); 9265 auto east60 = new immutable SimpleTimeZone(hours(1)); 9266 auto east90 = new immutable SimpleTimeZone(minutes(90)); 9267 auto east480 = new immutable SimpleTimeZone(hours(8)); 9268 9269 test("2010-12-22T17:22:01Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), UTC())); 9270 test("2010-12-22T17:22:01-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60)); 9271 test("2010-12-22T17:22:01-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60)); 9272 test("2010-12-22T17:22:01-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west90)); 9273 test("2010-12-22T17:22:01-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west480)); 9274 test("2010-12-22T17:22:01+01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9275 test("2010-12-22T17:22:01+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9276 test("2010-12-22T17:22:01+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 9277 test("2010-12-22T17:22:01+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east480)); 9278 9279 test("2010-11-03T06:51:06.57159Z", SysTime(DateTime(2010, 11, 3, 6, 51, 6), hnsecs(5715900), UTC())); 9280 test("2010-12-22T17:22:01.23412Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_341_200), UTC())); 9281 test("2010-12-22T17:22:01.23112-01:00", 9282 SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_311_200), west60)); 9283 test("2010-12-22T17:22:01.45-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), west60)); 9284 test("2010-12-22T17:22:01.1-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_000_000), west90)); 9285 test("2010-12-22T17:22:01.55-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(5_500_000), west480)); 9286 test("2010-12-22T17:22:01.1234567+01:00", 9287 SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_234_567), east60)); 9288 test("2010-12-22T17:22:01.0+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9289 test("2010-12-22T17:22:01.0000000+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 9290 test("2010-12-22T17:22:01.45+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), east480)); 9291 9292 static void testScope(scope ref string str) @safe 9293 { 9294 auto result = SysTime.fromISOExtString(str); 9295 } 9296 } 9297 9298 // https://issues.dlang.org/show_bug.cgi?id=17801 9299 @safe unittest 9300 { 9301 import core.time; 9302 import std.conv : to; 9303 import std.meta : AliasSeq; 9304 static foreach (C; AliasSeq!(char, wchar, dchar)) 9305 { 9306 static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) 9307 { 9308 assert(SysTime.fromISOExtString(to!S("2012-12-21T14:15:16Z")) == 9309 SysTime(DateTime(2012, 12, 21, 14, 15, 16), UTC())); 9310 } 9311 } 9312 } 9313 9314 9315 /++ 9316 Creates a $(LREF SysTime) from a string with the format 9317 YYYY-Mon-DD HH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ 9318 is the time zone). Whitespace is stripped from the given string. 9319 9320 The exact format is exactly as described in $(LREF toSimpleString) except 9321 that trailing zeroes are permitted - including having fractional seconds 9322 with all zeroes. The time zone and fractional seconds are optional, 9323 however, a decimal point with nothing following it is invalid. 9324 Also, while $(LREF toSimpleString) will never generate a 9325 string with more than 7 digits in the fractional seconds (because that's 9326 the limit with hecto-nanosecond precision), it will allow more than 7 9327 digits in order to read strings from other sources that have higher 9328 precision (however, any digits beyond 7 will be truncated). 9329 9330 If there is no time zone in the string, then 9331 $(REF LocalTime,std,datetime,timezone) is used. If the time zone is "Z", 9332 then `UTC` is used. Otherwise, a 9333 $(REF SimpleTimeZone,std,datetime,timezone) which corresponds to the 9334 given offset from UTC is used. To get the returned $(LREF SysTime) to be 9335 a particular time zone, pass in that time zone and the $(LREF SysTime) 9336 to be returned will be converted to that time zone (though it will still 9337 be read in as whatever time zone is in its string). 9338 9339 The accepted formats for time zone offsets are +HH, -HH, +HH:MM, and 9340 -HH:MM. 9341 9342 Params: 9343 simpleString = A string formatted in the way that 9344 `toSimpleString` formats dates and times. 9345 tz = The time zone to convert the given time to (no 9346 conversion occurs if null). 9347 9348 Throws: 9349 $(REF DateTimeException,std,datetime,date) if the given string is 9350 not in the ISO format or if the resulting $(LREF SysTime) would not 9351 be valid. 9352 +/ 9353 static SysTime fromSimpleString(S)(scope const S simpleString, immutable TimeZone tz = null) @safe 9354 if (isSomeString!(S)) 9355 { 9356 import std.algorithm.searching : find; 9357 import std.conv : to; 9358 import std.string : strip, indexOf; 9359 9360 auto str = strip(simpleString); 9361 9362 auto spaceIndex = str.indexOf(' '); 9363 enforce!DateTimeException(spaceIndex != -1, 9364 format("Invalid format for SysTime.fromSimpleString: %s", simpleString)); 9365 9366 auto found = str[spaceIndex + 1 .. $].find('.', 'Z', '+', '-'); 9367 auto dateTimeStr = str[0 .. $ - found[0].length]; 9368 9369 typeof(str) foundTZ; // needs to have longer lifetime than zoneStr 9370 typeof(str) fracSecStr; 9371 typeof(str) zoneStr; 9372 9373 if (found[1] != 0) 9374 { 9375 if (found[1] == 1) 9376 { 9377 foundTZ = found[0].find('Z', '+', '-')[0]; 9378 9379 if (foundTZ.length != 0) 9380 { 9381 fracSecStr = found[0][0 .. $ - foundTZ.length]; 9382 zoneStr = foundTZ; 9383 } 9384 else 9385 fracSecStr = found[0]; 9386 } 9387 else 9388 zoneStr = found[0]; 9389 } 9390 9391 try 9392 { 9393 auto dateTime = DateTime.fromSimpleString(dateTimeStr); 9394 auto fracSec = fracSecsFromISOString(fracSecStr); 9395 Rebindable!(immutable TimeZone) parsedZone; 9396 9397 if (zoneStr.empty) 9398 parsedZone = LocalTime(); 9399 else if (zoneStr == "Z") 9400 parsedZone = UTC(); 9401 else 9402 parsedZone = SimpleTimeZone.fromISOExtString(zoneStr); 9403 9404 auto retval = SysTime(dateTime, fracSec, parsedZone); 9405 9406 if (tz !is null) 9407 retval.timezone = tz; 9408 9409 return retval; 9410 } 9411 catch (DateTimeException dte) 9412 throw new DateTimeException(format("Invalid format for SysTime.fromSimpleString: %s", simpleString)); 9413 } 9414 9415 /// 9416 @safe unittest 9417 { 9418 import core.time : hours, msecs, usecs, hnsecs; 9419 import std.datetime.date : DateTime; 9420 import std.datetime.timezone : SimpleTimeZone, UTC; 9421 9422 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12") == 9423 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 9424 9425 assert(SysTime.fromSimpleString("1998-Dec-25 02:15:00.007") == 9426 SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(7))); 9427 9428 assert(SysTime.fromSimpleString("0000-Jan-05 23:09:59.00002") == 9429 SysTime(DateTime(0, 1, 5, 23, 9, 59), usecs(20))); 9430 9431 assert(SysTime.fromSimpleString("2013-Feb-07 04:39:37.000050392") == 9432 SysTime(DateTime(2013, 2, 7, 4, 39, 37), hnsecs(503))); 9433 9434 assert(SysTime.fromSimpleString("-0004-Jan-05 00:00:02") == 9435 SysTime(DateTime(-4, 1, 5, 0, 0, 2))); 9436 9437 assert(SysTime.fromSimpleString(" 2010-Jul-04 07:06:12 ") == 9438 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 9439 9440 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12Z") == 9441 SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC())); 9442 9443 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12-08:00") == 9444 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 9445 new immutable SimpleTimeZone(hours(-8)))); 9446 9447 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12+08:00") == 9448 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 9449 new immutable SimpleTimeZone(hours(8)))); 9450 } 9451 9452 @safe unittest 9453 { 9454 import core.time; 9455 foreach (str; ["", "20100704000000", "20100704 000000", 9456 "20100704t000000", "20100704T000000.", "20100704T000000.0", 9457 "2010-07-0400:00:00", "2010-07-04 00:00:00", "2010-07-04t00:00:00", 9458 "2010-07-04T00:00:00.", "2010-07-04T00:00:00.0", 9459 "2010-Jul-0400:00:00", "2010-Jul-04t00:00:00", "2010-Jul-04T00:00:00", 9460 "2010-Jul-04 00:00:00.", "2010-Jul-04 00:00:00.A", "2010-Jul-04 00:00:00.Z", 9461 "2010-Jul-04 00:00:00.0000000A", "2010-Jul-04 00:00:00.00000000A", 9462 "2010-Jul-04 00:00:00+", "2010-Jul-04 00:00:00-", 9463 "2010-Jul-04 00:00:00:", "2010-Jul-04 00:00:00-:", 9464 "2010-Jul-04 00:00:00+:", "2010-Jul-04 00:00:00-1:", 9465 "2010-Jul-04 00:00:00+1:", "2010-Jul-04 00:00:00+1:0", 9466 "2010-Jul-04 00:00:00-12.00", "2010-Jul-04 00:00:00+12.00", 9467 "2010-Jul-04 00:00:00-8", "2010-Jul-04 00:00:00+8", 9468 "20100704T000000-800", "20100704T000000+800", 9469 "20100704T000000-080", "20100704T000000+080", 9470 "20100704T000000-2400", "20100704T000000+2400", 9471 "20100704T000000-1260", "20100704T000000+1260", 9472 "20100704T000000.0-800", "20100704T000000.0+800", 9473 "20100704T000000.0-8", "20100704T000000.0+8", 9474 "20100704T000000.0-080", "20100704T000000.0+080", 9475 "20100704T000000.0-2400", "20100704T000000.0+2400", 9476 "20100704T000000.0-1260", "20100704T000000.0+1260", 9477 "2010-Jul-04 00:00:00-8:00", "2010-Jul-04 00:00:00+8:00", 9478 "2010-Jul-04 00:00:00-08:0", "2010-Jul-04 00:00:00+08:0", 9479 "2010-Jul-04 00:00:00-24:00", "2010-Jul-04 00:00:00+24:00", 9480 "2010-Jul-04 00:00:00-12:60", "2010-Jul-04 00:00:00+24:60", 9481 "2010-Jul-04 00:00:00.0-8:00", "2010-Jul-04 00:00:00+8:00", 9482 "2010-Jul-04 00:00:00.0-8", "2010-Jul-04 00:00:00.0+8", 9483 "2010-Jul-04 00:00:00.0-08:0", "2010-Jul-04 00:00:00.0+08:0", 9484 "2010-Jul-04 00:00:00.0-24:00", "2010-Jul-04 00:00:00.0+24:00", 9485 "2010-Jul-04 00:00:00.0-12:60", "2010-Jul-04 00:00:00.0+24:60", 9486 "20101222T172201", "2010-12-22T172201"]) 9487 { 9488 assertThrown!DateTimeException(SysTime.fromSimpleString(str), format("[%s]", str)); 9489 } 9490 9491 static void test(string str, SysTime st, size_t line = __LINE__) 9492 { 9493 if (SysTime.fromSimpleString(str) != st) 9494 throw new AssertError("unittest failure", __FILE__, line); 9495 } 9496 9497 test("2010-Dec-22 17:22:01", SysTime(DateTime(2010, 12, 22, 17, 22, 1))); 9498 test("1999-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("+01999-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 test(" 1999-Jul-06 12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9503 test(" 1999-Jul-06 12:30:33 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9504 9505 test("1907-Jul-07 12:12:12.0", SysTime(DateTime(1907, 7, 7, 12, 12, 12))); 9506 test("1907-Jul-07 12:12:12.0000000", SysTime(DateTime(1907, 7, 7, 12, 12, 12))); 9507 test("2010-Jul-04 00:00:00.00000000", SysTime(Date(2010, 7, 4))); 9508 test("2010-Jul-04 00:00:00.00000009", SysTime(Date(2010, 7, 4))); 9509 test("2010-Jul-04 00:00:00.00000019", SysTime(DateTime(2010, 7, 4), hnsecs(1))); 9510 test("1907-Jul-07 12:12:12.0000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), hnsecs(1))); 9511 test("1907-Jul-07 12:12:12.000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1))); 9512 test("1907-Jul-07 12:12:12.0000010", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1))); 9513 test("1907-Jul-07 12:12:12.001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1))); 9514 test("1907-Jul-07 12:12:12.0010000", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1))); 9515 9516 auto west60 = new immutable SimpleTimeZone(hours(-1)); 9517 auto west90 = new immutable SimpleTimeZone(minutes(-90)); 9518 auto west480 = new immutable SimpleTimeZone(hours(-8)); 9519 auto east60 = new immutable SimpleTimeZone(hours(1)); 9520 auto east90 = new immutable SimpleTimeZone(minutes(90)); 9521 auto east480 = new immutable SimpleTimeZone(hours(8)); 9522 9523 test("2010-Dec-22 17:22:01Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), UTC())); 9524 test("2010-Dec-22 17:22:01-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60)); 9525 test("2010-Dec-22 17:22:01-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60)); 9526 test("2010-Dec-22 17:22:01-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west90)); 9527 test("2010-Dec-22 17:22:01-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west480)); 9528 test("2010-Dec-22 17:22:01+01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9529 test("2010-Dec-22 17:22:01+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9530 test("2010-Dec-22 17:22:01+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 9531 test("2010-Dec-22 17:22:01+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east480)); 9532 9533 test("2010-Nov-03 06:51:06.57159Z", SysTime(DateTime(2010, 11, 3, 6, 51, 6), hnsecs(5715900), UTC())); 9534 test("2010-Dec-22 17:22:01.23412Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_341_200), UTC())); 9535 test("2010-Dec-22 17:22:01.23112-01:00", 9536 SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_311_200), west60)); 9537 test("2010-Dec-22 17:22:01.45-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), west60)); 9538 test("2010-Dec-22 17:22:01.1-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_000_000), west90)); 9539 test("2010-Dec-22 17:22:01.55-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(5_500_000), west480)); 9540 test("2010-Dec-22 17:22:01.1234567+01:00", 9541 SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_234_567), east60)); 9542 test("2010-Dec-22 17:22:01.0+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9543 test("2010-Dec-22 17:22:01.0000000+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 9544 test("2010-Dec-22 17:22:01.45+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), east480)); 9545 9546 static void testScope(scope ref string str) @safe 9547 { 9548 auto result = SysTime.fromSimpleString(str); 9549 } 9550 } 9551 9552 // https://issues.dlang.org/show_bug.cgi?id=17801 9553 @safe unittest 9554 { 9555 import core.time; 9556 import std.conv : to; 9557 import std.meta : AliasSeq; 9558 static foreach (C; AliasSeq!(char, wchar, dchar)) 9559 { 9560 static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) 9561 { 9562 assert(SysTime.fromSimpleString(to!S("2012-Dec-21 14:15:16Z")) == 9563 SysTime(DateTime(2012, 12, 21, 14, 15, 16), UTC())); 9564 } 9565 } 9566 } 9567 9568 9569 /++ 9570 Returns the $(LREF SysTime) farthest in the past which is representable 9571 by $(LREF SysTime). 9572 9573 The $(LREF SysTime) which is returned is in UTC. 9574 +/ 9575 @property static SysTime min() @safe pure nothrow 9576 { 9577 return SysTime(long.min, UTC()); 9578 } 9579 9580 @safe unittest 9581 { 9582 assert(SysTime.min.year < 0); 9583 assert(SysTime.min < SysTime.max); 9584 } 9585 9586 9587 /++ 9588 Returns the $(LREF SysTime) farthest in the future which is representable 9589 by $(LREF SysTime). 9590 9591 The $(LREF SysTime) which is returned is in UTC. 9592 +/ 9593 @property static SysTime max() @safe pure nothrow 9594 { 9595 return SysTime(long.max, UTC()); 9596 } 9597 9598 @safe unittest 9599 { 9600 assert(SysTime.max.year > 0); 9601 assert(SysTime.max > SysTime.min); 9602 } 9603 9604 9605 private: 9606 9607 /+ 9608 Returns `stdTime` converted to $(LREF SysTime)'s time zone. 9609 +/ 9610 @property long adjTime() @safe const nothrow scope 9611 { 9612 return _timezone.utcToTZ(_stdTime); 9613 } 9614 9615 9616 /+ 9617 Converts the given hnsecs from $(LREF SysTime)'s time zone to std time. 9618 +/ 9619 @property void adjTime(long adjTime) @safe nothrow scope 9620 { 9621 _stdTime = _timezone.tzToUTC(adjTime); 9622 } 9623 9624 9625 final class InitTimeZone : TimeZone 9626 { 9627 public: 9628 9629 static immutable(InitTimeZone) opCall() @safe pure nothrow @nogc { return _initTimeZone; } 9630 9631 @property override bool hasDST() @safe const nothrow @nogc { return false; } 9632 9633 override bool dstInEffect(long stdTime) @safe const scope nothrow @nogc { return false; } 9634 9635 override long utcToTZ(long stdTime) @safe const scope nothrow @nogc { return 0; } 9636 9637 override long tzToUTC(long adjTime) @safe const scope nothrow @nogc { return 0; } 9638 9639 override Duration utcOffsetAt(long stdTime) @safe const scope nothrow @nogc { return Duration.zero; } 9640 9641 private: 9642 9643 this() @safe immutable pure 9644 { 9645 super("SysTime.init's timezone", "SysTime.init's timezone", "SysTime.init's timezone"); 9646 } 9647 9648 static immutable InitTimeZone _initTimeZone = new immutable(InitTimeZone); 9649 } 9650 9651 // https://issues.dlang.org/show_bug.cgi?id=17732 9652 @safe unittest 9653 { 9654 assert(SysTime.init.timezone is InitTimeZone()); 9655 assert(SysTime.init.toISOString() == "00010101T000000+00:00"); 9656 assert(SysTime.init.toISOExtString() == "0001-01-01T00:00:00+00:00"); 9657 assert(SysTime.init.toSimpleString() == "0001-Jan-01 00:00:00+00:00"); 9658 assert(SysTime.init.toString() == "0001-Jan-01 00:00:00+00:00"); 9659 } 9660 9661 // Assigning a value to _timezone in SysTime.init currently doesn't work due 9662 // to https://issues.dlang.org/show_bug.cgi?id=17740. So, to hack around 9663 // that problem, these accessors have been added so that we can insert a 9664 // runtime check for null and then use InitTimeZone for SysTime.init (which 9665 // which is the only case where _timezone would be null). This thus fixes 9666 // the problem with segfaulting when using SysTime.init but at the cost of 9667 // what should be an unnecessary null check. Once 17740 has finally been 9668 // fixed, _timezoneStorage should be removed, these accessors should be 9669 // removed, and the _timezone variable declaration should be restored. 9670 pragma(inline, true) @property _timezone() @safe const pure nothrow @nogc 9671 { 9672 return _timezoneStorage is null ? InitTimeZone() : _timezoneStorage; 9673 } 9674 9675 pragma(inline, true) @property void _timezone(return scope immutable TimeZone tz) @safe pure nothrow @nogc scope 9676 { 9677 _timezoneStorage = tz; 9678 } 9679 9680 9681 long _stdTime; 9682 Rebindable!(immutable TimeZone) _timezoneStorage; 9683 //Rebindable!(immutable TimeZone) _timezone = InitTimeZone(); 9684 } 9685 9686 /// 9687 @safe unittest 9688 { 9689 import core.time : days, hours, seconds; 9690 import std.datetime.date : Date, DateTime; 9691 import std.datetime.timezone : SimpleTimeZone, UTC; 9692 9693 const dt = DateTime(2018, 1, 1, 10, 30, 0); 9694 // make a specific point in time in the UTC timezone 9695 auto st = SysTime(dt, UTC()); 9696 assert(st.year == 2018); 9697 assert(st.hour == 10); 9698 9699 // cast to convert 9700 assert(cast(DateTime) st == dt); 9701 assert(cast(Date) st == Date(2018, 1, 1)); 9702 9703 // make a specific point in time in the New York timezone 9704 const ny = SysTime(dt, 9705 new immutable SimpleTimeZone(-5.hours, "America/New_York") 9706 ); 9707 assert(ny != st); 9708 assert(ny.hour == 10); 9709 9710 // ISO standard time strings 9711 assert(st.toISOString() == "20180101T103000Z"); 9712 assert(st.toISOExtString() == "2018-01-01T10:30:00Z"); 9713 9714 // add two days and 30 seconds 9715 st += 2.days + 30.seconds; 9716 assert(st.toISOExtString() == "2018-01-03T10:30:30Z"); 9717 } 9718 9719 9720 /++ 9721 Converts from unix time (which uses midnight, January 1st, 1970 UTC as its 9722 epoch and seconds as its units) to "std time" (which uses midnight, 9723 January 1st, 1 A.D. UTC and hnsecs as its units). 9724 9725 The C standard does not specify the representation of time_t, so it is 9726 implementation defined. On POSIX systems, unix time is equivalent to 9727 time_t, but that's not necessarily true on other systems (e.g. it is 9728 not true for the Digital Mars C runtime). So, be careful when using unix 9729 time with C functions on non-POSIX systems. 9730 9731 "std time"'s epoch is based on the Proleptic Gregorian Calendar per ISO 9732 8601 and is what $(LREF SysTime) uses internally. However, holding the time 9733 as an integer in hnsecs since that epoch technically isn't actually part of 9734 the standard, much as it's based on it, so the name "std time" isn't 9735 particularly good, but there isn't an official name for it. C# uses "ticks" 9736 for the same thing, but they aren't actually clock ticks, and the term 9737 "ticks" $(I is) used for actual clock ticks for $(REF MonoTime, core,time), 9738 so it didn't make sense to use the term ticks here. So, for better or worse, 9739 std.datetime uses the term "std time" for this. 9740 9741 Params: 9742 unixTime = The unix time to convert. 9743 9744 See_Also: 9745 SysTime.fromUnixTime 9746 +/ 9747 long unixTimeToStdTime(long unixTime) @safe pure nothrow @nogc 9748 { 9749 return 621_355_968_000_000_000L + convert!("seconds", "hnsecs")(unixTime); 9750 } 9751 9752 /// 9753 @safe unittest 9754 { 9755 import std.datetime.date : DateTime; 9756 import std.datetime.timezone : UTC; 9757 9758 // Midnight, January 1st, 1970 9759 assert(unixTimeToStdTime(0) == 621_355_968_000_000_000L); 9760 assert(SysTime(unixTimeToStdTime(0)) == 9761 SysTime(DateTime(1970, 1, 1), UTC())); 9762 9763 assert(unixTimeToStdTime(int.max) == 642_830_804_470_000_000L); 9764 assert(SysTime(unixTimeToStdTime(int.max)) == 9765 SysTime(DateTime(2038, 1, 19, 3, 14, 7), UTC())); 9766 9767 assert(unixTimeToStdTime(-127_127) == 621_354_696_730_000_000L); 9768 assert(SysTime(unixTimeToStdTime(-127_127)) == 9769 SysTime(DateTime(1969, 12, 30, 12, 41, 13), UTC())); 9770 } 9771 9772 @safe unittest 9773 { 9774 // Midnight, January 2nd, 1970 9775 assert(unixTimeToStdTime(86_400) == 621_355_968_000_000_000L + 864_000_000_000L); 9776 // Midnight, December 31st, 1969 9777 assert(unixTimeToStdTime(-86_400) == 621_355_968_000_000_000L - 864_000_000_000L); 9778 9779 assert(unixTimeToStdTime(0) == (Date(1970, 1, 1) - Date(1, 1, 1)).total!"hnsecs"); 9780 assert(unixTimeToStdTime(0) == (DateTime(1970, 1, 1) - DateTime(1, 1, 1)).total!"hnsecs"); 9781 9782 foreach (dt; [DateTime(2010, 11, 1, 19, 5, 22), DateTime(1952, 7, 6, 2, 17, 9)]) 9783 assert(unixTimeToStdTime((dt - DateTime(1970, 1, 1)).total!"seconds") == (dt - DateTime.init).total!"hnsecs"); 9784 } 9785 9786 9787 /++ 9788 Converts std time (which uses midnight, January 1st, 1 A.D. UTC as its epoch 9789 and hnsecs as its units) to unix time (which uses midnight, January 1st, 9790 1970 UTC as its epoch and seconds as its units). 9791 9792 The C standard does not specify the representation of time_t, so it is 9793 implementation defined. On POSIX systems, unix time is equivalent to 9794 time_t, but that's not necessarily true on other systems (e.g. it is 9795 not true for the Digital Mars C runtime). So, be careful when using unix 9796 time with C functions on non-POSIX systems. 9797 9798 "std time"'s epoch is based on the Proleptic Gregorian Calendar per ISO 9799 8601 and is what $(LREF SysTime) uses internally. However, holding the time 9800 as an integer in hnsecs since that epoch technically isn't actually part of 9801 the standard, much as it's based on it, so the name "std time" isn't 9802 particularly good, but there isn't an official name for it. C# uses "ticks" 9803 for the same thing, but they aren't actually clock ticks, and the term 9804 "ticks" $(I is) used for actual clock ticks for $(REF MonoTime, core,time), 9805 so it didn't make sense to use the term ticks here. So, for better or worse, 9806 std.datetime uses the term "std time" for this. 9807 9808 By default, the return type is time_t (which is normally an alias for 9809 int on 32-bit systems and long on 64-bit systems), but if a different 9810 size is required than either int or long can be passed as a template 9811 argument to get the desired size. 9812 9813 If the return type is int, and the result can't fit in an int, then the 9814 closest value that can be held in 32 bits will be used (so `int.max` 9815 if it goes over and `int.min` if it goes under). However, no attempt 9816 is made to deal with integer overflow if the return type is long. 9817 9818 Params: 9819 T = The return type (int or long). It defaults to time_t, which is 9820 normally 32 bits on a 32-bit system and 64 bits on a 64-bit 9821 system. 9822 stdTime = The std time to convert. 9823 9824 Returns: 9825 A signed integer representing the unix time which is equivalent to 9826 the given std time. 9827 9828 See_Also: 9829 SysTime.toUnixTime 9830 +/ 9831 T stdTimeToUnixTime(T = time_t)(long stdTime) @safe pure nothrow 9832 if (is(T == int) || is(T == long)) 9833 { 9834 immutable unixTime = convert!("hnsecs", "seconds")(stdTime - 621_355_968_000_000_000L); 9835 9836 static assert(is(time_t == int) || is(time_t == long), 9837 "Currently, std.datetime only supports systems where time_t is int or long"); 9838 9839 static if (is(T == long)) 9840 return unixTime; 9841 else static if (is(T == int)) 9842 { 9843 if (unixTime > int.max) 9844 return int.max; 9845 return unixTime < int.min ? int.min : cast(int) unixTime; 9846 } 9847 else 9848 static assert(0, "Bug in template constraint. Only int and long allowed."); 9849 } 9850 9851 /// 9852 @safe unittest 9853 { 9854 // Midnight, January 1st, 1970 UTC 9855 assert(stdTimeToUnixTime(621_355_968_000_000_000L) == 0); 9856 9857 // 2038-01-19 03:14:07 UTC 9858 assert(stdTimeToUnixTime(642_830_804_470_000_000L) == int.max); 9859 } 9860 9861 @safe unittest 9862 { 9863 enum unixEpochAsStdTime = (Date(1970, 1, 1) - Date.init).total!"hnsecs"; 9864 9865 assert(stdTimeToUnixTime(unixEpochAsStdTime) == 0); // Midnight, January 1st, 1970 9866 assert(stdTimeToUnixTime(unixEpochAsStdTime + 864_000_000_000L) == 86_400); // Midnight, January 2nd, 1970 9867 assert(stdTimeToUnixTime(unixEpochAsStdTime - 864_000_000_000L) == -86_400); // Midnight, December 31st, 1969 9868 9869 assert(stdTimeToUnixTime((Date(1970, 1, 1) - Date(1, 1, 1)).total!"hnsecs") == 0); 9870 assert(stdTimeToUnixTime((DateTime(1970, 1, 1) - DateTime(1, 1, 1)).total!"hnsecs") == 0); 9871 9872 foreach (dt; [DateTime(2010, 11, 1, 19, 5, 22), DateTime(1952, 7, 6, 2, 17, 9)]) 9873 assert(stdTimeToUnixTime((dt - DateTime.init).total!"hnsecs") == (dt - DateTime(1970, 1, 1)).total!"seconds"); 9874 9875 enum max = convert!("seconds", "hnsecs")(int.max); 9876 enum min = convert!("seconds", "hnsecs")(int.min); 9877 enum one = convert!("seconds", "hnsecs")(1); 9878 9879 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + max) == int.max); 9880 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + max) == int.max); 9881 9882 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + max + one) == int.max + 1L); 9883 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + max + one) == int.max); 9884 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + max + 9_999_999) == int.max); 9885 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + max + 9_999_999) == int.max); 9886 9887 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + min) == int.min); 9888 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + min) == int.min); 9889 9890 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + min - one) == int.min - 1L); 9891 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + min - one) == int.min); 9892 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + min - 9_999_999) == int.min); 9893 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + min - 9_999_999) == int.min); 9894 } 9895 9896 9897 version (StdDdoc) 9898 { 9899 version (Windows) 9900 {} 9901 else 9902 { 9903 alias SYSTEMTIME = void*; 9904 alias FILETIME = void*; 9905 } 9906 9907 /++ 9908 $(BLUE This function is Windows-Only.) 9909 9910 Converts a `SYSTEMTIME` struct to a $(LREF SysTime). 9911 9912 Params: 9913 st = The `SYSTEMTIME` struct to convert. 9914 tz = The time zone that the time in the `SYSTEMTIME` struct is 9915 assumed to be (if the `SYSTEMTIME` was supplied by a Windows 9916 system call, the `SYSTEMTIME` will either be in local time 9917 or UTC, depending on the call). 9918 9919 Throws: 9920 $(REF DateTimeException,std,datetime,date) if the given 9921 `SYSTEMTIME` will not fit in a $(LREF SysTime), which is highly 9922 unlikely to happen given that `SysTime.max` is in 29,228 A.D. and 9923 the maximum `SYSTEMTIME` is in 30,827 A.D. 9924 +/ 9925 SysTime SYSTEMTIMEToSysTime(const scope SYSTEMTIME* st, immutable TimeZone tz = LocalTime()) @safe; 9926 9927 9928 /++ 9929 $(BLUE This function is Windows-Only.) 9930 9931 Converts a $(LREF SysTime) to a `SYSTEMTIME` struct. 9932 9933 The `SYSTEMTIME` which is returned will be set using the given 9934 $(LREF SysTime)'s time zone, so to get the `SYSTEMTIME` in 9935 UTC, set the $(LREF SysTime)'s time zone to UTC. 9936 9937 Params: 9938 sysTime = The $(LREF SysTime) to convert. 9939 9940 Throws: 9941 $(REF DateTimeException,std,datetime,date) if the given 9942 $(LREF SysTime) will not fit in a `SYSTEMTIME`. This will only 9943 happen if the $(LREF SysTime)'s date is prior to 1601 A.D. 9944 +/ 9945 SYSTEMTIME SysTimeToSYSTEMTIME(scope SysTime sysTime) @safe; 9946 9947 9948 /++ 9949 $(BLUE This function is Windows-Only.) 9950 9951 Converts a `FILETIME` struct to the number of hnsecs since midnight, 9952 January 1st, 1 A.D. 9953 9954 Params: 9955 ft = The `FILETIME` struct to convert. 9956 9957 Throws: 9958 $(REF DateTimeException,std,datetime,date) if the given 9959 `FILETIME` cannot be represented as the return value. 9960 +/ 9961 long FILETIMEToStdTime(scope const FILETIME* ft) @safe; 9962 9963 9964 /++ 9965 $(BLUE This function is Windows-Only.) 9966 9967 Converts a `FILETIME` struct to a $(LREF SysTime). 9968 9969 Params: 9970 ft = The `FILETIME` struct to convert. 9971 tz = The time zone that the $(LREF SysTime) will be in 9972 (`FILETIME`s are in UTC). 9973 9974 Throws: 9975 $(REF DateTimeException,std,datetime,date) if the given 9976 `FILETIME` will not fit in a $(LREF SysTime). 9977 +/ 9978 SysTime FILETIMEToSysTime(scope const FILETIME* ft, immutable TimeZone tz = LocalTime()) @safe; 9979 9980 9981 /++ 9982 $(BLUE This function is Windows-Only.) 9983 9984 Converts a number of hnsecs since midnight, January 1st, 1 A.D. to a 9985 `FILETIME` struct. 9986 9987 Params: 9988 stdTime = The number of hnsecs since midnight, January 1st, 1 A.D. 9989 UTC. 9990 9991 Throws: 9992 $(REF DateTimeException,std,datetime,date) if the given value will 9993 not fit in a `FILETIME`. 9994 +/ 9995 FILETIME stdTimeToFILETIME(long stdTime) @safe; 9996 9997 9998 /++ 9999 $(BLUE This function is Windows-Only.) 10000 10001 Converts a $(LREF SysTime) to a `FILETIME` struct. 10002 10003 `FILETIME`s are always in UTC. 10004 10005 Params: 10006 sysTime = The $(LREF SysTime) to convert. 10007 10008 Throws: 10009 $(REF DateTimeException,std,datetime,date) if the given 10010 $(LREF SysTime) will not fit in a `FILETIME`. 10011 +/ 10012 FILETIME SysTimeToFILETIME(scope SysTime sysTime) @safe; 10013 } 10014 else version (Windows) 10015 { 10016 SysTime SYSTEMTIMEToSysTime(const scope SYSTEMTIME* st, immutable TimeZone tz = LocalTime()) @safe 10017 { 10018 const max = SysTime.max; 10019 10020 static void throwLaterThanMax() 10021 { 10022 throw new DateTimeException("The given SYSTEMTIME is for a date greater than SysTime.max."); 10023 } 10024 10025 if (st.wYear > max.year) 10026 throwLaterThanMax(); 10027 else if (st.wYear == max.year) 10028 { 10029 if (st.wMonth > max.month) 10030 throwLaterThanMax(); 10031 else if (st.wMonth == max.month) 10032 { 10033 if (st.wDay > max.day) 10034 throwLaterThanMax(); 10035 else if (st.wDay == max.day) 10036 { 10037 if (st.wHour > max.hour) 10038 throwLaterThanMax(); 10039 else if (st.wHour == max.hour) 10040 { 10041 if (st.wMinute > max.minute) 10042 throwLaterThanMax(); 10043 else if (st.wMinute == max.minute) 10044 { 10045 if (st.wSecond > max.second) 10046 throwLaterThanMax(); 10047 else if (st.wSecond == max.second) 10048 { 10049 if (st.wMilliseconds > max.fracSecs.total!"msecs") 10050 throwLaterThanMax(); 10051 } 10052 } 10053 } 10054 } 10055 } 10056 } 10057 10058 auto dt = DateTime(st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); 10059 10060 import core.time : msecs; 10061 return SysTime(dt, msecs(st.wMilliseconds), tz); 10062 } 10063 10064 @system unittest 10065 { 10066 auto sysTime = Clock.currTime(UTC()); 10067 SYSTEMTIME st = void; 10068 GetSystemTime(&st); 10069 auto converted = SYSTEMTIMEToSysTime(&st, UTC()); 10070 import core.time : abs; 10071 assert(abs((converted - sysTime)) <= dur!"seconds"(2)); 10072 10073 static void testScope(scope SYSTEMTIME* st) @safe 10074 { 10075 auto result = SYSTEMTIMEToSysTime(st); 10076 } 10077 } 10078 10079 10080 SYSTEMTIME SysTimeToSYSTEMTIME(scope SysTime sysTime) @safe 10081 { 10082 immutable dt = cast(DateTime) sysTime; 10083 10084 if (dt.year < 1601) 10085 throw new DateTimeException("SYSTEMTIME cannot hold dates prior to the year 1601."); 10086 10087 SYSTEMTIME st; 10088 10089 st.wYear = dt.year; 10090 st.wMonth = dt.month; 10091 st.wDayOfWeek = dt.dayOfWeek; 10092 st.wDay = dt.day; 10093 st.wHour = dt.hour; 10094 st.wMinute = dt.minute; 10095 st.wSecond = dt.second; 10096 st.wMilliseconds = cast(ushort) sysTime.fracSecs.total!"msecs"; 10097 10098 return st; 10099 } 10100 10101 @system unittest 10102 { 10103 SYSTEMTIME st = void; 10104 GetSystemTime(&st); 10105 auto sysTime = SYSTEMTIMEToSysTime(&st, UTC()); 10106 10107 SYSTEMTIME result = SysTimeToSYSTEMTIME(sysTime); 10108 10109 assert(st.wYear == result.wYear); 10110 assert(st.wMonth == result.wMonth); 10111 assert(st.wDayOfWeek == result.wDayOfWeek); 10112 assert(st.wDay == result.wDay); 10113 assert(st.wHour == result.wHour); 10114 assert(st.wMinute == result.wMinute); 10115 assert(st.wSecond == result.wSecond); 10116 assert(st.wMilliseconds == result.wMilliseconds); 10117 10118 static void testScope(scope ref SysTime st) @safe 10119 { 10120 auto localResult = SysTimeToSYSTEMTIME(st); 10121 } 10122 } 10123 10124 private enum hnsecsFrom1601 = 504_911_232_000_000_000L; 10125 10126 long FILETIMEToStdTime(scope const FILETIME* ft) @safe 10127 { 10128 ULARGE_INTEGER ul; 10129 ul.HighPart = ft.dwHighDateTime; 10130 ul.LowPart = ft.dwLowDateTime; 10131 ulong tempHNSecs = ul.QuadPart; 10132 10133 if (tempHNSecs > long.max - hnsecsFrom1601) 10134 throw new DateTimeException("The given FILETIME cannot be represented as a stdTime value."); 10135 10136 return cast(long) tempHNSecs + hnsecsFrom1601; 10137 } 10138 10139 SysTime FILETIMEToSysTime(scope const FILETIME* ft, immutable TimeZone tz = LocalTime()) @safe 10140 { 10141 auto sysTime = SysTime(FILETIMEToStdTime(ft), UTC()); 10142 sysTime.timezone = tz; 10143 return sysTime; 10144 } 10145 10146 @system unittest 10147 { 10148 auto sysTime = Clock.currTime(UTC()); 10149 SYSTEMTIME st = void; 10150 GetSystemTime(&st); 10151 10152 FILETIME ft = void; 10153 SystemTimeToFileTime(&st, &ft); 10154 10155 auto converted = FILETIMEToSysTime(&ft); 10156 10157 import core.time : abs; 10158 assert(abs((converted - sysTime)) <= dur!"seconds"(2)); 10159 10160 static void testScope(scope FILETIME* ft) @safe 10161 { 10162 auto result = FILETIMEToSysTime(ft); 10163 } 10164 } 10165 10166 10167 FILETIME stdTimeToFILETIME(long stdTime) @safe 10168 { 10169 if (stdTime < hnsecsFrom1601) 10170 throw new DateTimeException("The given stdTime value cannot be represented as a FILETIME."); 10171 10172 ULARGE_INTEGER ul; 10173 ul.QuadPart = cast(ulong) stdTime - hnsecsFrom1601; 10174 10175 FILETIME ft; 10176 ft.dwHighDateTime = ul.HighPart; 10177 ft.dwLowDateTime = ul.LowPart; 10178 10179 return ft; 10180 } 10181 10182 FILETIME SysTimeToFILETIME(scope SysTime sysTime) @safe 10183 { 10184 return stdTimeToFILETIME(sysTime.stdTime); 10185 } 10186 10187 @system unittest 10188 { 10189 SYSTEMTIME st = void; 10190 GetSystemTime(&st); 10191 10192 FILETIME ft = void; 10193 SystemTimeToFileTime(&st, &ft); 10194 auto sysTime = FILETIMEToSysTime(&ft, UTC()); 10195 10196 FILETIME result = SysTimeToFILETIME(sysTime); 10197 10198 assert(ft.dwLowDateTime == result.dwLowDateTime); 10199 assert(ft.dwHighDateTime == result.dwHighDateTime); 10200 10201 static void testScope(scope ref SysTime st) @safe 10202 { 10203 auto local_result = SysTimeToFILETIME(st); 10204 } 10205 } 10206 } 10207 10208 10209 /++ 10210 Type representing the DOS file date/time format. 10211 +/ 10212 alias DosFileTime = uint; 10213 10214 /++ 10215 Converts from DOS file date/time to $(LREF SysTime). 10216 10217 Params: 10218 dft = The DOS file time to convert. 10219 tz = The time zone which the DOS file time is assumed to be in. 10220 10221 Throws: 10222 $(REF DateTimeException,std,datetime,date) if the `DosFileTime` is 10223 invalid. 10224 +/ 10225 SysTime DosFileTimeToSysTime(DosFileTime dft, immutable TimeZone tz = LocalTime()) @safe 10226 { 10227 uint dt = cast(uint) dft; 10228 10229 if (dt == 0) 10230 throw new DateTimeException("Invalid DosFileTime."); 10231 10232 int year = ((dt >> 25) & 0x7F) + 1980; 10233 int month = ((dt >> 21) & 0x0F); // 1 .. 12 10234 int dayOfMonth = ((dt >> 16) & 0x1F); // 1 .. 31 10235 int hour = (dt >> 11) & 0x1F; // 0 .. 23 10236 int minute = (dt >> 5) & 0x3F; // 0 .. 59 10237 int second = (dt << 1) & 0x3E; // 0 .. 58 (in 2 second increments) 10238 10239 try 10240 return SysTime(DateTime(year, month, dayOfMonth, hour, minute, second), tz); 10241 catch (DateTimeException dte) 10242 throw new DateTimeException("Invalid DosFileTime", __FILE__, __LINE__, dte); 10243 } 10244 10245 /// 10246 @safe unittest 10247 { 10248 import std.datetime.date : DateTime; 10249 10250 assert(DosFileTimeToSysTime(0b00000000001000010000000000000000) == SysTime(DateTime(1980, 1, 1, 0, 0, 0))); 10251 assert(DosFileTimeToSysTime(0b11111111100111111011111101111101) == SysTime(DateTime(2107, 12, 31, 23, 59, 58))); 10252 assert(DosFileTimeToSysTime(0x3E3F8456) == SysTime(DateTime(2011, 1, 31, 16, 34, 44))); 10253 } 10254 10255 @safe unittest 10256 { 10257 static void testScope(scope ref DosFileTime dft) @safe 10258 { 10259 auto result = DosFileTimeToSysTime(dft); 10260 } 10261 } 10262 10263 10264 /++ 10265 Converts from $(LREF SysTime) to DOS file date/time. 10266 10267 Params: 10268 sysTime = The $(LREF SysTime) to convert. 10269 10270 Throws: 10271 $(REF DateTimeException,std,datetime,date) if the given 10272 $(LREF SysTime) cannot be converted to a `DosFileTime`. 10273 +/ 10274 DosFileTime SysTimeToDosFileTime(scope SysTime sysTime) @safe 10275 { 10276 auto dateTime = cast(DateTime) sysTime; 10277 10278 if (dateTime.year < 1980) 10279 throw new DateTimeException("DOS File Times cannot hold dates prior to 1980."); 10280 10281 if (dateTime.year > 2107) 10282 throw new DateTimeException("DOS File Times cannot hold dates past 2107."); 10283 10284 uint retval = 0; 10285 retval = (dateTime.year - 1980) << 25; 10286 retval |= (dateTime.month & 0x0F) << 21; 10287 retval |= (dateTime.day & 0x1F) << 16; 10288 retval |= (dateTime.hour & 0x1F) << 11; 10289 retval |= (dateTime.minute & 0x3F) << 5; 10290 retval |= (dateTime.second >> 1) & 0x1F; 10291 10292 return cast(DosFileTime) retval; 10293 } 10294 10295 /// 10296 @safe unittest 10297 { 10298 import std.datetime.date : DateTime; 10299 10300 assert(SysTimeToDosFileTime(SysTime(DateTime(1980, 1, 1, 0, 0, 0))) == 0b00000000001000010000000000000000); 10301 assert(SysTimeToDosFileTime(SysTime(DateTime(2107, 12, 31, 23, 59, 58))) == 0b11111111100111111011111101111101); 10302 assert(SysTimeToDosFileTime(SysTime(DateTime(2011, 1, 31, 16, 34, 44))) == 0x3E3F8456); 10303 } 10304 10305 @safe unittest 10306 { 10307 static void testScope(scope ref SysTime st) @safe 10308 { 10309 auto result = SysTimeToDosFileTime(st); 10310 } 10311 } 10312 10313 10314 /++ 10315 The given array of `char` or random-access range of `char` or 10316 `ubyte` is expected to be in the format specified in 10317 $(HTTP tools.ietf.org/html/rfc5322, RFC 5322) section 3.3 with the 10318 grammar rule $(I date-time). It is the date-time format commonly used in 10319 internet messages such as e-mail and HTTP. The corresponding 10320 $(LREF SysTime) will be returned. 10321 10322 RFC 822 was the original spec (hence the function's name), whereas RFC 5322 10323 is the current spec. 10324 10325 The day of the week is ignored beyond verifying that it's a valid day of the 10326 week, as the day of the week can be inferred from the date. It is not 10327 checked whether the given day of the week matches the actual day of the week 10328 of the given date (though it is technically invalid per the spec if the 10329 day of the week doesn't match the actual day of the week of the given date). 10330 10331 If the time zone is `"-0000"` (or considered to be equivalent to 10332 `"-0000"` by section 4.3 of the spec), a 10333 $(REF SimpleTimeZone,std,datetime,timezone) with a utc offset of `0` is 10334 used rather than $(REF UTC,std,datetime,timezone), whereas `"+0000"` uses 10335 $(REF UTC,std,datetime,timezone). 10336 10337 Note that because $(LREF SysTime) does not currently support having a second 10338 value of 60 (as is sometimes done for leap seconds), if the date-time value 10339 does have a value of 60 for the seconds, it is treated as 59. 10340 10341 The one area in which this function violates RFC 5322 is that it accepts 10342 `"\n"` in folding whitespace in the place of `"\r\n"`, because the 10343 HTTP spec requires it. 10344 10345 Throws: 10346 $(REF DateTimeException,std,datetime,date) if the given string doesn't 10347 follow the grammar for a date-time field or if the resulting 10348 $(LREF SysTime) is invalid. 10349 +/ 10350 SysTime parseRFC822DateTime()(scope const char[] value) @safe 10351 { 10352 import std.string : representation; 10353 return parseRFC822DateTime(value.representation); 10354 } 10355 10356 /++ Ditto +/ 10357 SysTime parseRFC822DateTime(R)(scope R value) 10358 if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && 10359 (is(immutable ElementType!R == immutable char) || is(immutable ElementType!R == immutable ubyte))) 10360 { 10361 import std.algorithm.searching : find, all; 10362 import std.ascii : isDigit, isAlpha, isPrintable; 10363 import std.conv : to; 10364 import std.functional : not; 10365 import std.string : capitalize, format; 10366 import std.traits : EnumMembers, isArray; 10367 import std.typecons : Rebindable; 10368 10369 void stripAndCheckLen(R valueBefore, size_t minLen, size_t line = __LINE__) 10370 { 10371 value = _stripCFWS(valueBefore); 10372 if (value.length < minLen) 10373 throw new DateTimeException("date-time value too short", __FILE__, line); 10374 } 10375 stripAndCheckLen(value, "7Dec1200:00A".length); 10376 10377 static if (isArray!R && (is(ElementEncodingType!R == char) || is(ElementEncodingType!R == ubyte))) 10378 { 10379 static string sliceAsString(R str) @trusted 10380 { 10381 return cast(string) str; 10382 } 10383 } 10384 else 10385 { 10386 char[4] temp; 10387 char[] sliceAsString(R str) @trusted 10388 { 10389 size_t i = 0; 10390 foreach (c; str) 10391 temp[i++] = cast(char) c; 10392 return temp[0 .. str.length]; 10393 } 10394 } 10395 10396 // day-of-week 10397 if (isAlpha(value[0])) 10398 { 10399 auto dowStr = sliceAsString(value[0 .. 3]); 10400 switch (dowStr) 10401 { 10402 foreach (dow; EnumMembers!DayOfWeek) 10403 { 10404 enum dowC = capitalize(to!string(dow)); 10405 case dowC: 10406 goto afterDoW; 10407 } 10408 default: throw new DateTimeException(format("Invalid day-of-week: %s", dowStr)); 10409 } 10410 afterDoW: stripAndCheckLen(value[3 .. value.length], ",7Dec1200:00A".length); 10411 if (value[0] != ',') 10412 throw new DateTimeException("day-of-week missing comma"); 10413 stripAndCheckLen(value[1 .. value.length], "7Dec1200:00A".length); 10414 } 10415 10416 // day 10417 immutable digits = isDigit(value[1]) ? 2 : 1; 10418 immutable day = _convDigits!short(value[0 .. digits]); 10419 if (day == -1) 10420 throw new DateTimeException("Invalid day"); 10421 stripAndCheckLen(value[digits .. value.length], "Dec1200:00A".length); 10422 10423 // month 10424 Month month; 10425 { 10426 auto monStr = sliceAsString(value[0 .. 3]); 10427 switch (monStr) 10428 { 10429 foreach (mon; EnumMembers!Month) 10430 { 10431 enum monC = capitalize(to!string(mon)); 10432 case monC: 10433 { 10434 month = mon; 10435 goto afterMon; 10436 } 10437 } 10438 default: throw new DateTimeException(format("Invalid month: %s", monStr)); 10439 } 10440 afterMon: stripAndCheckLen(value[3 .. value.length], "1200:00A".length); 10441 } 10442 10443 // year 10444 auto found = value[2 .. value.length].find!(not!(isDigit))(); 10445 size_t yearLen = value.length - found.length; 10446 if (found.length == 0) 10447 throw new DateTimeException("Invalid year"); 10448 if (found[0] == ':') 10449 yearLen -= 2; 10450 auto year = _convDigits!short(value[0 .. yearLen]); 10451 if (year < 1900) 10452 { 10453 if (year == -1) 10454 throw new DateTimeException("Invalid year"); 10455 if (yearLen < 4) 10456 { 10457 if (yearLen == 3) 10458 year += 1900; 10459 else if (yearLen == 2) 10460 year += year < 50 ? 2000 : 1900; 10461 else 10462 throw new DateTimeException("Invalid year. Too few digits."); 10463 } 10464 else 10465 throw new DateTimeException("Invalid year. Cannot be earlier than 1900."); 10466 } 10467 stripAndCheckLen(value[yearLen .. value.length], "00:00A".length); 10468 10469 // hour 10470 immutable hour = _convDigits!short(value[0 .. 2]); 10471 stripAndCheckLen(value[2 .. value.length], ":00A".length); 10472 if (value[0] != ':') 10473 throw new DateTimeException("Invalid hour"); 10474 stripAndCheckLen(value[1 .. value.length], "00A".length); 10475 10476 // minute 10477 immutable minute = _convDigits!short(value[0 .. 2]); 10478 stripAndCheckLen(value[2 .. value.length], "A".length); 10479 10480 // second 10481 short second; 10482 if (value[0] == ':') 10483 { 10484 stripAndCheckLen(value[1 .. value.length], "00A".length); 10485 second = _convDigits!short(value[0 .. 2]); 10486 // this is just if/until SysTime is sorted out to fully support leap seconds 10487 if (second == 60) 10488 second = 59; 10489 stripAndCheckLen(value[2 .. value.length], "A".length); 10490 } 10491 10492 immutable(TimeZone) parseTZ(int sign) 10493 { 10494 if (value.length < 5) 10495 throw new DateTimeException("Invalid timezone"); 10496 immutable zoneHours = _convDigits!short(value[1 .. 3]); 10497 immutable zoneMinutes = _convDigits!short(value[3 .. 5]); 10498 if (zoneHours == -1 || zoneMinutes == -1 || zoneMinutes > 59) 10499 throw new DateTimeException("Invalid timezone"); 10500 value = value[5 .. value.length]; 10501 immutable utcOffset = (dur!"hours"(zoneHours) + dur!"minutes"(zoneMinutes)) * sign; 10502 if (utcOffset == Duration.zero) 10503 { 10504 return sign == 1 ? cast(immutable(TimeZone))UTC() 10505 : cast(immutable(TimeZone))new immutable SimpleTimeZone(Duration.zero); 10506 } 10507 return new immutable(SimpleTimeZone)(utcOffset); 10508 } 10509 10510 // zone 10511 Rebindable!(immutable TimeZone) tz; 10512 if (value[0] == '-') 10513 tz = parseTZ(-1); 10514 else if (value[0] == '+') 10515 tz = parseTZ(1); 10516 else 10517 { 10518 // obs-zone 10519 immutable tzLen = value.length - find(value, ' ', '\t', '(')[0].length; 10520 switch (sliceAsString(value[0 .. tzLen <= 4 ? tzLen : 4])) 10521 { 10522 case "UT": case "GMT": tz = UTC(); break; 10523 case "EST": tz = new immutable SimpleTimeZone(dur!"hours"(-5)); break; 10524 case "EDT": tz = new immutable SimpleTimeZone(dur!"hours"(-4)); break; 10525 case "CST": tz = new immutable SimpleTimeZone(dur!"hours"(-6)); break; 10526 case "CDT": tz = new immutable SimpleTimeZone(dur!"hours"(-5)); break; 10527 case "MST": tz = new immutable SimpleTimeZone(dur!"hours"(-7)); break; 10528 case "MDT": tz = new immutable SimpleTimeZone(dur!"hours"(-6)); break; 10529 case "PST": tz = new immutable SimpleTimeZone(dur!"hours"(-8)); break; 10530 case "PDT": tz = new immutable SimpleTimeZone(dur!"hours"(-7)); break; 10531 case "J": case "j": throw new DateTimeException("Invalid timezone"); 10532 default: 10533 { 10534 if (all!(isAlpha)(value[0 .. tzLen])) 10535 { 10536 tz = new immutable SimpleTimeZone(Duration.zero); 10537 break; 10538 } 10539 throw new DateTimeException("Invalid timezone"); 10540 } 10541 } 10542 value = value[tzLen .. value.length]; 10543 } 10544 10545 // This is kind of arbitrary. Technically, nothing but CFWS is legal past 10546 // the end of the timezone, but we don't want to be picky about that in a 10547 // function that's just parsing rather than validating. So, the idea here is 10548 // that if the next character is printable (and not part of CFWS), then it 10549 // might be part of the timezone and thus affect what the timezone was 10550 // supposed to be, so we'll throw, but otherwise, we'll just ignore it. 10551 if (!value.empty && isPrintable(value[0]) && value[0] != ' ' && value[0] != '(') 10552 throw new DateTimeException("Invalid timezone"); 10553 10554 try 10555 return SysTime(DateTime(year, month, day, hour, minute, second), tz); 10556 catch (DateTimeException dte) 10557 throw new DateTimeException("date-time format is correct, but the resulting SysTime is invalid.", dte); 10558 } 10559 10560 /// 10561 @safe unittest 10562 { 10563 import core.time : hours; 10564 import std.datetime.date : DateTime, DateTimeException; 10565 import std.datetime.timezone : SimpleTimeZone, UTC; 10566 import std.exception : assertThrown; 10567 10568 auto tz = new immutable SimpleTimeZone(hours(-8)); 10569 assert(parseRFC822DateTime("Sat, 6 Jan 1990 12:14:19 -0800") == 10570 SysTime(DateTime(1990, 1, 6, 12, 14, 19), tz)); 10571 10572 assert(parseRFC822DateTime("9 Jul 2002 13:11 +0000") == 10573 SysTime(DateTime(2002, 7, 9, 13, 11, 0), UTC())); 10574 10575 auto badStr = "29 Feb 2001 12:17:16 +0200"; 10576 assertThrown!DateTimeException(parseRFC822DateTime(badStr)); 10577 } 10578 10579 version (StdUnittest) private void testParse822(alias cr)(string str, SysTime expected, size_t line = __LINE__) 10580 { 10581 import std.format : format; 10582 auto value = cr(str); 10583 auto result = parseRFC822DateTime(value); 10584 if (result != expected) 10585 throw new AssertError(format("wrong result. expected [%s], actual[%s]", expected, result), __FILE__, line); 10586 } 10587 10588 version (StdUnittest) private void testBadParse822(alias cr)(string str, size_t line = __LINE__) 10589 { 10590 try 10591 parseRFC822DateTime(cr(str)); 10592 catch (DateTimeException) 10593 return; 10594 throw new AssertError("No DateTimeException was thrown", __FILE__, line); 10595 } 10596 10597 @system unittest 10598 { 10599 import core.time; 10600 import std.algorithm.iteration : filter, map; 10601 import std.algorithm.searching : canFind; 10602 import std.array : array; 10603 import std.ascii : letters; 10604 import std.format : format; 10605 import std.meta : AliasSeq; 10606 import std.range : chain, iota, take; 10607 import std.stdio : writefln, writeln; 10608 import std.string : representation; 10609 10610 static struct Rand3Letters 10611 { 10612 enum empty = false; 10613 @property auto front() { return _mon; } 10614 void popFront() 10615 { 10616 import std.exception : assumeUnique; 10617 import std.random : rndGen; 10618 _mon = rndGen.map!(a => letters[a % letters.length])().take(3).array().assumeUnique(); 10619 } 10620 string _mon; 10621 static auto start() { Rand3Letters retval; retval.popFront(); return retval; } 10622 } 10623 10624 static foreach (cr; AliasSeq!(function(string a){return cast(char[]) a;}, 10625 function(string a){return cast(ubyte[]) a;}, 10626 function(string a){return a;}, 10627 function(string a){return map!(b => cast(char) b)(a.representation);})) 10628 {(){ // workaround slow optimizations for large functions 10629 // https://issues.dlang.org/show_bug.cgi?id=2396 10630 scope(failure) writeln(typeof(cr).stringof); 10631 alias test = testParse822!cr; 10632 alias testBad = testBadParse822!cr; 10633 10634 immutable std1 = DateTime(2012, 12, 21, 13, 14, 15); 10635 immutable std2 = DateTime(2012, 12, 21, 13, 14, 0); 10636 immutable dst1 = DateTime(1976, 7, 4, 5, 4, 22); 10637 immutable dst2 = DateTime(1976, 7, 4, 5, 4, 0); 10638 10639 test("21 Dec 2012 13:14:15 +0000", SysTime(std1, UTC())); 10640 test("21 Dec 2012 13:14 +0000", SysTime(std2, UTC())); 10641 test("Fri, 21 Dec 2012 13:14 +0000", SysTime(std2, UTC())); 10642 test("Fri, 21 Dec 2012 13:14:15 +0000", SysTime(std1, UTC())); 10643 10644 test("04 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC())); 10645 test("04 Jul 1976 05:04 +0000", SysTime(dst2, UTC())); 10646 test("Sun, 04 Jul 1976 05:04 +0000", SysTime(dst2, UTC())); 10647 test("Sun, 04 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC())); 10648 10649 test("4 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC())); 10650 test("4 Jul 1976 05:04 +0000", SysTime(dst2, UTC())); 10651 test("Sun, 4 Jul 1976 05:04 +0000", SysTime(dst2, UTC())); 10652 test("Sun, 4 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC())); 10653 10654 auto badTZ = new immutable SimpleTimeZone(Duration.zero); 10655 test("21 Dec 2012 13:14:15 -0000", SysTime(std1, badTZ)); 10656 test("21 Dec 2012 13:14 -0000", SysTime(std2, badTZ)); 10657 test("Fri, 21 Dec 2012 13:14 -0000", SysTime(std2, badTZ)); 10658 test("Fri, 21 Dec 2012 13:14:15 -0000", SysTime(std1, badTZ)); 10659 10660 test("04 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ)); 10661 test("04 Jul 1976 05:04 -0000", SysTime(dst2, badTZ)); 10662 test("Sun, 04 Jul 1976 05:04 -0000", SysTime(dst2, badTZ)); 10663 test("Sun, 04 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ)); 10664 10665 test("4 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ)); 10666 test("4 Jul 1976 05:04 -0000", SysTime(dst2, badTZ)); 10667 test("Sun, 4 Jul 1976 05:04 -0000", SysTime(dst2, badTZ)); 10668 test("Sun, 4 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ)); 10669 10670 auto pst = new immutable SimpleTimeZone(dur!"hours"(-8)); 10671 auto pdt = new immutable SimpleTimeZone(dur!"hours"(-7)); 10672 test("21 Dec 2012 13:14:15 -0800", SysTime(std1, pst)); 10673 test("21 Dec 2012 13:14 -0800", SysTime(std2, pst)); 10674 test("Fri, 21 Dec 2012 13:14 -0800", SysTime(std2, pst)); 10675 test("Fri, 21 Dec 2012 13:14:15 -0800", SysTime(std1, pst)); 10676 10677 test("04 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt)); 10678 test("04 Jul 1976 05:04 -0700", SysTime(dst2, pdt)); 10679 test("Sun, 04 Jul 1976 05:04 -0700", SysTime(dst2, pdt)); 10680 test("Sun, 04 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt)); 10681 10682 test("4 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt)); 10683 test("4 Jul 1976 05:04 -0700", SysTime(dst2, pdt)); 10684 test("Sun, 4 Jul 1976 05:04 -0700", SysTime(dst2, pdt)); 10685 test("Sun, 4 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt)); 10686 10687 auto cet = new immutable SimpleTimeZone(dur!"hours"(1)); 10688 auto cest = new immutable SimpleTimeZone(dur!"hours"(2)); 10689 test("21 Dec 2012 13:14:15 +0100", SysTime(std1, cet)); 10690 test("21 Dec 2012 13:14 +0100", SysTime(std2, cet)); 10691 test("Fri, 21 Dec 2012 13:14 +0100", SysTime(std2, cet)); 10692 test("Fri, 21 Dec 2012 13:14:15 +0100", SysTime(std1, cet)); 10693 10694 test("04 Jul 1976 05:04:22 +0200", SysTime(dst1, cest)); 10695 test("04 Jul 1976 05:04 +0200", SysTime(dst2, cest)); 10696 test("Sun, 04 Jul 1976 05:04 +0200", SysTime(dst2, cest)); 10697 test("Sun, 04 Jul 1976 05:04:22 +0200", SysTime(dst1, cest)); 10698 10699 test("4 Jul 1976 05:04:22 +0200", SysTime(dst1, cest)); 10700 test("4 Jul 1976 05:04 +0200", SysTime(dst2, cest)); 10701 test("Sun, 4 Jul 1976 05:04 +0200", SysTime(dst2, cest)); 10702 test("Sun, 4 Jul 1976 05:04:22 +0200", SysTime(dst1, cest)); 10703 10704 // dst and std times are switched in the Southern Hemisphere which is why the 10705 // time zone names and DateTime variables don't match. 10706 auto cstStd = new immutable SimpleTimeZone(dur!"hours"(9) + dur!"minutes"(30)); 10707 auto cstDST = new immutable SimpleTimeZone(dur!"hours"(10) + dur!"minutes"(30)); 10708 test("21 Dec 2012 13:14:15 +1030", SysTime(std1, cstDST)); 10709 test("21 Dec 2012 13:14 +1030", SysTime(std2, cstDST)); 10710 test("Fri, 21 Dec 2012 13:14 +1030", SysTime(std2, cstDST)); 10711 test("Fri, 21 Dec 2012 13:14:15 +1030", SysTime(std1, cstDST)); 10712 10713 test("04 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 10714 test("04 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 10715 test("Sun, 04 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 10716 test("Sun, 04 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 10717 10718 test("4 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 10719 test("4 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 10720 test("Sun, 4 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 10721 test("Sun, 4 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 10722 10723 foreach (int i, mon; _monthNames) 10724 { 10725 test(format("17 %s 2012 00:05:02 +0000", mon), SysTime(DateTime(2012, i + 1, 17, 0, 5, 2), UTC())); 10726 test(format("17 %s 2012 00:05 +0000", mon), SysTime(DateTime(2012, i + 1, 17, 0, 5, 0), UTC())); 10727 } 10728 10729 import std.uni : toLower, toUpper; 10730 foreach (mon; chain(_monthNames[].map!(a => toLower(a))(), 10731 _monthNames[].map!(a => toUpper(a))(), 10732 ["Jam", "Jen", "Fec", "Fdb", "Mas", "Mbr", "Aps", "Aqr", "Mai", "Miy", 10733 "Jum", "Jbn", "Jup", "Jal", "Aur", "Apg", "Sem", "Sap", "Ocm", "Odt", 10734 "Nom", "Nav", "Dem", "Dac"], 10735 Rand3Letters.start().filter!(a => !_monthNames[].canFind(a)).take(20))) 10736 { 10737 scope(failure) writefln("Month: %s", mon); 10738 testBad(format("17 %s 2012 00:05:02 +0000", mon)); 10739 testBad(format("17 %s 2012 00:05 +0000", mon)); 10740 } 10741 10742 immutable string[7] daysOfWeekNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; 10743 10744 { 10745 auto start = SysTime(DateTime(2012, 11, 11, 9, 42, 0), UTC()); 10746 int day = 11; 10747 10748 foreach (int i, dow; daysOfWeekNames) 10749 { 10750 auto curr = start + dur!"days"(i); 10751 test(format("%s, %s Nov 2012 09:42:00 +0000", dow, day), curr); 10752 test(format("%s, %s Nov 2012 09:42 +0000", dow, day++), curr); 10753 10754 // Whether the day of the week matches the date is ignored. 10755 test(format("%s, 11 Nov 2012 09:42:00 +0000", dow), start); 10756 test(format("%s, 11 Nov 2012 09:42 +0000", dow), start); 10757 } 10758 } 10759 10760 foreach (dow; chain(daysOfWeekNames[].map!(a => toLower(a))(), 10761 daysOfWeekNames[].map!(a => toUpper(a))(), 10762 ["Sum", "Spn", "Mom", "Man", "Tuf", "Tae", "Wem", "Wdd", "The", "Tur", 10763 "Fro", "Fai", "San", "Sut"], 10764 Rand3Letters.start().filter!(a => !daysOfWeekNames[].canFind(a)).take(20))) 10765 { 10766 scope(failure) writefln("Day of Week: %s", dow); 10767 testBad(format("%s, 11 Nov 2012 09:42:00 +0000", dow)); 10768 testBad(format("%s, 11 Nov 2012 09:42 +0000", dow)); 10769 } 10770 10771 testBad("31 Dec 1899 23:59:59 +0000"); 10772 test("01 Jan 1900 00:00:00 +0000", SysTime(Date(1900, 1, 1), UTC())); 10773 test("01 Jan 1900 00:00:00 -0000", SysTime(Date(1900, 1, 1), 10774 new immutable SimpleTimeZone(Duration.zero))); 10775 test("01 Jan 1900 00:00:00 -0700", SysTime(Date(1900, 1, 1), 10776 new immutable SimpleTimeZone(dur!"hours"(-7)))); 10777 10778 { 10779 auto st1 = SysTime(Date(1900, 1, 1), UTC()); 10780 auto st2 = SysTime(Date(1900, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-11))); 10781 foreach (i; 1900 .. 2102) 10782 { 10783 test(format("1 Jan %05d 00:00 +0000", i), st1); 10784 test(format("1 Jan %05d 00:00 -1100", i), st2); 10785 st1.add!"years"(1); 10786 st2.add!"years"(1); 10787 } 10788 st1.year = 9998; 10789 st2.year = 9998; 10790 foreach (i; 9998 .. 11_002) 10791 { 10792 test(format("1 Jan %05d 00:00 +0000", i), st1); 10793 test(format("1 Jan %05d 00:00 -1100", i), st2); 10794 st1.add!"years"(1); 10795 st2.add!"years"(1); 10796 } 10797 } 10798 10799 testBad("12 Feb 1907 23:17:09 0000"); 10800 testBad("12 Feb 1907 23:17:09 +000"); 10801 testBad("12 Feb 1907 23:17:09 -000"); 10802 testBad("12 Feb 1907 23:17:09 +00000"); 10803 testBad("12 Feb 1907 23:17:09 -00000"); 10804 testBad("12 Feb 1907 23:17:09 +A"); 10805 testBad("12 Feb 1907 23:17:09 +PST"); 10806 testBad("12 Feb 1907 23:17:09 -A"); 10807 testBad("12 Feb 1907 23:17:09 -PST"); 10808 10809 // test trailing stuff that gets ignored 10810 { 10811 foreach (c; chain(iota(0, 33), ['('], iota(127, ubyte.max + 1))) 10812 { 10813 scope(failure) writefln("c: %d", c); 10814 test(format("21 Dec 2012 13:14:15 +0000%c", cast(char) c), SysTime(std1, UTC())); 10815 test(format("21 Dec 2012 13:14:15 +0000%c ", cast(char) c), SysTime(std1, UTC())); 10816 test(format("21 Dec 2012 13:14:15 +0000%chello", cast(char) c), SysTime(std1, UTC())); 10817 } 10818 } 10819 10820 // test trailing stuff that doesn't get ignored 10821 { 10822 foreach (c; chain(iota(33, '('), iota('(' + 1, 127))) 10823 { 10824 scope(failure) writefln("c: %d", c); 10825 testBad(format("21 Dec 2012 13:14:15 +0000%c", cast(char) c)); 10826 testBad(format("21 Dec 2012 13:14:15 +0000%c ", cast(char) c)); 10827 testBad(format("21 Dec 2012 13:14:15 +0000%chello", cast(char) c)); 10828 } 10829 } 10830 10831 testBad("32 Jan 2012 12:13:14 -0800"); 10832 testBad("31 Jan 2012 24:13:14 -0800"); 10833 testBad("31 Jan 2012 12:60:14 -0800"); 10834 testBad("31 Jan 2012 12:13:61 -0800"); 10835 testBad("31 Jan 2012 12:13:14 -0860"); 10836 test("31 Jan 2012 12:13:14 -0859", 10837 SysTime(DateTime(2012, 1, 31, 12, 13, 14), 10838 new immutable SimpleTimeZone(dur!"hours"(-8) + dur!"minutes"(-59)))); 10839 10840 // leap-seconds 10841 test("21 Dec 2012 15:59:60 -0800", SysTime(DateTime(2012, 12, 21, 15, 59, 59), pst)); 10842 10843 // FWS 10844 test("Sun,4 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 10845 test("Sun,4 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 10846 test("Sun,4 Jul 1976 05:04 +0930 (foo)", SysTime(dst2, cstStd)); 10847 test("Sun,4 Jul 1976 05:04:22 +0930 (foo)", SysTime(dst1, cstStd)); 10848 test("Sun,4 \r\n Jul \r\n 1976 \r\n 05:04 \r\n +0930 \r\n (foo)", SysTime(dst2, cstStd)); 10849 test("Sun,4 \r\n Jul \r\n 1976 \r\n 05:04:22 \r\n +0930 \r\n (foo)", SysTime(dst1, cstStd)); 10850 10851 auto str = "01 Jan 2012 12:13:14 -0800 "; 10852 test(str, SysTime(DateTime(2012, 1, 1, 12, 13, 14), new immutable SimpleTimeZone(hours(-8)))); 10853 foreach (i; 0 .. str.length) 10854 { 10855 auto currStr = str.dup; 10856 currStr[i] = 'x'; 10857 scope(failure) writefln("failed: %s", currStr); 10858 testBad(cast(string) currStr); 10859 } 10860 foreach (i; 2 .. str.length) 10861 { 10862 auto currStr = str[0 .. $ - i]; 10863 scope(failure) writefln("failed: %s", currStr); 10864 testBad(cast(string) currStr); 10865 testBad((cast(string) currStr) ~ " "); 10866 } 10867 }();} 10868 10869 static void testScope(scope ref string str) @safe 10870 { 10871 auto result = parseRFC822DateTime(str); 10872 } 10873 } 10874 10875 // Obsolete Format per section 4.3 of RFC 5322. 10876 @system unittest 10877 { 10878 import std.algorithm.iteration : filter, map; 10879 import std.ascii : letters; 10880 import std.exception : collectExceptionMsg; 10881 import std.format : format; 10882 import std.meta : AliasSeq; 10883 import std.range : chain, iota; 10884 import std.stdio : writefln, writeln; 10885 import std.string : representation; 10886 10887 auto std1 = SysTime(DateTime(2012, 12, 21, 13, 14, 15), UTC()); 10888 auto std2 = SysTime(DateTime(2012, 12, 21, 13, 14, 0), UTC()); 10889 auto std3 = SysTime(DateTime(1912, 12, 21, 13, 14, 15), UTC()); 10890 auto std4 = SysTime(DateTime(1912, 12, 21, 13, 14, 0), UTC()); 10891 auto dst1 = SysTime(DateTime(1976, 7, 4, 5, 4, 22), UTC()); 10892 auto dst2 = SysTime(DateTime(1976, 7, 4, 5, 4, 0), UTC()); 10893 auto tooLate1 = SysTime(Date(10_000, 1, 1), UTC()); 10894 auto tooLate2 = SysTime(DateTime(12_007, 12, 31, 12, 22, 19), UTC()); 10895 10896 static foreach (cr; AliasSeq!(function(string a){return cast(char[]) a;}, 10897 function(string a){return cast(ubyte[]) a;}, 10898 function(string a){return a;}, 10899 function(string a){return map!(b => cast(char) b)(a.representation);})) 10900 {(){ // workaround slow optimizations for large functions 10901 // https://issues.dlang.org/show_bug.cgi?id=2396 10902 scope(failure) writeln(typeof(cr).stringof); 10903 alias test = testParse822!cr; 10904 { 10905 auto list = ["", " ", " \r\n\t", "\t\r\n (hello world( frien(dog)) silly \r\n ) \t\t \r\n ()", 10906 " \n ", "\t\n\t", " \n\t (foo) \n (bar) \r\n (baz) \n "]; 10907 10908 foreach (i, cfws; list) 10909 { 10910 scope(failure) writefln("i: %s", i); 10911 10912 test(format("%1$s21%1$sDec%1$s2012%1$s13:14:15%1$s+0000%1$s", cfws), std1); 10913 test(format("%1$s21%1$sDec%1$s2012%1$s13:14%1$s+0000%1$s", cfws), std2); 10914 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s2012%1$s13:14%1$s+0000%1$s", cfws), std2); 10915 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s2012%1$s13:14:15%1$s+0000%1$s", cfws), std1); 10916 10917 test(format("%1$s04%1$sJul%1$s1976%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10918 test(format("%1$s04%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2); 10919 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2); 10920 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s1976%1$s05:04:22 +0000%1$s", cfws), dst1); 10921 10922 test(format("%1$s4%1$sJul%1$s1976%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10923 test(format("%1$s4%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2); 10924 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2); 10925 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s1976%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10926 10927 test(format("%1$s21%1$sDec%1$s12%1$s13:14:15%1$s+0000%1$s", cfws), std1); 10928 test(format("%1$s21%1$sDec%1$s12%1$s13:14%1$s+0000%1$s", cfws), std2); 10929 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s12%1$s13:14%1$s+0000%1$s", cfws), std2); 10930 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s12%1$s13:14:15%1$s+0000%1$s", cfws), std1); 10931 10932 test(format("%1$s04%1$sJul%1$s76%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10933 test(format("%1$s04%1$sJul%1$s76%1$s05:04%1$s+0000%1$s", cfws), dst2); 10934 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s76%1$s05:04%1$s+0000%1$s", cfws), dst2); 10935 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s76%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10936 10937 test(format("%1$s4%1$sJul%1$s76 05:04:22%1$s+0000%1$s", cfws), dst1); 10938 test(format("%1$s4%1$sJul%1$s76 05:04%1$s+0000%1$s", cfws), dst2); 10939 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s76%1$s05:04%1$s+0000%1$s", cfws), dst2); 10940 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s76%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10941 10942 test(format("%1$s21%1$sDec%1$s012%1$s13:14:15%1$s+0000%1$s", cfws), std3); 10943 test(format("%1$s21%1$sDec%1$s012%1$s13:14%1$s+0000%1$s", cfws), std4); 10944 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s012%1$s13:14%1$s+0000%1$s", cfws), std4); 10945 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s012%1$s13:14:15%1$s+0000%1$s", cfws), std3); 10946 10947 test(format("%1$s04%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10948 test(format("%1$s04%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2); 10949 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2); 10950 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10951 10952 test(format("%1$s4%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10953 test(format("%1$s4%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2); 10954 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2); 10955 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10956 10957 test(format("%1$s1%1$sJan%1$s10000%1$s00:00:00%1$s+0000%1$s", cfws), tooLate1); 10958 test(format("%1$s31%1$sDec%1$s12007%1$s12:22:19%1$s+0000%1$s", cfws), tooLate2); 10959 test(format("%1$sSat%1$s,%1$s1%1$sJan%1$s10000%1$s00:00:00%1$s+0000%1$s", cfws), tooLate1); 10960 test(format("%1$sSun%1$s,%1$s31%1$sDec%1$s12007%1$s12:22:19%1$s+0000%1$s", cfws), tooLate2); 10961 } 10962 } 10963 10964 // test years of 1, 2, and 3 digits. 10965 { 10966 auto st1 = SysTime(Date(2000, 1, 1), UTC()); 10967 auto st2 = SysTime(Date(2000, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-12))); 10968 foreach (i; 0 .. 50) 10969 { 10970 test(format("1 Jan %02d 00:00 GMT", i), st1); 10971 test(format("1 Jan %02d 00:00 -1200", i), st2); 10972 st1.add!"years"(1); 10973 st2.add!"years"(1); 10974 } 10975 } 10976 10977 { 10978 auto st1 = SysTime(Date(1950, 1, 1), UTC()); 10979 auto st2 = SysTime(Date(1950, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-12))); 10980 foreach (i; 50 .. 100) 10981 { 10982 test(format("1 Jan %02d 00:00 GMT", i), st1); 10983 test(format("1 Jan %02d 00:00 -1200", i), st2); 10984 st1.add!"years"(1); 10985 st2.add!"years"(1); 10986 } 10987 } 10988 10989 { 10990 auto st1 = SysTime(Date(1900, 1, 1), UTC()); 10991 auto st2 = SysTime(Date(1900, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-11))); 10992 foreach (i; 0 .. 1000) 10993 { 10994 test(format("1 Jan %03d 00:00 GMT", i), st1); 10995 test(format("1 Jan %03d 00:00 -1100", i), st2); 10996 st1.add!"years"(1); 10997 st2.add!"years"(1); 10998 } 10999 } 11000 11001 foreach (i; 0 .. 10) 11002 { 11003 auto str1 = cr(format("1 Jan %d 00:00 GMT", i)); 11004 auto str2 = cr(format("1 Jan %d 00:00 -1200", i)); 11005 assertThrown!DateTimeException(parseRFC822DateTime(str1)); 11006 assertThrown!DateTimeException(parseRFC822DateTime(str1)); 11007 } 11008 11009 // test time zones 11010 { 11011 auto dt = DateTime(1982, 5, 3, 12, 22, 4); 11012 test("Wed, 03 May 1982 12:22:04 UT", SysTime(dt, UTC())); 11013 test("Wed, 03 May 1982 12:22:04 GMT", SysTime(dt, UTC())); 11014 test("Wed, 03 May 1982 12:22:04 EST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-5)))); 11015 test("Wed, 03 May 1982 12:22:04 EDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-4)))); 11016 test("Wed, 03 May 1982 12:22:04 CST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-6)))); 11017 test("Wed, 03 May 1982 12:22:04 CDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-5)))); 11018 test("Wed, 03 May 1982 12:22:04 MST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-7)))); 11019 test("Wed, 03 May 1982 12:22:04 MDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-6)))); 11020 test("Wed, 03 May 1982 12:22:04 PST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-8)))); 11021 test("Wed, 03 May 1982 12:22:04 PDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-7)))); 11022 11023 auto badTZ = new immutable SimpleTimeZone(Duration.zero); 11024 foreach (dchar c; filter!(a => a != 'j' && a != 'J')(letters)) 11025 { 11026 scope(failure) writefln("c: %s", c); 11027 test(format("Wed, 03 May 1982 12:22:04 %s", c), SysTime(dt, badTZ)); 11028 test(format("Wed, 03 May 1982 12:22:04%s", c), SysTime(dt, badTZ)); 11029 } 11030 11031 foreach (dchar c; ['j', 'J']) 11032 { 11033 scope(failure) writefln("c: %s", c); 11034 assertThrown!DateTimeException(parseRFC822DateTime(cr(format("Wed, 03 May 1982 12:22:04 %s", c)))); 11035 assertThrown!DateTimeException(parseRFC822DateTime(cr(format("Wed, 03 May 1982 12:22:04%s", c)))); 11036 } 11037 11038 foreach (string s; ["AAA", "GQW", "DDT", "PDA", "GT", "GM"]) 11039 { 11040 scope(failure) writefln("s: %s", s); 11041 test(format("Wed, 03 May 1982 12:22:04 %s", s), SysTime(dt, badTZ)); 11042 } 11043 11044 // test trailing stuff that gets ignored 11045 { 11046 foreach (c; chain(iota(0, 33), ['('], iota(127, ubyte.max + 1))) 11047 { 11048 scope(failure) writefln("c: %d", c); 11049 test(format("21Dec1213:14:15+0000%c", cast(char) c), std1); 11050 test(format("21Dec1213:14:15+0000%c ", cast(char) c), std1); 11051 test(format("21Dec1213:14:15+0000%chello", cast(char) c), std1); 11052 } 11053 } 11054 11055 // test trailing stuff that doesn't get ignored 11056 { 11057 foreach (c; chain(iota(33, '('), iota('(' + 1, 127))) 11058 { 11059 scope(failure) writefln("c: %d", 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%c ", cast(char) c)))); 11064 assertThrown!DateTimeException( 11065 parseRFC822DateTime(cr(format("21Dec1213:14:15+0000%chello", cast(char) c)))); 11066 } 11067 } 11068 } 11069 11070 // test that the checks for minimum length work correctly and avoid 11071 // any RangeErrors. 11072 test("7Dec1200:00A", SysTime(DateTime(2012, 12, 7, 0, 0, 0), 11073 new immutable SimpleTimeZone(Duration.zero))); 11074 test("Fri,7Dec1200:00A", SysTime(DateTime(2012, 12, 7, 0, 0, 0), 11075 new immutable SimpleTimeZone(Duration.zero))); 11076 test("7Dec1200:00:00A", SysTime(DateTime(2012, 12, 7, 0, 0, 0), 11077 new immutable SimpleTimeZone(Duration.zero))); 11078 test("Fri,7Dec1200:00:00A", SysTime(DateTime(2012, 12, 7, 0, 0, 0), 11079 new immutable SimpleTimeZone(Duration.zero))); 11080 11081 auto tooShortMsg = collectExceptionMsg!DateTimeException(parseRFC822DateTime("")); 11082 foreach (str; ["Fri,7Dec1200:00:00", "7Dec1200:00:00"]) 11083 { 11084 foreach (i; 0 .. str.length) 11085 { 11086 auto value = str[0 .. $ - i]; 11087 scope(failure) writeln(value); 11088 assert(collectExceptionMsg!DateTimeException(parseRFC822DateTime(value)) == tooShortMsg); 11089 } 11090 } 11091 }();} 11092 } 11093 11094 11095 private: 11096 11097 /+ 11098 Returns the given hnsecs as an ISO string of fractional seconds. 11099 +/ 11100 string fracSecsToISOString(int hnsecs, int prec = -1) @safe pure nothrow 11101 { 11102 import std.array : appender; 11103 auto w = appender!string(); 11104 try 11105 fracSecsToISOString(w, hnsecs, prec); 11106 catch (Exception e) 11107 assert(0, "fracSecsToISOString() threw."); 11108 return w.data; 11109 } 11110 11111 void fracSecsToISOString(W)(ref W writer, int hnsecs, int prec = -1) 11112 { 11113 import std.conv : toChars; 11114 import std.range : padLeft; 11115 11116 assert(hnsecs >= 0); 11117 11118 if (prec == 0) 11119 return; 11120 11121 if (hnsecs == 0) 11122 return; 11123 11124 put(writer, '.'); 11125 auto chars = hnsecs.toChars.padLeft('0', 7); 11126 11127 if (prec == -1) 11128 { 11129 while (chars.back == '0') 11130 chars.popBack(); 11131 put(writer, chars); 11132 } 11133 else 11134 put(writer, chars[0 .. prec]); 11135 } 11136 11137 @safe unittest 11138 { 11139 assert(fracSecsToISOString(0) == ""); 11140 assert(fracSecsToISOString(1) == ".0000001"); 11141 assert(fracSecsToISOString(10) == ".000001"); 11142 assert(fracSecsToISOString(100) == ".00001"); 11143 assert(fracSecsToISOString(1000) == ".0001"); 11144 assert(fracSecsToISOString(10_000) == ".001"); 11145 assert(fracSecsToISOString(100_000) == ".01"); 11146 assert(fracSecsToISOString(1_000_000) == ".1"); 11147 assert(fracSecsToISOString(1_000_001) == ".1000001"); 11148 assert(fracSecsToISOString(1_001_001) == ".1001001"); 11149 assert(fracSecsToISOString(1_071_601) == ".1071601"); 11150 assert(fracSecsToISOString(1_271_641) == ".1271641"); 11151 assert(fracSecsToISOString(9_999_999) == ".9999999"); 11152 assert(fracSecsToISOString(9_999_990) == ".999999"); 11153 assert(fracSecsToISOString(9_999_900) == ".99999"); 11154 assert(fracSecsToISOString(9_999_000) == ".9999"); 11155 assert(fracSecsToISOString(9_990_000) == ".999"); 11156 assert(fracSecsToISOString(9_900_000) == ".99"); 11157 assert(fracSecsToISOString(9_000_000) == ".9"); 11158 assert(fracSecsToISOString(999) == ".0000999"); 11159 assert(fracSecsToISOString(9990) == ".000999"); 11160 assert(fracSecsToISOString(99_900) == ".00999"); 11161 assert(fracSecsToISOString(999_000) == ".0999"); 11162 } 11163 11164 11165 /+ 11166 Returns a Duration corresponding to to the given ISO string of 11167 fractional seconds. 11168 +/ 11169 static Duration fracSecsFromISOString(S)(scope const S isoString) @safe pure 11170 if (isSomeString!S) 11171 { 11172 import std.algorithm.searching : all; 11173 import std.ascii : isDigit; 11174 import std.conv : to; 11175 import std.format : format; 11176 import std.string : representation; 11177 11178 if (isoString.empty) 11179 return Duration.zero; 11180 11181 auto str = isoString.representation; 11182 11183 enforce!DateTimeException(str[0] == '.', format("Invalid format for fracSecsFromISOString: %s", isoString)); 11184 str.popFront(); 11185 11186 enforce!DateTimeException(!str.empty && all!isDigit(str), 11187 format("Invalid format for fracSecsFromISOString: %s", isoString)); 11188 11189 dchar[7] fullISOString = void; 11190 foreach (i, ref dchar c; fullISOString) 11191 { 11192 if (i < str.length) 11193 c = str[i]; 11194 else 11195 c = '0'; 11196 } 11197 11198 return hnsecs(to!int(fullISOString[])); 11199 } 11200 11201 @safe unittest 11202 { 11203 import core.time; 11204 static void testFSInvalid(string isoString) 11205 { 11206 fracSecsFromISOString(isoString); 11207 } 11208 11209 assertThrown!DateTimeException(testFSInvalid(".")); 11210 assertThrown!DateTimeException(testFSInvalid("0.")); 11211 assertThrown!DateTimeException(testFSInvalid("0")); 11212 assertThrown!DateTimeException(testFSInvalid("0000000")); 11213 assertThrown!DateTimeException(testFSInvalid("T")); 11214 assertThrown!DateTimeException(testFSInvalid("T.")); 11215 assertThrown!DateTimeException(testFSInvalid(".T")); 11216 assertThrown!DateTimeException(testFSInvalid(".00000Q0")); 11217 assertThrown!DateTimeException(testFSInvalid(".000000Q")); 11218 assertThrown!DateTimeException(testFSInvalid(".0000000Q")); 11219 assertThrown!DateTimeException(testFSInvalid(".0000000000Q")); 11220 11221 assert(fracSecsFromISOString("") == Duration.zero); 11222 assert(fracSecsFromISOString(".0000001") == hnsecs(1)); 11223 assert(fracSecsFromISOString(".000001") == hnsecs(10)); 11224 assert(fracSecsFromISOString(".00001") == hnsecs(100)); 11225 assert(fracSecsFromISOString(".0001") == hnsecs(1000)); 11226 assert(fracSecsFromISOString(".001") == hnsecs(10_000)); 11227 assert(fracSecsFromISOString(".01") == hnsecs(100_000)); 11228 assert(fracSecsFromISOString(".1") == hnsecs(1_000_000)); 11229 assert(fracSecsFromISOString(".1000001") == hnsecs(1_000_001)); 11230 assert(fracSecsFromISOString(".1001001") == hnsecs(1_001_001)); 11231 assert(fracSecsFromISOString(".1071601") == hnsecs(1_071_601)); 11232 assert(fracSecsFromISOString(".1271641") == hnsecs(1_271_641)); 11233 assert(fracSecsFromISOString(".9999999") == hnsecs(9_999_999)); 11234 assert(fracSecsFromISOString(".9999990") == hnsecs(9_999_990)); 11235 assert(fracSecsFromISOString(".999999") == hnsecs(9_999_990)); 11236 assert(fracSecsFromISOString(".9999900") == hnsecs(9_999_900)); 11237 assert(fracSecsFromISOString(".99999") == hnsecs(9_999_900)); 11238 assert(fracSecsFromISOString(".9999000") == hnsecs(9_999_000)); 11239 assert(fracSecsFromISOString(".9999") == hnsecs(9_999_000)); 11240 assert(fracSecsFromISOString(".9990000") == hnsecs(9_990_000)); 11241 assert(fracSecsFromISOString(".999") == hnsecs(9_990_000)); 11242 assert(fracSecsFromISOString(".9900000") == hnsecs(9_900_000)); 11243 assert(fracSecsFromISOString(".9900") == hnsecs(9_900_000)); 11244 assert(fracSecsFromISOString(".99") == hnsecs(9_900_000)); 11245 assert(fracSecsFromISOString(".9000000") == hnsecs(9_000_000)); 11246 assert(fracSecsFromISOString(".9") == hnsecs(9_000_000)); 11247 assert(fracSecsFromISOString(".0000999") == hnsecs(999)); 11248 assert(fracSecsFromISOString(".0009990") == hnsecs(9990)); 11249 assert(fracSecsFromISOString(".000999") == hnsecs(9990)); 11250 assert(fracSecsFromISOString(".0099900") == hnsecs(99_900)); 11251 assert(fracSecsFromISOString(".00999") == hnsecs(99_900)); 11252 assert(fracSecsFromISOString(".0999000") == hnsecs(999_000)); 11253 assert(fracSecsFromISOString(".0999") == hnsecs(999_000)); 11254 assert(fracSecsFromISOString(".00000000") == Duration.zero); 11255 assert(fracSecsFromISOString(".00000001") == Duration.zero); 11256 assert(fracSecsFromISOString(".00000009") == Duration.zero); 11257 assert(fracSecsFromISOString(".1234567890") == hnsecs(1_234_567)); 11258 assert(fracSecsFromISOString(".12345678901234567890") == hnsecs(1_234_567)); 11259 } 11260 11261 11262 /+ 11263 This function is used to split out the units without getting the remaining 11264 hnsecs. 11265 11266 Params: 11267 units = The units to split out. 11268 hnsecs = The current total hnsecs. 11269 11270 Returns: 11271 The split out value. 11272 +/ 11273 long getUnitsFromHNSecs(string units)(long hnsecs) @safe pure nothrow 11274 if (validTimeUnits(units) && 11275 CmpTimeUnits!(units, "months") < 0) 11276 { 11277 return convert!("hnsecs", units)(hnsecs); 11278 } 11279 11280 @safe unittest 11281 { 11282 auto hnsecs = 2595000000007L; 11283 immutable days = getUnitsFromHNSecs!"days"(hnsecs); 11284 assert(days == 3); 11285 assert(hnsecs == 2595000000007L); 11286 } 11287 11288 11289 /+ 11290 This function is used to split out the units without getting the units but 11291 just the remaining hnsecs. 11292 11293 Params: 11294 units = The units to split out. 11295 hnsecs = The current total hnsecs. 11296 11297 Returns: 11298 The remaining hnsecs. 11299 +/ 11300 long removeUnitsFromHNSecs(string units)(long hnsecs) @safe pure nothrow 11301 if (validTimeUnits(units) && 11302 CmpTimeUnits!(units, "months") < 0) 11303 { 11304 immutable value = convert!("hnsecs", units)(hnsecs); 11305 return hnsecs - convert!(units, "hnsecs")(value); 11306 } 11307 11308 @safe unittest 11309 { 11310 auto hnsecs = 2595000000007L; 11311 auto returned = removeUnitsFromHNSecs!"days"(hnsecs); 11312 assert(returned == 3000000007); 11313 assert(hnsecs == 2595000000007L); 11314 } 11315 11316 11317 /+ 11318 Strips what RFC 5322, section 3.2.2 refers to as CFWS from the left-hand 11319 side of the given range (it strips comments delimited by $(D '(') and 11320 `'`') as well as folding whitespace). 11321 11322 It is assumed that the given range contains the value of a header field and 11323 no terminating CRLF for the line (though the CRLF for folding whitespace is 11324 of course expected and stripped) and thus that the only case of CR or LF is 11325 in folding whitespace. 11326 11327 If a comment does not terminate correctly (e.g. mismatched parens) or if the 11328 the FWS is malformed, then the range will be empty when stripCWFS is done. 11329 However, only minimal validation of the content is done (e.g. quoted pairs 11330 within a comment aren't validated beyond \$LPAREN or \$RPAREN, because 11331 they're inside a comment, and thus their value doesn't matter anyway). It's 11332 only when the content does not conform to the grammar rules for FWS and thus 11333 literally cannot be parsed that content is considered invalid, and an empty 11334 range is returned. 11335 11336 Note that _stripCFWS is eager, not lazy. It does not create a new range. 11337 Rather, it pops off the CFWS from the range and returns it. 11338 +/ 11339 R _stripCFWS(R)(R range) 11340 if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && 11341 (is(immutable ElementType!R == immutable char) || is(immutable ElementType!R == immutable ubyte))) 11342 { 11343 immutable e = range.length; 11344 outer: for (size_t i = 0; i < e; ) 11345 { 11346 switch (range[i]) 11347 { 11348 case ' ': case '\t': 11349 { 11350 ++i; 11351 break; 11352 } 11353 case '\r': 11354 { 11355 if (i + 2 < e && range[i + 1] == '\n' && (range[i + 2] == ' ' || range[i + 2] == '\t')) 11356 { 11357 i += 3; 11358 break; 11359 } 11360 break outer; 11361 } 11362 case '\n': 11363 { 11364 if (i + 1 < e && (range[i + 1] == ' ' || range[i + 1] == '\t')) 11365 { 11366 i += 2; 11367 break; 11368 } 11369 break outer; 11370 } 11371 case '(': 11372 { 11373 ++i; 11374 size_t commentLevel = 1; 11375 while (i < e) 11376 { 11377 if (range[i] == '(') 11378 ++commentLevel; 11379 else if (range[i] == ')') 11380 { 11381 ++i; 11382 if (--commentLevel == 0) 11383 continue outer; 11384 continue; 11385 } 11386 else if (range[i] == '\\') 11387 { 11388 if (++i == e) 11389 break outer; 11390 } 11391 ++i; 11392 } 11393 break outer; 11394 } 11395 default: return range[i .. e]; 11396 } 11397 } 11398 return range[e .. e]; 11399 } 11400 11401 @system unittest 11402 { 11403 import std.algorithm.comparison : equal; 11404 import std.algorithm.iteration : map; 11405 import std.meta : AliasSeq; 11406 import std.stdio : writeln; 11407 import std.string : representation; 11408 11409 static foreach (cr; AliasSeq!(function(string a){return cast(ubyte[]) a;}, 11410 function(string a){return map!(b => cast(char) b)(a.representation);})) 11411 { 11412 scope(failure) writeln(typeof(cr).stringof); 11413 11414 assert(_stripCFWS(cr("")).empty); 11415 assert(_stripCFWS(cr("\r")).empty); 11416 assert(_stripCFWS(cr("\r\n")).empty); 11417 assert(_stripCFWS(cr("\r\n ")).empty); 11418 assert(_stripCFWS(cr(" \t\r\n")).empty); 11419 assert(equal(_stripCFWS(cr(" \t\r\n hello")), cr("hello"))); 11420 assert(_stripCFWS(cr(" \t\r\nhello")).empty); 11421 assert(_stripCFWS(cr(" \t\r\n\v")).empty); 11422 assert(equal(_stripCFWS(cr("\v \t\r\n\v")), cr("\v \t\r\n\v"))); 11423 assert(_stripCFWS(cr("()")).empty); 11424 assert(_stripCFWS(cr("(hello world)")).empty); 11425 assert(_stripCFWS(cr("(hello world)(hello world)")).empty); 11426 assert(_stripCFWS(cr("(hello world\r\n foo\r where's\nwaldo)")).empty); 11427 assert(_stripCFWS(cr(" \t (hello \tworld\r\n foo\r where's\nwaldo)\t\t ")).empty); 11428 assert(_stripCFWS(cr(" ")).empty); 11429 assert(_stripCFWS(cr("\t\t\t")).empty); 11430 assert(_stripCFWS(cr("\t \r\n\r \n")).empty); 11431 assert(_stripCFWS(cr("(hello world) (can't find waldo) (he's lost)")).empty); 11432 assert(_stripCFWS(cr("(hello\\) world) (can't \\(find waldo) (he's \\(\\)lost)")).empty); 11433 assert(_stripCFWS(cr("(((((")).empty); 11434 assert(_stripCFWS(cr("(((()))")).empty); 11435 assert(_stripCFWS(cr("(((())))")).empty); 11436 assert(equal(_stripCFWS(cr("(((()))))")), cr(")"))); 11437 assert(equal(_stripCFWS(cr(")))))")), cr(")))))"))); 11438 assert(equal(_stripCFWS(cr("()))))")), cr("))))"))); 11439 assert(equal(_stripCFWS(cr(" hello hello ")), cr("hello hello "))); 11440 assert(equal(_stripCFWS(cr("\thello (world)")), cr("hello (world)"))); 11441 assert(equal(_stripCFWS(cr(" \r\n \\((\\)) foo")), cr("\\((\\)) foo"))); 11442 assert(equal(_stripCFWS(cr(" \r\n (\\((\\))) foo")), cr("foo"))); 11443 assert(equal(_stripCFWS(cr(" \r\n (\\(())) foo")), cr(") foo"))); 11444 assert(_stripCFWS(cr(" \r\n (((\\))) foo")).empty); 11445 11446 assert(_stripCFWS(cr("(hello)(hello)")).empty); 11447 assert(_stripCFWS(cr(" \r\n (hello)\r\n (hello)")).empty); 11448 assert(_stripCFWS(cr(" \r\n (hello) \r\n (hello) \r\n ")).empty); 11449 assert(_stripCFWS(cr("\t\t\t\t(hello)\t\t\t\t(hello)\t\t\t\t")).empty); 11450 assert(equal(_stripCFWS(cr(" \r\n (hello)\r\n (hello) \r\n hello")), cr("hello"))); 11451 assert(equal(_stripCFWS(cr(" \r\n (hello) \r\n (hello) \r\n hello")), cr("hello"))); 11452 assert(equal(_stripCFWS(cr("\t\r\n\t(hello)\r\n\t(hello)\t\r\n hello")), cr("hello"))); 11453 assert(equal(_stripCFWS(cr("\t\r\n\t(hello)\t\r\n\t(hello)\t\r\n hello")), cr("hello"))); 11454 assert(equal(_stripCFWS(cr(" \r\n (hello) \r\n \r\n (hello) \r\n hello")), cr("hello"))); 11455 assert(equal(_stripCFWS(cr(" \r\n (hello) \r\n (hello) \r\n \r\n hello")), cr("hello"))); 11456 assert(equal(_stripCFWS(cr(" \r\n \r\n (hello)\t\r\n (hello) \r\n hello")), cr("hello"))); 11457 assert(equal(_stripCFWS(cr(" \r\n\t\r\n\t(hello)\t\r\n (hello) \r\n hello")), cr("hello"))); 11458 11459 assert(equal(_stripCFWS(cr(" (\r\n ( \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(" (\t\r\n ( \r\n ) \r\n ) foo")), cr("foo"))); 11462 assert(equal(_stripCFWS(cr(" (\r\n\t( \r\n ) \r\n ) foo")), cr("foo"))); 11463 assert(equal(_stripCFWS(cr(" ( \r\n (\t\r\n ) \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\t) \r\n ) foo")), cr("foo"))); 11466 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n) \r\n ) foo")), cr("foo"))); 11467 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n )\t\r\n ) foo")), cr("foo"))); 11468 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n )\r\n ) foo")), cr("foo"))); 11469 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n) foo")), cr("foo"))); 11470 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n\t) foo")), cr("foo"))); 11471 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n ) \r\n foo")), cr("foo"))); 11472 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n )\t\r\n foo")), cr("foo"))); 11473 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n )\r\n foo")), cr("foo"))); 11474 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 ) \r\n ) foo")), cr("foo"))); 11477 assert(equal(_stripCFWS(cr(" (\t\r\n \r\n ( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 11478 assert(equal(_stripCFWS(cr(" (\r\n \r\n\t( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 11479 assert(equal(_stripCFWS(cr(" (\r\n \r\n( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 11480 assert(equal(_stripCFWS(cr(" (\r\n \r\n ( \r\n \r\n\t) \r\n ) foo")), cr("foo"))); 11481 assert(equal(_stripCFWS(cr(" (\r\n \r\n ( \r\n \r\n )\t\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(equal(_stripCFWS(cr(" ( \r\n bar \r\n ( \r\n bar \r\n ) \r\n ) foo")), cr("foo"))); 11485 assert(equal(_stripCFWS(cr(" ( \r\n () \r\n ( \r\n () \r\n ) \r\n ) foo")), cr("foo"))); 11486 assert(equal(_stripCFWS(cr(" ( \r\n \\\\ \r\n ( \r\n \\\\ \r\n ) \r\n ) foo")), cr("foo"))); 11487 11488 assert(_stripCFWS(cr("(hello)(hello)")).empty); 11489 assert(_stripCFWS(cr(" \n (hello)\n (hello) \n ")).empty); 11490 assert(_stripCFWS(cr(" \n (hello) \n (hello) \n ")).empty); 11491 assert(equal(_stripCFWS(cr(" \n (hello)\n (hello) \n hello")), cr("hello"))); 11492 assert(equal(_stripCFWS(cr(" \n (hello) \n (hello) \n hello")), cr("hello"))); 11493 assert(equal(_stripCFWS(cr("\t\n\t(hello)\n\t(hello)\t\n hello")), cr("hello"))); 11494 assert(equal(_stripCFWS(cr("\t\n\t(hello)\t\n\t(hello)\t\n hello")), cr("hello"))); 11495 assert(equal(_stripCFWS(cr(" \n (hello) \n \n (hello) \n hello")), cr("hello"))); 11496 assert(equal(_stripCFWS(cr(" \n (hello) \n (hello) \n \n hello")), cr("hello"))); 11497 assert(equal(_stripCFWS(cr(" \n \n (hello)\t\n (hello) \n hello")), cr("hello"))); 11498 assert(equal(_stripCFWS(cr(" \n\t\n\t(hello)\t\n (hello) \n hello")), cr("hello"))); 11499 } 11500 } 11501 11502 // This is so that we don't have to worry about std.conv.to throwing. It also 11503 // doesn't have to worry about quite as many cases as std.conv.to, since it 11504 // doesn't have to worry about a sign on the value or about whether it fits. 11505 T _convDigits(T, R)(R str) 11506 if (isIntegral!T && isSigned!T) // The constraints on R were already covered by parseRFC822DateTime. 11507 { 11508 import std.ascii : isDigit; 11509 11510 assert(!str.empty); 11511 T num = 0; 11512 foreach (i; 0 .. str.length) 11513 { 11514 if (i != 0) 11515 num *= 10; 11516 if (!isDigit(str[i])) 11517 return -1; 11518 num += str[i] - '0'; 11519 } 11520 return num; 11521 } 11522 11523 @safe unittest 11524 { 11525 import std.conv : to; 11526 import std.range : chain, iota; 11527 foreach (i; chain(iota(0, 101), [250, 999, 1000, 1001, 2345, 9999])) 11528 { 11529 assert(_convDigits!int(to!string(i)) == i, i.to!string); 11530 } 11531 foreach (str; ["-42", "+42", "1a", "1 ", " ", " 42 "]) 11532 { 11533 assert(_convDigits!int(str) == -1, str); 11534 } 11535 } 11536 11537 11538 // NOTE: all the non-simple array literals are wrapped in functions, because 11539 // otherwise importing causes re-evaluation of the static initializers using 11540 // CTFE with unittests enabled 11541 version (StdUnittest) 11542 { 11543 private @safe: 11544 // Variables to help in testing. 11545 Duration currLocalDiffFromUTC; 11546 immutable (TimeZone)[] testTZs; 11547 11548 // All of these helper arrays are sorted in ascending order. 11549 auto testYearsBC = [-1999, -1200, -600, -4, -1, 0]; 11550 auto testYearsAD = [1, 4, 1000, 1999, 2000, 2012]; 11551 11552 // I'd use a Tuple, but I get forward reference errors if I try. 11553 struct MonthDay 11554 { 11555 Month month; 11556 short day; 11557 11558 this(int m, short d) 11559 { 11560 month = cast(Month) m; 11561 day = d; 11562 } 11563 } 11564 11565 MonthDay[] testMonthDays() 11566 { 11567 static result = [MonthDay(1, 1), 11568 MonthDay(1, 2), 11569 MonthDay(3, 17), 11570 MonthDay(7, 4), 11571 MonthDay(10, 27), 11572 MonthDay(12, 30), 11573 MonthDay(12, 31)]; 11574 return result; 11575 } 11576 11577 auto testDays = [1, 2, 9, 10, 16, 20, 25, 28, 29, 30, 31]; 11578 11579 TimeOfDay[] testTODs() 11580 { 11581 static result = [TimeOfDay(0, 0, 0), 11582 TimeOfDay(0, 0, 1), 11583 TimeOfDay(0, 1, 0), 11584 TimeOfDay(1, 0, 0), 11585 TimeOfDay(13, 13, 13), 11586 TimeOfDay(23, 59, 59)]; 11587 return result; 11588 } 11589 11590 auto testHours = [0, 1, 12, 22, 23]; 11591 auto testMinSecs = [0, 1, 30, 58, 59]; 11592 11593 // Throwing exceptions is incredibly expensive, so we want to use a smaller 11594 // set of values for tests using assertThrown. 11595 TimeOfDay[] testTODsThrown() 11596 { 11597 static result = [TimeOfDay(0, 0, 0), 11598 TimeOfDay(13, 13, 13), 11599 TimeOfDay(23, 59, 59)]; 11600 return result; 11601 } 11602 11603 Date[] testDatesBC; 11604 Date[] testDatesAD; 11605 11606 DateTime[] testDateTimesBC; 11607 DateTime[] testDateTimesAD; 11608 11609 Duration[] testFracSecs; 11610 11611 SysTime[] testSysTimesBC; 11612 SysTime[] testSysTimesAD; 11613 11614 // I'd use a Tuple, but I get forward reference errors if I try. 11615 struct GregDay { int day; Date date; } 11616 GregDay[] testGregDaysBC() 11617 { 11618 static result = [GregDay(-1_373_427, Date(-3760, 9, 7)), // Start of the Hebrew Calendar 11619 GregDay(-735_233, Date(-2012, 1, 1)), 11620 GregDay(-735_202, Date(-2012, 2, 1)), 11621 GregDay(-735_175, Date(-2012, 2, 28)), 11622 GregDay(-735_174, Date(-2012, 2, 29)), 11623 GregDay(-735_173, Date(-2012, 3, 1)), 11624 GregDay(-734_502, Date(-2010, 1, 1)), 11625 GregDay(-734_472, Date(-2010, 1, 31)), 11626 GregDay(-734_471, Date(-2010, 2, 1)), 11627 GregDay(-734_444, Date(-2010, 2, 28)), 11628 GregDay(-734_443, Date(-2010, 3, 1)), 11629 GregDay(-734_413, Date(-2010, 3, 31)), 11630 GregDay(-734_412, Date(-2010, 4, 1)), 11631 GregDay(-734_383, Date(-2010, 4, 30)), 11632 GregDay(-734_382, Date(-2010, 5, 1)), 11633 GregDay(-734_352, Date(-2010, 5, 31)), 11634 GregDay(-734_351, Date(-2010, 6, 1)), 11635 GregDay(-734_322, Date(-2010, 6, 30)), 11636 GregDay(-734_321, Date(-2010, 7, 1)), 11637 GregDay(-734_291, Date(-2010, 7, 31)), 11638 GregDay(-734_290, Date(-2010, 8, 1)), 11639 GregDay(-734_260, Date(-2010, 8, 31)), 11640 GregDay(-734_259, Date(-2010, 9, 1)), 11641 GregDay(-734_230, Date(-2010, 9, 30)), 11642 GregDay(-734_229, Date(-2010, 10, 1)), 11643 GregDay(-734_199, Date(-2010, 10, 31)), 11644 GregDay(-734_198, Date(-2010, 11, 1)), 11645 GregDay(-734_169, Date(-2010, 11, 30)), 11646 GregDay(-734_168, Date(-2010, 12, 1)), 11647 GregDay(-734_139, Date(-2010, 12, 30)), 11648 GregDay(-734_138, Date(-2010, 12, 31)), 11649 GregDay(-731_215, Date(-2001, 1, 1)), 11650 GregDay(-730_850, Date(-2000, 1, 1)), 11651 GregDay(-730_849, Date(-2000, 1, 2)), 11652 GregDay(-730_486, Date(-2000, 12, 30)), 11653 GregDay(-730_485, Date(-2000, 12, 31)), 11654 GregDay(-730_484, Date(-1999, 1, 1)), 11655 GregDay(-694_690, Date(-1901, 1, 1)), 11656 GregDay(-694_325, Date(-1900, 1, 1)), 11657 GregDay(-585_118, Date(-1601, 1, 1)), 11658 GregDay(-584_753, Date(-1600, 1, 1)), 11659 GregDay(-584_388, Date(-1600, 12, 31)), 11660 GregDay(-584_387, Date(-1599, 1, 1)), 11661 GregDay(-365_972, Date(-1001, 1, 1)), 11662 GregDay(-365_607, Date(-1000, 1, 1)), 11663 GregDay(-183_351, Date(-501, 1, 1)), 11664 GregDay(-182_986, Date(-500, 1, 1)), 11665 GregDay(-182_621, Date(-499, 1, 1)), 11666 GregDay(-146_827, Date(-401, 1, 1)), 11667 GregDay(-146_462, Date(-400, 1, 1)), 11668 GregDay(-146_097, Date(-400, 12, 31)), 11669 GregDay(-110_302, Date(-301, 1, 1)), 11670 GregDay(-109_937, Date(-300, 1, 1)), 11671 GregDay(-73_778, Date(-201, 1, 1)), 11672 GregDay(-73_413, Date(-200, 1, 1)), 11673 GregDay(-38_715, Date(-105, 1, 1)), 11674 GregDay(-37_254, Date(-101, 1, 1)), 11675 GregDay(-36_889, Date(-100, 1, 1)), 11676 GregDay(-36_524, Date(-99, 1, 1)), 11677 GregDay(-36_160, Date(-99, 12, 31)), 11678 GregDay(-35_794, Date(-97, 1, 1)), 11679 GregDay(-18_627, Date(-50, 1, 1)), 11680 GregDay(-18_262, Date(-49, 1, 1)), 11681 GregDay(-3652, Date(-9, 1, 1)), 11682 GregDay(-2191, Date(-5, 1, 1)), 11683 GregDay(-1827, Date(-5, 12, 31)), 11684 GregDay(-1826, Date(-4, 1, 1)), 11685 GregDay(-1825, Date(-4, 1, 2)), 11686 GregDay(-1462, Date(-4, 12, 30)), 11687 GregDay(-1461, Date(-4, 12, 31)), 11688 GregDay(-1460, Date(-3, 1, 1)), 11689 GregDay(-1096, Date(-3, 12, 31)), 11690 GregDay(-1095, Date(-2, 1, 1)), 11691 GregDay(-731, Date(-2, 12, 31)), 11692 GregDay(-730, Date(-1, 1, 1)), 11693 GregDay(-367, Date(-1, 12, 30)), 11694 GregDay(-366, Date(-1, 12, 31)), 11695 GregDay(-365, Date(0, 1, 1)), 11696 GregDay(-31, Date(0, 11, 30)), 11697 GregDay(-30, Date(0, 12, 1)), 11698 GregDay(-1, Date(0, 12, 30)), 11699 GregDay(0, Date(0, 12, 31))]; 11700 return result; 11701 } 11702 11703 GregDay[] testGregDaysAD() 11704 { 11705 static result = [GregDay(1, Date(1, 1, 1)), 11706 GregDay(2, Date(1, 1, 2)), 11707 GregDay(32, Date(1, 2, 1)), 11708 GregDay(365, Date(1, 12, 31)), 11709 GregDay(366, Date(2, 1, 1)), 11710 GregDay(731, Date(3, 1, 1)), 11711 GregDay(1096, Date(4, 1, 1)), 11712 GregDay(1097, Date(4, 1, 2)), 11713 GregDay(1460, Date(4, 12, 30)), 11714 GregDay(1461, Date(4, 12, 31)), 11715 GregDay(1462, Date(5, 1, 1)), 11716 GregDay(17_898, Date(50, 1, 1)), 11717 GregDay(35_065, Date(97, 1, 1)), 11718 GregDay(36_160, Date(100, 1, 1)), 11719 GregDay(36_525, Date(101, 1, 1)), 11720 GregDay(37_986, Date(105, 1, 1)), 11721 GregDay(72_684, Date(200, 1, 1)), 11722 GregDay(73_049, Date(201, 1, 1)), 11723 GregDay(109_208, Date(300, 1, 1)), 11724 GregDay(109_573, Date(301, 1, 1)), 11725 GregDay(145_732, Date(400, 1, 1)), 11726 GregDay(146_098, Date(401, 1, 1)), 11727 GregDay(182_257, Date(500, 1, 1)), 11728 GregDay(182_622, Date(501, 1, 1)), 11729 GregDay(364_878, Date(1000, 1, 1)), 11730 GregDay(365_243, Date(1001, 1, 1)), 11731 GregDay(584_023, Date(1600, 1, 1)), 11732 GregDay(584_389, Date(1601, 1, 1)), 11733 GregDay(693_596, Date(1900, 1, 1)), 11734 GregDay(693_961, Date(1901, 1, 1)), 11735 GregDay(729_755, Date(1999, 1, 1)), 11736 GregDay(730_120, Date(2000, 1, 1)), 11737 GregDay(730_121, Date(2000, 1, 2)), 11738 GregDay(730_484, Date(2000, 12, 30)), 11739 GregDay(730_485, Date(2000, 12, 31)), 11740 GregDay(730_486, Date(2001, 1, 1)), 11741 GregDay(733_773, Date(2010, 1, 1)), 11742 GregDay(733_774, Date(2010, 1, 2)), 11743 GregDay(733_803, Date(2010, 1, 31)), 11744 GregDay(733_804, Date(2010, 2, 1)), 11745 GregDay(733_831, Date(2010, 2, 28)), 11746 GregDay(733_832, Date(2010, 3, 1)), 11747 GregDay(733_862, Date(2010, 3, 31)), 11748 GregDay(733_863, Date(2010, 4, 1)), 11749 GregDay(733_892, Date(2010, 4, 30)), 11750 GregDay(733_893, Date(2010, 5, 1)), 11751 GregDay(733_923, Date(2010, 5, 31)), 11752 GregDay(733_924, Date(2010, 6, 1)), 11753 GregDay(733_953, Date(2010, 6, 30)), 11754 GregDay(733_954, Date(2010, 7, 1)), 11755 GregDay(733_984, Date(2010, 7, 31)), 11756 GregDay(733_985, Date(2010, 8, 1)), 11757 GregDay(734_015, Date(2010, 8, 31)), 11758 GregDay(734_016, Date(2010, 9, 1)), 11759 GregDay(734_045, Date(2010, 9, 30)), 11760 GregDay(734_046, Date(2010, 10, 1)), 11761 GregDay(734_076, Date(2010, 10, 31)), 11762 GregDay(734_077, Date(2010, 11, 1)), 11763 GregDay(734_106, Date(2010, 11, 30)), 11764 GregDay(734_107, Date(2010, 12, 1)), 11765 GregDay(734_136, Date(2010, 12, 30)), 11766 GregDay(734_137, Date(2010, 12, 31)), 11767 GregDay(734_503, Date(2012, 1, 1)), 11768 GregDay(734_534, Date(2012, 2, 1)), 11769 GregDay(734_561, Date(2012, 2, 28)), 11770 GregDay(734_562, Date(2012, 2, 29)), 11771 GregDay(734_563, Date(2012, 3, 1)), 11772 GregDay(734_858, Date(2012, 12, 21))]; 11773 return result; 11774 } 11775 11776 // I'd use a Tuple, but I get forward reference errors if I try. 11777 struct DayOfYear { int day; MonthDay md; } 11778 DayOfYear[] testDaysOfYear() 11779 { 11780 static result = [DayOfYear(1, MonthDay(1, 1)), 11781 DayOfYear(2, MonthDay(1, 2)), 11782 DayOfYear(3, MonthDay(1, 3)), 11783 DayOfYear(31, MonthDay(1, 31)), 11784 DayOfYear(32, MonthDay(2, 1)), 11785 DayOfYear(59, MonthDay(2, 28)), 11786 DayOfYear(60, MonthDay(3, 1)), 11787 DayOfYear(90, MonthDay(3, 31)), 11788 DayOfYear(91, MonthDay(4, 1)), 11789 DayOfYear(120, MonthDay(4, 30)), 11790 DayOfYear(121, MonthDay(5, 1)), 11791 DayOfYear(151, MonthDay(5, 31)), 11792 DayOfYear(152, MonthDay(6, 1)), 11793 DayOfYear(181, MonthDay(6, 30)), 11794 DayOfYear(182, MonthDay(7, 1)), 11795 DayOfYear(212, MonthDay(7, 31)), 11796 DayOfYear(213, MonthDay(8, 1)), 11797 DayOfYear(243, MonthDay(8, 31)), 11798 DayOfYear(244, MonthDay(9, 1)), 11799 DayOfYear(273, MonthDay(9, 30)), 11800 DayOfYear(274, MonthDay(10, 1)), 11801 DayOfYear(304, MonthDay(10, 31)), 11802 DayOfYear(305, MonthDay(11, 1)), 11803 DayOfYear(334, MonthDay(11, 30)), 11804 DayOfYear(335, MonthDay(12, 1)), 11805 DayOfYear(363, MonthDay(12, 29)), 11806 DayOfYear(364, MonthDay(12, 30)), 11807 DayOfYear(365, MonthDay(12, 31))]; 11808 return result; 11809 } 11810 11811 DayOfYear[] testDaysOfLeapYear() 11812 { 11813 static result = [DayOfYear(1, MonthDay(1, 1)), 11814 DayOfYear(2, MonthDay(1, 2)), 11815 DayOfYear(3, MonthDay(1, 3)), 11816 DayOfYear(31, MonthDay(1, 31)), 11817 DayOfYear(32, MonthDay(2, 1)), 11818 DayOfYear(59, MonthDay(2, 28)), 11819 DayOfYear(60, MonthDay(2, 29)), 11820 DayOfYear(61, MonthDay(3, 1)), 11821 DayOfYear(91, MonthDay(3, 31)), 11822 DayOfYear(92, MonthDay(4, 1)), 11823 DayOfYear(121, MonthDay(4, 30)), 11824 DayOfYear(122, MonthDay(5, 1)), 11825 DayOfYear(152, MonthDay(5, 31)), 11826 DayOfYear(153, MonthDay(6, 1)), 11827 DayOfYear(182, MonthDay(6, 30)), 11828 DayOfYear(183, MonthDay(7, 1)), 11829 DayOfYear(213, MonthDay(7, 31)), 11830 DayOfYear(214, MonthDay(8, 1)), 11831 DayOfYear(244, MonthDay(8, 31)), 11832 DayOfYear(245, MonthDay(9, 1)), 11833 DayOfYear(274, MonthDay(9, 30)), 11834 DayOfYear(275, MonthDay(10, 1)), 11835 DayOfYear(305, MonthDay(10, 31)), 11836 DayOfYear(306, MonthDay(11, 1)), 11837 DayOfYear(335, MonthDay(11, 30)), 11838 DayOfYear(336, MonthDay(12, 1)), 11839 DayOfYear(364, MonthDay(12, 29)), 11840 DayOfYear(365, MonthDay(12, 30)), 11841 DayOfYear(366, MonthDay(12, 31))]; 11842 return result; 11843 } 11844 11845 void initializeTests() 11846 { 11847 import std.algorithm.sorting : sort; 11848 import std.typecons : Rebindable; 11849 immutable lt = LocalTime().utcToTZ(0); 11850 currLocalDiffFromUTC = dur!"hnsecs"(lt); 11851 11852 version (Posix) 11853 { 11854 import std.datetime.timezone : PosixTimeZone; 11855 immutable otherTZ = lt < 0 ? PosixTimeZone.getTimeZone("Australia/Sydney") 11856 : PosixTimeZone.getTimeZone("America/Denver"); 11857 } 11858 else version (Windows) 11859 { 11860 import std.datetime.timezone : WindowsTimeZone; 11861 immutable otherTZ = lt < 0 ? WindowsTimeZone.getTimeZone("AUS Eastern Standard Time") 11862 : WindowsTimeZone.getTimeZone("Mountain Standard Time"); 11863 } 11864 11865 immutable ot = otherTZ.utcToTZ(0); 11866 11867 auto diffs = [0L, lt, ot]; 11868 auto diffAA = [0L : Rebindable!(immutable TimeZone)(UTC())]; 11869 diffAA[lt] = Rebindable!(immutable TimeZone)(LocalTime()); 11870 diffAA[ot] = Rebindable!(immutable TimeZone)(otherTZ); 11871 11872 sort(diffs); 11873 testTZs = [diffAA[diffs[0]], diffAA[diffs[1]], diffAA[diffs[2]]]; 11874 11875 testFracSecs = [Duration.zero, hnsecs(1), hnsecs(5007), hnsecs(9_999_999)]; 11876 11877 foreach (year; testYearsBC) 11878 { 11879 foreach (md; testMonthDays) 11880 testDatesBC ~= Date(year, md.month, md.day); 11881 } 11882 11883 foreach (year; testYearsAD) 11884 { 11885 foreach (md; testMonthDays) 11886 testDatesAD ~= Date(year, md.month, md.day); 11887 } 11888 11889 foreach (dt; testDatesBC) 11890 { 11891 foreach (tod; testTODs) 11892 testDateTimesBC ~= DateTime(dt, tod); 11893 } 11894 11895 foreach (dt; testDatesAD) 11896 { 11897 foreach (tod; testTODs) 11898 testDateTimesAD ~= DateTime(dt, tod); 11899 } 11900 11901 foreach (dt; testDateTimesBC) 11902 { 11903 foreach (tz; testTZs) 11904 { 11905 foreach (fs; testFracSecs) 11906 testSysTimesBC ~= SysTime(dt, fs, tz); 11907 } 11908 } 11909 11910 foreach (dt; testDateTimesAD) 11911 { 11912 foreach (tz; testTZs) 11913 { 11914 foreach (fs; testFracSecs) 11915 testSysTimesAD ~= SysTime(dt, fs, tz); 11916 } 11917 } 11918 } 11919 }