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 $(TR $(TD Duration) $(TD +) $(TD SysTime) $(TD -->) $(TD SysTime)) 6305 ) 6306 6307 Params: 6308 duration = The $(REF Duration, core,time) to add to or subtract from 6309 this $(LREF SysTime). 6310 +/ 6311 SysTime opBinary(string op)(Duration duration) @safe const pure nothrow return scope 6312 if (op == "+" || op == "-") 6313 { 6314 SysTime retval = SysTime(this._stdTime, this._timezone); 6315 immutable hnsecs = duration.total!"hnsecs"; 6316 mixin("retval._stdTime " ~ op ~ "= hnsecs;"); 6317 return retval; 6318 } 6319 6320 /// ditto 6321 SysTime opBinaryRight(string op)(Duration duration) const @safe pure nothrow 6322 if (op == "+") 6323 { 6324 return this + duration; 6325 } 6326 6327 /// 6328 @safe unittest 6329 { 6330 import core.time : hours, seconds; 6331 import std.datetime.date : DateTime; 6332 6333 assert(SysTime(DateTime(2015, 12, 31, 23, 59, 59)) + seconds(1) == 6334 SysTime(DateTime(2016, 1, 1, 0, 0, 0))); 6335 6336 assert(SysTime(DateTime(2015, 12, 31, 23, 59, 59)) + hours(1) == 6337 SysTime(DateTime(2016, 1, 1, 0, 59, 59))); 6338 6339 assert(SysTime(DateTime(2016, 1, 1, 0, 0, 0)) - seconds(1) == 6340 SysTime(DateTime(2015, 12, 31, 23, 59, 59))); 6341 6342 assert(SysTime(DateTime(2016, 1, 1, 0, 59, 59)) - hours(1) == 6343 SysTime(DateTime(2015, 12, 31, 23, 59, 59))); 6344 6345 assert(SysTime(DateTime(2015, 12, 31, 23, 59, 59)) + seconds(1) == 6346 seconds(1) + SysTime(DateTime(2015, 12, 31, 23, 59, 59))); 6347 } 6348 6349 @safe unittest 6350 { 6351 import core.time; 6352 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_678)); 6353 6354 assert(st + dur!"weeks"(7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33), hnsecs(2_345_678))); 6355 assert(st + dur!"weeks"(-7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33), hnsecs(2_345_678))); 6356 assert(st + dur!"days"(7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33), hnsecs(2_345_678))); 6357 assert(st + dur!"days"(-7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33), hnsecs(2_345_678))); 6358 assert(st + dur!"hours"(7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33), hnsecs(2_345_678))); 6359 assert(st + dur!"hours"(-7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33), hnsecs(2_345_678))); 6360 assert(st + dur!"minutes"(7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33), hnsecs(2_345_678))); 6361 assert(st + dur!"minutes"(-7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33), hnsecs(2_345_678))); 6362 assert(st + dur!"seconds"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40), hnsecs(2_345_678))); 6363 assert(st + dur!"seconds"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26), hnsecs(2_345_678))); 6364 assert(st + dur!"msecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_415_678))); 6365 assert(st + dur!"msecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_275_678))); 6366 assert(st + dur!"usecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_748))); 6367 assert(st + dur!"usecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_608))); 6368 assert(st + dur!"hnsecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_685))); 6369 assert(st + dur!"hnsecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_671))); 6370 6371 assert(st - dur!"weeks"(-7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33), hnsecs(2_345_678))); 6372 assert(st - dur!"weeks"(7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33), hnsecs(2_345_678))); 6373 assert(st - dur!"days"(-7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33), hnsecs(2_345_678))); 6374 assert(st - dur!"days"(7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33), hnsecs(2_345_678))); 6375 assert(st - dur!"hours"(-7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33), hnsecs(2_345_678))); 6376 assert(st - dur!"hours"(7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33), hnsecs(2_345_678))); 6377 assert(st - dur!"minutes"(-7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33), hnsecs(2_345_678))); 6378 assert(st - dur!"minutes"(7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33), hnsecs(2_345_678))); 6379 assert(st - dur!"seconds"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40), hnsecs(2_345_678))); 6380 assert(st - dur!"seconds"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26), hnsecs(2_345_678))); 6381 assert(st - dur!"msecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_415_678))); 6382 assert(st - dur!"msecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_275_678))); 6383 assert(st - dur!"usecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_748))); 6384 assert(st - dur!"usecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_608))); 6385 assert(st - dur!"hnsecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_685))); 6386 assert(st - dur!"hnsecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_671))); 6387 6388 static void testST(SysTime orig, long hnsecs, SysTime expected, size_t line = __LINE__) @safe 6389 { 6390 auto result = orig + dur!"hnsecs"(hnsecs); 6391 if (result != expected) 6392 throw new AssertError(format("Failed. actual [%s] != expected [%s]", result, expected), __FILE__, line); 6393 } 6394 6395 // Test A.D. 6396 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274)); 6397 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274))); 6398 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(275))); 6399 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(276))); 6400 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(284))); 6401 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(374))); 6402 testST(beforeAD, 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(999))); 6403 testST(beforeAD, 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1000))); 6404 testST(beforeAD, 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1274))); 6405 testST(beforeAD, 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1275))); 6406 testST(beforeAD, 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2274))); 6407 testST(beforeAD, 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(26_999))); 6408 testST(beforeAD, 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_000))); 6409 testST(beforeAD, 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_001))); 6410 testST(beforeAD, 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_766_999))); 6411 testST(beforeAD, 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_767_000))); 6412 testST(beforeAD, 1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_000_274))); 6413 testST(beforeAD, 60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 39), hnsecs(274))); 6414 testST(beforeAD, 3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 36, 33), hnsecs(274))); 6415 testST(beforeAD, 600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 31, 33), hnsecs(274))); 6416 testST(beforeAD, 36_000_000_000L, SysTime(DateTime(1999, 7, 6, 13, 30, 33), hnsecs(274))); 6417 6418 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(273))); 6419 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(272))); 6420 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(264))); 6421 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(174))); 6422 testST(beforeAD, -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 6423 testST(beforeAD, -275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_999))); 6424 testST(beforeAD, -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_274))); 6425 testST(beforeAD, -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_273))); 6426 testST(beforeAD, -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_998_274))); 6427 testST(beforeAD, -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_967_000))); 6428 testST(beforeAD, -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_966_999))); 6429 testST(beforeAD, -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_167_000))); 6430 testST(beforeAD, -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_166_999))); 6431 testST(beforeAD, -1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_000_274))); 6432 testST(beforeAD, -60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 27), hnsecs(274))); 6433 testST(beforeAD, -3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 24, 33), hnsecs(274))); 6434 testST(beforeAD, -600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 29, 33), hnsecs(274))); 6435 testST(beforeAD, -36_000_000_000L, SysTime(DateTime(1999, 7, 6, 11, 30, 33), hnsecs(274))); 6436 6437 // Test B.C. 6438 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274)); 6439 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274))); 6440 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(275))); 6441 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(276))); 6442 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(284))); 6443 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(374))); 6444 testST(beforeBC, 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(999))); 6445 testST(beforeBC, 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1000))); 6446 testST(beforeBC, 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1274))); 6447 testST(beforeBC, 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1275))); 6448 testST(beforeBC, 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(2274))); 6449 testST(beforeBC, 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(26_999))); 6450 testST(beforeBC, 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_000))); 6451 testST(beforeBC, 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_001))); 6452 testST(beforeBC, 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_766_999))); 6453 testST(beforeBC, 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_767_000))); 6454 testST(beforeBC, 1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_000_274))); 6455 testST(beforeBC, 60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 39), hnsecs(274))); 6456 testST(beforeBC, 3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 36, 33), hnsecs(274))); 6457 testST(beforeBC, 600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), hnsecs(274))); 6458 testST(beforeBC, 36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), hnsecs(274))); 6459 6460 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(273))); 6461 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(272))); 6462 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(264))); 6463 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(174))); 6464 testST(beforeBC, -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 6465 testST(beforeBC, -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_999))); 6466 testST(beforeBC, -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_274))); 6467 testST(beforeBC, -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_273))); 6468 testST(beforeBC, -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_998_274))); 6469 testST(beforeBC, -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_967_000))); 6470 testST(beforeBC, -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_966_999))); 6471 testST(beforeBC, -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_167_000))); 6472 testST(beforeBC, -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_166_999))); 6473 testST(beforeBC, -1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_000_274))); 6474 testST(beforeBC, -60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 27), hnsecs(274))); 6475 testST(beforeBC, -3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 24, 33), hnsecs(274))); 6476 testST(beforeBC, -600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), hnsecs(274))); 6477 testST(beforeBC, -36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), hnsecs(274))); 6478 6479 // Test Both 6480 auto beforeBoth1 = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 6481 testST(beforeBoth1, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 6482 testST(beforeBoth1, 0, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6483 testST(beforeBoth1, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6484 testST(beforeBoth1, -2, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998))); 6485 testST(beforeBoth1, -1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_000))); 6486 testST(beforeBoth1, -2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_998_000))); 6487 testST(beforeBoth1, -2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_997_445))); 6488 testST(beforeBoth1, -1_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_000_000))); 6489 testST(beforeBoth1, -2_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(8_000_000))); 6490 testST(beforeBoth1, -2_333_333, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(7_666_667))); 6491 testST(beforeBoth1, -10_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59))); 6492 testST(beforeBoth1, -20_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 58))); 6493 testST(beforeBoth1, -20_888_888, SysTime(DateTime(0, 12, 31, 23, 59, 57), hnsecs(9_111_112))); 6494 6495 auto beforeBoth2 = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 6496 testST(beforeBoth2, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998))); 6497 testST(beforeBoth2, 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6498 testST(beforeBoth2, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6499 testST(beforeBoth2, 2, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 6500 testST(beforeBoth2, 1000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999))); 6501 testST(beforeBoth2, 2000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1999))); 6502 testST(beforeBoth2, 2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2554))); 6503 testST(beforeBoth2, 1_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999_999))); 6504 testST(beforeBoth2, 2_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1_999_999))); 6505 testST(beforeBoth2, 2_333_333, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2_333_332))); 6506 testST(beforeBoth2, 10_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 6507 testST(beforeBoth2, 20_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 1), hnsecs(9_999_999))); 6508 testST(beforeBoth2, 20_888_888, SysTime(DateTime(1, 1, 1, 0, 0, 2), hnsecs(888_887))); 6509 6510 auto duration = dur!"seconds"(12); 6511 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6512 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6513 assert(cst + duration == SysTime(DateTime(1999, 7, 6, 12, 30, 45))); 6514 assert(ist + duration == SysTime(DateTime(1999, 7, 6, 12, 30, 45))); 6515 assert(cst - duration == SysTime(DateTime(1999, 7, 6, 12, 30, 21))); 6516 assert(ist - duration == SysTime(DateTime(1999, 7, 6, 12, 30, 21))); 6517 6518 static void testScope(scope ref SysTime st, scope ref Duration d) @safe 6519 { 6520 auto result = st + d; 6521 } 6522 } 6523 6524 6525 /++ 6526 Gives the result of adding or subtracting a $(REF Duration, core,time) from 6527 this $(LREF SysTime), as well as assigning the result to this 6528 $(LREF SysTime). 6529 6530 The legal types of arithmetic for $(LREF SysTime) using this operator are 6531 6532 $(BOOKTABLE, 6533 $(TR $(TD SysTime) $(TD +) $(TD Duration) $(TD -->) $(TD SysTime)) 6534 $(TR $(TD SysTime) $(TD -) $(TD Duration) $(TD -->) $(TD SysTime)) 6535 ) 6536 6537 Params: 6538 duration = The $(REF Duration, core,time) to add to or subtract from 6539 this $(LREF SysTime). 6540 +/ 6541 ref SysTime opOpAssign(string op)(Duration duration) @safe pure nothrow scope 6542 if (op == "+" || op == "-") 6543 { 6544 immutable hnsecs = duration.total!"hnsecs"; 6545 mixin("_stdTime " ~ op ~ "= hnsecs;"); 6546 return this; 6547 } 6548 6549 @safe unittest 6550 { 6551 import core.time; 6552 auto before = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6553 assert(before + dur!"weeks"(7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33))); 6554 assert(before + dur!"weeks"(-7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33))); 6555 assert(before + dur!"days"(7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33))); 6556 assert(before + dur!"days"(-7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33))); 6557 6558 assert(before + dur!"hours"(7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33))); 6559 assert(before + dur!"hours"(-7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33))); 6560 assert(before + dur!"minutes"(7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33))); 6561 assert(before + dur!"minutes"(-7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33))); 6562 assert(before + dur!"seconds"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40))); 6563 assert(before + dur!"seconds"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26))); 6564 assert(before + dur!"msecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(7))); 6565 assert(before + dur!"msecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), msecs(993))); 6566 assert(before + dur!"usecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(7))); 6567 assert(before + dur!"usecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), usecs(999_993))); 6568 assert(before + dur!"hnsecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(7))); 6569 assert(before + dur!"hnsecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_993))); 6570 6571 assert(before - dur!"weeks"(-7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33))); 6572 assert(before - dur!"weeks"(7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33))); 6573 assert(before - dur!"days"(-7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33))); 6574 assert(before - dur!"days"(7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33))); 6575 6576 assert(before - dur!"hours"(-7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33))); 6577 assert(before - dur!"hours"(7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33))); 6578 assert(before - dur!"minutes"(-7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33))); 6579 assert(before - dur!"minutes"(7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33))); 6580 assert(before - dur!"seconds"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40))); 6581 assert(before - dur!"seconds"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26))); 6582 assert(before - dur!"msecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(7))); 6583 assert(before - dur!"msecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), msecs(993))); 6584 assert(before - dur!"usecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(7))); 6585 assert(before - dur!"usecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), usecs(999_993))); 6586 assert(before - dur!"hnsecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(7))); 6587 assert(before - dur!"hnsecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_993))); 6588 6589 static void testST(SysTime orig, long hnsecs, SysTime expected, size_t line = __LINE__) @safe 6590 { 6591 auto r = orig += dur!"hnsecs"(hnsecs); 6592 if (orig != expected) 6593 throw new AssertError(format("Failed 1. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 6594 if (r != expected) 6595 throw new AssertError(format("Failed 2. actual [%s] != expected [%s]", r, expected), __FILE__, line); 6596 } 6597 6598 // Test A.D. 6599 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274)); 6600 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274))); 6601 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(275))); 6602 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(276))); 6603 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(284))); 6604 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(374))); 6605 testST(beforeAD, 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(999))); 6606 testST(beforeAD, 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1000))); 6607 testST(beforeAD, 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1274))); 6608 testST(beforeAD, 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1275))); 6609 testST(beforeAD, 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2274))); 6610 testST(beforeAD, 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(26_999))); 6611 testST(beforeAD, 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_000))); 6612 testST(beforeAD, 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_001))); 6613 testST(beforeAD, 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_766_999))); 6614 testST(beforeAD, 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_767_000))); 6615 testST(beforeAD, 1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_000_274))); 6616 testST(beforeAD, 60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 39), hnsecs(274))); 6617 testST(beforeAD, 3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 36, 33), hnsecs(274))); 6618 testST(beforeAD, 600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 31, 33), hnsecs(274))); 6619 testST(beforeAD, 36_000_000_000L, SysTime(DateTime(1999, 7, 6, 13, 30, 33), hnsecs(274))); 6620 6621 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(273))); 6622 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(272))); 6623 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(264))); 6624 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(174))); 6625 testST(beforeAD, -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 6626 testST(beforeAD, -275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_999))); 6627 testST(beforeAD, -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_274))); 6628 testST(beforeAD, -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_273))); 6629 testST(beforeAD, -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_998_274))); 6630 testST(beforeAD, -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_967_000))); 6631 testST(beforeAD, -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_966_999))); 6632 testST(beforeAD, -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_167_000))); 6633 testST(beforeAD, -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_166_999))); 6634 testST(beforeAD, -1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_000_274))); 6635 testST(beforeAD, -60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 27), hnsecs(274))); 6636 testST(beforeAD, -3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 24, 33), hnsecs(274))); 6637 testST(beforeAD, -600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 29, 33), hnsecs(274))); 6638 testST(beforeAD, -36_000_000_000L, SysTime(DateTime(1999, 7, 6, 11, 30, 33), hnsecs(274))); 6639 6640 // Test B.C. 6641 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274)); 6642 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274))); 6643 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(275))); 6644 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(276))); 6645 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(284))); 6646 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(374))); 6647 testST(beforeBC, 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(999))); 6648 testST(beforeBC, 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1000))); 6649 testST(beforeBC, 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1274))); 6650 testST(beforeBC, 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1275))); 6651 testST(beforeBC, 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(2274))); 6652 testST(beforeBC, 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(26_999))); 6653 testST(beforeBC, 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_000))); 6654 testST(beforeBC, 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_001))); 6655 testST(beforeBC, 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_766_999))); 6656 testST(beforeBC, 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_767_000))); 6657 testST(beforeBC, 1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_000_274))); 6658 testST(beforeBC, 60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 39), hnsecs(274))); 6659 testST(beforeBC, 3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 36, 33), hnsecs(274))); 6660 testST(beforeBC, 600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), hnsecs(274))); 6661 testST(beforeBC, 36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), hnsecs(274))); 6662 6663 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(273))); 6664 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(272))); 6665 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(264))); 6666 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(174))); 6667 testST(beforeBC, -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 6668 testST(beforeBC, -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_999))); 6669 testST(beforeBC, -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_274))); 6670 testST(beforeBC, -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_273))); 6671 testST(beforeBC, -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_998_274))); 6672 testST(beforeBC, -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_967_000))); 6673 testST(beforeBC, -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_966_999))); 6674 testST(beforeBC, -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_167_000))); 6675 testST(beforeBC, -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_166_999))); 6676 testST(beforeBC, -1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_000_274))); 6677 testST(beforeBC, -60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 27), hnsecs(274))); 6678 testST(beforeBC, -3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 24, 33), hnsecs(274))); 6679 testST(beforeBC, -600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), hnsecs(274))); 6680 testST(beforeBC, -36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), hnsecs(274))); 6681 6682 // Test Both 6683 auto beforeBoth1 = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 6684 testST(beforeBoth1, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 6685 testST(beforeBoth1, 0, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6686 testST(beforeBoth1, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6687 testST(beforeBoth1, -2, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998))); 6688 testST(beforeBoth1, -1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_000))); 6689 testST(beforeBoth1, -2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_998_000))); 6690 testST(beforeBoth1, -2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_997_445))); 6691 testST(beforeBoth1, -1_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_000_000))); 6692 testST(beforeBoth1, -2_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(8_000_000))); 6693 testST(beforeBoth1, -2_333_333, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(7_666_667))); 6694 testST(beforeBoth1, -10_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59))); 6695 testST(beforeBoth1, -20_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 58))); 6696 testST(beforeBoth1, -20_888_888, SysTime(DateTime(0, 12, 31, 23, 59, 57), hnsecs(9_111_112))); 6697 6698 auto beforeBoth2 = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 6699 testST(beforeBoth2, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998))); 6700 testST(beforeBoth2, 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6701 testST(beforeBoth2, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6702 testST(beforeBoth2, 2, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 6703 testST(beforeBoth2, 1000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999))); 6704 testST(beforeBoth2, 2000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1999))); 6705 testST(beforeBoth2, 2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2554))); 6706 testST(beforeBoth2, 1_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999_999))); 6707 testST(beforeBoth2, 2_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1_999_999))); 6708 testST(beforeBoth2, 2_333_333, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2_333_332))); 6709 testST(beforeBoth2, 10_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 6710 testST(beforeBoth2, 20_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 1), hnsecs(9_999_999))); 6711 testST(beforeBoth2, 20_888_888, SysTime(DateTime(1, 1, 1, 0, 0, 2), hnsecs(888_887))); 6712 6713 { 6714 auto st = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 6715 (st += dur!"hnsecs"(52)) += dur!"seconds"(-907); 6716 assert(st == SysTime(DateTime(0, 12, 31, 23, 44, 53), hnsecs(51))); 6717 } 6718 6719 auto duration = dur!"seconds"(12); 6720 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6721 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6722 static assert(!__traits(compiles, cst += duration)); 6723 static assert(!__traits(compiles, ist += duration)); 6724 static assert(!__traits(compiles, cst -= duration)); 6725 static assert(!__traits(compiles, ist -= duration)); 6726 6727 static void testScope(scope ref SysTime st, scope ref Duration d) @safe 6728 { 6729 auto result1 = st += d; 6730 auto result2 = st -= d; 6731 } 6732 } 6733 6734 6735 /++ 6736 Gives the difference between two $(LREF SysTime)s. 6737 6738 The legal types of arithmetic for $(LREF SysTime) using this operator 6739 are 6740 6741 $(BOOKTABLE, 6742 $(TR $(TD SysTime) $(TD -) $(TD SysTime) $(TD -->) $(TD duration)) 6743 ) 6744 +/ 6745 Duration opBinary(string op)(SysTime rhs) @safe const pure nothrow scope 6746 if (op == "-") 6747 { 6748 return dur!"hnsecs"(_stdTime - rhs._stdTime); 6749 } 6750 6751 @safe unittest 6752 { 6753 import core.time; 6754 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1998, 7, 6, 12, 30, 33)) == 6755 dur!"seconds"(31_536_000)); 6756 assert(SysTime(DateTime(1998, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6757 dur!"seconds"(-31_536_000)); 6758 6759 assert(SysTime(DateTime(1999, 8, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6760 dur!"seconds"(26_78_400)); 6761 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 8, 6, 12, 30, 33)) == 6762 dur!"seconds"(-26_78_400)); 6763 6764 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 5, 12, 30, 33)) == 6765 dur!"seconds"(86_400)); 6766 assert(SysTime(DateTime(1999, 7, 5, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6767 dur!"seconds"(-86_400)); 6768 6769 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 11, 30, 33)) == 6770 dur!"seconds"(3600)); 6771 assert(SysTime(DateTime(1999, 7, 6, 11, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6772 dur!"seconds"(-3600)); 6773 6774 assert(SysTime(DateTime(1999, 7, 6, 12, 31, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6775 dur!"seconds"(60)); 6776 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 31, 33)) == 6777 dur!"seconds"(-60)); 6778 6779 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 34)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6780 dur!"seconds"(1)); 6781 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 34)) == 6782 dur!"seconds"(-1)); 6783 6784 { 6785 auto dt = DateTime(1999, 7, 6, 12, 30, 33); 6786 assert(SysTime(dt, msecs(532)) - SysTime(dt) == msecs(532)); 6787 assert(SysTime(dt) - SysTime(dt, msecs(532)) == msecs(-532)); 6788 6789 assert(SysTime(dt, usecs(333_347)) - SysTime(dt) == usecs(333_347)); 6790 assert(SysTime(dt) - SysTime(dt, usecs(333_347)) == usecs(-333_347)); 6791 6792 assert(SysTime(dt, hnsecs(1_234_567)) - SysTime(dt) == hnsecs(1_234_567)); 6793 assert(SysTime(dt) - SysTime(dt, hnsecs(1_234_567)) == hnsecs(-1_234_567)); 6794 } 6795 6796 assert(SysTime(DateTime(1, 1, 1, 12, 30, 33)) - SysTime(DateTime(1, 1, 1, 0, 0, 0)) == dur!"seconds"(45033)); 6797 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)) - SysTime(DateTime(1, 1, 1, 12, 30, 33)) == dur!"seconds"(-45033)); 6798 assert(SysTime(DateTime(0, 12, 31, 12, 30, 33)) - SysTime(DateTime(1, 1, 1, 0, 0, 0)) == dur!"seconds"(-41367)); 6799 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)) - SysTime(DateTime(0, 12, 31, 12, 30, 33)) == dur!"seconds"(41367)); 6800 6801 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)) - SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)) == 6802 dur!"hnsecs"(1)); 6803 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)) - SysTime(DateTime(1, 1, 1, 0, 0, 0)) == 6804 dur!"hnsecs"(-1)); 6805 6806 version (Posix) 6807 { 6808 import std.datetime.timezone : PosixTimeZone; 6809 immutable tz = PosixTimeZone.getTimeZone("America/Los_Angeles"); 6810 } 6811 else version (Windows) 6812 { 6813 import std.datetime.timezone : WindowsTimeZone; 6814 immutable tz = WindowsTimeZone.getTimeZone("Pacific Standard Time"); 6815 } 6816 6817 { 6818 auto dt = DateTime(2011, 1, 13, 8, 17, 2); 6819 auto d = msecs(296); 6820 assert(SysTime(dt, d, tz) - SysTime(dt, d, tz) == Duration.zero); 6821 assert(SysTime(dt, d, tz) - SysTime(dt, d, UTC()) == hours(8)); 6822 assert(SysTime(dt, d, UTC()) - SysTime(dt, d, tz) == hours(-8)); 6823 } 6824 6825 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6826 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6827 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6828 assert(st - st == Duration.zero); 6829 assert(cst - st == Duration.zero); 6830 assert(ist - st == Duration.zero); 6831 6832 assert(st - cst == Duration.zero); 6833 assert(cst - cst == Duration.zero); 6834 assert(ist - cst == Duration.zero); 6835 6836 assert(st - ist == Duration.zero); 6837 assert(cst - ist == Duration.zero); 6838 assert(ist - ist == Duration.zero); 6839 6840 static void testScope(scope ref SysTime left, scope ref SysTime right) @safe 6841 { 6842 auto result = left - right; 6843 } 6844 } 6845 6846 6847 /++ 6848 Returns the difference between the two $(LREF SysTime)s in months. 6849 6850 To get the difference in years, subtract the year property 6851 of two $(LREF SysTime)s. To get the difference in days or weeks, 6852 subtract the $(LREF SysTime)s themselves and use the 6853 $(REF Duration, core,time) that results. Because converting between 6854 months and smaller units requires a specific date (which 6855 $(REF Duration, core,time)s don't have), getting the difference in 6856 months requires some math using both the year and month properties, so 6857 this is a convenience function for getting the difference in months. 6858 6859 Note that the number of days in the months or how far into the month 6860 either date is is irrelevant. It is the difference in the month property 6861 combined with the difference in years * 12. So, for instance, 6862 December 31st and January 1st are one month apart just as December 1st 6863 and January 31st are one month apart. 6864 6865 Params: 6866 rhs = The $(LREF SysTime) to subtract from this one. 6867 +/ 6868 int diffMonths(scope SysTime rhs) @safe const nothrow scope 6869 { 6870 return (cast(Date) this).diffMonths(cast(Date) rhs); 6871 } 6872 6873 /// 6874 @safe unittest 6875 { 6876 import core.time; 6877 import std.datetime.date : Date; 6878 6879 assert(SysTime(Date(1999, 2, 1)).diffMonths( 6880 SysTime(Date(1999, 1, 31))) == 1); 6881 6882 assert(SysTime(Date(1999, 1, 31)).diffMonths( 6883 SysTime(Date(1999, 2, 1))) == -1); 6884 6885 assert(SysTime(Date(1999, 3, 1)).diffMonths( 6886 SysTime(Date(1999, 1, 1))) == 2); 6887 6888 assert(SysTime(Date(1999, 1, 1)).diffMonths( 6889 SysTime(Date(1999, 3, 31))) == -2); 6890 } 6891 6892 @safe unittest 6893 { 6894 import core.time; 6895 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6896 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6897 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6898 assert(st.diffMonths(st) == 0); 6899 assert(cst.diffMonths(st) == 0); 6900 assert(ist.diffMonths(st) == 0); 6901 6902 assert(st.diffMonths(cst) == 0); 6903 assert(cst.diffMonths(cst) == 0); 6904 assert(ist.diffMonths(cst) == 0); 6905 6906 assert(st.diffMonths(ist) == 0); 6907 assert(cst.diffMonths(ist) == 0); 6908 assert(ist.diffMonths(ist) == 0); 6909 6910 static void testScope(scope ref SysTime left, scope ref SysTime right) @safe 6911 { 6912 auto result = left.diffMonths(right); 6913 } 6914 } 6915 6916 6917 /++ 6918 Whether this $(LREF SysTime) is in a leap year. 6919 +/ 6920 @property bool isLeapYear() @safe const nothrow scope 6921 { 6922 return (cast(Date) this).isLeapYear; 6923 } 6924 6925 @safe unittest 6926 { 6927 import core.time; 6928 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6929 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6930 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6931 assert(!st.isLeapYear); 6932 assert(!cst.isLeapYear); 6933 assert(!ist.isLeapYear); 6934 6935 static void testScope(scope ref SysTime st) @safe 6936 { 6937 auto result = st.isLeapYear; 6938 } 6939 } 6940 6941 6942 /++ 6943 Day of the week this $(LREF SysTime) is on. 6944 +/ 6945 @property DayOfWeek dayOfWeek() @safe const nothrow scope 6946 { 6947 return getDayOfWeek(dayOfGregorianCal); 6948 } 6949 6950 @safe unittest 6951 { 6952 import core.time; 6953 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6954 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6955 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6956 assert(st.dayOfWeek == DayOfWeek.tue); 6957 assert(cst.dayOfWeek == DayOfWeek.tue); 6958 assert(ist.dayOfWeek == DayOfWeek.tue); 6959 6960 static void testScope(scope ref SysTime st) @safe 6961 { 6962 auto result = st.dayOfWeek; 6963 } 6964 } 6965 6966 6967 /++ 6968 Day of the year this $(LREF SysTime) is on. 6969 +/ 6970 @property ushort dayOfYear() @safe const nothrow scope 6971 { 6972 return (cast(Date) this).dayOfYear; 6973 } 6974 6975 /// 6976 @safe unittest 6977 { 6978 import core.time; 6979 import std.datetime.date : DateTime; 6980 6981 assert(SysTime(DateTime(1999, 1, 1, 12, 22, 7)).dayOfYear == 1); 6982 assert(SysTime(DateTime(1999, 12, 31, 7, 2, 59)).dayOfYear == 365); 6983 assert(SysTime(DateTime(2000, 12, 31, 21, 20, 0)).dayOfYear == 366); 6984 } 6985 6986 @safe unittest 6987 { 6988 import core.time; 6989 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6990 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6991 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6992 assert(st.dayOfYear == 187); 6993 assert(cst.dayOfYear == 187); 6994 assert(ist.dayOfYear == 187); 6995 6996 static void testScope(scope ref SysTime st) @safe 6997 { 6998 auto result = st.dayOfYear; 6999 } 7000 } 7001 7002 7003 /++ 7004 Day of the year. 7005 7006 Params: 7007 day = The day of the year to set which day of the year this 7008 $(LREF SysTime) is on. 7009 +/ 7010 @property void dayOfYear(int day) @safe scope 7011 { 7012 immutable hnsecs = adjTime; 7013 immutable days = convert!("hnsecs", "days")(hnsecs); 7014 immutable theRest = hnsecs - convert!("days", "hnsecs")(days); 7015 7016 auto date = Date(cast(int) days); 7017 date.dayOfYear = day; 7018 7019 immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1); 7020 7021 adjTime = newDaysHNSecs + theRest; 7022 } 7023 7024 @safe unittest 7025 { 7026 import core.time; 7027 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7028 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7029 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7030 st.dayOfYear = 12; 7031 assert(st.dayOfYear == 12); 7032 static assert(!__traits(compiles, cst.dayOfYear = 12)); 7033 static assert(!__traits(compiles, ist.dayOfYear = 12)); 7034 7035 static void testScope(scope ref SysTime st) @safe 7036 { 7037 st.dayOfYear = 42; 7038 } 7039 } 7040 7041 7042 /++ 7043 The Xth day of the Gregorian Calendar that this $(LREF SysTime) is on. 7044 +/ 7045 @property int dayOfGregorianCal() @safe const nothrow scope 7046 { 7047 immutable adjustedTime = adjTime; 7048 7049 // We have to add one because 0 would be midnight, January 1st, 1 A.D., 7050 // which would be the 1st day of the Gregorian Calendar, not the 0th. So, 7051 // simply casting to days is one day off. 7052 if (adjustedTime > 0) 7053 return cast(int) getUnitsFromHNSecs!"days"(adjustedTime) + 1; 7054 7055 long hnsecs = adjustedTime; 7056 immutable days = cast(int) splitUnitsFromHNSecs!"days"(hnsecs); 7057 7058 return hnsecs == 0 ? days + 1 : days; 7059 } 7060 7061 /// 7062 @safe unittest 7063 { 7064 import core.time; 7065 import std.datetime.date : DateTime; 7066 7067 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).dayOfGregorianCal == 1); 7068 assert(SysTime(DateTime(1, 12, 31, 23, 59, 59)).dayOfGregorianCal == 365); 7069 assert(SysTime(DateTime(2, 1, 1, 2, 2, 2)).dayOfGregorianCal == 366); 7070 7071 assert(SysTime(DateTime(0, 12, 31, 7, 7, 7)).dayOfGregorianCal == 0); 7072 assert(SysTime(DateTime(0, 1, 1, 19, 30, 0)).dayOfGregorianCal == -365); 7073 assert(SysTime(DateTime(-1, 12, 31, 4, 7, 0)).dayOfGregorianCal == -366); 7074 7075 assert(SysTime(DateTime(2000, 1, 1, 9, 30, 20)).dayOfGregorianCal == 730_120); 7076 assert(SysTime(DateTime(2010, 12, 31, 15, 45, 50)).dayOfGregorianCal == 734_137); 7077 } 7078 7079 @safe unittest 7080 { 7081 import core.time; 7082 // Test A.D. 7083 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).dayOfGregorianCal == 1); 7084 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1)).dayOfGregorianCal == 1); 7085 assert(SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)).dayOfGregorianCal == 1); 7086 7087 assert(SysTime(DateTime(1, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 1); 7088 assert(SysTime(DateTime(1, 1, 2, 12, 2, 9), msecs(212)).dayOfGregorianCal == 2); 7089 assert(SysTime(DateTime(1, 2, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 32); 7090 assert(SysTime(DateTime(2, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 366); 7091 assert(SysTime(DateTime(3, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 731); 7092 assert(SysTime(DateTime(4, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 1096); 7093 assert(SysTime(DateTime(5, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 1462); 7094 assert(SysTime(DateTime(50, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 17_898); 7095 assert(SysTime(DateTime(97, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 35_065); 7096 assert(SysTime(DateTime(100, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 36_160); 7097 assert(SysTime(DateTime(101, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 36_525); 7098 assert(SysTime(DateTime(105, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 37_986); 7099 assert(SysTime(DateTime(200, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 72_684); 7100 assert(SysTime(DateTime(201, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 73_049); 7101 assert(SysTime(DateTime(300, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 109_208); 7102 assert(SysTime(DateTime(301, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 109_573); 7103 assert(SysTime(DateTime(400, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 145_732); 7104 assert(SysTime(DateTime(401, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 146_098); 7105 assert(SysTime(DateTime(500, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 182_257); 7106 assert(SysTime(DateTime(501, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 182_622); 7107 assert(SysTime(DateTime(1000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 364_878); 7108 assert(SysTime(DateTime(1001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 365_243); 7109 assert(SysTime(DateTime(1600, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 584_023); 7110 assert(SysTime(DateTime(1601, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 584_389); 7111 assert(SysTime(DateTime(1900, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 693_596); 7112 assert(SysTime(DateTime(1901, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 693_961); 7113 assert(SysTime(DateTime(1945, 11, 12, 12, 2, 9), msecs(212)).dayOfGregorianCal == 710_347); 7114 assert(SysTime(DateTime(1999, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 729_755); 7115 assert(SysTime(DateTime(2000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 730_120); 7116 assert(SysTime(DateTime(2001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 730_486); 7117 7118 assert(SysTime(DateTime(2010, 1, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_773); 7119 assert(SysTime(DateTime(2010, 1, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_803); 7120 assert(SysTime(DateTime(2010, 2, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_804); 7121 assert(SysTime(DateTime(2010, 2, 28, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_831); 7122 assert(SysTime(DateTime(2010, 3, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_832); 7123 assert(SysTime(DateTime(2010, 3, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_862); 7124 assert(SysTime(DateTime(2010, 4, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_863); 7125 assert(SysTime(DateTime(2010, 4, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_892); 7126 assert(SysTime(DateTime(2010, 5, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_893); 7127 assert(SysTime(DateTime(2010, 5, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_923); 7128 assert(SysTime(DateTime(2010, 6, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_924); 7129 assert(SysTime(DateTime(2010, 6, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_953); 7130 assert(SysTime(DateTime(2010, 7, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_954); 7131 assert(SysTime(DateTime(2010, 7, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_984); 7132 assert(SysTime(DateTime(2010, 8, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_985); 7133 assert(SysTime(DateTime(2010, 8, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_015); 7134 assert(SysTime(DateTime(2010, 9, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_016); 7135 assert(SysTime(DateTime(2010, 9, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_045); 7136 assert(SysTime(DateTime(2010, 10, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_046); 7137 assert(SysTime(DateTime(2010, 10, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_076); 7138 assert(SysTime(DateTime(2010, 11, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_077); 7139 assert(SysTime(DateTime(2010, 11, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_106); 7140 assert(SysTime(DateTime(2010, 12, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_107); 7141 assert(SysTime(DateTime(2010, 12, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_137); 7142 7143 assert(SysTime(DateTime(2012, 2, 1, 0, 0, 0)).dayOfGregorianCal == 734_534); 7144 assert(SysTime(DateTime(2012, 2, 28, 0, 0, 0)).dayOfGregorianCal == 734_561); 7145 assert(SysTime(DateTime(2012, 2, 29, 0, 0, 0)).dayOfGregorianCal == 734_562); 7146 assert(SysTime(DateTime(2012, 3, 1, 0, 0, 0)).dayOfGregorianCal == 734_563); 7147 7148 // Test B.C. 7149 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)).dayOfGregorianCal == 0); 7150 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998)).dayOfGregorianCal == 0); 7151 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59)).dayOfGregorianCal == 0); 7152 assert(SysTime(DateTime(0, 12, 31, 0, 0, 0), hnsecs(1)).dayOfGregorianCal == 0); 7153 assert(SysTime(DateTime(0, 12, 31, 0, 0, 0)).dayOfGregorianCal == 0); 7154 7155 assert(SysTime(DateTime(-1, 12, 31, 23, 59, 59), hnsecs(9_999_999)).dayOfGregorianCal == -366); 7156 assert(SysTime(DateTime(-1, 12, 31, 23, 59, 59), hnsecs(9_999_998)).dayOfGregorianCal == -366); 7157 assert(SysTime(DateTime(-1, 12, 31, 23, 59, 59)).dayOfGregorianCal == -366); 7158 assert(SysTime(DateTime(-1, 12, 31, 0, 0, 0)).dayOfGregorianCal == -366); 7159 7160 assert(SysTime(DateTime(0, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == 0); 7161 assert(SysTime(DateTime(0, 12, 30, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1); 7162 assert(SysTime(DateTime(0, 12, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -30); 7163 assert(SysTime(DateTime(0, 11, 30, 12, 2, 9), msecs(212)).dayOfGregorianCal == -31); 7164 7165 assert(SysTime(DateTime(-1, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -366); 7166 assert(SysTime(DateTime(-1, 12, 30, 12, 2, 9), msecs(212)).dayOfGregorianCal == -367); 7167 assert(SysTime(DateTime(-1, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730); 7168 assert(SysTime(DateTime(-2, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -731); 7169 assert(SysTime(DateTime(-2, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1095); 7170 assert(SysTime(DateTime(-3, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1096); 7171 assert(SysTime(DateTime(-3, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1460); 7172 assert(SysTime(DateTime(-4, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1461); 7173 assert(SysTime(DateTime(-4, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1826); 7174 assert(SysTime(DateTime(-5, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1827); 7175 assert(SysTime(DateTime(-5, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -2191); 7176 assert(SysTime(DateTime(-9, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -3652); 7177 7178 assert(SysTime(DateTime(-49, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -18_262); 7179 assert(SysTime(DateTime(-50, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -18_627); 7180 assert(SysTime(DateTime(-97, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -35_794); 7181 assert(SysTime(DateTime(-99, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -36_160); 7182 assert(SysTime(DateTime(-99, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -36_524); 7183 assert(SysTime(DateTime(-100, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -36_889); 7184 assert(SysTime(DateTime(-101, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -37_254); 7185 assert(SysTime(DateTime(-105, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -38_715); 7186 assert(SysTime(DateTime(-200, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -73_413); 7187 assert(SysTime(DateTime(-201, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -73_778); 7188 assert(SysTime(DateTime(-300, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -109_937); 7189 assert(SysTime(DateTime(-301, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -110_302); 7190 assert(SysTime(DateTime(-400, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -146_097); 7191 assert(SysTime(DateTime(-400, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -146_462); 7192 assert(SysTime(DateTime(-401, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -146_827); 7193 assert(SysTime(DateTime(-499, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -182_621); 7194 assert(SysTime(DateTime(-500, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -182_986); 7195 assert(SysTime(DateTime(-501, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -183_351); 7196 assert(SysTime(DateTime(-1000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -365_607); 7197 assert(SysTime(DateTime(-1001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -365_972); 7198 assert(SysTime(DateTime(-1599, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -584_387); 7199 assert(SysTime(DateTime(-1600, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -584_388); 7200 assert(SysTime(DateTime(-1600, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -584_753); 7201 assert(SysTime(DateTime(-1601, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -585_118); 7202 assert(SysTime(DateTime(-1900, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -694_325); 7203 assert(SysTime(DateTime(-1901, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -694_690); 7204 assert(SysTime(DateTime(-1999, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730_484); 7205 assert(SysTime(DateTime(-2000, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730_485); 7206 assert(SysTime(DateTime(-2000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730_850); 7207 assert(SysTime(DateTime(-2001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -731_215); 7208 7209 assert(SysTime(DateTime(-2010, 1, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_502); 7210 assert(SysTime(DateTime(-2010, 1, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_472); 7211 assert(SysTime(DateTime(-2010, 2, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_471); 7212 assert(SysTime(DateTime(-2010, 2, 28, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_444); 7213 assert(SysTime(DateTime(-2010, 3, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_443); 7214 assert(SysTime(DateTime(-2010, 3, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_413); 7215 assert(SysTime(DateTime(-2010, 4, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_412); 7216 assert(SysTime(DateTime(-2010, 4, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_383); 7217 assert(SysTime(DateTime(-2010, 5, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_382); 7218 assert(SysTime(DateTime(-2010, 5, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_352); 7219 assert(SysTime(DateTime(-2010, 6, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_351); 7220 assert(SysTime(DateTime(-2010, 6, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_322); 7221 assert(SysTime(DateTime(-2010, 7, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_321); 7222 assert(SysTime(DateTime(-2010, 7, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_291); 7223 assert(SysTime(DateTime(-2010, 8, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_290); 7224 assert(SysTime(DateTime(-2010, 8, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_260); 7225 assert(SysTime(DateTime(-2010, 9, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_259); 7226 assert(SysTime(DateTime(-2010, 9, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_230); 7227 assert(SysTime(DateTime(-2010, 10, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_229); 7228 assert(SysTime(DateTime(-2010, 10, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_199); 7229 assert(SysTime(DateTime(-2010, 11, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_198); 7230 assert(SysTime(DateTime(-2010, 11, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_169); 7231 assert(SysTime(DateTime(-2010, 12, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_168); 7232 assert(SysTime(DateTime(-2010, 12, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_138); 7233 7234 assert(SysTime(DateTime(-2012, 2, 1, 0, 0, 0)).dayOfGregorianCal == -735_202); 7235 assert(SysTime(DateTime(-2012, 2, 28, 0, 0, 0)).dayOfGregorianCal == -735_175); 7236 assert(SysTime(DateTime(-2012, 2, 29, 0, 0, 0)).dayOfGregorianCal == -735_174); 7237 assert(SysTime(DateTime(-2012, 3, 1, 0, 0, 0)).dayOfGregorianCal == -735_173); 7238 7239 // Start of Hebrew Calendar 7240 assert(SysTime(DateTime(-3760, 9, 7, 0, 0, 0)).dayOfGregorianCal == -1_373_427); 7241 7242 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7243 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7244 assert(cst.dayOfGregorianCal == 729_941); 7245 assert(ist.dayOfGregorianCal == 729_941); 7246 7247 static void testScope(scope ref SysTime st) @safe 7248 { 7249 auto result = st.dayOfGregorianCal; 7250 } 7251 } 7252 7253 7254 // Test that the logic for the day of the Gregorian Calendar is consistent 7255 // between Date and SysTime. 7256 @safe unittest 7257 { 7258 import core.time; 7259 void test(Date date, SysTime st, size_t line = __LINE__) 7260 { 7261 if (date.dayOfGregorianCal != st.dayOfGregorianCal) 7262 { 7263 throw new AssertError(format("Date [%s] SysTime [%s]", date.dayOfGregorianCal, st.dayOfGregorianCal), 7264 __FILE__, line); 7265 } 7266 } 7267 7268 // Test A.D. 7269 test(Date(1, 1, 1), SysTime(DateTime(1, 1, 1, 0, 0, 0))); 7270 test(Date(1, 1, 2), SysTime(DateTime(1, 1, 2, 0, 0, 0), hnsecs(500))); 7271 test(Date(1, 2, 1), SysTime(DateTime(1, 2, 1, 0, 0, 0), hnsecs(50_000))); 7272 test(Date(2, 1, 1), SysTime(DateTime(2, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 7273 test(Date(3, 1, 1), SysTime(DateTime(3, 1, 1, 12, 13, 14))); 7274 test(Date(4, 1, 1), SysTime(DateTime(4, 1, 1, 12, 13, 14), hnsecs(500))); 7275 test(Date(5, 1, 1), SysTime(DateTime(5, 1, 1, 12, 13, 14), hnsecs(50_000))); 7276 test(Date(50, 1, 1), SysTime(DateTime(50, 1, 1, 12, 13, 14), hnsecs(9_999_999))); 7277 test(Date(97, 1, 1), SysTime(DateTime(97, 1, 1, 23, 59, 59))); 7278 test(Date(100, 1, 1), SysTime(DateTime(100, 1, 1, 23, 59, 59), hnsecs(500))); 7279 test(Date(101, 1, 1), SysTime(DateTime(101, 1, 1, 23, 59, 59), hnsecs(50_000))); 7280 test(Date(105, 1, 1), SysTime(DateTime(105, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7281 test(Date(200, 1, 1), SysTime(DateTime(200, 1, 1, 0, 0, 0))); 7282 test(Date(201, 1, 1), SysTime(DateTime(201, 1, 1, 0, 0, 0), hnsecs(500))); 7283 test(Date(300, 1, 1), SysTime(DateTime(300, 1, 1, 0, 0, 0), hnsecs(50_000))); 7284 test(Date(301, 1, 1), SysTime(DateTime(301, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 7285 test(Date(400, 1, 1), SysTime(DateTime(400, 1, 1, 12, 13, 14))); 7286 test(Date(401, 1, 1), SysTime(DateTime(401, 1, 1, 12, 13, 14), hnsecs(500))); 7287 test(Date(500, 1, 1), SysTime(DateTime(500, 1, 1, 12, 13, 14), hnsecs(50_000))); 7288 test(Date(501, 1, 1), SysTime(DateTime(501, 1, 1, 12, 13, 14), hnsecs(9_999_999))); 7289 test(Date(1000, 1, 1), SysTime(DateTime(1000, 1, 1, 23, 59, 59))); 7290 test(Date(1001, 1, 1), SysTime(DateTime(1001, 1, 1, 23, 59, 59), hnsecs(500))); 7291 test(Date(1600, 1, 1), SysTime(DateTime(1600, 1, 1, 23, 59, 59), hnsecs(50_000))); 7292 test(Date(1601, 1, 1), SysTime(DateTime(1601, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7293 test(Date(1900, 1, 1), SysTime(DateTime(1900, 1, 1, 0, 0, 0))); 7294 test(Date(1901, 1, 1), SysTime(DateTime(1901, 1, 1, 0, 0, 0), hnsecs(500))); 7295 test(Date(1945, 11, 12), SysTime(DateTime(1945, 11, 12, 0, 0, 0), hnsecs(50_000))); 7296 test(Date(1999, 1, 1), SysTime(DateTime(1999, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 7297 test(Date(1999, 7, 6), SysTime(DateTime(1999, 7, 6, 12, 13, 14))); 7298 test(Date(2000, 1, 1), SysTime(DateTime(2000, 1, 1, 12, 13, 14), hnsecs(500))); 7299 test(Date(2001, 1, 1), SysTime(DateTime(2001, 1, 1, 12, 13, 14), hnsecs(50_000))); 7300 7301 test(Date(2010, 1, 1), SysTime(DateTime(2010, 1, 1, 12, 13, 14), hnsecs(9_999_999))); 7302 test(Date(2010, 1, 31), SysTime(DateTime(2010, 1, 31, 23, 0, 0))); 7303 test(Date(2010, 2, 1), SysTime(DateTime(2010, 2, 1, 23, 59, 59), hnsecs(500))); 7304 test(Date(2010, 2, 28), SysTime(DateTime(2010, 2, 28, 23, 59, 59), hnsecs(50_000))); 7305 test(Date(2010, 3, 1), SysTime(DateTime(2010, 3, 1, 23, 59, 59), hnsecs(9_999_999))); 7306 test(Date(2010, 3, 31), SysTime(DateTime(2010, 3, 31, 0, 0, 0))); 7307 test(Date(2010, 4, 1), SysTime(DateTime(2010, 4, 1, 0, 0, 0), hnsecs(500))); 7308 test(Date(2010, 4, 30), SysTime(DateTime(2010, 4, 30, 0, 0, 0), hnsecs(50_000))); 7309 test(Date(2010, 5, 1), SysTime(DateTime(2010, 5, 1, 0, 0, 0), hnsecs(9_999_999))); 7310 test(Date(2010, 5, 31), SysTime(DateTime(2010, 5, 31, 12, 13, 14))); 7311 test(Date(2010, 6, 1), SysTime(DateTime(2010, 6, 1, 12, 13, 14), hnsecs(500))); 7312 test(Date(2010, 6, 30), SysTime(DateTime(2010, 6, 30, 12, 13, 14), hnsecs(50_000))); 7313 test(Date(2010, 7, 1), SysTime(DateTime(2010, 7, 1, 12, 13, 14), hnsecs(9_999_999))); 7314 test(Date(2010, 7, 31), SysTime(DateTime(2010, 7, 31, 23, 59, 59))); 7315 test(Date(2010, 8, 1), SysTime(DateTime(2010, 8, 1, 23, 59, 59), hnsecs(500))); 7316 test(Date(2010, 8, 31), SysTime(DateTime(2010, 8, 31, 23, 59, 59), hnsecs(50_000))); 7317 test(Date(2010, 9, 1), SysTime(DateTime(2010, 9, 1, 23, 59, 59), hnsecs(9_999_999))); 7318 test(Date(2010, 9, 30), SysTime(DateTime(2010, 9, 30, 12, 0, 0))); 7319 test(Date(2010, 10, 1), SysTime(DateTime(2010, 10, 1, 0, 12, 0), hnsecs(500))); 7320 test(Date(2010, 10, 31), SysTime(DateTime(2010, 10, 31, 0, 0, 12), hnsecs(50_000))); 7321 test(Date(2010, 11, 1), SysTime(DateTime(2010, 11, 1, 23, 0, 0), hnsecs(9_999_999))); 7322 test(Date(2010, 11, 30), SysTime(DateTime(2010, 11, 30, 0, 59, 0))); 7323 test(Date(2010, 12, 1), SysTime(DateTime(2010, 12, 1, 0, 0, 59), hnsecs(500))); 7324 test(Date(2010, 12, 31), SysTime(DateTime(2010, 12, 31, 0, 59, 59), hnsecs(50_000))); 7325 7326 test(Date(2012, 2, 1), SysTime(DateTime(2012, 2, 1, 23, 0, 59), hnsecs(9_999_999))); 7327 test(Date(2012, 2, 28), SysTime(DateTime(2012, 2, 28, 23, 59, 0))); 7328 test(Date(2012, 2, 29), SysTime(DateTime(2012, 2, 29, 7, 7, 7), hnsecs(7))); 7329 test(Date(2012, 3, 1), SysTime(DateTime(2012, 3, 1, 7, 7, 7), hnsecs(7))); 7330 7331 // Test B.C. 7332 test(Date(0, 12, 31), SysTime(DateTime(0, 12, 31, 0, 0, 0))); 7333 test(Date(0, 12, 30), SysTime(DateTime(0, 12, 30, 0, 0, 0), hnsecs(500))); 7334 test(Date(0, 12, 1), SysTime(DateTime(0, 12, 1, 0, 0, 0), hnsecs(50_000))); 7335 test(Date(0, 11, 30), SysTime(DateTime(0, 11, 30, 0, 0, 0), hnsecs(9_999_999))); 7336 7337 test(Date(-1, 12, 31), SysTime(DateTime(-1, 12, 31, 12, 13, 14))); 7338 test(Date(-1, 12, 30), SysTime(DateTime(-1, 12, 30, 12, 13, 14), hnsecs(500))); 7339 test(Date(-1, 1, 1), SysTime(DateTime(-1, 1, 1, 12, 13, 14), hnsecs(50_000))); 7340 test(Date(-2, 12, 31), SysTime(DateTime(-2, 12, 31, 12, 13, 14), hnsecs(9_999_999))); 7341 test(Date(-2, 1, 1), SysTime(DateTime(-2, 1, 1, 23, 59, 59))); 7342 test(Date(-3, 12, 31), SysTime(DateTime(-3, 12, 31, 23, 59, 59), hnsecs(500))); 7343 test(Date(-3, 1, 1), SysTime(DateTime(-3, 1, 1, 23, 59, 59), hnsecs(50_000))); 7344 test(Date(-4, 12, 31), SysTime(DateTime(-4, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 7345 test(Date(-4, 1, 1), SysTime(DateTime(-4, 1, 1, 0, 0, 0))); 7346 test(Date(-5, 12, 31), SysTime(DateTime(-5, 12, 31, 0, 0, 0), hnsecs(500))); 7347 test(Date(-5, 1, 1), SysTime(DateTime(-5, 1, 1, 0, 0, 0), hnsecs(50_000))); 7348 test(Date(-9, 1, 1), SysTime(DateTime(-9, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 7349 7350 test(Date(-49, 1, 1), SysTime(DateTime(-49, 1, 1, 12, 13, 14))); 7351 test(Date(-50, 1, 1), SysTime(DateTime(-50, 1, 1, 12, 13, 14), hnsecs(500))); 7352 test(Date(-97, 1, 1), SysTime(DateTime(-97, 1, 1, 12, 13, 14), hnsecs(50_000))); 7353 test(Date(-99, 12, 31), SysTime(DateTime(-99, 12, 31, 12, 13, 14), hnsecs(9_999_999))); 7354 test(Date(-99, 1, 1), SysTime(DateTime(-99, 1, 1, 23, 59, 59))); 7355 test(Date(-100, 1, 1), SysTime(DateTime(-100, 1, 1, 23, 59, 59), hnsecs(500))); 7356 test(Date(-101, 1, 1), SysTime(DateTime(-101, 1, 1, 23, 59, 59), hnsecs(50_000))); 7357 test(Date(-105, 1, 1), SysTime(DateTime(-105, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7358 test(Date(-200, 1, 1), SysTime(DateTime(-200, 1, 1, 0, 0, 0))); 7359 test(Date(-201, 1, 1), SysTime(DateTime(-201, 1, 1, 0, 0, 0), hnsecs(500))); 7360 test(Date(-300, 1, 1), SysTime(DateTime(-300, 1, 1, 0, 0, 0), hnsecs(50_000))); 7361 test(Date(-301, 1, 1), SysTime(DateTime(-301, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 7362 test(Date(-400, 12, 31), SysTime(DateTime(-400, 12, 31, 12, 13, 14))); 7363 test(Date(-400, 1, 1), SysTime(DateTime(-400, 1, 1, 12, 13, 14), hnsecs(500))); 7364 test(Date(-401, 1, 1), SysTime(DateTime(-401, 1, 1, 12, 13, 14), hnsecs(50_000))); 7365 test(Date(-499, 1, 1), SysTime(DateTime(-499, 1, 1, 12, 13, 14), hnsecs(9_999_999))); 7366 test(Date(-500, 1, 1), SysTime(DateTime(-500, 1, 1, 23, 59, 59))); 7367 test(Date(-501, 1, 1), SysTime(DateTime(-501, 1, 1, 23, 59, 59), hnsecs(500))); 7368 test(Date(-1000, 1, 1), SysTime(DateTime(-1000, 1, 1, 23, 59, 59), hnsecs(50_000))); 7369 test(Date(-1001, 1, 1), SysTime(DateTime(-1001, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7370 test(Date(-1599, 1, 1), SysTime(DateTime(-1599, 1, 1, 0, 0, 0))); 7371 test(Date(-1600, 12, 31), SysTime(DateTime(-1600, 12, 31, 0, 0, 0), hnsecs(500))); 7372 test(Date(-1600, 1, 1), SysTime(DateTime(-1600, 1, 1, 0, 0, 0), hnsecs(50_000))); 7373 test(Date(-1601, 1, 1), SysTime(DateTime(-1601, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 7374 test(Date(-1900, 1, 1), SysTime(DateTime(-1900, 1, 1, 12, 13, 14))); 7375 test(Date(-1901, 1, 1), SysTime(DateTime(-1901, 1, 1, 12, 13, 14), hnsecs(500))); 7376 test(Date(-1999, 1, 1), SysTime(DateTime(-1999, 1, 1, 12, 13, 14), hnsecs(50_000))); 7377 test(Date(-1999, 7, 6), SysTime(DateTime(-1999, 7, 6, 12, 13, 14), hnsecs(9_999_999))); 7378 test(Date(-2000, 12, 31), SysTime(DateTime(-2000, 12, 31, 23, 59, 59))); 7379 test(Date(-2000, 1, 1), SysTime(DateTime(-2000, 1, 1, 23, 59, 59), hnsecs(500))); 7380 test(Date(-2001, 1, 1), SysTime(DateTime(-2001, 1, 1, 23, 59, 59), hnsecs(50_000))); 7381 7382 test(Date(-2010, 1, 1), SysTime(DateTime(-2010, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7383 test(Date(-2010, 1, 31), SysTime(DateTime(-2010, 1, 31, 0, 0, 0))); 7384 test(Date(-2010, 2, 1), SysTime(DateTime(-2010, 2, 1, 0, 0, 0), hnsecs(500))); 7385 test(Date(-2010, 2, 28), SysTime(DateTime(-2010, 2, 28, 0, 0, 0), hnsecs(50_000))); 7386 test(Date(-2010, 3, 1), SysTime(DateTime(-2010, 3, 1, 0, 0, 0), hnsecs(9_999_999))); 7387 test(Date(-2010, 3, 31), SysTime(DateTime(-2010, 3, 31, 12, 13, 14))); 7388 test(Date(-2010, 4, 1), SysTime(DateTime(-2010, 4, 1, 12, 13, 14), hnsecs(500))); 7389 test(Date(-2010, 4, 30), SysTime(DateTime(-2010, 4, 30, 12, 13, 14), hnsecs(50_000))); 7390 test(Date(-2010, 5, 1), SysTime(DateTime(-2010, 5, 1, 12, 13, 14), hnsecs(9_999_999))); 7391 test(Date(-2010, 5, 31), SysTime(DateTime(-2010, 5, 31, 23, 59, 59))); 7392 test(Date(-2010, 6, 1), SysTime(DateTime(-2010, 6, 1, 23, 59, 59), hnsecs(500))); 7393 test(Date(-2010, 6, 30), SysTime(DateTime(-2010, 6, 30, 23, 59, 59), hnsecs(50_000))); 7394 test(Date(-2010, 7, 1), SysTime(DateTime(-2010, 7, 1, 23, 59, 59), hnsecs(9_999_999))); 7395 test(Date(-2010, 7, 31), SysTime(DateTime(-2010, 7, 31, 0, 0, 0))); 7396 test(Date(-2010, 8, 1), SysTime(DateTime(-2010, 8, 1, 0, 0, 0), hnsecs(500))); 7397 test(Date(-2010, 8, 31), SysTime(DateTime(-2010, 8, 31, 0, 0, 0), hnsecs(50_000))); 7398 test(Date(-2010, 9, 1), SysTime(DateTime(-2010, 9, 1, 0, 0, 0), hnsecs(9_999_999))); 7399 test(Date(-2010, 9, 30), SysTime(DateTime(-2010, 9, 30, 12, 0, 0))); 7400 test(Date(-2010, 10, 1), SysTime(DateTime(-2010, 10, 1, 0, 12, 0), hnsecs(500))); 7401 test(Date(-2010, 10, 31), SysTime(DateTime(-2010, 10, 31, 0, 0, 12), hnsecs(50_000))); 7402 test(Date(-2010, 11, 1), SysTime(DateTime(-2010, 11, 1, 23, 0, 0), hnsecs(9_999_999))); 7403 test(Date(-2010, 11, 30), SysTime(DateTime(-2010, 11, 30, 0, 59, 0))); 7404 test(Date(-2010, 12, 1), SysTime(DateTime(-2010, 12, 1, 0, 0, 59), hnsecs(500))); 7405 test(Date(-2010, 12, 31), SysTime(DateTime(-2010, 12, 31, 0, 59, 59), hnsecs(50_000))); 7406 7407 test(Date(-2012, 2, 1), SysTime(DateTime(-2012, 2, 1, 23, 0, 59), hnsecs(9_999_999))); 7408 test(Date(-2012, 2, 28), SysTime(DateTime(-2012, 2, 28, 23, 59, 0))); 7409 test(Date(-2012, 2, 29), SysTime(DateTime(-2012, 2, 29, 7, 7, 7), hnsecs(7))); 7410 test(Date(-2012, 3, 1), SysTime(DateTime(-2012, 3, 1, 7, 7, 7), hnsecs(7))); 7411 7412 test(Date(-3760, 9, 7), SysTime(DateTime(-3760, 9, 7, 0, 0, 0))); 7413 } 7414 7415 7416 /++ 7417 The Xth day of the Gregorian Calendar that this $(LREF SysTime) is on. 7418 Setting this property does not affect the time portion of $(LREF SysTime). 7419 7420 Params: 7421 days = The day of the Gregorian Calendar to set this $(LREF SysTime) 7422 to. 7423 +/ 7424 @property void dayOfGregorianCal(int days) @safe nothrow scope 7425 { 7426 auto hnsecs = adjTime; 7427 hnsecs = removeUnitsFromHNSecs!"days"(hnsecs); 7428 7429 if (hnsecs < 0) 7430 hnsecs += convert!("hours", "hnsecs")(24); 7431 7432 if (--days < 0) 7433 { 7434 hnsecs -= convert!("hours", "hnsecs")(24); 7435 ++days; 7436 } 7437 7438 immutable newDaysHNSecs = convert!("days", "hnsecs")(days); 7439 7440 adjTime = newDaysHNSecs + hnsecs; 7441 } 7442 7443 /// 7444 @safe unittest 7445 { 7446 import core.time; 7447 import std.datetime.date : DateTime; 7448 7449 auto st = SysTime(DateTime(0, 1, 1, 12, 0, 0)); 7450 st.dayOfGregorianCal = 1; 7451 assert(st == SysTime(DateTime(1, 1, 1, 12, 0, 0))); 7452 7453 st.dayOfGregorianCal = 365; 7454 assert(st == SysTime(DateTime(1, 12, 31, 12, 0, 0))); 7455 7456 st.dayOfGregorianCal = 366; 7457 assert(st == SysTime(DateTime(2, 1, 1, 12, 0, 0))); 7458 7459 st.dayOfGregorianCal = 0; 7460 assert(st == SysTime(DateTime(0, 12, 31, 12, 0, 0))); 7461 7462 st.dayOfGregorianCal = -365; 7463 assert(st == SysTime(DateTime(-0, 1, 1, 12, 0, 0))); 7464 7465 st.dayOfGregorianCal = -366; 7466 assert(st == SysTime(DateTime(-1, 12, 31, 12, 0, 0))); 7467 7468 st.dayOfGregorianCal = 730_120; 7469 assert(st == SysTime(DateTime(2000, 1, 1, 12, 0, 0))); 7470 7471 st.dayOfGregorianCal = 734_137; 7472 assert(st == SysTime(DateTime(2010, 12, 31, 12, 0, 0))); 7473 } 7474 7475 @safe unittest 7476 { 7477 import core.time; 7478 void testST(SysTime orig, int day, SysTime expected, size_t line = __LINE__) @safe 7479 { 7480 orig.dayOfGregorianCal = day; 7481 if (orig != expected) 7482 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 7483 } 7484 7485 // Test A.D. 7486 testST(SysTime(DateTime(1, 1, 1, 0, 0, 0)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 7487 testST(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 7488 testST(SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)), 1, 7489 SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7490 7491 // Test B.C. 7492 testST(SysTime(DateTime(0, 1, 1, 0, 0, 0)), 0, SysTime(DateTime(0, 12, 31, 0, 0, 0))); 7493 testST(SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)), 0, 7494 SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 7495 testST(SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(1)), 0, 7496 SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1))); 7497 testST(SysTime(DateTime(0, 1, 1, 23, 59, 59)), 0, SysTime(DateTime(0, 12, 31, 23, 59, 59))); 7498 7499 // Test Both. 7500 testST(SysTime(DateTime(-512, 7, 20, 0, 0, 0)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 7501 testST(SysTime(DateTime(-513, 6, 6, 0, 0, 0), hnsecs(1)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 7502 testST(SysTime(DateTime(-511, 5, 7, 23, 59, 59), hnsecs(9_999_999)), 1, 7503 SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7504 7505 testST(SysTime(DateTime(1607, 4, 8, 0, 0, 0)), 0, SysTime(DateTime(0, 12, 31, 0, 0, 0))); 7506 testST(SysTime(DateTime(1500, 3, 9, 23, 59, 59), hnsecs(9_999_999)), 0, 7507 SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 7508 testST(SysTime(DateTime(999, 2, 10, 23, 59, 59), hnsecs(1)), 0, 7509 SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1))); 7510 testST(SysTime(DateTime(2007, 12, 11, 23, 59, 59)), 0, SysTime(DateTime(0, 12, 31, 23, 59, 59))); 7511 7512 7513 auto st = SysTime(DateTime(1, 1, 1, 12, 2, 9), msecs(212)); 7514 7515 void testST2(int day, SysTime expected, size_t line = __LINE__) @safe 7516 { 7517 st.dayOfGregorianCal = day; 7518 if (st != expected) 7519 throw new AssertError(format("Failed. actual [%s] != expected [%s]", st, expected), __FILE__, line); 7520 } 7521 7522 // Test A.D. 7523 testST2(1, SysTime(DateTime(1, 1, 1, 12, 2, 9), msecs(212))); 7524 testST2(2, SysTime(DateTime(1, 1, 2, 12, 2, 9), msecs(212))); 7525 testST2(32, SysTime(DateTime(1, 2, 1, 12, 2, 9), msecs(212))); 7526 testST2(366, SysTime(DateTime(2, 1, 1, 12, 2, 9), msecs(212))); 7527 testST2(731, SysTime(DateTime(3, 1, 1, 12, 2, 9), msecs(212))); 7528 testST2(1096, SysTime(DateTime(4, 1, 1, 12, 2, 9), msecs(212))); 7529 testST2(1462, SysTime(DateTime(5, 1, 1, 12, 2, 9), msecs(212))); 7530 testST2(17_898, SysTime(DateTime(50, 1, 1, 12, 2, 9), msecs(212))); 7531 testST2(35_065, SysTime(DateTime(97, 1, 1, 12, 2, 9), msecs(212))); 7532 testST2(36_160, SysTime(DateTime(100, 1, 1, 12, 2, 9), msecs(212))); 7533 testST2(36_525, SysTime(DateTime(101, 1, 1, 12, 2, 9), msecs(212))); 7534 testST2(37_986, SysTime(DateTime(105, 1, 1, 12, 2, 9), msecs(212))); 7535 testST2(72_684, SysTime(DateTime(200, 1, 1, 12, 2, 9), msecs(212))); 7536 testST2(73_049, SysTime(DateTime(201, 1, 1, 12, 2, 9), msecs(212))); 7537 testST2(109_208, SysTime(DateTime(300, 1, 1, 12, 2, 9), msecs(212))); 7538 testST2(109_573, SysTime(DateTime(301, 1, 1, 12, 2, 9), msecs(212))); 7539 testST2(145_732, SysTime(DateTime(400, 1, 1, 12, 2, 9), msecs(212))); 7540 testST2(146_098, SysTime(DateTime(401, 1, 1, 12, 2, 9), msecs(212))); 7541 testST2(182_257, SysTime(DateTime(500, 1, 1, 12, 2, 9), msecs(212))); 7542 testST2(182_622, SysTime(DateTime(501, 1, 1, 12, 2, 9), msecs(212))); 7543 testST2(364_878, SysTime(DateTime(1000, 1, 1, 12, 2, 9), msecs(212))); 7544 testST2(365_243, SysTime(DateTime(1001, 1, 1, 12, 2, 9), msecs(212))); 7545 testST2(584_023, SysTime(DateTime(1600, 1, 1, 12, 2, 9), msecs(212))); 7546 testST2(584_389, SysTime(DateTime(1601, 1, 1, 12, 2, 9), msecs(212))); 7547 testST2(693_596, SysTime(DateTime(1900, 1, 1, 12, 2, 9), msecs(212))); 7548 testST2(693_961, SysTime(DateTime(1901, 1, 1, 12, 2, 9), msecs(212))); 7549 testST2(729_755, SysTime(DateTime(1999, 1, 1, 12, 2, 9), msecs(212))); 7550 testST2(730_120, SysTime(DateTime(2000, 1, 1, 12, 2, 9), msecs(212))); 7551 testST2(730_486, SysTime(DateTime(2001, 1, 1, 12, 2, 9), msecs(212))); 7552 7553 testST2(733_773, SysTime(DateTime(2010, 1, 1, 12, 2, 9), msecs(212))); 7554 testST2(733_803, SysTime(DateTime(2010, 1, 31, 12, 2, 9), msecs(212))); 7555 testST2(733_804, SysTime(DateTime(2010, 2, 1, 12, 2, 9), msecs(212))); 7556 testST2(733_831, SysTime(DateTime(2010, 2, 28, 12, 2, 9), msecs(212))); 7557 testST2(733_832, SysTime(DateTime(2010, 3, 1, 12, 2, 9), msecs(212))); 7558 testST2(733_862, SysTime(DateTime(2010, 3, 31, 12, 2, 9), msecs(212))); 7559 testST2(733_863, SysTime(DateTime(2010, 4, 1, 12, 2, 9), msecs(212))); 7560 testST2(733_892, SysTime(DateTime(2010, 4, 30, 12, 2, 9), msecs(212))); 7561 testST2(733_893, SysTime(DateTime(2010, 5, 1, 12, 2, 9), msecs(212))); 7562 testST2(733_923, SysTime(DateTime(2010, 5, 31, 12, 2, 9), msecs(212))); 7563 testST2(733_924, SysTime(DateTime(2010, 6, 1, 12, 2, 9), msecs(212))); 7564 testST2(733_953, SysTime(DateTime(2010, 6, 30, 12, 2, 9), msecs(212))); 7565 testST2(733_954, SysTime(DateTime(2010, 7, 1, 12, 2, 9), msecs(212))); 7566 testST2(733_984, SysTime(DateTime(2010, 7, 31, 12, 2, 9), msecs(212))); 7567 testST2(733_985, SysTime(DateTime(2010, 8, 1, 12, 2, 9), msecs(212))); 7568 testST2(734_015, SysTime(DateTime(2010, 8, 31, 12, 2, 9), msecs(212))); 7569 testST2(734_016, SysTime(DateTime(2010, 9, 1, 12, 2, 9), msecs(212))); 7570 testST2(734_045, SysTime(DateTime(2010, 9, 30, 12, 2, 9), msecs(212))); 7571 testST2(734_046, SysTime(DateTime(2010, 10, 1, 12, 2, 9), msecs(212))); 7572 testST2(734_076, SysTime(DateTime(2010, 10, 31, 12, 2, 9), msecs(212))); 7573 testST2(734_077, SysTime(DateTime(2010, 11, 1, 12, 2, 9), msecs(212))); 7574 testST2(734_106, SysTime(DateTime(2010, 11, 30, 12, 2, 9), msecs(212))); 7575 testST2(734_107, SysTime(DateTime(2010, 12, 1, 12, 2, 9), msecs(212))); 7576 testST2(734_137, SysTime(DateTime(2010, 12, 31, 12, 2, 9), msecs(212))); 7577 7578 testST2(734_534, SysTime(DateTime(2012, 2, 1, 12, 2, 9), msecs(212))); 7579 testST2(734_561, SysTime(DateTime(2012, 2, 28, 12, 2, 9), msecs(212))); 7580 testST2(734_562, SysTime(DateTime(2012, 2, 29, 12, 2, 9), msecs(212))); 7581 testST2(734_563, SysTime(DateTime(2012, 3, 1, 12, 2, 9), msecs(212))); 7582 7583 testST2(734_534, SysTime(DateTime(2012, 2, 1, 12, 2, 9), msecs(212))); 7584 7585 testST2(734_561, SysTime(DateTime(2012, 2, 28, 12, 2, 9), msecs(212))); 7586 testST2(734_562, SysTime(DateTime(2012, 2, 29, 12, 2, 9), msecs(212))); 7587 testST2(734_563, SysTime(DateTime(2012, 3, 1, 12, 2, 9), msecs(212))); 7588 7589 // Test B.C. 7590 testST2(0, SysTime(DateTime(0, 12, 31, 12, 2, 9), msecs(212))); 7591 testST2(-1, SysTime(DateTime(0, 12, 30, 12, 2, 9), msecs(212))); 7592 testST2(-30, SysTime(DateTime(0, 12, 1, 12, 2, 9), msecs(212))); 7593 testST2(-31, SysTime(DateTime(0, 11, 30, 12, 2, 9), msecs(212))); 7594 7595 testST2(-366, SysTime(DateTime(-1, 12, 31, 12, 2, 9), msecs(212))); 7596 testST2(-367, SysTime(DateTime(-1, 12, 30, 12, 2, 9), msecs(212))); 7597 testST2(-730, SysTime(DateTime(-1, 1, 1, 12, 2, 9), msecs(212))); 7598 testST2(-731, SysTime(DateTime(-2, 12, 31, 12, 2, 9), msecs(212))); 7599 testST2(-1095, SysTime(DateTime(-2, 1, 1, 12, 2, 9), msecs(212))); 7600 testST2(-1096, SysTime(DateTime(-3, 12, 31, 12, 2, 9), msecs(212))); 7601 testST2(-1460, SysTime(DateTime(-3, 1, 1, 12, 2, 9), msecs(212))); 7602 testST2(-1461, SysTime(DateTime(-4, 12, 31, 12, 2, 9), msecs(212))); 7603 testST2(-1826, SysTime(DateTime(-4, 1, 1, 12, 2, 9), msecs(212))); 7604 testST2(-1827, SysTime(DateTime(-5, 12, 31, 12, 2, 9), msecs(212))); 7605 testST2(-2191, SysTime(DateTime(-5, 1, 1, 12, 2, 9), msecs(212))); 7606 testST2(-3652, SysTime(DateTime(-9, 1, 1, 12, 2, 9), msecs(212))); 7607 7608 testST2(-18_262, SysTime(DateTime(-49, 1, 1, 12, 2, 9), msecs(212))); 7609 testST2(-18_627, SysTime(DateTime(-50, 1, 1, 12, 2, 9), msecs(212))); 7610 testST2(-35_794, SysTime(DateTime(-97, 1, 1, 12, 2, 9), msecs(212))); 7611 testST2(-36_160, SysTime(DateTime(-99, 12, 31, 12, 2, 9), msecs(212))); 7612 testST2(-36_524, SysTime(DateTime(-99, 1, 1, 12, 2, 9), msecs(212))); 7613 testST2(-36_889, SysTime(DateTime(-100, 1, 1, 12, 2, 9), msecs(212))); 7614 testST2(-37_254, SysTime(DateTime(-101, 1, 1, 12, 2, 9), msecs(212))); 7615 testST2(-38_715, SysTime(DateTime(-105, 1, 1, 12, 2, 9), msecs(212))); 7616 testST2(-73_413, SysTime(DateTime(-200, 1, 1, 12, 2, 9), msecs(212))); 7617 testST2(-73_778, SysTime(DateTime(-201, 1, 1, 12, 2, 9), msecs(212))); 7618 testST2(-109_937, SysTime(DateTime(-300, 1, 1, 12, 2, 9), msecs(212))); 7619 testST2(-110_302, SysTime(DateTime(-301, 1, 1, 12, 2, 9), msecs(212))); 7620 testST2(-146_097, SysTime(DateTime(-400, 12, 31, 12, 2, 9), msecs(212))); 7621 testST2(-146_462, SysTime(DateTime(-400, 1, 1, 12, 2, 9), msecs(212))); 7622 testST2(-146_827, SysTime(DateTime(-401, 1, 1, 12, 2, 9), msecs(212))); 7623 testST2(-182_621, SysTime(DateTime(-499, 1, 1, 12, 2, 9), msecs(212))); 7624 testST2(-182_986, SysTime(DateTime(-500, 1, 1, 12, 2, 9), msecs(212))); 7625 testST2(-183_351, SysTime(DateTime(-501, 1, 1, 12, 2, 9), msecs(212))); 7626 testST2(-365_607, SysTime(DateTime(-1000, 1, 1, 12, 2, 9), msecs(212))); 7627 testST2(-365_972, SysTime(DateTime(-1001, 1, 1, 12, 2, 9), msecs(212))); 7628 testST2(-584_387, SysTime(DateTime(-1599, 1, 1, 12, 2, 9), msecs(212))); 7629 testST2(-584_388, SysTime(DateTime(-1600, 12, 31, 12, 2, 9), msecs(212))); 7630 testST2(-584_753, SysTime(DateTime(-1600, 1, 1, 12, 2, 9), msecs(212))); 7631 testST2(-585_118, SysTime(DateTime(-1601, 1, 1, 12, 2, 9), msecs(212))); 7632 testST2(-694_325, SysTime(DateTime(-1900, 1, 1, 12, 2, 9), msecs(212))); 7633 testST2(-694_690, SysTime(DateTime(-1901, 1, 1, 12, 2, 9), msecs(212))); 7634 testST2(-730_484, SysTime(DateTime(-1999, 1, 1, 12, 2, 9), msecs(212))); 7635 testST2(-730_485, SysTime(DateTime(-2000, 12, 31, 12, 2, 9), msecs(212))); 7636 testST2(-730_850, SysTime(DateTime(-2000, 1, 1, 12, 2, 9), msecs(212))); 7637 testST2(-731_215, SysTime(DateTime(-2001, 1, 1, 12, 2, 9), msecs(212))); 7638 7639 testST2(-734_502, SysTime(DateTime(-2010, 1, 1, 12, 2, 9), msecs(212))); 7640 testST2(-734_472, SysTime(DateTime(-2010, 1, 31, 12, 2, 9), msecs(212))); 7641 testST2(-734_471, SysTime(DateTime(-2010, 2, 1, 12, 2, 9), msecs(212))); 7642 testST2(-734_444, SysTime(DateTime(-2010, 2, 28, 12, 2, 9), msecs(212))); 7643 testST2(-734_443, SysTime(DateTime(-2010, 3, 1, 12, 2, 9), msecs(212))); 7644 testST2(-734_413, SysTime(DateTime(-2010, 3, 31, 12, 2, 9), msecs(212))); 7645 testST2(-734_412, SysTime(DateTime(-2010, 4, 1, 12, 2, 9), msecs(212))); 7646 testST2(-734_383, SysTime(DateTime(-2010, 4, 30, 12, 2, 9), msecs(212))); 7647 testST2(-734_382, SysTime(DateTime(-2010, 5, 1, 12, 2, 9), msecs(212))); 7648 testST2(-734_352, SysTime(DateTime(-2010, 5, 31, 12, 2, 9), msecs(212))); 7649 testST2(-734_351, SysTime(DateTime(-2010, 6, 1, 12, 2, 9), msecs(212))); 7650 testST2(-734_322, SysTime(DateTime(-2010, 6, 30, 12, 2, 9), msecs(212))); 7651 testST2(-734_321, SysTime(DateTime(-2010, 7, 1, 12, 2, 9), msecs(212))); 7652 testST2(-734_291, SysTime(DateTime(-2010, 7, 31, 12, 2, 9), msecs(212))); 7653 testST2(-734_290, SysTime(DateTime(-2010, 8, 1, 12, 2, 9), msecs(212))); 7654 testST2(-734_260, SysTime(DateTime(-2010, 8, 31, 12, 2, 9), msecs(212))); 7655 testST2(-734_259, SysTime(DateTime(-2010, 9, 1, 12, 2, 9), msecs(212))); 7656 testST2(-734_230, SysTime(DateTime(-2010, 9, 30, 12, 2, 9), msecs(212))); 7657 testST2(-734_229, SysTime(DateTime(-2010, 10, 1, 12, 2, 9), msecs(212))); 7658 testST2(-734_199, SysTime(DateTime(-2010, 10, 31, 12, 2, 9), msecs(212))); 7659 testST2(-734_198, SysTime(DateTime(-2010, 11, 1, 12, 2, 9), msecs(212))); 7660 testST2(-734_169, SysTime(DateTime(-2010, 11, 30, 12, 2, 9), msecs(212))); 7661 testST2(-734_168, SysTime(DateTime(-2010, 12, 1, 12, 2, 9), msecs(212))); 7662 testST2(-734_138, SysTime(DateTime(-2010, 12, 31, 12, 2, 9), msecs(212))); 7663 7664 testST2(-735_202, SysTime(DateTime(-2012, 2, 1, 12, 2, 9), msecs(212))); 7665 testST2(-735_175, SysTime(DateTime(-2012, 2, 28, 12, 2, 9), msecs(212))); 7666 testST2(-735_174, SysTime(DateTime(-2012, 2, 29, 12, 2, 9), msecs(212))); 7667 testST2(-735_173, SysTime(DateTime(-2012, 3, 1, 12, 2, 9), msecs(212))); 7668 7669 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7670 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7671 static assert(!__traits(compiles, cst.dayOfGregorianCal = 7)); 7672 static assert(!__traits(compiles, ist.dayOfGregorianCal = 7)); 7673 7674 static void testScope(scope ref SysTime st) @safe 7675 { 7676 st.dayOfGregorianCal = 42; 7677 } 7678 } 7679 7680 7681 /++ 7682 The ISO 8601 week of the year that this $(LREF SysTime) is in. 7683 7684 See_Also: 7685 $(HTTP en.wikipedia.org/wiki/ISO_week_date, ISO Week Date). 7686 +/ 7687 @property ubyte isoWeek() @safe const nothrow scope 7688 { 7689 return (cast(Date) this).isoWeek; 7690 } 7691 7692 /// 7693 @safe unittest 7694 { 7695 import core.time; 7696 import std.datetime.date : Date; 7697 7698 auto st = SysTime(Date(1999, 7, 6)); 7699 const cst = SysTime(Date(2010, 5, 1)); 7700 immutable ist = SysTime(Date(2015, 10, 10)); 7701 7702 assert(st.isoWeek == 27); 7703 assert(cst.isoWeek == 17); 7704 assert(ist.isoWeek == 41); 7705 } 7706 7707 @safe unittest 7708 { 7709 static void testScope(scope ref SysTime st) @safe 7710 { 7711 auto result = st.isoWeek; 7712 } 7713 } 7714 7715 7716 /++ 7717 $(LREF SysTime) for the last day in the month that this Date is in. 7718 The time portion of endOfMonth is always 23:59:59.9999999. 7719 +/ 7720 @property SysTime endOfMonth() @safe const nothrow return scope 7721 { 7722 immutable hnsecs = adjTime; 7723 immutable days = getUnitsFromHNSecs!"days"(hnsecs); 7724 7725 auto date = Date(cast(int) days + 1).endOfMonth; 7726 auto newDays = date.dayOfGregorianCal - 1; 7727 long theTimeHNSecs; 7728 7729 if (newDays < 0) 7730 { 7731 theTimeHNSecs = -1; 7732 ++newDays; 7733 } 7734 else 7735 theTimeHNSecs = convert!("days", "hnsecs")(1) - 1; 7736 7737 immutable newDaysHNSecs = convert!("days", "hnsecs")(newDays); 7738 7739 auto retval = SysTime(this._stdTime, this._timezone); 7740 retval.adjTime = newDaysHNSecs + theTimeHNSecs; 7741 7742 return retval; 7743 } 7744 7745 /// 7746 @safe unittest 7747 { 7748 import core.time : msecs, usecs, hnsecs; 7749 import std.datetime.date : DateTime; 7750 7751 assert(SysTime(DateTime(1999, 1, 6, 0, 0, 0)).endOfMonth == 7752 SysTime(DateTime(1999, 1, 31, 23, 59, 59), hnsecs(9_999_999))); 7753 7754 assert(SysTime(DateTime(1999, 2, 7, 19, 30, 0), msecs(24)).endOfMonth == 7755 SysTime(DateTime(1999, 2, 28, 23, 59, 59), hnsecs(9_999_999))); 7756 7757 assert(SysTime(DateTime(2000, 2, 7, 5, 12, 27), usecs(5203)).endOfMonth == 7758 SysTime(DateTime(2000, 2, 29, 23, 59, 59), hnsecs(9_999_999))); 7759 7760 assert(SysTime(DateTime(2000, 6, 4, 12, 22, 9), hnsecs(12345)).endOfMonth == 7761 SysTime(DateTime(2000, 6, 30, 23, 59, 59), hnsecs(9_999_999))); 7762 } 7763 7764 @safe unittest 7765 { 7766 import core.time; 7767 // Test A.D. 7768 assert(SysTime(Date(1999, 1, 1)).endOfMonth == SysTime(DateTime(1999, 1, 31, 23, 59, 59), hnsecs(9_999_999))); 7769 assert(SysTime(Date(1999, 2, 1)).endOfMonth == SysTime(DateTime(1999, 2, 28, 23, 59, 59), hnsecs(9_999_999))); 7770 assert(SysTime(Date(2000, 2, 1)).endOfMonth == SysTime(DateTime(2000, 2, 29, 23, 59, 59), hnsecs(9_999_999))); 7771 assert(SysTime(Date(1999, 3, 1)).endOfMonth == SysTime(DateTime(1999, 3, 31, 23, 59, 59), hnsecs(9_999_999))); 7772 assert(SysTime(Date(1999, 4, 1)).endOfMonth == SysTime(DateTime(1999, 4, 30, 23, 59, 59), hnsecs(9_999_999))); 7773 assert(SysTime(Date(1999, 5, 1)).endOfMonth == SysTime(DateTime(1999, 5, 31, 23, 59, 59), hnsecs(9_999_999))); 7774 assert(SysTime(Date(1999, 6, 1)).endOfMonth == SysTime(DateTime(1999, 6, 30, 23, 59, 59), hnsecs(9_999_999))); 7775 assert(SysTime(Date(1999, 7, 1)).endOfMonth == SysTime(DateTime(1999, 7, 31, 23, 59, 59), hnsecs(9_999_999))); 7776 assert(SysTime(Date(1999, 8, 1)).endOfMonth == SysTime(DateTime(1999, 8, 31, 23, 59, 59), hnsecs(9_999_999))); 7777 assert(SysTime(Date(1999, 9, 1)).endOfMonth == SysTime(DateTime(1999, 9, 30, 23, 59, 59), hnsecs(9_999_999))); 7778 assert(SysTime(Date(1999, 10, 1)).endOfMonth == SysTime(DateTime(1999, 10, 31, 23, 59, 59), hnsecs(9_999_999))); 7779 assert(SysTime(Date(1999, 11, 1)).endOfMonth == SysTime(DateTime(1999, 11, 30, 23, 59, 59), hnsecs(9_999_999))); 7780 assert(SysTime(Date(1999, 12, 1)).endOfMonth == SysTime(DateTime(1999, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 7781 7782 // Test B.C. 7783 assert(SysTime(Date(-1999, 1, 1)).endOfMonth == SysTime(DateTime(-1999, 1, 31, 23, 59, 59), hnsecs(9_999_999))); 7784 assert(SysTime(Date(-1999, 2, 1)).endOfMonth == SysTime(DateTime(-1999, 2, 28, 23, 59, 59), hnsecs(9_999_999))); 7785 assert(SysTime(Date(-2000, 2, 1)).endOfMonth == SysTime(DateTime(-2000, 2, 29, 23, 59, 59), hnsecs(9_999_999))); 7786 assert(SysTime(Date(-1999, 3, 1)).endOfMonth == SysTime(DateTime(-1999, 3, 31, 23, 59, 59), hnsecs(9_999_999))); 7787 assert(SysTime(Date(-1999, 4, 1)).endOfMonth == SysTime(DateTime(-1999, 4, 30, 23, 59, 59), hnsecs(9_999_999))); 7788 assert(SysTime(Date(-1999, 5, 1)).endOfMonth == SysTime(DateTime(-1999, 5, 31, 23, 59, 59), hnsecs(9_999_999))); 7789 assert(SysTime(Date(-1999, 6, 1)).endOfMonth == SysTime(DateTime(-1999, 6, 30, 23, 59, 59), hnsecs(9_999_999))); 7790 assert(SysTime(Date(-1999, 7, 1)).endOfMonth == SysTime(DateTime(-1999, 7, 31, 23, 59, 59), hnsecs(9_999_999))); 7791 assert(SysTime(Date(-1999, 8, 1)).endOfMonth == SysTime(DateTime(-1999, 8, 31, 23, 59, 59), hnsecs(9_999_999))); 7792 assert(SysTime(Date(-1999, 9, 1)).endOfMonth == SysTime(DateTime(-1999, 9, 30, 23, 59, 59), hnsecs(9_999_999))); 7793 assert(SysTime(Date(-1999, 10, 1)).endOfMonth == 7794 SysTime(DateTime(-1999, 10, 31, 23, 59, 59), hnsecs(9_999_999))); 7795 assert(SysTime(Date(-1999, 11, 1)).endOfMonth == 7796 SysTime(DateTime(-1999, 11, 30, 23, 59, 59), hnsecs(9_999_999))); 7797 assert(SysTime(Date(-1999, 12, 1)).endOfMonth == 7798 SysTime(DateTime(-1999, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 7799 7800 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7801 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7802 assert(cst.endOfMonth == SysTime(DateTime(1999, 7, 31, 23, 59, 59), hnsecs(9_999_999))); 7803 assert(ist.endOfMonth == SysTime(DateTime(1999, 7, 31, 23, 59, 59), hnsecs(9_999_999))); 7804 7805 static void testScope(scope ref SysTime st) @safe 7806 { 7807 auto result = st.endOfMonth; 7808 } 7809 } 7810 7811 7812 /++ 7813 The last day in the month that this $(LREF SysTime) is in. 7814 +/ 7815 @property ubyte daysInMonth() @safe const nothrow scope 7816 { 7817 return Date(dayOfGregorianCal).daysInMonth; 7818 } 7819 7820 /// 7821 @safe unittest 7822 { 7823 import core.time; 7824 import std.datetime.date : DateTime; 7825 7826 assert(SysTime(DateTime(1999, 1, 6, 0, 0, 0)).daysInMonth == 31); 7827 assert(SysTime(DateTime(1999, 2, 7, 19, 30, 0)).daysInMonth == 28); 7828 assert(SysTime(DateTime(2000, 2, 7, 5, 12, 27)).daysInMonth == 29); 7829 assert(SysTime(DateTime(2000, 6, 4, 12, 22, 9)).daysInMonth == 30); 7830 } 7831 7832 @safe unittest 7833 { 7834 import core.time; 7835 // Test A.D. 7836 assert(SysTime(DateTime(1999, 1, 1, 12, 1, 13)).daysInMonth == 31); 7837 assert(SysTime(DateTime(1999, 2, 1, 17, 13, 12)).daysInMonth == 28); 7838 assert(SysTime(DateTime(2000, 2, 1, 13, 2, 12)).daysInMonth == 29); 7839 assert(SysTime(DateTime(1999, 3, 1, 12, 13, 12)).daysInMonth == 31); 7840 assert(SysTime(DateTime(1999, 4, 1, 12, 6, 13)).daysInMonth == 30); 7841 assert(SysTime(DateTime(1999, 5, 1, 15, 13, 12)).daysInMonth == 31); 7842 assert(SysTime(DateTime(1999, 6, 1, 13, 7, 12)).daysInMonth == 30); 7843 assert(SysTime(DateTime(1999, 7, 1, 12, 13, 17)).daysInMonth == 31); 7844 assert(SysTime(DateTime(1999, 8, 1, 12, 3, 13)).daysInMonth == 31); 7845 assert(SysTime(DateTime(1999, 9, 1, 12, 13, 12)).daysInMonth == 30); 7846 assert(SysTime(DateTime(1999, 10, 1, 13, 19, 12)).daysInMonth == 31); 7847 assert(SysTime(DateTime(1999, 11, 1, 12, 13, 17)).daysInMonth == 30); 7848 assert(SysTime(DateTime(1999, 12, 1, 12, 52, 13)).daysInMonth == 31); 7849 7850 // Test B.C. 7851 assert(SysTime(DateTime(-1999, 1, 1, 12, 1, 13)).daysInMonth == 31); 7852 assert(SysTime(DateTime(-1999, 2, 1, 7, 13, 12)).daysInMonth == 28); 7853 assert(SysTime(DateTime(-2000, 2, 1, 13, 2, 12)).daysInMonth == 29); 7854 assert(SysTime(DateTime(-1999, 3, 1, 12, 13, 12)).daysInMonth == 31); 7855 assert(SysTime(DateTime(-1999, 4, 1, 12, 6, 13)).daysInMonth == 30); 7856 assert(SysTime(DateTime(-1999, 5, 1, 5, 13, 12)).daysInMonth == 31); 7857 assert(SysTime(DateTime(-1999, 6, 1, 13, 7, 12)).daysInMonth == 30); 7858 assert(SysTime(DateTime(-1999, 7, 1, 12, 13, 17)).daysInMonth == 31); 7859 assert(SysTime(DateTime(-1999, 8, 1, 12, 3, 13)).daysInMonth == 31); 7860 assert(SysTime(DateTime(-1999, 9, 1, 12, 13, 12)).daysInMonth == 30); 7861 assert(SysTime(DateTime(-1999, 10, 1, 13, 19, 12)).daysInMonth == 31); 7862 assert(SysTime(DateTime(-1999, 11, 1, 12, 13, 17)).daysInMonth == 30); 7863 assert(SysTime(DateTime(-1999, 12, 1, 12, 52, 13)).daysInMonth == 31); 7864 7865 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7866 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7867 assert(cst.daysInMonth == 31); 7868 assert(ist.daysInMonth == 31); 7869 7870 static void testScope(scope ref SysTime st) @safe 7871 { 7872 auto result = st.daysInMonth; 7873 } 7874 } 7875 7876 7877 /++ 7878 Whether the current year is a date in A.D. 7879 +/ 7880 @property bool isAD() @safe const nothrow scope 7881 { 7882 return adjTime >= 0; 7883 } 7884 7885 /// 7886 @safe unittest 7887 { 7888 import core.time; 7889 import std.datetime.date : DateTime; 7890 7891 assert(SysTime(DateTime(1, 1, 1, 12, 7, 0)).isAD); 7892 assert(SysTime(DateTime(2010, 12, 31, 0, 0, 0)).isAD); 7893 assert(!SysTime(DateTime(0, 12, 31, 23, 59, 59)).isAD); 7894 assert(!SysTime(DateTime(-2010, 1, 1, 2, 2, 2)).isAD); 7895 } 7896 7897 @safe unittest 7898 { 7899 import core.time; 7900 assert(SysTime(DateTime(2010, 7, 4, 12, 0, 9)).isAD); 7901 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).isAD); 7902 assert(!SysTime(DateTime(0, 12, 31, 23, 59, 59)).isAD); 7903 assert(!SysTime(DateTime(0, 1, 1, 23, 59, 59)).isAD); 7904 assert(!SysTime(DateTime(-1, 1, 1, 23 ,59 ,59)).isAD); 7905 assert(!SysTime(DateTime(-2010, 7, 4, 12, 2, 2)).isAD); 7906 7907 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7908 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7909 assert(cst.isAD); 7910 assert(ist.isAD); 7911 7912 static void testScope(scope ref SysTime st) @safe 7913 { 7914 auto result = st.isAD; 7915 } 7916 } 7917 7918 7919 /++ 7920 The $(HTTP en.wikipedia.org/wiki/Julian_day, Julian day) 7921 for this $(LREF SysTime) at the given time. For example, 7922 prior to noon, 1996-03-31 would be the Julian day number 2_450_173, so 7923 this function returns 2_450_173, while from noon onward, the Julian 7924 day number would be 2_450_174, so this function returns 2_450_174. 7925 +/ 7926 @property long julianDay() @safe const nothrow scope 7927 { 7928 immutable jd = dayOfGregorianCal + 1_721_425; 7929 return hour < 12 ? jd - 1 : jd; 7930 } 7931 7932 @safe unittest 7933 { 7934 import core.time; 7935 assert(SysTime(DateTime(-4713, 11, 24, 0, 0, 0)).julianDay == -1); 7936 assert(SysTime(DateTime(-4713, 11, 24, 12, 0, 0)).julianDay == 0); 7937 7938 assert(SysTime(DateTime(0, 12, 31, 0, 0, 0)).julianDay == 1_721_424); 7939 assert(SysTime(DateTime(0, 12, 31, 12, 0, 0)).julianDay == 1_721_425); 7940 7941 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).julianDay == 1_721_425); 7942 assert(SysTime(DateTime(1, 1, 1, 12, 0, 0)).julianDay == 1_721_426); 7943 7944 assert(SysTime(DateTime(1582, 10, 15, 0, 0, 0)).julianDay == 2_299_160); 7945 assert(SysTime(DateTime(1582, 10, 15, 12, 0, 0)).julianDay == 2_299_161); 7946 7947 assert(SysTime(DateTime(1858, 11, 17, 0, 0, 0)).julianDay == 2_400_000); 7948 assert(SysTime(DateTime(1858, 11, 17, 12, 0, 0)).julianDay == 2_400_001); 7949 7950 assert(SysTime(DateTime(1982, 1, 4, 0, 0, 0)).julianDay == 2_444_973); 7951 assert(SysTime(DateTime(1982, 1, 4, 12, 0, 0)).julianDay == 2_444_974); 7952 7953 assert(SysTime(DateTime(1996, 3, 31, 0, 0, 0)).julianDay == 2_450_173); 7954 assert(SysTime(DateTime(1996, 3, 31, 12, 0, 0)).julianDay == 2_450_174); 7955 7956 assert(SysTime(DateTime(2010, 8, 24, 0, 0, 0)).julianDay == 2_455_432); 7957 assert(SysTime(DateTime(2010, 8, 24, 12, 0, 0)).julianDay == 2_455_433); 7958 7959 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7960 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7961 assert(cst.julianDay == 2_451_366); 7962 assert(ist.julianDay == 2_451_366); 7963 7964 static void testScope(scope ref SysTime st) @safe 7965 { 7966 auto result = st.julianDay; 7967 } 7968 } 7969 7970 7971 /++ 7972 The modified $(HTTP en.wikipedia.org/wiki/Julian_day, Julian day) for 7973 any time on this date (since, the modified Julian day changes at 7974 midnight). 7975 +/ 7976 @property long modJulianDay() @safe const nothrow scope 7977 { 7978 return dayOfGregorianCal + 1_721_425 - 2_400_001; 7979 } 7980 7981 @safe unittest 7982 { 7983 import core.time; 7984 assert(SysTime(DateTime(1858, 11, 17, 0, 0, 0)).modJulianDay == 0); 7985 assert(SysTime(DateTime(1858, 11, 17, 12, 0, 0)).modJulianDay == 0); 7986 7987 assert(SysTime(DateTime(2010, 8, 24, 0, 0, 0)).modJulianDay == 55_432); 7988 assert(SysTime(DateTime(2010, 8, 24, 12, 0, 0)).modJulianDay == 55_432); 7989 7990 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7991 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7992 assert(cst.modJulianDay == 51_365); 7993 assert(ist.modJulianDay == 51_365); 7994 7995 static void testScope(scope ref SysTime st) @safe 7996 { 7997 auto result = st.modJulianDay; 7998 } 7999 } 8000 8001 8002 /++ 8003 Returns a $(REF Date,std,datetime,date) equivalent to this $(LREF SysTime). 8004 +/ 8005 Date opCast(T)() @safe const nothrow scope 8006 if (is(immutable T == immutable Date)) 8007 { 8008 return Date(dayOfGregorianCal); 8009 } 8010 8011 @safe unittest 8012 { 8013 import core.time; 8014 assert(cast(Date) SysTime(Date(1999, 7, 6)) == Date(1999, 7, 6)); 8015 assert(cast(Date) SysTime(Date(2000, 12, 31)) == Date(2000, 12, 31)); 8016 assert(cast(Date) SysTime(Date(2001, 1, 1)) == Date(2001, 1, 1)); 8017 8018 assert(cast(Date) SysTime(DateTime(1999, 7, 6, 12, 10, 9)) == Date(1999, 7, 6)); 8019 assert(cast(Date) SysTime(DateTime(2000, 12, 31, 13, 11, 10)) == Date(2000, 12, 31)); 8020 assert(cast(Date) SysTime(DateTime(2001, 1, 1, 14, 12, 11)) == Date(2001, 1, 1)); 8021 8022 assert(cast(Date) SysTime(Date(-1999, 7, 6)) == Date(-1999, 7, 6)); 8023 assert(cast(Date) SysTime(Date(-2000, 12, 31)) == Date(-2000, 12, 31)); 8024 assert(cast(Date) SysTime(Date(-2001, 1, 1)) == Date(-2001, 1, 1)); 8025 8026 assert(cast(Date) SysTime(DateTime(-1999, 7, 6, 12, 10, 9)) == Date(-1999, 7, 6)); 8027 assert(cast(Date) SysTime(DateTime(-2000, 12, 31, 13, 11, 10)) == Date(-2000, 12, 31)); 8028 assert(cast(Date) SysTime(DateTime(-2001, 1, 1, 14, 12, 11)) == Date(-2001, 1, 1)); 8029 8030 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8031 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8032 assert(cast(Date) cst != Date.init); 8033 assert(cast(Date) ist != Date.init); 8034 8035 static void testScope(scope ref SysTime st) @safe 8036 { 8037 auto result = cast(Date) st; 8038 } 8039 } 8040 8041 8042 /++ 8043 Returns a $(REF DateTime,std,datetime,date) equivalent to this 8044 $(LREF SysTime). 8045 +/ 8046 DateTime opCast(T)() @safe const nothrow scope 8047 if (is(immutable T == immutable DateTime)) 8048 { 8049 try 8050 { 8051 auto hnsecs = adjTime; 8052 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 8053 8054 if (hnsecs < 0) 8055 { 8056 hnsecs += convert!("hours", "hnsecs")(24); 8057 --days; 8058 } 8059 8060 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 8061 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 8062 immutable second = getUnitsFromHNSecs!"seconds"(hnsecs); 8063 8064 return DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour, cast(int) minute, cast(int) second)); 8065 } 8066 catch (Exception e) 8067 assert(0, "Either DateTime's constructor or TimeOfDay's constructor threw."); 8068 } 8069 8070 @safe unittest 8071 { 8072 import core.time; 8073 assert(cast(DateTime) SysTime(DateTime(1, 1, 6, 7, 12, 22)) == DateTime(1, 1, 6, 7, 12, 22)); 8074 assert(cast(DateTime) SysTime(DateTime(1, 1, 6, 7, 12, 22), msecs(22)) == DateTime(1, 1, 6, 7, 12, 22)); 8075 assert(cast(DateTime) SysTime(Date(1999, 7, 6)) == DateTime(1999, 7, 6, 0, 0, 0)); 8076 assert(cast(DateTime) SysTime(Date(2000, 12, 31)) == DateTime(2000, 12, 31, 0, 0, 0)); 8077 assert(cast(DateTime) SysTime(Date(2001, 1, 1)) == DateTime(2001, 1, 1, 0, 0, 0)); 8078 8079 assert(cast(DateTime) SysTime(DateTime(1999, 7, 6, 12, 10, 9)) == DateTime(1999, 7, 6, 12, 10, 9)); 8080 assert(cast(DateTime) SysTime(DateTime(2000, 12, 31, 13, 11, 10)) == DateTime(2000, 12, 31, 13, 11, 10)); 8081 assert(cast(DateTime) SysTime(DateTime(2001, 1, 1, 14, 12, 11)) == DateTime(2001, 1, 1, 14, 12, 11)); 8082 8083 assert(cast(DateTime) SysTime(DateTime(-1, 1, 6, 7, 12, 22)) == DateTime(-1, 1, 6, 7, 12, 22)); 8084 assert(cast(DateTime) SysTime(DateTime(-1, 1, 6, 7, 12, 22), msecs(22)) == DateTime(-1, 1, 6, 7, 12, 22)); 8085 assert(cast(DateTime) SysTime(Date(-1999, 7, 6)) == DateTime(-1999, 7, 6, 0, 0, 0)); 8086 assert(cast(DateTime) SysTime(Date(-2000, 12, 31)) == DateTime(-2000, 12, 31, 0, 0, 0)); 8087 assert(cast(DateTime) SysTime(Date(-2001, 1, 1)) == DateTime(-2001, 1, 1, 0, 0, 0)); 8088 8089 assert(cast(DateTime) SysTime(DateTime(-1999, 7, 6, 12, 10, 9)) == DateTime(-1999, 7, 6, 12, 10, 9)); 8090 assert(cast(DateTime) SysTime(DateTime(-2000, 12, 31, 13, 11, 10)) == DateTime(-2000, 12, 31, 13, 11, 10)); 8091 assert(cast(DateTime) SysTime(DateTime(-2001, 1, 1, 14, 12, 11)) == DateTime(-2001, 1, 1, 14, 12, 11)); 8092 8093 assert(cast(DateTime) SysTime(DateTime(2011, 1, 13, 8, 17, 2), msecs(296), LocalTime()) == 8094 DateTime(2011, 1, 13, 8, 17, 2)); 8095 8096 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8097 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8098 assert(cast(DateTime) cst != DateTime.init); 8099 assert(cast(DateTime) ist != DateTime.init); 8100 8101 static void testScope(scope ref SysTime st) @safe 8102 { 8103 auto result = cast(DateTime) st; 8104 } 8105 } 8106 8107 8108 /++ 8109 Returns a $(REF TimeOfDay,std,datetime,date) equivalent to this 8110 $(LREF SysTime). 8111 +/ 8112 TimeOfDay opCast(T)() @safe const nothrow scope 8113 if (is(immutable T == immutable TimeOfDay)) 8114 { 8115 try 8116 { 8117 auto hnsecs = adjTime; 8118 hnsecs = removeUnitsFromHNSecs!"days"(hnsecs); 8119 8120 if (hnsecs < 0) 8121 hnsecs += convert!("hours", "hnsecs")(24); 8122 8123 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 8124 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 8125 immutable second = getUnitsFromHNSecs!"seconds"(hnsecs); 8126 8127 return TimeOfDay(cast(int) hour, cast(int) minute, cast(int) second); 8128 } 8129 catch (Exception e) 8130 assert(0, "TimeOfDay's constructor threw."); 8131 } 8132 8133 @safe unittest 8134 { 8135 import core.time; 8136 assert(cast(TimeOfDay) SysTime(Date(1999, 7, 6)) == TimeOfDay(0, 0, 0)); 8137 assert(cast(TimeOfDay) SysTime(Date(2000, 12, 31)) == TimeOfDay(0, 0, 0)); 8138 assert(cast(TimeOfDay) SysTime(Date(2001, 1, 1)) == TimeOfDay(0, 0, 0)); 8139 8140 assert(cast(TimeOfDay) SysTime(DateTime(1999, 7, 6, 12, 10, 9)) == TimeOfDay(12, 10, 9)); 8141 assert(cast(TimeOfDay) SysTime(DateTime(2000, 12, 31, 13, 11, 10)) == TimeOfDay(13, 11, 10)); 8142 assert(cast(TimeOfDay) SysTime(DateTime(2001, 1, 1, 14, 12, 11)) == TimeOfDay(14, 12, 11)); 8143 8144 assert(cast(TimeOfDay) SysTime(Date(-1999, 7, 6)) == TimeOfDay(0, 0, 0)); 8145 assert(cast(TimeOfDay) SysTime(Date(-2000, 12, 31)) == TimeOfDay(0, 0, 0)); 8146 assert(cast(TimeOfDay) SysTime(Date(-2001, 1, 1)) == TimeOfDay(0, 0, 0)); 8147 8148 assert(cast(TimeOfDay) SysTime(DateTime(-1999, 7, 6, 12, 10, 9)) == TimeOfDay(12, 10, 9)); 8149 assert(cast(TimeOfDay) SysTime(DateTime(-2000, 12, 31, 13, 11, 10)) == TimeOfDay(13, 11, 10)); 8150 assert(cast(TimeOfDay) SysTime(DateTime(-2001, 1, 1, 14, 12, 11)) == TimeOfDay(14, 12, 11)); 8151 8152 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8153 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8154 assert(cast(TimeOfDay) cst != TimeOfDay.init); 8155 assert(cast(TimeOfDay) ist != TimeOfDay.init); 8156 8157 static void testScope(scope ref SysTime st) @safe 8158 { 8159 auto result = cast(TimeOfDay) st; 8160 } 8161 } 8162 8163 8164 // Temporary hack until bug https://issues.dlang.org/show_bug.cgi?id=4867 is fixed. 8165 // This allows assignment from const(SysTime) to SysTime. 8166 // It may be a good idea to keep it though, since casting from a type to itself 8167 // should be allowed, and it doesn't work without this opCast() since opCast() 8168 // has already been defined for other types. 8169 SysTime opCast(T)() @safe const pure nothrow scope 8170 if (is(immutable T == immutable SysTime)) 8171 { 8172 return SysTime(_stdTime, _timezone); 8173 } 8174 8175 @safe unittest 8176 { 8177 static void testScope(scope ref SysTime st) @safe 8178 { 8179 auto result = cast(SysTime) st; 8180 } 8181 } 8182 8183 8184 /++ 8185 Converts this $(LREF SysTime) to a string with the format 8186 YYYYMMDDTHHMMSS.FFFFFFFTZ (where F is fractional seconds and TZ is time 8187 zone). 8188 8189 Note that the number of digits in the fractional seconds varies with the 8190 number of fractional seconds. It's a maximum of 7 (which would be 8191 hnsecs), but only has as many as are necessary to hold the correct value 8192 (so no trailing zeroes), and if there are no fractional seconds, then 8193 there is no decimal point. 8194 8195 If this $(LREF SysTime)'s time zone is 8196 $(REF LocalTime,std,datetime,timezone), then TZ is empty. If its time 8197 zone is `UTC`, then it is "Z". Otherwise, it is the offset from UTC 8198 (e.g. +0100 or -0700). Note that the offset from UTC is $(I not) enough 8199 to uniquely identify the time zone. 8200 8201 Time zone offsets will be in the form +HHMM or -HHMM. 8202 8203 $(RED Warning: 8204 Previously, toISOString did the same as $(LREF toISOExtString) and 8205 generated +HH:MM or -HH:MM for the time zone when it was not 8206 $(REF LocalTime,std,datetime,timezone) or 8207 $(REF UTC,std,datetime,timezone), which is not in conformance with 8208 ISO 8601 for the non-extended string format. This has now been 8209 fixed. However, for now, fromISOString will continue to accept the 8210 extended format for the time zone so that any code which has been 8211 writing out the result of toISOString to read in later will continue 8212 to work. The current behavior will be kept until July 2019 at which 8213 point, fromISOString will be fixed to be standards compliant.) 8214 8215 Params: 8216 writer = A `char` accepting 8217 $(REF_ALTTEXT output range, isOutputRange, std, range, primitives) 8218 Returns: 8219 A `string` when not using an output range; `void` otherwise. 8220 +/ 8221 string toISOString() @safe const nothrow scope 8222 { 8223 import std.array : appender; 8224 auto app = appender!string(); 8225 app.reserve(30); 8226 try 8227 toISOString(app); 8228 catch (Exception e) 8229 assert(0, "toISOString() threw."); 8230 return app.data; 8231 } 8232 8233 /// ditto 8234 void toISOString(W)(ref W writer) const scope 8235 if (isOutputRange!(W, char)) 8236 { 8237 immutable adjustedTime = adjTime; 8238 long hnsecs = adjustedTime; 8239 8240 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 8241 8242 if (hnsecs < 0) 8243 { 8244 hnsecs += convert!("hours", "hnsecs")(24); 8245 --days; 8246 } 8247 8248 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 8249 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 8250 immutable second = splitUnitsFromHNSecs!"seconds"(hnsecs); 8251 8252 auto dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour, 8253 cast(int) minute, cast(int) second)); 8254 8255 if (_timezone is LocalTime()) 8256 { 8257 dateTime.toISOString(writer); 8258 fracSecsToISOString(writer, cast(int) hnsecs); 8259 return; 8260 } 8261 8262 if (_timezone is UTC()) 8263 { 8264 dateTime.toISOString(writer); 8265 fracSecsToISOString(writer, cast(int) hnsecs); 8266 put(writer, 'Z'); 8267 return; 8268 } 8269 8270 immutable utcOffset = dur!"hnsecs"(adjustedTime - stdTime); 8271 8272 dateTime.toISOString(writer); 8273 fracSecsToISOString(writer, cast(int) hnsecs); 8274 SimpleTimeZone.toISOExtString(writer, utcOffset); 8275 } 8276 8277 /// 8278 @safe unittest 8279 { 8280 import core.time : msecs, hnsecs; 8281 import std.datetime.date : DateTime; 8282 8283 assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toISOString() == 8284 "20100704T070612"); 8285 8286 assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(24)).toISOString() == 8287 "19981225T021500.024"); 8288 8289 assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toISOString() == 8290 "00000105T230959"); 8291 8292 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toISOString() == 8293 "-00040105T000002.052092"); 8294 } 8295 8296 @safe unittest 8297 { 8298 import core.time; 8299 // Test A.D. 8300 assert(SysTime(DateTime.init, UTC()).toISOString() == "00010101T000000Z"); 8301 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC()).toISOString() == "00010101T000000.0000001Z"); 8302 8303 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0)).toISOString() == "00091204T000000"); 8304 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12)).toISOString() == "00991204T050612"); 8305 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59)).toISOString() == "09991204T134459"); 8306 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59)).toISOString() == "99990704T235959"); 8307 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1)).toISOString() == "+100001020T010101"); 8308 8309 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0), msecs(42)).toISOString() == "00091204T000000.042"); 8310 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12), msecs(100)).toISOString() == "00991204T050612.1"); 8311 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59), usecs(45020)).toISOString() == "09991204T134459.04502"); 8312 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOString() == "99990704T235959.0000012"); 8313 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOString() == "+100001020T010101.050789"); 8314 8315 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 8316 new immutable SimpleTimeZone(dur!"minutes"(-360))).toISOString() == 8317 "20121221T121212-06:00"); 8318 8319 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 8320 new immutable SimpleTimeZone(dur!"minutes"(420))).toISOString() == 8321 "20121221T121212+07:00"); 8322 8323 // Test B.C. 8324 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toISOString() == 8325 "00001231T235959.9999999Z"); 8326 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC()).toISOString() == "00001231T235959.0000001Z"); 8327 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), UTC()).toISOString() == "00001231T235959Z"); 8328 8329 assert(SysTime(DateTime(0, 12, 4, 0, 12, 4)).toISOString() == "00001204T001204"); 8330 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0)).toISOString() == "-00091204T000000"); 8331 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12)).toISOString() == "-00991204T050612"); 8332 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59)).toISOString() == "-09991204T134459"); 8333 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59)).toISOString() == "-99990704T235959"); 8334 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1)).toISOString() == "-100001020T010101"); 8335 8336 assert(SysTime(DateTime(0, 12, 4, 0, 0, 0), msecs(7)).toISOString() == "00001204T000000.007"); 8337 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0), msecs(42)).toISOString() == "-00091204T000000.042"); 8338 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12), msecs(100)).toISOString() == "-00991204T050612.1"); 8339 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59), usecs(45020)).toISOString() == "-09991204T134459.04502"); 8340 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOString() == "-99990704T235959.0000012"); 8341 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOString() == "-100001020T010101.050789"); 8342 8343 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8344 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8345 assert(cst.toISOString() == "19990706T123033"); 8346 assert(ist.toISOString() == "19990706T123033"); 8347 8348 static void testScope(scope ref SysTime st) @safe 8349 { 8350 auto result = st.toISOString(); 8351 } 8352 } 8353 8354 8355 8356 /++ 8357 Converts this $(LREF SysTime) to a string with the format 8358 YYYY-MM-DDTHH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ 8359 is the time zone). 8360 8361 Default behaviour: 8362 Note that the number of digits in the fractional seconds varies with the 8363 number of fractional seconds. It's a maximum of 7 (which would be 8364 hnsecs), but only has as many as are necessary to hold the correct value 8365 (so no trailing zeroes), and if there are no fractional seconds, then 8366 there is no decimal point. 8367 8368 The optional parameter "prec" allows to change the default behavior by 8369 specifying the precision of the fractional seconds. The accepted values 8370 are in the range [-1, 7], where -1 represents the default behavior. 8371 8372 If this $(LREF SysTime)'s time zone is 8373 $(REF LocalTime,std,datetime,timezone), then TZ is empty. If its time 8374 zone is `UTC`, then it is "Z". Otherwise, it is the offset from UTC 8375 (e.g. +01:00 or -07:00). Note that the offset from UTC is $(I not) 8376 enough to uniquely identify the time zone. 8377 8378 Time zone offsets will be in the form +HH:MM or -HH:MM. 8379 8380 Params: 8381 writer = A `char` accepting 8382 $(REF_ALTTEXT output range, isOutputRange, std, range, primitives) 8383 prec = An `int` representing the desired precision. Acceptable values range from -1 to 7, where -1 represents the default behavior. 8384 Returns: 8385 A `string` when not using an output range; `void` otherwise. 8386 +/ 8387 string toISOExtString(int prec = -1) @safe const nothrow scope 8388 { 8389 assert(prec >= -1 && prec <= 7, "Precision must be in the range [-1, 7]"); 8390 8391 import std.array : appender; 8392 auto app = appender!string(); 8393 app.reserve(35); 8394 try 8395 toISOExtString(app, prec); 8396 catch (Exception e) 8397 assert(0, "toISOExtString() threw."); 8398 return app.data; 8399 } 8400 8401 /// ditto 8402 void toISOExtString(W)(ref W writer, int prec = -1) const scope 8403 if (isOutputRange!(W, char)) 8404 { 8405 assert(prec >= -1 && prec <= 7, "Precision must be in the range [-1, 7]"); 8406 8407 immutable adjustedTime = adjTime; 8408 long hnsecs = adjustedTime; 8409 8410 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 8411 8412 if (hnsecs < 0) 8413 { 8414 hnsecs += convert!("hours", "hnsecs")(24); 8415 --days; 8416 } 8417 8418 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 8419 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 8420 immutable second = splitUnitsFromHNSecs!"seconds"(hnsecs); 8421 8422 immutable dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour, 8423 cast(int) minute, cast(int) second)); 8424 8425 if (_timezone is LocalTime()) 8426 { 8427 dateTime.toISOExtString(writer); 8428 fracSecsToISOString(writer, cast(int) hnsecs, prec); 8429 return; 8430 } 8431 8432 if (_timezone is UTC()) 8433 { 8434 dateTime.toISOExtString(writer); 8435 fracSecsToISOString(writer, cast(int) hnsecs, prec); 8436 put(writer, 'Z'); 8437 return; 8438 } 8439 8440 immutable utcOffset = dur!"hnsecs"(adjustedTime - stdTime); 8441 8442 dateTime.toISOExtString(writer); 8443 fracSecsToISOString(writer, cast(int) hnsecs, prec); 8444 SimpleTimeZone.toISOExtString(writer, utcOffset); 8445 } 8446 8447 /// 8448 @safe unittest 8449 { 8450 import core.time : msecs, hnsecs; 8451 import std.datetime.date : DateTime; 8452 8453 assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toISOExtString() == 8454 "2010-07-04T07:06:12"); 8455 8456 assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(24)).toISOExtString() == 8457 "1998-12-25T02:15:00.024"); 8458 8459 assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toISOExtString() == 8460 "0000-01-05T23:09:59"); 8461 8462 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toISOExtString() == 8463 "-0004-01-05T00:00:02.052092"); 8464 8465 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toISOExtString(4) == 8466 "-0004-01-05T00:00:02.0520"); 8467 8468 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toISOExtString(2) == 8469 "-0004-01-05T00:00:02.05"); 8470 8471 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toISOExtString(7) == 8472 "-0004-01-05T00:00:02.0520920"); 8473 } 8474 8475 @safe unittest 8476 { 8477 import core.time; 8478 // Test A.D. 8479 assert(SysTime(DateTime.init, UTC()).toISOExtString() == "0001-01-01T00:00:00Z"); 8480 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC()).toISOExtString() == 8481 "0001-01-01T00:00:00.0000001Z"); 8482 8483 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0)).toISOExtString() == "0009-12-04T00:00:00"); 8484 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12)).toISOExtString() == "0099-12-04T05:06:12"); 8485 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59)).toISOExtString() == "0999-12-04T13:44:59"); 8486 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59)).toISOExtString() == "9999-07-04T23:59:59"); 8487 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1)).toISOExtString() == "+10000-10-20T01:01:01"); 8488 8489 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0), msecs(42)).toISOExtString() == "0009-12-04T00:00:00.042"); 8490 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12), msecs(100)).toISOExtString() == "0099-12-04T05:06:12.1"); 8491 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59), usecs(45020)).toISOExtString() == "0999-12-04T13:44:59.04502"); 8492 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOExtString() == "9999-07-04T23:59:59.0000012"); 8493 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOExtString() == 8494 "+10000-10-20T01:01:01.050789"); 8495 8496 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 8497 new immutable SimpleTimeZone(dur!"minutes"(-360))).toISOExtString() == 8498 "2012-12-21T12:12:12-06:00"); 8499 8500 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 8501 new immutable SimpleTimeZone(dur!"minutes"(420))).toISOExtString() == 8502 "2012-12-21T12:12:12+07:00"); 8503 8504 // Test B.C. 8505 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toISOExtString() == 8506 "0000-12-31T23:59:59.9999999Z"); 8507 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC()).toISOExtString() == 8508 "0000-12-31T23:59:59.0000001Z"); 8509 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), UTC()).toISOExtString() == "0000-12-31T23:59:59Z"); 8510 8511 assert(SysTime(DateTime(0, 12, 4, 0, 12, 4)).toISOExtString() == "0000-12-04T00:12:04"); 8512 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0)).toISOExtString() == "-0009-12-04T00:00:00"); 8513 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12)).toISOExtString() == "-0099-12-04T05:06:12"); 8514 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59)).toISOExtString() == "-0999-12-04T13:44:59"); 8515 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59)).toISOExtString() == "-9999-07-04T23:59:59"); 8516 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1)).toISOExtString() == "-10000-10-20T01:01:01"); 8517 8518 assert(SysTime(DateTime(0, 12, 4, 0, 0, 0), msecs(7)).toISOExtString() == "0000-12-04T00:00:00.007"); 8519 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0), msecs(42)).toISOExtString() == "-0009-12-04T00:00:00.042"); 8520 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12), msecs(100)).toISOExtString() == "-0099-12-04T05:06:12.1"); 8521 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59), usecs(45020)).toISOExtString() == 8522 "-0999-12-04T13:44:59.04502"); 8523 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOExtString() == 8524 "-9999-07-04T23:59:59.0000012"); 8525 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOExtString() == 8526 "-10000-10-20T01:01:01.050789"); 8527 8528 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8529 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8530 assert(cst.toISOExtString() == "1999-07-06T12:30:33"); 8531 assert(ist.toISOExtString() == "1999-07-06T12:30:33"); 8532 8533 static void testScope(scope ref SysTime st) @safe 8534 { 8535 auto result = st.toISOExtString(); 8536 } 8537 } 8538 8539 /++ 8540 Converts this $(LREF SysTime) to a string with the format 8541 YYYY-Mon-DD HH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ 8542 is the time zone). 8543 8544 Note that the number of digits in the fractional seconds varies with the 8545 number of fractional seconds. It's a maximum of 7 (which would be 8546 hnsecs), but only has as many as are necessary to hold the correct value 8547 (so no trailing zeroes), and if there are no fractional seconds, then 8548 there is no decimal point. 8549 8550 If this $(LREF SysTime)'s time zone is 8551 $(REF LocalTime,std,datetime,timezone), then TZ is empty. If its time 8552 zone is `UTC`, then it is "Z". Otherwise, it is the offset from UTC 8553 (e.g. +01:00 or -07:00). Note that the offset from UTC is $(I not) 8554 enough to uniquely identify the time zone. 8555 8556 Time zone offsets will be in the form +HH:MM or -HH:MM. 8557 8558 Params: 8559 writer = A `char` accepting 8560 $(REF_ALTTEXT output range, isOutputRange, std, range, primitives) 8561 Returns: 8562 A `string` when not using an output range; `void` otherwise. 8563 +/ 8564 string toSimpleString() @safe const nothrow scope 8565 { 8566 import std.array : appender; 8567 auto app = appender!string(); 8568 app.reserve(35); 8569 try 8570 toSimpleString(app); 8571 catch (Exception e) 8572 assert(0, "toSimpleString() threw."); 8573 return app.data; 8574 } 8575 8576 /// ditto 8577 void toSimpleString(W)(ref W writer) const scope 8578 if (isOutputRange!(W, char)) 8579 { 8580 immutable adjustedTime = adjTime; 8581 long hnsecs = adjustedTime; 8582 8583 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 8584 8585 if (hnsecs < 0) 8586 { 8587 hnsecs += convert!("hours", "hnsecs")(24); 8588 --days; 8589 } 8590 8591 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 8592 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 8593 immutable second = splitUnitsFromHNSecs!"seconds"(hnsecs); 8594 8595 immutable dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour, 8596 cast(int) minute, cast(int) second)); 8597 8598 if (_timezone is LocalTime()) 8599 { 8600 dateTime.toSimpleString(writer); 8601 fracSecsToISOString(writer, cast(int) hnsecs); 8602 return; 8603 } 8604 8605 if (_timezone is UTC()) 8606 { 8607 dateTime.toSimpleString(writer); 8608 fracSecsToISOString(writer, cast(int) hnsecs); 8609 put(writer, 'Z'); 8610 return; 8611 } 8612 8613 immutable utcOffset = dur!"hnsecs"(adjustedTime - stdTime); 8614 8615 dateTime.toSimpleString(writer); 8616 fracSecsToISOString(writer, cast(int) hnsecs); 8617 SimpleTimeZone.toISOExtString(writer, utcOffset); 8618 } 8619 8620 /// 8621 @safe unittest 8622 { 8623 import core.time : msecs, hnsecs; 8624 import std.datetime.date : DateTime; 8625 8626 assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toSimpleString() == 8627 "2010-Jul-04 07:06:12"); 8628 8629 assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(24)).toSimpleString() == 8630 "1998-Dec-25 02:15:00.024"); 8631 8632 assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toSimpleString() == 8633 "0000-Jan-05 23:09:59"); 8634 8635 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toSimpleString() == 8636 "-0004-Jan-05 00:00:02.052092"); 8637 } 8638 8639 @safe unittest 8640 { 8641 import core.time; 8642 // Test A.D. 8643 assert(SysTime(DateTime.init, UTC()).toString() == "0001-Jan-01 00:00:00Z"); 8644 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC()).toString() == "0001-Jan-01 00:00:00.0000001Z"); 8645 8646 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0)).toSimpleString() == "0009-Dec-04 00:00:00"); 8647 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12)).toSimpleString() == "0099-Dec-04 05:06:12"); 8648 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59)).toSimpleString() == "0999-Dec-04 13:44:59"); 8649 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59)).toSimpleString() == "9999-Jul-04 23:59:59"); 8650 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1)).toSimpleString() == "+10000-Oct-20 01:01:01"); 8651 8652 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0), msecs(42)).toSimpleString() == "0009-Dec-04 00:00:00.042"); 8653 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12), msecs(100)).toSimpleString() == "0099-Dec-04 05:06:12.1"); 8654 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59), usecs(45020)).toSimpleString() == 8655 "0999-Dec-04 13:44:59.04502"); 8656 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59), hnsecs(12)).toSimpleString() == 8657 "9999-Jul-04 23:59:59.0000012"); 8658 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1), hnsecs(507890)).toSimpleString() == 8659 "+10000-Oct-20 01:01:01.050789"); 8660 8661 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 8662 new immutable SimpleTimeZone(dur!"minutes"(-360))).toSimpleString() == 8663 "2012-Dec-21 12:12:12-06:00"); 8664 8665 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 8666 new immutable SimpleTimeZone(dur!"minutes"(420))).toSimpleString() == 8667 "2012-Dec-21 12:12:12+07:00"); 8668 8669 // Test B.C. 8670 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toSimpleString() == 8671 "0000-Dec-31 23:59:59.9999999Z"); 8672 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC()).toSimpleString() == 8673 "0000-Dec-31 23:59:59.0000001Z"); 8674 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), UTC()).toSimpleString() == "0000-Dec-31 23:59:59Z"); 8675 8676 assert(SysTime(DateTime(0, 12, 4, 0, 12, 4)).toSimpleString() == "0000-Dec-04 00:12:04"); 8677 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0)).toSimpleString() == "-0009-Dec-04 00:00:00"); 8678 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12)).toSimpleString() == "-0099-Dec-04 05:06:12"); 8679 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59)).toSimpleString() == "-0999-Dec-04 13:44:59"); 8680 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59)).toSimpleString() == "-9999-Jul-04 23:59:59"); 8681 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1)).toSimpleString() == "-10000-Oct-20 01:01:01"); 8682 8683 assert(SysTime(DateTime(0, 12, 4, 0, 0, 0), msecs(7)).toSimpleString() == "0000-Dec-04 00:00:00.007"); 8684 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0), msecs(42)).toSimpleString() == "-0009-Dec-04 00:00:00.042"); 8685 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12), msecs(100)).toSimpleString() == "-0099-Dec-04 05:06:12.1"); 8686 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59), usecs(45020)).toSimpleString() == 8687 "-0999-Dec-04 13:44:59.04502"); 8688 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59), hnsecs(12)).toSimpleString() == 8689 "-9999-Jul-04 23:59:59.0000012"); 8690 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1), hnsecs(507890)).toSimpleString() == 8691 "-10000-Oct-20 01:01:01.050789"); 8692 8693 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8694 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8695 assert(cst.toSimpleString() == "1999-Jul-06 12:30:33"); 8696 assert(ist.toSimpleString() == "1999-Jul-06 12:30:33"); 8697 8698 static void testScope(scope ref SysTime st) @safe 8699 { 8700 auto result = st.toSimpleString(); 8701 } 8702 } 8703 8704 8705 /++ 8706 Converts this $(LREF SysTime) to a string. 8707 8708 This function exists to make it easy to convert a $(LREF SysTime) to a 8709 string for code that does not care what the exact format is - just that 8710 it presents the information in a clear manner. It also makes it easy to 8711 simply convert a $(LREF SysTime) to a string when using functions such 8712 as `to!string`, `format`, or `writeln` which use toString to convert 8713 user-defined types. So, it is unlikely that much code will call 8714 toString directly. 8715 8716 The format of the string is purposefully unspecified, and code that 8717 cares about the format of the string should use `toISOString`, 8718 `toISOExtString`, `toSimpleString`, or some other custom formatting 8719 function that explicitly generates the format that the code needs. The 8720 reason is that the code is then clear about what format it's using, 8721 making it less error-prone to maintain the code and interact with other 8722 software that consumes the generated strings. It's for this same reason 8723 that $(LREF SysTime) has no `fromString` function, whereas it does have 8724 `fromISOString`, `fromISOExtString`, and `fromSimpleString`. 8725 8726 The format returned by toString may or may not change in the future. 8727 8728 Params: 8729 writer = A `char` accepting 8730 $(REF_ALTTEXT output range, isOutputRange, std, range, primitives) 8731 Returns: 8732 A `string` when not using an output range; `void` otherwise. 8733 +/ 8734 string toString() @safe const nothrow scope 8735 { 8736 return toSimpleString(); 8737 } 8738 8739 /// ditto 8740 void toString(W)(ref W writer) const scope 8741 if (isOutputRange!(W, char)) 8742 { 8743 toSimpleString(writer); 8744 } 8745 8746 @safe unittest 8747 { 8748 import core.time; 8749 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8750 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8751 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8752 static assert(__traits(compiles, st.toString())); 8753 static assert(__traits(compiles, cst.toString())); 8754 static assert(__traits(compiles, ist.toString())); 8755 8756 static void testScope(scope ref SysTime st) @safe 8757 { 8758 auto result = st.toString(); 8759 } 8760 } 8761 8762 8763 /++ 8764 Creates a $(LREF SysTime) from a string with the format 8765 YYYYMMDDTHHMMSS.FFFFFFFTZ (where F is fractional seconds and TZ 8766 is the time zone). Whitespace is stripped from the given string. 8767 8768 The exact format is exactly as described in $(LREF toISOString) except 8769 that trailing zeroes are permitted - including having fractional seconds 8770 with all zeroes. The time zone and fractional seconds are optional, 8771 however, a decimal point with nothing following it is invalid. 8772 Also, while $(LREF toISOString) will never generate a string 8773 with more than 7 digits in the fractional seconds (because that's the 8774 limit with hecto-nanosecond precision), it will allow more than 7 digits 8775 in order to read strings from other sources that have higher precision 8776 (however, any digits beyond 7 will be truncated). 8777 8778 If there is no time zone in the string, then 8779 $(REF LocalTime,std,datetime,timezone) is used. If the time zone is "Z", 8780 then `UTC` is used. Otherwise, a 8781 $(REF SimpleTimeZone,std,datetime,timezone) which corresponds to the 8782 given offset from UTC is used. To get the returned $(LREF SysTime) to be 8783 a particular time zone, pass in that time zone and the $(LREF SysTime) 8784 to be returned will be converted to that time zone (though it will still 8785 be read in as whatever time zone is in its string). 8786 8787 The accepted formats for time zone offsets are +HH, -HH, +HHMM, and 8788 -HHMM. 8789 8790 $(RED Warning: 8791 Previously, $(LREF toISOString) did the same as 8792 $(LREF toISOExtString) and generated +HH:MM or -HH:MM for the time 8793 zone when it was not $(REF LocalTime,std,datetime,timezone) or 8794 $(REF UTC,std,datetime,timezone), which is not in conformance with 8795 ISO 8601 for the non-extended string format. This has now been 8796 fixed. However, for now, fromISOString will continue to accept the 8797 extended format for the time zone so that any code which has been 8798 writing out the result of toISOString to read in later will continue 8799 to work. The current behavior will be kept until July 2019 at which 8800 point, fromISOString will be fixed to be standards compliant.) 8801 8802 Params: 8803 isoString = A string formatted in the ISO format for dates and times. 8804 tz = The time zone to convert the given time to (no 8805 conversion occurs if null). 8806 8807 Throws: 8808 $(REF DateTimeException,std,datetime,date) if the given string is 8809 not in the ISO format or if the resulting $(LREF SysTime) would not 8810 be valid. 8811 +/ 8812 static SysTime fromISOString(S)(scope const S isoString, immutable TimeZone tz = null) @safe 8813 if (isSomeString!S) 8814 { 8815 import std.algorithm.searching : startsWith, find; 8816 import std.conv : to; 8817 import std.string : strip; 8818 import std.utf : byCodeUnit; 8819 8820 auto str = strip(isoString); 8821 immutable skipFirst = str.startsWith('+', '-'); 8822 8823 auto found = (skipFirst ? str[1..$] : str).byCodeUnit.find('.', 'Z', '+', '-'); 8824 auto dateTimeStr = str[0 .. $ - found[0].length]; 8825 8826 typeof(str.byCodeUnit) foundTZ; // needs to have longer lifetime than zoneStr 8827 typeof(str) fracSecStr; 8828 typeof(str) zoneStr; 8829 8830 if (found[1] != 0) 8831 { 8832 if (found[1] == 1) 8833 { 8834 foundTZ = found[0].find('Z', '+', '-')[0]; 8835 8836 if (foundTZ.length != 0) 8837 { 8838 static if (isNarrowString!S) 8839 { 8840 fracSecStr = found[0][0 .. $ - foundTZ.length].source; 8841 zoneStr = foundTZ.source; 8842 } 8843 else 8844 { 8845 fracSecStr = found[0][0 .. $ - foundTZ.length]; 8846 zoneStr = foundTZ; 8847 } 8848 } 8849 else 8850 { 8851 static if (isNarrowString!S) 8852 fracSecStr = found[0].source; 8853 else 8854 fracSecStr = found[0]; 8855 } 8856 } 8857 else 8858 { 8859 static if (isNarrowString!S) 8860 zoneStr = found[0].source; 8861 else 8862 zoneStr = found[0]; 8863 } 8864 } 8865 8866 try 8867 { 8868 auto dateTime = DateTime.fromISOString(dateTimeStr); 8869 auto fracSec = fracSecsFromISOString(fracSecStr); 8870 8871 Rebindable!(immutable TimeZone) parsedZone; 8872 8873 if (zoneStr.empty) 8874 parsedZone = LocalTime(); 8875 else if (zoneStr == "Z") 8876 parsedZone = UTC(); 8877 else 8878 { 8879 try 8880 parsedZone = SimpleTimeZone.fromISOString(zoneStr); 8881 catch (DateTimeException dte) 8882 parsedZone = SimpleTimeZone.fromISOExtString(zoneStr); 8883 } 8884 8885 auto retval = SysTime(dateTime, fracSec, parsedZone); 8886 8887 if (tz !is null) 8888 retval.timezone = tz; 8889 8890 return retval; 8891 } 8892 catch (DateTimeException dte) 8893 throw new DateTimeException(format("Invalid format for SysTime.fromISOString: %s", isoString)); 8894 } 8895 8896 /// 8897 @safe unittest 8898 { 8899 import core.time : hours, msecs, usecs, hnsecs; 8900 import std.datetime.date : DateTime; 8901 import std.datetime.timezone : SimpleTimeZone, UTC; 8902 8903 assert(SysTime.fromISOString("20100704T070612") == 8904 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 8905 8906 assert(SysTime.fromISOString("19981225T021500.007") == 8907 SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(7))); 8908 8909 assert(SysTime.fromISOString("00000105T230959.00002") == 8910 SysTime(DateTime(0, 1, 5, 23, 9, 59), usecs(20))); 8911 8912 assert(SysTime.fromISOString("20130207T043937.000050392") == 8913 SysTime(DateTime(2013, 2, 7, 4, 39, 37), hnsecs(503))); 8914 8915 assert(SysTime.fromISOString("-00040105T000002") == 8916 SysTime(DateTime(-4, 1, 5, 0, 0, 2))); 8917 8918 assert(SysTime.fromISOString(" 20100704T070612 ") == 8919 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 8920 8921 assert(SysTime.fromISOString("20100704T070612Z") == 8922 SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC())); 8923 8924 assert(SysTime.fromISOString("20100704T070612-0800") == 8925 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 8926 new immutable SimpleTimeZone(hours(-8)))); 8927 8928 assert(SysTime.fromISOString("20100704T070612+0800") == 8929 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 8930 new immutable SimpleTimeZone(hours(8)))); 8931 } 8932 8933 @safe unittest 8934 { 8935 import core.time; 8936 foreach (str; ["", "20100704000000", "20100704 000000", "20100704t000000", 8937 "20100704T000000.", "20100704T000000.A", "20100704T000000.Z", 8938 "20100704T000000.0000000A", "20100704T000000.00000000A", 8939 "20100704T000000+", "20100704T000000-", "20100704T000000:", 8940 "20100704T000000-:", "20100704T000000+:", "20100704T000000-1:", 8941 "20100704T000000+1:", "20100704T000000+1:0", 8942 "20100704T000000-12.00", "20100704T000000+12.00", 8943 "20100704T000000-8", "20100704T000000+8", 8944 "20100704T000000-800", "20100704T000000+800", 8945 "20100704T000000-080", "20100704T000000+080", 8946 "20100704T000000-2400", "20100704T000000+2400", 8947 "20100704T000000-1260", "20100704T000000+1260", 8948 "20100704T000000.0-8", "20100704T000000.0+8", 8949 "20100704T000000.0-800", "20100704T000000.0+800", 8950 "20100704T000000.0-080", "20100704T000000.0+080", 8951 "20100704T000000.0-2400", "20100704T000000.0+2400", 8952 "20100704T000000.0-1260", "20100704T000000.0+1260", 8953 "20100704T000000-8:00", "20100704T000000+8:00", 8954 "20100704T000000-08:0", "20100704T000000+08:0", 8955 "20100704T000000-24:00", "20100704T000000+24:00", 8956 "20100704T000000-12:60", "20100704T000000+12:60", 8957 "20100704T000000.0-8:00", "20100704T000000.0+8:00", 8958 "20100704T000000.0-08:0", "20100704T000000.0+08:0", 8959 "20100704T000000.0-24:00", "20100704T000000.0+24:00", 8960 "20100704T000000.0-12:60", "20100704T000000.0+12:60", 8961 "2010-07-0400:00:00", "2010-07-04 00:00:00", 8962 "2010-07-04t00:00:00", "2010-07-04T00:00:00.", 8963 "2010-Jul-0400:00:00", "2010-Jul-04 00:00:00", "2010-Jul-04t00:00:00", 8964 "2010-Jul-04T00:00:00", "2010-Jul-04 00:00:00.", 8965 "2010-12-22T172201", "2010-Dec-22 17:22:01"]) 8966 { 8967 assertThrown!DateTimeException(SysTime.fromISOString(str), format("[%s]", str)); 8968 } 8969 8970 static void test(string str, SysTime st, size_t line = __LINE__) 8971 { 8972 if (SysTime.fromISOString(str) != st) 8973 throw new AssertError("unittest failure", __FILE__, line); 8974 } 8975 8976 test("20101222T172201", SysTime(DateTime(2010, 12, 22, 17, 22, 1))); 8977 test("19990706T123033", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8978 test("-19990706T123033", SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 8979 test("+019990706T123033", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8980 test("19990706T123033 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8981 test(" 19990706T123033", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8982 test(" 19990706T123033 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8983 8984 test("19070707T121212.0", SysTime(DateTime(1907, 7, 7, 12, 12, 12))); 8985 test("19070707T121212.0000000", SysTime(DateTime(1907, 7, 7, 12, 12, 12))); 8986 test("19070707T121212.0000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), hnsecs(1))); 8987 test("20100704T000000.00000000", SysTime(Date(2010, 7, 4))); 8988 test("20100704T000000.00000009", SysTime(Date(2010, 7, 4))); 8989 test("20100704T000000.00000019", SysTime(DateTime(2010, 7, 4), hnsecs(1))); 8990 test("19070707T121212.000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1))); 8991 test("19070707T121212.0000010", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1))); 8992 test("19070707T121212.001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1))); 8993 test("19070707T121212.0010000", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1))); 8994 8995 auto west60 = new immutable SimpleTimeZone(hours(-1)); 8996 auto west90 = new immutable SimpleTimeZone(minutes(-90)); 8997 auto west480 = new immutable SimpleTimeZone(hours(-8)); 8998 auto east60 = new immutable SimpleTimeZone(hours(1)); 8999 auto east90 = new immutable SimpleTimeZone(minutes(90)); 9000 auto east480 = new immutable SimpleTimeZone(hours(8)); 9001 9002 test("20101222T172201Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), UTC())); 9003 test("20101222T172201-0100", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60)); 9004 test("20101222T172201-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60)); 9005 test("20101222T172201-0130", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west90)); 9006 test("20101222T172201-0800", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west480)); 9007 test("20101222T172201+0100", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9008 test("20101222T172201+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9009 test("20101222T172201+0130", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 9010 test("20101222T172201+0800", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east480)); 9011 9012 test("20101103T065106.57159Z", SysTime(DateTime(2010, 11, 3, 6, 51, 6), hnsecs(5715900), UTC())); 9013 test("20101222T172201.23412Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_341_200), UTC())); 9014 test("20101222T172201.23112-0100", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_311_200), west60)); 9015 test("20101222T172201.45-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), west60)); 9016 test("20101222T172201.1-0130", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_000_000), west90)); 9017 test("20101222T172201.55-0800", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(5_500_000), west480)); 9018 test("20101222T172201.1234567+0100", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_234_567), east60)); 9019 test("20101222T172201.0+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9020 test("20101222T172201.0000000+0130", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 9021 test("20101222T172201.45+0800", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), east480)); 9022 9023 // for dstring coverage 9024 assert(SysTime.fromISOString("20101222T172201.23112-0100"d) == SysTime( 9025 DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_311_200), west60)); 9026 assert(SysTime.fromISOString("19070707T121212.0010000"d) == SysTime( 9027 DateTime(1907, 7, 7, 12, 12, 12), msecs(1))); 9028 9029 // @@@DEPRECATED_2019-07@@@ 9030 // This isn't deprecated per se, but that text will make it so that it 9031 // pops up when deprecations are moved along around July 2019. At that 9032 // time, we will update fromISOString so that it is conformant with ISO 9033 // 8601, and it will no longer accept ISO extended time zones (it does 9034 // currently because of https://issues.dlang.org/show_bug.cgi?id=15654 9035 // toISOString used to incorrectly use the ISO extended time zone format). 9036 // These tests will then start failing will need to be updated accordingly. 9037 // Also, the notes about this issue in toISOString and fromISOString's 9038 // documentation will need to be removed. 9039 test("20101222T172201-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60)); 9040 test("20101222T172201-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west90)); 9041 test("20101222T172201-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west480)); 9042 test("20101222T172201+01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9043 test("20101222T172201+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 9044 test("20101222T172201+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east480)); 9045 9046 test("20101222T172201.23112-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_311_200), west60)); 9047 test("20101222T172201.1-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_000_000), west90)); 9048 test("20101222T172201.55-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(5_500_000), west480)); 9049 test("20101222T172201.1234567+01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_234_567), east60)); 9050 test("20101222T172201.0000000+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 9051 test("20101222T172201.45+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), east480)); 9052 9053 static void testScope(scope ref string str) @safe 9054 { 9055 auto result = SysTime.fromISOString(str); 9056 } 9057 } 9058 9059 // https://issues.dlang.org/show_bug.cgi?id=17801 9060 @safe unittest 9061 { 9062 import std.conv : to; 9063 import std.meta : AliasSeq; 9064 static foreach (C; AliasSeq!(char, wchar, dchar)) 9065 { 9066 static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) 9067 { 9068 assert(SysTime.fromISOString(to!S("20121221T141516Z")) == 9069 SysTime(DateTime(2012, 12, 21, 14, 15, 16), UTC())); 9070 } 9071 } 9072 } 9073 9074 9075 /++ 9076 Creates a $(LREF SysTime) from a string with the format 9077 YYYY-MM-DDTHH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ 9078 is the time zone). Whitespace is stripped from the given string. 9079 9080 The exact format is exactly as described in $(LREF toISOExtString) 9081 except that trailing zeroes are permitted - including having fractional 9082 seconds with all zeroes. The time zone and fractional seconds are 9083 optional, however, a decimal point with nothing following it is invalid. 9084 Also, while $(LREF toISOExtString) will never generate a 9085 string with more than 7 digits in the fractional seconds (because that's 9086 the limit with hecto-nanosecond precision), it will allow more than 7 9087 digits in order to read strings from other sources that have higher 9088 precision (however, any digits beyond 7 will be truncated). 9089 9090 If there is no time zone in the string, then 9091 $(REF LocalTime,std,datetime,timezone) is used. If the time zone is "Z", 9092 then `UTC` is used. Otherwise, a 9093 $(REF SimpleTimeZone,std,datetime,timezone) which corresponds to the 9094 given offset from UTC is used. To get the returned $(LREF SysTime) to be 9095 a particular time zone, pass in that time zone and the $(LREF SysTime) 9096 to be returned will be converted to that time zone (though it will still 9097 be read in as whatever time zone is in its string). 9098 9099 The accepted formats for time zone offsets are +HH, -HH, +HH:MM, and 9100 -HH:MM. 9101 9102 Params: 9103 isoExtString = A string formatted in the ISO Extended format for 9104 dates and times. 9105 tz = The time zone to convert the given time to (no 9106 conversion occurs if null). 9107 9108 Throws: 9109 $(REF DateTimeException,std,datetime,date) if the given string is 9110 not in the ISO format or if the resulting $(LREF SysTime) would not 9111 be valid. 9112 +/ 9113 static SysTime fromISOExtString(S)(scope const S isoExtString, immutable TimeZone tz = null) @safe 9114 if (isSomeString!(S)) 9115 { 9116 import std.algorithm.searching : countUntil, find; 9117 import std.conv : to; 9118 import std.string : strip, indexOf; 9119 9120 auto str = strip(isoExtString); 9121 9122 auto tIndex = str.indexOf('T'); 9123 enforce!DateTimeException(tIndex != -1, 9124 format("Invalid format for SysTime.fromISOExtString: %s", isoExtString)); 9125 9126 auto found = str[tIndex + 1 .. $].find('.', 'Z', '+', '-'); 9127 auto dateTimeStr = str[0 .. $ - found[0].length]; 9128 9129 typeof(str) foundTZ; // needs to have longer lifetime than zoneStr 9130 typeof(str) fracSecStr; 9131 typeof(str) zoneStr; 9132 9133 if (found[1] != 0) 9134 { 9135 if (found[1] == 1) 9136 { 9137 foundTZ = found[0].find('Z', '+', '-')[0]; 9138 9139 if (foundTZ.length != 0) 9140 { 9141 fracSecStr = found[0][0 .. $ - foundTZ.length]; 9142 zoneStr = foundTZ; 9143 } 9144 else 9145 fracSecStr = found[0]; 9146 } 9147 else 9148 zoneStr = found[0]; 9149 } 9150 9151 try 9152 { 9153 auto dateTime = DateTime.fromISOExtString(dateTimeStr); 9154 auto fracSec = fracSecsFromISOString(fracSecStr); 9155 Rebindable!(immutable TimeZone) parsedZone; 9156 9157 if (zoneStr.empty) 9158 parsedZone = LocalTime(); 9159 else if (zoneStr == "Z") 9160 parsedZone = UTC(); 9161 else 9162 parsedZone = SimpleTimeZone.fromISOExtString(zoneStr); 9163 9164 auto retval = SysTime(dateTime, fracSec, parsedZone); 9165 9166 if (tz !is null) 9167 retval.timezone = tz; 9168 9169 return retval; 9170 } 9171 catch (DateTimeException dte) 9172 throw new DateTimeException(format("Invalid format for SysTime.fromISOExtString: %s", isoExtString)); 9173 } 9174 9175 /// 9176 @safe unittest 9177 { 9178 import core.time : hours, msecs, usecs, hnsecs; 9179 import std.datetime.date : DateTime; 9180 import std.datetime.timezone : SimpleTimeZone, UTC; 9181 9182 assert(SysTime.fromISOExtString("2010-07-04T07:06:12") == 9183 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 9184 9185 assert(SysTime.fromISOExtString("1998-12-25T02:15:00.007") == 9186 SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(7))); 9187 9188 assert(SysTime.fromISOExtString("0000-01-05T23:09:59.00002") == 9189 SysTime(DateTime(0, 1, 5, 23, 9, 59), usecs(20))); 9190 9191 assert(SysTime.fromISOExtString("2013-02-07T04:39:37.000050392") == 9192 SysTime(DateTime(2013, 2, 7, 4, 39, 37), hnsecs(503))); 9193 9194 assert(SysTime.fromISOExtString("-0004-01-05T00:00:02") == 9195 SysTime(DateTime(-4, 1, 5, 0, 0, 2))); 9196 9197 assert(SysTime.fromISOExtString(" 2010-07-04T07:06:12 ") == 9198 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 9199 9200 assert(SysTime.fromISOExtString("2010-07-04T07:06:12Z") == 9201 SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC())); 9202 9203 assert(SysTime.fromISOExtString("2010-07-04T07:06:12-08:00") == 9204 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 9205 new immutable SimpleTimeZone(hours(-8)))); 9206 assert(SysTime.fromISOExtString("2010-07-04T07:06:12+08:00") == 9207 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 9208 new immutable SimpleTimeZone(hours(8)))); 9209 } 9210 9211 @safe unittest 9212 { 9213 import core.time; 9214 foreach (str; ["", "20100704000000", "20100704 000000", 9215 "20100704t000000", "20100704T000000.", "20100704T000000.0", 9216 "2010-07:0400:00:00", "2010-07-04 00:00:00", 9217 "2010-07-04 00:00:00", "2010-07-04t00:00:00", 9218 "2010-07-04T00:00:00.", "2010-07-04T00:00:00.A", "2010-07-04T00:00:00.Z", 9219 "2010-07-04T00:00:00.0000000A", "2010-07-04T00:00:00.00000000A", 9220 "2010-07-04T00:00:00+", "2010-07-04T00:00:00-", 9221 "2010-07-04T00:00:00:", "2010-07-04T00:00:00-:", "2010-07-04T00:00:00+:", 9222 "2010-07-04T00:00:00-1:", "2010-07-04T00:00:00+1:", "2010-07-04T00:00:00+1:0", 9223 "2010-07-04T00:00:00-12.00", "2010-07-04T00:00:00+12.00", 9224 "2010-07-04T00:00:00-8", "2010-07-04T00:00:00+8", 9225 "20100704T000000-800", "20100704T000000+800", 9226 "20100704T000000-080", "20100704T000000+080", 9227 "20100704T000000-2400", "20100704T000000+2400", 9228 "20100704T000000-1260", "20100704T000000+1260", 9229 "20100704T000000.0-800", "20100704T000000.0+800", 9230 "20100704T000000.0-8", "20100704T000000.0+8", 9231 "20100704T000000.0-080", "20100704T000000.0+080", 9232 "20100704T000000.0-2400", "20100704T000000.0+2400", 9233 "20100704T000000.0-1260", "20100704T000000.0+1260", 9234 "2010-07-04T00:00:00-8:00", "2010-07-04T00:00:00+8:00", 9235 "2010-07-04T00:00:00-24:00", "2010-07-04T00:00:00+24:00", 9236 "2010-07-04T00:00:00-12:60", "2010-07-04T00:00:00+12:60", 9237 "2010-07-04T00:00:00.0-8:00", "2010-07-04T00:00:00.0+8:00", 9238 "2010-07-04T00:00:00.0-8", "2010-07-04T00:00:00.0+8", 9239 "2010-07-04T00:00:00.0-24:00", "2010-07-04T00:00:00.0+24:00", 9240 "2010-07-04T00:00:00.0-12:60", "2010-07-04T00:00:00.0+12:60", 9241 "2010-Jul-0400:00:00", "2010-Jul-04t00:00:00", 9242 "2010-Jul-04 00:00:00.", "2010-Jul-04 00:00:00.0", 9243 "20101222T172201", "2010-Dec-22 17:22:01"]) 9244 { 9245 assertThrown!DateTimeException(SysTime.fromISOExtString(str), format("[%s]", str)); 9246 } 9247 9248 static void test(string str, SysTime st, size_t line = __LINE__) 9249 { 9250 if (SysTime.fromISOExtString(str) != st) 9251 throw new AssertError("unittest failure", __FILE__, line); 9252 } 9253 9254 test("2010-12-22T17:22:01", SysTime(DateTime(2010, 12, 22, 17, 22, 1))); 9255 test("1999-07-06T12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9256 test("-1999-07-06T12:30:33", SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 9257 test("+01999-07-06T12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9258 test("1999-07-06T12:30:33 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9259 test(" 1999-07-06T12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9260 test(" 1999-07-06T12:30:33 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9261 9262 test("1907-07-07T12:12:12.0", SysTime(DateTime(1907, 7, 7, 12, 12, 12))); 9263 test("1907-07-07T12:12:12.0000000", SysTime(DateTime(1907, 7, 7, 12, 12, 12))); 9264 test("1907-07-07T12:12:12.0000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), hnsecs(1))); 9265 test("2010-07-04T00:00:00.00000000", SysTime(Date(2010, 7, 4))); 9266 test("2010-07-04T00:00:00.00000009", SysTime(Date(2010, 7, 4))); 9267 test("2010-07-04T00:00:00.00000019", SysTime(DateTime(2010, 7, 4), hnsecs(1))); 9268 test("1907-07-07T12:12:12.000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1))); 9269 test("1907-07-07T12:12:12.0000010", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1))); 9270 test("1907-07-07T12:12:12.001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1))); 9271 test("1907-07-07T12:12:12.0010000", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1))); 9272 9273 auto west60 = new immutable SimpleTimeZone(hours(-1)); 9274 auto west90 = new immutable SimpleTimeZone(minutes(-90)); 9275 auto west480 = new immutable SimpleTimeZone(hours(-8)); 9276 auto east60 = new immutable SimpleTimeZone(hours(1)); 9277 auto east90 = new immutable SimpleTimeZone(minutes(90)); 9278 auto east480 = new immutable SimpleTimeZone(hours(8)); 9279 9280 test("2010-12-22T17:22:01Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), UTC())); 9281 test("2010-12-22T17:22:01-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60)); 9282 test("2010-12-22T17:22:01-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60)); 9283 test("2010-12-22T17:22:01-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west90)); 9284 test("2010-12-22T17:22:01-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west480)); 9285 test("2010-12-22T17:22:01+01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9286 test("2010-12-22T17:22:01+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9287 test("2010-12-22T17:22:01+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 9288 test("2010-12-22T17:22:01+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east480)); 9289 9290 test("2010-11-03T06:51:06.57159Z", SysTime(DateTime(2010, 11, 3, 6, 51, 6), hnsecs(5715900), UTC())); 9291 test("2010-12-22T17:22:01.23412Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_341_200), UTC())); 9292 test("2010-12-22T17:22:01.23112-01:00", 9293 SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_311_200), west60)); 9294 test("2010-12-22T17:22:01.45-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), west60)); 9295 test("2010-12-22T17:22:01.1-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_000_000), west90)); 9296 test("2010-12-22T17:22:01.55-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(5_500_000), west480)); 9297 test("2010-12-22T17:22:01.1234567+01:00", 9298 SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_234_567), east60)); 9299 test("2010-12-22T17:22:01.0+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9300 test("2010-12-22T17:22:01.0000000+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 9301 test("2010-12-22T17:22:01.45+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), east480)); 9302 9303 static void testScope(scope ref string str) @safe 9304 { 9305 auto result = SysTime.fromISOExtString(str); 9306 } 9307 } 9308 9309 // https://issues.dlang.org/show_bug.cgi?id=17801 9310 @safe unittest 9311 { 9312 import core.time; 9313 import std.conv : to; 9314 import std.meta : AliasSeq; 9315 static foreach (C; AliasSeq!(char, wchar, dchar)) 9316 { 9317 static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) 9318 { 9319 assert(SysTime.fromISOExtString(to!S("2012-12-21T14:15:16Z")) == 9320 SysTime(DateTime(2012, 12, 21, 14, 15, 16), UTC())); 9321 } 9322 } 9323 } 9324 9325 9326 /++ 9327 Creates a $(LREF SysTime) from a string with the format 9328 YYYY-Mon-DD HH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ 9329 is the time zone). Whitespace is stripped from the given string. 9330 9331 The exact format is exactly as described in $(LREF toSimpleString) except 9332 that trailing zeroes are permitted - including having fractional seconds 9333 with all zeroes. The time zone and fractional seconds are optional, 9334 however, a decimal point with nothing following it is invalid. 9335 Also, while $(LREF toSimpleString) will never generate a 9336 string with more than 7 digits in the fractional seconds (because that's 9337 the limit with hecto-nanosecond precision), it will allow more than 7 9338 digits in order to read strings from other sources that have higher 9339 precision (however, any digits beyond 7 will be truncated). 9340 9341 If there is no time zone in the string, then 9342 $(REF LocalTime,std,datetime,timezone) is used. If the time zone is "Z", 9343 then `UTC` is used. Otherwise, a 9344 $(REF SimpleTimeZone,std,datetime,timezone) which corresponds to the 9345 given offset from UTC is used. To get the returned $(LREF SysTime) to be 9346 a particular time zone, pass in that time zone and the $(LREF SysTime) 9347 to be returned will be converted to that time zone (though it will still 9348 be read in as whatever time zone is in its string). 9349 9350 The accepted formats for time zone offsets are +HH, -HH, +HH:MM, and 9351 -HH:MM. 9352 9353 Params: 9354 simpleString = A string formatted in the way that 9355 `toSimpleString` formats dates and times. 9356 tz = The time zone to convert the given time to (no 9357 conversion occurs if null). 9358 9359 Throws: 9360 $(REF DateTimeException,std,datetime,date) if the given string is 9361 not in the ISO format or if the resulting $(LREF SysTime) would not 9362 be valid. 9363 +/ 9364 static SysTime fromSimpleString(S)(scope const S simpleString, immutable TimeZone tz = null) @safe 9365 if (isSomeString!(S)) 9366 { 9367 import std.algorithm.searching : find; 9368 import std.conv : to; 9369 import std.string : strip, indexOf; 9370 9371 auto str = strip(simpleString); 9372 9373 auto spaceIndex = str.indexOf(' '); 9374 enforce!DateTimeException(spaceIndex != -1, 9375 format("Invalid format for SysTime.fromSimpleString: %s", simpleString)); 9376 9377 auto found = str[spaceIndex + 1 .. $].find('.', 'Z', '+', '-'); 9378 auto dateTimeStr = str[0 .. $ - found[0].length]; 9379 9380 typeof(str) foundTZ; // needs to have longer lifetime than zoneStr 9381 typeof(str) fracSecStr; 9382 typeof(str) zoneStr; 9383 9384 if (found[1] != 0) 9385 { 9386 if (found[1] == 1) 9387 { 9388 foundTZ = found[0].find('Z', '+', '-')[0]; 9389 9390 if (foundTZ.length != 0) 9391 { 9392 fracSecStr = found[0][0 .. $ - foundTZ.length]; 9393 zoneStr = foundTZ; 9394 } 9395 else 9396 fracSecStr = found[0]; 9397 } 9398 else 9399 zoneStr = found[0]; 9400 } 9401 9402 try 9403 { 9404 auto dateTime = DateTime.fromSimpleString(dateTimeStr); 9405 auto fracSec = fracSecsFromISOString(fracSecStr); 9406 Rebindable!(immutable TimeZone) parsedZone; 9407 9408 if (zoneStr.empty) 9409 parsedZone = LocalTime(); 9410 else if (zoneStr == "Z") 9411 parsedZone = UTC(); 9412 else 9413 parsedZone = SimpleTimeZone.fromISOExtString(zoneStr); 9414 9415 auto retval = SysTime(dateTime, fracSec, parsedZone); 9416 9417 if (tz !is null) 9418 retval.timezone = tz; 9419 9420 return retval; 9421 } 9422 catch (DateTimeException dte) 9423 throw new DateTimeException(format("Invalid format for SysTime.fromSimpleString: %s", simpleString)); 9424 } 9425 9426 /// 9427 @safe unittest 9428 { 9429 import core.time : hours, msecs, usecs, hnsecs; 9430 import std.datetime.date : DateTime; 9431 import std.datetime.timezone : SimpleTimeZone, UTC; 9432 9433 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12") == 9434 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 9435 9436 assert(SysTime.fromSimpleString("1998-Dec-25 02:15:00.007") == 9437 SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(7))); 9438 9439 assert(SysTime.fromSimpleString("0000-Jan-05 23:09:59.00002") == 9440 SysTime(DateTime(0, 1, 5, 23, 9, 59), usecs(20))); 9441 9442 assert(SysTime.fromSimpleString("2013-Feb-07 04:39:37.000050392") == 9443 SysTime(DateTime(2013, 2, 7, 4, 39, 37), hnsecs(503))); 9444 9445 assert(SysTime.fromSimpleString("-0004-Jan-05 00:00:02") == 9446 SysTime(DateTime(-4, 1, 5, 0, 0, 2))); 9447 9448 assert(SysTime.fromSimpleString(" 2010-Jul-04 07:06:12 ") == 9449 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 9450 9451 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12Z") == 9452 SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC())); 9453 9454 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12-08:00") == 9455 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 9456 new immutable SimpleTimeZone(hours(-8)))); 9457 9458 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12+08:00") == 9459 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 9460 new immutable SimpleTimeZone(hours(8)))); 9461 } 9462 9463 @safe unittest 9464 { 9465 import core.time; 9466 foreach (str; ["", "20100704000000", "20100704 000000", 9467 "20100704t000000", "20100704T000000.", "20100704T000000.0", 9468 "2010-07-0400:00:00", "2010-07-04 00:00:00", "2010-07-04t00:00:00", 9469 "2010-07-04T00:00:00.", "2010-07-04T00:00:00.0", 9470 "2010-Jul-0400:00:00", "2010-Jul-04t00:00:00", "2010-Jul-04T00:00:00", 9471 "2010-Jul-04 00:00:00.", "2010-Jul-04 00:00:00.A", "2010-Jul-04 00:00:00.Z", 9472 "2010-Jul-04 00:00:00.0000000A", "2010-Jul-04 00:00:00.00000000A", 9473 "2010-Jul-04 00:00:00+", "2010-Jul-04 00:00:00-", 9474 "2010-Jul-04 00:00:00:", "2010-Jul-04 00:00:00-:", 9475 "2010-Jul-04 00:00:00+:", "2010-Jul-04 00:00:00-1:", 9476 "2010-Jul-04 00:00:00+1:", "2010-Jul-04 00:00:00+1:0", 9477 "2010-Jul-04 00:00:00-12.00", "2010-Jul-04 00:00:00+12.00", 9478 "2010-Jul-04 00:00:00-8", "2010-Jul-04 00:00:00+8", 9479 "20100704T000000-800", "20100704T000000+800", 9480 "20100704T000000-080", "20100704T000000+080", 9481 "20100704T000000-2400", "20100704T000000+2400", 9482 "20100704T000000-1260", "20100704T000000+1260", 9483 "20100704T000000.0-800", "20100704T000000.0+800", 9484 "20100704T000000.0-8", "20100704T000000.0+8", 9485 "20100704T000000.0-080", "20100704T000000.0+080", 9486 "20100704T000000.0-2400", "20100704T000000.0+2400", 9487 "20100704T000000.0-1260", "20100704T000000.0+1260", 9488 "2010-Jul-04 00:00:00-8:00", "2010-Jul-04 00:00:00+8:00", 9489 "2010-Jul-04 00:00:00-08:0", "2010-Jul-04 00:00:00+08:0", 9490 "2010-Jul-04 00:00:00-24:00", "2010-Jul-04 00:00:00+24:00", 9491 "2010-Jul-04 00:00:00-12:60", "2010-Jul-04 00:00:00+24:60", 9492 "2010-Jul-04 00:00:00.0-8:00", "2010-Jul-04 00:00:00+8:00", 9493 "2010-Jul-04 00:00:00.0-8", "2010-Jul-04 00:00:00.0+8", 9494 "2010-Jul-04 00:00:00.0-08:0", "2010-Jul-04 00:00:00.0+08:0", 9495 "2010-Jul-04 00:00:00.0-24:00", "2010-Jul-04 00:00:00.0+24:00", 9496 "2010-Jul-04 00:00:00.0-12:60", "2010-Jul-04 00:00:00.0+24:60", 9497 "20101222T172201", "2010-12-22T172201"]) 9498 { 9499 assertThrown!DateTimeException(SysTime.fromSimpleString(str), format("[%s]", str)); 9500 } 9501 9502 static void test(string str, SysTime st, size_t line = __LINE__) 9503 { 9504 if (SysTime.fromSimpleString(str) != st) 9505 throw new AssertError("unittest failure", __FILE__, line); 9506 } 9507 9508 test("2010-Dec-22 17:22:01", SysTime(DateTime(2010, 12, 22, 17, 22, 1))); 9509 test("1999-Jul-06 12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9510 test("-1999-Jul-06 12:30:33", SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 9511 test("+01999-Jul-06 12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9512 test("1999-Jul-06 12:30:33 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9513 test(" 1999-Jul-06 12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9514 test(" 1999-Jul-06 12:30:33 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9515 9516 test("1907-Jul-07 12:12:12.0", SysTime(DateTime(1907, 7, 7, 12, 12, 12))); 9517 test("1907-Jul-07 12:12:12.0000000", SysTime(DateTime(1907, 7, 7, 12, 12, 12))); 9518 test("2010-Jul-04 00:00:00.00000000", SysTime(Date(2010, 7, 4))); 9519 test("2010-Jul-04 00:00:00.00000009", SysTime(Date(2010, 7, 4))); 9520 test("2010-Jul-04 00:00:00.00000019", SysTime(DateTime(2010, 7, 4), hnsecs(1))); 9521 test("1907-Jul-07 12:12:12.0000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), hnsecs(1))); 9522 test("1907-Jul-07 12:12:12.000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1))); 9523 test("1907-Jul-07 12:12:12.0000010", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1))); 9524 test("1907-Jul-07 12:12:12.001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1))); 9525 test("1907-Jul-07 12:12:12.0010000", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1))); 9526 9527 auto west60 = new immutable SimpleTimeZone(hours(-1)); 9528 auto west90 = new immutable SimpleTimeZone(minutes(-90)); 9529 auto west480 = new immutable SimpleTimeZone(hours(-8)); 9530 auto east60 = new immutable SimpleTimeZone(hours(1)); 9531 auto east90 = new immutable SimpleTimeZone(minutes(90)); 9532 auto east480 = new immutable SimpleTimeZone(hours(8)); 9533 9534 test("2010-Dec-22 17:22:01Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), UTC())); 9535 test("2010-Dec-22 17:22:01-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60)); 9536 test("2010-Dec-22 17:22:01-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60)); 9537 test("2010-Dec-22 17:22:01-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west90)); 9538 test("2010-Dec-22 17:22:01-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west480)); 9539 test("2010-Dec-22 17:22:01+01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9540 test("2010-Dec-22 17:22:01+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9541 test("2010-Dec-22 17:22:01+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 9542 test("2010-Dec-22 17:22:01+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east480)); 9543 9544 test("2010-Nov-03 06:51:06.57159Z", SysTime(DateTime(2010, 11, 3, 6, 51, 6), hnsecs(5715900), UTC())); 9545 test("2010-Dec-22 17:22:01.23412Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_341_200), UTC())); 9546 test("2010-Dec-22 17:22:01.23112-01:00", 9547 SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_311_200), west60)); 9548 test("2010-Dec-22 17:22:01.45-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), west60)); 9549 test("2010-Dec-22 17:22:01.1-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_000_000), west90)); 9550 test("2010-Dec-22 17:22:01.55-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(5_500_000), west480)); 9551 test("2010-Dec-22 17:22:01.1234567+01:00", 9552 SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_234_567), east60)); 9553 test("2010-Dec-22 17:22:01.0+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9554 test("2010-Dec-22 17:22:01.0000000+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 9555 test("2010-Dec-22 17:22:01.45+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), east480)); 9556 9557 static void testScope(scope ref string str) @safe 9558 { 9559 auto result = SysTime.fromSimpleString(str); 9560 } 9561 } 9562 9563 // https://issues.dlang.org/show_bug.cgi?id=17801 9564 @safe unittest 9565 { 9566 import core.time; 9567 import std.conv : to; 9568 import std.meta : AliasSeq; 9569 static foreach (C; AliasSeq!(char, wchar, dchar)) 9570 { 9571 static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) 9572 { 9573 assert(SysTime.fromSimpleString(to!S("2012-Dec-21 14:15:16Z")) == 9574 SysTime(DateTime(2012, 12, 21, 14, 15, 16), UTC())); 9575 } 9576 } 9577 } 9578 9579 9580 /++ 9581 Returns the $(LREF SysTime) farthest in the past which is representable 9582 by $(LREF SysTime). 9583 9584 The $(LREF SysTime) which is returned is in UTC. 9585 +/ 9586 @property static SysTime min() @safe pure nothrow 9587 { 9588 return SysTime(long.min, UTC()); 9589 } 9590 9591 @safe unittest 9592 { 9593 assert(SysTime.min.year < 0); 9594 assert(SysTime.min < SysTime.max); 9595 } 9596 9597 9598 /++ 9599 Returns the $(LREF SysTime) farthest in the future which is representable 9600 by $(LREF SysTime). 9601 9602 The $(LREF SysTime) which is returned is in UTC. 9603 +/ 9604 @property static SysTime max() @safe pure nothrow 9605 { 9606 return SysTime(long.max, UTC()); 9607 } 9608 9609 @safe unittest 9610 { 9611 assert(SysTime.max.year > 0); 9612 assert(SysTime.max > SysTime.min); 9613 } 9614 9615 9616 private: 9617 9618 /+ 9619 Returns `stdTime` converted to $(LREF SysTime)'s time zone. 9620 +/ 9621 @property long adjTime() @safe const nothrow scope 9622 { 9623 return _timezone.utcToTZ(_stdTime); 9624 } 9625 9626 9627 /+ 9628 Converts the given hnsecs from $(LREF SysTime)'s time zone to std time. 9629 +/ 9630 @property void adjTime(long adjTime) @safe nothrow scope 9631 { 9632 _stdTime = _timezone.tzToUTC(adjTime); 9633 } 9634 9635 9636 final class InitTimeZone : TimeZone 9637 { 9638 public: 9639 9640 static immutable(InitTimeZone) opCall() @safe pure nothrow @nogc { return _initTimeZone; } 9641 9642 @property override bool hasDST() @safe const nothrow @nogc { return false; } 9643 9644 override bool dstInEffect(long stdTime) @safe const scope nothrow @nogc { return false; } 9645 9646 override long utcToTZ(long stdTime) @safe const scope nothrow @nogc { return 0; } 9647 9648 override long tzToUTC(long adjTime) @safe const scope nothrow @nogc { return 0; } 9649 9650 override Duration utcOffsetAt(long stdTime) @safe const scope nothrow @nogc { return Duration.zero; } 9651 9652 private: 9653 9654 this() @safe immutable pure 9655 { 9656 super("SysTime.init's timezone", "SysTime.init's timezone", "SysTime.init's timezone"); 9657 } 9658 9659 static immutable InitTimeZone _initTimeZone = new immutable(InitTimeZone); 9660 } 9661 9662 // https://issues.dlang.org/show_bug.cgi?id=17732 9663 @safe unittest 9664 { 9665 assert(SysTime.init.timezone is InitTimeZone()); 9666 assert(SysTime.init.toISOString() == "00010101T000000+00:00"); 9667 assert(SysTime.init.toISOExtString() == "0001-01-01T00:00:00+00:00"); 9668 assert(SysTime.init.toSimpleString() == "0001-Jan-01 00:00:00+00:00"); 9669 assert(SysTime.init.toString() == "0001-Jan-01 00:00:00+00:00"); 9670 } 9671 9672 // Assigning a value to _timezone in SysTime.init currently doesn't work due 9673 // to https://issues.dlang.org/show_bug.cgi?id=17740. So, to hack around 9674 // that problem, these accessors have been added so that we can insert a 9675 // runtime check for null and then use InitTimeZone for SysTime.init (which 9676 // which is the only case where _timezone would be null). This thus fixes 9677 // the problem with segfaulting when using SysTime.init but at the cost of 9678 // what should be an unnecessary null check. Once 17740 has finally been 9679 // fixed, _timezoneStorage should be removed, these accessors should be 9680 // removed, and the _timezone variable declaration should be restored. 9681 pragma(inline, true) @property _timezone() @safe const pure nothrow @nogc 9682 { 9683 return _timezoneStorage is null ? InitTimeZone() : _timezoneStorage; 9684 } 9685 9686 pragma(inline, true) @property void _timezone(return scope immutable TimeZone tz) @safe pure nothrow @nogc scope 9687 { 9688 _timezoneStorage = tz; 9689 } 9690 9691 9692 long _stdTime; 9693 Rebindable!(immutable TimeZone) _timezoneStorage; 9694 //Rebindable!(immutable TimeZone) _timezone = InitTimeZone(); 9695 } 9696 9697 /// 9698 @safe unittest 9699 { 9700 import core.time : days, hours, seconds; 9701 import std.datetime.date : Date, DateTime; 9702 import std.datetime.timezone : SimpleTimeZone, UTC; 9703 9704 const dt = DateTime(2018, 1, 1, 10, 30, 0); 9705 // make a specific point in time in the UTC timezone 9706 auto st = SysTime(dt, UTC()); 9707 assert(st.year == 2018); 9708 assert(st.hour == 10); 9709 9710 // cast to convert 9711 assert(cast(DateTime) st == dt); 9712 assert(cast(Date) st == Date(2018, 1, 1)); 9713 9714 // make a specific point in time in the New York timezone 9715 const ny = SysTime(dt, 9716 new immutable SimpleTimeZone(-5.hours, "America/New_York") 9717 ); 9718 assert(ny != st); 9719 assert(ny.hour == 10); 9720 9721 // ISO standard time strings 9722 assert(st.toISOString() == "20180101T103000Z"); 9723 assert(st.toISOExtString() == "2018-01-01T10:30:00Z"); 9724 9725 // add two days and 30 seconds 9726 st += 2.days + 30.seconds; 9727 assert(st.toISOExtString() == "2018-01-03T10:30:30Z"); 9728 } 9729 9730 9731 /++ 9732 Converts from unix time (which uses midnight, January 1st, 1970 UTC as its 9733 epoch and seconds as its units) to "std time" (which uses midnight, 9734 January 1st, 1 A.D. UTC and hnsecs as its units). 9735 9736 The C standard does not specify the representation of time_t, so it is 9737 implementation defined. On POSIX systems, unix time is equivalent to 9738 time_t, but that's not necessarily true on other systems (e.g. it is 9739 not true for the Digital Mars C runtime). So, be careful when using unix 9740 time with C functions on non-POSIX systems. 9741 9742 "std time"'s epoch is based on the Proleptic Gregorian Calendar per ISO 9743 8601 and is what $(LREF SysTime) uses internally. However, holding the time 9744 as an integer in hnsecs since that epoch technically isn't actually part of 9745 the standard, much as it's based on it, so the name "std time" isn't 9746 particularly good, but there isn't an official name for it. C# uses "ticks" 9747 for the same thing, but they aren't actually clock ticks, and the term 9748 "ticks" $(I is) used for actual clock ticks for $(REF MonoTime, core,time), 9749 so it didn't make sense to use the term ticks here. So, for better or worse, 9750 std.datetime uses the term "std time" for this. 9751 9752 Params: 9753 unixTime = The unix time to convert. 9754 9755 See_Also: 9756 SysTime.fromUnixTime 9757 +/ 9758 long unixTimeToStdTime(long unixTime) @safe pure nothrow @nogc 9759 { 9760 return 621_355_968_000_000_000L + convert!("seconds", "hnsecs")(unixTime); 9761 } 9762 9763 /// 9764 @safe unittest 9765 { 9766 import std.datetime.date : DateTime; 9767 import std.datetime.timezone : UTC; 9768 9769 // Midnight, January 1st, 1970 9770 assert(unixTimeToStdTime(0) == 621_355_968_000_000_000L); 9771 assert(SysTime(unixTimeToStdTime(0)) == 9772 SysTime(DateTime(1970, 1, 1), UTC())); 9773 9774 assert(unixTimeToStdTime(int.max) == 642_830_804_470_000_000L); 9775 assert(SysTime(unixTimeToStdTime(int.max)) == 9776 SysTime(DateTime(2038, 1, 19, 3, 14, 7), UTC())); 9777 9778 assert(unixTimeToStdTime(-127_127) == 621_354_696_730_000_000L); 9779 assert(SysTime(unixTimeToStdTime(-127_127)) == 9780 SysTime(DateTime(1969, 12, 30, 12, 41, 13), UTC())); 9781 } 9782 9783 @safe unittest 9784 { 9785 // Midnight, January 2nd, 1970 9786 assert(unixTimeToStdTime(86_400) == 621_355_968_000_000_000L + 864_000_000_000L); 9787 // Midnight, December 31st, 1969 9788 assert(unixTimeToStdTime(-86_400) == 621_355_968_000_000_000L - 864_000_000_000L); 9789 9790 assert(unixTimeToStdTime(0) == (Date(1970, 1, 1) - Date(1, 1, 1)).total!"hnsecs"); 9791 assert(unixTimeToStdTime(0) == (DateTime(1970, 1, 1) - DateTime(1, 1, 1)).total!"hnsecs"); 9792 9793 foreach (dt; [DateTime(2010, 11, 1, 19, 5, 22), DateTime(1952, 7, 6, 2, 17, 9)]) 9794 assert(unixTimeToStdTime((dt - DateTime(1970, 1, 1)).total!"seconds") == (dt - DateTime.init).total!"hnsecs"); 9795 } 9796 9797 9798 /++ 9799 Converts std time (which uses midnight, January 1st, 1 A.D. UTC as its epoch 9800 and hnsecs as its units) to unix time (which uses midnight, January 1st, 9801 1970 UTC as its epoch and seconds as its units). 9802 9803 The C standard does not specify the representation of time_t, so it is 9804 implementation defined. On POSIX systems, unix time is equivalent to 9805 time_t, but that's not necessarily true on other systems (e.g. it is 9806 not true for the Digital Mars C runtime). So, be careful when using unix 9807 time with C functions on non-POSIX systems. 9808 9809 "std time"'s epoch is based on the Proleptic Gregorian Calendar per ISO 9810 8601 and is what $(LREF SysTime) uses internally. However, holding the time 9811 as an integer in hnsecs since that epoch technically isn't actually part of 9812 the standard, much as it's based on it, so the name "std time" isn't 9813 particularly good, but there isn't an official name for it. C# uses "ticks" 9814 for the same thing, but they aren't actually clock ticks, and the term 9815 "ticks" $(I is) used for actual clock ticks for $(REF MonoTime, core,time), 9816 so it didn't make sense to use the term ticks here. So, for better or worse, 9817 std.datetime uses the term "std time" for this. 9818 9819 By default, the return type is time_t (which is normally an alias for 9820 int on 32-bit systems and long on 64-bit systems), but if a different 9821 size is required than either int or long can be passed as a template 9822 argument to get the desired size. 9823 9824 If the return type is int, and the result can't fit in an int, then the 9825 closest value that can be held in 32 bits will be used (so `int.max` 9826 if it goes over and `int.min` if it goes under). However, no attempt 9827 is made to deal with integer overflow if the return type is long. 9828 9829 Params: 9830 T = The return type (int or long). It defaults to time_t, which is 9831 normally 32 bits on a 32-bit system and 64 bits on a 64-bit 9832 system. 9833 stdTime = The std time to convert. 9834 9835 Returns: 9836 A signed integer representing the unix time which is equivalent to 9837 the given std time. 9838 9839 See_Also: 9840 SysTime.toUnixTime 9841 +/ 9842 T stdTimeToUnixTime(T = time_t)(long stdTime) @safe pure nothrow 9843 if (is(T == int) || is(T == long)) 9844 { 9845 immutable unixTime = convert!("hnsecs", "seconds")(stdTime - 621_355_968_000_000_000L); 9846 9847 static assert(is(time_t == int) || is(time_t == long), 9848 "Currently, std.datetime only supports systems where time_t is int or long"); 9849 9850 static if (is(T == long)) 9851 return unixTime; 9852 else static if (is(T == int)) 9853 { 9854 if (unixTime > int.max) 9855 return int.max; 9856 return unixTime < int.min ? int.min : cast(int) unixTime; 9857 } 9858 else 9859 static assert(0, "Bug in template constraint. Only int and long allowed."); 9860 } 9861 9862 /// 9863 @safe unittest 9864 { 9865 // Midnight, January 1st, 1970 UTC 9866 assert(stdTimeToUnixTime(621_355_968_000_000_000L) == 0); 9867 9868 // 2038-01-19 03:14:07 UTC 9869 assert(stdTimeToUnixTime(642_830_804_470_000_000L) == int.max); 9870 } 9871 9872 @safe unittest 9873 { 9874 enum unixEpochAsStdTime = (Date(1970, 1, 1) - Date.init).total!"hnsecs"; 9875 9876 assert(stdTimeToUnixTime(unixEpochAsStdTime) == 0); // Midnight, January 1st, 1970 9877 assert(stdTimeToUnixTime(unixEpochAsStdTime + 864_000_000_000L) == 86_400); // Midnight, January 2nd, 1970 9878 assert(stdTimeToUnixTime(unixEpochAsStdTime - 864_000_000_000L) == -86_400); // Midnight, December 31st, 1969 9879 9880 assert(stdTimeToUnixTime((Date(1970, 1, 1) - Date(1, 1, 1)).total!"hnsecs") == 0); 9881 assert(stdTimeToUnixTime((DateTime(1970, 1, 1) - DateTime(1, 1, 1)).total!"hnsecs") == 0); 9882 9883 foreach (dt; [DateTime(2010, 11, 1, 19, 5, 22), DateTime(1952, 7, 6, 2, 17, 9)]) 9884 assert(stdTimeToUnixTime((dt - DateTime.init).total!"hnsecs") == (dt - DateTime(1970, 1, 1)).total!"seconds"); 9885 9886 enum max = convert!("seconds", "hnsecs")(int.max); 9887 enum min = convert!("seconds", "hnsecs")(int.min); 9888 enum one = convert!("seconds", "hnsecs")(1); 9889 9890 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + max) == int.max); 9891 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + max) == int.max); 9892 9893 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + max + one) == int.max + 1L); 9894 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + max + one) == int.max); 9895 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + max + 9_999_999) == int.max); 9896 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + max + 9_999_999) == int.max); 9897 9898 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + min) == int.min); 9899 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + min) == int.min); 9900 9901 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + min - one) == int.min - 1L); 9902 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + min - one) == int.min); 9903 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + min - 9_999_999) == int.min); 9904 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + min - 9_999_999) == int.min); 9905 } 9906 9907 9908 version (StdDdoc) 9909 { 9910 version (Windows) 9911 {} 9912 else 9913 { 9914 alias SYSTEMTIME = void*; 9915 alias FILETIME = void*; 9916 } 9917 9918 /++ 9919 $(BLUE This function is Windows-Only.) 9920 9921 Converts a `SYSTEMTIME` struct to a $(LREF SysTime). 9922 9923 Params: 9924 st = The `SYSTEMTIME` struct to convert. 9925 tz = The time zone that the time in the `SYSTEMTIME` struct is 9926 assumed to be (if the `SYSTEMTIME` was supplied by a Windows 9927 system call, the `SYSTEMTIME` will either be in local time 9928 or UTC, depending on the call). 9929 9930 Throws: 9931 $(REF DateTimeException,std,datetime,date) if the given 9932 `SYSTEMTIME` will not fit in a $(LREF SysTime), which is highly 9933 unlikely to happen given that `SysTime.max` is in 29,228 A.D. and 9934 the maximum `SYSTEMTIME` is in 30,827 A.D. 9935 +/ 9936 SysTime SYSTEMTIMEToSysTime(const scope SYSTEMTIME* st, immutable TimeZone tz = LocalTime()) @safe; 9937 9938 9939 /++ 9940 $(BLUE This function is Windows-Only.) 9941 9942 Converts a $(LREF SysTime) to a `SYSTEMTIME` struct. 9943 9944 The `SYSTEMTIME` which is returned will be set using the given 9945 $(LREF SysTime)'s time zone, so to get the `SYSTEMTIME` in 9946 UTC, set the $(LREF SysTime)'s time zone to UTC. 9947 9948 Params: 9949 sysTime = The $(LREF SysTime) to convert. 9950 9951 Throws: 9952 $(REF DateTimeException,std,datetime,date) if the given 9953 $(LREF SysTime) will not fit in a `SYSTEMTIME`. This will only 9954 happen if the $(LREF SysTime)'s date is prior to 1601 A.D. 9955 +/ 9956 SYSTEMTIME SysTimeToSYSTEMTIME(scope SysTime sysTime) @safe; 9957 9958 9959 /++ 9960 $(BLUE This function is Windows-Only.) 9961 9962 Converts a `FILETIME` struct to the number of hnsecs since midnight, 9963 January 1st, 1 A.D. 9964 9965 Params: 9966 ft = The `FILETIME` struct to convert. 9967 9968 Throws: 9969 $(REF DateTimeException,std,datetime,date) if the given 9970 `FILETIME` cannot be represented as the return value. 9971 +/ 9972 long FILETIMEToStdTime(scope const FILETIME* ft) @safe; 9973 9974 9975 /++ 9976 $(BLUE This function is Windows-Only.) 9977 9978 Converts a `FILETIME` struct to a $(LREF SysTime). 9979 9980 Params: 9981 ft = The `FILETIME` struct to convert. 9982 tz = The time zone that the $(LREF SysTime) will be in 9983 (`FILETIME`s are in UTC). 9984 9985 Throws: 9986 $(REF DateTimeException,std,datetime,date) if the given 9987 `FILETIME` will not fit in a $(LREF SysTime). 9988 +/ 9989 SysTime FILETIMEToSysTime(scope const FILETIME* ft, immutable TimeZone tz = LocalTime()) @safe; 9990 9991 9992 /++ 9993 $(BLUE This function is Windows-Only.) 9994 9995 Converts a number of hnsecs since midnight, January 1st, 1 A.D. to a 9996 `FILETIME` struct. 9997 9998 Params: 9999 stdTime = The number of hnsecs since midnight, January 1st, 1 A.D. 10000 UTC. 10001 10002 Throws: 10003 $(REF DateTimeException,std,datetime,date) if the given value will 10004 not fit in a `FILETIME`. 10005 +/ 10006 FILETIME stdTimeToFILETIME(long stdTime) @safe; 10007 10008 10009 /++ 10010 $(BLUE This function is Windows-Only.) 10011 10012 Converts a $(LREF SysTime) to a `FILETIME` struct. 10013 10014 `FILETIME`s are always in UTC. 10015 10016 Params: 10017 sysTime = The $(LREF SysTime) to convert. 10018 10019 Throws: 10020 $(REF DateTimeException,std,datetime,date) if the given 10021 $(LREF SysTime) will not fit in a `FILETIME`. 10022 +/ 10023 FILETIME SysTimeToFILETIME(scope SysTime sysTime) @safe; 10024 } 10025 else version (Windows) 10026 { 10027 SysTime SYSTEMTIMEToSysTime(const scope SYSTEMTIME* st, immutable TimeZone tz = LocalTime()) @safe 10028 { 10029 const max = SysTime.max; 10030 10031 static void throwLaterThanMax() 10032 { 10033 throw new DateTimeException("The given SYSTEMTIME is for a date greater than SysTime.max."); 10034 } 10035 10036 if (st.wYear > max.year) 10037 throwLaterThanMax(); 10038 else if (st.wYear == max.year) 10039 { 10040 if (st.wMonth > max.month) 10041 throwLaterThanMax(); 10042 else if (st.wMonth == max.month) 10043 { 10044 if (st.wDay > max.day) 10045 throwLaterThanMax(); 10046 else if (st.wDay == max.day) 10047 { 10048 if (st.wHour > max.hour) 10049 throwLaterThanMax(); 10050 else if (st.wHour == max.hour) 10051 { 10052 if (st.wMinute > max.minute) 10053 throwLaterThanMax(); 10054 else if (st.wMinute == max.minute) 10055 { 10056 if (st.wSecond > max.second) 10057 throwLaterThanMax(); 10058 else if (st.wSecond == max.second) 10059 { 10060 if (st.wMilliseconds > max.fracSecs.total!"msecs") 10061 throwLaterThanMax(); 10062 } 10063 } 10064 } 10065 } 10066 } 10067 } 10068 10069 auto dt = DateTime(st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); 10070 10071 import core.time : msecs; 10072 return SysTime(dt, msecs(st.wMilliseconds), tz); 10073 } 10074 10075 @system unittest 10076 { 10077 auto sysTime = Clock.currTime(UTC()); 10078 SYSTEMTIME st = void; 10079 GetSystemTime(&st); 10080 auto converted = SYSTEMTIMEToSysTime(&st, UTC()); 10081 import core.time : abs; 10082 assert(abs((converted - sysTime)) <= dur!"seconds"(2)); 10083 10084 static void testScope(scope SYSTEMTIME* st) @safe 10085 { 10086 auto result = SYSTEMTIMEToSysTime(st); 10087 } 10088 } 10089 10090 10091 SYSTEMTIME SysTimeToSYSTEMTIME(scope SysTime sysTime) @safe 10092 { 10093 immutable dt = cast(DateTime) sysTime; 10094 10095 if (dt.year < 1601) 10096 throw new DateTimeException("SYSTEMTIME cannot hold dates prior to the year 1601."); 10097 10098 SYSTEMTIME st; 10099 10100 st.wYear = dt.year; 10101 st.wMonth = dt.month; 10102 st.wDayOfWeek = dt.dayOfWeek; 10103 st.wDay = dt.day; 10104 st.wHour = dt.hour; 10105 st.wMinute = dt.minute; 10106 st.wSecond = dt.second; 10107 st.wMilliseconds = cast(ushort) sysTime.fracSecs.total!"msecs"; 10108 10109 return st; 10110 } 10111 10112 @system unittest 10113 { 10114 SYSTEMTIME st = void; 10115 GetSystemTime(&st); 10116 auto sysTime = SYSTEMTIMEToSysTime(&st, UTC()); 10117 10118 SYSTEMTIME result = SysTimeToSYSTEMTIME(sysTime); 10119 10120 assert(st.wYear == result.wYear); 10121 assert(st.wMonth == result.wMonth); 10122 assert(st.wDayOfWeek == result.wDayOfWeek); 10123 assert(st.wDay == result.wDay); 10124 assert(st.wHour == result.wHour); 10125 assert(st.wMinute == result.wMinute); 10126 assert(st.wSecond == result.wSecond); 10127 assert(st.wMilliseconds == result.wMilliseconds); 10128 10129 static void testScope(scope ref SysTime st) @safe 10130 { 10131 auto localResult = SysTimeToSYSTEMTIME(st); 10132 } 10133 } 10134 10135 private enum hnsecsFrom1601 = 504_911_232_000_000_000L; 10136 10137 long FILETIMEToStdTime(scope const FILETIME* ft) @safe 10138 { 10139 ULARGE_INTEGER ul; 10140 ul.HighPart = ft.dwHighDateTime; 10141 ul.LowPart = ft.dwLowDateTime; 10142 ulong tempHNSecs = ul.QuadPart; 10143 10144 if (tempHNSecs > long.max - hnsecsFrom1601) 10145 throw new DateTimeException("The given FILETIME cannot be represented as a stdTime value."); 10146 10147 return cast(long) tempHNSecs + hnsecsFrom1601; 10148 } 10149 10150 SysTime FILETIMEToSysTime(scope const FILETIME* ft, immutable TimeZone tz = LocalTime()) @safe 10151 { 10152 auto sysTime = SysTime(FILETIMEToStdTime(ft), UTC()); 10153 sysTime.timezone = tz; 10154 return sysTime; 10155 } 10156 10157 @system unittest 10158 { 10159 auto sysTime = Clock.currTime(UTC()); 10160 SYSTEMTIME st = void; 10161 GetSystemTime(&st); 10162 10163 FILETIME ft = void; 10164 SystemTimeToFileTime(&st, &ft); 10165 10166 auto converted = FILETIMEToSysTime(&ft); 10167 10168 import core.time : abs; 10169 assert(abs((converted - sysTime)) <= dur!"seconds"(2)); 10170 10171 static void testScope(scope FILETIME* ft) @safe 10172 { 10173 auto result = FILETIMEToSysTime(ft); 10174 } 10175 } 10176 10177 10178 FILETIME stdTimeToFILETIME(long stdTime) @safe 10179 { 10180 if (stdTime < hnsecsFrom1601) 10181 throw new DateTimeException("The given stdTime value cannot be represented as a FILETIME."); 10182 10183 ULARGE_INTEGER ul; 10184 ul.QuadPart = cast(ulong) stdTime - hnsecsFrom1601; 10185 10186 FILETIME ft; 10187 ft.dwHighDateTime = ul.HighPart; 10188 ft.dwLowDateTime = ul.LowPart; 10189 10190 return ft; 10191 } 10192 10193 FILETIME SysTimeToFILETIME(scope SysTime sysTime) @safe 10194 { 10195 return stdTimeToFILETIME(sysTime.stdTime); 10196 } 10197 10198 @system unittest 10199 { 10200 SYSTEMTIME st = void; 10201 GetSystemTime(&st); 10202 10203 FILETIME ft = void; 10204 SystemTimeToFileTime(&st, &ft); 10205 auto sysTime = FILETIMEToSysTime(&ft, UTC()); 10206 10207 FILETIME result = SysTimeToFILETIME(sysTime); 10208 10209 assert(ft.dwLowDateTime == result.dwLowDateTime); 10210 assert(ft.dwHighDateTime == result.dwHighDateTime); 10211 10212 static void testScope(scope ref SysTime st) @safe 10213 { 10214 auto local_result = SysTimeToFILETIME(st); 10215 } 10216 } 10217 } 10218 10219 10220 /++ 10221 Type representing the DOS file date/time format. 10222 +/ 10223 alias DosFileTime = uint; 10224 10225 /++ 10226 Converts from DOS file date/time to $(LREF SysTime). 10227 10228 Params: 10229 dft = The DOS file time to convert. 10230 tz = The time zone which the DOS file time is assumed to be in. 10231 10232 Throws: 10233 $(REF DateTimeException,std,datetime,date) if the `DosFileTime` is 10234 invalid. 10235 +/ 10236 SysTime DosFileTimeToSysTime(DosFileTime dft, immutable TimeZone tz = LocalTime()) @safe 10237 { 10238 uint dt = cast(uint) dft; 10239 10240 if (dt == 0) 10241 throw new DateTimeException("Invalid DosFileTime."); 10242 10243 int year = ((dt >> 25) & 0x7F) + 1980; 10244 int month = ((dt >> 21) & 0x0F); // 1 .. 12 10245 int dayOfMonth = ((dt >> 16) & 0x1F); // 1 .. 31 10246 int hour = (dt >> 11) & 0x1F; // 0 .. 23 10247 int minute = (dt >> 5) & 0x3F; // 0 .. 59 10248 int second = (dt << 1) & 0x3E; // 0 .. 58 (in 2 second increments) 10249 10250 try 10251 return SysTime(DateTime(year, month, dayOfMonth, hour, minute, second), tz); 10252 catch (DateTimeException dte) 10253 throw new DateTimeException("Invalid DosFileTime", __FILE__, __LINE__, dte); 10254 } 10255 10256 /// 10257 @safe unittest 10258 { 10259 import std.datetime.date : DateTime; 10260 10261 assert(DosFileTimeToSysTime(0b00000000001000010000000000000000) == SysTime(DateTime(1980, 1, 1, 0, 0, 0))); 10262 assert(DosFileTimeToSysTime(0b11111111100111111011111101111101) == SysTime(DateTime(2107, 12, 31, 23, 59, 58))); 10263 assert(DosFileTimeToSysTime(0x3E3F8456) == SysTime(DateTime(2011, 1, 31, 16, 34, 44))); 10264 } 10265 10266 @safe unittest 10267 { 10268 static void testScope(scope ref DosFileTime dft) @safe 10269 { 10270 auto result = DosFileTimeToSysTime(dft); 10271 } 10272 } 10273 10274 10275 /++ 10276 Converts from $(LREF SysTime) to DOS file date/time. 10277 10278 Params: 10279 sysTime = The $(LREF SysTime) to convert. 10280 10281 Throws: 10282 $(REF DateTimeException,std,datetime,date) if the given 10283 $(LREF SysTime) cannot be converted to a `DosFileTime`. 10284 +/ 10285 DosFileTime SysTimeToDosFileTime(scope SysTime sysTime) @safe 10286 { 10287 auto dateTime = cast(DateTime) sysTime; 10288 10289 if (dateTime.year < 1980) 10290 throw new DateTimeException("DOS File Times cannot hold dates prior to 1980."); 10291 10292 if (dateTime.year > 2107) 10293 throw new DateTimeException("DOS File Times cannot hold dates past 2107."); 10294 10295 uint retval = 0; 10296 retval = (dateTime.year - 1980) << 25; 10297 retval |= (dateTime.month & 0x0F) << 21; 10298 retval |= (dateTime.day & 0x1F) << 16; 10299 retval |= (dateTime.hour & 0x1F) << 11; 10300 retval |= (dateTime.minute & 0x3F) << 5; 10301 retval |= (dateTime.second >> 1) & 0x1F; 10302 10303 return cast(DosFileTime) retval; 10304 } 10305 10306 /// 10307 @safe unittest 10308 { 10309 import std.datetime.date : DateTime; 10310 10311 assert(SysTimeToDosFileTime(SysTime(DateTime(1980, 1, 1, 0, 0, 0))) == 0b00000000001000010000000000000000); 10312 assert(SysTimeToDosFileTime(SysTime(DateTime(2107, 12, 31, 23, 59, 58))) == 0b11111111100111111011111101111101); 10313 assert(SysTimeToDosFileTime(SysTime(DateTime(2011, 1, 31, 16, 34, 44))) == 0x3E3F8456); 10314 } 10315 10316 @safe unittest 10317 { 10318 static void testScope(scope ref SysTime st) @safe 10319 { 10320 auto result = SysTimeToDosFileTime(st); 10321 } 10322 } 10323 10324 10325 /++ 10326 The given array of `char` or random-access range of `char` or 10327 `ubyte` is expected to be in the format specified in 10328 $(HTTP tools.ietf.org/html/rfc5322, RFC 5322) section 3.3 with the 10329 grammar rule $(I date-time). It is the date-time format commonly used in 10330 internet messages such as e-mail and HTTP. The corresponding 10331 $(LREF SysTime) will be returned. 10332 10333 RFC 822 was the original spec (hence the function's name), whereas RFC 5322 10334 is the current spec. 10335 10336 The day of the week is ignored beyond verifying that it's a valid day of the 10337 week, as the day of the week can be inferred from the date. It is not 10338 checked whether the given day of the week matches the actual day of the week 10339 of the given date (though it is technically invalid per the spec if the 10340 day of the week doesn't match the actual day of the week of the given date). 10341 10342 If the time zone is `"-0000"` (or considered to be equivalent to 10343 `"-0000"` by section 4.3 of the spec), a 10344 $(REF SimpleTimeZone,std,datetime,timezone) with a utc offset of `0` is 10345 used rather than $(REF UTC,std,datetime,timezone), whereas `"+0000"` uses 10346 $(REF UTC,std,datetime,timezone). 10347 10348 Note that because $(LREF SysTime) does not currently support having a second 10349 value of 60 (as is sometimes done for leap seconds), if the date-time value 10350 does have a value of 60 for the seconds, it is treated as 59. 10351 10352 The one area in which this function violates RFC 5322 is that it accepts 10353 `"\n"` in folding whitespace in the place of `"\r\n"`, because the 10354 HTTP spec requires it. 10355 10356 Throws: 10357 $(REF DateTimeException,std,datetime,date) if the given string doesn't 10358 follow the grammar for a date-time field or if the resulting 10359 $(LREF SysTime) is invalid. 10360 +/ 10361 SysTime parseRFC822DateTime()(scope const char[] value) @safe 10362 { 10363 import std.string : representation; 10364 return parseRFC822DateTime(value.representation); 10365 } 10366 10367 /++ Ditto +/ 10368 SysTime parseRFC822DateTime(R)(scope R value) 10369 if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && 10370 (is(immutable ElementType!R == immutable char) || is(immutable ElementType!R == immutable ubyte))) 10371 { 10372 import std.algorithm.searching : find, all; 10373 import std.ascii : isDigit, isAlpha, isPrintable; 10374 import std.conv : to; 10375 import std.functional : not; 10376 import std.string : capitalize, format; 10377 import std.traits : EnumMembers, isArray; 10378 import std.typecons : Rebindable; 10379 10380 void stripAndCheckLen(R valueBefore, size_t minLen, size_t line = __LINE__) 10381 { 10382 value = _stripCFWS(valueBefore); 10383 if (value.length < minLen) 10384 throw new DateTimeException("date-time value too short", __FILE__, line); 10385 } 10386 stripAndCheckLen(value, "7Dec1200:00A".length); 10387 10388 static if (isArray!R && (is(ElementEncodingType!R == char) || is(ElementEncodingType!R == ubyte))) 10389 { 10390 static string sliceAsString(R str) @trusted 10391 { 10392 return cast(string) str; 10393 } 10394 } 10395 else 10396 { 10397 char[4] temp; 10398 char[] sliceAsString(R str) @trusted 10399 { 10400 size_t i = 0; 10401 foreach (c; str) 10402 temp[i++] = cast(char) c; 10403 return temp[0 .. str.length]; 10404 } 10405 } 10406 10407 // day-of-week 10408 if (isAlpha(value[0])) 10409 { 10410 auto dowStr = sliceAsString(value[0 .. 3]); 10411 switch (dowStr) 10412 { 10413 foreach (dow; EnumMembers!DayOfWeek) 10414 { 10415 enum dowC = capitalize(to!string(dow)); 10416 case dowC: 10417 goto afterDoW; 10418 } 10419 default: throw new DateTimeException(format("Invalid day-of-week: %s", dowStr)); 10420 } 10421 afterDoW: stripAndCheckLen(value[3 .. value.length], ",7Dec1200:00A".length); 10422 if (value[0] != ',') 10423 throw new DateTimeException("day-of-week missing comma"); 10424 stripAndCheckLen(value[1 .. value.length], "7Dec1200:00A".length); 10425 } 10426 10427 // day 10428 immutable digits = isDigit(value[1]) ? 2 : 1; 10429 immutable day = _convDigits!short(value[0 .. digits]); 10430 if (day == -1) 10431 throw new DateTimeException("Invalid day"); 10432 stripAndCheckLen(value[digits .. value.length], "Dec1200:00A".length); 10433 10434 // month 10435 Month month; 10436 { 10437 auto monStr = sliceAsString(value[0 .. 3]); 10438 switch (monStr) 10439 { 10440 foreach (mon; EnumMembers!Month) 10441 { 10442 enum monC = capitalize(to!string(mon)); 10443 case monC: 10444 { 10445 month = mon; 10446 goto afterMon; 10447 } 10448 } 10449 default: throw new DateTimeException(format("Invalid month: %s", monStr)); 10450 } 10451 afterMon: stripAndCheckLen(value[3 .. value.length], "1200:00A".length); 10452 } 10453 10454 // year 10455 auto found = value[2 .. value.length].find!(not!(isDigit))(); 10456 size_t yearLen = value.length - found.length; 10457 if (found.length == 0) 10458 throw new DateTimeException("Invalid year"); 10459 if (found[0] == ':') 10460 yearLen -= 2; 10461 auto year = _convDigits!short(value[0 .. yearLen]); 10462 if (year < 1900) 10463 { 10464 if (year == -1) 10465 throw new DateTimeException("Invalid year"); 10466 if (yearLen < 4) 10467 { 10468 if (yearLen == 3) 10469 year += 1900; 10470 else if (yearLen == 2) 10471 year += year < 50 ? 2000 : 1900; 10472 else 10473 throw new DateTimeException("Invalid year. Too few digits."); 10474 } 10475 else 10476 throw new DateTimeException("Invalid year. Cannot be earlier than 1900."); 10477 } 10478 stripAndCheckLen(value[yearLen .. value.length], "00:00A".length); 10479 10480 // hour 10481 immutable hour = _convDigits!short(value[0 .. 2]); 10482 stripAndCheckLen(value[2 .. value.length], ":00A".length); 10483 if (value[0] != ':') 10484 throw new DateTimeException("Invalid hour"); 10485 stripAndCheckLen(value[1 .. value.length], "00A".length); 10486 10487 // minute 10488 immutable minute = _convDigits!short(value[0 .. 2]); 10489 stripAndCheckLen(value[2 .. value.length], "A".length); 10490 10491 // second 10492 short second; 10493 if (value[0] == ':') 10494 { 10495 stripAndCheckLen(value[1 .. value.length], "00A".length); 10496 second = _convDigits!short(value[0 .. 2]); 10497 // this is just if/until SysTime is sorted out to fully support leap seconds 10498 if (second == 60) 10499 second = 59; 10500 stripAndCheckLen(value[2 .. value.length], "A".length); 10501 } 10502 10503 immutable(TimeZone) parseTZ(int sign) 10504 { 10505 if (value.length < 5) 10506 throw new DateTimeException("Invalid timezone"); 10507 immutable zoneHours = _convDigits!short(value[1 .. 3]); 10508 immutable zoneMinutes = _convDigits!short(value[3 .. 5]); 10509 if (zoneHours == -1 || zoneMinutes == -1 || zoneMinutes > 59) 10510 throw new DateTimeException("Invalid timezone"); 10511 value = value[5 .. value.length]; 10512 immutable utcOffset = (dur!"hours"(zoneHours) + dur!"minutes"(zoneMinutes)) * sign; 10513 if (utcOffset == Duration.zero) 10514 { 10515 return sign == 1 ? cast(immutable(TimeZone))UTC() 10516 : cast(immutable(TimeZone))new immutable SimpleTimeZone(Duration.zero); 10517 } 10518 return new immutable(SimpleTimeZone)(utcOffset); 10519 } 10520 10521 // zone 10522 Rebindable!(immutable TimeZone) tz; 10523 if (value[0] == '-') 10524 tz = parseTZ(-1); 10525 else if (value[0] == '+') 10526 tz = parseTZ(1); 10527 else 10528 { 10529 // obs-zone 10530 immutable tzLen = value.length - find(value, ' ', '\t', '(')[0].length; 10531 switch (sliceAsString(value[0 .. tzLen <= 4 ? tzLen : 4])) 10532 { 10533 case "UT": case "GMT": tz = UTC(); break; 10534 case "EST": tz = new immutable SimpleTimeZone(dur!"hours"(-5)); break; 10535 case "EDT": tz = new immutable SimpleTimeZone(dur!"hours"(-4)); break; 10536 case "CST": tz = new immutable SimpleTimeZone(dur!"hours"(-6)); break; 10537 case "CDT": tz = new immutable SimpleTimeZone(dur!"hours"(-5)); break; 10538 case "MST": tz = new immutable SimpleTimeZone(dur!"hours"(-7)); break; 10539 case "MDT": tz = new immutable SimpleTimeZone(dur!"hours"(-6)); break; 10540 case "PST": tz = new immutable SimpleTimeZone(dur!"hours"(-8)); break; 10541 case "PDT": tz = new immutable SimpleTimeZone(dur!"hours"(-7)); break; 10542 case "J": case "j": throw new DateTimeException("Invalid timezone"); 10543 default: 10544 { 10545 if (all!(isAlpha)(value[0 .. tzLen])) 10546 { 10547 tz = new immutable SimpleTimeZone(Duration.zero); 10548 break; 10549 } 10550 throw new DateTimeException("Invalid timezone"); 10551 } 10552 } 10553 value = value[tzLen .. value.length]; 10554 } 10555 10556 // This is kind of arbitrary. Technically, nothing but CFWS is legal past 10557 // the end of the timezone, but we don't want to be picky about that in a 10558 // function that's just parsing rather than validating. So, the idea here is 10559 // that if the next character is printable (and not part of CFWS), then it 10560 // might be part of the timezone and thus affect what the timezone was 10561 // supposed to be, so we'll throw, but otherwise, we'll just ignore it. 10562 if (!value.empty && isPrintable(value[0]) && value[0] != ' ' && value[0] != '(') 10563 throw new DateTimeException("Invalid timezone"); 10564 10565 try 10566 return SysTime(DateTime(year, month, day, hour, minute, second), tz); 10567 catch (DateTimeException dte) 10568 throw new DateTimeException("date-time format is correct, but the resulting SysTime is invalid.", dte); 10569 } 10570 10571 /// 10572 @safe unittest 10573 { 10574 import core.time : hours; 10575 import std.datetime.date : DateTime, DateTimeException; 10576 import std.datetime.timezone : SimpleTimeZone, UTC; 10577 import std.exception : assertThrown; 10578 10579 auto tz = new immutable SimpleTimeZone(hours(-8)); 10580 assert(parseRFC822DateTime("Sat, 6 Jan 1990 12:14:19 -0800") == 10581 SysTime(DateTime(1990, 1, 6, 12, 14, 19), tz)); 10582 10583 assert(parseRFC822DateTime("9 Jul 2002 13:11 +0000") == 10584 SysTime(DateTime(2002, 7, 9, 13, 11, 0), UTC())); 10585 10586 auto badStr = "29 Feb 2001 12:17:16 +0200"; 10587 assertThrown!DateTimeException(parseRFC822DateTime(badStr)); 10588 } 10589 10590 version (StdUnittest) private void testParse822(alias cr)(string str, SysTime expected, size_t line = __LINE__) 10591 { 10592 import std.format : format; 10593 auto value = cr(str); 10594 auto result = parseRFC822DateTime(value); 10595 if (result != expected) 10596 throw new AssertError(format("wrong result. expected [%s], actual[%s]", expected, result), __FILE__, line); 10597 } 10598 10599 version (StdUnittest) private void testBadParse822(alias cr)(string str, size_t line = __LINE__) 10600 { 10601 try 10602 parseRFC822DateTime(cr(str)); 10603 catch (DateTimeException) 10604 return; 10605 throw new AssertError("No DateTimeException was thrown", __FILE__, line); 10606 } 10607 10608 @system unittest 10609 { 10610 import core.time; 10611 import std.algorithm.iteration : filter, map; 10612 import std.algorithm.searching : canFind; 10613 import std.array : array; 10614 import std.ascii : letters; 10615 import std.format : format; 10616 import std.meta : AliasSeq; 10617 import std.range : chain, iota, take; 10618 import std.stdio : writefln, writeln; 10619 import std.string : representation; 10620 10621 static struct Rand3Letters 10622 { 10623 enum empty = false; 10624 @property auto front() { return _mon; } 10625 void popFront() 10626 { 10627 import std.exception : assumeUnique; 10628 import std.random : rndGen; 10629 _mon = rndGen.map!(a => letters[a % letters.length])().take(3).array().assumeUnique(); 10630 } 10631 string _mon; 10632 static auto start() { Rand3Letters retval; retval.popFront(); return retval; } 10633 } 10634 10635 static foreach (cr; AliasSeq!(function(string a){return cast(char[]) a;}, 10636 function(string a){return cast(ubyte[]) a;}, 10637 function(string a){return a;}, 10638 function(string a){return map!(b => cast(char) b)(a.representation);})) 10639 {(){ // workaround slow optimizations for large functions 10640 // https://issues.dlang.org/show_bug.cgi?id=2396 10641 scope(failure) writeln(typeof(cr).stringof); 10642 alias test = testParse822!cr; 10643 alias testBad = testBadParse822!cr; 10644 10645 immutable std1 = DateTime(2012, 12, 21, 13, 14, 15); 10646 immutable std2 = DateTime(2012, 12, 21, 13, 14, 0); 10647 immutable dst1 = DateTime(1976, 7, 4, 5, 4, 22); 10648 immutable dst2 = DateTime(1976, 7, 4, 5, 4, 0); 10649 10650 test("21 Dec 2012 13:14:15 +0000", SysTime(std1, UTC())); 10651 test("21 Dec 2012 13:14 +0000", SysTime(std2, UTC())); 10652 test("Fri, 21 Dec 2012 13:14 +0000", SysTime(std2, UTC())); 10653 test("Fri, 21 Dec 2012 13:14:15 +0000", SysTime(std1, UTC())); 10654 10655 test("04 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC())); 10656 test("04 Jul 1976 05:04 +0000", SysTime(dst2, UTC())); 10657 test("Sun, 04 Jul 1976 05:04 +0000", SysTime(dst2, UTC())); 10658 test("Sun, 04 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC())); 10659 10660 test("4 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC())); 10661 test("4 Jul 1976 05:04 +0000", SysTime(dst2, UTC())); 10662 test("Sun, 4 Jul 1976 05:04 +0000", SysTime(dst2, UTC())); 10663 test("Sun, 4 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC())); 10664 10665 auto badTZ = new immutable SimpleTimeZone(Duration.zero); 10666 test("21 Dec 2012 13:14:15 -0000", SysTime(std1, badTZ)); 10667 test("21 Dec 2012 13:14 -0000", SysTime(std2, badTZ)); 10668 test("Fri, 21 Dec 2012 13:14 -0000", SysTime(std2, badTZ)); 10669 test("Fri, 21 Dec 2012 13:14:15 -0000", SysTime(std1, badTZ)); 10670 10671 test("04 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ)); 10672 test("04 Jul 1976 05:04 -0000", SysTime(dst2, badTZ)); 10673 test("Sun, 04 Jul 1976 05:04 -0000", SysTime(dst2, badTZ)); 10674 test("Sun, 04 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ)); 10675 10676 test("4 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ)); 10677 test("4 Jul 1976 05:04 -0000", SysTime(dst2, badTZ)); 10678 test("Sun, 4 Jul 1976 05:04 -0000", SysTime(dst2, badTZ)); 10679 test("Sun, 4 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ)); 10680 10681 auto pst = new immutable SimpleTimeZone(dur!"hours"(-8)); 10682 auto pdt = new immutable SimpleTimeZone(dur!"hours"(-7)); 10683 test("21 Dec 2012 13:14:15 -0800", SysTime(std1, pst)); 10684 test("21 Dec 2012 13:14 -0800", SysTime(std2, pst)); 10685 test("Fri, 21 Dec 2012 13:14 -0800", SysTime(std2, pst)); 10686 test("Fri, 21 Dec 2012 13:14:15 -0800", SysTime(std1, pst)); 10687 10688 test("04 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt)); 10689 test("04 Jul 1976 05:04 -0700", SysTime(dst2, pdt)); 10690 test("Sun, 04 Jul 1976 05:04 -0700", SysTime(dst2, pdt)); 10691 test("Sun, 04 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt)); 10692 10693 test("4 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt)); 10694 test("4 Jul 1976 05:04 -0700", SysTime(dst2, pdt)); 10695 test("Sun, 4 Jul 1976 05:04 -0700", SysTime(dst2, pdt)); 10696 test("Sun, 4 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt)); 10697 10698 auto cet = new immutable SimpleTimeZone(dur!"hours"(1)); 10699 auto cest = new immutable SimpleTimeZone(dur!"hours"(2)); 10700 test("21 Dec 2012 13:14:15 +0100", SysTime(std1, cet)); 10701 test("21 Dec 2012 13:14 +0100", SysTime(std2, cet)); 10702 test("Fri, 21 Dec 2012 13:14 +0100", SysTime(std2, cet)); 10703 test("Fri, 21 Dec 2012 13:14:15 +0100", SysTime(std1, cet)); 10704 10705 test("04 Jul 1976 05:04:22 +0200", SysTime(dst1, cest)); 10706 test("04 Jul 1976 05:04 +0200", SysTime(dst2, cest)); 10707 test("Sun, 04 Jul 1976 05:04 +0200", SysTime(dst2, cest)); 10708 test("Sun, 04 Jul 1976 05:04:22 +0200", SysTime(dst1, cest)); 10709 10710 test("4 Jul 1976 05:04:22 +0200", SysTime(dst1, cest)); 10711 test("4 Jul 1976 05:04 +0200", SysTime(dst2, cest)); 10712 test("Sun, 4 Jul 1976 05:04 +0200", SysTime(dst2, cest)); 10713 test("Sun, 4 Jul 1976 05:04:22 +0200", SysTime(dst1, cest)); 10714 10715 // dst and std times are switched in the Southern Hemisphere which is why the 10716 // time zone names and DateTime variables don't match. 10717 auto cstStd = new immutable SimpleTimeZone(dur!"hours"(9) + dur!"minutes"(30)); 10718 auto cstDST = new immutable SimpleTimeZone(dur!"hours"(10) + dur!"minutes"(30)); 10719 test("21 Dec 2012 13:14:15 +1030", SysTime(std1, cstDST)); 10720 test("21 Dec 2012 13:14 +1030", SysTime(std2, cstDST)); 10721 test("Fri, 21 Dec 2012 13:14 +1030", SysTime(std2, cstDST)); 10722 test("Fri, 21 Dec 2012 13:14:15 +1030", SysTime(std1, cstDST)); 10723 10724 test("04 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 10725 test("04 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 10726 test("Sun, 04 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 10727 test("Sun, 04 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 10728 10729 test("4 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 10730 test("4 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 10731 test("Sun, 4 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 10732 test("Sun, 4 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 10733 10734 foreach (int i, mon; _monthNames) 10735 { 10736 test(format("17 %s 2012 00:05:02 +0000", mon), SysTime(DateTime(2012, i + 1, 17, 0, 5, 2), UTC())); 10737 test(format("17 %s 2012 00:05 +0000", mon), SysTime(DateTime(2012, i + 1, 17, 0, 5, 0), UTC())); 10738 } 10739 10740 import std.uni : toLower, toUpper; 10741 foreach (mon; chain(_monthNames[].map!(a => toLower(a))(), 10742 _monthNames[].map!(a => toUpper(a))(), 10743 ["Jam", "Jen", "Fec", "Fdb", "Mas", "Mbr", "Aps", "Aqr", "Mai", "Miy", 10744 "Jum", "Jbn", "Jup", "Jal", "Aur", "Apg", "Sem", "Sap", "Ocm", "Odt", 10745 "Nom", "Nav", "Dem", "Dac"], 10746 Rand3Letters.start().filter!(a => !_monthNames[].canFind(a)).take(20))) 10747 { 10748 scope(failure) writefln("Month: %s", mon); 10749 testBad(format("17 %s 2012 00:05:02 +0000", mon)); 10750 testBad(format("17 %s 2012 00:05 +0000", mon)); 10751 } 10752 10753 immutable string[7] daysOfWeekNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; 10754 10755 { 10756 auto start = SysTime(DateTime(2012, 11, 11, 9, 42, 0), UTC()); 10757 int day = 11; 10758 10759 foreach (int i, dow; daysOfWeekNames) 10760 { 10761 auto curr = start + dur!"days"(i); 10762 test(format("%s, %s Nov 2012 09:42:00 +0000", dow, day), curr); 10763 test(format("%s, %s Nov 2012 09:42 +0000", dow, day++), curr); 10764 10765 // Whether the day of the week matches the date is ignored. 10766 test(format("%s, 11 Nov 2012 09:42:00 +0000", dow), start); 10767 test(format("%s, 11 Nov 2012 09:42 +0000", dow), start); 10768 } 10769 } 10770 10771 foreach (dow; chain(daysOfWeekNames[].map!(a => toLower(a))(), 10772 daysOfWeekNames[].map!(a => toUpper(a))(), 10773 ["Sum", "Spn", "Mom", "Man", "Tuf", "Tae", "Wem", "Wdd", "The", "Tur", 10774 "Fro", "Fai", "San", "Sut"], 10775 Rand3Letters.start().filter!(a => !daysOfWeekNames[].canFind(a)).take(20))) 10776 { 10777 scope(failure) writefln("Day of Week: %s", dow); 10778 testBad(format("%s, 11 Nov 2012 09:42:00 +0000", dow)); 10779 testBad(format("%s, 11 Nov 2012 09:42 +0000", dow)); 10780 } 10781 10782 testBad("31 Dec 1899 23:59:59 +0000"); 10783 test("01 Jan 1900 00:00:00 +0000", SysTime(Date(1900, 1, 1), UTC())); 10784 test("01 Jan 1900 00:00:00 -0000", SysTime(Date(1900, 1, 1), 10785 new immutable SimpleTimeZone(Duration.zero))); 10786 test("01 Jan 1900 00:00:00 -0700", SysTime(Date(1900, 1, 1), 10787 new immutable SimpleTimeZone(dur!"hours"(-7)))); 10788 10789 { 10790 auto st1 = SysTime(Date(1900, 1, 1), UTC()); 10791 auto st2 = SysTime(Date(1900, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-11))); 10792 foreach (i; 1900 .. 2102) 10793 { 10794 test(format("1 Jan %05d 00:00 +0000", i), st1); 10795 test(format("1 Jan %05d 00:00 -1100", i), st2); 10796 st1.add!"years"(1); 10797 st2.add!"years"(1); 10798 } 10799 st1.year = 9998; 10800 st2.year = 9998; 10801 foreach (i; 9998 .. 11_002) 10802 { 10803 test(format("1 Jan %05d 00:00 +0000", i), st1); 10804 test(format("1 Jan %05d 00:00 -1100", i), st2); 10805 st1.add!"years"(1); 10806 st2.add!"years"(1); 10807 } 10808 } 10809 10810 testBad("12 Feb 1907 23:17:09 0000"); 10811 testBad("12 Feb 1907 23:17:09 +000"); 10812 testBad("12 Feb 1907 23:17:09 -000"); 10813 testBad("12 Feb 1907 23:17:09 +00000"); 10814 testBad("12 Feb 1907 23:17:09 -00000"); 10815 testBad("12 Feb 1907 23:17:09 +A"); 10816 testBad("12 Feb 1907 23:17:09 +PST"); 10817 testBad("12 Feb 1907 23:17:09 -A"); 10818 testBad("12 Feb 1907 23:17:09 -PST"); 10819 10820 // test trailing stuff that gets ignored 10821 { 10822 foreach (c; chain(iota(0, 33), ['('], iota(127, ubyte.max + 1))) 10823 { 10824 scope(failure) writefln("c: %d", c); 10825 test(format("21 Dec 2012 13:14:15 +0000%c", cast(char) c), SysTime(std1, UTC())); 10826 test(format("21 Dec 2012 13:14:15 +0000%c ", cast(char) c), SysTime(std1, UTC())); 10827 test(format("21 Dec 2012 13:14:15 +0000%chello", cast(char) c), SysTime(std1, UTC())); 10828 } 10829 } 10830 10831 // test trailing stuff that doesn't get ignored 10832 { 10833 foreach (c; chain(iota(33, '('), iota('(' + 1, 127))) 10834 { 10835 scope(failure) writefln("c: %d", c); 10836 testBad(format("21 Dec 2012 13:14:15 +0000%c", cast(char) c)); 10837 testBad(format("21 Dec 2012 13:14:15 +0000%c ", cast(char) c)); 10838 testBad(format("21 Dec 2012 13:14:15 +0000%chello", cast(char) c)); 10839 } 10840 } 10841 10842 testBad("32 Jan 2012 12:13:14 -0800"); 10843 testBad("31 Jan 2012 24:13:14 -0800"); 10844 testBad("31 Jan 2012 12:60:14 -0800"); 10845 testBad("31 Jan 2012 12:13:61 -0800"); 10846 testBad("31 Jan 2012 12:13:14 -0860"); 10847 test("31 Jan 2012 12:13:14 -0859", 10848 SysTime(DateTime(2012, 1, 31, 12, 13, 14), 10849 new immutable SimpleTimeZone(dur!"hours"(-8) + dur!"minutes"(-59)))); 10850 10851 // leap-seconds 10852 test("21 Dec 2012 15:59:60 -0800", SysTime(DateTime(2012, 12, 21, 15, 59, 59), pst)); 10853 10854 // FWS 10855 test("Sun,4 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 10856 test("Sun,4 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 10857 test("Sun,4 Jul 1976 05:04 +0930 (foo)", SysTime(dst2, cstStd)); 10858 test("Sun,4 Jul 1976 05:04:22 +0930 (foo)", SysTime(dst1, cstStd)); 10859 test("Sun,4 \r\n Jul \r\n 1976 \r\n 05:04 \r\n +0930 \r\n (foo)", SysTime(dst2, cstStd)); 10860 test("Sun,4 \r\n Jul \r\n 1976 \r\n 05:04:22 \r\n +0930 \r\n (foo)", SysTime(dst1, cstStd)); 10861 10862 auto str = "01 Jan 2012 12:13:14 -0800 "; 10863 test(str, SysTime(DateTime(2012, 1, 1, 12, 13, 14), new immutable SimpleTimeZone(hours(-8)))); 10864 foreach (i; 0 .. str.length) 10865 { 10866 auto currStr = str.dup; 10867 currStr[i] = 'x'; 10868 scope(failure) writefln("failed: %s", currStr); 10869 testBad(cast(string) currStr); 10870 } 10871 foreach (i; 2 .. str.length) 10872 { 10873 auto currStr = str[0 .. $ - i]; 10874 scope(failure) writefln("failed: %s", currStr); 10875 testBad(cast(string) currStr); 10876 testBad((cast(string) currStr) ~ " "); 10877 } 10878 }();} 10879 10880 static void testScope(scope ref string str) @safe 10881 { 10882 auto result = parseRFC822DateTime(str); 10883 } 10884 } 10885 10886 // Obsolete Format per section 4.3 of RFC 5322. 10887 @system unittest 10888 { 10889 import std.algorithm.iteration : filter, map; 10890 import std.ascii : letters; 10891 import std.exception : collectExceptionMsg; 10892 import std.format : format; 10893 import std.meta : AliasSeq; 10894 import std.range : chain, iota; 10895 import std.stdio : writefln, writeln; 10896 import std.string : representation; 10897 10898 auto std1 = SysTime(DateTime(2012, 12, 21, 13, 14, 15), UTC()); 10899 auto std2 = SysTime(DateTime(2012, 12, 21, 13, 14, 0), UTC()); 10900 auto std3 = SysTime(DateTime(1912, 12, 21, 13, 14, 15), UTC()); 10901 auto std4 = SysTime(DateTime(1912, 12, 21, 13, 14, 0), UTC()); 10902 auto dst1 = SysTime(DateTime(1976, 7, 4, 5, 4, 22), UTC()); 10903 auto dst2 = SysTime(DateTime(1976, 7, 4, 5, 4, 0), UTC()); 10904 auto tooLate1 = SysTime(Date(10_000, 1, 1), UTC()); 10905 auto tooLate2 = SysTime(DateTime(12_007, 12, 31, 12, 22, 19), UTC()); 10906 10907 static foreach (cr; AliasSeq!(function(string a){return cast(char[]) a;}, 10908 function(string a){return cast(ubyte[]) a;}, 10909 function(string a){return a;}, 10910 function(string a){return map!(b => cast(char) b)(a.representation);})) 10911 {(){ // workaround slow optimizations for large functions 10912 // https://issues.dlang.org/show_bug.cgi?id=2396 10913 scope(failure) writeln(typeof(cr).stringof); 10914 alias test = testParse822!cr; 10915 { 10916 auto list = ["", " ", " \r\n\t", "\t\r\n (hello world( frien(dog)) silly \r\n ) \t\t \r\n ()", 10917 " \n ", "\t\n\t", " \n\t (foo) \n (bar) \r\n (baz) \n "]; 10918 10919 foreach (i, cfws; list) 10920 { 10921 scope(failure) writefln("i: %s", i); 10922 10923 test(format("%1$s21%1$sDec%1$s2012%1$s13:14:15%1$s+0000%1$s", cfws), std1); 10924 test(format("%1$s21%1$sDec%1$s2012%1$s13:14%1$s+0000%1$s", cfws), std2); 10925 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s2012%1$s13:14%1$s+0000%1$s", cfws), std2); 10926 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s2012%1$s13:14:15%1$s+0000%1$s", cfws), std1); 10927 10928 test(format("%1$s04%1$sJul%1$s1976%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10929 test(format("%1$s04%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2); 10930 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2); 10931 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s1976%1$s05:04:22 +0000%1$s", cfws), dst1); 10932 10933 test(format("%1$s4%1$sJul%1$s1976%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10934 test(format("%1$s4%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2); 10935 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2); 10936 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s1976%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10937 10938 test(format("%1$s21%1$sDec%1$s12%1$s13:14:15%1$s+0000%1$s", cfws), std1); 10939 test(format("%1$s21%1$sDec%1$s12%1$s13:14%1$s+0000%1$s", cfws), std2); 10940 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s12%1$s13:14%1$s+0000%1$s", cfws), std2); 10941 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s12%1$s13:14:15%1$s+0000%1$s", cfws), std1); 10942 10943 test(format("%1$s04%1$sJul%1$s76%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10944 test(format("%1$s04%1$sJul%1$s76%1$s05:04%1$s+0000%1$s", cfws), dst2); 10945 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s76%1$s05:04%1$s+0000%1$s", cfws), dst2); 10946 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s76%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10947 10948 test(format("%1$s4%1$sJul%1$s76 05:04:22%1$s+0000%1$s", cfws), dst1); 10949 test(format("%1$s4%1$sJul%1$s76 05:04%1$s+0000%1$s", cfws), dst2); 10950 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s76%1$s05:04%1$s+0000%1$s", cfws), dst2); 10951 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s76%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10952 10953 test(format("%1$s21%1$sDec%1$s012%1$s13:14:15%1$s+0000%1$s", cfws), std3); 10954 test(format("%1$s21%1$sDec%1$s012%1$s13:14%1$s+0000%1$s", cfws), std4); 10955 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s012%1$s13:14%1$s+0000%1$s", cfws), std4); 10956 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s012%1$s13:14:15%1$s+0000%1$s", cfws), std3); 10957 10958 test(format("%1$s04%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10959 test(format("%1$s04%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2); 10960 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2); 10961 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10962 10963 test(format("%1$s4%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10964 test(format("%1$s4%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2); 10965 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2); 10966 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10967 10968 test(format("%1$s1%1$sJan%1$s10000%1$s00:00:00%1$s+0000%1$s", cfws), tooLate1); 10969 test(format("%1$s31%1$sDec%1$s12007%1$s12:22:19%1$s+0000%1$s", cfws), tooLate2); 10970 test(format("%1$sSat%1$s,%1$s1%1$sJan%1$s10000%1$s00:00:00%1$s+0000%1$s", cfws), tooLate1); 10971 test(format("%1$sSun%1$s,%1$s31%1$sDec%1$s12007%1$s12:22:19%1$s+0000%1$s", cfws), tooLate2); 10972 } 10973 } 10974 10975 // test years of 1, 2, and 3 digits. 10976 { 10977 auto st1 = SysTime(Date(2000, 1, 1), UTC()); 10978 auto st2 = SysTime(Date(2000, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-12))); 10979 foreach (i; 0 .. 50) 10980 { 10981 test(format("1 Jan %02d 00:00 GMT", i), st1); 10982 test(format("1 Jan %02d 00:00 -1200", i), st2); 10983 st1.add!"years"(1); 10984 st2.add!"years"(1); 10985 } 10986 } 10987 10988 { 10989 auto st1 = SysTime(Date(1950, 1, 1), UTC()); 10990 auto st2 = SysTime(Date(1950, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-12))); 10991 foreach (i; 50 .. 100) 10992 { 10993 test(format("1 Jan %02d 00:00 GMT", i), st1); 10994 test(format("1 Jan %02d 00:00 -1200", i), st2); 10995 st1.add!"years"(1); 10996 st2.add!"years"(1); 10997 } 10998 } 10999 11000 { 11001 auto st1 = SysTime(Date(1900, 1, 1), UTC()); 11002 auto st2 = SysTime(Date(1900, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-11))); 11003 foreach (i; 0 .. 1000) 11004 { 11005 test(format("1 Jan %03d 00:00 GMT", i), st1); 11006 test(format("1 Jan %03d 00:00 -1100", i), st2); 11007 st1.add!"years"(1); 11008 st2.add!"years"(1); 11009 } 11010 } 11011 11012 foreach (i; 0 .. 10) 11013 { 11014 auto str1 = cr(format("1 Jan %d 00:00 GMT", i)); 11015 auto str2 = cr(format("1 Jan %d 00:00 -1200", i)); 11016 assertThrown!DateTimeException(parseRFC822DateTime(str1)); 11017 assertThrown!DateTimeException(parseRFC822DateTime(str1)); 11018 } 11019 11020 // test time zones 11021 { 11022 auto dt = DateTime(1982, 5, 3, 12, 22, 4); 11023 test("Wed, 03 May 1982 12:22:04 UT", SysTime(dt, UTC())); 11024 test("Wed, 03 May 1982 12:22:04 GMT", SysTime(dt, UTC())); 11025 test("Wed, 03 May 1982 12:22:04 EST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-5)))); 11026 test("Wed, 03 May 1982 12:22:04 EDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-4)))); 11027 test("Wed, 03 May 1982 12:22:04 CST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-6)))); 11028 test("Wed, 03 May 1982 12:22:04 CDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-5)))); 11029 test("Wed, 03 May 1982 12:22:04 MST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-7)))); 11030 test("Wed, 03 May 1982 12:22:04 MDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-6)))); 11031 test("Wed, 03 May 1982 12:22:04 PST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-8)))); 11032 test("Wed, 03 May 1982 12:22:04 PDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-7)))); 11033 11034 auto badTZ = new immutable SimpleTimeZone(Duration.zero); 11035 foreach (dchar c; filter!(a => a != 'j' && a != 'J')(letters)) 11036 { 11037 scope(failure) writefln("c: %s", c); 11038 test(format("Wed, 03 May 1982 12:22:04 %s", c), SysTime(dt, badTZ)); 11039 test(format("Wed, 03 May 1982 12:22:04%s", c), SysTime(dt, badTZ)); 11040 } 11041 11042 foreach (dchar c; ['j', 'J']) 11043 { 11044 scope(failure) writefln("c: %s", c); 11045 assertThrown!DateTimeException(parseRFC822DateTime(cr(format("Wed, 03 May 1982 12:22:04 %s", c)))); 11046 assertThrown!DateTimeException(parseRFC822DateTime(cr(format("Wed, 03 May 1982 12:22:04%s", c)))); 11047 } 11048 11049 foreach (string s; ["AAA", "GQW", "DDT", "PDA", "GT", "GM"]) 11050 { 11051 scope(failure) writefln("s: %s", s); 11052 test(format("Wed, 03 May 1982 12:22:04 %s", s), SysTime(dt, badTZ)); 11053 } 11054 11055 // test trailing stuff that gets ignored 11056 { 11057 foreach (c; chain(iota(0, 33), ['('], iota(127, ubyte.max + 1))) 11058 { 11059 scope(failure) writefln("c: %d", c); 11060 test(format("21Dec1213:14:15+0000%c", cast(char) c), std1); 11061 test(format("21Dec1213:14:15+0000%c ", cast(char) c), std1); 11062 test(format("21Dec1213:14:15+0000%chello", cast(char) c), std1); 11063 } 11064 } 11065 11066 // test trailing stuff that doesn't get ignored 11067 { 11068 foreach (c; chain(iota(33, '('), iota('(' + 1, 127))) 11069 { 11070 scope(failure) writefln("c: %d", c); 11071 assertThrown!DateTimeException( 11072 parseRFC822DateTime(cr(format("21Dec1213:14:15+0000%c", cast(char) c)))); 11073 assertThrown!DateTimeException( 11074 parseRFC822DateTime(cr(format("21Dec1213:14:15+0000%c ", cast(char) c)))); 11075 assertThrown!DateTimeException( 11076 parseRFC822DateTime(cr(format("21Dec1213:14:15+0000%chello", cast(char) c)))); 11077 } 11078 } 11079 } 11080 11081 // test that the checks for minimum length work correctly and avoid 11082 // any RangeErrors. 11083 test("7Dec1200:00A", SysTime(DateTime(2012, 12, 7, 0, 0, 0), 11084 new immutable SimpleTimeZone(Duration.zero))); 11085 test("Fri,7Dec1200:00A", SysTime(DateTime(2012, 12, 7, 0, 0, 0), 11086 new immutable SimpleTimeZone(Duration.zero))); 11087 test("7Dec1200:00:00A", SysTime(DateTime(2012, 12, 7, 0, 0, 0), 11088 new immutable SimpleTimeZone(Duration.zero))); 11089 test("Fri,7Dec1200:00:00A", SysTime(DateTime(2012, 12, 7, 0, 0, 0), 11090 new immutable SimpleTimeZone(Duration.zero))); 11091 11092 auto tooShortMsg = collectExceptionMsg!DateTimeException(parseRFC822DateTime("")); 11093 foreach (str; ["Fri,7Dec1200:00:00", "7Dec1200:00:00"]) 11094 { 11095 foreach (i; 0 .. str.length) 11096 { 11097 auto value = str[0 .. $ - i]; 11098 scope(failure) writeln(value); 11099 assert(collectExceptionMsg!DateTimeException(parseRFC822DateTime(value)) == tooShortMsg); 11100 } 11101 } 11102 }();} 11103 } 11104 11105 11106 private: 11107 11108 /+ 11109 Returns the given hnsecs as an ISO string of fractional seconds. 11110 +/ 11111 string fracSecsToISOString(int hnsecs, int prec = -1) @safe pure nothrow 11112 { 11113 import std.array : appender; 11114 auto w = appender!string(); 11115 try 11116 fracSecsToISOString(w, hnsecs, prec); 11117 catch (Exception e) 11118 assert(0, "fracSecsToISOString() threw."); 11119 return w.data; 11120 } 11121 11122 void fracSecsToISOString(W)(ref W writer, int hnsecs, int prec = -1) 11123 { 11124 import std.conv : toChars; 11125 import std.range : padLeft; 11126 11127 assert(hnsecs >= 0); 11128 11129 if (prec == 0) 11130 return; 11131 11132 if (hnsecs == 0) 11133 return; 11134 11135 put(writer, '.'); 11136 auto chars = hnsecs.toChars.padLeft('0', 7); 11137 11138 if (prec == -1) 11139 { 11140 while (chars.back == '0') 11141 chars.popBack(); 11142 put(writer, chars); 11143 } 11144 else 11145 put(writer, chars[0 .. prec]); 11146 } 11147 11148 @safe unittest 11149 { 11150 assert(fracSecsToISOString(0) == ""); 11151 assert(fracSecsToISOString(1) == ".0000001"); 11152 assert(fracSecsToISOString(10) == ".000001"); 11153 assert(fracSecsToISOString(100) == ".00001"); 11154 assert(fracSecsToISOString(1000) == ".0001"); 11155 assert(fracSecsToISOString(10_000) == ".001"); 11156 assert(fracSecsToISOString(100_000) == ".01"); 11157 assert(fracSecsToISOString(1_000_000) == ".1"); 11158 assert(fracSecsToISOString(1_000_001) == ".1000001"); 11159 assert(fracSecsToISOString(1_001_001) == ".1001001"); 11160 assert(fracSecsToISOString(1_071_601) == ".1071601"); 11161 assert(fracSecsToISOString(1_271_641) == ".1271641"); 11162 assert(fracSecsToISOString(9_999_999) == ".9999999"); 11163 assert(fracSecsToISOString(9_999_990) == ".999999"); 11164 assert(fracSecsToISOString(9_999_900) == ".99999"); 11165 assert(fracSecsToISOString(9_999_000) == ".9999"); 11166 assert(fracSecsToISOString(9_990_000) == ".999"); 11167 assert(fracSecsToISOString(9_900_000) == ".99"); 11168 assert(fracSecsToISOString(9_000_000) == ".9"); 11169 assert(fracSecsToISOString(999) == ".0000999"); 11170 assert(fracSecsToISOString(9990) == ".000999"); 11171 assert(fracSecsToISOString(99_900) == ".00999"); 11172 assert(fracSecsToISOString(999_000) == ".0999"); 11173 } 11174 11175 11176 /+ 11177 Returns a Duration corresponding to to the given ISO string of 11178 fractional seconds. 11179 +/ 11180 static Duration fracSecsFromISOString(S)(scope const S isoString) @safe pure 11181 if (isSomeString!S) 11182 { 11183 import std.algorithm.searching : all; 11184 import std.ascii : isDigit; 11185 import std.conv : to; 11186 import std.format : format; 11187 import std.string : representation; 11188 11189 if (isoString.empty) 11190 return Duration.zero; 11191 11192 auto str = isoString.representation; 11193 11194 enforce!DateTimeException(str[0] == '.', format("Invalid format for fracSecsFromISOString: %s", isoString)); 11195 str.popFront(); 11196 11197 enforce!DateTimeException(!str.empty && all!isDigit(str), 11198 format("Invalid format for fracSecsFromISOString: %s", isoString)); 11199 11200 dchar[7] fullISOString = void; 11201 foreach (i, ref dchar c; fullISOString) 11202 { 11203 if (i < str.length) 11204 c = str[i]; 11205 else 11206 c = '0'; 11207 } 11208 11209 return hnsecs(to!int(fullISOString[])); 11210 } 11211 11212 @safe unittest 11213 { 11214 import core.time; 11215 static void testFSInvalid(string isoString) 11216 { 11217 fracSecsFromISOString(isoString); 11218 } 11219 11220 assertThrown!DateTimeException(testFSInvalid(".")); 11221 assertThrown!DateTimeException(testFSInvalid("0.")); 11222 assertThrown!DateTimeException(testFSInvalid("0")); 11223 assertThrown!DateTimeException(testFSInvalid("0000000")); 11224 assertThrown!DateTimeException(testFSInvalid("T")); 11225 assertThrown!DateTimeException(testFSInvalid("T.")); 11226 assertThrown!DateTimeException(testFSInvalid(".T")); 11227 assertThrown!DateTimeException(testFSInvalid(".00000Q0")); 11228 assertThrown!DateTimeException(testFSInvalid(".000000Q")); 11229 assertThrown!DateTimeException(testFSInvalid(".0000000Q")); 11230 assertThrown!DateTimeException(testFSInvalid(".0000000000Q")); 11231 11232 assert(fracSecsFromISOString("") == Duration.zero); 11233 assert(fracSecsFromISOString(".0000001") == hnsecs(1)); 11234 assert(fracSecsFromISOString(".000001") == hnsecs(10)); 11235 assert(fracSecsFromISOString(".00001") == hnsecs(100)); 11236 assert(fracSecsFromISOString(".0001") == hnsecs(1000)); 11237 assert(fracSecsFromISOString(".001") == hnsecs(10_000)); 11238 assert(fracSecsFromISOString(".01") == hnsecs(100_000)); 11239 assert(fracSecsFromISOString(".1") == hnsecs(1_000_000)); 11240 assert(fracSecsFromISOString(".1000001") == hnsecs(1_000_001)); 11241 assert(fracSecsFromISOString(".1001001") == hnsecs(1_001_001)); 11242 assert(fracSecsFromISOString(".1071601") == hnsecs(1_071_601)); 11243 assert(fracSecsFromISOString(".1271641") == hnsecs(1_271_641)); 11244 assert(fracSecsFromISOString(".9999999") == hnsecs(9_999_999)); 11245 assert(fracSecsFromISOString(".9999990") == hnsecs(9_999_990)); 11246 assert(fracSecsFromISOString(".999999") == hnsecs(9_999_990)); 11247 assert(fracSecsFromISOString(".9999900") == hnsecs(9_999_900)); 11248 assert(fracSecsFromISOString(".99999") == hnsecs(9_999_900)); 11249 assert(fracSecsFromISOString(".9999000") == hnsecs(9_999_000)); 11250 assert(fracSecsFromISOString(".9999") == hnsecs(9_999_000)); 11251 assert(fracSecsFromISOString(".9990000") == hnsecs(9_990_000)); 11252 assert(fracSecsFromISOString(".999") == hnsecs(9_990_000)); 11253 assert(fracSecsFromISOString(".9900000") == hnsecs(9_900_000)); 11254 assert(fracSecsFromISOString(".9900") == hnsecs(9_900_000)); 11255 assert(fracSecsFromISOString(".99") == hnsecs(9_900_000)); 11256 assert(fracSecsFromISOString(".9000000") == hnsecs(9_000_000)); 11257 assert(fracSecsFromISOString(".9") == hnsecs(9_000_000)); 11258 assert(fracSecsFromISOString(".0000999") == hnsecs(999)); 11259 assert(fracSecsFromISOString(".0009990") == hnsecs(9990)); 11260 assert(fracSecsFromISOString(".000999") == hnsecs(9990)); 11261 assert(fracSecsFromISOString(".0099900") == hnsecs(99_900)); 11262 assert(fracSecsFromISOString(".00999") == hnsecs(99_900)); 11263 assert(fracSecsFromISOString(".0999000") == hnsecs(999_000)); 11264 assert(fracSecsFromISOString(".0999") == hnsecs(999_000)); 11265 assert(fracSecsFromISOString(".00000000") == Duration.zero); 11266 assert(fracSecsFromISOString(".00000001") == Duration.zero); 11267 assert(fracSecsFromISOString(".00000009") == Duration.zero); 11268 assert(fracSecsFromISOString(".1234567890") == hnsecs(1_234_567)); 11269 assert(fracSecsFromISOString(".12345678901234567890") == hnsecs(1_234_567)); 11270 } 11271 11272 11273 /+ 11274 This function is used to split out the units without getting the remaining 11275 hnsecs. 11276 11277 Params: 11278 units = The units to split out. 11279 hnsecs = The current total hnsecs. 11280 11281 Returns: 11282 The split out value. 11283 +/ 11284 long getUnitsFromHNSecs(string units)(long hnsecs) @safe pure nothrow 11285 if (validTimeUnits(units) && 11286 CmpTimeUnits!(units, "months") < 0) 11287 { 11288 return convert!("hnsecs", units)(hnsecs); 11289 } 11290 11291 @safe unittest 11292 { 11293 auto hnsecs = 2595000000007L; 11294 immutable days = getUnitsFromHNSecs!"days"(hnsecs); 11295 assert(days == 3); 11296 assert(hnsecs == 2595000000007L); 11297 } 11298 11299 11300 /+ 11301 This function is used to split out the units without getting the units but 11302 just the remaining hnsecs. 11303 11304 Params: 11305 units = The units to split out. 11306 hnsecs = The current total hnsecs. 11307 11308 Returns: 11309 The remaining hnsecs. 11310 +/ 11311 long removeUnitsFromHNSecs(string units)(long hnsecs) @safe pure nothrow 11312 if (validTimeUnits(units) && 11313 CmpTimeUnits!(units, "months") < 0) 11314 { 11315 immutable value = convert!("hnsecs", units)(hnsecs); 11316 return hnsecs - convert!(units, "hnsecs")(value); 11317 } 11318 11319 @safe unittest 11320 { 11321 auto hnsecs = 2595000000007L; 11322 auto returned = removeUnitsFromHNSecs!"days"(hnsecs); 11323 assert(returned == 3000000007); 11324 assert(hnsecs == 2595000000007L); 11325 } 11326 11327 11328 /+ 11329 Strips what RFC 5322, section 3.2.2 refers to as CFWS from the left-hand 11330 side of the given range (it strips comments delimited by $(D '(') and 11331 `'`') as well as folding whitespace). 11332 11333 It is assumed that the given range contains the value of a header field and 11334 no terminating CRLF for the line (though the CRLF for folding whitespace is 11335 of course expected and stripped) and thus that the only case of CR or LF is 11336 in folding whitespace. 11337 11338 If a comment does not terminate correctly (e.g. mismatched parens) or if the 11339 the FWS is malformed, then the range will be empty when stripCWFS is done. 11340 However, only minimal validation of the content is done (e.g. quoted pairs 11341 within a comment aren't validated beyond \$LPAREN or \$RPAREN, because 11342 they're inside a comment, and thus their value doesn't matter anyway). It's 11343 only when the content does not conform to the grammar rules for FWS and thus 11344 literally cannot be parsed that content is considered invalid, and an empty 11345 range is returned. 11346 11347 Note that _stripCFWS is eager, not lazy. It does not create a new range. 11348 Rather, it pops off the CFWS from the range and returns it. 11349 +/ 11350 R _stripCFWS(R)(R range) 11351 if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && 11352 (is(immutable ElementType!R == immutable char) || is(immutable ElementType!R == immutable ubyte))) 11353 { 11354 immutable e = range.length; 11355 outer: for (size_t i = 0; i < e; ) 11356 { 11357 switch (range[i]) 11358 { 11359 case ' ': case '\t': 11360 { 11361 ++i; 11362 break; 11363 } 11364 case '\r': 11365 { 11366 if (i + 2 < e && range[i + 1] == '\n' && (range[i + 2] == ' ' || range[i + 2] == '\t')) 11367 { 11368 i += 3; 11369 break; 11370 } 11371 break outer; 11372 } 11373 case '\n': 11374 { 11375 if (i + 1 < e && (range[i + 1] == ' ' || range[i + 1] == '\t')) 11376 { 11377 i += 2; 11378 break; 11379 } 11380 break outer; 11381 } 11382 case '(': 11383 { 11384 ++i; 11385 size_t commentLevel = 1; 11386 while (i < e) 11387 { 11388 if (range[i] == '(') 11389 ++commentLevel; 11390 else if (range[i] == ')') 11391 { 11392 ++i; 11393 if (--commentLevel == 0) 11394 continue outer; 11395 continue; 11396 } 11397 else if (range[i] == '\\') 11398 { 11399 if (++i == e) 11400 break outer; 11401 } 11402 ++i; 11403 } 11404 break outer; 11405 } 11406 default: return range[i .. e]; 11407 } 11408 } 11409 return range[e .. e]; 11410 } 11411 11412 @system unittest 11413 { 11414 import std.algorithm.comparison : equal; 11415 import std.algorithm.iteration : map; 11416 import std.meta : AliasSeq; 11417 import std.stdio : writeln; 11418 import std.string : representation; 11419 11420 static foreach (cr; AliasSeq!(function(string a){return cast(ubyte[]) a;}, 11421 function(string a){return map!(b => cast(char) b)(a.representation);})) 11422 { 11423 scope(failure) writeln(typeof(cr).stringof); 11424 11425 assert(_stripCFWS(cr("")).empty); 11426 assert(_stripCFWS(cr("\r")).empty); 11427 assert(_stripCFWS(cr("\r\n")).empty); 11428 assert(_stripCFWS(cr("\r\n ")).empty); 11429 assert(_stripCFWS(cr(" \t\r\n")).empty); 11430 assert(equal(_stripCFWS(cr(" \t\r\n hello")), cr("hello"))); 11431 assert(_stripCFWS(cr(" \t\r\nhello")).empty); 11432 assert(_stripCFWS(cr(" \t\r\n\v")).empty); 11433 assert(equal(_stripCFWS(cr("\v \t\r\n\v")), cr("\v \t\r\n\v"))); 11434 assert(_stripCFWS(cr("()")).empty); 11435 assert(_stripCFWS(cr("(hello world)")).empty); 11436 assert(_stripCFWS(cr("(hello world)(hello world)")).empty); 11437 assert(_stripCFWS(cr("(hello world\r\n foo\r where's\nwaldo)")).empty); 11438 assert(_stripCFWS(cr(" \t (hello \tworld\r\n foo\r where's\nwaldo)\t\t ")).empty); 11439 assert(_stripCFWS(cr(" ")).empty); 11440 assert(_stripCFWS(cr("\t\t\t")).empty); 11441 assert(_stripCFWS(cr("\t \r\n\r \n")).empty); 11442 assert(_stripCFWS(cr("(hello world) (can't find waldo) (he's lost)")).empty); 11443 assert(_stripCFWS(cr("(hello\\) world) (can't \\(find waldo) (he's \\(\\)lost)")).empty); 11444 assert(_stripCFWS(cr("(((((")).empty); 11445 assert(_stripCFWS(cr("(((()))")).empty); 11446 assert(_stripCFWS(cr("(((())))")).empty); 11447 assert(equal(_stripCFWS(cr("(((()))))")), cr(")"))); 11448 assert(equal(_stripCFWS(cr(")))))")), cr(")))))"))); 11449 assert(equal(_stripCFWS(cr("()))))")), cr("))))"))); 11450 assert(equal(_stripCFWS(cr(" hello hello ")), cr("hello hello "))); 11451 assert(equal(_stripCFWS(cr("\thello (world)")), cr("hello (world)"))); 11452 assert(equal(_stripCFWS(cr(" \r\n \\((\\)) foo")), cr("\\((\\)) foo"))); 11453 assert(equal(_stripCFWS(cr(" \r\n (\\((\\))) foo")), cr("foo"))); 11454 assert(equal(_stripCFWS(cr(" \r\n (\\(())) foo")), cr(") foo"))); 11455 assert(_stripCFWS(cr(" \r\n (((\\))) foo")).empty); 11456 11457 assert(_stripCFWS(cr("(hello)(hello)")).empty); 11458 assert(_stripCFWS(cr(" \r\n (hello)\r\n (hello)")).empty); 11459 assert(_stripCFWS(cr(" \r\n (hello) \r\n (hello) \r\n ")).empty); 11460 assert(_stripCFWS(cr("\t\t\t\t(hello)\t\t\t\t(hello)\t\t\t\t")).empty); 11461 assert(equal(_stripCFWS(cr(" \r\n (hello)\r\n (hello) \r\n hello")), cr("hello"))); 11462 assert(equal(_stripCFWS(cr(" \r\n (hello) \r\n (hello) \r\n hello")), cr("hello"))); 11463 assert(equal(_stripCFWS(cr("\t\r\n\t(hello)\r\n\t(hello)\t\r\n hello")), cr("hello"))); 11464 assert(equal(_stripCFWS(cr("\t\r\n\t(hello)\t\r\n\t(hello)\t\r\n hello")), cr("hello"))); 11465 assert(equal(_stripCFWS(cr(" \r\n (hello) \r\n \r\n (hello) \r\n hello")), cr("hello"))); 11466 assert(equal(_stripCFWS(cr(" \r\n (hello) \r\n (hello) \r\n \r\n hello")), cr("hello"))); 11467 assert(equal(_stripCFWS(cr(" \r\n \r\n (hello)\t\r\n (hello) \r\n hello")), cr("hello"))); 11468 assert(equal(_stripCFWS(cr(" \r\n\t\r\n\t(hello)\t\r\n (hello) \r\n hello")), cr("hello"))); 11469 11470 assert(equal(_stripCFWS(cr(" (\r\n ( \r\n ) \r\n ) foo")), cr("foo"))); 11471 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n ) foo")), cr("foo"))); 11472 assert(equal(_stripCFWS(cr(" (\t\r\n ( \r\n ) \r\n ) foo")), cr("foo"))); 11473 assert(equal(_stripCFWS(cr(" (\r\n\t( \r\n ) \r\n ) foo")), cr("foo"))); 11474 assert(equal(_stripCFWS(cr(" ( \r\n (\t\r\n ) \r\n ) foo")), cr("foo"))); 11475 assert(equal(_stripCFWS(cr(" ( \r\n (\r\n ) \r\n ) foo")), cr("foo"))); 11476 assert(equal(_stripCFWS(cr(" ( \r\n (\r\n\t) \r\n ) foo")), cr("foo"))); 11477 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n) \r\n ) foo")), cr("foo"))); 11478 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n )\t\r\n ) foo")), cr("foo"))); 11479 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n )\r\n ) foo")), cr("foo"))); 11480 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n) foo")), cr("foo"))); 11481 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n\t) foo")), cr("foo"))); 11482 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n ) \r\n foo")), cr("foo"))); 11483 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n )\t\r\n foo")), cr("foo"))); 11484 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n )\r\n foo")), cr("foo"))); 11485 11486 assert(equal(_stripCFWS(cr(" ( \r\n \r\n ( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 11487 assert(equal(_stripCFWS(cr(" ( \r\n \r\n ( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 11488 assert(equal(_stripCFWS(cr(" (\t\r\n \r\n ( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 11489 assert(equal(_stripCFWS(cr(" (\r\n \r\n\t( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 11490 assert(equal(_stripCFWS(cr(" (\r\n \r\n( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 11491 assert(equal(_stripCFWS(cr(" (\r\n \r\n ( \r\n \r\n\t) \r\n ) foo")), cr("foo"))); 11492 assert(equal(_stripCFWS(cr(" (\r\n \r\n ( \r\n \r\n )\t\r\n ) foo")), cr("foo"))); 11493 assert(equal(_stripCFWS(cr(" (\r\n \r\n ( \r\n \r\n )\r\n ) foo")), cr("foo"))); 11494 11495 assert(equal(_stripCFWS(cr(" ( \r\n bar \r\n ( \r\n bar \r\n ) \r\n ) foo")), cr("foo"))); 11496 assert(equal(_stripCFWS(cr(" ( \r\n () \r\n ( \r\n () \r\n ) \r\n ) foo")), cr("foo"))); 11497 assert(equal(_stripCFWS(cr(" ( \r\n \\\\ \r\n ( \r\n \\\\ \r\n ) \r\n ) foo")), cr("foo"))); 11498 11499 assert(_stripCFWS(cr("(hello)(hello)")).empty); 11500 assert(_stripCFWS(cr(" \n (hello)\n (hello) \n ")).empty); 11501 assert(_stripCFWS(cr(" \n (hello) \n (hello) \n ")).empty); 11502 assert(equal(_stripCFWS(cr(" \n (hello)\n (hello) \n hello")), cr("hello"))); 11503 assert(equal(_stripCFWS(cr(" \n (hello) \n (hello) \n hello")), cr("hello"))); 11504 assert(equal(_stripCFWS(cr("\t\n\t(hello)\n\t(hello)\t\n hello")), cr("hello"))); 11505 assert(equal(_stripCFWS(cr("\t\n\t(hello)\t\n\t(hello)\t\n hello")), cr("hello"))); 11506 assert(equal(_stripCFWS(cr(" \n (hello) \n \n (hello) \n hello")), cr("hello"))); 11507 assert(equal(_stripCFWS(cr(" \n (hello) \n (hello) \n \n hello")), cr("hello"))); 11508 assert(equal(_stripCFWS(cr(" \n \n (hello)\t\n (hello) \n hello")), cr("hello"))); 11509 assert(equal(_stripCFWS(cr(" \n\t\n\t(hello)\t\n (hello) \n hello")), cr("hello"))); 11510 } 11511 } 11512 11513 // This is so that we don't have to worry about std.conv.to throwing. It also 11514 // doesn't have to worry about quite as many cases as std.conv.to, since it 11515 // doesn't have to worry about a sign on the value or about whether it fits. 11516 T _convDigits(T, R)(R str) 11517 if (isIntegral!T && isSigned!T) // The constraints on R were already covered by parseRFC822DateTime. 11518 { 11519 import std.ascii : isDigit; 11520 11521 assert(!str.empty); 11522 T num = 0; 11523 foreach (i; 0 .. str.length) 11524 { 11525 if (i != 0) 11526 num *= 10; 11527 if (!isDigit(str[i])) 11528 return -1; 11529 num += str[i] - '0'; 11530 } 11531 return num; 11532 } 11533 11534 @safe unittest 11535 { 11536 import std.conv : to; 11537 import std.range : chain, iota; 11538 foreach (i; chain(iota(0, 101), [250, 999, 1000, 1001, 2345, 9999])) 11539 { 11540 assert(_convDigits!int(to!string(i)) == i, i.to!string); 11541 } 11542 foreach (str; ["-42", "+42", "1a", "1 ", " ", " 42 "]) 11543 { 11544 assert(_convDigits!int(str) == -1, str); 11545 } 11546 } 11547 11548 11549 // NOTE: all the non-simple array literals are wrapped in functions, because 11550 // otherwise importing causes re-evaluation of the static initializers using 11551 // CTFE with unittests enabled 11552 version (StdUnittest) 11553 { 11554 private @safe: 11555 // Variables to help in testing. 11556 Duration currLocalDiffFromUTC; 11557 immutable (TimeZone)[] testTZs; 11558 11559 // All of these helper arrays are sorted in ascending order. 11560 auto testYearsBC = [-1999, -1200, -600, -4, -1, 0]; 11561 auto testYearsAD = [1, 4, 1000, 1999, 2000, 2012]; 11562 11563 // I'd use a Tuple, but I get forward reference errors if I try. 11564 struct MonthDay 11565 { 11566 Month month; 11567 short day; 11568 11569 this(int m, short d) 11570 { 11571 month = cast(Month) m; 11572 day = d; 11573 } 11574 } 11575 11576 MonthDay[] testMonthDays() 11577 { 11578 static result = [MonthDay(1, 1), 11579 MonthDay(1, 2), 11580 MonthDay(3, 17), 11581 MonthDay(7, 4), 11582 MonthDay(10, 27), 11583 MonthDay(12, 30), 11584 MonthDay(12, 31)]; 11585 return result; 11586 } 11587 11588 auto testDays = [1, 2, 9, 10, 16, 20, 25, 28, 29, 30, 31]; 11589 11590 TimeOfDay[] testTODs() 11591 { 11592 static result = [TimeOfDay(0, 0, 0), 11593 TimeOfDay(0, 0, 1), 11594 TimeOfDay(0, 1, 0), 11595 TimeOfDay(1, 0, 0), 11596 TimeOfDay(13, 13, 13), 11597 TimeOfDay(23, 59, 59)]; 11598 return result; 11599 } 11600 11601 auto testHours = [0, 1, 12, 22, 23]; 11602 auto testMinSecs = [0, 1, 30, 58, 59]; 11603 11604 // Throwing exceptions is incredibly expensive, so we want to use a smaller 11605 // set of values for tests using assertThrown. 11606 TimeOfDay[] testTODsThrown() 11607 { 11608 static result = [TimeOfDay(0, 0, 0), 11609 TimeOfDay(13, 13, 13), 11610 TimeOfDay(23, 59, 59)]; 11611 return result; 11612 } 11613 11614 Date[] testDatesBC; 11615 Date[] testDatesAD; 11616 11617 DateTime[] testDateTimesBC; 11618 DateTime[] testDateTimesAD; 11619 11620 Duration[] testFracSecs; 11621 11622 SysTime[] testSysTimesBC; 11623 SysTime[] testSysTimesAD; 11624 11625 // I'd use a Tuple, but I get forward reference errors if I try. 11626 struct GregDay { int day; Date date; } 11627 GregDay[] testGregDaysBC() 11628 { 11629 static result = [GregDay(-1_373_427, Date(-3760, 9, 7)), // Start of the Hebrew Calendar 11630 GregDay(-735_233, Date(-2012, 1, 1)), 11631 GregDay(-735_202, Date(-2012, 2, 1)), 11632 GregDay(-735_175, Date(-2012, 2, 28)), 11633 GregDay(-735_174, Date(-2012, 2, 29)), 11634 GregDay(-735_173, Date(-2012, 3, 1)), 11635 GregDay(-734_502, Date(-2010, 1, 1)), 11636 GregDay(-734_472, Date(-2010, 1, 31)), 11637 GregDay(-734_471, Date(-2010, 2, 1)), 11638 GregDay(-734_444, Date(-2010, 2, 28)), 11639 GregDay(-734_443, Date(-2010, 3, 1)), 11640 GregDay(-734_413, Date(-2010, 3, 31)), 11641 GregDay(-734_412, Date(-2010, 4, 1)), 11642 GregDay(-734_383, Date(-2010, 4, 30)), 11643 GregDay(-734_382, Date(-2010, 5, 1)), 11644 GregDay(-734_352, Date(-2010, 5, 31)), 11645 GregDay(-734_351, Date(-2010, 6, 1)), 11646 GregDay(-734_322, Date(-2010, 6, 30)), 11647 GregDay(-734_321, Date(-2010, 7, 1)), 11648 GregDay(-734_291, Date(-2010, 7, 31)), 11649 GregDay(-734_290, Date(-2010, 8, 1)), 11650 GregDay(-734_260, Date(-2010, 8, 31)), 11651 GregDay(-734_259, Date(-2010, 9, 1)), 11652 GregDay(-734_230, Date(-2010, 9, 30)), 11653 GregDay(-734_229, Date(-2010, 10, 1)), 11654 GregDay(-734_199, Date(-2010, 10, 31)), 11655 GregDay(-734_198, Date(-2010, 11, 1)), 11656 GregDay(-734_169, Date(-2010, 11, 30)), 11657 GregDay(-734_168, Date(-2010, 12, 1)), 11658 GregDay(-734_139, Date(-2010, 12, 30)), 11659 GregDay(-734_138, Date(-2010, 12, 31)), 11660 GregDay(-731_215, Date(-2001, 1, 1)), 11661 GregDay(-730_850, Date(-2000, 1, 1)), 11662 GregDay(-730_849, Date(-2000, 1, 2)), 11663 GregDay(-730_486, Date(-2000, 12, 30)), 11664 GregDay(-730_485, Date(-2000, 12, 31)), 11665 GregDay(-730_484, Date(-1999, 1, 1)), 11666 GregDay(-694_690, Date(-1901, 1, 1)), 11667 GregDay(-694_325, Date(-1900, 1, 1)), 11668 GregDay(-585_118, Date(-1601, 1, 1)), 11669 GregDay(-584_753, Date(-1600, 1, 1)), 11670 GregDay(-584_388, Date(-1600, 12, 31)), 11671 GregDay(-584_387, Date(-1599, 1, 1)), 11672 GregDay(-365_972, Date(-1001, 1, 1)), 11673 GregDay(-365_607, Date(-1000, 1, 1)), 11674 GregDay(-183_351, Date(-501, 1, 1)), 11675 GregDay(-182_986, Date(-500, 1, 1)), 11676 GregDay(-182_621, Date(-499, 1, 1)), 11677 GregDay(-146_827, Date(-401, 1, 1)), 11678 GregDay(-146_462, Date(-400, 1, 1)), 11679 GregDay(-146_097, Date(-400, 12, 31)), 11680 GregDay(-110_302, Date(-301, 1, 1)), 11681 GregDay(-109_937, Date(-300, 1, 1)), 11682 GregDay(-73_778, Date(-201, 1, 1)), 11683 GregDay(-73_413, Date(-200, 1, 1)), 11684 GregDay(-38_715, Date(-105, 1, 1)), 11685 GregDay(-37_254, Date(-101, 1, 1)), 11686 GregDay(-36_889, Date(-100, 1, 1)), 11687 GregDay(-36_524, Date(-99, 1, 1)), 11688 GregDay(-36_160, Date(-99, 12, 31)), 11689 GregDay(-35_794, Date(-97, 1, 1)), 11690 GregDay(-18_627, Date(-50, 1, 1)), 11691 GregDay(-18_262, Date(-49, 1, 1)), 11692 GregDay(-3652, Date(-9, 1, 1)), 11693 GregDay(-2191, Date(-5, 1, 1)), 11694 GregDay(-1827, Date(-5, 12, 31)), 11695 GregDay(-1826, Date(-4, 1, 1)), 11696 GregDay(-1825, Date(-4, 1, 2)), 11697 GregDay(-1462, Date(-4, 12, 30)), 11698 GregDay(-1461, Date(-4, 12, 31)), 11699 GregDay(-1460, Date(-3, 1, 1)), 11700 GregDay(-1096, Date(-3, 12, 31)), 11701 GregDay(-1095, Date(-2, 1, 1)), 11702 GregDay(-731, Date(-2, 12, 31)), 11703 GregDay(-730, Date(-1, 1, 1)), 11704 GregDay(-367, Date(-1, 12, 30)), 11705 GregDay(-366, Date(-1, 12, 31)), 11706 GregDay(-365, Date(0, 1, 1)), 11707 GregDay(-31, Date(0, 11, 30)), 11708 GregDay(-30, Date(0, 12, 1)), 11709 GregDay(-1, Date(0, 12, 30)), 11710 GregDay(0, Date(0, 12, 31))]; 11711 return result; 11712 } 11713 11714 GregDay[] testGregDaysAD() 11715 { 11716 static result = [GregDay(1, Date(1, 1, 1)), 11717 GregDay(2, Date(1, 1, 2)), 11718 GregDay(32, Date(1, 2, 1)), 11719 GregDay(365, Date(1, 12, 31)), 11720 GregDay(366, Date(2, 1, 1)), 11721 GregDay(731, Date(3, 1, 1)), 11722 GregDay(1096, Date(4, 1, 1)), 11723 GregDay(1097, Date(4, 1, 2)), 11724 GregDay(1460, Date(4, 12, 30)), 11725 GregDay(1461, Date(4, 12, 31)), 11726 GregDay(1462, Date(5, 1, 1)), 11727 GregDay(17_898, Date(50, 1, 1)), 11728 GregDay(35_065, Date(97, 1, 1)), 11729 GregDay(36_160, Date(100, 1, 1)), 11730 GregDay(36_525, Date(101, 1, 1)), 11731 GregDay(37_986, Date(105, 1, 1)), 11732 GregDay(72_684, Date(200, 1, 1)), 11733 GregDay(73_049, Date(201, 1, 1)), 11734 GregDay(109_208, Date(300, 1, 1)), 11735 GregDay(109_573, Date(301, 1, 1)), 11736 GregDay(145_732, Date(400, 1, 1)), 11737 GregDay(146_098, Date(401, 1, 1)), 11738 GregDay(182_257, Date(500, 1, 1)), 11739 GregDay(182_622, Date(501, 1, 1)), 11740 GregDay(364_878, Date(1000, 1, 1)), 11741 GregDay(365_243, Date(1001, 1, 1)), 11742 GregDay(584_023, Date(1600, 1, 1)), 11743 GregDay(584_389, Date(1601, 1, 1)), 11744 GregDay(693_596, Date(1900, 1, 1)), 11745 GregDay(693_961, Date(1901, 1, 1)), 11746 GregDay(729_755, Date(1999, 1, 1)), 11747 GregDay(730_120, Date(2000, 1, 1)), 11748 GregDay(730_121, Date(2000, 1, 2)), 11749 GregDay(730_484, Date(2000, 12, 30)), 11750 GregDay(730_485, Date(2000, 12, 31)), 11751 GregDay(730_486, Date(2001, 1, 1)), 11752 GregDay(733_773, Date(2010, 1, 1)), 11753 GregDay(733_774, Date(2010, 1, 2)), 11754 GregDay(733_803, Date(2010, 1, 31)), 11755 GregDay(733_804, Date(2010, 2, 1)), 11756 GregDay(733_831, Date(2010, 2, 28)), 11757 GregDay(733_832, Date(2010, 3, 1)), 11758 GregDay(733_862, Date(2010, 3, 31)), 11759 GregDay(733_863, Date(2010, 4, 1)), 11760 GregDay(733_892, Date(2010, 4, 30)), 11761 GregDay(733_893, Date(2010, 5, 1)), 11762 GregDay(733_923, Date(2010, 5, 31)), 11763 GregDay(733_924, Date(2010, 6, 1)), 11764 GregDay(733_953, Date(2010, 6, 30)), 11765 GregDay(733_954, Date(2010, 7, 1)), 11766 GregDay(733_984, Date(2010, 7, 31)), 11767 GregDay(733_985, Date(2010, 8, 1)), 11768 GregDay(734_015, Date(2010, 8, 31)), 11769 GregDay(734_016, Date(2010, 9, 1)), 11770 GregDay(734_045, Date(2010, 9, 30)), 11771 GregDay(734_046, Date(2010, 10, 1)), 11772 GregDay(734_076, Date(2010, 10, 31)), 11773 GregDay(734_077, Date(2010, 11, 1)), 11774 GregDay(734_106, Date(2010, 11, 30)), 11775 GregDay(734_107, Date(2010, 12, 1)), 11776 GregDay(734_136, Date(2010, 12, 30)), 11777 GregDay(734_137, Date(2010, 12, 31)), 11778 GregDay(734_503, Date(2012, 1, 1)), 11779 GregDay(734_534, Date(2012, 2, 1)), 11780 GregDay(734_561, Date(2012, 2, 28)), 11781 GregDay(734_562, Date(2012, 2, 29)), 11782 GregDay(734_563, Date(2012, 3, 1)), 11783 GregDay(734_858, Date(2012, 12, 21))]; 11784 return result; 11785 } 11786 11787 // I'd use a Tuple, but I get forward reference errors if I try. 11788 struct DayOfYear { int day; MonthDay md; } 11789 DayOfYear[] testDaysOfYear() 11790 { 11791 static result = [DayOfYear(1, MonthDay(1, 1)), 11792 DayOfYear(2, MonthDay(1, 2)), 11793 DayOfYear(3, MonthDay(1, 3)), 11794 DayOfYear(31, MonthDay(1, 31)), 11795 DayOfYear(32, MonthDay(2, 1)), 11796 DayOfYear(59, MonthDay(2, 28)), 11797 DayOfYear(60, MonthDay(3, 1)), 11798 DayOfYear(90, MonthDay(3, 31)), 11799 DayOfYear(91, MonthDay(4, 1)), 11800 DayOfYear(120, MonthDay(4, 30)), 11801 DayOfYear(121, MonthDay(5, 1)), 11802 DayOfYear(151, MonthDay(5, 31)), 11803 DayOfYear(152, MonthDay(6, 1)), 11804 DayOfYear(181, MonthDay(6, 30)), 11805 DayOfYear(182, MonthDay(7, 1)), 11806 DayOfYear(212, MonthDay(7, 31)), 11807 DayOfYear(213, MonthDay(8, 1)), 11808 DayOfYear(243, MonthDay(8, 31)), 11809 DayOfYear(244, MonthDay(9, 1)), 11810 DayOfYear(273, MonthDay(9, 30)), 11811 DayOfYear(274, MonthDay(10, 1)), 11812 DayOfYear(304, MonthDay(10, 31)), 11813 DayOfYear(305, MonthDay(11, 1)), 11814 DayOfYear(334, MonthDay(11, 30)), 11815 DayOfYear(335, MonthDay(12, 1)), 11816 DayOfYear(363, MonthDay(12, 29)), 11817 DayOfYear(364, MonthDay(12, 30)), 11818 DayOfYear(365, MonthDay(12, 31))]; 11819 return result; 11820 } 11821 11822 DayOfYear[] testDaysOfLeapYear() 11823 { 11824 static result = [DayOfYear(1, MonthDay(1, 1)), 11825 DayOfYear(2, MonthDay(1, 2)), 11826 DayOfYear(3, MonthDay(1, 3)), 11827 DayOfYear(31, MonthDay(1, 31)), 11828 DayOfYear(32, MonthDay(2, 1)), 11829 DayOfYear(59, MonthDay(2, 28)), 11830 DayOfYear(60, MonthDay(2, 29)), 11831 DayOfYear(61, MonthDay(3, 1)), 11832 DayOfYear(91, MonthDay(3, 31)), 11833 DayOfYear(92, MonthDay(4, 1)), 11834 DayOfYear(121, MonthDay(4, 30)), 11835 DayOfYear(122, MonthDay(5, 1)), 11836 DayOfYear(152, MonthDay(5, 31)), 11837 DayOfYear(153, MonthDay(6, 1)), 11838 DayOfYear(182, MonthDay(6, 30)), 11839 DayOfYear(183, MonthDay(7, 1)), 11840 DayOfYear(213, MonthDay(7, 31)), 11841 DayOfYear(214, MonthDay(8, 1)), 11842 DayOfYear(244, MonthDay(8, 31)), 11843 DayOfYear(245, MonthDay(9, 1)), 11844 DayOfYear(274, MonthDay(9, 30)), 11845 DayOfYear(275, MonthDay(10, 1)), 11846 DayOfYear(305, MonthDay(10, 31)), 11847 DayOfYear(306, MonthDay(11, 1)), 11848 DayOfYear(335, MonthDay(11, 30)), 11849 DayOfYear(336, MonthDay(12, 1)), 11850 DayOfYear(364, MonthDay(12, 29)), 11851 DayOfYear(365, MonthDay(12, 30)), 11852 DayOfYear(366, MonthDay(12, 31))]; 11853 return result; 11854 } 11855 11856 void initializeTests() 11857 { 11858 import std.algorithm.sorting : sort; 11859 import std.typecons : Rebindable; 11860 immutable lt = LocalTime().utcToTZ(0); 11861 currLocalDiffFromUTC = dur!"hnsecs"(lt); 11862 11863 version (Posix) 11864 { 11865 import std.datetime.timezone : PosixTimeZone; 11866 immutable otherTZ = lt < 0 ? PosixTimeZone.getTimeZone("Australia/Sydney") 11867 : PosixTimeZone.getTimeZone("America/Denver"); 11868 } 11869 else version (Windows) 11870 { 11871 import std.datetime.timezone : WindowsTimeZone; 11872 immutable otherTZ = lt < 0 ? WindowsTimeZone.getTimeZone("AUS Eastern Standard Time") 11873 : WindowsTimeZone.getTimeZone("Mountain Standard Time"); 11874 } 11875 11876 immutable ot = otherTZ.utcToTZ(0); 11877 11878 auto diffs = [0L, lt, ot]; 11879 auto diffAA = [0L : Rebindable!(immutable TimeZone)(UTC())]; 11880 diffAA[lt] = Rebindable!(immutable TimeZone)(LocalTime()); 11881 diffAA[ot] = Rebindable!(immutable TimeZone)(otherTZ); 11882 11883 sort(diffs); 11884 testTZs = [diffAA[diffs[0]], diffAA[diffs[1]], diffAA[diffs[2]]]; 11885 11886 testFracSecs = [Duration.zero, hnsecs(1), hnsecs(5007), hnsecs(9_999_999)]; 11887 11888 foreach (year; testYearsBC) 11889 { 11890 foreach (md; testMonthDays) 11891 testDatesBC ~= Date(year, md.month, md.day); 11892 } 11893 11894 foreach (year; testYearsAD) 11895 { 11896 foreach (md; testMonthDays) 11897 testDatesAD ~= Date(year, md.month, md.day); 11898 } 11899 11900 foreach (dt; testDatesBC) 11901 { 11902 foreach (tod; testTODs) 11903 testDateTimesBC ~= DateTime(dt, tod); 11904 } 11905 11906 foreach (dt; testDatesAD) 11907 { 11908 foreach (tod; testTODs) 11909 testDateTimesAD ~= DateTime(dt, tod); 11910 } 11911 11912 foreach (dt; testDateTimesBC) 11913 { 11914 foreach (tz; testTZs) 11915 { 11916 foreach (fs; testFracSecs) 11917 testSysTimesBC ~= SysTime(dt, fs, tz); 11918 } 11919 } 11920 11921 foreach (dt; testDateTimesAD) 11922 { 11923 foreach (tz; testTZs) 11924 { 11925 foreach (fs; testFracSecs) 11926 testSysTimesAD ~= SysTime(dt, fs, tz); 11927 } 11928 } 11929 } 11930 }