1 // Written in the D programming language 2 3 /++ 4 5 $(SCRIPT inhibitQuickIndex = 1;) 6 $(DIVC quickindex, 7 $(BOOKTABLE, 8 $(TR $(TH Category) $(TH Functions)) 9 $(TR $(TD Types) $(TD 10 $(LREF Clock) 11 $(LREF SysTime) 12 $(LREF DosFileTime) 13 )) 14 $(TR $(TD Conversion) $(TD 15 $(LREF parseRFC822DateTime) 16 $(LREF DosFileTimeToSysTime) 17 $(LREF FILETIMEToStdTime) 18 $(LREF FILETIMEToSysTime) 19 $(LREF stdTimeToFILETIME) 20 $(LREF stdTimeToUnixTime) 21 $(LREF SYSTEMTIMEToSysTime) 22 $(LREF SysTimeToDosFileTime) 23 $(LREF SysTimeToFILETIME) 24 $(LREF SysTimeToSYSTEMTIME) 25 $(LREF unixTimeToStdTime) 26 )) 27 )) 28 29 License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). 30 Authors: $(HTTP jmdavisprog.com, Jonathan M Davis) 31 Source: $(PHOBOSSRC std/datetime/systime.d) 32 +/ 33 module std.datetime.systime; 34 35 version (OSX) 36 version = Darwin; 37 else version (iOS) 38 version = Darwin; 39 else version (TVOS) 40 version = Darwin; 41 else version (WatchOS) 42 version = Darwin; 43 44 /// Get the current time as a $(LREF SysTime) 45 @safe unittest 46 { 47 import std.datetime.timezone : LocalTime; 48 SysTime today = Clock.currTime(); 49 assert(today.timezone is LocalTime()); 50 } 51 52 /// Construct a $(LREF SysTime) from a ISO time string 53 @safe unittest 54 { 55 import std.datetime.date : DateTime; 56 import std.datetime.timezone : UTC; 57 58 auto st = SysTime.fromISOExtString("2018-01-01T10:30:00Z"); 59 assert(st == SysTime(DateTime(2018, 1, 1, 10, 30, 0), UTC())); 60 } 61 62 /// Make a specific point in time in the New York timezone 63 @safe unittest 64 { 65 import core.time : hours; 66 import std.datetime.date : DateTime; 67 import std.datetime.timezone : SimpleTimeZone; 68 69 auto ny = SysTime( 70 DateTime(2018, 1, 1, 10, 30, 0), 71 new immutable SimpleTimeZone(-5.hours, "America/New_York") 72 ); 73 74 // ISO standard time strings 75 assert(ny.toISOString() == "20180101T103000-05:00"); 76 assert(ny.toISOExtString() == "2018-01-01T10:30:00-05:00"); 77 } 78 79 // Note: reconsider using specific imports below after 80 // https://issues.dlang.org/show_bug.cgi?id=17630 has been fixed 81 import core.time;// : ClockType, convert, dur, Duration, seconds, TimeException; 82 import std.datetime.date;// : _monthNames, AllowDayOverflow, CmpTimeUnits, Date, 83 //DateTime, DateTimeException, DayOfWeek, enforceValid, getDayOfWeek, maxDay, 84 //Month, splitUnitsFromHNSecs, TimeOfDay, validTimeUnits, yearIsLeapYear; 85 import std.datetime.timezone;// : LocalTime, SimpleTimeZone, TimeZone, UTC; 86 import std.exception : enforce; 87 import std.format : format; 88 import std.range.primitives; 89 import std.traits : isIntegral, isSigned, isSomeString, isNarrowString; 90 91 version (Windows) 92 { 93 import core.stdc.time : time_t; 94 import core.sys.windows.winbase; 95 import core.sys.windows.winnt; 96 import core.sys.windows.winsock2; 97 } 98 else version (Posix) 99 { 100 import core.sys.posix.signal : timespec; 101 import core.sys.posix.sys.types : time_t; 102 } 103 104 version (StdUnittest) 105 { 106 import core.exception : AssertError; 107 import std.exception : assertThrown; 108 } 109 110 111 @safe unittest 112 { 113 initializeTests(); 114 } 115 116 version (unittest) private bool clockSupported(ClockType c) 117 { 118 // Skip unsupported clocks on older linux kernels, assume that only 119 // CLOCK_MONOTONIC and CLOCK_REALTIME exist, as that is the lowest 120 // common denominator supported by all versions of Linux pre-2.6.12. 121 version (Linux_Pre_2639) 122 return c == ClockType.normal || c == ClockType.precise; 123 else 124 return true; 125 } 126 127 /++ 128 Effectively a namespace to make it clear that the methods it contains are 129 getting the time from the system clock. It cannot be instantiated. 130 +/ 131 final class Clock 132 { 133 public: 134 135 /++ 136 Returns the current time in the given time zone. 137 138 Params: 139 clockType = The $(REF ClockType, core,time) indicates which system 140 clock to use to get the current time. Very few programs 141 need to use anything other than the default. 142 tz = The time zone for the SysTime that's returned. 143 144 Throws: 145 $(REF DateTimeException,std,datetime,date) if it fails to get the 146 time. 147 +/ 148 static SysTime currTime(ClockType clockType = ClockType.normal)(immutable TimeZone tz = LocalTime()) @safe 149 { 150 return SysTime(currStdTime!clockType, tz); 151 } 152 153 @safe unittest 154 { 155 import std.format : format; 156 import core.time; 157 assert(currTime().timezone is LocalTime()); 158 assert(currTime(UTC()).timezone is UTC()); 159 160 // core.stdc.time.time does not always use unix time on Windows systems. 161 // In particular, dmc does not use unix time. If we can guarantee that 162 // the MS runtime uses unix time, then we may be able run this test 163 // then, but for now, we're just not going to run this test on Windows. 164 version (Posix) 165 { 166 static import core.stdc.time; 167 static import std.math; 168 immutable unixTimeD = currTime().toUnixTime(); 169 immutable unixTimeC = core.stdc.time.time(null); 170 assert(std.math.abs(unixTimeC - unixTimeD) <= 2); 171 } 172 173 auto norm1 = Clock.currTime; 174 auto norm2 = Clock.currTime(UTC()); 175 assert(norm1 <= norm2, format("%s %s", norm1, norm2)); 176 assert(abs(norm1 - norm2) <= seconds(2)); 177 178 import std.meta : AliasSeq; 179 static foreach (ct; AliasSeq!(ClockType.coarse, ClockType.precise, ClockType.second)) 180 {{ 181 static if (clockSupported(ct)) 182 { 183 auto value1 = Clock.currTime!ct; 184 auto value2 = Clock.currTime!ct(UTC()); 185 assert(value1 <= value2, format("%s %s (ClockType: %s)", value1, value2, ct)); 186 assert(abs(value1 - value2) <= seconds(2), format("ClockType.%s", ct)); 187 } 188 }} 189 } 190 191 192 /++ 193 Returns the number of hnsecs since midnight, January 1st, 1 A.D. for the 194 current time. 195 196 Params: 197 clockType = The $(REF ClockType, core,time) indicates which system 198 clock to use to get the current time. Very few programs 199 need to use anything other than the default. 200 201 Throws: 202 $(REF DateTimeException,std,datetime,date) if it fails to get the 203 time. 204 +/ 205 static @property long currStdTime(ClockType clockType = ClockType.normal)() @trusted 206 { 207 static if (clockType != ClockType.coarse && 208 clockType != ClockType.normal && 209 clockType != ClockType.precise && 210 clockType != ClockType.second) 211 { 212 static assert(0, format("ClockType.%s is not supported by Clock.currTime or Clock.currStdTime", clockType)); 213 } 214 215 version (Windows) 216 { 217 FILETIME fileTime; 218 GetSystemTimeAsFileTime(&fileTime); 219 immutable result = FILETIMEToStdTime(&fileTime); 220 static if (clockType == ClockType.second) 221 { 222 // Ideally, this would use core.std.time.time, but the C runtime 223 // has to be using unix time for that to work, and that's not 224 // guaranteed on Windows. Digital Mars does not use unix time. 225 // MS may or may not. If it does, then this can be made to use 226 // core.stdc.time for MS, but for now, we'll leave it like this. 227 return convert!("seconds", "hnsecs")(convert!("hnsecs", "seconds")(result)); 228 } 229 else 230 return result; 231 } 232 else version (Posix) 233 { 234 static import core.stdc.time; 235 enum hnsecsToUnixEpoch = unixTimeToStdTime(0); 236 237 version (Darwin) 238 { 239 static if (clockType == ClockType.second) 240 return unixTimeToStdTime(core.stdc.time.time(null)); 241 else 242 { 243 import core.sys.posix.sys.time : gettimeofday, timeval; 244 timeval tv = void; 245 // Posix gettimeofday called with a valid timeval address 246 // and a null second parameter doesn't fail. 247 gettimeofday(&tv, null); 248 return convert!("seconds", "hnsecs")(tv.tv_sec) + 249 tv.tv_usec * 10 + 250 hnsecsToUnixEpoch; 251 } 252 } 253 else version (linux) 254 { 255 static if (clockType == ClockType.second) 256 return unixTimeToStdTime(core.stdc.time.time(null)); 257 else 258 { 259 import core.sys.linux.time : CLOCK_REALTIME_COARSE; 260 import core.sys.posix.time : clock_gettime, CLOCK_REALTIME; 261 static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME_COARSE; 262 else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME; 263 else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME; 264 else static assert(0, "Previous static if is wrong."); 265 timespec ts = void; 266 immutable error = clock_gettime(clockArg, &ts); 267 // Posix clock_gettime called with a valid address and valid clock_id is only 268 // permitted to fail if the number of seconds does not fit in time_t. If tv_sec 269 // is long or larger overflow won't happen before 292 billion years A.D. 270 static if (ts.tv_sec.max < long.max) 271 { 272 if (error) 273 throw new TimeException("Call to clock_gettime() failed"); 274 } 275 return convert!("seconds", "hnsecs")(ts.tv_sec) + 276 ts.tv_nsec / 100 + 277 hnsecsToUnixEpoch; 278 } 279 } 280 else version (FreeBSD) 281 { 282 import core.sys.freebsd.time : clock_gettime, CLOCK_REALTIME, 283 CLOCK_REALTIME_FAST, CLOCK_REALTIME_PRECISE, CLOCK_SECOND; 284 static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME_FAST; 285 else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME; 286 else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME_PRECISE; 287 else static if (clockType == ClockType.second) alias clockArg = CLOCK_SECOND; 288 else static assert(0, "Previous static if is wrong."); 289 timespec ts = void; 290 immutable error = clock_gettime(clockArg, &ts); 291 // Posix clock_gettime called with a valid address and valid clock_id is only 292 // permitted to fail if the number of seconds does not fit in time_t. If tv_sec 293 // is long or larger overflow won't happen before 292 billion years A.D. 294 static if (ts.tv_sec.max < long.max) 295 { 296 if (error) 297 throw new TimeException("Call to clock_gettime() failed"); 298 } 299 return convert!("seconds", "hnsecs")(ts.tv_sec) + 300 ts.tv_nsec / 100 + 301 hnsecsToUnixEpoch; 302 } 303 else version (NetBSD) 304 { 305 static if (clockType == ClockType.second) 306 return unixTimeToStdTime(core.stdc.time.time(null)); 307 else 308 { 309 import core.sys.netbsd.time : clock_gettime, CLOCK_REALTIME; 310 timespec ts = void; 311 immutable error = clock_gettime(CLOCK_REALTIME, &ts); 312 // Posix clock_gettime called with a valid address and valid clock_id is only 313 // permitted to fail if the number of seconds does not fit in time_t. If tv_sec 314 // is long or larger overflow won't happen before 292 billion years A.D. 315 static if (ts.tv_sec.max < long.max) 316 { 317 if (error) 318 throw new TimeException("Call to clock_gettime() failed"); 319 } 320 return convert!("seconds", "hnsecs")(ts.tv_sec) + 321 ts.tv_nsec / 100 + 322 hnsecsToUnixEpoch; 323 } 324 } 325 else version (OpenBSD) 326 { 327 static if (clockType == ClockType.second) 328 return unixTimeToStdTime(core.stdc.time.time(null)); 329 else 330 { 331 import core.sys.openbsd.time : clock_gettime, CLOCK_REALTIME; 332 static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME; 333 else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME; 334 else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME; 335 else static assert(0, "Previous static if is wrong."); 336 timespec ts; 337 if (clock_gettime(clockArg, &ts) != 0) 338 throw new TimeException("Call to clock_gettime() failed"); 339 return convert!("seconds", "hnsecs")(ts.tv_sec) + 340 ts.tv_nsec / 100 + 341 hnsecsToUnixEpoch; 342 } 343 } 344 else version (DragonFlyBSD) 345 { 346 import core.sys.dragonflybsd.time : clock_gettime, CLOCK_REALTIME, 347 CLOCK_REALTIME_FAST, CLOCK_REALTIME_PRECISE, CLOCK_SECOND; 348 static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME_FAST; 349 else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME; 350 else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME_PRECISE; 351 else static if (clockType == ClockType.second) alias clockArg = CLOCK_SECOND; 352 else static assert(0, "Previous static if is wrong."); 353 timespec ts = void; 354 immutable error = clock_gettime(clockArg, &ts); 355 // Posix clock_gettime called with a valid address and valid clock_id is only 356 // permitted to fail if the number of seconds does not fit in time_t. If tv_sec 357 // is long or larger overflow won't happen before 292 billion years A.D. 358 static if (ts.tv_sec.max < long.max) 359 { 360 if (error) 361 throw new TimeException("Call to clock_gettime() failed"); 362 } 363 return convert!("seconds", "hnsecs")(ts.tv_sec) + 364 ts.tv_nsec / 100 + 365 hnsecsToUnixEpoch; 366 } 367 else version (Solaris) 368 { 369 static if (clockType == ClockType.second) 370 return unixTimeToStdTime(core.stdc.time.time(null)); 371 else 372 { 373 import core.sys.solaris.time : clock_gettime, CLOCK_REALTIME; 374 static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME; 375 else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME; 376 else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME; 377 else static assert(0, "Previous static if is wrong."); 378 timespec ts = void; 379 immutable error = clock_gettime(clockArg, &ts); 380 // Posix clock_gettime called with a valid address and valid clock_id is only 381 // permitted to fail if the number of seconds does not fit in time_t. If tv_sec 382 // is long or larger overflow won't happen before 292 billion years A.D. 383 static if (ts.tv_sec.max < long.max) 384 { 385 if (error) 386 throw new TimeException("Call to clock_gettime() failed"); 387 } 388 return convert!("seconds", "hnsecs")(ts.tv_sec) + 389 ts.tv_nsec / 100 + 390 hnsecsToUnixEpoch; 391 } 392 } 393 else version (Hurd) 394 { 395 static if (clockType == ClockType.second) 396 return unixTimeToStdTime(core.stdc.time.time(null)); 397 else 398 { 399 import core.sys.hurd.time : CLOCK_REALTIME_COARSE; 400 import core.sys.posix.time : clock_gettime, CLOCK_REALTIME; 401 static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME_COARSE; 402 else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME; 403 else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME; 404 else static assert(0, "Previous static if is wrong."); 405 timespec ts = void; 406 immutable error = clock_gettime(clockArg, &ts); 407 // Posix clock_gettime called with a valid address and valid clock_id is only 408 // permitted to fail if the number of seconds does not fit in time_t. If tv_sec 409 // is long or larger overflow won't happen before 292 billion years A.D. 410 static if (ts.tv_sec.max < long.max) 411 { 412 if (error) 413 throw new TimeException("Call to clock_gettime() failed"); 414 } 415 return convert!("seconds", "hnsecs")(ts.tv_sec) + 416 ts.tv_nsec / 100 + 417 hnsecsToUnixEpoch; 418 } 419 } 420 else static assert(0, "Unsupported OS"); 421 } 422 else static assert(0, "Unsupported OS"); 423 } 424 425 @safe unittest 426 { 427 import std.format : format; 428 import std.math.algebraic : abs; 429 import std.meta : AliasSeq; 430 enum limit = convert!("seconds", "hnsecs")(2); 431 432 auto norm1 = Clock.currStdTime; 433 auto norm2 = Clock.currStdTime; 434 assert(norm1 <= norm2, format("%s %s", norm1, norm2)); 435 assert(abs(norm1 - norm2) <= limit); 436 437 static foreach (ct; AliasSeq!(ClockType.coarse, ClockType.precise, ClockType.second)) 438 {{ 439 static if (clockSupported(ct)) 440 { 441 auto value1 = Clock.currStdTime!ct; 442 auto value2 = Clock.currStdTime!ct; 443 assert(value1 <= value2, format("%s %s (ClockType: %s)", value1, value2, ct)); 444 assert(abs(value1 - value2) <= limit); 445 } 446 }} 447 } 448 449 450 private: 451 452 @disable this(); 453 } 454 455 /// Get the current time as a $(LREF SysTime) 456 @safe unittest 457 { 458 import std.datetime.timezone : LocalTime; 459 SysTime today = Clock.currTime(); 460 assert(today.timezone is LocalTime()); 461 } 462 463 464 /++ 465 `SysTime` is the type used to get the current time from the 466 system or doing anything that involves time zones. Unlike 467 $(REF DateTime,std,datetime,date), the time zone is an integral part of 468 `SysTime` (though for local time applications, time zones can be ignored 469 and it will work, since it defaults to using the local time zone). It holds 470 its internal time in std time (hnsecs since midnight, January 1st, 1 A.D. 471 UTC), so it interfaces well with the system time. However, that means that, 472 unlike $(REF DateTime,std,datetime,date), it is not optimized for 473 calendar-based operations, and getting individual units from it such as 474 years or days is going to involve conversions and be less efficient. 475 476 An $(I hnsec) (hecto-nanosecond) is 100 nanoseconds. There are 10,000,000 hnsecs in a second. 477 478 For calendar-based operations that don't 479 care about time zones, then $(REF DateTime,std,datetime,date) would be 480 the type to use. For system time, use `SysTime`. 481 482 $(LREF Clock.currTime) will return the current time as a `SysTime`. 483 To convert a `SysTime` to a $(REF Date,std,datetime,date) or 484 $(REF DateTime,std,datetime,date), simply cast it. To convert a 485 $(REF Date,std,datetime,date) or $(REF DateTime,std,datetime,date) to a 486 `SysTime`, use `SysTime`'s constructor, and pass in the intended time 487 zone with it (or don't pass in a $(REF TimeZone,std,datetime,timezone), and 488 the local time zone will be used). Be aware, however, that converting from a 489 $(REF DateTime,std,datetime,date) to a `SysTime` will not necessarily 490 be 100% accurate due to DST (one hour of the year doesn't exist and another 491 occurs twice). To not risk any conversion errors, keep times as 492 `SysTime`s. Aside from DST though, there shouldn't be any conversion 493 problems. 494 495 For using time zones other than local time or UTC, use 496 $(REF PosixTimeZone,std,datetime,timezone) on Posix systems (or on Windows, 497 if providing the TZ Database files), and use 498 $(REF WindowsTimeZone,std,datetime,timezone) on Windows systems. The time in 499 `SysTime` is kept internally in hnsecs from midnight, January 1st, 1 A.D. 500 UTC. Conversion error cannot happen when changing the time zone of a 501 `SysTime`. $(REF LocalTime,std,datetime,timezone) is the 502 $(REF TimeZone,std,datetime,timezone) class which represents the local time, 503 and `UTC` is the $(REF TimeZone,std,datetime,timezone) class which 504 represents UTC. `SysTime` uses $(REF LocalTime,std,datetime,timezone) if 505 no $(REF TimeZone,std,datetime,timezone) is provided. For more details on 506 time zones, see the documentation for $(REF TimeZone,std,datetime,timezone), 507 $(REF PosixTimeZone,std,datetime,timezone), and 508 $(REF WindowsTimeZone,std,datetime,timezone). 509 510 `SysTime`'s range is from approximately 29,000 B.C. to approximately 511 29,000 A.D. 512 +/ 513 struct SysTime 514 { 515 import core.stdc.time : tm; 516 version (Posix) import core.sys.posix.sys.time : timeval; 517 import std.typecons : Rebindable; 518 519 public: 520 521 /++ 522 Params: 523 dateTime = The $(REF DateTime,std,datetime,date) to use to set 524 this $(LREF SysTime)'s internal std time. As 525 $(REF DateTime,std,datetime,date) has no concept of 526 time zone, tz is used as its time zone. 527 tz = The $(REF TimeZone,std,datetime,timezone) to use for this 528 $(LREF SysTime). If null, 529 $(REF LocalTime,std,datetime,timezone) will be used. The 530 given $(REF DateTime,std,datetime,date) is assumed to 531 be in the given time zone. 532 +/ 533 this(DateTime dateTime, return scope immutable TimeZone tz = null) return scope @safe nothrow 534 { 535 try 536 this(dateTime, Duration.zero, tz); 537 catch (Exception e) 538 assert(0, "SysTime's constructor threw when it shouldn't have."); 539 } 540 541 @safe unittest 542 { 543 static void test(DateTime dt, immutable TimeZone tz, long expected) 544 { 545 auto sysTime = SysTime(dt, tz); 546 assert(sysTime._stdTime == expected); 547 assert(sysTime._timezone is (tz is null ? LocalTime() : tz), format("Given DateTime: %s", dt)); 548 } 549 550 test(DateTime.init, UTC(), 0); 551 test(DateTime(1, 1, 1, 12, 30, 33), UTC(), 450_330_000_000L); 552 test(DateTime(0, 12, 31, 12, 30, 33), UTC(), -413_670_000_000L); 553 test(DateTime(1, 1, 1, 0, 0, 0), UTC(), 0); 554 test(DateTime(1, 1, 1, 0, 0, 1), UTC(), 10_000_000L); 555 test(DateTime(0, 12, 31, 23, 59, 59), UTC(), -10_000_000L); 556 557 test(DateTime(1, 1, 1, 0, 0, 0), new immutable SimpleTimeZone(dur!"minutes"(-60)), 36_000_000_000L); 558 test(DateTime(1, 1, 1, 0, 0, 0), new immutable SimpleTimeZone(Duration.zero), 0); 559 test(DateTime(1, 1, 1, 0, 0, 0), new immutable SimpleTimeZone(dur!"minutes"(60)), -36_000_000_000L); 560 561 static void testScope(scope ref DateTime dt) @safe 562 { 563 auto st = SysTime(dt); 564 } 565 } 566 567 /++ 568 Params: 569 dateTime = The $(REF DateTime,std,datetime,date) to use to set 570 this $(LREF SysTime)'s internal std time. As 571 $(REF DateTime,std,datetime,date) has no concept of 572 time zone, tz is used as its time zone. 573 fracSecs = The fractional seconds portion of the time. 574 tz = The $(REF TimeZone,std,datetime,timezone) to use for this 575 $(LREF SysTime). If null, 576 $(REF LocalTime,std,datetime,timezone) will be used. The 577 given $(REF DateTime,std,datetime,date) is assumed to 578 be in the given time zone. 579 580 Throws: 581 $(REF DateTimeException,std,datetime,date) if `fracSecs` is negative or if it's 582 greater than or equal to one second. 583 +/ 584 this(DateTime dateTime, Duration fracSecs, return scope immutable TimeZone tz = null) return scope @safe 585 { 586 enforce(fracSecs >= Duration.zero, new DateTimeException("A SysTime cannot have negative fractional seconds.")); 587 enforce(fracSecs < seconds(1), new DateTimeException("Fractional seconds must be less than one second.")); 588 auto nonNullTZ = tz is null ? LocalTime() : tz; 589 590 immutable dateDiff = dateTime.date - Date.init; 591 immutable todDiff = dateTime.timeOfDay - TimeOfDay.init; 592 593 immutable adjustedTime = dateDiff + todDiff + fracSecs; 594 immutable standardTime = nonNullTZ.tzToUTC(adjustedTime.total!"hnsecs"); 595 596 this(standardTime, nonNullTZ); 597 } 598 599 @safe unittest 600 { 601 import core.time; 602 static void test(DateTime dt, Duration fracSecs, immutable TimeZone tz, long expected) 603 { 604 auto sysTime = SysTime(dt, fracSecs, tz); 605 assert(sysTime._stdTime == expected); 606 assert(sysTime._timezone is (tz is null ? LocalTime() : tz), 607 format("Given DateTime: %s, Given Duration: %s", dt, fracSecs)); 608 } 609 610 test(DateTime.init, Duration.zero, UTC(), 0); 611 test(DateTime(1, 1, 1, 12, 30, 33), Duration.zero, UTC(), 450_330_000_000L); 612 test(DateTime(0, 12, 31, 12, 30, 33), Duration.zero, UTC(), -413_670_000_000L); 613 test(DateTime(1, 1, 1, 0, 0, 0), msecs(1), UTC(), 10_000L); 614 test(DateTime(0, 12, 31, 23, 59, 59), msecs(999), UTC(), -10_000L); 615 616 test(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC(), -1); 617 test(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC(), -9_999_999); 618 test(DateTime(0, 12, 31, 23, 59, 59), Duration.zero, UTC(), -10_000_000); 619 620 assertThrown!DateTimeException(SysTime(DateTime.init, hnsecs(-1), UTC())); 621 assertThrown!DateTimeException(SysTime(DateTime.init, seconds(1), UTC())); 622 623 static void testScope(scope ref DateTime dt, scope ref Duration d) @safe 624 { 625 auto st = SysTime(dt, d); 626 } 627 } 628 629 /++ 630 Params: 631 date = The $(REF Date,std,datetime,date) to use to set this 632 $(LREF SysTime)'s internal std time. As 633 $(REF Date,std,datetime,date) has no concept of time zone, tz 634 is used as its time zone. 635 tz = The $(REF TimeZone,std,datetime,timezone) to use for this 636 $(LREF SysTime). If null, 637 $(REF LocalTime,std,datetime,timezone) will be used. The 638 given $(REF Date,std,datetime,date) is assumed to be in the 639 given time zone. 640 +/ 641 this(Date date, return scope immutable TimeZone tz = null) return scope @safe nothrow 642 { 643 _timezone = tz is null ? LocalTime() : tz; 644 645 try 646 { 647 immutable adjustedTime = (date - Date(1, 1, 1)).total!"hnsecs"; 648 immutable standardTime = _timezone.tzToUTC(adjustedTime); 649 650 this(standardTime, _timezone); 651 } 652 catch (Exception e) 653 assert(0, "Date's constructor through when it shouldn't have."); 654 } 655 656 @safe unittest 657 { 658 static void test(Date d, immutable TimeZone tz, long expected) 659 { 660 auto sysTime = SysTime(d, tz); 661 assert(sysTime._stdTime == expected); 662 assert(sysTime._timezone is (tz is null ? LocalTime() : tz), format("Given Date: %s", d)); 663 } 664 665 test(Date.init, UTC(), 0); 666 test(Date(1, 1, 1), UTC(), 0); 667 test(Date(1, 1, 2), UTC(), 864000000000); 668 test(Date(0, 12, 31), UTC(), -864000000000); 669 670 static void testScope(scope ref Date d) @safe 671 { 672 auto st = SysTime(d); 673 } 674 } 675 676 /++ 677 Note: 678 Whereas the other constructors take in the given date/time, assume 679 that it's in the given time zone, and convert it to hnsecs in UTC 680 since midnight, January 1st, 1 A.D. UTC - i.e. std time - this 681 constructor takes a std time, which is specifically already in UTC, 682 so no conversion takes place. Of course, the various getter 683 properties and functions will use the given time zone's conversion 684 function to convert the results to that time zone, but no conversion 685 of the arguments to this constructor takes place. 686 687 Params: 688 stdTime = The number of hnsecs since midnight, January 1st, 1 A.D. 689 UTC. 690 tz = The $(REF TimeZone,std,datetime,timezone) to use for this 691 $(LREF SysTime). If null, 692 $(REF LocalTime,std,datetime,timezone) will be used. 693 +/ 694 this(long stdTime, return scope immutable TimeZone tz = null) return scope @safe pure nothrow 695 { 696 _stdTime = stdTime; 697 _timezone = tz is null ? LocalTime() : tz; 698 } 699 700 @safe unittest 701 { 702 static void test(long stdTime, immutable TimeZone tz) 703 { 704 auto sysTime = SysTime(stdTime, tz); 705 assert(sysTime._stdTime == stdTime); 706 assert(sysTime._timezone is (tz is null ? LocalTime() : tz), format("Given stdTime: %s", stdTime)); 707 } 708 709 foreach (stdTime; [-1234567890L, -250, 0, 250, 1235657390L]) 710 { 711 foreach (tz; testTZs) 712 test(stdTime, tz); 713 } 714 } 715 716 717 /++ 718 Params: 719 rhs = The $(LREF SysTime) to assign to this one. 720 721 Returns: The `this` of this `SysTime`. 722 +/ 723 ref SysTime opAssign()(auto ref const(SysTime) rhs) scope return @safe pure nothrow 724 { 725 _stdTime = rhs._stdTime; 726 _timezone = rhs._timezone; 727 return this; 728 } 729 730 @safe unittest 731 { 732 SysTime st; 733 st = SysTime(DateTime(2012, 12, 21, 1, 2, 3), UTC()); 734 assert(st == SysTime(DateTime(2012, 12, 21, 1, 2, 3), UTC())); 735 736 const other = SysTime(DateTime(19, 1, 7, 13, 14, 15), LocalTime()); 737 st = other; 738 assert(st == other); 739 740 version (none) // https://issues.dlang.org/show_bug.cgi?id=21175 741 static void testScope(scope ref SysTime left, const scope SysTime right) @safe 742 { 743 left = right; 744 } 745 } 746 747 748 /++ 749 Checks for equality between this $(LREF SysTime) and the given 750 $(LREF SysTime). 751 752 Note that the time zone is ignored. Only the internal 753 std times (which are in UTC) are compared. 754 +/ 755 bool opEquals()(auto ref const(SysTime) rhs) @safe const pure nothrow scope 756 { 757 return _stdTime == rhs._stdTime; 758 } 759 760 @safe unittest 761 { 762 import std.range : chain; 763 764 assert(SysTime(DateTime.init, UTC()) == SysTime(0, UTC())); 765 assert(SysTime(DateTime.init, UTC()) == SysTime(0)); 766 assert(SysTime(Date.init, UTC()) == SysTime(0)); 767 assert(SysTime(0) == SysTime(0)); 768 769 static void test(DateTime dt, immutable TimeZone tz1, immutable TimeZone tz2) 770 { 771 auto st1 = SysTime(dt); 772 st1.timezone = tz1; 773 774 auto st2 = SysTime(dt); 775 st2.timezone = tz2; 776 777 assert(st1 == st2); 778 } 779 780 foreach (tz1; testTZs) 781 { 782 foreach (tz2; testTZs) 783 { 784 foreach (dt; chain(testDateTimesBC, testDateTimesAD)) 785 test(dt, tz1, tz2); 786 } 787 } 788 789 auto st = SysTime(DateTime(1999, 7, 6, 12, 33, 30)); 790 const cst = SysTime(DateTime(1999, 7, 6, 12, 33, 30)); 791 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 33, 30)); 792 assert(st == st); 793 assert(st == cst); 794 assert(st == ist); 795 assert(cst == st); 796 assert(cst == cst); 797 assert(cst == ist); 798 assert(ist == st); 799 assert(ist == cst); 800 assert(ist == ist); 801 802 static void testScope(scope ref SysTime left, const scope SysTime right) @safe 803 { 804 assert(left == right); 805 assert(right == left); 806 } 807 } 808 809 810 /++ 811 Compares this $(LREF SysTime) with the given $(LREF SysTime). 812 813 Time zone is irrelevant when comparing $(LREF SysTime)s. 814 815 Returns: 816 $(BOOKTABLE, 817 $(TR $(TD this < rhs) $(TD < 0)) 818 $(TR $(TD this == rhs) $(TD 0)) 819 $(TR $(TD this > rhs) $(TD > 0)) 820 ) 821 +/ 822 int opCmp()(auto ref const(SysTime) rhs) @safe const pure nothrow scope 823 { 824 if (_stdTime < rhs._stdTime) 825 return -1; 826 if (_stdTime > rhs._stdTime) 827 return 1; 828 return 0; 829 } 830 831 @safe unittest 832 { 833 import std.algorithm.iteration : map; 834 import std.array : array; 835 import std.range : chain; 836 837 assert(SysTime(DateTime.init, UTC()).opCmp(SysTime(0, UTC())) == 0); 838 assert(SysTime(DateTime.init, UTC()).opCmp(SysTime(0)) == 0); 839 assert(SysTime(Date.init, UTC()).opCmp(SysTime(0)) == 0); 840 assert(SysTime(0).opCmp(SysTime(0)) == 0); 841 842 static void testEqual(SysTime st, immutable TimeZone tz1, immutable TimeZone tz2) 843 { 844 auto st1 = st; 845 st1.timezone = tz1; 846 847 auto st2 = st; 848 st2.timezone = tz2; 849 850 assert(st1.opCmp(st2) == 0); 851 } 852 853 auto sts = array(map!SysTime(chain(testDateTimesBC, testDateTimesAD))); 854 855 foreach (st; sts) 856 { 857 foreach (tz1; testTZs) 858 { 859 foreach (tz2; testTZs) 860 testEqual(st, tz1, tz2); 861 } 862 } 863 864 static void testCmp(SysTime st1, immutable TimeZone tz1, SysTime st2, immutable TimeZone tz2) 865 { 866 st1.timezone = tz1; 867 st2.timezone = tz2; 868 assert(st1.opCmp(st2) < 0); 869 assert(st2.opCmp(st1) > 0); 870 } 871 872 foreach (si, st1; sts) 873 { 874 foreach (st2; sts[si + 1 .. $]) 875 { 876 foreach (tz1; testTZs) 877 { 878 foreach (tz2; testTZs) 879 testCmp(st1, tz1, st2, tz2); 880 } 881 } 882 } 883 884 auto st = SysTime(DateTime(1999, 7, 6, 12, 33, 30)); 885 const cst = SysTime(DateTime(1999, 7, 6, 12, 33, 30)); 886 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 33, 30)); 887 assert(st.opCmp(st) == 0); 888 assert(st.opCmp(cst) == 0); 889 assert(st.opCmp(ist) == 0); 890 assert(cst.opCmp(st) == 0); 891 assert(cst.opCmp(cst) == 0); 892 assert(cst.opCmp(ist) == 0); 893 assert(ist.opCmp(st) == 0); 894 assert(ist.opCmp(cst) == 0); 895 assert(ist.opCmp(ist) == 0); 896 897 static void testScope(scope ref SysTime left, const scope SysTime right) @safe 898 { 899 assert(left < right); 900 assert(right > left); 901 } 902 } 903 904 905 /++ 906 Returns: A hash of the $(LREF SysTime). 907 +/ 908 size_t toHash() const @nogc pure nothrow @safe scope 909 { 910 static if (is(size_t == ulong)) 911 return _stdTime; 912 else 913 { 914 // MurmurHash2 915 enum ulong m = 0xc6a4a7935bd1e995UL; 916 enum ulong n = m * 16; 917 enum uint r = 47; 918 919 ulong k = _stdTime; 920 k *= m; 921 k ^= k >> r; 922 k *= m; 923 924 ulong h = n; 925 h ^= k; 926 h *= m; 927 928 return cast(size_t) h; 929 } 930 } 931 932 @safe unittest 933 { 934 assert(SysTime(0).toHash == SysTime(0).toHash); 935 assert(SysTime(DateTime(2000, 1, 1)).toHash == SysTime(DateTime(2000, 1, 1)).toHash); 936 assert(SysTime(DateTime(2000, 1, 1)).toHash != SysTime(DateTime(2000, 1, 2)).toHash); 937 938 // test that timezones aren't taken into account 939 assert(SysTime(0, LocalTime()).toHash == SysTime(0, LocalTime()).toHash); 940 assert(SysTime(0, LocalTime()).toHash == SysTime(0, UTC()).toHash); 941 assert(SysTime(DateTime(2000, 1, 1), LocalTime()).toHash == SysTime(DateTime(2000, 1, 1), LocalTime()).toHash); 942 immutable zone = new SimpleTimeZone(dur!"minutes"(60)); 943 assert(SysTime(DateTime(2000, 1, 1, 1), zone).toHash == SysTime(DateTime(2000, 1, 1), UTC()).toHash); 944 assert(SysTime(DateTime(2000, 1, 1), zone).toHash != SysTime(DateTime(2000, 1, 1), UTC()).toHash); 945 946 static void testScope(scope ref SysTime st) @safe 947 { 948 auto result = st.toHash(); 949 } 950 } 951 952 953 /++ 954 Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive 955 are B.C. 956 +/ 957 @property short year() @safe const nothrow scope 958 { 959 return (cast(Date) this).year; 960 } 961 962 @safe unittest 963 { 964 import std.range : chain; 965 static void test(SysTime sysTime, long expected) 966 { 967 assert(sysTime.year == expected, format("Value given: %s", sysTime)); 968 } 969 970 test(SysTime(0, UTC()), 1); 971 test(SysTime(1, UTC()), 1); 972 test(SysTime(-1, UTC()), 0); 973 974 foreach (year; chain(testYearsBC, testYearsAD)) 975 { 976 foreach (md; testMonthDays) 977 { 978 foreach (tod; testTODs) 979 { 980 auto dt = DateTime(Date(year, md.month, md.day), tod); 981 foreach (tz; testTZs) 982 { 983 foreach (fs; testFracSecs) 984 test(SysTime(dt, fs, tz), year); 985 } 986 } 987 } 988 } 989 990 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 991 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 992 assert(cst.year == 1999); 993 assert(ist.year == 1999); 994 995 static void testScope(scope ref SysTime st) @safe 996 { 997 auto result = st.year; 998 } 999 } 1000 1001 /++ 1002 Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive 1003 are B.C. 1004 1005 Params: 1006 year = The year to set this $(LREF SysTime)'s year to. 1007 1008 Throws: 1009 $(REF DateTimeException,std,datetime,date) if the new year is not 1010 a leap year and the resulting date would be on February 29th. 1011 +/ 1012 @property void year(int year) @safe scope 1013 { 1014 auto hnsecs = adjTime; 1015 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 1016 1017 if (hnsecs < 0) 1018 { 1019 hnsecs += convert!("hours", "hnsecs")(24); 1020 --days; 1021 } 1022 1023 auto date = Date(cast(int) days); 1024 date.year = year; 1025 1026 immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1); 1027 adjTime = newDaysHNSecs + hnsecs; 1028 } 1029 1030 /// 1031 @safe unittest 1032 { 1033 import std.datetime.date : DateTime; 1034 1035 assert(SysTime(DateTime(1999, 7, 6, 9, 7, 5)).year == 1999); 1036 assert(SysTime(DateTime(2010, 10, 4, 0, 0, 30)).year == 2010); 1037 assert(SysTime(DateTime(-7, 4, 5, 7, 45, 2)).year == -7); 1038 } 1039 1040 @safe unittest 1041 { 1042 import std.range : chain; 1043 1044 static void test(SysTime st, int year, SysTime expected) 1045 { 1046 st.year = year; 1047 assert(st == expected); 1048 } 1049 1050 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 1051 { 1052 auto dt = cast(DateTime) st; 1053 1054 foreach (year; chain(testYearsBC, testYearsAD)) 1055 { 1056 auto e = SysTime(DateTime(year, dt.month, dt.day, dt.hour, dt.minute, dt.second), 1057 st.fracSecs, 1058 st.timezone); 1059 test(st, year, e); 1060 } 1061 } 1062 1063 foreach (fs; testFracSecs) 1064 { 1065 foreach (tz; testTZs) 1066 { 1067 foreach (tod; testTODs) 1068 { 1069 test(SysTime(DateTime(Date(1999, 2, 28), tod), fs, tz), 2000, 1070 SysTime(DateTime(Date(2000, 2, 28), tod), fs, tz)); 1071 test(SysTime(DateTime(Date(2000, 2, 28), tod), fs, tz), 1999, 1072 SysTime(DateTime(Date(1999, 2, 28), tod), fs, tz)); 1073 } 1074 1075 foreach (tod; testTODsThrown) 1076 { 1077 auto st = SysTime(DateTime(Date(2000, 2, 29), tod), fs, tz); 1078 assertThrown!DateTimeException(st.year = 1999); 1079 } 1080 } 1081 } 1082 1083 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1084 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1085 static assert(!__traits(compiles, cst.year = 7)); 1086 static assert(!__traits(compiles, ist.year = 7)); 1087 1088 static void testScope(scope ref SysTime st) @safe 1089 { 1090 st.year = 42; 1091 } 1092 } 1093 1094 /++ 1095 Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C. 1096 1097 Throws: 1098 $(REF DateTimeException,std,datetime,date) if `isAD` is true. 1099 +/ 1100 @property ushort yearBC() @safe const scope 1101 { 1102 return (cast(Date) this).yearBC; 1103 } 1104 1105 /// 1106 @safe unittest 1107 { 1108 import std.datetime.date : DateTime; 1109 1110 assert(SysTime(DateTime(0, 1, 1, 12, 30, 33)).yearBC == 1); 1111 assert(SysTime(DateTime(-1, 1, 1, 10, 7, 2)).yearBC == 2); 1112 assert(SysTime(DateTime(-100, 1, 1, 4, 59, 0)).yearBC == 101); 1113 } 1114 1115 @safe unittest 1116 { 1117 import std.exception : assertNotThrown; 1118 foreach (st; testSysTimesBC) 1119 { 1120 auto msg = format("SysTime: %s", st); 1121 assertNotThrown!DateTimeException(st.yearBC, msg); 1122 assert(st.yearBC == (st.year * -1) + 1, msg); 1123 } 1124 1125 foreach (st; [testSysTimesAD[0], testSysTimesAD[$/2], testSysTimesAD[$-1]]) 1126 assertThrown!DateTimeException(st.yearBC, format("SysTime: %s", st)); 1127 1128 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1129 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1130 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1131 st.year = 12; 1132 assert(st.year == 12); 1133 static assert(!__traits(compiles, cst.year = 12)); 1134 static assert(!__traits(compiles, ist.year = 12)); 1135 1136 static void testScope(scope ref SysTime st) @safe 1137 { 1138 auto result = st.yearBC; 1139 } 1140 } 1141 1142 1143 /++ 1144 Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C. 1145 1146 Params: 1147 year = The year B.C. to set this $(LREF SysTime)'s year to. 1148 1149 Throws: 1150 $(REF DateTimeException,std,datetime,date) if a non-positive value 1151 is given. 1152 +/ 1153 @property void yearBC(int year) @safe scope 1154 { 1155 auto hnsecs = adjTime; 1156 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 1157 1158 if (hnsecs < 0) 1159 { 1160 hnsecs += convert!("hours", "hnsecs")(24); 1161 --days; 1162 } 1163 1164 auto date = Date(cast(int) days); 1165 date.yearBC = year; 1166 1167 immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1); 1168 adjTime = newDaysHNSecs + hnsecs; 1169 } 1170 1171 @safe unittest 1172 { 1173 auto st = SysTime(DateTime(2010, 1, 1, 7, 30, 0)); 1174 st.yearBC = 1; 1175 assert(st == SysTime(DateTime(0, 1, 1, 7, 30, 0))); 1176 1177 st.yearBC = 10; 1178 assert(st == SysTime(DateTime(-9, 1, 1, 7, 30, 0))); 1179 } 1180 1181 @safe unittest 1182 { 1183 import std.range : chain; 1184 static void test(SysTime st, int year, SysTime expected) 1185 { 1186 st.yearBC = year; 1187 assert(st == expected, format("SysTime: %s", st)); 1188 } 1189 1190 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 1191 { 1192 auto dt = cast(DateTime) st; 1193 1194 foreach (year; testYearsBC) 1195 { 1196 auto e = SysTime(DateTime(year, dt.month, dt.day, dt.hour, dt.minute, dt.second), 1197 st.fracSecs, 1198 st.timezone); 1199 test(st, (year * -1) + 1, e); 1200 } 1201 } 1202 1203 foreach (st; [testSysTimesBC[0], testSysTimesBC[$ - 1], testSysTimesAD[0], testSysTimesAD[$ - 1]]) 1204 { 1205 foreach (year; testYearsBC) 1206 assertThrown!DateTimeException(st.yearBC = year); 1207 } 1208 1209 foreach (fs; testFracSecs) 1210 { 1211 foreach (tz; testTZs) 1212 { 1213 foreach (tod; testTODs) 1214 { 1215 test(SysTime(DateTime(Date(-1999, 2, 28), tod), fs, tz), 2001, 1216 SysTime(DateTime(Date(-2000, 2, 28), tod), fs, tz)); 1217 test(SysTime(DateTime(Date(-2000, 2, 28), tod), fs, tz), 2000, 1218 SysTime(DateTime(Date(-1999, 2, 28), tod), fs, tz)); 1219 } 1220 1221 foreach (tod; testTODsThrown) 1222 { 1223 auto st = SysTime(DateTime(Date(-2000, 2, 29), tod), fs, tz); 1224 assertThrown!DateTimeException(st.year = -1999); 1225 } 1226 } 1227 } 1228 1229 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1230 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1231 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1232 st.yearBC = 12; 1233 assert(st.yearBC == 12); 1234 static assert(!__traits(compiles, cst.yearBC = 12)); 1235 static assert(!__traits(compiles, ist.yearBC = 12)); 1236 1237 static void testScope(scope ref SysTime st) @safe 1238 { 1239 st.yearBC = 42; 1240 } 1241 } 1242 1243 1244 /++ 1245 Month of a Gregorian Year. 1246 +/ 1247 @property Month month() @safe const nothrow scope 1248 { 1249 return (cast(Date) this).month; 1250 } 1251 1252 /// 1253 @safe unittest 1254 { 1255 import std.datetime.date : DateTime; 1256 1257 assert(SysTime(DateTime(1999, 7, 6, 9, 7, 5)).month == 7); 1258 assert(SysTime(DateTime(2010, 10, 4, 0, 0, 30)).month == 10); 1259 assert(SysTime(DateTime(-7, 4, 5, 7, 45, 2)).month == 4); 1260 } 1261 1262 @safe unittest 1263 { 1264 import std.range : chain; 1265 1266 static void test(SysTime sysTime, Month expected) 1267 { 1268 assert(sysTime.month == expected, format("Value given: %s", sysTime)); 1269 } 1270 1271 test(SysTime(0, UTC()), Month.jan); 1272 test(SysTime(1, UTC()), Month.jan); 1273 test(SysTime(-1, UTC()), Month.dec); 1274 1275 foreach (year; chain(testYearsBC, testYearsAD)) 1276 { 1277 foreach (md; testMonthDays) 1278 { 1279 foreach (tod; testTODs) 1280 { 1281 auto dt = DateTime(Date(year, md.month, md.day), tod); 1282 foreach (fs; testFracSecs) 1283 { 1284 foreach (tz; testTZs) 1285 test(SysTime(dt, fs, tz), md.month); 1286 } 1287 } 1288 } 1289 } 1290 1291 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1292 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1293 assert(cst.month == 7); 1294 assert(ist.month == 7); 1295 1296 static void testScope(scope ref SysTime st) @safe 1297 { 1298 auto result = st.month; 1299 } 1300 } 1301 1302 1303 /++ 1304 Month of a Gregorian Year. 1305 1306 Params: 1307 month = The month to set this $(LREF SysTime)'s month to. 1308 1309 Throws: 1310 $(REF DateTimeException,std,datetime,date) if the given month is 1311 not a valid month. 1312 +/ 1313 @property void month(Month month) @safe scope 1314 { 1315 auto hnsecs = adjTime; 1316 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 1317 1318 if (hnsecs < 0) 1319 { 1320 hnsecs += convert!("hours", "hnsecs")(24); 1321 --days; 1322 } 1323 1324 auto date = Date(cast(int) days); 1325 date.month = month; 1326 1327 immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1); 1328 adjTime = newDaysHNSecs + hnsecs; 1329 } 1330 1331 @safe unittest 1332 { 1333 import std.algorithm.iteration : filter; 1334 import std.range : chain; 1335 1336 static void test(SysTime st, Month month, SysTime expected) 1337 { 1338 st.month = cast(Month) month; 1339 assert(st == expected); 1340 } 1341 1342 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 1343 { 1344 auto dt = cast(DateTime) st; 1345 1346 foreach (md; testMonthDays) 1347 { 1348 if (st.day > maxDay(dt.year, md.month)) 1349 continue; 1350 auto e = SysTime(DateTime(dt.year, md.month, dt.day, dt.hour, dt.minute, dt.second), 1351 st.fracSecs, 1352 st.timezone); 1353 test(st, md.month, e); 1354 } 1355 } 1356 1357 foreach (fs; testFracSecs) 1358 { 1359 foreach (tz; testTZs) 1360 { 1361 foreach (tod; testTODs) 1362 { 1363 foreach (year; filter!((a){return yearIsLeapYear(a);}) (chain(testYearsBC, testYearsAD))) 1364 { 1365 test(SysTime(DateTime(Date(year, 1, 29), tod), fs, tz), 1366 Month.feb, 1367 SysTime(DateTime(Date(year, 2, 29), tod), fs, tz)); 1368 } 1369 1370 foreach (year; chain(testYearsBC, testYearsAD)) 1371 { 1372 test(SysTime(DateTime(Date(year, 1, 28), tod), fs, tz), 1373 Month.feb, 1374 SysTime(DateTime(Date(year, 2, 28), tod), fs, tz)); 1375 test(SysTime(DateTime(Date(year, 7, 30), tod), fs, tz), 1376 Month.jun, 1377 SysTime(DateTime(Date(year, 6, 30), tod), fs, tz)); 1378 } 1379 } 1380 } 1381 } 1382 1383 foreach (fs; [testFracSecs[0], testFracSecs[$-1]]) 1384 { 1385 foreach (tz; testTZs) 1386 { 1387 foreach (tod; testTODsThrown) 1388 { 1389 foreach (year; [testYearsBC[$-3], testYearsBC[$-2], 1390 testYearsBC[$-2], testYearsAD[0], 1391 testYearsAD[$-2], testYearsAD[$-1]]) 1392 { 1393 auto day = yearIsLeapYear(year) ? 30 : 29; 1394 auto st1 = SysTime(DateTime(Date(year, 1, day), tod), fs, tz); 1395 assertThrown!DateTimeException(st1.month = Month.feb); 1396 1397 auto st2 = SysTime(DateTime(Date(year, 7, 31), tod), fs, tz); 1398 assertThrown!DateTimeException(st2.month = Month.jun); 1399 } 1400 } 1401 } 1402 } 1403 1404 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1405 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1406 static assert(!__traits(compiles, cst.month = Month.dec)); 1407 static assert(!__traits(compiles, ist.month = Month.dec)); 1408 1409 static void testScope(scope ref SysTime st) @safe 1410 { 1411 st.month = Month.dec; 1412 } 1413 } 1414 1415 /++ 1416 Day of a Gregorian Month. 1417 +/ 1418 @property ubyte day() @safe const nothrow scope 1419 { 1420 return (cast(Date) this).day; 1421 } 1422 1423 /// 1424 @safe unittest 1425 { 1426 import std.datetime.date : DateTime; 1427 1428 assert(SysTime(DateTime(1999, 7, 6, 9, 7, 5)).day == 6); 1429 assert(SysTime(DateTime(2010, 10, 4, 0, 0, 30)).day == 4); 1430 assert(SysTime(DateTime(-7, 4, 5, 7, 45, 2)).day == 5); 1431 } 1432 1433 @safe unittest 1434 { 1435 import std.range : chain; 1436 1437 static void test(SysTime sysTime, int expected) 1438 { 1439 assert(sysTime.day == expected, format("Value given: %s", sysTime)); 1440 } 1441 1442 test(SysTime(0, UTC()), 1); 1443 test(SysTime(1, UTC()), 1); 1444 test(SysTime(-1, UTC()), 31); 1445 1446 foreach (year; chain(testYearsBC, testYearsAD)) 1447 { 1448 foreach (md; testMonthDays) 1449 { 1450 foreach (tod; testTODs) 1451 { 1452 auto dt = DateTime(Date(year, md.month, md.day), tod); 1453 1454 foreach (tz; testTZs) 1455 { 1456 foreach (fs; testFracSecs) 1457 test(SysTime(dt, fs, tz), md.day); 1458 } 1459 } 1460 } 1461 } 1462 1463 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1464 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1465 assert(cst.day == 6); 1466 assert(ist.day == 6); 1467 1468 static void testScope(scope ref SysTime st) @safe 1469 { 1470 auto result = st.day; 1471 } 1472 } 1473 1474 1475 /++ 1476 Day of a Gregorian Month. 1477 1478 Params: 1479 day = The day of the month to set this $(LREF SysTime)'s day to. 1480 1481 Throws: 1482 $(REF DateTimeException,std,datetime,date) if the given day is not 1483 a valid day of the current month. 1484 +/ 1485 @property void day(int day) @safe scope 1486 { 1487 auto hnsecs = adjTime; 1488 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 1489 1490 if (hnsecs < 0) 1491 { 1492 hnsecs += convert!("hours", "hnsecs")(24); 1493 --days; 1494 } 1495 1496 auto date = Date(cast(int) days); 1497 date.day = day; 1498 1499 immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1); 1500 adjTime = newDaysHNSecs + hnsecs; 1501 } 1502 1503 @safe unittest 1504 { 1505 import std.range : chain; 1506 import std.traits : EnumMembers; 1507 1508 foreach (day; chain(testDays)) 1509 { 1510 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 1511 { 1512 auto dt = cast(DateTime) st; 1513 1514 if (day > maxDay(dt.year, dt.month)) 1515 continue; 1516 auto expected = SysTime(DateTime(dt.year, dt.month, day, dt.hour, dt.minute, dt.second), 1517 st.fracSecs, 1518 st.timezone); 1519 st.day = day; 1520 assert(st == expected, format("[%s] [%s]", st, expected)); 1521 } 1522 } 1523 1524 foreach (tz; testTZs) 1525 { 1526 foreach (tod; testTODs) 1527 { 1528 foreach (fs; testFracSecs) 1529 { 1530 foreach (year; chain(testYearsBC, testYearsAD)) 1531 { 1532 foreach (month; EnumMembers!Month) 1533 { 1534 auto st = SysTime(DateTime(Date(year, month, 1), tod), fs, tz); 1535 immutable max = maxDay(year, month); 1536 auto expected = SysTime(DateTime(Date(year, month, max), tod), fs, tz); 1537 1538 st.day = max; 1539 assert(st == expected, format("[%s] [%s]", st, expected)); 1540 } 1541 } 1542 } 1543 } 1544 } 1545 1546 foreach (tz; testTZs) 1547 { 1548 foreach (tod; testTODsThrown) 1549 { 1550 foreach (fs; [testFracSecs[0], testFracSecs[$-1]]) 1551 { 1552 foreach (year; [testYearsBC[$-3], testYearsBC[$-2], 1553 testYearsBC[$-2], testYearsAD[0], 1554 testYearsAD[$-2], testYearsAD[$-1]]) 1555 { 1556 foreach (month; EnumMembers!Month) 1557 { 1558 auto st = SysTime(DateTime(Date(year, month, 1), tod), fs, tz); 1559 immutable max = maxDay(year, month); 1560 1561 assertThrown!DateTimeException(st.day = max + 1); 1562 } 1563 } 1564 } 1565 } 1566 } 1567 1568 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1569 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1570 static assert(!__traits(compiles, cst.day = 27)); 1571 static assert(!__traits(compiles, ist.day = 27)); 1572 1573 static void testScope(scope ref SysTime st) @safe 1574 { 1575 st.day = 12; 1576 } 1577 } 1578 1579 1580 /++ 1581 Hours past midnight. 1582 +/ 1583 @property ubyte hour() @safe const nothrow scope 1584 { 1585 auto hnsecs = adjTime; 1586 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 1587 1588 if (hnsecs < 0) 1589 { 1590 hnsecs += convert!("hours", "hnsecs")(24); 1591 --days; 1592 } 1593 1594 return cast(ubyte) getUnitsFromHNSecs!"hours"(hnsecs); 1595 } 1596 1597 @safe unittest 1598 { 1599 import std.range : chain; 1600 1601 static void test(SysTime sysTime, int expected) 1602 { 1603 assert(sysTime.hour == expected, format("Value given: %s", sysTime)); 1604 } 1605 1606 test(SysTime(0, UTC()), 0); 1607 test(SysTime(1, UTC()), 0); 1608 test(SysTime(-1, UTC()), 23); 1609 1610 foreach (tz; testTZs) 1611 { 1612 foreach (year; chain(testYearsBC, testYearsAD)) 1613 { 1614 foreach (md; testMonthDays) 1615 { 1616 foreach (hour; testHours) 1617 { 1618 foreach (minute; testMinSecs) 1619 { 1620 foreach (second; testMinSecs) 1621 { 1622 auto dt = DateTime(Date(year, md.month, md.day), TimeOfDay(hour, minute, second)); 1623 foreach (fs; testFracSecs) 1624 test(SysTime(dt, fs, tz), hour); 1625 } 1626 } 1627 } 1628 } 1629 } 1630 } 1631 1632 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1633 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1634 assert(cst.hour == 12); 1635 assert(ist.hour == 12); 1636 1637 static void testScope(scope ref SysTime st) @safe 1638 { 1639 auto result = st.hour; 1640 } 1641 } 1642 1643 1644 /++ 1645 Hours past midnight. 1646 1647 Params: 1648 hour = The hours to set this $(LREF SysTime)'s hour to. 1649 1650 Throws: 1651 $(REF DateTimeException,std,datetime,date) if the given hour are 1652 not a valid hour of the day. 1653 +/ 1654 @property void hour(int hour) @safe scope 1655 { 1656 enforceValid!"hours"(hour); 1657 1658 auto hnsecs = adjTime; 1659 auto days = splitUnitsFromHNSecs!"days"(hnsecs); 1660 immutable daysHNSecs = convert!("days", "hnsecs")(days); 1661 immutable negative = hnsecs < 0; 1662 1663 if (negative) 1664 hnsecs += convert!("hours", "hnsecs")(24); 1665 1666 hnsecs = removeUnitsFromHNSecs!"hours"(hnsecs); 1667 hnsecs += convert!("hours", "hnsecs")(hour); 1668 1669 if (negative) 1670 hnsecs -= convert!("hours", "hnsecs")(24); 1671 1672 adjTime = daysHNSecs + hnsecs; 1673 } 1674 1675 @safe unittest 1676 { 1677 import std.range : chain; 1678 1679 foreach (hour; chain(testHours)) 1680 { 1681 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 1682 { 1683 auto dt = cast(DateTime) st; 1684 auto expected = SysTime(DateTime(dt.year, dt.month, dt.day, hour, dt.minute, dt.second), 1685 st.fracSecs, 1686 st.timezone); 1687 st.hour = hour; 1688 assert(st == expected, format("[%s] [%s]", st, expected)); 1689 } 1690 } 1691 1692 auto st = testSysTimesAD[0]; 1693 assertThrown!DateTimeException(st.hour = -1); 1694 assertThrown!DateTimeException(st.hour = 60); 1695 1696 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1697 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1698 static assert(!__traits(compiles, cst.hour = 27)); 1699 static assert(!__traits(compiles, ist.hour = 27)); 1700 1701 static void testScope(scope ref SysTime st) @safe 1702 { 1703 st.hour = 12; 1704 } 1705 } 1706 1707 1708 /++ 1709 Minutes past the current hour. 1710 +/ 1711 @property ubyte minute() @safe const nothrow scope 1712 { 1713 auto hnsecs = adjTime; 1714 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 1715 1716 if (hnsecs < 0) 1717 { 1718 hnsecs += convert!("hours", "hnsecs")(24); 1719 --days; 1720 } 1721 1722 hnsecs = removeUnitsFromHNSecs!"hours"(hnsecs); 1723 1724 return cast(ubyte) getUnitsFromHNSecs!"minutes"(hnsecs); 1725 } 1726 1727 @safe unittest 1728 { 1729 import std.range : chain; 1730 1731 static void test(SysTime sysTime, int expected) 1732 { 1733 assert(sysTime.minute == expected, format("Value given: %s", sysTime)); 1734 } 1735 1736 test(SysTime(0, UTC()), 0); 1737 test(SysTime(1, UTC()), 0); 1738 test(SysTime(-1, UTC()), 59); 1739 1740 foreach (tz; testTZs) 1741 { 1742 foreach (year; chain(testYearsBC, testYearsAD)) 1743 { 1744 foreach (md; testMonthDays) 1745 { 1746 foreach (hour; testHours) 1747 { 1748 foreach (minute; testMinSecs) 1749 { 1750 foreach (second; testMinSecs) 1751 { 1752 auto dt = DateTime(Date(year, md.month, md.day), TimeOfDay(hour, minute, second)); 1753 foreach (fs; testFracSecs) 1754 test(SysTime(dt, fs, tz), minute); 1755 } 1756 } 1757 } 1758 } 1759 } 1760 } 1761 1762 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1763 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1764 assert(cst.minute == 30); 1765 assert(ist.minute == 30); 1766 1767 static void testScope(scope ref SysTime st) @safe 1768 { 1769 auto result = st.minute; 1770 } 1771 } 1772 1773 1774 /++ 1775 Minutes past the current hour. 1776 1777 Params: 1778 minute = The minute to set this $(LREF SysTime)'s minute to. 1779 1780 Throws: 1781 $(REF DateTimeException,std,datetime,date) if the given minute are 1782 not a valid minute of an hour. 1783 +/ 1784 @property void minute(int minute) @safe scope 1785 { 1786 enforceValid!"minutes"(minute); 1787 1788 auto hnsecs = adjTime; 1789 auto days = splitUnitsFromHNSecs!"days"(hnsecs); 1790 immutable daysHNSecs = convert!("days", "hnsecs")(days); 1791 immutable negative = hnsecs < 0; 1792 1793 if (negative) 1794 hnsecs += convert!("hours", "hnsecs")(24); 1795 1796 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 1797 hnsecs = removeUnitsFromHNSecs!"minutes"(hnsecs); 1798 1799 hnsecs += convert!("hours", "hnsecs")(hour); 1800 hnsecs += convert!("minutes", "hnsecs")(minute); 1801 1802 if (negative) 1803 hnsecs -= convert!("hours", "hnsecs")(24); 1804 1805 adjTime = daysHNSecs + hnsecs; 1806 } 1807 1808 @safe unittest 1809 { 1810 import std.range : chain; 1811 1812 foreach (minute; testMinSecs) 1813 { 1814 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 1815 { 1816 auto dt = cast(DateTime) st; 1817 auto expected = SysTime(DateTime(dt.year, dt.month, dt.day, dt.hour, minute, dt.second), 1818 st.fracSecs, 1819 st.timezone); 1820 st.minute = minute; 1821 assert(st == expected, format("[%s] [%s]", st, expected)); 1822 } 1823 } 1824 1825 auto st = testSysTimesAD[0]; 1826 assertThrown!DateTimeException(st.minute = -1); 1827 assertThrown!DateTimeException(st.minute = 60); 1828 1829 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1830 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1831 static assert(!__traits(compiles, cst.minute = 27)); 1832 static assert(!__traits(compiles, ist.minute = 27)); 1833 1834 static void testScope(scope ref SysTime st) @safe 1835 { 1836 st.minute = 12; 1837 } 1838 } 1839 1840 1841 /++ 1842 Seconds past the current minute. 1843 +/ 1844 @property ubyte second() @safe const nothrow scope 1845 { 1846 auto hnsecs = adjTime; 1847 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 1848 1849 if (hnsecs < 0) 1850 { 1851 hnsecs += convert!("hours", "hnsecs")(24); 1852 --days; 1853 } 1854 1855 hnsecs = removeUnitsFromHNSecs!"hours"(hnsecs); 1856 hnsecs = removeUnitsFromHNSecs!"minutes"(hnsecs); 1857 1858 return cast(ubyte) getUnitsFromHNSecs!"seconds"(hnsecs); 1859 } 1860 1861 @safe unittest 1862 { 1863 import std.range : chain; 1864 1865 static void test(SysTime sysTime, int expected) 1866 { 1867 assert(sysTime.second == expected, format("Value given: %s", sysTime)); 1868 } 1869 1870 test(SysTime(0, UTC()), 0); 1871 test(SysTime(1, UTC()), 0); 1872 test(SysTime(-1, UTC()), 59); 1873 1874 foreach (tz; testTZs) 1875 { 1876 foreach (year; chain(testYearsBC, testYearsAD)) 1877 { 1878 foreach (md; testMonthDays) 1879 { 1880 foreach (hour; testHours) 1881 { 1882 foreach (minute; testMinSecs) 1883 { 1884 foreach (second; testMinSecs) 1885 { 1886 auto dt = DateTime(Date(year, md.month, md.day), TimeOfDay(hour, minute, second)); 1887 foreach (fs; testFracSecs) 1888 test(SysTime(dt, fs, tz), second); 1889 } 1890 } 1891 } 1892 } 1893 } 1894 } 1895 1896 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1897 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1898 assert(cst.second == 33); 1899 assert(ist.second == 33); 1900 1901 static void testScope(scope ref SysTime st) @safe 1902 { 1903 auto result = st.second; 1904 } 1905 } 1906 1907 1908 /++ 1909 Seconds past the current minute. 1910 1911 Params: 1912 second = The second to set this $(LREF SysTime)'s second to. 1913 1914 Throws: 1915 $(REF DateTimeException,std,datetime,date) if the given second are 1916 not a valid second of a minute. 1917 +/ 1918 @property void second(int second) @safe scope 1919 { 1920 enforceValid!"seconds"(second); 1921 1922 auto hnsecs = adjTime; 1923 auto days = splitUnitsFromHNSecs!"days"(hnsecs); 1924 immutable daysHNSecs = convert!("days", "hnsecs")(days); 1925 immutable negative = hnsecs < 0; 1926 1927 if (negative) 1928 hnsecs += convert!("hours", "hnsecs")(24); 1929 1930 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 1931 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 1932 hnsecs = removeUnitsFromHNSecs!"seconds"(hnsecs); 1933 1934 hnsecs += convert!("hours", "hnsecs")(hour); 1935 hnsecs += convert!("minutes", "hnsecs")(minute); 1936 hnsecs += convert!("seconds", "hnsecs")(second); 1937 1938 if (negative) 1939 hnsecs -= convert!("hours", "hnsecs")(24); 1940 1941 adjTime = daysHNSecs + hnsecs; 1942 } 1943 1944 @safe unittest 1945 { 1946 import std.range : chain; 1947 1948 foreach (second; testMinSecs) 1949 { 1950 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 1951 { 1952 auto dt = cast(DateTime) st; 1953 auto expected = SysTime(DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, second), 1954 st.fracSecs, 1955 st.timezone); 1956 st.second = second; 1957 assert(st == expected, format("[%s] [%s]", st, expected)); 1958 } 1959 } 1960 1961 auto st = testSysTimesAD[0]; 1962 assertThrown!DateTimeException(st.second = -1); 1963 assertThrown!DateTimeException(st.second = 60); 1964 1965 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1966 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1967 static assert(!__traits(compiles, cst.seconds = 27)); 1968 static assert(!__traits(compiles, ist.seconds = 27)); 1969 1970 static void testScope(scope ref SysTime st) @safe 1971 { 1972 st.second = 12; 1973 } 1974 } 1975 1976 1977 /++ 1978 Fractional seconds past the second (i.e. the portion of a 1979 $(LREF SysTime) which is less than a second). 1980 +/ 1981 @property Duration fracSecs() @safe const nothrow scope 1982 { 1983 auto hnsecs = removeUnitsFromHNSecs!"days"(adjTime); 1984 1985 if (hnsecs < 0) 1986 hnsecs += convert!("hours", "hnsecs")(24); 1987 1988 return dur!"hnsecs"(removeUnitsFromHNSecs!"seconds"(hnsecs)); 1989 } 1990 1991 /// 1992 @safe unittest 1993 { 1994 import core.time : msecs, usecs, hnsecs, nsecs; 1995 import std.datetime.date : DateTime; 1996 1997 auto dt = DateTime(1982, 4, 1, 20, 59, 22); 1998 assert(SysTime(dt, msecs(213)).fracSecs == msecs(213)); 1999 assert(SysTime(dt, usecs(5202)).fracSecs == usecs(5202)); 2000 assert(SysTime(dt, hnsecs(1234567)).fracSecs == hnsecs(1234567)); 2001 2002 // SysTime and Duration both have a precision of hnsecs (100 ns), 2003 // so nsecs are going to be truncated. 2004 assert(SysTime(dt, nsecs(123456789)).fracSecs == nsecs(123456700)); 2005 } 2006 2007 @safe unittest 2008 { 2009 import std.range : chain; 2010 import core.time; 2011 2012 assert(SysTime(0, UTC()).fracSecs == Duration.zero); 2013 assert(SysTime(1, UTC()).fracSecs == hnsecs(1)); 2014 assert(SysTime(-1, UTC()).fracSecs == hnsecs(9_999_999)); 2015 2016 foreach (tz; testTZs) 2017 { 2018 foreach (year; chain(testYearsBC, testYearsAD)) 2019 { 2020 foreach (md; testMonthDays) 2021 { 2022 foreach (hour; testHours) 2023 { 2024 foreach (minute; testMinSecs) 2025 { 2026 foreach (second; testMinSecs) 2027 { 2028 auto dt = DateTime(Date(year, md.month, md.day), TimeOfDay(hour, minute, second)); 2029 foreach (fs; testFracSecs) 2030 assert(SysTime(dt, fs, tz).fracSecs == fs); 2031 } 2032 } 2033 } 2034 } 2035 } 2036 } 2037 2038 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 2039 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 2040 assert(cst.fracSecs == Duration.zero); 2041 assert(ist.fracSecs == Duration.zero); 2042 2043 static void testScope(scope ref SysTime st) @safe 2044 { 2045 auto result = st.fracSecs; 2046 } 2047 } 2048 2049 2050 /++ 2051 Fractional seconds past the second (i.e. the portion of a 2052 $(LREF SysTime) which is less than a second). 2053 2054 Params: 2055 fracSecs = The duration to set this $(LREF SysTime)'s fractional 2056 seconds to. 2057 2058 Throws: 2059 $(REF DateTimeException,std,datetime,date) if the given duration 2060 is negative or if it's greater than or equal to one second. 2061 +/ 2062 @property void fracSecs(Duration fracSecs) @safe scope 2063 { 2064 enforce(fracSecs >= Duration.zero, new DateTimeException("A SysTime cannot have negative fractional seconds.")); 2065 enforce(fracSecs < seconds(1), new DateTimeException("Fractional seconds must be less than one second.")); 2066 2067 auto oldHNSecs = adjTime; 2068 auto days = splitUnitsFromHNSecs!"days"(oldHNSecs); 2069 immutable daysHNSecs = convert!("days", "hnsecs")(days); 2070 immutable negative = oldHNSecs < 0; 2071 2072 if (negative) 2073 oldHNSecs += convert!("hours", "hnsecs")(24); 2074 2075 immutable seconds = splitUnitsFromHNSecs!"seconds"(oldHNSecs); 2076 immutable secondsHNSecs = convert!("seconds", "hnsecs")(seconds); 2077 auto newHNSecs = fracSecs.total!"hnsecs" + secondsHNSecs; 2078 2079 if (negative) 2080 newHNSecs -= convert!("hours", "hnsecs")(24); 2081 2082 adjTime = daysHNSecs + newHNSecs; 2083 } 2084 2085 /// 2086 @safe unittest 2087 { 2088 import core.time : Duration, msecs, hnsecs, nsecs; 2089 import std.datetime.date : DateTime; 2090 2091 auto st = SysTime(DateTime(1982, 4, 1, 20, 59, 22)); 2092 assert(st.fracSecs == Duration.zero); 2093 2094 st.fracSecs = msecs(213); 2095 assert(st.fracSecs == msecs(213)); 2096 2097 st.fracSecs = hnsecs(1234567); 2098 assert(st.fracSecs == hnsecs(1234567)); 2099 2100 // SysTime has a precision of hnsecs (100 ns), so nsecs are 2101 // going to be truncated. 2102 st.fracSecs = nsecs(123456789); 2103 assert(st.fracSecs == hnsecs(1234567)); 2104 } 2105 2106 @safe unittest 2107 { 2108 import std.range : chain; 2109 import core.time; 2110 2111 foreach (fracSec; testFracSecs) 2112 { 2113 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 2114 { 2115 auto dt = cast(DateTime) st; 2116 auto expected = SysTime(dt, fracSec, st.timezone); 2117 st.fracSecs = fracSec; 2118 assert(st == expected, format("[%s] [%s]", st, expected)); 2119 } 2120 } 2121 2122 auto st = testSysTimesAD[0]; 2123 assertThrown!DateTimeException(st.fracSecs = hnsecs(-1)); 2124 assertThrown!DateTimeException(st.fracSecs = seconds(1)); 2125 2126 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 2127 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 2128 static assert(!__traits(compiles, cst.fracSecs = msecs(7))); 2129 static assert(!__traits(compiles, ist.fracSecs = msecs(7))); 2130 2131 static void testScope(scope ref SysTime st) @safe 2132 { 2133 st.fracSecs = Duration.zero; 2134 } 2135 } 2136 2137 2138 /++ 2139 The total hnsecs from midnight, January 1st, 1 A.D. UTC. This is the 2140 internal representation of $(LREF SysTime). 2141 +/ 2142 @property long stdTime() @safe const pure nothrow scope @nogc 2143 { 2144 return _stdTime; 2145 } 2146 2147 @safe unittest 2148 { 2149 import core.time; 2150 assert(SysTime(0).stdTime == 0); 2151 assert(SysTime(1).stdTime == 1); 2152 assert(SysTime(-1).stdTime == -1); 2153 assert(SysTime(DateTime(1, 1, 1, 0, 0, 33), hnsecs(502), UTC()).stdTime == 330_000_502L); 2154 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 0), UTC()).stdTime == 621_355_968_000_000_000L); 2155 2156 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 2157 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 2158 assert(cst.stdTime > 0); 2159 assert(ist.stdTime > 0); 2160 2161 static void testScope(scope ref SysTime st) @safe 2162 { 2163 auto result = st.stdTime; 2164 } 2165 } 2166 2167 2168 /++ 2169 The total hnsecs from midnight, January 1st, 1 A.D. UTC. This is the 2170 internal representation of $(LREF SysTime). 2171 2172 Params: 2173 stdTime = The number of hnsecs since January 1st, 1 A.D. UTC. 2174 +/ 2175 @property void stdTime(long stdTime) @safe pure nothrow scope 2176 { 2177 _stdTime = stdTime; 2178 } 2179 2180 @safe unittest 2181 { 2182 import core.time; 2183 static void test(long stdTime, SysTime expected, size_t line = __LINE__) 2184 { 2185 auto st = SysTime(0, UTC()); 2186 st.stdTime = stdTime; 2187 assert(st == expected); 2188 } 2189 2190 test(0, SysTime(Date(1, 1, 1), UTC())); 2191 test(1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC())); 2192 test(-1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC())); 2193 test(330_000_502L, SysTime(DateTime(1, 1, 1, 0, 0, 33), hnsecs(502), UTC())); 2194 test(621_355_968_000_000_000L, SysTime(DateTime(1970, 1, 1, 0, 0, 0), UTC())); 2195 2196 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 2197 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 2198 static assert(!__traits(compiles, cst.stdTime = 27)); 2199 static assert(!__traits(compiles, ist.stdTime = 27)); 2200 2201 static void testScope(scope ref SysTime st) @safe 2202 { 2203 st.stdTime = 42; 2204 } 2205 } 2206 2207 2208 /++ 2209 The current time zone of this $(LREF SysTime). Its internal time is 2210 always kept in UTC, so there are no conversion issues between time zones 2211 due to DST. Functions which return all or part of the time - such as 2212 hours - adjust the time to this $(LREF SysTime)'s time zone before 2213 returning. 2214 +/ 2215 @property immutable(TimeZone) timezone() @safe const pure nothrow return scope 2216 { 2217 return _timezone; 2218 } 2219 2220 @safe unittest 2221 { 2222 assert(SysTime.init.timezone is InitTimeZone()); 2223 assert(SysTime(DateTime.init, UTC()).timezone is UTC()); 2224 2225 static void testScope(scope ref SysTime st) @safe 2226 { 2227 auto result = st.timezone; 2228 } 2229 } 2230 2231 2232 /++ 2233 The current time zone of this $(LREF SysTime). It's internal time is 2234 always kept in UTC, so there are no conversion issues between time zones 2235 due to DST. Functions which return all or part of the time - such as 2236 hours - adjust the time to this $(LREF SysTime)'s time zone before 2237 returning. 2238 2239 Params: 2240 timezone = The $(REF _TimeZone,std,datetime,_timezone) to set this 2241 $(LREF SysTime)'s time zone to. 2242 +/ 2243 @property void timezone(immutable TimeZone timezone) @safe pure nothrow scope 2244 { 2245 if (timezone is null) 2246 _timezone = LocalTime(); 2247 else 2248 _timezone = timezone; 2249 } 2250 2251 @safe unittest 2252 { 2253 SysTime st; 2254 st.timezone = null; 2255 assert(st.timezone is LocalTime()); 2256 st.timezone = UTC(); 2257 assert(st.timezone is UTC()); 2258 2259 static void testScope(scope ref SysTime st) @safe 2260 { 2261 st.timezone = UTC(); 2262 } 2263 } 2264 2265 2266 /++ 2267 Returns whether DST is in effect for this $(LREF SysTime). 2268 +/ 2269 @property bool dstInEffect() @safe const nothrow return scope 2270 { 2271 return _timezone.dstInEffect(_stdTime); 2272 } 2273 2274 // This function's full unit testing is done in the time zone classes, but 2275 // this verifies that SysTime.init works correctly, since historically, it 2276 // has segfaulted due to a null _timezone. 2277 @safe unittest 2278 { 2279 assert(!SysTime.init.dstInEffect); 2280 2281 static void testScope(scope ref SysTime st) @safe 2282 { 2283 auto result = st.dstInEffect; 2284 } 2285 } 2286 2287 2288 /++ 2289 Returns what the offset from UTC is for this $(LREF SysTime). 2290 It includes the DST offset in effect at that time (if any). 2291 +/ 2292 @property Duration utcOffset() @safe const nothrow return scope 2293 { 2294 return _timezone.utcOffsetAt(_stdTime); 2295 } 2296 2297 // This function's full unit testing is done in the time zone classes, but 2298 // this verifies that SysTime.init works correctly, since historically, it 2299 // has segfaulted due to a null _timezone. 2300 @safe unittest 2301 { 2302 assert(SysTime.init.utcOffset == Duration.zero); 2303 2304 static void testScope(scope ref SysTime st) @safe 2305 { 2306 auto result = st.utcOffset; 2307 } 2308 } 2309 2310 2311 /++ 2312 Returns a $(LREF SysTime) with the same std time as this one, but with 2313 $(REF LocalTime,std,datetime,timezone) as its time zone. 2314 +/ 2315 SysTime toLocalTime() @safe const pure nothrow scope 2316 { 2317 return SysTime(_stdTime, LocalTime()); 2318 } 2319 2320 @safe unittest 2321 { 2322 import core.time; 2323 { 2324 auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), hnsecs(27)); 2325 assert(sysTime == sysTime.toLocalTime()); 2326 assert(sysTime._stdTime == sysTime.toLocalTime()._stdTime); 2327 assert(sysTime.toLocalTime().timezone is LocalTime()); 2328 assert(sysTime.toLocalTime().timezone is sysTime.timezone); 2329 assert(sysTime.toLocalTime().timezone !is UTC()); 2330 } 2331 2332 { 2333 auto stz = new immutable SimpleTimeZone(dur!"minutes"(-3 * 60)); 2334 auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), hnsecs(27), stz); 2335 assert(sysTime == sysTime.toLocalTime()); 2336 assert(sysTime._stdTime == sysTime.toLocalTime()._stdTime); 2337 assert(sysTime.toLocalTime().timezone is LocalTime()); 2338 assert(sysTime.toLocalTime().timezone !is UTC()); 2339 assert(sysTime.toLocalTime().timezone !is stz); 2340 } 2341 2342 static void testScope(scope ref SysTime st) @safe 2343 { 2344 auto result = st.toLocalTime(); 2345 } 2346 } 2347 2348 2349 /++ 2350 Returns a $(LREF SysTime) with the same std time as this one, but with 2351 `UTC` as its time zone. 2352 +/ 2353 SysTime toUTC() @safe const pure nothrow scope 2354 { 2355 return SysTime(_stdTime, UTC()); 2356 } 2357 2358 @safe unittest 2359 { 2360 import core.time; 2361 auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), hnsecs(27)); 2362 assert(sysTime == sysTime.toUTC()); 2363 assert(sysTime._stdTime == sysTime.toUTC()._stdTime); 2364 assert(sysTime.toUTC().timezone is UTC()); 2365 assert(sysTime.toUTC().timezone !is LocalTime()); 2366 assert(sysTime.toUTC().timezone !is sysTime.timezone); 2367 2368 static void testScope(scope ref SysTime st) @safe 2369 { 2370 auto result = st.toUTC(); 2371 } 2372 } 2373 2374 2375 /++ 2376 Returns a $(LREF SysTime) with the same std time as this one, but with 2377 given time zone as its time zone. 2378 +/ 2379 SysTime toOtherTZ(immutable TimeZone tz) @safe const pure nothrow scope 2380 { 2381 if (tz is null) 2382 return SysTime(_stdTime, LocalTime()); 2383 else 2384 return SysTime(_stdTime, tz); 2385 } 2386 2387 @safe unittest 2388 { 2389 import core.time; 2390 auto stz = new immutable SimpleTimeZone(dur!"minutes"(11 * 60)); 2391 auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), hnsecs(27)); 2392 assert(sysTime == sysTime.toOtherTZ(stz)); 2393 assert(sysTime._stdTime == sysTime.toOtherTZ(stz)._stdTime); 2394 assert(sysTime.toOtherTZ(stz).timezone is stz); 2395 assert(sysTime.toOtherTZ(stz).timezone !is LocalTime()); 2396 assert(sysTime.toOtherTZ(stz).timezone !is UTC()); 2397 assert(sysTime.toOtherTZ(null).timezone is LocalTime()); 2398 2399 static void testScope(scope ref SysTime st) @safe 2400 { 2401 auto result = st.toOtherTZ(null); 2402 } 2403 } 2404 2405 2406 /++ 2407 Converts this $(LREF SysTime) to unix time (i.e. seconds from midnight, 2408 January 1st, 1970 in UTC). 2409 2410 The C standard does not specify the representation of time_t, so it is 2411 implementation defined. On POSIX systems, unix time is equivalent to 2412 time_t, but that's not necessarily true on other systems (e.g. it is 2413 not true for the Digital Mars C runtime). So, be careful when using unix 2414 time with C functions on non-POSIX systems. 2415 2416 By default, the return type is time_t (which is normally an alias for 2417 int on 32-bit systems and long on 64-bit systems), but if a different 2418 size is required than either int or long can be passed as a template 2419 argument to get the desired size. 2420 2421 If the return type is int, and the result can't fit in an int, then the 2422 closest value that can be held in 32 bits will be used (so `int.max` 2423 if it goes over and `int.min` if it goes under). However, no attempt 2424 is made to deal with integer overflow if the return type is long. 2425 2426 Params: 2427 T = The return type (int or long). It defaults to time_t, which is 2428 normally 32 bits on a 32-bit system and 64 bits on a 64-bit 2429 system. 2430 2431 Returns: 2432 A signed integer representing the unix time which is equivalent to 2433 this SysTime. 2434 +/ 2435 T toUnixTime(T = time_t)() @safe const pure nothrow scope 2436 if (is(T == int) || is(T == long)) 2437 { 2438 return stdTimeToUnixTime!T(_stdTime); 2439 } 2440 2441 /// 2442 @safe unittest 2443 { 2444 import core.time : hours; 2445 import std.datetime.date : DateTime; 2446 import std.datetime.timezone : SimpleTimeZone, UTC; 2447 2448 assert(SysTime(DateTime(1970, 1, 1), UTC()).toUnixTime() == 0); 2449 2450 auto pst = new immutable SimpleTimeZone(hours(-8)); 2451 assert(SysTime(DateTime(1970, 1, 1), pst).toUnixTime() == 28800); 2452 2453 auto utc = SysTime(DateTime(2007, 12, 22, 8, 14, 45), UTC()); 2454 assert(utc.toUnixTime() == 1_198_311_285); 2455 2456 auto ca = SysTime(DateTime(2007, 12, 22, 8, 14, 45), pst); 2457 assert(ca.toUnixTime() == 1_198_340_085); 2458 2459 static void testScope(scope ref SysTime st) @safe 2460 { 2461 auto result = st.toUnixTime(); 2462 } 2463 } 2464 2465 @safe unittest 2466 { 2467 import std.meta : AliasSeq; 2468 import core.time; 2469 assert(SysTime(DateTime(1970, 1, 1), UTC()).toUnixTime() == 0); 2470 static foreach (units; ["hnsecs", "usecs", "msecs"]) 2471 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 0), dur!units(1), UTC()).toUnixTime() == 0); 2472 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), UTC()).toUnixTime() == 1); 2473 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toUnixTime() == 0); 2474 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999_999), UTC()).toUnixTime() == 0); 2475 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), msecs(999), UTC()).toUnixTime() == 0); 2476 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), UTC()).toUnixTime() == -1); 2477 } 2478 2479 2480 /++ 2481 Converts from unix time (i.e. seconds from midnight, January 1st, 1970 2482 in UTC) to a $(LREF SysTime). 2483 2484 The C standard does not specify the representation of time_t, so it is 2485 implementation defined. On POSIX systems, unix time is equivalent to 2486 time_t, but that's not necessarily true on other systems (e.g. it is 2487 not true for the Digital Mars C runtime). So, be careful when using unix 2488 time with C functions on non-POSIX systems. 2489 2490 Params: 2491 unixTime = Seconds from midnight, January 1st, 1970 in UTC. 2492 tz = The time zone for the SysTime that's returned. 2493 +/ 2494 static SysTime fromUnixTime(long unixTime, immutable TimeZone tz = LocalTime()) @safe pure nothrow 2495 { 2496 return SysTime(unixTimeToStdTime(unixTime), tz); 2497 } 2498 2499 /// 2500 @safe unittest 2501 { 2502 import core.time : hours; 2503 import std.datetime.date : DateTime; 2504 import std.datetime.timezone : SimpleTimeZone, UTC; 2505 2506 assert(SysTime.fromUnixTime(0) == 2507 SysTime(DateTime(1970, 1, 1), UTC())); 2508 2509 auto pst = new immutable SimpleTimeZone(hours(-8)); 2510 assert(SysTime.fromUnixTime(28800) == 2511 SysTime(DateTime(1970, 1, 1), pst)); 2512 2513 auto st1 = SysTime.fromUnixTime(1_198_311_285, UTC()); 2514 assert(st1 == SysTime(DateTime(2007, 12, 22, 8, 14, 45), UTC())); 2515 assert(st1.timezone is UTC()); 2516 assert(st1 == SysTime(DateTime(2007, 12, 22, 0, 14, 45), pst)); 2517 2518 auto st2 = SysTime.fromUnixTime(1_198_311_285, pst); 2519 assert(st2 == SysTime(DateTime(2007, 12, 22, 8, 14, 45), UTC())); 2520 assert(st2.timezone is pst); 2521 assert(st2 == SysTime(DateTime(2007, 12, 22, 0, 14, 45), pst)); 2522 } 2523 2524 @safe unittest 2525 { 2526 import core.time; 2527 assert(SysTime.fromUnixTime(0) == SysTime(DateTime(1970, 1, 1), UTC())); 2528 assert(SysTime.fromUnixTime(1) == SysTime(DateTime(1970, 1, 1, 0, 0, 1), UTC())); 2529 assert(SysTime.fromUnixTime(-1) == SysTime(DateTime(1969, 12, 31, 23, 59, 59), UTC())); 2530 2531 auto st = SysTime.fromUnixTime(0); 2532 auto dt = cast(DateTime) st; 2533 assert(dt <= DateTime(1970, 2, 1) && dt >= DateTime(1969, 12, 31)); 2534 assert(st.timezone is LocalTime()); 2535 2536 auto aest = new immutable SimpleTimeZone(hours(10)); 2537 assert(SysTime.fromUnixTime(-36000) == SysTime(DateTime(1970, 1, 1), aest)); 2538 } 2539 2540 2541 /++ 2542 Returns a `timeval` which represents this $(LREF SysTime). 2543 2544 Note that like all conversions in std.datetime, this is a truncating 2545 conversion. 2546 2547 If `timeval.tv_sec` is int, and the result can't fit in an int, then 2548 the closest value that can be held in 32 bits will be used for 2549 `tv_sec`. (so `int.max` if it goes over and `int.min` if it 2550 goes under). 2551 +/ 2552 timeval toTimeVal() @safe const pure nothrow scope 2553 { 2554 immutable tv_sec = toUnixTime!(typeof(timeval.tv_sec))(); 2555 immutable fracHNSecs = removeUnitsFromHNSecs!"seconds"(_stdTime - 621_355_968_000_000_000L); 2556 immutable tv_usec = cast(typeof(timeval.tv_usec))convert!("hnsecs", "usecs")(fracHNSecs); 2557 return timeval(tv_sec, tv_usec); 2558 } 2559 2560 @safe unittest 2561 { 2562 import core.time; 2563 assert(SysTime(DateTime(1970, 1, 1), UTC()).toTimeVal() == timeval(0, 0)); 2564 assert(SysTime(DateTime(1970, 1, 1), hnsecs(9), UTC()).toTimeVal() == timeval(0, 0)); 2565 assert(SysTime(DateTime(1970, 1, 1), hnsecs(10), UTC()).toTimeVal() == timeval(0, 1)); 2566 assert(SysTime(DateTime(1970, 1, 1), usecs(7), UTC()).toTimeVal() == timeval(0, 7)); 2567 2568 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), UTC()).toTimeVal() == timeval(1, 0)); 2569 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), hnsecs(9), UTC()).toTimeVal() == timeval(1, 0)); 2570 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), hnsecs(10), UTC()).toTimeVal() == timeval(1, 1)); 2571 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), usecs(7), UTC()).toTimeVal() == timeval(1, 7)); 2572 2573 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toTimeVal() == timeval(0, 0)); 2574 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_990), UTC()).toTimeVal() == timeval(0, -1)); 2575 2576 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999_999), UTC()).toTimeVal() == timeval(0, -1)); 2577 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999), UTC()).toTimeVal() == timeval(0, -999_001)); 2578 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), msecs(999), UTC()).toTimeVal() == timeval(0, -1000)); 2579 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), UTC()).toTimeVal() == timeval(-1, 0)); 2580 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 58), usecs(17), UTC()).toTimeVal() == timeval(-1, -999_983)); 2581 2582 static void testScope(scope ref SysTime st) @safe 2583 { 2584 auto result = st.toTimeVal(); 2585 } 2586 } 2587 2588 2589 version (StdDdoc) 2590 { 2591 version (Windows) private struct timespec {} 2592 /++ 2593 Returns a `timespec` which represents this $(LREF SysTime). 2594 2595 $(BLUE This function is Posix-Only.) 2596 +/ 2597 timespec toTimeSpec() @safe const pure nothrow scope; 2598 } 2599 else version (Posix) 2600 { 2601 timespec toTimeSpec() @safe const pure nothrow scope 2602 { 2603 immutable tv_sec = toUnixTime!(typeof(timespec.tv_sec))(); 2604 immutable fracHNSecs = removeUnitsFromHNSecs!"seconds"(_stdTime - 621_355_968_000_000_000L); 2605 immutable tv_nsec = cast(typeof(timespec.tv_nsec))convert!("hnsecs", "nsecs")(fracHNSecs); 2606 return timespec(tv_sec, tv_nsec); 2607 } 2608 2609 @safe unittest 2610 { 2611 import core.time; 2612 assert(SysTime(DateTime(1970, 1, 1), UTC()).toTimeSpec() == timespec(0, 0)); 2613 assert(SysTime(DateTime(1970, 1, 1), hnsecs(9), UTC()).toTimeSpec() == timespec(0, 900)); 2614 assert(SysTime(DateTime(1970, 1, 1), hnsecs(10), UTC()).toTimeSpec() == timespec(0, 1000)); 2615 assert(SysTime(DateTime(1970, 1, 1), usecs(7), UTC()).toTimeSpec() == timespec(0, 7000)); 2616 2617 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), UTC()).toTimeSpec() == timespec(1, 0)); 2618 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), hnsecs(9), UTC()).toTimeSpec() == timespec(1, 900)); 2619 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), hnsecs(10), UTC()).toTimeSpec() == timespec(1, 1000)); 2620 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), usecs(7), UTC()).toTimeSpec() == timespec(1, 7000)); 2621 2622 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toTimeSpec() == 2623 timespec(0, -100)); 2624 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_990), UTC()).toTimeSpec() == 2625 timespec(0, -1000)); 2626 2627 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999_999), UTC()).toTimeSpec() == 2628 timespec(0, -1_000)); 2629 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999), UTC()).toTimeSpec() == 2630 timespec(0, -999_001_000)); 2631 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), msecs(999), UTC()).toTimeSpec() == 2632 timespec(0, -1_000_000)); 2633 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), UTC()).toTimeSpec() == 2634 timespec(-1, 0)); 2635 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 58), usecs(17), UTC()).toTimeSpec() == 2636 timespec(-1, -999_983_000)); 2637 2638 static void testScope(scope ref SysTime st) @safe 2639 { 2640 auto result = st.toTimeSpec(); 2641 } 2642 } 2643 } 2644 2645 /++ 2646 Returns a `tm` which represents this $(LREF SysTime). 2647 +/ 2648 tm toTM() @safe const nothrow scope 2649 { 2650 auto dateTime = cast(DateTime) this; 2651 tm timeInfo; 2652 2653 timeInfo.tm_sec = dateTime.second; 2654 timeInfo.tm_min = dateTime.minute; 2655 timeInfo.tm_hour = dateTime.hour; 2656 timeInfo.tm_mday = dateTime.day; 2657 timeInfo.tm_mon = dateTime.month - 1; 2658 timeInfo.tm_year = dateTime.year - 1900; 2659 timeInfo.tm_wday = dateTime.dayOfWeek; 2660 timeInfo.tm_yday = dateTime.dayOfYear - 1; 2661 timeInfo.tm_isdst = _timezone.dstInEffect(_stdTime); 2662 2663 version (Posix) 2664 { 2665 import std.utf : toUTFz; 2666 timeInfo.tm_gmtoff = cast(int) convert!("hnsecs", "seconds")(adjTime - _stdTime); 2667 auto zone = timeInfo.tm_isdst ? _timezone.dstName : _timezone.stdName; 2668 timeInfo.tm_zone = zone.toUTFz!(char*)(); 2669 } 2670 2671 return timeInfo; 2672 } 2673 2674 @system unittest 2675 { 2676 import std.conv : to; 2677 import core.time; 2678 2679 version (Posix) 2680 { 2681 import std.datetime.timezone : clearTZEnvVar, setTZEnvVar; 2682 setTZEnvVar("America/Los_Angeles"); 2683 scope(exit) clearTZEnvVar(); 2684 } 2685 2686 { 2687 auto timeInfo = SysTime(DateTime(1970, 1, 1)).toTM(); 2688 2689 assert(timeInfo.tm_sec == 0); 2690 assert(timeInfo.tm_min == 0); 2691 assert(timeInfo.tm_hour == 0); 2692 assert(timeInfo.tm_mday == 1); 2693 assert(timeInfo.tm_mon == 0); 2694 assert(timeInfo.tm_year == 70); 2695 assert(timeInfo.tm_wday == 4); 2696 assert(timeInfo.tm_yday == 0); 2697 2698 version (Posix) 2699 assert(timeInfo.tm_isdst == 0); 2700 else version (Windows) 2701 assert(timeInfo.tm_isdst == 0 || timeInfo.tm_isdst == 1); 2702 2703 version (Posix) 2704 { 2705 assert(timeInfo.tm_gmtoff == -8 * 60 * 60); 2706 assert(to!string(timeInfo.tm_zone) == "PST"); 2707 } 2708 } 2709 2710 { 2711 auto timeInfo = SysTime(DateTime(2010, 7, 4, 12, 15, 7), hnsecs(15)).toTM(); 2712 2713 assert(timeInfo.tm_sec == 7); 2714 assert(timeInfo.tm_min == 15); 2715 assert(timeInfo.tm_hour == 12); 2716 assert(timeInfo.tm_mday == 4); 2717 assert(timeInfo.tm_mon == 6); 2718 assert(timeInfo.tm_year == 110); 2719 assert(timeInfo.tm_wday == 0); 2720 assert(timeInfo.tm_yday == 184); 2721 2722 version (Posix) 2723 assert(timeInfo.tm_isdst == 1); 2724 else version (Windows) 2725 assert(timeInfo.tm_isdst == 0 || timeInfo.tm_isdst == 1); 2726 2727 version (Posix) 2728 { 2729 assert(timeInfo.tm_gmtoff == -7 * 60 * 60); 2730 assert(to!string(timeInfo.tm_zone) == "PDT"); 2731 } 2732 } 2733 2734 // This is more to verify that SysTime.init.toTM() doesn't segfault and 2735 // does something sane rather than that the value is anything 2736 // particularly useful. 2737 { 2738 auto timeInfo = SysTime.init.toTM(); 2739 2740 assert(timeInfo.tm_sec == 0); 2741 assert(timeInfo.tm_min == 0); 2742 assert(timeInfo.tm_hour == 0); 2743 assert(timeInfo.tm_mday == 1); 2744 assert(timeInfo.tm_mon == 0); 2745 assert(timeInfo.tm_year == -1899); 2746 assert(timeInfo.tm_wday == 1); 2747 assert(timeInfo.tm_yday == 0); 2748 assert(timeInfo.tm_isdst == 0); 2749 2750 version (Posix) 2751 { 2752 assert(timeInfo.tm_gmtoff == 0); 2753 assert(to!string(timeInfo.tm_zone) == "SysTime.init's timezone"); 2754 } 2755 } 2756 2757 static void testScope(scope ref SysTime st) @safe 2758 { 2759 auto result = st.toTM(); 2760 } 2761 } 2762 2763 2764 /++ 2765 Adds the given number of years or months to this $(LREF SysTime). A 2766 negative number will subtract. 2767 2768 Note that if day overflow is allowed, and the date with the adjusted 2769 year/month overflows the number of days in the new month, then the month 2770 will be incremented by one, and the day set to the number of days 2771 overflowed. (e.g. if the day were 31 and the new month were June, then 2772 the month would be incremented to July, and the new day would be 1). If 2773 day overflow is not allowed, then the day will be set to the last valid 2774 day in the month (e.g. June 31st would become June 30th). 2775 2776 Params: 2777 units = The type of units to add ("years" or "months"). 2778 value = The number of months or years to add to this 2779 $(LREF SysTime). 2780 allowOverflow = Whether the days should be allowed to overflow, 2781 causing the month to increment. 2782 +/ 2783 ref SysTime add(string units)(long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe nothrow scope 2784 if (units == "years" || units == "months") 2785 { 2786 auto hnsecs = adjTime; 2787 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 2788 2789 if (hnsecs < 0) 2790 { 2791 hnsecs += convert!("hours", "hnsecs")(24); 2792 --days; 2793 } 2794 2795 auto date = Date(cast(int) days); 2796 date.add!units(value, allowOverflow); 2797 days = date.dayOfGregorianCal - 1; 2798 2799 if (days < 0) 2800 { 2801 hnsecs -= convert!("hours", "hnsecs")(24); 2802 ++days; 2803 } 2804 2805 immutable newDaysHNSecs = convert!("days", "hnsecs")(days); 2806 2807 adjTime = newDaysHNSecs + hnsecs; 2808 2809 return this; 2810 } 2811 2812 @safe unittest 2813 { 2814 auto st1 = SysTime(DateTime(2010, 1, 1, 12, 30, 33)); 2815 st1.add!"months"(11); 2816 assert(st1 == SysTime(DateTime(2010, 12, 1, 12, 30, 33))); 2817 2818 auto st2 = SysTime(DateTime(2010, 1, 1, 12, 30, 33)); 2819 st2.add!"months"(-11); 2820 assert(st2 == SysTime(DateTime(2009, 2, 1, 12, 30, 33))); 2821 2822 auto st3 = SysTime(DateTime(2000, 2, 29, 12, 30, 33)); 2823 st3.add!"years"(1); 2824 assert(st3 == SysTime(DateTime(2001, 3, 1, 12, 30, 33))); 2825 2826 auto st4 = SysTime(DateTime(2000, 2, 29, 12, 30, 33)); 2827 st4.add!"years"(1, AllowDayOverflow.no); 2828 assert(st4 == SysTime(DateTime(2001, 2, 28, 12, 30, 33))); 2829 } 2830 2831 // Test add!"years"() with AllowDayOverflow.yes 2832 @safe unittest 2833 { 2834 import core.time; 2835 // Test A.D. 2836 { 2837 auto sysTime = SysTime(Date(1999, 7, 6)); 2838 sysTime.add!"years"(7); 2839 assert(sysTime == SysTime(Date(2006, 7, 6))); 2840 sysTime.add!"years"(-9); 2841 assert(sysTime == SysTime(Date(1997, 7, 6))); 2842 } 2843 2844 { 2845 auto sysTime = SysTime(Date(1999, 2, 28)); 2846 sysTime.add!"years"(1); 2847 assert(sysTime == SysTime(Date(2000, 2, 28))); 2848 } 2849 2850 { 2851 auto sysTime = SysTime(Date(2000, 2, 29)); 2852 sysTime.add!"years"(-1); 2853 assert(sysTime == SysTime(Date(1999, 3, 1))); 2854 } 2855 2856 { 2857 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 7, 3), msecs(234)); 2858 sysTime.add!"years"(7); 2859 assert(sysTime == SysTime(DateTime(2006, 7, 6, 12, 7, 3), msecs(234))); 2860 sysTime.add!"years"(-9); 2861 assert(sysTime == SysTime(DateTime(1997, 7, 6, 12, 7, 3), msecs(234))); 2862 } 2863 2864 { 2865 auto sysTime = SysTime(DateTime(1999, 2, 28, 0, 7, 2), usecs(1207)); 2866 sysTime.add!"years"(1); 2867 assert(sysTime == SysTime(DateTime(2000, 2, 28, 0, 7, 2), usecs(1207))); 2868 } 2869 2870 { 2871 auto sysTime = SysTime(DateTime(2000, 2, 29, 0, 7, 2), usecs(1207)); 2872 sysTime.add!"years"(-1); 2873 assert(sysTime == SysTime(DateTime(1999, 3, 1, 0, 7, 2), usecs(1207))); 2874 } 2875 2876 // Test B.C. 2877 { 2878 auto sysTime = SysTime(Date(-1999, 7, 6)); 2879 sysTime.add!"years"(-7); 2880 assert(sysTime == SysTime(Date(-2006, 7, 6))); 2881 sysTime.add!"years"(9); 2882 assert(sysTime == SysTime(Date(-1997, 7, 6))); 2883 } 2884 2885 { 2886 auto sysTime = SysTime(Date(-1999, 2, 28)); 2887 sysTime.add!"years"(-1); 2888 assert(sysTime == SysTime(Date(-2000, 2, 28))); 2889 } 2890 2891 { 2892 auto sysTime = SysTime(Date(-2000, 2, 29)); 2893 sysTime.add!"years"(1); 2894 assert(sysTime == SysTime(Date(-1999, 3, 1))); 2895 } 2896 2897 { 2898 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 7, 3), msecs(234)); 2899 sysTime.add!"years"(-7); 2900 assert(sysTime == SysTime(DateTime(-2006, 7, 6, 12, 7, 3), msecs(234))); 2901 sysTime.add!"years"(9); 2902 assert(sysTime == SysTime(DateTime(-1997, 7, 6, 12, 7, 3), msecs(234))); 2903 } 2904 2905 { 2906 auto sysTime = SysTime(DateTime(-1999, 2, 28, 3, 3, 3), hnsecs(3)); 2907 sysTime.add!"years"(-1); 2908 assert(sysTime == SysTime(DateTime(-2000, 2, 28, 3, 3, 3), hnsecs(3))); 2909 } 2910 2911 { 2912 auto sysTime = SysTime(DateTime(-2000, 2, 29, 3, 3, 3), hnsecs(3)); 2913 sysTime.add!"years"(1); 2914 assert(sysTime == SysTime(DateTime(-1999, 3, 1, 3, 3, 3), hnsecs(3))); 2915 } 2916 2917 // Test Both 2918 { 2919 auto sysTime = SysTime(Date(4, 7, 6)); 2920 sysTime.add!"years"(-5); 2921 assert(sysTime == SysTime(Date(-1, 7, 6))); 2922 sysTime.add!"years"(5); 2923 assert(sysTime == SysTime(Date(4, 7, 6))); 2924 } 2925 2926 { 2927 auto sysTime = SysTime(Date(-4, 7, 6)); 2928 sysTime.add!"years"(5); 2929 assert(sysTime == SysTime(Date(1, 7, 6))); 2930 sysTime.add!"years"(-5); 2931 assert(sysTime == SysTime(Date(-4, 7, 6))); 2932 } 2933 2934 { 2935 auto sysTime = SysTime(Date(4, 7, 6)); 2936 sysTime.add!"years"(-8); 2937 assert(sysTime == SysTime(Date(-4, 7, 6))); 2938 sysTime.add!"years"(8); 2939 assert(sysTime == SysTime(Date(4, 7, 6))); 2940 } 2941 2942 { 2943 auto sysTime = SysTime(Date(-4, 7, 6)); 2944 sysTime.add!"years"(8); 2945 assert(sysTime == SysTime(Date(4, 7, 6))); 2946 sysTime.add!"years"(-8); 2947 assert(sysTime == SysTime(Date(-4, 7, 6))); 2948 } 2949 2950 { 2951 auto sysTime = SysTime(Date(-4, 2, 29)); 2952 sysTime.add!"years"(5); 2953 assert(sysTime == SysTime(Date(1, 3, 1))); 2954 } 2955 2956 { 2957 auto sysTime = SysTime(Date(4, 2, 29)); 2958 sysTime.add!"years"(-5); 2959 assert(sysTime == SysTime(Date(-1, 3, 1))); 2960 } 2961 2962 { 2963 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 2964 sysTime.add!"years"(-1); 2965 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0))); 2966 sysTime.add!"years"(1); 2967 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 2968 } 2969 2970 { 2971 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 2972 sysTime.add!"years"(-1); 2973 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 2974 sysTime.add!"years"(1); 2975 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 2976 } 2977 2978 { 2979 auto sysTime = SysTime(DateTime(0, 1, 1, 0, 0, 0)); 2980 sysTime.add!"years"(1); 2981 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 2982 sysTime.add!"years"(-1); 2983 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0))); 2984 } 2985 2986 { 2987 auto sysTime = SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 2988 sysTime.add!"years"(1); 2989 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 2990 sysTime.add!"years"(-1); 2991 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 2992 } 2993 2994 { 2995 auto sysTime = SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329)); 2996 sysTime.add!"years"(-5); 2997 assert(sysTime == SysTime(DateTime(-1, 7, 6, 14, 7, 1), usecs(54329))); 2998 sysTime.add!"years"(5); 2999 assert(sysTime == SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329))); 3000 } 3001 3002 { 3003 auto sysTime = SysTime(DateTime(-4, 7, 6, 14, 7, 1), usecs(54329)); 3004 sysTime.add!"years"(5); 3005 assert(sysTime == SysTime(DateTime(1, 7, 6, 14, 7, 1), usecs(54329))); 3006 sysTime.add!"years"(-5); 3007 assert(sysTime == SysTime(DateTime(-4, 7, 6, 14, 7, 1), usecs(54329))); 3008 } 3009 3010 { 3011 auto sysTime = SysTime(DateTime(-4, 2, 29, 5, 5, 5), msecs(555)); 3012 sysTime.add!"years"(5); 3013 assert(sysTime == SysTime(DateTime(1, 3, 1, 5, 5, 5), msecs(555))); 3014 } 3015 3016 { 3017 auto sysTime = SysTime(DateTime(4, 2, 29, 5, 5, 5), msecs(555)); 3018 sysTime.add!"years"(-5); 3019 assert(sysTime == SysTime(DateTime(-1, 3, 1, 5, 5, 5), msecs(555))); 3020 } 3021 3022 { 3023 auto sysTime = SysTime(DateTime(4, 2, 29, 5, 5, 5), msecs(555)); 3024 sysTime.add!"years"(-5).add!"years"(7); 3025 assert(sysTime == SysTime(DateTime(6, 3, 1, 5, 5, 5), msecs(555))); 3026 } 3027 3028 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 3029 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 3030 static assert(!__traits(compiles, cst.add!"years"(4))); 3031 static assert(!__traits(compiles, ist.add!"years"(4))); 3032 3033 static void testScope(scope ref SysTime st) @safe 3034 { 3035 auto result = st.add!"years"(42); 3036 } 3037 } 3038 3039 // Test add!"years"() with AllowDayOverflow.no 3040 @safe unittest 3041 { 3042 import core.time; 3043 // Test A.D. 3044 { 3045 auto sysTime = SysTime(Date(1999, 7, 6)); 3046 sysTime.add!"years"(7, AllowDayOverflow.no); 3047 assert(sysTime == SysTime(Date(2006, 7, 6))); 3048 sysTime.add!"years"(-9, AllowDayOverflow.no); 3049 assert(sysTime == SysTime(Date(1997, 7, 6))); 3050 } 3051 3052 { 3053 auto sysTime = SysTime(Date(1999, 2, 28)); 3054 sysTime.add!"years"(1, AllowDayOverflow.no); 3055 assert(sysTime == SysTime(Date(2000, 2, 28))); 3056 } 3057 3058 { 3059 auto sysTime = SysTime(Date(2000, 2, 29)); 3060 sysTime.add!"years"(-1, AllowDayOverflow.no); 3061 assert(sysTime == SysTime(Date(1999, 2, 28))); 3062 } 3063 3064 { 3065 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 7, 3), msecs(234)); 3066 sysTime.add!"years"(7, AllowDayOverflow.no); 3067 assert(sysTime == SysTime(DateTime(2006, 7, 6, 12, 7, 3), msecs(234))); 3068 sysTime.add!"years"(-9, AllowDayOverflow.no); 3069 assert(sysTime == SysTime(DateTime(1997, 7, 6, 12, 7, 3), msecs(234))); 3070 } 3071 3072 { 3073 auto sysTime = SysTime(DateTime(1999, 2, 28, 0, 7, 2), usecs(1207)); 3074 sysTime.add!"years"(1, AllowDayOverflow.no); 3075 assert(sysTime == SysTime(DateTime(2000, 2, 28, 0, 7, 2), usecs(1207))); 3076 } 3077 3078 { 3079 auto sysTime = SysTime(DateTime(2000, 2, 29, 0, 7, 2), usecs(1207)); 3080 sysTime.add!"years"(-1, AllowDayOverflow.no); 3081 assert(sysTime == SysTime(DateTime(1999, 2, 28, 0, 7, 2), usecs(1207))); 3082 } 3083 3084 // Test B.C. 3085 { 3086 auto sysTime = SysTime(Date(-1999, 7, 6)); 3087 sysTime.add!"years"(-7, AllowDayOverflow.no); 3088 assert(sysTime == SysTime(Date(-2006, 7, 6))); 3089 sysTime.add!"years"(9, AllowDayOverflow.no); 3090 assert(sysTime == SysTime(Date(-1997, 7, 6))); 3091 } 3092 3093 { 3094 auto sysTime = SysTime(Date(-1999, 2, 28)); 3095 sysTime.add!"years"(-1, AllowDayOverflow.no); 3096 assert(sysTime == SysTime(Date(-2000, 2, 28))); 3097 } 3098 3099 { 3100 auto sysTime = SysTime(Date(-2000, 2, 29)); 3101 sysTime.add!"years"(1, AllowDayOverflow.no); 3102 assert(sysTime == SysTime(Date(-1999, 2, 28))); 3103 } 3104 3105 { 3106 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 7, 3), msecs(234)); 3107 sysTime.add!"years"(-7, AllowDayOverflow.no); 3108 assert(sysTime == SysTime(DateTime(-2006, 7, 6, 12, 7, 3), msecs(234))); 3109 sysTime.add!"years"(9, AllowDayOverflow.no); 3110 assert(sysTime == SysTime(DateTime(-1997, 7, 6, 12, 7, 3), msecs(234))); 3111 } 3112 3113 { 3114 auto sysTime = SysTime(DateTime(-1999, 2, 28, 3, 3, 3), hnsecs(3)); 3115 sysTime.add!"years"(-1, AllowDayOverflow.no); 3116 assert(sysTime == SysTime(DateTime(-2000, 2, 28, 3, 3, 3), hnsecs(3))); 3117 } 3118 3119 { 3120 auto sysTime = SysTime(DateTime(-2000, 2, 29, 3, 3, 3), hnsecs(3)); 3121 sysTime.add!"years"(1, AllowDayOverflow.no); 3122 assert(sysTime == SysTime(DateTime(-1999, 2, 28, 3, 3, 3), hnsecs(3))); 3123 } 3124 3125 // Test Both 3126 { 3127 auto sysTime = SysTime(Date(4, 7, 6)); 3128 sysTime.add!"years"(-5, AllowDayOverflow.no); 3129 assert(sysTime == SysTime(Date(-1, 7, 6))); 3130 sysTime.add!"years"(5, AllowDayOverflow.no); 3131 assert(sysTime == SysTime(Date(4, 7, 6))); 3132 } 3133 3134 { 3135 auto sysTime = SysTime(Date(-4, 7, 6)); 3136 sysTime.add!"years"(5, AllowDayOverflow.no); 3137 assert(sysTime == SysTime(Date(1, 7, 6))); 3138 sysTime.add!"years"(-5, AllowDayOverflow.no); 3139 assert(sysTime == SysTime(Date(-4, 7, 6))); 3140 } 3141 3142 { 3143 auto sysTime = SysTime(Date(4, 7, 6)); 3144 sysTime.add!"years"(-8, AllowDayOverflow.no); 3145 assert(sysTime == SysTime(Date(-4, 7, 6))); 3146 sysTime.add!"years"(8, AllowDayOverflow.no); 3147 assert(sysTime == SysTime(Date(4, 7, 6))); 3148 } 3149 3150 { 3151 auto sysTime = SysTime(Date(-4, 7, 6)); 3152 sysTime.add!"years"(8, AllowDayOverflow.no); 3153 assert(sysTime == SysTime(Date(4, 7, 6))); 3154 sysTime.add!"years"(-8, AllowDayOverflow.no); 3155 assert(sysTime == SysTime(Date(-4, 7, 6))); 3156 } 3157 3158 { 3159 auto sysTime = SysTime(Date(-4, 2, 29)); 3160 sysTime.add!"years"(5, AllowDayOverflow.no); 3161 assert(sysTime == SysTime(Date(1, 2, 28))); 3162 } 3163 3164 { 3165 auto sysTime = SysTime(Date(4, 2, 29)); 3166 sysTime.add!"years"(-5, AllowDayOverflow.no); 3167 assert(sysTime == SysTime(Date(-1, 2, 28))); 3168 } 3169 3170 { 3171 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 3172 sysTime.add!"years"(-1, AllowDayOverflow.no); 3173 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0))); 3174 sysTime.add!"years"(1, AllowDayOverflow.no); 3175 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 3176 } 3177 3178 { 3179 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 3180 sysTime.add!"years"(-1, AllowDayOverflow.no); 3181 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3182 sysTime.add!"years"(1, AllowDayOverflow.no); 3183 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3184 } 3185 3186 { 3187 auto sysTime = SysTime(DateTime(0, 1, 1, 0, 0, 0)); 3188 sysTime.add!"years"(1, AllowDayOverflow.no); 3189 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 3190 sysTime.add!"years"(-1, AllowDayOverflow.no); 3191 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0))); 3192 } 3193 3194 { 3195 auto sysTime = SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 3196 sysTime.add!"years"(1, AllowDayOverflow.no); 3197 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3198 sysTime.add!"years"(-1, AllowDayOverflow.no); 3199 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3200 } 3201 3202 { 3203 auto sysTime = SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329)); 3204 sysTime.add!"years"(-5); 3205 assert(sysTime == SysTime(DateTime(-1, 7, 6, 14, 7, 1), usecs(54329))); 3206 sysTime.add!"years"(5); 3207 assert(sysTime == SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329))); 3208 } 3209 3210 { 3211 auto sysTime = SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329)); 3212 sysTime.add!"years"(-5, AllowDayOverflow.no); 3213 assert(sysTime == SysTime(DateTime(-1, 7, 6, 14, 7, 1), usecs(54329))); 3214 sysTime.add!"years"(5, AllowDayOverflow.no); 3215 assert(sysTime == SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329))); 3216 } 3217 3218 { 3219 auto sysTime = SysTime(DateTime(-4, 7, 6, 14, 7, 1), usecs(54329)); 3220 sysTime.add!"years"(5, AllowDayOverflow.no); 3221 assert(sysTime == SysTime(DateTime(1, 7, 6, 14, 7, 1), usecs(54329))); 3222 sysTime.add!"years"(-5, AllowDayOverflow.no); 3223 assert(sysTime == SysTime(DateTime(-4, 7, 6, 14, 7, 1), usecs(54329))); 3224 } 3225 3226 { 3227 auto sysTime = SysTime(DateTime(-4, 2, 29, 5, 5, 5), msecs(555)); 3228 sysTime.add!"years"(5, AllowDayOverflow.no); 3229 assert(sysTime == SysTime(DateTime(1, 2, 28, 5, 5, 5), msecs(555))); 3230 } 3231 3232 { 3233 auto sysTime = SysTime(DateTime(4, 2, 29, 5, 5, 5), msecs(555)); 3234 sysTime.add!"years"(-5, AllowDayOverflow.no); 3235 assert(sysTime == SysTime(DateTime(-1, 2, 28, 5, 5, 5), msecs(555))); 3236 } 3237 3238 { 3239 auto sysTime = SysTime(DateTime(4, 2, 29, 5, 5, 5), msecs(555)); 3240 sysTime.add!"years"(-5, AllowDayOverflow.no).add!"years"(7, AllowDayOverflow.no); 3241 assert(sysTime == SysTime(DateTime(6, 2, 28, 5, 5, 5), msecs(555))); 3242 } 3243 } 3244 3245 // Test add!"months"() with AllowDayOverflow.yes 3246 @safe unittest 3247 { 3248 import core.time; 3249 // Test A.D. 3250 { 3251 auto sysTime = SysTime(Date(1999, 7, 6)); 3252 sysTime.add!"months"(3); 3253 assert(sysTime == SysTime(Date(1999, 10, 6))); 3254 sysTime.add!"months"(-4); 3255 assert(sysTime == SysTime(Date(1999, 6, 6))); 3256 } 3257 3258 { 3259 auto sysTime = SysTime(Date(1999, 7, 6)); 3260 sysTime.add!"months"(6); 3261 assert(sysTime == SysTime(Date(2000, 1, 6))); 3262 sysTime.add!"months"(-6); 3263 assert(sysTime == SysTime(Date(1999, 7, 6))); 3264 } 3265 3266 { 3267 auto sysTime = SysTime(Date(1999, 7, 6)); 3268 sysTime.add!"months"(27); 3269 assert(sysTime == SysTime(Date(2001, 10, 6))); 3270 sysTime.add!"months"(-28); 3271 assert(sysTime == SysTime(Date(1999, 6, 6))); 3272 } 3273 3274 { 3275 auto sysTime = SysTime(Date(1999, 5, 31)); 3276 sysTime.add!"months"(1); 3277 assert(sysTime == SysTime(Date(1999, 7, 1))); 3278 } 3279 3280 { 3281 auto sysTime = SysTime(Date(1999, 5, 31)); 3282 sysTime.add!"months"(-1); 3283 assert(sysTime == SysTime(Date(1999, 5, 1))); 3284 } 3285 3286 { 3287 auto sysTime = SysTime(Date(1999, 2, 28)); 3288 sysTime.add!"months"(12); 3289 assert(sysTime == SysTime(Date(2000, 2, 28))); 3290 } 3291 3292 { 3293 auto sysTime = SysTime(Date(2000, 2, 29)); 3294 sysTime.add!"months"(12); 3295 assert(sysTime == SysTime(Date(2001, 3, 1))); 3296 } 3297 3298 { 3299 auto sysTime = SysTime(Date(1999, 7, 31)); 3300 sysTime.add!"months"(1); 3301 assert(sysTime == SysTime(Date(1999, 8, 31))); 3302 sysTime.add!"months"(1); 3303 assert(sysTime == SysTime(Date(1999, 10, 1))); 3304 } 3305 3306 { 3307 auto sysTime = SysTime(Date(1998, 8, 31)); 3308 sysTime.add!"months"(13); 3309 assert(sysTime == SysTime(Date(1999, 10, 1))); 3310 sysTime.add!"months"(-13); 3311 assert(sysTime == SysTime(Date(1998, 9, 1))); 3312 } 3313 3314 { 3315 auto sysTime = SysTime(Date(1997, 12, 31)); 3316 sysTime.add!"months"(13); 3317 assert(sysTime == SysTime(Date(1999, 1, 31))); 3318 sysTime.add!"months"(-13); 3319 assert(sysTime == SysTime(Date(1997, 12, 31))); 3320 } 3321 3322 { 3323 auto sysTime = SysTime(Date(1997, 12, 31)); 3324 sysTime.add!"months"(14); 3325 assert(sysTime == SysTime(Date(1999, 3, 3))); 3326 sysTime.add!"months"(-14); 3327 assert(sysTime == SysTime(Date(1998, 1, 3))); 3328 } 3329 3330 { 3331 auto sysTime = SysTime(Date(1998, 12, 31)); 3332 sysTime.add!"months"(14); 3333 assert(sysTime == SysTime(Date(2000, 3, 2))); 3334 sysTime.add!"months"(-14); 3335 assert(sysTime == SysTime(Date(1999, 1, 2))); 3336 } 3337 3338 { 3339 auto sysTime = SysTime(Date(1999, 12, 31)); 3340 sysTime.add!"months"(14); 3341 assert(sysTime == SysTime(Date(2001, 3, 3))); 3342 sysTime.add!"months"(-14); 3343 assert(sysTime == SysTime(Date(2000, 1, 3))); 3344 } 3345 3346 { 3347 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), usecs(5007)); 3348 sysTime.add!"months"(3); 3349 assert(sysTime == SysTime(DateTime(1999, 10, 6, 12, 2, 7), usecs(5007))); 3350 sysTime.add!"months"(-4); 3351 assert(sysTime == SysTime(DateTime(1999, 6, 6, 12, 2, 7), usecs(5007))); 3352 } 3353 3354 { 3355 auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), hnsecs(422202)); 3356 sysTime.add!"months"(14); 3357 assert(sysTime == SysTime(DateTime(2000, 3, 2, 7, 7, 7), hnsecs(422202))); 3358 sysTime.add!"months"(-14); 3359 assert(sysTime == SysTime(DateTime(1999, 1, 2, 7, 7, 7), hnsecs(422202))); 3360 } 3361 3362 { 3363 auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), hnsecs(422202)); 3364 sysTime.add!"months"(14); 3365 assert(sysTime == SysTime(DateTime(2001, 3, 3, 7, 7, 7), hnsecs(422202))); 3366 sysTime.add!"months"(-14); 3367 assert(sysTime == SysTime(DateTime(2000, 1, 3, 7, 7, 7), hnsecs(422202))); 3368 } 3369 3370 // Test B.C. 3371 { 3372 auto sysTime = SysTime(Date(-1999, 7, 6)); 3373 sysTime.add!"months"(3); 3374 assert(sysTime == SysTime(Date(-1999, 10, 6))); 3375 sysTime.add!"months"(-4); 3376 assert(sysTime == SysTime(Date(-1999, 6, 6))); 3377 } 3378 3379 { 3380 auto sysTime = SysTime(Date(-1999, 7, 6)); 3381 sysTime.add!"months"(6); 3382 assert(sysTime == SysTime(Date(-1998, 1, 6))); 3383 sysTime.add!"months"(-6); 3384 assert(sysTime == SysTime(Date(-1999, 7, 6))); 3385 } 3386 3387 { 3388 auto sysTime = SysTime(Date(-1999, 7, 6)); 3389 sysTime.add!"months"(-27); 3390 assert(sysTime == SysTime(Date(-2001, 4, 6))); 3391 sysTime.add!"months"(28); 3392 assert(sysTime == SysTime(Date(-1999, 8, 6))); 3393 } 3394 3395 { 3396 auto sysTime = SysTime(Date(-1999, 5, 31)); 3397 sysTime.add!"months"(1); 3398 assert(sysTime == SysTime(Date(-1999, 7, 1))); 3399 } 3400 3401 { 3402 auto sysTime = SysTime(Date(-1999, 5, 31)); 3403 sysTime.add!"months"(-1); 3404 assert(sysTime == SysTime(Date(-1999, 5, 1))); 3405 } 3406 3407 { 3408 auto sysTime = SysTime(Date(-1999, 2, 28)); 3409 sysTime.add!"months"(-12); 3410 assert(sysTime == SysTime(Date(-2000, 2, 28))); 3411 } 3412 3413 { 3414 auto sysTime = SysTime(Date(-2000, 2, 29)); 3415 sysTime.add!"months"(-12); 3416 assert(sysTime == SysTime(Date(-2001, 3, 1))); 3417 } 3418 3419 { 3420 auto sysTime = SysTime(Date(-1999, 7, 31)); 3421 sysTime.add!"months"(1); 3422 assert(sysTime == SysTime(Date(-1999, 8, 31))); 3423 sysTime.add!"months"(1); 3424 assert(sysTime == SysTime(Date(-1999, 10, 1))); 3425 } 3426 3427 { 3428 auto sysTime = SysTime(Date(-1998, 8, 31)); 3429 sysTime.add!"months"(13); 3430 assert(sysTime == SysTime(Date(-1997, 10, 1))); 3431 sysTime.add!"months"(-13); 3432 assert(sysTime == SysTime(Date(-1998, 9, 1))); 3433 } 3434 3435 { 3436 auto sysTime = SysTime(Date(-1997, 12, 31)); 3437 sysTime.add!"months"(13); 3438 assert(sysTime == SysTime(Date(-1995, 1, 31))); 3439 sysTime.add!"months"(-13); 3440 assert(sysTime == SysTime(Date(-1997, 12, 31))); 3441 } 3442 3443 { 3444 auto sysTime = SysTime(Date(-1997, 12, 31)); 3445 sysTime.add!"months"(14); 3446 assert(sysTime == SysTime(Date(-1995, 3, 3))); 3447 sysTime.add!"months"(-14); 3448 assert(sysTime == SysTime(Date(-1996, 1, 3))); 3449 } 3450 3451 { 3452 auto sysTime = SysTime(Date(-2002, 12, 31)); 3453 sysTime.add!"months"(14); 3454 assert(sysTime == SysTime(Date(-2000, 3, 2))); 3455 sysTime.add!"months"(-14); 3456 assert(sysTime == SysTime(Date(-2001, 1, 2))); 3457 } 3458 3459 { 3460 auto sysTime = SysTime(Date(-2001, 12, 31)); 3461 sysTime.add!"months"(14); 3462 assert(sysTime == SysTime(Date(-1999, 3, 3))); 3463 sysTime.add!"months"(-14); 3464 assert(sysTime == SysTime(Date(-2000, 1, 3))); 3465 } 3466 3467 { 3468 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), usecs(5007)); 3469 sysTime.add!"months"(3); 3470 assert(sysTime == SysTime(DateTime(-1999, 10, 6, 12, 2, 7), usecs(5007))); 3471 sysTime.add!"months"(-4); 3472 assert(sysTime == SysTime(DateTime(-1999, 6, 6, 12, 2, 7), usecs(5007))); 3473 } 3474 3475 { 3476 auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), hnsecs(422202)); 3477 sysTime.add!"months"(14); 3478 assert(sysTime == SysTime(DateTime(-2000, 3, 2, 7, 7, 7), hnsecs(422202))); 3479 sysTime.add!"months"(-14); 3480 assert(sysTime == SysTime(DateTime(-2001, 1, 2, 7, 7, 7), hnsecs(422202))); 3481 } 3482 3483 { 3484 auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), hnsecs(422202)); 3485 sysTime.add!"months"(14); 3486 assert(sysTime == SysTime(DateTime(-1999, 3, 3, 7, 7, 7), hnsecs(422202))); 3487 sysTime.add!"months"(-14); 3488 assert(sysTime == SysTime(DateTime(-2000, 1, 3, 7, 7, 7), hnsecs(422202))); 3489 } 3490 3491 // Test Both 3492 { 3493 auto sysTime = SysTime(Date(1, 1, 1)); 3494 sysTime.add!"months"(-1); 3495 assert(sysTime == SysTime(Date(0, 12, 1))); 3496 sysTime.add!"months"(1); 3497 assert(sysTime == SysTime(Date(1, 1, 1))); 3498 } 3499 3500 { 3501 auto sysTime = SysTime(Date(4, 1, 1)); 3502 sysTime.add!"months"(-48); 3503 assert(sysTime == SysTime(Date(0, 1, 1))); 3504 sysTime.add!"months"(48); 3505 assert(sysTime == SysTime(Date(4, 1, 1))); 3506 } 3507 3508 { 3509 auto sysTime = SysTime(Date(4, 3, 31)); 3510 sysTime.add!"months"(-49); 3511 assert(sysTime == SysTime(Date(0, 3, 2))); 3512 sysTime.add!"months"(49); 3513 assert(sysTime == SysTime(Date(4, 4, 2))); 3514 } 3515 3516 { 3517 auto sysTime = SysTime(Date(4, 3, 31)); 3518 sysTime.add!"months"(-85); 3519 assert(sysTime == SysTime(Date(-3, 3, 3))); 3520 sysTime.add!"months"(85); 3521 assert(sysTime == SysTime(Date(4, 4, 3))); 3522 } 3523 3524 { 3525 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 3526 sysTime.add!"months"(-1); 3527 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 3528 sysTime.add!"months"(1); 3529 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 3530 } 3531 3532 { 3533 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 3534 sysTime.add!"months"(-1); 3535 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 3536 sysTime.add!"months"(1); 3537 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3538 } 3539 3540 { 3541 auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0)); 3542 sysTime.add!"months"(1); 3543 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 3544 sysTime.add!"months"(-1); 3545 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 3546 } 3547 3548 { 3549 auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)); 3550 sysTime.add!"months"(1); 3551 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3552 sysTime.add!"months"(-1); 3553 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 3554 } 3555 3556 { 3557 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17)); 3558 sysTime.add!"months"(-1); 3559 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 7, 9), hnsecs(17))); 3560 sysTime.add!"months"(1); 3561 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17))); 3562 } 3563 3564 { 3565 auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), msecs(9)); 3566 sysTime.add!"months"(-85); 3567 assert(sysTime == SysTime(DateTime(-3, 3, 3, 12, 11, 10), msecs(9))); 3568 sysTime.add!"months"(85); 3569 assert(sysTime == SysTime(DateTime(4, 4, 3, 12, 11, 10), msecs(9))); 3570 } 3571 3572 { 3573 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 3574 sysTime.add!"months"(85); 3575 assert(sysTime == SysTime(DateTime(4, 5, 1, 12, 11, 10), msecs(9))); 3576 sysTime.add!"months"(-85); 3577 assert(sysTime == SysTime(DateTime(-3, 4, 1, 12, 11, 10), msecs(9))); 3578 } 3579 3580 { 3581 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 3582 sysTime.add!"months"(85).add!"months"(-83); 3583 assert(sysTime == SysTime(DateTime(-3, 6, 1, 12, 11, 10), msecs(9))); 3584 } 3585 3586 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 3587 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 3588 static assert(!__traits(compiles, cst.add!"months"(4))); 3589 static assert(!__traits(compiles, ist.add!"months"(4))); 3590 3591 static void testScope(scope ref SysTime st) @safe 3592 { 3593 auto result = st.add!"months"(42); 3594 } 3595 } 3596 3597 // Test add!"months"() with AllowDayOverflow.no 3598 @safe unittest 3599 { 3600 import core.time; 3601 // Test A.D. 3602 { 3603 auto sysTime = SysTime(Date(1999, 7, 6)); 3604 sysTime.add!"months"(3, AllowDayOverflow.no); 3605 assert(sysTime == SysTime(Date(1999, 10, 6))); 3606 sysTime.add!"months"(-4, AllowDayOverflow.no); 3607 assert(sysTime == SysTime(Date(1999, 6, 6))); 3608 } 3609 3610 { 3611 auto sysTime = SysTime(Date(1999, 7, 6)); 3612 sysTime.add!"months"(6, AllowDayOverflow.no); 3613 assert(sysTime == SysTime(Date(2000, 1, 6))); 3614 sysTime.add!"months"(-6, AllowDayOverflow.no); 3615 assert(sysTime == SysTime(Date(1999, 7, 6))); 3616 } 3617 3618 { 3619 auto sysTime = SysTime(Date(1999, 7, 6)); 3620 sysTime.add!"months"(27, AllowDayOverflow.no); 3621 assert(sysTime == SysTime(Date(2001, 10, 6))); 3622 sysTime.add!"months"(-28, AllowDayOverflow.no); 3623 assert(sysTime == SysTime(Date(1999, 6, 6))); 3624 } 3625 3626 { 3627 auto sysTime = SysTime(Date(1999, 5, 31)); 3628 sysTime.add!"months"(1, AllowDayOverflow.no); 3629 assert(sysTime == SysTime(Date(1999, 6, 30))); 3630 } 3631 3632 { 3633 auto sysTime = SysTime(Date(1999, 5, 31)); 3634 sysTime.add!"months"(-1, AllowDayOverflow.no); 3635 assert(sysTime == SysTime(Date(1999, 4, 30))); 3636 } 3637 3638 { 3639 auto sysTime = SysTime(Date(1999, 2, 28)); 3640 sysTime.add!"months"(12, AllowDayOverflow.no); 3641 assert(sysTime == SysTime(Date(2000, 2, 28))); 3642 } 3643 3644 { 3645 auto sysTime = SysTime(Date(2000, 2, 29)); 3646 sysTime.add!"months"(12, AllowDayOverflow.no); 3647 assert(sysTime == SysTime(Date(2001, 2, 28))); 3648 } 3649 3650 { 3651 auto sysTime = SysTime(Date(1999, 7, 31)); 3652 sysTime.add!"months"(1, AllowDayOverflow.no); 3653 assert(sysTime == SysTime(Date(1999, 8, 31))); 3654 sysTime.add!"months"(1, AllowDayOverflow.no); 3655 assert(sysTime == SysTime(Date(1999, 9, 30))); 3656 } 3657 3658 { 3659 auto sysTime = SysTime(Date(1998, 8, 31)); 3660 sysTime.add!"months"(13, AllowDayOverflow.no); 3661 assert(sysTime == SysTime(Date(1999, 9, 30))); 3662 sysTime.add!"months"(-13, AllowDayOverflow.no); 3663 assert(sysTime == SysTime(Date(1998, 8, 30))); 3664 } 3665 3666 { 3667 auto sysTime = SysTime(Date(1997, 12, 31)); 3668 sysTime.add!"months"(13, AllowDayOverflow.no); 3669 assert(sysTime == SysTime(Date(1999, 1, 31))); 3670 sysTime.add!"months"(-13, AllowDayOverflow.no); 3671 assert(sysTime == SysTime(Date(1997, 12, 31))); 3672 } 3673 3674 { 3675 auto sysTime = SysTime(Date(1997, 12, 31)); 3676 sysTime.add!"months"(14, AllowDayOverflow.no); 3677 assert(sysTime == SysTime(Date(1999, 2, 28))); 3678 sysTime.add!"months"(-14, AllowDayOverflow.no); 3679 assert(sysTime == SysTime(Date(1997, 12, 28))); 3680 } 3681 3682 { 3683 auto sysTime = SysTime(Date(1998, 12, 31)); 3684 sysTime.add!"months"(14, AllowDayOverflow.no); 3685 assert(sysTime == SysTime(Date(2000, 2, 29))); 3686 sysTime.add!"months"(-14, AllowDayOverflow.no); 3687 assert(sysTime == SysTime(Date(1998, 12, 29))); 3688 } 3689 3690 { 3691 auto sysTime = SysTime(Date(1999, 12, 31)); 3692 sysTime.add!"months"(14, AllowDayOverflow.no); 3693 assert(sysTime == SysTime(Date(2001, 2, 28))); 3694 sysTime.add!"months"(-14, AllowDayOverflow.no); 3695 assert(sysTime == SysTime(Date(1999, 12, 28))); 3696 } 3697 3698 { 3699 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), usecs(5007)); 3700 sysTime.add!"months"(3, AllowDayOverflow.no); 3701 assert(sysTime == SysTime(DateTime(1999, 10, 6, 12, 2, 7), usecs(5007))); 3702 sysTime.add!"months"(-4, AllowDayOverflow.no); 3703 assert(sysTime == SysTime(DateTime(1999, 6, 6, 12, 2, 7), usecs(5007))); 3704 } 3705 3706 { 3707 auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), hnsecs(422202)); 3708 sysTime.add!"months"(14, AllowDayOverflow.no); 3709 assert(sysTime == SysTime(DateTime(2000, 2, 29, 7, 7, 7), hnsecs(422202))); 3710 sysTime.add!"months"(-14, AllowDayOverflow.no); 3711 assert(sysTime == SysTime(DateTime(1998, 12, 29, 7, 7, 7), hnsecs(422202))); 3712 } 3713 3714 { 3715 auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), hnsecs(422202)); 3716 sysTime.add!"months"(14, AllowDayOverflow.no); 3717 assert(sysTime == SysTime(DateTime(2001, 2, 28, 7, 7, 7), hnsecs(422202))); 3718 sysTime.add!"months"(-14, AllowDayOverflow.no); 3719 assert(sysTime == SysTime(DateTime(1999, 12, 28, 7, 7, 7), hnsecs(422202))); 3720 } 3721 3722 // Test B.C. 3723 { 3724 auto sysTime = SysTime(Date(-1999, 7, 6)); 3725 sysTime.add!"months"(3, AllowDayOverflow.no); 3726 assert(sysTime == SysTime(Date(-1999, 10, 6))); 3727 sysTime.add!"months"(-4, AllowDayOverflow.no); 3728 assert(sysTime == SysTime(Date(-1999, 6, 6))); 3729 } 3730 3731 { 3732 auto sysTime = SysTime(Date(-1999, 7, 6)); 3733 sysTime.add!"months"(6, AllowDayOverflow.no); 3734 assert(sysTime == SysTime(Date(-1998, 1, 6))); 3735 sysTime.add!"months"(-6, AllowDayOverflow.no); 3736 assert(sysTime == SysTime(Date(-1999, 7, 6))); 3737 } 3738 3739 { 3740 auto sysTime = SysTime(Date(-1999, 7, 6)); 3741 sysTime.add!"months"(-27, AllowDayOverflow.no); 3742 assert(sysTime == SysTime(Date(-2001, 4, 6))); 3743 sysTime.add!"months"(28, AllowDayOverflow.no); 3744 assert(sysTime == SysTime(Date(-1999, 8, 6))); 3745 } 3746 3747 { 3748 auto sysTime = SysTime(Date(-1999, 5, 31)); 3749 sysTime.add!"months"(1, AllowDayOverflow.no); 3750 assert(sysTime == SysTime(Date(-1999, 6, 30))); 3751 } 3752 3753 { 3754 auto sysTime = SysTime(Date(-1999, 5, 31)); 3755 sysTime.add!"months"(-1, AllowDayOverflow.no); 3756 assert(sysTime == SysTime(Date(-1999, 4, 30))); 3757 } 3758 3759 { 3760 auto sysTime = SysTime(Date(-1999, 2, 28)); 3761 sysTime.add!"months"(-12, AllowDayOverflow.no); 3762 assert(sysTime == SysTime(Date(-2000, 2, 28))); 3763 } 3764 3765 { 3766 auto sysTime = SysTime(Date(-2000, 2, 29)); 3767 sysTime.add!"months"(-12, AllowDayOverflow.no); 3768 assert(sysTime == SysTime(Date(-2001, 2, 28))); 3769 } 3770 3771 { 3772 auto sysTime = SysTime(Date(-1999, 7, 31)); 3773 sysTime.add!"months"(1, AllowDayOverflow.no); 3774 assert(sysTime == SysTime(Date(-1999, 8, 31))); 3775 sysTime.add!"months"(1, AllowDayOverflow.no); 3776 assert(sysTime == SysTime(Date(-1999, 9, 30))); 3777 } 3778 3779 { 3780 auto sysTime = SysTime(Date(-1998, 8, 31)); 3781 sysTime.add!"months"(13, AllowDayOverflow.no); 3782 assert(sysTime == SysTime(Date(-1997, 9, 30))); 3783 sysTime.add!"months"(-13, AllowDayOverflow.no); 3784 assert(sysTime == SysTime(Date(-1998, 8, 30))); 3785 } 3786 3787 { 3788 auto sysTime = SysTime(Date(-1997, 12, 31)); 3789 sysTime.add!"months"(13, AllowDayOverflow.no); 3790 assert(sysTime == SysTime(Date(-1995, 1, 31))); 3791 sysTime.add!"months"(-13, AllowDayOverflow.no); 3792 assert(sysTime == SysTime(Date(-1997, 12, 31))); 3793 } 3794 3795 { 3796 auto sysTime = SysTime(Date(-1997, 12, 31)); 3797 sysTime.add!"months"(14, AllowDayOverflow.no); 3798 assert(sysTime == SysTime(Date(-1995, 2, 28))); 3799 sysTime.add!"months"(-14, AllowDayOverflow.no); 3800 assert(sysTime == SysTime(Date(-1997, 12, 28))); 3801 } 3802 3803 { 3804 auto sysTime = SysTime(Date(-2002, 12, 31)); 3805 sysTime.add!"months"(14, AllowDayOverflow.no); 3806 assert(sysTime == SysTime(Date(-2000, 2, 29))); 3807 sysTime.add!"months"(-14, AllowDayOverflow.no); 3808 assert(sysTime == SysTime(Date(-2002, 12, 29))); 3809 } 3810 3811 { 3812 auto sysTime = SysTime(Date(-2001, 12, 31)); 3813 sysTime.add!"months"(14, AllowDayOverflow.no); 3814 assert(sysTime == SysTime(Date(-1999, 2, 28))); 3815 sysTime.add!"months"(-14, AllowDayOverflow.no); 3816 assert(sysTime == SysTime(Date(-2001, 12, 28))); 3817 } 3818 3819 { 3820 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), usecs(5007)); 3821 sysTime.add!"months"(3, AllowDayOverflow.no); 3822 assert(sysTime == SysTime(DateTime(-1999, 10, 6, 12, 2, 7), usecs(5007))); 3823 sysTime.add!"months"(-4, AllowDayOverflow.no); 3824 assert(sysTime == SysTime(DateTime(-1999, 6, 6, 12, 2, 7), usecs(5007))); 3825 } 3826 3827 { 3828 auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), hnsecs(422202)); 3829 sysTime.add!"months"(14, AllowDayOverflow.no); 3830 assert(sysTime == SysTime(DateTime(-2000, 2, 29, 7, 7, 7), hnsecs(422202))); 3831 sysTime.add!"months"(-14, AllowDayOverflow.no); 3832 assert(sysTime == SysTime(DateTime(-2002, 12, 29, 7, 7, 7), hnsecs(422202))); 3833 } 3834 3835 { 3836 auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), hnsecs(422202)); 3837 sysTime.add!"months"(14, AllowDayOverflow.no); 3838 assert(sysTime == SysTime(DateTime(-1999, 2, 28, 7, 7, 7), hnsecs(422202))); 3839 sysTime.add!"months"(-14, AllowDayOverflow.no); 3840 assert(sysTime == SysTime(DateTime(-2001, 12, 28, 7, 7, 7), hnsecs(422202))); 3841 } 3842 3843 // Test Both 3844 { 3845 auto sysTime = SysTime(Date(1, 1, 1)); 3846 sysTime.add!"months"(-1, AllowDayOverflow.no); 3847 assert(sysTime == SysTime(Date(0, 12, 1))); 3848 sysTime.add!"months"(1, AllowDayOverflow.no); 3849 assert(sysTime == SysTime(Date(1, 1, 1))); 3850 } 3851 3852 { 3853 auto sysTime = SysTime(Date(4, 1, 1)); 3854 sysTime.add!"months"(-48, AllowDayOverflow.no); 3855 assert(sysTime == SysTime(Date(0, 1, 1))); 3856 sysTime.add!"months"(48, AllowDayOverflow.no); 3857 assert(sysTime == SysTime(Date(4, 1, 1))); 3858 } 3859 3860 { 3861 auto sysTime = SysTime(Date(4, 3, 31)); 3862 sysTime.add!"months"(-49, AllowDayOverflow.no); 3863 assert(sysTime == SysTime(Date(0, 2, 29))); 3864 sysTime.add!"months"(49, AllowDayOverflow.no); 3865 assert(sysTime == SysTime(Date(4, 3, 29))); 3866 } 3867 3868 { 3869 auto sysTime = SysTime(Date(4, 3, 31)); 3870 sysTime.add!"months"(-85, AllowDayOverflow.no); 3871 assert(sysTime == SysTime(Date(-3, 2, 28))); 3872 sysTime.add!"months"(85, AllowDayOverflow.no); 3873 assert(sysTime == SysTime(Date(4, 3, 28))); 3874 } 3875 3876 { 3877 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 3878 sysTime.add!"months"(-1, AllowDayOverflow.no); 3879 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 3880 sysTime.add!"months"(1, AllowDayOverflow.no); 3881 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 3882 } 3883 3884 { 3885 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 3886 sysTime.add!"months"(-1, AllowDayOverflow.no); 3887 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 3888 sysTime.add!"months"(1, AllowDayOverflow.no); 3889 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3890 } 3891 3892 { 3893 auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0)); 3894 sysTime.add!"months"(1, AllowDayOverflow.no); 3895 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 3896 sysTime.add!"months"(-1, AllowDayOverflow.no); 3897 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 3898 } 3899 3900 { 3901 auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)); 3902 sysTime.add!"months"(1, AllowDayOverflow.no); 3903 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3904 sysTime.add!"months"(-1, AllowDayOverflow.no); 3905 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 3906 } 3907 3908 { 3909 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17)); 3910 sysTime.add!"months"(-1, AllowDayOverflow.no); 3911 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 7, 9), hnsecs(17))); 3912 sysTime.add!"months"(1, AllowDayOverflow.no); 3913 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17))); 3914 } 3915 3916 { 3917 auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), msecs(9)); 3918 sysTime.add!"months"(-85, AllowDayOverflow.no); 3919 assert(sysTime == SysTime(DateTime(-3, 2, 28, 12, 11, 10), msecs(9))); 3920 sysTime.add!"months"(85, AllowDayOverflow.no); 3921 assert(sysTime == SysTime(DateTime(4, 3, 28, 12, 11, 10), msecs(9))); 3922 } 3923 3924 { 3925 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 3926 sysTime.add!"months"(85, AllowDayOverflow.no); 3927 assert(sysTime == SysTime(DateTime(4, 4, 30, 12, 11, 10), msecs(9))); 3928 sysTime.add!"months"(-85, AllowDayOverflow.no); 3929 assert(sysTime == SysTime(DateTime(-3, 3, 30, 12, 11, 10), msecs(9))); 3930 } 3931 3932 { 3933 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 3934 sysTime.add!"months"(85, AllowDayOverflow.no).add!"months"(-83, AllowDayOverflow.no); 3935 assert(sysTime == SysTime(DateTime(-3, 5, 30, 12, 11, 10), msecs(9))); 3936 } 3937 } 3938 3939 3940 /++ 3941 Adds the given number of years or months to this $(LREF SysTime). A 3942 negative number will subtract. 3943 3944 The difference between rolling and adding is that rolling does not 3945 affect larger units. Rolling a $(LREF SysTime) 12 months 3946 gets the exact same $(LREF SysTime). However, the days can still be 3947 affected due to the differing number of days in each month. 3948 3949 Because there are no units larger than years, there is no difference 3950 between adding and rolling years. 3951 3952 Params: 3953 units = The type of units to add ("years" or "months"). 3954 value = The number of months or years to add to this 3955 $(LREF SysTime). 3956 allowOverflow = Whether the days should be allowed to overflow, 3957 causing the month to increment. 3958 +/ 3959 ref SysTime roll(string units) 3960 (long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe nothrow scope 3961 if (units == "years") 3962 { 3963 return add!"years"(value, allowOverflow); 3964 } 3965 3966 /// 3967 @safe unittest 3968 { 3969 import std.datetime.date : AllowDayOverflow, DateTime; 3970 3971 auto st1 = SysTime(DateTime(2010, 1, 1, 12, 33, 33)); 3972 st1.roll!"months"(1); 3973 assert(st1 == SysTime(DateTime(2010, 2, 1, 12, 33, 33))); 3974 3975 auto st2 = SysTime(DateTime(2010, 1, 1, 12, 33, 33)); 3976 st2.roll!"months"(-1); 3977 assert(st2 == SysTime(DateTime(2010, 12, 1, 12, 33, 33))); 3978 3979 auto st3 = SysTime(DateTime(1999, 1, 29, 12, 33, 33)); 3980 st3.roll!"months"(1); 3981 assert(st3 == SysTime(DateTime(1999, 3, 1, 12, 33, 33))); 3982 3983 auto st4 = SysTime(DateTime(1999, 1, 29, 12, 33, 33)); 3984 st4.roll!"months"(1, AllowDayOverflow.no); 3985 assert(st4 == SysTime(DateTime(1999, 2, 28, 12, 33, 33))); 3986 3987 auto st5 = SysTime(DateTime(2000, 2, 29, 12, 30, 33)); 3988 st5.roll!"years"(1); 3989 assert(st5 == SysTime(DateTime(2001, 3, 1, 12, 30, 33))); 3990 3991 auto st6 = SysTime(DateTime(2000, 2, 29, 12, 30, 33)); 3992 st6.roll!"years"(1, AllowDayOverflow.no); 3993 assert(st6 == SysTime(DateTime(2001, 2, 28, 12, 30, 33))); 3994 } 3995 3996 @safe unittest 3997 { 3998 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 3999 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 4000 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 4001 st.roll!"years"(4); 4002 static assert(!__traits(compiles, cst.roll!"years"(4))); 4003 static assert(!__traits(compiles, ist.roll!"years"(4))); 4004 4005 static void testScope(scope ref SysTime st) @safe 4006 { 4007 auto result = st.roll!"years"(42); 4008 } 4009 } 4010 4011 4012 // Shares documentation with "years" overload. 4013 ref SysTime roll(string units) 4014 (long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe nothrow scope 4015 if (units == "months") 4016 { 4017 auto hnsecs = adjTime; 4018 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 4019 4020 if (hnsecs < 0) 4021 { 4022 hnsecs += convert!("hours", "hnsecs")(24); 4023 --days; 4024 } 4025 4026 auto date = Date(cast(int) days); 4027 date.roll!"months"(value, allowOverflow); 4028 days = date.dayOfGregorianCal - 1; 4029 4030 if (days < 0) 4031 { 4032 hnsecs -= convert!("hours", "hnsecs")(24); 4033 ++days; 4034 } 4035 4036 immutable newDaysHNSecs = convert!("days", "hnsecs")(days); 4037 adjTime = newDaysHNSecs + hnsecs; 4038 return this; 4039 } 4040 4041 // Test roll!"months"() with AllowDayOverflow.yes 4042 @safe unittest 4043 { 4044 import core.time; 4045 // Test A.D. 4046 { 4047 auto sysTime = SysTime(Date(1999, 7, 6)); 4048 sysTime.roll!"months"(3); 4049 assert(sysTime == SysTime(Date(1999, 10, 6))); 4050 sysTime.roll!"months"(-4); 4051 assert(sysTime == SysTime(Date(1999, 6, 6))); 4052 } 4053 4054 { 4055 auto sysTime = SysTime(Date(1999, 7, 6)); 4056 sysTime.roll!"months"(6); 4057 assert(sysTime == SysTime(Date(1999, 1, 6))); 4058 sysTime.roll!"months"(-6); 4059 assert(sysTime == SysTime(Date(1999, 7, 6))); 4060 } 4061 4062 { 4063 auto sysTime = SysTime(Date(1999, 7, 6)); 4064 sysTime.roll!"months"(27); 4065 assert(sysTime == SysTime(Date(1999, 10, 6))); 4066 sysTime.roll!"months"(-28); 4067 assert(sysTime == SysTime(Date(1999, 6, 6))); 4068 } 4069 4070 { 4071 auto sysTime = SysTime(Date(1999, 5, 31)); 4072 sysTime.roll!"months"(1); 4073 assert(sysTime == SysTime(Date(1999, 7, 1))); 4074 } 4075 4076 { 4077 auto sysTime = SysTime(Date(1999, 5, 31)); 4078 sysTime.roll!"months"(-1); 4079 assert(sysTime == SysTime(Date(1999, 5, 1))); 4080 } 4081 4082 { 4083 auto sysTime = SysTime(Date(1999, 2, 28)); 4084 sysTime.roll!"months"(12); 4085 assert(sysTime == SysTime(Date(1999, 2, 28))); 4086 } 4087 4088 { 4089 auto sysTime = SysTime(Date(2000, 2, 29)); 4090 sysTime.roll!"months"(12); 4091 assert(sysTime == SysTime(Date(2000, 2, 29))); 4092 } 4093 4094 { 4095 auto sysTime = SysTime(Date(1999, 7, 31)); 4096 sysTime.roll!"months"(1); 4097 assert(sysTime == SysTime(Date(1999, 8, 31))); 4098 sysTime.roll!"months"(1); 4099 assert(sysTime == SysTime(Date(1999, 10, 1))); 4100 } 4101 4102 { 4103 auto sysTime = SysTime(Date(1998, 8, 31)); 4104 sysTime.roll!"months"(13); 4105 assert(sysTime == SysTime(Date(1998, 10, 1))); 4106 sysTime.roll!"months"(-13); 4107 assert(sysTime == SysTime(Date(1998, 9, 1))); 4108 } 4109 4110 { 4111 auto sysTime = SysTime(Date(1997, 12, 31)); 4112 sysTime.roll!"months"(13); 4113 assert(sysTime == SysTime(Date(1997, 1, 31))); 4114 sysTime.roll!"months"(-13); 4115 assert(sysTime == SysTime(Date(1997, 12, 31))); 4116 } 4117 4118 { 4119 auto sysTime = SysTime(Date(1997, 12, 31)); 4120 sysTime.roll!"months"(14); 4121 assert(sysTime == SysTime(Date(1997, 3, 3))); 4122 sysTime.roll!"months"(-14); 4123 assert(sysTime == SysTime(Date(1997, 1, 3))); 4124 } 4125 4126 { 4127 auto sysTime = SysTime(Date(1998, 12, 31)); 4128 sysTime.roll!"months"(14); 4129 assert(sysTime == SysTime(Date(1998, 3, 3))); 4130 sysTime.roll!"months"(-14); 4131 assert(sysTime == SysTime(Date(1998, 1, 3))); 4132 } 4133 4134 { 4135 auto sysTime = SysTime(Date(1999, 12, 31)); 4136 sysTime.roll!"months"(14); 4137 assert(sysTime == SysTime(Date(1999, 3, 3))); 4138 sysTime.roll!"months"(-14); 4139 assert(sysTime == SysTime(Date(1999, 1, 3))); 4140 } 4141 4142 { 4143 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), usecs(5007)); 4144 sysTime.roll!"months"(3); 4145 assert(sysTime == SysTime(DateTime(1999, 10, 6, 12, 2, 7), usecs(5007))); 4146 sysTime.roll!"months"(-4); 4147 assert(sysTime == SysTime(DateTime(1999, 6, 6, 12, 2, 7), usecs(5007))); 4148 } 4149 4150 { 4151 auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), hnsecs(422202)); 4152 sysTime.roll!"months"(14); 4153 assert(sysTime == SysTime(DateTime(1998, 3, 3, 7, 7, 7), hnsecs(422202))); 4154 sysTime.roll!"months"(-14); 4155 assert(sysTime == SysTime(DateTime(1998, 1, 3, 7, 7, 7), hnsecs(422202))); 4156 } 4157 4158 { 4159 auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), hnsecs(422202)); 4160 sysTime.roll!"months"(14); 4161 assert(sysTime == SysTime(DateTime(1999, 3, 3, 7, 7, 7), hnsecs(422202))); 4162 sysTime.roll!"months"(-14); 4163 assert(sysTime == SysTime(DateTime(1999, 1, 3, 7, 7, 7), hnsecs(422202))); 4164 } 4165 4166 // Test B.C. 4167 { 4168 auto sysTime = SysTime(Date(-1999, 7, 6)); 4169 sysTime.roll!"months"(3); 4170 assert(sysTime == SysTime(Date(-1999, 10, 6))); 4171 sysTime.roll!"months"(-4); 4172 assert(sysTime == SysTime(Date(-1999, 6, 6))); 4173 } 4174 4175 { 4176 auto sysTime = SysTime(Date(-1999, 7, 6)); 4177 sysTime.roll!"months"(6); 4178 assert(sysTime == SysTime(Date(-1999, 1, 6))); 4179 sysTime.roll!"months"(-6); 4180 assert(sysTime == SysTime(Date(-1999, 7, 6))); 4181 } 4182 4183 { 4184 auto sysTime = SysTime(Date(-1999, 7, 6)); 4185 sysTime.roll!"months"(-27); 4186 assert(sysTime == SysTime(Date(-1999, 4, 6))); 4187 sysTime.roll!"months"(28); 4188 assert(sysTime == SysTime(Date(-1999, 8, 6))); 4189 } 4190 4191 { 4192 auto sysTime = SysTime(Date(-1999, 5, 31)); 4193 sysTime.roll!"months"(1); 4194 assert(sysTime == SysTime(Date(-1999, 7, 1))); 4195 } 4196 4197 { 4198 auto sysTime = SysTime(Date(-1999, 5, 31)); 4199 sysTime.roll!"months"(-1); 4200 assert(sysTime == SysTime(Date(-1999, 5, 1))); 4201 } 4202 4203 { 4204 auto sysTime = SysTime(Date(-1999, 2, 28)); 4205 sysTime.roll!"months"(-12); 4206 assert(sysTime == SysTime(Date(-1999, 2, 28))); 4207 } 4208 4209 { 4210 auto sysTime = SysTime(Date(-2000, 2, 29)); 4211 sysTime.roll!"months"(-12); 4212 assert(sysTime == SysTime(Date(-2000, 2, 29))); 4213 } 4214 4215 { 4216 auto sysTime = SysTime(Date(-1999, 7, 31)); 4217 sysTime.roll!"months"(1); 4218 assert(sysTime == SysTime(Date(-1999, 8, 31))); 4219 sysTime.roll!"months"(1); 4220 assert(sysTime == SysTime(Date(-1999, 10, 1))); 4221 } 4222 4223 { 4224 auto sysTime = SysTime(Date(-1998, 8, 31)); 4225 sysTime.roll!"months"(13); 4226 assert(sysTime == SysTime(Date(-1998, 10, 1))); 4227 sysTime.roll!"months"(-13); 4228 assert(sysTime == SysTime(Date(-1998, 9, 1))); 4229 } 4230 4231 { 4232 auto sysTime = SysTime(Date(-1997, 12, 31)); 4233 sysTime.roll!"months"(13); 4234 assert(sysTime == SysTime(Date(-1997, 1, 31))); 4235 sysTime.roll!"months"(-13); 4236 assert(sysTime == SysTime(Date(-1997, 12, 31))); 4237 } 4238 4239 { 4240 auto sysTime = SysTime(Date(-1997, 12, 31)); 4241 sysTime.roll!"months"(14); 4242 assert(sysTime == SysTime(Date(-1997, 3, 3))); 4243 sysTime.roll!"months"(-14); 4244 assert(sysTime == SysTime(Date(-1997, 1, 3))); 4245 } 4246 4247 { 4248 auto sysTime = SysTime(Date(-2002, 12, 31)); 4249 sysTime.roll!"months"(14); 4250 assert(sysTime == SysTime(Date(-2002, 3, 3))); 4251 sysTime.roll!"months"(-14); 4252 assert(sysTime == SysTime(Date(-2002, 1, 3))); 4253 } 4254 4255 { 4256 auto sysTime = SysTime(Date(-2001, 12, 31)); 4257 sysTime.roll!"months"(14); 4258 assert(sysTime == SysTime(Date(-2001, 3, 3))); 4259 sysTime.roll!"months"(-14); 4260 assert(sysTime == SysTime(Date(-2001, 1, 3))); 4261 } 4262 4263 { 4264 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 4265 sysTime.roll!"months"(-1); 4266 assert(sysTime == SysTime(DateTime(1, 12, 1, 0, 0, 0))); 4267 sysTime.roll!"months"(1); 4268 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 4269 } 4270 4271 { 4272 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 4273 sysTime.roll!"months"(-1); 4274 assert(sysTime == SysTime(DateTime(1, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 4275 sysTime.roll!"months"(1); 4276 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 4277 } 4278 4279 { 4280 auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0)); 4281 sysTime.roll!"months"(1); 4282 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0))); 4283 sysTime.roll!"months"(-1); 4284 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 4285 } 4286 4287 { 4288 auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)); 4289 sysTime.roll!"months"(1); 4290 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 4291 sysTime.roll!"months"(-1); 4292 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 4293 } 4294 4295 { 4296 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), hnsecs(5007)); 4297 sysTime.roll!"months"(3); 4298 assert(sysTime == SysTime(DateTime(-1999, 10, 6, 12, 2, 7), hnsecs(5007))); 4299 sysTime.roll!"months"(-4); 4300 assert(sysTime == SysTime(DateTime(-1999, 6, 6, 12, 2, 7), hnsecs(5007))); 4301 } 4302 4303 { 4304 auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), hnsecs(422202)); 4305 sysTime.roll!"months"(14); 4306 assert(sysTime == SysTime(DateTime(-2002, 3, 3, 7, 7, 7), hnsecs(422202))); 4307 sysTime.roll!"months"(-14); 4308 assert(sysTime == SysTime(DateTime(-2002, 1, 3, 7, 7, 7), hnsecs(422202))); 4309 } 4310 4311 { 4312 auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), hnsecs(422202)); 4313 sysTime.roll!"months"(14); 4314 assert(sysTime == SysTime(DateTime(-2001, 3, 3, 7, 7, 7), hnsecs(422202))); 4315 sysTime.roll!"months"(-14); 4316 assert(sysTime == SysTime(DateTime(-2001, 1, 3, 7, 7, 7), hnsecs(422202))); 4317 } 4318 4319 // Test Both 4320 { 4321 auto sysTime = SysTime(Date(1, 1, 1)); 4322 sysTime.roll!"months"(-1); 4323 assert(sysTime == SysTime(Date(1, 12, 1))); 4324 sysTime.roll!"months"(1); 4325 assert(sysTime == SysTime(Date(1, 1, 1))); 4326 } 4327 4328 { 4329 auto sysTime = SysTime(Date(4, 1, 1)); 4330 sysTime.roll!"months"(-48); 4331 assert(sysTime == SysTime(Date(4, 1, 1))); 4332 sysTime.roll!"months"(48); 4333 assert(sysTime == SysTime(Date(4, 1, 1))); 4334 } 4335 4336 { 4337 auto sysTime = SysTime(Date(4, 3, 31)); 4338 sysTime.roll!"months"(-49); 4339 assert(sysTime == SysTime(Date(4, 3, 2))); 4340 sysTime.roll!"months"(49); 4341 assert(sysTime == SysTime(Date(4, 4, 2))); 4342 } 4343 4344 { 4345 auto sysTime = SysTime(Date(4, 3, 31)); 4346 sysTime.roll!"months"(-85); 4347 assert(sysTime == SysTime(Date(4, 3, 2))); 4348 sysTime.roll!"months"(85); 4349 assert(sysTime == SysTime(Date(4, 4, 2))); 4350 } 4351 4352 { 4353 auto sysTime = SysTime(Date(-1, 1, 1)); 4354 sysTime.roll!"months"(-1); 4355 assert(sysTime == SysTime(Date(-1, 12, 1))); 4356 sysTime.roll!"months"(1); 4357 assert(sysTime == SysTime(Date(-1, 1, 1))); 4358 } 4359 4360 { 4361 auto sysTime = SysTime(Date(-4, 1, 1)); 4362 sysTime.roll!"months"(-48); 4363 assert(sysTime == SysTime(Date(-4, 1, 1))); 4364 sysTime.roll!"months"(48); 4365 assert(sysTime == SysTime(Date(-4, 1, 1))); 4366 } 4367 4368 { 4369 auto sysTime = SysTime(Date(-4, 3, 31)); 4370 sysTime.roll!"months"(-49); 4371 assert(sysTime == SysTime(Date(-4, 3, 2))); 4372 sysTime.roll!"months"(49); 4373 assert(sysTime == SysTime(Date(-4, 4, 2))); 4374 } 4375 4376 { 4377 auto sysTime = SysTime(Date(-4, 3, 31)); 4378 sysTime.roll!"months"(-85); 4379 assert(sysTime == SysTime(Date(-4, 3, 2))); 4380 sysTime.roll!"months"(85); 4381 assert(sysTime == SysTime(Date(-4, 4, 2))); 4382 } 4383 4384 { 4385 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17)); 4386 sysTime.roll!"months"(-1); 4387 assert(sysTime == SysTime(DateTime(1, 12, 1, 0, 7, 9), hnsecs(17))); 4388 sysTime.roll!"months"(1); 4389 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17))); 4390 } 4391 4392 { 4393 auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), msecs(9)); 4394 sysTime.roll!"months"(-85); 4395 assert(sysTime == SysTime(DateTime(4, 3, 2, 12, 11, 10), msecs(9))); 4396 sysTime.roll!"months"(85); 4397 assert(sysTime == SysTime(DateTime(4, 4, 2, 12, 11, 10), msecs(9))); 4398 } 4399 4400 { 4401 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 4402 sysTime.roll!"months"(85); 4403 assert(sysTime == SysTime(DateTime(-3, 5, 1, 12, 11, 10), msecs(9))); 4404 sysTime.roll!"months"(-85); 4405 assert(sysTime == SysTime(DateTime(-3, 4, 1, 12, 11, 10), msecs(9))); 4406 } 4407 4408 { 4409 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 4410 sysTime.roll!"months"(85).roll!"months"(-83); 4411 assert(sysTime == SysTime(DateTime(-3, 6, 1, 12, 11, 10), msecs(9))); 4412 } 4413 4414 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 4415 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 4416 static assert(!__traits(compiles, cst.roll!"months"(4))); 4417 static assert(!__traits(compiles, ist.roll!"months"(4))); 4418 4419 static void testScope(scope ref SysTime st) @safe 4420 { 4421 auto result = st.roll!"months"(42); 4422 } 4423 } 4424 4425 // Test roll!"months"() with AllowDayOverflow.no 4426 @safe unittest 4427 { 4428 import core.time; 4429 // Test A.D. 4430 { 4431 auto sysTime = SysTime(Date(1999, 7, 6)); 4432 sysTime.roll!"months"(3, AllowDayOverflow.no); 4433 assert(sysTime == SysTime(Date(1999, 10, 6))); 4434 sysTime.roll!"months"(-4, AllowDayOverflow.no); 4435 assert(sysTime == SysTime(Date(1999, 6, 6))); 4436 } 4437 4438 { 4439 auto sysTime = SysTime(Date(1999, 7, 6)); 4440 sysTime.roll!"months"(6, AllowDayOverflow.no); 4441 assert(sysTime == SysTime(Date(1999, 1, 6))); 4442 sysTime.roll!"months"(-6, AllowDayOverflow.no); 4443 assert(sysTime == SysTime(Date(1999, 7, 6))); 4444 } 4445 4446 { 4447 auto sysTime = SysTime(Date(1999, 7, 6)); 4448 sysTime.roll!"months"(27, AllowDayOverflow.no); 4449 assert(sysTime == SysTime(Date(1999, 10, 6))); 4450 sysTime.roll!"months"(-28, AllowDayOverflow.no); 4451 assert(sysTime == SysTime(Date(1999, 6, 6))); 4452 } 4453 4454 { 4455 auto sysTime = SysTime(Date(1999, 5, 31)); 4456 sysTime.roll!"months"(1, AllowDayOverflow.no); 4457 assert(sysTime == SysTime(Date(1999, 6, 30))); 4458 } 4459 4460 { 4461 auto sysTime = SysTime(Date(1999, 5, 31)); 4462 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4463 assert(sysTime == SysTime(Date(1999, 4, 30))); 4464 } 4465 4466 { 4467 auto sysTime = SysTime(Date(1999, 2, 28)); 4468 sysTime.roll!"months"(12, AllowDayOverflow.no); 4469 assert(sysTime == SysTime(Date(1999, 2, 28))); 4470 } 4471 4472 { 4473 auto sysTime = SysTime(Date(2000, 2, 29)); 4474 sysTime.roll!"months"(12, AllowDayOverflow.no); 4475 assert(sysTime == SysTime(Date(2000, 2, 29))); 4476 } 4477 4478 { 4479 auto sysTime = SysTime(Date(1999, 7, 31)); 4480 sysTime.roll!"months"(1, AllowDayOverflow.no); 4481 assert(sysTime == SysTime(Date(1999, 8, 31))); 4482 sysTime.roll!"months"(1, AllowDayOverflow.no); 4483 assert(sysTime == SysTime(Date(1999, 9, 30))); 4484 } 4485 4486 { 4487 auto sysTime = SysTime(Date(1998, 8, 31)); 4488 sysTime.roll!"months"(13, AllowDayOverflow.no); 4489 assert(sysTime == SysTime(Date(1998, 9, 30))); 4490 sysTime.roll!"months"(-13, AllowDayOverflow.no); 4491 assert(sysTime == SysTime(Date(1998, 8, 30))); 4492 } 4493 4494 { 4495 auto sysTime = SysTime(Date(1997, 12, 31)); 4496 sysTime.roll!"months"(13, AllowDayOverflow.no); 4497 assert(sysTime == SysTime(Date(1997, 1, 31))); 4498 sysTime.roll!"months"(-13, AllowDayOverflow.no); 4499 assert(sysTime == SysTime(Date(1997, 12, 31))); 4500 } 4501 4502 { 4503 auto sysTime = SysTime(Date(1997, 12, 31)); 4504 sysTime.roll!"months"(14, AllowDayOverflow.no); 4505 assert(sysTime == SysTime(Date(1997, 2, 28))); 4506 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4507 assert(sysTime == SysTime(Date(1997, 12, 28))); 4508 } 4509 4510 { 4511 auto sysTime = SysTime(Date(1998, 12, 31)); 4512 sysTime.roll!"months"(14, AllowDayOverflow.no); 4513 assert(sysTime == SysTime(Date(1998, 2, 28))); 4514 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4515 assert(sysTime == SysTime(Date(1998, 12, 28))); 4516 } 4517 4518 { 4519 auto sysTime = SysTime(Date(1999, 12, 31)); 4520 sysTime.roll!"months"(14, AllowDayOverflow.no); 4521 assert(sysTime == SysTime(Date(1999, 2, 28))); 4522 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4523 assert(sysTime == SysTime(Date(1999, 12, 28))); 4524 } 4525 4526 { 4527 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), usecs(5007)); 4528 sysTime.roll!"months"(3, AllowDayOverflow.no); 4529 assert(sysTime == SysTime(DateTime(1999, 10, 6, 12, 2, 7), usecs(5007))); 4530 sysTime.roll!"months"(-4, AllowDayOverflow.no); 4531 assert(sysTime == SysTime(DateTime(1999, 6, 6, 12, 2, 7), usecs(5007))); 4532 } 4533 4534 { 4535 auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), hnsecs(422202)); 4536 sysTime.roll!"months"(14, AllowDayOverflow.no); 4537 assert(sysTime == SysTime(DateTime(1998, 2, 28, 7, 7, 7), hnsecs(422202))); 4538 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4539 assert(sysTime == SysTime(DateTime(1998, 12, 28, 7, 7, 7), hnsecs(422202))); 4540 } 4541 4542 { 4543 auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), hnsecs(422202)); 4544 sysTime.roll!"months"(14, AllowDayOverflow.no); 4545 assert(sysTime == SysTime(DateTime(1999, 2, 28, 7, 7, 7), hnsecs(422202))); 4546 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4547 assert(sysTime == SysTime(DateTime(1999, 12, 28, 7, 7, 7), hnsecs(422202))); 4548 } 4549 4550 // Test B.C. 4551 { 4552 auto sysTime = SysTime(Date(-1999, 7, 6)); 4553 sysTime.roll!"months"(3, AllowDayOverflow.no); 4554 assert(sysTime == SysTime(Date(-1999, 10, 6))); 4555 sysTime.roll!"months"(-4, AllowDayOverflow.no); 4556 assert(sysTime == SysTime(Date(-1999, 6, 6))); 4557 } 4558 4559 { 4560 auto sysTime = SysTime(Date(-1999, 7, 6)); 4561 sysTime.roll!"months"(6, AllowDayOverflow.no); 4562 assert(sysTime == SysTime(Date(-1999, 1, 6))); 4563 sysTime.roll!"months"(-6, AllowDayOverflow.no); 4564 assert(sysTime == SysTime(Date(-1999, 7, 6))); 4565 } 4566 4567 { 4568 auto sysTime = SysTime(Date(-1999, 7, 6)); 4569 sysTime.roll!"months"(-27, AllowDayOverflow.no); 4570 assert(sysTime == SysTime(Date(-1999, 4, 6))); 4571 sysTime.roll!"months"(28, AllowDayOverflow.no); 4572 assert(sysTime == SysTime(Date(-1999, 8, 6))); 4573 } 4574 4575 { 4576 auto sysTime = SysTime(Date(-1999, 5, 31)); 4577 sysTime.roll!"months"(1, AllowDayOverflow.no); 4578 assert(sysTime == SysTime(Date(-1999, 6, 30))); 4579 } 4580 4581 { 4582 auto sysTime = SysTime(Date(-1999, 5, 31)); 4583 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4584 assert(sysTime == SysTime(Date(-1999, 4, 30))); 4585 } 4586 4587 { 4588 auto sysTime = SysTime(Date(-1999, 2, 28)); 4589 sysTime.roll!"months"(-12, AllowDayOverflow.no); 4590 assert(sysTime == SysTime(Date(-1999, 2, 28))); 4591 } 4592 4593 { 4594 auto sysTime = SysTime(Date(-2000, 2, 29)); 4595 sysTime.roll!"months"(-12, AllowDayOverflow.no); 4596 assert(sysTime == SysTime(Date(-2000, 2, 29))); 4597 } 4598 4599 { 4600 auto sysTime = SysTime(Date(-1999, 7, 31)); 4601 sysTime.roll!"months"(1, AllowDayOverflow.no); 4602 assert(sysTime == SysTime(Date(-1999, 8, 31))); 4603 sysTime.roll!"months"(1, AllowDayOverflow.no); 4604 assert(sysTime == SysTime(Date(-1999, 9, 30))); 4605 } 4606 4607 { 4608 auto sysTime = SysTime(Date(-1998, 8, 31)); 4609 sysTime.roll!"months"(13, AllowDayOverflow.no); 4610 assert(sysTime == SysTime(Date(-1998, 9, 30))); 4611 sysTime.roll!"months"(-13, AllowDayOverflow.no); 4612 assert(sysTime == SysTime(Date(-1998, 8, 30))); 4613 } 4614 4615 { 4616 auto sysTime = SysTime(Date(-1997, 12, 31)); 4617 sysTime.roll!"months"(13, AllowDayOverflow.no); 4618 assert(sysTime == SysTime(Date(-1997, 1, 31))); 4619 sysTime.roll!"months"(-13, AllowDayOverflow.no); 4620 assert(sysTime == SysTime(Date(-1997, 12, 31))); 4621 } 4622 4623 { 4624 auto sysTime = SysTime(Date(-1997, 12, 31)); 4625 sysTime.roll!"months"(14, AllowDayOverflow.no); 4626 assert(sysTime == SysTime(Date(-1997, 2, 28))); 4627 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4628 assert(sysTime == SysTime(Date(-1997, 12, 28))); 4629 } 4630 4631 { 4632 auto sysTime = SysTime(Date(-2002, 12, 31)); 4633 sysTime.roll!"months"(14, AllowDayOverflow.no); 4634 assert(sysTime == SysTime(Date(-2002, 2, 28))); 4635 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4636 assert(sysTime == SysTime(Date(-2002, 12, 28))); 4637 } 4638 4639 { 4640 auto sysTime = SysTime(Date(-2001, 12, 31)); 4641 sysTime.roll!"months"(14, AllowDayOverflow.no); 4642 assert(sysTime == SysTime(Date(-2001, 2, 28))); 4643 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4644 assert(sysTime == SysTime(Date(-2001, 12, 28))); 4645 } 4646 4647 { 4648 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), usecs(5007)); 4649 sysTime.roll!"months"(3, AllowDayOverflow.no); 4650 assert(sysTime == SysTime(DateTime(-1999, 10, 6, 12, 2, 7), usecs(5007))); 4651 sysTime.roll!"months"(-4, AllowDayOverflow.no); 4652 assert(sysTime == SysTime(DateTime(-1999, 6, 6, 12, 2, 7), usecs(5007))); 4653 } 4654 4655 { 4656 auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), hnsecs(422202)); 4657 sysTime.roll!"months"(14, AllowDayOverflow.no); 4658 assert(sysTime == SysTime(DateTime(-2002, 2, 28, 7, 7, 7), hnsecs(422202))); 4659 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4660 assert(sysTime == SysTime(DateTime(-2002, 12, 28, 7, 7, 7), hnsecs(422202))); 4661 } 4662 4663 { 4664 auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), hnsecs(422202)); 4665 sysTime.roll!"months"(14, AllowDayOverflow.no); 4666 assert(sysTime == SysTime(DateTime(-2001, 2, 28, 7, 7, 7), hnsecs(422202))); 4667 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4668 assert(sysTime == SysTime(DateTime(-2001, 12, 28, 7, 7, 7), hnsecs(422202))); 4669 } 4670 4671 // Test Both 4672 { 4673 auto sysTime = SysTime(Date(1, 1, 1)); 4674 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4675 assert(sysTime == SysTime(Date(1, 12, 1))); 4676 sysTime.roll!"months"(1, AllowDayOverflow.no); 4677 assert(sysTime == SysTime(Date(1, 1, 1))); 4678 } 4679 4680 { 4681 auto sysTime = SysTime(Date(4, 1, 1)); 4682 sysTime.roll!"months"(-48, AllowDayOverflow.no); 4683 assert(sysTime == SysTime(Date(4, 1, 1))); 4684 sysTime.roll!"months"(48, AllowDayOverflow.no); 4685 assert(sysTime == SysTime(Date(4, 1, 1))); 4686 } 4687 4688 { 4689 auto sysTime = SysTime(Date(4, 3, 31)); 4690 sysTime.roll!"months"(-49, AllowDayOverflow.no); 4691 assert(sysTime == SysTime(Date(4, 2, 29))); 4692 sysTime.roll!"months"(49, AllowDayOverflow.no); 4693 assert(sysTime == SysTime(Date(4, 3, 29))); 4694 } 4695 4696 { 4697 auto sysTime = SysTime(Date(4, 3, 31)); 4698 sysTime.roll!"months"(-85, AllowDayOverflow.no); 4699 assert(sysTime == SysTime(Date(4, 2, 29))); 4700 sysTime.roll!"months"(85, AllowDayOverflow.no); 4701 assert(sysTime == SysTime(Date(4, 3, 29))); 4702 } 4703 4704 { 4705 auto sysTime = SysTime(Date(-1, 1, 1)); 4706 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4707 assert(sysTime == SysTime(Date(-1, 12, 1))); 4708 sysTime.roll!"months"(1, AllowDayOverflow.no); 4709 assert(sysTime == SysTime(Date(-1, 1, 1))); 4710 } 4711 4712 { 4713 auto sysTime = SysTime(Date(-4, 1, 1)); 4714 sysTime.roll!"months"(-48, AllowDayOverflow.no); 4715 assert(sysTime == SysTime(Date(-4, 1, 1))); 4716 sysTime.roll!"months"(48, AllowDayOverflow.no); 4717 assert(sysTime == SysTime(Date(-4, 1, 1))); 4718 } 4719 4720 { 4721 auto sysTime = SysTime(Date(-4, 3, 31)); 4722 sysTime.roll!"months"(-49, AllowDayOverflow.no); 4723 assert(sysTime == SysTime(Date(-4, 2, 29))); 4724 sysTime.roll!"months"(49, AllowDayOverflow.no); 4725 assert(sysTime == SysTime(Date(-4, 3, 29))); 4726 } 4727 4728 { 4729 auto sysTime = SysTime(Date(-4, 3, 31)); 4730 sysTime.roll!"months"(-85, AllowDayOverflow.no); 4731 assert(sysTime == SysTime(Date(-4, 2, 29))); 4732 sysTime.roll!"months"(85, AllowDayOverflow.no); 4733 assert(sysTime == SysTime(Date(-4, 3, 29))); 4734 } 4735 4736 { 4737 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 4738 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4739 assert(sysTime == SysTime(DateTime(1, 12, 1, 0, 0, 0))); 4740 sysTime.roll!"months"(1, AllowDayOverflow.no); 4741 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 4742 } 4743 4744 { 4745 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 4746 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4747 assert(sysTime == SysTime(DateTime(1, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 4748 sysTime.roll!"months"(1, AllowDayOverflow.no); 4749 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 4750 } 4751 4752 { 4753 auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0)); 4754 sysTime.roll!"months"(1, AllowDayOverflow.no); 4755 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0))); 4756 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4757 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 4758 } 4759 4760 { 4761 auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)); 4762 sysTime.roll!"months"(1, AllowDayOverflow.no); 4763 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 4764 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4765 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 4766 } 4767 4768 { 4769 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17)); 4770 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4771 assert(sysTime == SysTime(DateTime(1, 12, 1, 0, 7, 9), hnsecs(17))); 4772 sysTime.roll!"months"(1, AllowDayOverflow.no); 4773 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17))); 4774 } 4775 4776 { 4777 auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), msecs(9)); 4778 sysTime.roll!"months"(-85, AllowDayOverflow.no); 4779 assert(sysTime == SysTime(DateTime(4, 2, 29, 12, 11, 10), msecs(9))); 4780 sysTime.roll!"months"(85, AllowDayOverflow.no); 4781 assert(sysTime == SysTime(DateTime(4, 3, 29, 12, 11, 10), msecs(9))); 4782 } 4783 4784 { 4785 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 4786 sysTime.roll!"months"(85, AllowDayOverflow.no); 4787 assert(sysTime == SysTime(DateTime(-3, 4, 30, 12, 11, 10), msecs(9))); 4788 sysTime.roll!"months"(-85, AllowDayOverflow.no); 4789 assert(sysTime == SysTime(DateTime(-3, 3, 30, 12, 11, 10), msecs(9))); 4790 } 4791 4792 { 4793 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 4794 sysTime.roll!"months"(85, AllowDayOverflow.no).roll!"months"(-83, AllowDayOverflow.no); 4795 assert(sysTime == SysTime(DateTime(-3, 5, 30, 12, 11, 10), msecs(9))); 4796 } 4797 } 4798 4799 4800 /++ 4801 Adds the given number of units to this $(LREF SysTime). A negative number 4802 will subtract. 4803 4804 The difference between rolling and adding is that rolling does not 4805 affect larger units. For instance, rolling a $(LREF SysTime) one 4806 year's worth of days gets the exact same $(LREF SysTime). 4807 4808 Accepted units are `"days"`, `"minutes"`, `"hours"`, 4809 `"minutes"`, `"seconds"`, `"msecs"`, `"usecs"`, and 4810 `"hnsecs"`. 4811 4812 Note that when rolling msecs, usecs or hnsecs, they all add up to a 4813 second. So, for example, rolling 1000 msecs is exactly the same as 4814 rolling 100,000 usecs. 4815 4816 Params: 4817 units = The units to add. 4818 value = The number of $(D_PARAM units) to add to this 4819 $(LREF SysTime). 4820 +/ 4821 ref SysTime roll(string units)(long value) @safe nothrow scope 4822 if (units == "days") 4823 { 4824 auto hnsecs = adjTime; 4825 auto gdays = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 4826 4827 if (hnsecs < 0) 4828 { 4829 hnsecs += convert!("hours", "hnsecs")(24); 4830 --gdays; 4831 } 4832 4833 auto date = Date(cast(int) gdays); 4834 date.roll!"days"(value); 4835 gdays = date.dayOfGregorianCal - 1; 4836 4837 if (gdays < 0) 4838 { 4839 hnsecs -= convert!("hours", "hnsecs")(24); 4840 ++gdays; 4841 } 4842 4843 immutable newDaysHNSecs = convert!("days", "hnsecs")(gdays); 4844 adjTime = newDaysHNSecs + hnsecs; 4845 return this; 4846 } 4847 4848 /// 4849 @safe unittest 4850 { 4851 import core.time : msecs, hnsecs; 4852 import std.datetime.date : DateTime; 4853 4854 auto st1 = SysTime(DateTime(2010, 1, 1, 11, 23, 12)); 4855 st1.roll!"days"(1); 4856 assert(st1 == SysTime(DateTime(2010, 1, 2, 11, 23, 12))); 4857 st1.roll!"days"(365); 4858 assert(st1 == SysTime(DateTime(2010, 1, 26, 11, 23, 12))); 4859 st1.roll!"days"(-32); 4860 assert(st1 == SysTime(DateTime(2010, 1, 25, 11, 23, 12))); 4861 4862 auto st2 = SysTime(DateTime(2010, 7, 4, 12, 0, 0)); 4863 st2.roll!"hours"(1); 4864 assert(st2 == SysTime(DateTime(2010, 7, 4, 13, 0, 0))); 4865 4866 auto st3 = SysTime(DateTime(2010, 2, 12, 12, 0, 0)); 4867 st3.roll!"hours"(-1); 4868 assert(st3 == SysTime(DateTime(2010, 2, 12, 11, 0, 0))); 4869 4870 auto st4 = SysTime(DateTime(2009, 12, 31, 0, 0, 0)); 4871 st4.roll!"minutes"(1); 4872 assert(st4 == SysTime(DateTime(2009, 12, 31, 0, 1, 0))); 4873 4874 auto st5 = SysTime(DateTime(2010, 1, 1, 0, 0, 0)); 4875 st5.roll!"minutes"(-1); 4876 assert(st5 == SysTime(DateTime(2010, 1, 1, 0, 59, 0))); 4877 4878 auto st6 = SysTime(DateTime(2009, 12, 31, 0, 0, 0)); 4879 st6.roll!"seconds"(1); 4880 assert(st6 == SysTime(DateTime(2009, 12, 31, 0, 0, 1))); 4881 4882 auto st7 = SysTime(DateTime(2010, 1, 1, 0, 0, 0)); 4883 st7.roll!"seconds"(-1); 4884 assert(st7 == SysTime(DateTime(2010, 1, 1, 0, 0, 59))); 4885 4886 auto dt = DateTime(2010, 1, 1, 0, 0, 0); 4887 auto st8 = SysTime(dt); 4888 st8.roll!"msecs"(1); 4889 assert(st8 == SysTime(dt, msecs(1))); 4890 4891 auto st9 = SysTime(dt); 4892 st9.roll!"msecs"(-1); 4893 assert(st9 == SysTime(dt, msecs(999))); 4894 4895 auto st10 = SysTime(dt); 4896 st10.roll!"hnsecs"(1); 4897 assert(st10 == SysTime(dt, hnsecs(1))); 4898 4899 auto st11 = SysTime(dt); 4900 st11.roll!"hnsecs"(-1); 4901 assert(st11 == SysTime(dt, hnsecs(9_999_999))); 4902 } 4903 4904 @safe unittest 4905 { 4906 import core.time; 4907 // Test A.D. 4908 { 4909 auto sysTime = SysTime(Date(1999, 2, 28)); 4910 sysTime.roll!"days"(1); 4911 assert(sysTime == SysTime(Date(1999, 2, 1))); 4912 sysTime.roll!"days"(-1); 4913 assert(sysTime == SysTime(Date(1999, 2, 28))); 4914 } 4915 4916 { 4917 auto sysTime = SysTime(Date(2000, 2, 28)); 4918 sysTime.roll!"days"(1); 4919 assert(sysTime == SysTime(Date(2000, 2, 29))); 4920 sysTime.roll!"days"(1); 4921 assert(sysTime == SysTime(Date(2000, 2, 1))); 4922 sysTime.roll!"days"(-1); 4923 assert(sysTime == SysTime(Date(2000, 2, 29))); 4924 } 4925 4926 { 4927 auto sysTime = SysTime(Date(1999, 6, 30)); 4928 sysTime.roll!"days"(1); 4929 assert(sysTime == SysTime(Date(1999, 6, 1))); 4930 sysTime.roll!"days"(-1); 4931 assert(sysTime == SysTime(Date(1999, 6, 30))); 4932 } 4933 4934 { 4935 auto sysTime = SysTime(Date(1999, 7, 31)); 4936 sysTime.roll!"days"(1); 4937 assert(sysTime == SysTime(Date(1999, 7, 1))); 4938 sysTime.roll!"days"(-1); 4939 assert(sysTime == SysTime(Date(1999, 7, 31))); 4940 } 4941 4942 { 4943 auto sysTime = SysTime(Date(1999, 1, 1)); 4944 sysTime.roll!"days"(-1); 4945 assert(sysTime == SysTime(Date(1999, 1, 31))); 4946 sysTime.roll!"days"(1); 4947 assert(sysTime == SysTime(Date(1999, 1, 1))); 4948 } 4949 4950 { 4951 auto sysTime = SysTime(Date(1999, 7, 6)); 4952 sysTime.roll!"days"(9); 4953 assert(sysTime == SysTime(Date(1999, 7, 15))); 4954 sysTime.roll!"days"(-11); 4955 assert(sysTime == SysTime(Date(1999, 7, 4))); 4956 sysTime.roll!"days"(30); 4957 assert(sysTime == SysTime(Date(1999, 7, 3))); 4958 sysTime.roll!"days"(-3); 4959 assert(sysTime == SysTime(Date(1999, 7, 31))); 4960 } 4961 4962 { 4963 auto sysTime = SysTime(Date(1999, 7, 6)); 4964 sysTime.roll!"days"(365); 4965 assert(sysTime == SysTime(Date(1999, 7, 30))); 4966 sysTime.roll!"days"(-365); 4967 assert(sysTime == SysTime(Date(1999, 7, 6))); 4968 sysTime.roll!"days"(366); 4969 assert(sysTime == SysTime(Date(1999, 7, 31))); 4970 sysTime.roll!"days"(730); 4971 assert(sysTime == SysTime(Date(1999, 7, 17))); 4972 sysTime.roll!"days"(-1096); 4973 assert(sysTime == SysTime(Date(1999, 7, 6))); 4974 } 4975 4976 { 4977 auto sysTime = SysTime(Date(1999, 2, 6)); 4978 sysTime.roll!"days"(365); 4979 assert(sysTime == SysTime(Date(1999, 2, 7))); 4980 sysTime.roll!"days"(-365); 4981 assert(sysTime == SysTime(Date(1999, 2, 6))); 4982 sysTime.roll!"days"(366); 4983 assert(sysTime == SysTime(Date(1999, 2, 8))); 4984 sysTime.roll!"days"(730); 4985 assert(sysTime == SysTime(Date(1999, 2, 10))); 4986 sysTime.roll!"days"(-1096); 4987 assert(sysTime == SysTime(Date(1999, 2, 6))); 4988 } 4989 4990 { 4991 auto sysTime = SysTime(DateTime(1999, 2, 28, 7, 9, 2), usecs(234578)); 4992 sysTime.roll!"days"(1); 4993 assert(sysTime == SysTime(DateTime(1999, 2, 1, 7, 9, 2), usecs(234578))); 4994 sysTime.roll!"days"(-1); 4995 assert(sysTime == SysTime(DateTime(1999, 2, 28, 7, 9, 2), usecs(234578))); 4996 } 4997 4998 { 4999 auto sysTime = SysTime(DateTime(1999, 7, 6, 7, 9, 2), usecs(234578)); 5000 sysTime.roll!"days"(9); 5001 assert(sysTime == SysTime(DateTime(1999, 7, 15, 7, 9, 2), usecs(234578))); 5002 sysTime.roll!"days"(-11); 5003 assert(sysTime == SysTime(DateTime(1999, 7, 4, 7, 9, 2), usecs(234578))); 5004 sysTime.roll!"days"(30); 5005 assert(sysTime == SysTime(DateTime(1999, 7, 3, 7, 9, 2), usecs(234578))); 5006 sysTime.roll!"days"(-3); 5007 assert(sysTime == SysTime(DateTime(1999, 7, 31, 7, 9, 2), usecs(234578))); 5008 } 5009 5010 // Test B.C. 5011 { 5012 auto sysTime = SysTime(Date(-1999, 2, 28)); 5013 sysTime.roll!"days"(1); 5014 assert(sysTime == SysTime(Date(-1999, 2, 1))); 5015 sysTime.roll!"days"(-1); 5016 assert(sysTime == SysTime(Date(-1999, 2, 28))); 5017 } 5018 5019 { 5020 auto sysTime = SysTime(Date(-2000, 2, 28)); 5021 sysTime.roll!"days"(1); 5022 assert(sysTime == SysTime(Date(-2000, 2, 29))); 5023 sysTime.roll!"days"(1); 5024 assert(sysTime == SysTime(Date(-2000, 2, 1))); 5025 sysTime.roll!"days"(-1); 5026 assert(sysTime == SysTime(Date(-2000, 2, 29))); 5027 } 5028 5029 { 5030 auto sysTime = SysTime(Date(-1999, 6, 30)); 5031 sysTime.roll!"days"(1); 5032 assert(sysTime == SysTime(Date(-1999, 6, 1))); 5033 sysTime.roll!"days"(-1); 5034 assert(sysTime == SysTime(Date(-1999, 6, 30))); 5035 } 5036 5037 { 5038 auto sysTime = SysTime(Date(-1999, 7, 31)); 5039 sysTime.roll!"days"(1); 5040 assert(sysTime == SysTime(Date(-1999, 7, 1))); 5041 sysTime.roll!"days"(-1); 5042 assert(sysTime == SysTime(Date(-1999, 7, 31))); 5043 } 5044 5045 { 5046 auto sysTime = SysTime(Date(-1999, 1, 1)); 5047 sysTime.roll!"days"(-1); 5048 assert(sysTime == SysTime(Date(-1999, 1, 31))); 5049 sysTime.roll!"days"(1); 5050 assert(sysTime == SysTime(Date(-1999, 1, 1))); 5051 } 5052 5053 { 5054 auto sysTime = SysTime(Date(-1999, 7, 6)); 5055 sysTime.roll!"days"(9); 5056 assert(sysTime == SysTime(Date(-1999, 7, 15))); 5057 sysTime.roll!"days"(-11); 5058 assert(sysTime == SysTime(Date(-1999, 7, 4))); 5059 sysTime.roll!"days"(30); 5060 assert(sysTime == SysTime(Date(-1999, 7, 3))); 5061 sysTime.roll!"days"(-3); 5062 assert(sysTime == SysTime(Date(-1999, 7, 31))); 5063 } 5064 5065 { 5066 auto sysTime = SysTime(Date(-1999, 7, 6)); 5067 sysTime.roll!"days"(365); 5068 assert(sysTime == SysTime(Date(-1999, 7, 30))); 5069 sysTime.roll!"days"(-365); 5070 assert(sysTime == SysTime(Date(-1999, 7, 6))); 5071 sysTime.roll!"days"(366); 5072 assert(sysTime == SysTime(Date(-1999, 7, 31))); 5073 sysTime.roll!"days"(730); 5074 assert(sysTime == SysTime(Date(-1999, 7, 17))); 5075 sysTime.roll!"days"(-1096); 5076 assert(sysTime == SysTime(Date(-1999, 7, 6))); 5077 } 5078 5079 { 5080 auto sysTime = SysTime(DateTime(-1999, 2, 28, 7, 9, 2), usecs(234578)); 5081 sysTime.roll!"days"(1); 5082 assert(sysTime == SysTime(DateTime(-1999, 2, 1, 7, 9, 2), usecs(234578))); 5083 sysTime.roll!"days"(-1); 5084 assert(sysTime == SysTime(DateTime(-1999, 2, 28, 7, 9, 2), usecs(234578))); 5085 } 5086 5087 { 5088 auto sysTime = SysTime(DateTime(-1999, 7, 6, 7, 9, 2), usecs(234578)); 5089 sysTime.roll!"days"(9); 5090 assert(sysTime == SysTime(DateTime(-1999, 7, 15, 7, 9, 2), usecs(234578))); 5091 sysTime.roll!"days"(-11); 5092 assert(sysTime == SysTime(DateTime(-1999, 7, 4, 7, 9, 2), usecs(234578))); 5093 sysTime.roll!"days"(30); 5094 assert(sysTime == SysTime(DateTime(-1999, 7, 3, 7, 9, 2), usecs(234578))); 5095 sysTime.roll!"days"(-3); 5096 } 5097 5098 // Test Both 5099 { 5100 auto sysTime = SysTime(Date(1, 7, 6)); 5101 sysTime.roll!"days"(-365); 5102 assert(sysTime == SysTime(Date(1, 7, 13))); 5103 sysTime.roll!"days"(365); 5104 assert(sysTime == SysTime(Date(1, 7, 6))); 5105 sysTime.roll!"days"(-731); 5106 assert(sysTime == SysTime(Date(1, 7, 19))); 5107 sysTime.roll!"days"(730); 5108 assert(sysTime == SysTime(Date(1, 7, 5))); 5109 } 5110 5111 { 5112 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 5113 sysTime.roll!"days"(-1); 5114 assert(sysTime == SysTime(DateTime(1, 1, 31, 0, 0, 0))); 5115 sysTime.roll!"days"(1); 5116 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5117 } 5118 5119 { 5120 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 5121 sysTime.roll!"days"(-1); 5122 assert(sysTime == SysTime(DateTime(1, 1, 31, 23, 59, 59), hnsecs(9_999_999))); 5123 sysTime.roll!"days"(1); 5124 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 5125 } 5126 5127 { 5128 auto sysTime = SysTime(DateTime(0, 12, 31, 0, 0, 0)); 5129 sysTime.roll!"days"(1); 5130 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 5131 sysTime.roll!"days"(-1); 5132 assert(sysTime == SysTime(DateTime(0, 12, 31, 0, 0, 0))); 5133 } 5134 5135 { 5136 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5137 sysTime.roll!"days"(1); 5138 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 5139 sysTime.roll!"days"(-1); 5140 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5141 } 5142 5143 { 5144 auto sysTime = SysTime(DateTime(1, 7, 6, 13, 13, 9), msecs(22)); 5145 sysTime.roll!"days"(-365); 5146 assert(sysTime == SysTime(DateTime(1, 7, 13, 13, 13, 9), msecs(22))); 5147 sysTime.roll!"days"(365); 5148 assert(sysTime == SysTime(DateTime(1, 7, 6, 13, 13, 9), msecs(22))); 5149 sysTime.roll!"days"(-731); 5150 assert(sysTime == SysTime(DateTime(1, 7, 19, 13, 13, 9), msecs(22))); 5151 sysTime.roll!"days"(730); 5152 assert(sysTime == SysTime(DateTime(1, 7, 5, 13, 13, 9), msecs(22))); 5153 } 5154 5155 { 5156 auto sysTime = SysTime(DateTime(0, 7, 6, 13, 13, 9), msecs(22)); 5157 sysTime.roll!"days"(-365); 5158 assert(sysTime == SysTime(DateTime(0, 7, 13, 13, 13, 9), msecs(22))); 5159 sysTime.roll!"days"(365); 5160 assert(sysTime == SysTime(DateTime(0, 7, 6, 13, 13, 9), msecs(22))); 5161 sysTime.roll!"days"(-731); 5162 assert(sysTime == SysTime(DateTime(0, 7, 19, 13, 13, 9), msecs(22))); 5163 sysTime.roll!"days"(730); 5164 assert(sysTime == SysTime(DateTime(0, 7, 5, 13, 13, 9), msecs(22))); 5165 } 5166 5167 { 5168 auto sysTime = SysTime(DateTime(0, 7, 6, 13, 13, 9), msecs(22)); 5169 sysTime.roll!"days"(-365).roll!"days"(362).roll!"days"(-12).roll!"days"(730); 5170 assert(sysTime == SysTime(DateTime(0, 7, 8, 13, 13, 9), msecs(22))); 5171 } 5172 5173 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5174 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5175 static assert(!__traits(compiles, cst.roll!"days"(4))); 5176 static assert(!__traits(compiles, ist.roll!"days"(4))); 5177 5178 static void testScope(scope ref SysTime st) @safe 5179 { 5180 auto result = st.roll!"days"(42); 5181 } 5182 } 5183 5184 5185 // Shares documentation with "days" version. 5186 ref SysTime roll(string units)(long value) @safe nothrow scope 5187 if (units == "hours" || units == "minutes" || units == "seconds") 5188 { 5189 try 5190 { 5191 auto hnsecs = adjTime; 5192 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 5193 5194 if (hnsecs < 0) 5195 { 5196 hnsecs += convert!("hours", "hnsecs")(24); 5197 --days; 5198 } 5199 5200 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 5201 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 5202 immutable second = splitUnitsFromHNSecs!"seconds"(hnsecs); 5203 5204 auto dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour, 5205 cast(int) minute, cast(int) second)); 5206 dateTime.roll!units(value); 5207 --days; 5208 5209 hnsecs += convert!("hours", "hnsecs")(dateTime.hour); 5210 hnsecs += convert!("minutes", "hnsecs")(dateTime.minute); 5211 hnsecs += convert!("seconds", "hnsecs")(dateTime.second); 5212 5213 if (days < 0) 5214 { 5215 hnsecs -= convert!("hours", "hnsecs")(24); 5216 ++days; 5217 } 5218 5219 immutable newDaysHNSecs = convert!("days", "hnsecs")(days); 5220 adjTime = newDaysHNSecs + hnsecs; 5221 return this; 5222 } 5223 catch (Exception e) 5224 assert(0, "Either DateTime's constructor or TimeOfDay's constructor threw."); 5225 } 5226 5227 // Test roll!"hours"(). 5228 @safe unittest 5229 { 5230 import core.time; 5231 static void testST(SysTime orig, int hours, SysTime expected, size_t line = __LINE__) @safe 5232 { 5233 orig.roll!"hours"(hours); 5234 if (orig != expected) 5235 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 5236 } 5237 5238 // Test A.D. 5239 immutable d = msecs(45); 5240 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), d); 5241 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5242 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 13, 30, 33), d)); 5243 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 14, 30, 33), d)); 5244 testST(beforeAD, 3, SysTime(DateTime(1999, 7, 6, 15, 30, 33), d)); 5245 testST(beforeAD, 4, SysTime(DateTime(1999, 7, 6, 16, 30, 33), d)); 5246 testST(beforeAD, 5, SysTime(DateTime(1999, 7, 6, 17, 30, 33), d)); 5247 testST(beforeAD, 6, SysTime(DateTime(1999, 7, 6, 18, 30, 33), d)); 5248 testST(beforeAD, 7, SysTime(DateTime(1999, 7, 6, 19, 30, 33), d)); 5249 testST(beforeAD, 8, SysTime(DateTime(1999, 7, 6, 20, 30, 33), d)); 5250 testST(beforeAD, 9, SysTime(DateTime(1999, 7, 6, 21, 30, 33), d)); 5251 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 22, 30, 33), d)); 5252 testST(beforeAD, 11, SysTime(DateTime(1999, 7, 6, 23, 30, 33), d)); 5253 testST(beforeAD, 12, SysTime(DateTime(1999, 7, 6, 0, 30, 33), d)); 5254 testST(beforeAD, 13, SysTime(DateTime(1999, 7, 6, 1, 30, 33), d)); 5255 testST(beforeAD, 14, SysTime(DateTime(1999, 7, 6, 2, 30, 33), d)); 5256 testST(beforeAD, 15, SysTime(DateTime(1999, 7, 6, 3, 30, 33), d)); 5257 testST(beforeAD, 16, SysTime(DateTime(1999, 7, 6, 4, 30, 33), d)); 5258 testST(beforeAD, 17, SysTime(DateTime(1999, 7, 6, 5, 30, 33), d)); 5259 testST(beforeAD, 18, SysTime(DateTime(1999, 7, 6, 6, 30, 33), d)); 5260 testST(beforeAD, 19, SysTime(DateTime(1999, 7, 6, 7, 30, 33), d)); 5261 testST(beforeAD, 20, SysTime(DateTime(1999, 7, 6, 8, 30, 33), d)); 5262 testST(beforeAD, 21, SysTime(DateTime(1999, 7, 6, 9, 30, 33), d)); 5263 testST(beforeAD, 22, SysTime(DateTime(1999, 7, 6, 10, 30, 33), d)); 5264 testST(beforeAD, 23, SysTime(DateTime(1999, 7, 6, 11, 30, 33), d)); 5265 testST(beforeAD, 24, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5266 testST(beforeAD, 25, SysTime(DateTime(1999, 7, 6, 13, 30, 33), d)); 5267 testST(beforeAD, 50, SysTime(DateTime(1999, 7, 6, 14, 30, 33), d)); 5268 testST(beforeAD, 10_000, SysTime(DateTime(1999, 7, 6, 4, 30, 33), d)); 5269 5270 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 11, 30, 33), d)); 5271 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 10, 30, 33), d)); 5272 testST(beforeAD, -3, SysTime(DateTime(1999, 7, 6, 9, 30, 33), d)); 5273 testST(beforeAD, -4, SysTime(DateTime(1999, 7, 6, 8, 30, 33), d)); 5274 testST(beforeAD, -5, SysTime(DateTime(1999, 7, 6, 7, 30, 33), d)); 5275 testST(beforeAD, -6, SysTime(DateTime(1999, 7, 6, 6, 30, 33), d)); 5276 testST(beforeAD, -7, SysTime(DateTime(1999, 7, 6, 5, 30, 33), d)); 5277 testST(beforeAD, -8, SysTime(DateTime(1999, 7, 6, 4, 30, 33), d)); 5278 testST(beforeAD, -9, SysTime(DateTime(1999, 7, 6, 3, 30, 33), d)); 5279 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 2, 30, 33), d)); 5280 testST(beforeAD, -11, SysTime(DateTime(1999, 7, 6, 1, 30, 33), d)); 5281 testST(beforeAD, -12, SysTime(DateTime(1999, 7, 6, 0, 30, 33), d)); 5282 testST(beforeAD, -13, SysTime(DateTime(1999, 7, 6, 23, 30, 33), d)); 5283 testST(beforeAD, -14, SysTime(DateTime(1999, 7, 6, 22, 30, 33), d)); 5284 testST(beforeAD, -15, SysTime(DateTime(1999, 7, 6, 21, 30, 33), d)); 5285 testST(beforeAD, -16, SysTime(DateTime(1999, 7, 6, 20, 30, 33), d)); 5286 testST(beforeAD, -17, SysTime(DateTime(1999, 7, 6, 19, 30, 33), d)); 5287 testST(beforeAD, -18, SysTime(DateTime(1999, 7, 6, 18, 30, 33), d)); 5288 testST(beforeAD, -19, SysTime(DateTime(1999, 7, 6, 17, 30, 33), d)); 5289 testST(beforeAD, -20, SysTime(DateTime(1999, 7, 6, 16, 30, 33), d)); 5290 testST(beforeAD, -21, SysTime(DateTime(1999, 7, 6, 15, 30, 33), d)); 5291 testST(beforeAD, -22, SysTime(DateTime(1999, 7, 6, 14, 30, 33), d)); 5292 testST(beforeAD, -23, SysTime(DateTime(1999, 7, 6, 13, 30, 33), d)); 5293 testST(beforeAD, -24, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5294 testST(beforeAD, -25, SysTime(DateTime(1999, 7, 6, 11, 30, 33), d)); 5295 testST(beforeAD, -50, SysTime(DateTime(1999, 7, 6, 10, 30, 33), d)); 5296 testST(beforeAD, -10_000, SysTime(DateTime(1999, 7, 6, 20, 30, 33), d)); 5297 5298 testST(SysTime(DateTime(1999, 7, 6, 0, 30, 33), d), 1, SysTime(DateTime(1999, 7, 6, 1, 30, 33), d)); 5299 testST(SysTime(DateTime(1999, 7, 6, 0, 30, 33), d), 0, SysTime(DateTime(1999, 7, 6, 0, 30, 33), d)); 5300 testST(SysTime(DateTime(1999, 7, 6, 0, 30, 33), d), -1, SysTime(DateTime(1999, 7, 6, 23, 30, 33), d)); 5301 5302 testST(SysTime(DateTime(1999, 7, 6, 23, 30, 33), d), 1, SysTime(DateTime(1999, 7, 6, 0, 30, 33), d)); 5303 testST(SysTime(DateTime(1999, 7, 6, 23, 30, 33), d), 0, SysTime(DateTime(1999, 7, 6, 23, 30, 33), d)); 5304 testST(SysTime(DateTime(1999, 7, 6, 23, 30, 33), d), -1, SysTime(DateTime(1999, 7, 6, 22, 30, 33), d)); 5305 5306 testST(SysTime(DateTime(1999, 7, 31, 23, 30, 33), d), 1, SysTime(DateTime(1999, 7, 31, 0, 30, 33), d)); 5307 testST(SysTime(DateTime(1999, 8, 1, 0, 30, 33), d), -1, SysTime(DateTime(1999, 8, 1, 23, 30, 33), d)); 5308 5309 testST(SysTime(DateTime(1999, 12, 31, 23, 30, 33), d), 1, SysTime(DateTime(1999, 12, 31, 0, 30, 33), d)); 5310 testST(SysTime(DateTime(2000, 1, 1, 0, 30, 33), d), -1, SysTime(DateTime(2000, 1, 1, 23, 30, 33), d)); 5311 5312 testST(SysTime(DateTime(1999, 2, 28, 23, 30, 33), d), 25, SysTime(DateTime(1999, 2, 28, 0, 30, 33), d)); 5313 testST(SysTime(DateTime(1999, 3, 2, 0, 30, 33), d), -25, SysTime(DateTime(1999, 3, 2, 23, 30, 33), d)); 5314 5315 testST(SysTime(DateTime(2000, 2, 28, 23, 30, 33), d), 25, SysTime(DateTime(2000, 2, 28, 0, 30, 33), d)); 5316 testST(SysTime(DateTime(2000, 3, 1, 0, 30, 33), d), -25, SysTime(DateTime(2000, 3, 1, 23, 30, 33), d)); 5317 5318 // Test B.C. 5319 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d); 5320 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5321 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), d)); 5322 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 14, 30, 33), d)); 5323 testST(beforeBC, 3, SysTime(DateTime(-1999, 7, 6, 15, 30, 33), d)); 5324 testST(beforeBC, 4, SysTime(DateTime(-1999, 7, 6, 16, 30, 33), d)); 5325 testST(beforeBC, 5, SysTime(DateTime(-1999, 7, 6, 17, 30, 33), d)); 5326 testST(beforeBC, 6, SysTime(DateTime(-1999, 7, 6, 18, 30, 33), d)); 5327 testST(beforeBC, 7, SysTime(DateTime(-1999, 7, 6, 19, 30, 33), d)); 5328 testST(beforeBC, 8, SysTime(DateTime(-1999, 7, 6, 20, 30, 33), d)); 5329 testST(beforeBC, 9, SysTime(DateTime(-1999, 7, 6, 21, 30, 33), d)); 5330 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 22, 30, 33), d)); 5331 testST(beforeBC, 11, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d)); 5332 testST(beforeBC, 12, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d)); 5333 testST(beforeBC, 13, SysTime(DateTime(-1999, 7, 6, 1, 30, 33), d)); 5334 testST(beforeBC, 14, SysTime(DateTime(-1999, 7, 6, 2, 30, 33), d)); 5335 testST(beforeBC, 15, SysTime(DateTime(-1999, 7, 6, 3, 30, 33), d)); 5336 testST(beforeBC, 16, SysTime(DateTime(-1999, 7, 6, 4, 30, 33), d)); 5337 testST(beforeBC, 17, SysTime(DateTime(-1999, 7, 6, 5, 30, 33), d)); 5338 testST(beforeBC, 18, SysTime(DateTime(-1999, 7, 6, 6, 30, 33), d)); 5339 testST(beforeBC, 19, SysTime(DateTime(-1999, 7, 6, 7, 30, 33), d)); 5340 testST(beforeBC, 20, SysTime(DateTime(-1999, 7, 6, 8, 30, 33), d)); 5341 testST(beforeBC, 21, SysTime(DateTime(-1999, 7, 6, 9, 30, 33), d)); 5342 testST(beforeBC, 22, SysTime(DateTime(-1999, 7, 6, 10, 30, 33), d)); 5343 testST(beforeBC, 23, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), d)); 5344 testST(beforeBC, 24, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5345 testST(beforeBC, 25, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), d)); 5346 testST(beforeBC, 50, SysTime(DateTime(-1999, 7, 6, 14, 30, 33), d)); 5347 testST(beforeBC, 10_000, SysTime(DateTime(-1999, 7, 6, 4, 30, 33), d)); 5348 5349 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), d)); 5350 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 10, 30, 33), d)); 5351 testST(beforeBC, -3, SysTime(DateTime(-1999, 7, 6, 9, 30, 33), d)); 5352 testST(beforeBC, -4, SysTime(DateTime(-1999, 7, 6, 8, 30, 33), d)); 5353 testST(beforeBC, -5, SysTime(DateTime(-1999, 7, 6, 7, 30, 33), d)); 5354 testST(beforeBC, -6, SysTime(DateTime(-1999, 7, 6, 6, 30, 33), d)); 5355 testST(beforeBC, -7, SysTime(DateTime(-1999, 7, 6, 5, 30, 33), d)); 5356 testST(beforeBC, -8, SysTime(DateTime(-1999, 7, 6, 4, 30, 33), d)); 5357 testST(beforeBC, -9, SysTime(DateTime(-1999, 7, 6, 3, 30, 33), d)); 5358 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 2, 30, 33), d)); 5359 testST(beforeBC, -11, SysTime(DateTime(-1999, 7, 6, 1, 30, 33), d)); 5360 testST(beforeBC, -12, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d)); 5361 testST(beforeBC, -13, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d)); 5362 testST(beforeBC, -14, SysTime(DateTime(-1999, 7, 6, 22, 30, 33), d)); 5363 testST(beforeBC, -15, SysTime(DateTime(-1999, 7, 6, 21, 30, 33), d)); 5364 testST(beforeBC, -16, SysTime(DateTime(-1999, 7, 6, 20, 30, 33), d)); 5365 testST(beforeBC, -17, SysTime(DateTime(-1999, 7, 6, 19, 30, 33), d)); 5366 testST(beforeBC, -18, SysTime(DateTime(-1999, 7, 6, 18, 30, 33), d)); 5367 testST(beforeBC, -19, SysTime(DateTime(-1999, 7, 6, 17, 30, 33), d)); 5368 testST(beforeBC, -20, SysTime(DateTime(-1999, 7, 6, 16, 30, 33), d)); 5369 testST(beforeBC, -21, SysTime(DateTime(-1999, 7, 6, 15, 30, 33), d)); 5370 testST(beforeBC, -22, SysTime(DateTime(-1999, 7, 6, 14, 30, 33), d)); 5371 testST(beforeBC, -23, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), d)); 5372 testST(beforeBC, -24, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5373 testST(beforeBC, -25, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), d)); 5374 testST(beforeBC, -50, SysTime(DateTime(-1999, 7, 6, 10, 30, 33), d)); 5375 testST(beforeBC, -10_000, SysTime(DateTime(-1999, 7, 6, 20, 30, 33), d)); 5376 5377 testST(SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 1, 30, 33), d)); 5378 testST(SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d)); 5379 testST(SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d)); 5380 5381 testST(SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d)); 5382 testST(SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d)); 5383 testST(SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 22, 30, 33), d)); 5384 5385 testST(SysTime(DateTime(-1999, 7, 31, 23, 30, 33), d), 1, SysTime(DateTime(-1999, 7, 31, 0, 30, 33), d)); 5386 testST(SysTime(DateTime(-1999, 8, 1, 0, 30, 33), d), -1, SysTime(DateTime(-1999, 8, 1, 23, 30, 33), d)); 5387 5388 testST(SysTime(DateTime(-2001, 12, 31, 23, 30, 33), d), 1, SysTime(DateTime(-2001, 12, 31, 0, 30, 33), d)); 5389 testST(SysTime(DateTime(-2000, 1, 1, 0, 30, 33), d), -1, SysTime(DateTime(-2000, 1, 1, 23, 30, 33), d)); 5390 5391 testST(SysTime(DateTime(-2001, 2, 28, 23, 30, 33), d), 25, SysTime(DateTime(-2001, 2, 28, 0, 30, 33), d)); 5392 testST(SysTime(DateTime(-2001, 3, 2, 0, 30, 33), d), -25, SysTime(DateTime(-2001, 3, 2, 23, 30, 33), d)); 5393 5394 testST(SysTime(DateTime(-2000, 2, 28, 23, 30, 33), d), 25, SysTime(DateTime(-2000, 2, 28, 0, 30, 33), d)); 5395 testST(SysTime(DateTime(-2000, 3, 1, 0, 30, 33), d), -25, SysTime(DateTime(-2000, 3, 1, 23, 30, 33), d)); 5396 5397 // Test Both 5398 testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 17_546, SysTime(DateTime(-1, 1, 1, 13, 30, 33), d)); 5399 testST(SysTime(DateTime(1, 1, 1, 13, 30, 33), d), -17_546, SysTime(DateTime(1, 1, 1, 11, 30, 33), d)); 5400 5401 { 5402 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 5403 sysTime.roll!"hours"(-1); 5404 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 0, 0))); 5405 sysTime.roll!"hours"(1); 5406 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5407 } 5408 5409 { 5410 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 59, 59), hnsecs(9_999_999)); 5411 sysTime.roll!"hours"(-1); 5412 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 5413 sysTime.roll!"hours"(1); 5414 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 59, 59), hnsecs(9_999_999))); 5415 } 5416 5417 { 5418 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 0, 0)); 5419 sysTime.roll!"hours"(1); 5420 assert(sysTime == SysTime(DateTime(0, 12, 31, 0, 0, 0))); 5421 sysTime.roll!"hours"(-1); 5422 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 0, 0))); 5423 } 5424 5425 { 5426 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5427 sysTime.roll!"hours"(1); 5428 assert(sysTime == SysTime(DateTime(0, 12, 31, 0, 59, 59), hnsecs(9_999_999))); 5429 sysTime.roll!"hours"(-1); 5430 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5431 } 5432 5433 { 5434 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5435 sysTime.roll!"hours"(1).roll!"hours"(-67); 5436 assert(sysTime == SysTime(DateTime(0, 12, 31, 5, 59, 59), hnsecs(9_999_999))); 5437 } 5438 5439 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5440 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5441 static assert(!__traits(compiles, cst.roll!"hours"(4))); 5442 static assert(!__traits(compiles, ist.roll!"hours"(4))); 5443 5444 static void testScope(scope ref SysTime st) @safe 5445 { 5446 auto result = st.roll!"hours"(42); 5447 } 5448 } 5449 5450 // Test roll!"minutes"(). 5451 @safe unittest 5452 { 5453 import core.time; 5454 static void testST(SysTime orig, int minutes, SysTime expected, size_t line = __LINE__) @safe 5455 { 5456 orig.roll!"minutes"(minutes); 5457 if (orig != expected) 5458 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 5459 } 5460 5461 // Test A.D. 5462 immutable d = usecs(7203); 5463 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), d); 5464 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5465 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 31, 33), d)); 5466 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 32, 33), d)); 5467 testST(beforeAD, 3, SysTime(DateTime(1999, 7, 6, 12, 33, 33), d)); 5468 testST(beforeAD, 4, SysTime(DateTime(1999, 7, 6, 12, 34, 33), d)); 5469 testST(beforeAD, 5, SysTime(DateTime(1999, 7, 6, 12, 35, 33), d)); 5470 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 40, 33), d)); 5471 testST(beforeAD, 15, SysTime(DateTime(1999, 7, 6, 12, 45, 33), d)); 5472 testST(beforeAD, 29, SysTime(DateTime(1999, 7, 6, 12, 59, 33), d)); 5473 testST(beforeAD, 30, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5474 testST(beforeAD, 45, SysTime(DateTime(1999, 7, 6, 12, 15, 33), d)); 5475 testST(beforeAD, 60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5476 testST(beforeAD, 75, SysTime(DateTime(1999, 7, 6, 12, 45, 33), d)); 5477 testST(beforeAD, 90, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5478 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 10, 33), d)); 5479 5480 testST(beforeAD, 689, SysTime(DateTime(1999, 7, 6, 12, 59, 33), d)); 5481 testST(beforeAD, 690, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5482 testST(beforeAD, 691, SysTime(DateTime(1999, 7, 6, 12, 1, 33), d)); 5483 testST(beforeAD, 960, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5484 testST(beforeAD, 1439, SysTime(DateTime(1999, 7, 6, 12, 29, 33), d)); 5485 testST(beforeAD, 1440, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5486 testST(beforeAD, 1441, SysTime(DateTime(1999, 7, 6, 12, 31, 33), d)); 5487 testST(beforeAD, 2880, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5488 5489 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 29, 33), d)); 5490 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 28, 33), d)); 5491 testST(beforeAD, -3, SysTime(DateTime(1999, 7, 6, 12, 27, 33), d)); 5492 testST(beforeAD, -4, SysTime(DateTime(1999, 7, 6, 12, 26, 33), d)); 5493 testST(beforeAD, -5, SysTime(DateTime(1999, 7, 6, 12, 25, 33), d)); 5494 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 20, 33), d)); 5495 testST(beforeAD, -15, SysTime(DateTime(1999, 7, 6, 12, 15, 33), d)); 5496 testST(beforeAD, -29, SysTime(DateTime(1999, 7, 6, 12, 1, 33), d)); 5497 testST(beforeAD, -30, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5498 testST(beforeAD, -45, SysTime(DateTime(1999, 7, 6, 12, 45, 33), d)); 5499 testST(beforeAD, -60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5500 testST(beforeAD, -75, SysTime(DateTime(1999, 7, 6, 12, 15, 33), d)); 5501 testST(beforeAD, -90, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5502 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 50, 33), d)); 5503 5504 testST(beforeAD, -749, SysTime(DateTime(1999, 7, 6, 12, 1, 33), d)); 5505 testST(beforeAD, -750, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5506 testST(beforeAD, -751, SysTime(DateTime(1999, 7, 6, 12, 59, 33), d)); 5507 testST(beforeAD, -960, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5508 testST(beforeAD, -1439, SysTime(DateTime(1999, 7, 6, 12, 31, 33), d)); 5509 testST(beforeAD, -1440, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5510 testST(beforeAD, -1441, SysTime(DateTime(1999, 7, 6, 12, 29, 33), d)); 5511 testST(beforeAD, -2880, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5512 5513 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 33), d), 1, SysTime(DateTime(1999, 7, 6, 12, 1, 33), d)); 5514 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 33), d), 0, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5515 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 33), d), -1, SysTime(DateTime(1999, 7, 6, 12, 59, 33), d)); 5516 5517 testST(SysTime(DateTime(1999, 7, 6, 11, 59, 33), d), 1, SysTime(DateTime(1999, 7, 6, 11, 0, 33), d)); 5518 testST(SysTime(DateTime(1999, 7, 6, 11, 59, 33), d), 0, SysTime(DateTime(1999, 7, 6, 11, 59, 33), d)); 5519 testST(SysTime(DateTime(1999, 7, 6, 11, 59, 33), d), -1, SysTime(DateTime(1999, 7, 6, 11, 58, 33), d)); 5520 5521 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 33), d), 1, SysTime(DateTime(1999, 7, 6, 0, 1, 33), d)); 5522 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 33), d), 0, SysTime(DateTime(1999, 7, 6, 0, 0, 33), d)); 5523 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 33), d), -1, SysTime(DateTime(1999, 7, 6, 0, 59, 33), d)); 5524 5525 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 33), d), 1, SysTime(DateTime(1999, 7, 5, 23, 0, 33), d)); 5526 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 33), d), 0, SysTime(DateTime(1999, 7, 5, 23, 59, 33), d)); 5527 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 33), d), -1, SysTime(DateTime(1999, 7, 5, 23, 58, 33), d)); 5528 5529 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 33), d), 1, SysTime(DateTime(1998, 12, 31, 23, 0, 33), d)); 5530 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 33), d), 0, SysTime(DateTime(1998, 12, 31, 23, 59, 33), d)); 5531 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 33), d), -1, SysTime(DateTime(1998, 12, 31, 23, 58, 33), d)); 5532 5533 // Test B.C. 5534 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d); 5535 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5536 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), d)); 5537 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 32, 33), d)); 5538 testST(beforeBC, 3, SysTime(DateTime(-1999, 7, 6, 12, 33, 33), d)); 5539 testST(beforeBC, 4, SysTime(DateTime(-1999, 7, 6, 12, 34, 33), d)); 5540 testST(beforeBC, 5, SysTime(DateTime(-1999, 7, 6, 12, 35, 33), d)); 5541 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 40, 33), d)); 5542 testST(beforeBC, 15, SysTime(DateTime(-1999, 7, 6, 12, 45, 33), d)); 5543 testST(beforeBC, 29, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), d)); 5544 testST(beforeBC, 30, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5545 testST(beforeBC, 45, SysTime(DateTime(-1999, 7, 6, 12, 15, 33), d)); 5546 testST(beforeBC, 60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5547 testST(beforeBC, 75, SysTime(DateTime(-1999, 7, 6, 12, 45, 33), d)); 5548 testST(beforeBC, 90, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5549 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 10, 33), d)); 5550 5551 testST(beforeBC, 689, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), d)); 5552 testST(beforeBC, 690, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5553 testST(beforeBC, 691, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), d)); 5554 testST(beforeBC, 960, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5555 testST(beforeBC, 1439, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), d)); 5556 testST(beforeBC, 1440, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5557 testST(beforeBC, 1441, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), d)); 5558 testST(beforeBC, 2880, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5559 5560 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), d)); 5561 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 28, 33), d)); 5562 testST(beforeBC, -3, SysTime(DateTime(-1999, 7, 6, 12, 27, 33), d)); 5563 testST(beforeBC, -4, SysTime(DateTime(-1999, 7, 6, 12, 26, 33), d)); 5564 testST(beforeBC, -5, SysTime(DateTime(-1999, 7, 6, 12, 25, 33), d)); 5565 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 20, 33), d)); 5566 testST(beforeBC, -15, SysTime(DateTime(-1999, 7, 6, 12, 15, 33), d)); 5567 testST(beforeBC, -29, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), d)); 5568 testST(beforeBC, -30, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5569 testST(beforeBC, -45, SysTime(DateTime(-1999, 7, 6, 12, 45, 33), d)); 5570 testST(beforeBC, -60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5571 testST(beforeBC, -75, SysTime(DateTime(-1999, 7, 6, 12, 15, 33), d)); 5572 testST(beforeBC, -90, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5573 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 50, 33), d)); 5574 5575 testST(beforeBC, -749, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), d)); 5576 testST(beforeBC, -750, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5577 testST(beforeBC, -751, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), d)); 5578 testST(beforeBC, -960, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5579 testST(beforeBC, -1439, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), d)); 5580 testST(beforeBC, -1440, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5581 testST(beforeBC, -1441, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), d)); 5582 testST(beforeBC, -2880, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5583 5584 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), d)); 5585 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5586 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), d)); 5587 5588 testST(SysTime(DateTime(-1999, 7, 6, 11, 59, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 11, 0, 33), d)); 5589 testST(SysTime(DateTime(-1999, 7, 6, 11, 59, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 11, 59, 33), d)); 5590 testST(SysTime(DateTime(-1999, 7, 6, 11, 59, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 11, 58, 33), d)); 5591 5592 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 0, 1, 33), d)); 5593 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 0, 0, 33), d)); 5594 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 0, 59, 33), d)); 5595 5596 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 33), d), 1, SysTime(DateTime(-1999, 7, 5, 23, 0, 33), d)); 5597 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 33), d), 0, SysTime(DateTime(-1999, 7, 5, 23, 59, 33), d)); 5598 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 33), d), -1, SysTime(DateTime(-1999, 7, 5, 23, 58, 33), d)); 5599 5600 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 33), d), 1, SysTime(DateTime(-2000, 12, 31, 23, 0, 33), d)); 5601 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 33), d), 0, SysTime(DateTime(-2000, 12, 31, 23, 59, 33), d)); 5602 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 33), d), -1, SysTime(DateTime(-2000, 12, 31, 23, 58, 33), d)); 5603 5604 // Test Both 5605 testST(SysTime(DateTime(1, 1, 1, 0, 0, 0)), -1, SysTime(DateTime(1, 1, 1, 0, 59, 0))); 5606 testST(SysTime(DateTime(0, 12, 31, 23, 59, 0)), 1, SysTime(DateTime(0, 12, 31, 23, 0, 0))); 5607 5608 testST(SysTime(DateTime(0, 1, 1, 0, 0, 0)), -1, SysTime(DateTime(0, 1, 1, 0, 59, 0))); 5609 testST(SysTime(DateTime(-1, 12, 31, 23, 59, 0)), 1, SysTime(DateTime(-1, 12, 31, 23, 0, 0))); 5610 5611 testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 1_052_760, SysTime(DateTime(-1, 1, 1, 11, 30, 33), d)); 5612 testST(SysTime(DateTime(1, 1, 1, 13, 30, 33), d), -1_052_760, SysTime(DateTime(1, 1, 1, 13, 30, 33), d)); 5613 5614 testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 1_052_782, SysTime(DateTime(-1, 1, 1, 11, 52, 33), d)); 5615 testST(SysTime(DateTime(1, 1, 1, 13, 52, 33), d), -1_052_782, SysTime(DateTime(1, 1, 1, 13, 30, 33), d)); 5616 5617 { 5618 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 5619 sysTime.roll!"minutes"(-1); 5620 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 59, 0))); 5621 sysTime.roll!"minutes"(1); 5622 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5623 } 5624 5625 { 5626 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 59), hnsecs(9_999_999)); 5627 sysTime.roll!"minutes"(-1); 5628 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 59, 59), hnsecs(9_999_999))); 5629 sysTime.roll!"minutes"(1); 5630 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 59), hnsecs(9_999_999))); 5631 } 5632 5633 { 5634 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 0)); 5635 sysTime.roll!"minutes"(1); 5636 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 0, 0))); 5637 sysTime.roll!"minutes"(-1); 5638 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 0))); 5639 } 5640 5641 { 5642 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5643 sysTime.roll!"minutes"(1); 5644 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 0, 59), hnsecs(9_999_999))); 5645 sysTime.roll!"minutes"(-1); 5646 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5647 } 5648 5649 { 5650 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5651 sysTime.roll!"minutes"(1).roll!"minutes"(-79); 5652 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 41, 59), hnsecs(9_999_999))); 5653 } 5654 5655 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5656 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5657 static assert(!__traits(compiles, cst.roll!"minutes"(4))); 5658 static assert(!__traits(compiles, ist.roll!"minutes"(4))); 5659 5660 static void testScope(scope ref SysTime st) @safe 5661 { 5662 auto result = st.roll!"minutes"(42); 5663 } 5664 } 5665 5666 // Test roll!"seconds"(). 5667 @safe unittest 5668 { 5669 import core.time; 5670 static void testST(SysTime orig, int seconds, SysTime expected, size_t line = __LINE__) @safe 5671 { 5672 orig.roll!"seconds"(seconds); 5673 if (orig != expected) 5674 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 5675 } 5676 5677 // Test A.D. 5678 immutable d = msecs(274); 5679 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), d); 5680 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5681 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 34), d)); 5682 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 35), d)); 5683 testST(beforeAD, 3, SysTime(DateTime(1999, 7, 6, 12, 30, 36), d)); 5684 testST(beforeAD, 4, SysTime(DateTime(1999, 7, 6, 12, 30, 37), d)); 5685 testST(beforeAD, 5, SysTime(DateTime(1999, 7, 6, 12, 30, 38), d)); 5686 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 43), d)); 5687 testST(beforeAD, 15, SysTime(DateTime(1999, 7, 6, 12, 30, 48), d)); 5688 testST(beforeAD, 26, SysTime(DateTime(1999, 7, 6, 12, 30, 59), d)); 5689 testST(beforeAD, 27, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d)); 5690 testST(beforeAD, 30, SysTime(DateTime(1999, 7, 6, 12, 30, 3), d)); 5691 testST(beforeAD, 59, SysTime(DateTime(1999, 7, 6, 12, 30, 32), d)); 5692 testST(beforeAD, 60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5693 testST(beforeAD, 61, SysTime(DateTime(1999, 7, 6, 12, 30, 34), d)); 5694 5695 testST(beforeAD, 1766, SysTime(DateTime(1999, 7, 6, 12, 30, 59), d)); 5696 testST(beforeAD, 1767, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d)); 5697 testST(beforeAD, 1768, SysTime(DateTime(1999, 7, 6, 12, 30, 1), d)); 5698 testST(beforeAD, 2007, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d)); 5699 testST(beforeAD, 3599, SysTime(DateTime(1999, 7, 6, 12, 30, 32), d)); 5700 testST(beforeAD, 3600, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5701 testST(beforeAD, 3601, SysTime(DateTime(1999, 7, 6, 12, 30, 34), d)); 5702 testST(beforeAD, 7200, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5703 5704 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 32), d)); 5705 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 31), d)); 5706 testST(beforeAD, -3, SysTime(DateTime(1999, 7, 6, 12, 30, 30), d)); 5707 testST(beforeAD, -4, SysTime(DateTime(1999, 7, 6, 12, 30, 29), d)); 5708 testST(beforeAD, -5, SysTime(DateTime(1999, 7, 6, 12, 30, 28), d)); 5709 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 23), d)); 5710 testST(beforeAD, -15, SysTime(DateTime(1999, 7, 6, 12, 30, 18), d)); 5711 testST(beforeAD, -33, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d)); 5712 testST(beforeAD, -34, SysTime(DateTime(1999, 7, 6, 12, 30, 59), d)); 5713 testST(beforeAD, -35, SysTime(DateTime(1999, 7, 6, 12, 30, 58), d)); 5714 testST(beforeAD, -59, SysTime(DateTime(1999, 7, 6, 12, 30, 34), d)); 5715 testST(beforeAD, -60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5716 testST(beforeAD, -61, SysTime(DateTime(1999, 7, 6, 12, 30, 32), d)); 5717 5718 testST(SysTime(DateTime(1999, 7, 6, 12, 30, 0), d), 1, SysTime(DateTime(1999, 7, 6, 12, 30, 1), d)); 5719 testST(SysTime(DateTime(1999, 7, 6, 12, 30, 0), d), 0, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d)); 5720 testST(SysTime(DateTime(1999, 7, 6, 12, 30, 0), d), -1, SysTime(DateTime(1999, 7, 6, 12, 30, 59), d)); 5721 5722 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 0), d), 1, SysTime(DateTime(1999, 7, 6, 12, 0, 1), d)); 5723 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 0), d), 0, SysTime(DateTime(1999, 7, 6, 12, 0, 0), d)); 5724 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 0), d), -1, SysTime(DateTime(1999, 7, 6, 12, 0, 59), d)); 5725 5726 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 0), d), 1, SysTime(DateTime(1999, 7, 6, 0, 0, 1), d)); 5727 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 0), d), 0, SysTime(DateTime(1999, 7, 6, 0, 0, 0), d)); 5728 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 0), d), -1, SysTime(DateTime(1999, 7, 6, 0, 0, 59), d)); 5729 5730 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 59), d), 1, SysTime(DateTime(1999, 7, 5, 23, 59, 0), d)); 5731 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 59), d), 0, SysTime(DateTime(1999, 7, 5, 23, 59, 59), d)); 5732 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 59), d), -1, SysTime(DateTime(1999, 7, 5, 23, 59, 58), d)); 5733 5734 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 59), d), 1, SysTime(DateTime(1998, 12, 31, 23, 59, 0), d)); 5735 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 59), d), 0, SysTime(DateTime(1998, 12, 31, 23, 59, 59), d)); 5736 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 59), d), -1, SysTime(DateTime(1998, 12, 31, 23, 59, 58), d)); 5737 5738 // Test B.C. 5739 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d); 5740 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5741 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), d)); 5742 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 35), d)); 5743 testST(beforeBC, 3, SysTime(DateTime(-1999, 7, 6, 12, 30, 36), d)); 5744 testST(beforeBC, 4, SysTime(DateTime(-1999, 7, 6, 12, 30, 37), d)); 5745 testST(beforeBC, 5, SysTime(DateTime(-1999, 7, 6, 12, 30, 38), d)); 5746 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 43), d)); 5747 testST(beforeBC, 15, SysTime(DateTime(-1999, 7, 6, 12, 30, 48), d)); 5748 testST(beforeBC, 26, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), d)); 5749 testST(beforeBC, 27, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d)); 5750 testST(beforeBC, 30, SysTime(DateTime(-1999, 7, 6, 12, 30, 3), d)); 5751 testST(beforeBC, 59, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), d)); 5752 testST(beforeBC, 60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5753 testST(beforeBC, 61, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), d)); 5754 5755 testST(beforeBC, 1766, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), d)); 5756 testST(beforeBC, 1767, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d)); 5757 testST(beforeBC, 1768, SysTime(DateTime(-1999, 7, 6, 12, 30, 1), d)); 5758 testST(beforeBC, 2007, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d)); 5759 testST(beforeBC, 3599, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), d)); 5760 testST(beforeBC, 3600, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5761 testST(beforeBC, 3601, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), d)); 5762 testST(beforeBC, 7200, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5763 5764 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), d)); 5765 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 31), d)); 5766 testST(beforeBC, -3, SysTime(DateTime(-1999, 7, 6, 12, 30, 30), d)); 5767 testST(beforeBC, -4, SysTime(DateTime(-1999, 7, 6, 12, 30, 29), d)); 5768 testST(beforeBC, -5, SysTime(DateTime(-1999, 7, 6, 12, 30, 28), d)); 5769 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 23), d)); 5770 testST(beforeBC, -15, SysTime(DateTime(-1999, 7, 6, 12, 30, 18), d)); 5771 testST(beforeBC, -33, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d)); 5772 testST(beforeBC, -34, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), d)); 5773 testST(beforeBC, -35, SysTime(DateTime(-1999, 7, 6, 12, 30, 58), d)); 5774 testST(beforeBC, -59, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), d)); 5775 testST(beforeBC, -60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5776 testST(beforeBC, -61, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), d)); 5777 5778 testST(SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d), 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 1), d)); 5779 testST(SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d), 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d)); 5780 testST(SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d), -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), d)); 5781 5782 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 0), d), 1, SysTime(DateTime(-1999, 7, 6, 12, 0, 1), d)); 5783 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 0), d), 0, SysTime(DateTime(-1999, 7, 6, 12, 0, 0), d)); 5784 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 0), d), -1, SysTime(DateTime(-1999, 7, 6, 12, 0, 59), d)); 5785 5786 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 0), d), 1, SysTime(DateTime(-1999, 7, 6, 0, 0, 1), d)); 5787 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 0), d), 0, SysTime(DateTime(-1999, 7, 6, 0, 0, 0), d)); 5788 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 0), d), -1, SysTime(DateTime(-1999, 7, 6, 0, 0, 59), d)); 5789 5790 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 59), d), 1, SysTime(DateTime(-1999, 7, 5, 23, 59, 0), d)); 5791 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 59), d), 0, SysTime(DateTime(-1999, 7, 5, 23, 59, 59), d)); 5792 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 59), d), -1, SysTime(DateTime(-1999, 7, 5, 23, 59, 58), d)); 5793 5794 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 59), d), 1, SysTime(DateTime(-2000, 12, 31, 23, 59, 0), d)); 5795 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 59), d), 0, SysTime(DateTime(-2000, 12, 31, 23, 59, 59), d)); 5796 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 59), d), -1, SysTime(DateTime(-2000, 12, 31, 23, 59, 58), d)); 5797 5798 // Test Both 5799 testST(SysTime(DateTime(1, 1, 1, 0, 0, 0), d), -1, SysTime(DateTime(1, 1, 1, 0, 0, 59), d)); 5800 testST(SysTime(DateTime(0, 12, 31, 23, 59, 59), d), 1, SysTime(DateTime(0, 12, 31, 23, 59, 0), d)); 5801 5802 testST(SysTime(DateTime(0, 1, 1, 0, 0, 0), d), -1, SysTime(DateTime(0, 1, 1, 0, 0, 59), d)); 5803 testST(SysTime(DateTime(-1, 12, 31, 23, 59, 59), d), 1, SysTime(DateTime(-1, 12, 31, 23, 59, 0), d)); 5804 5805 testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 63_165_600L, SysTime(DateTime(-1, 1, 1, 11, 30, 33), d)); 5806 testST(SysTime(DateTime(1, 1, 1, 13, 30, 33), d), -63_165_600L, SysTime(DateTime(1, 1, 1, 13, 30, 33), d)); 5807 5808 testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 63_165_617L, SysTime(DateTime(-1, 1, 1, 11, 30, 50), d)); 5809 testST(SysTime(DateTime(1, 1, 1, 13, 30, 50), d), -63_165_617L, SysTime(DateTime(1, 1, 1, 13, 30, 33), d)); 5810 5811 { 5812 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 5813 sysTime.roll!"seconds"(-1); 5814 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 59))); 5815 sysTime.roll!"seconds"(1); 5816 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5817 } 5818 5819 { 5820 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(9_999_999)); 5821 sysTime.roll!"seconds"(-1); 5822 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 59), hnsecs(9_999_999))); 5823 sysTime.roll!"seconds"(1); 5824 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 5825 } 5826 5827 { 5828 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59)); 5829 sysTime.roll!"seconds"(1); 5830 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 0))); 5831 sysTime.roll!"seconds"(-1); 5832 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59))); 5833 } 5834 5835 { 5836 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5837 sysTime.roll!"seconds"(1); 5838 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 0), hnsecs(9_999_999))); 5839 sysTime.roll!"seconds"(-1); 5840 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5841 } 5842 5843 { 5844 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5845 sysTime.roll!"seconds"(1).roll!"seconds"(-102); 5846 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 18), hnsecs(9_999_999))); 5847 } 5848 5849 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5850 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5851 static assert(!__traits(compiles, cst.roll!"seconds"(4))); 5852 static assert(!__traits(compiles, ist.roll!"seconds"(4))); 5853 5854 static void testScope(scope ref SysTime st) @safe 5855 { 5856 auto result = st.roll!"seconds"(42); 5857 } 5858 } 5859 5860 5861 // Shares documentation with "days" version. 5862 ref SysTime roll(string units)(long value) @safe nothrow scope 5863 if (units == "msecs" || units == "usecs" || units == "hnsecs") 5864 { 5865 auto hnsecs = adjTime; 5866 immutable days = splitUnitsFromHNSecs!"days"(hnsecs); 5867 immutable negative = hnsecs < 0; 5868 5869 if (negative) 5870 hnsecs += convert!("hours", "hnsecs")(24); 5871 5872 immutable seconds = splitUnitsFromHNSecs!"seconds"(hnsecs); 5873 hnsecs += convert!(units, "hnsecs")(value); 5874 hnsecs %= convert!("seconds", "hnsecs")(1); 5875 5876 if (hnsecs < 0) 5877 hnsecs += convert!("seconds", "hnsecs")(1); 5878 hnsecs += convert!("seconds", "hnsecs")(seconds); 5879 5880 if (negative) 5881 hnsecs -= convert!("hours", "hnsecs")(24); 5882 5883 immutable newDaysHNSecs = convert!("days", "hnsecs")(days); 5884 adjTime = newDaysHNSecs + hnsecs; 5885 return this; 5886 } 5887 5888 5889 // Test roll!"msecs"(). 5890 @safe unittest 5891 { 5892 import core.time; 5893 static void testST(SysTime orig, int milliseconds, SysTime expected, size_t line = __LINE__) @safe 5894 { 5895 orig.roll!"msecs"(milliseconds); 5896 if (orig != expected) 5897 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 5898 } 5899 5900 // Test A.D. 5901 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274)); 5902 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274))); 5903 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(275))); 5904 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(276))); 5905 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(284))); 5906 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(374))); 5907 testST(beforeAD, 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999))); 5908 testST(beforeAD, 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5909 testST(beforeAD, 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274))); 5910 testST(beforeAD, 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(275))); 5911 testST(beforeAD, 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274))); 5912 testST(beforeAD, 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999))); 5913 testST(beforeAD, 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5914 testST(beforeAD, 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(1))); 5915 testST(beforeAD, 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999))); 5916 testST(beforeAD, 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5917 5918 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(273))); 5919 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(272))); 5920 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(264))); 5921 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(174))); 5922 testST(beforeAD, -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5923 testST(beforeAD, -275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999))); 5924 testST(beforeAD, -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274))); 5925 testST(beforeAD, -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(273))); 5926 testST(beforeAD, -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274))); 5927 testST(beforeAD, -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5928 testST(beforeAD, -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999))); 5929 testST(beforeAD, -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5930 testST(beforeAD, -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999))); 5931 5932 // Test B.C. 5933 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274)); 5934 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274))); 5935 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(275))); 5936 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(276))); 5937 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(284))); 5938 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(374))); 5939 testST(beforeBC, 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999))); 5940 testST(beforeBC, 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 5941 testST(beforeBC, 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274))); 5942 testST(beforeBC, 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(275))); 5943 testST(beforeBC, 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274))); 5944 testST(beforeBC, 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999))); 5945 testST(beforeBC, 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 5946 testST(beforeBC, 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(1))); 5947 testST(beforeBC, 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999))); 5948 testST(beforeBC, 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 5949 5950 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(273))); 5951 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(272))); 5952 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(264))); 5953 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(174))); 5954 testST(beforeBC, -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 5955 testST(beforeBC, -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999))); 5956 testST(beforeBC, -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274))); 5957 testST(beforeBC, -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(273))); 5958 testST(beforeBC, -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274))); 5959 testST(beforeBC, -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 5960 testST(beforeBC, -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999))); 5961 testST(beforeBC, -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 5962 testST(beforeBC, -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999))); 5963 5964 // Test Both 5965 auto beforeBoth1 = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 5966 testST(beforeBoth1, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), msecs(1))); 5967 testST(beforeBoth1, 0, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5968 testST(beforeBoth1, -1, SysTime(DateTime(1, 1, 1, 0, 0, 0), msecs(999))); 5969 testST(beforeBoth1, -2, SysTime(DateTime(1, 1, 1, 0, 0, 0), msecs(998))); 5970 testST(beforeBoth1, -1000, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5971 testST(beforeBoth1, -2000, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5972 testST(beforeBoth1, -2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), msecs(445))); 5973 5974 auto beforeBoth2 = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5975 testST(beforeBoth2, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_989_999))); 5976 testST(beforeBoth2, 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5977 testST(beforeBoth2, 1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9999))); 5978 testST(beforeBoth2, 2, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(19_999))); 5979 testST(beforeBoth2, 1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5980 testST(beforeBoth2, 2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5981 testST(beforeBoth2, 2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(5_549_999))); 5982 5983 { 5984 auto st = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5985 st.roll!"msecs"(1202).roll!"msecs"(-703); 5986 assert(st == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(4_989_999))); 5987 } 5988 5989 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5990 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5991 static assert(!__traits(compiles, cst.roll!"msecs"(4))); 5992 static assert(!__traits(compiles, ist.roll!"msecs"(4))); 5993 5994 static void testScope(scope ref SysTime st) @safe 5995 { 5996 auto result = st.roll!"msecs"(42); 5997 } 5998 } 5999 6000 // Test roll!"usecs"(). 6001 @safe unittest 6002 { 6003 import core.time; 6004 static void testST(SysTime orig, long microseconds, SysTime expected, size_t line = __LINE__) @safe 6005 { 6006 orig.roll!"usecs"(microseconds); 6007 if (orig != expected) 6008 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 6009 } 6010 6011 // Test A.D. 6012 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274)); 6013 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 6014 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(275))); 6015 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(276))); 6016 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(284))); 6017 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(374))); 6018 testST(beforeAD, 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(999))); 6019 testST(beforeAD, 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(1000))); 6020 testST(beforeAD, 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(1274))); 6021 testST(beforeAD, 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(1275))); 6022 testST(beforeAD, 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(2274))); 6023 testST(beforeAD, 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(26_999))); 6024 testST(beforeAD, 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(27_000))); 6025 testST(beforeAD, 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(27_001))); 6026 testST(beforeAD, 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(766_999))); 6027 testST(beforeAD, 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(767_000))); 6028 testST(beforeAD, 1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 6029 testST(beforeAD, 60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 6030 testST(beforeAD, 3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 6031 6032 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(273))); 6033 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(272))); 6034 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(264))); 6035 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(174))); 6036 testST(beforeAD, -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 6037 testST(beforeAD, -275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(999_999))); 6038 testST(beforeAD, -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(999_274))); 6039 testST(beforeAD, -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(999_273))); 6040 testST(beforeAD, -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(998_274))); 6041 testST(beforeAD, -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(967_000))); 6042 testST(beforeAD, -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(966_999))); 6043 testST(beforeAD, -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(167_000))); 6044 testST(beforeAD, -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(166_999))); 6045 testST(beforeAD, -1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 6046 testST(beforeAD, -60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 6047 testST(beforeAD, -3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 6048 6049 // Test B.C. 6050 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274)); 6051 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 6052 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(275))); 6053 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(276))); 6054 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(284))); 6055 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(374))); 6056 testST(beforeBC, 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(999))); 6057 testST(beforeBC, 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(1000))); 6058 testST(beforeBC, 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(1274))); 6059 testST(beforeBC, 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(1275))); 6060 testST(beforeBC, 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(2274))); 6061 testST(beforeBC, 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(26_999))); 6062 testST(beforeBC, 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(27_000))); 6063 testST(beforeBC, 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(27_001))); 6064 testST(beforeBC, 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(766_999))); 6065 testST(beforeBC, 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(767_000))); 6066 testST(beforeBC, 1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 6067 testST(beforeBC, 60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 6068 testST(beforeBC, 3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 6069 6070 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(273))); 6071 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(272))); 6072 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(264))); 6073 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(174))); 6074 testST(beforeBC, -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 6075 testST(beforeBC, -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(999_999))); 6076 testST(beforeBC, -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(999_274))); 6077 testST(beforeBC, -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(999_273))); 6078 testST(beforeBC, -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(998_274))); 6079 testST(beforeBC, -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(967_000))); 6080 testST(beforeBC, -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(966_999))); 6081 testST(beforeBC, -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(167_000))); 6082 testST(beforeBC, -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(166_999))); 6083 testST(beforeBC, -1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 6084 testST(beforeBC, -60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 6085 testST(beforeBC, -3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 6086 6087 // Test Both 6088 auto beforeBoth1 = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 6089 testST(beforeBoth1, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(1))); 6090 testST(beforeBoth1, 0, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6091 testST(beforeBoth1, -1, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(999_999))); 6092 testST(beforeBoth1, -2, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(999_998))); 6093 testST(beforeBoth1, -1000, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(999_000))); 6094 testST(beforeBoth1, -2000, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(998_000))); 6095 testST(beforeBoth1, -2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(997_445))); 6096 testST(beforeBoth1, -1_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6097 testST(beforeBoth1, -2_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6098 testST(beforeBoth1, -2_333_333, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(666_667))); 6099 6100 auto beforeBoth2 = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 6101 testST(beforeBoth2, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_989))); 6102 testST(beforeBoth2, 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6103 testST(beforeBoth2, 1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9))); 6104 testST(beforeBoth2, 2, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(19))); 6105 testST(beforeBoth2, 1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9999))); 6106 testST(beforeBoth2, 2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(19_999))); 6107 testST(beforeBoth2, 2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(25_549))); 6108 testST(beforeBoth2, 1_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6109 testST(beforeBoth2, 2_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6110 testST(beforeBoth2, 2_333_333, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(3_333_329))); 6111 6112 { 6113 auto st = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 6114 st.roll!"usecs"(9_020_027); 6115 assert(st == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(200_269))); 6116 } 6117 6118 { 6119 auto st = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 6120 st.roll!"usecs"(9_020_027).roll!"usecs"(-70_034); 6121 assert(st == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_499_929))); 6122 } 6123 6124 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6125 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6126 static assert(!__traits(compiles, cst.roll!"usecs"(4))); 6127 static assert(!__traits(compiles, ist.roll!"usecs"(4))); 6128 6129 static void testScope(scope ref SysTime st) @safe 6130 { 6131 auto result = st.roll!"usecs"(42); 6132 } 6133 } 6134 6135 // Test roll!"hnsecs"(). 6136 @safe unittest 6137 { 6138 import core.time; 6139 static void testST(SysTime orig, long hnsecs, SysTime expected, size_t line = __LINE__) @safe 6140 { 6141 orig.roll!"hnsecs"(hnsecs); 6142 if (orig != expected) 6143 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 6144 } 6145 6146 // Test A.D. 6147 auto dtAD = DateTime(1999, 7, 6, 12, 30, 33); 6148 auto beforeAD = SysTime(dtAD, hnsecs(274)); 6149 testST(beforeAD, 0, SysTime(dtAD, hnsecs(274))); 6150 testST(beforeAD, 1, SysTime(dtAD, hnsecs(275))); 6151 testST(beforeAD, 2, SysTime(dtAD, hnsecs(276))); 6152 testST(beforeAD, 10, SysTime(dtAD, hnsecs(284))); 6153 testST(beforeAD, 100, SysTime(dtAD, hnsecs(374))); 6154 testST(beforeAD, 725, SysTime(dtAD, hnsecs(999))); 6155 testST(beforeAD, 726, SysTime(dtAD, hnsecs(1000))); 6156 testST(beforeAD, 1000, SysTime(dtAD, hnsecs(1274))); 6157 testST(beforeAD, 1001, SysTime(dtAD, hnsecs(1275))); 6158 testST(beforeAD, 2000, SysTime(dtAD, hnsecs(2274))); 6159 testST(beforeAD, 26_725, SysTime(dtAD, hnsecs(26_999))); 6160 testST(beforeAD, 26_726, SysTime(dtAD, hnsecs(27_000))); 6161 testST(beforeAD, 26_727, SysTime(dtAD, hnsecs(27_001))); 6162 testST(beforeAD, 1_766_725, SysTime(dtAD, hnsecs(1_766_999))); 6163 testST(beforeAD, 1_766_726, SysTime(dtAD, hnsecs(1_767_000))); 6164 testST(beforeAD, 1_000_000, SysTime(dtAD, hnsecs(1_000_274))); 6165 testST(beforeAD, 60_000_000L, SysTime(dtAD, hnsecs(274))); 6166 testST(beforeAD, 3_600_000_000L, SysTime(dtAD, hnsecs(274))); 6167 testST(beforeAD, 600_000_000L, SysTime(dtAD, hnsecs(274))); 6168 testST(beforeAD, 36_000_000_000L, SysTime(dtAD, hnsecs(274))); 6169 6170 testST(beforeAD, -1, SysTime(dtAD, hnsecs(273))); 6171 testST(beforeAD, -2, SysTime(dtAD, hnsecs(272))); 6172 testST(beforeAD, -10, SysTime(dtAD, hnsecs(264))); 6173 testST(beforeAD, -100, SysTime(dtAD, hnsecs(174))); 6174 testST(beforeAD, -274, SysTime(dtAD)); 6175 testST(beforeAD, -275, SysTime(dtAD, hnsecs(9_999_999))); 6176 testST(beforeAD, -1000, SysTime(dtAD, hnsecs(9_999_274))); 6177 testST(beforeAD, -1001, SysTime(dtAD, hnsecs(9_999_273))); 6178 testST(beforeAD, -2000, SysTime(dtAD, hnsecs(9_998_274))); 6179 testST(beforeAD, -33_274, SysTime(dtAD, hnsecs(9_967_000))); 6180 testST(beforeAD, -33_275, SysTime(dtAD, hnsecs(9_966_999))); 6181 testST(beforeAD, -1_833_274, SysTime(dtAD, hnsecs(8_167_000))); 6182 testST(beforeAD, -1_833_275, SysTime(dtAD, hnsecs(8_166_999))); 6183 testST(beforeAD, -1_000_000, SysTime(dtAD, hnsecs(9_000_274))); 6184 testST(beforeAD, -60_000_000L, SysTime(dtAD, hnsecs(274))); 6185 testST(beforeAD, -3_600_000_000L, SysTime(dtAD, hnsecs(274))); 6186 testST(beforeAD, -600_000_000L, SysTime(dtAD, hnsecs(274))); 6187 testST(beforeAD, -36_000_000_000L, SysTime(dtAD, hnsecs(274))); 6188 6189 // Test B.C. 6190 auto dtBC = DateTime(-1999, 7, 6, 12, 30, 33); 6191 auto beforeBC = SysTime(dtBC, hnsecs(274)); 6192 testST(beforeBC, 0, SysTime(dtBC, hnsecs(274))); 6193 testST(beforeBC, 1, SysTime(dtBC, hnsecs(275))); 6194 testST(beforeBC, 2, SysTime(dtBC, hnsecs(276))); 6195 testST(beforeBC, 10, SysTime(dtBC, hnsecs(284))); 6196 testST(beforeBC, 100, SysTime(dtBC, hnsecs(374))); 6197 testST(beforeBC, 725, SysTime(dtBC, hnsecs(999))); 6198 testST(beforeBC, 726, SysTime(dtBC, hnsecs(1000))); 6199 testST(beforeBC, 1000, SysTime(dtBC, hnsecs(1274))); 6200 testST(beforeBC, 1001, SysTime(dtBC, hnsecs(1275))); 6201 testST(beforeBC, 2000, SysTime(dtBC, hnsecs(2274))); 6202 testST(beforeBC, 26_725, SysTime(dtBC, hnsecs(26_999))); 6203 testST(beforeBC, 26_726, SysTime(dtBC, hnsecs(27_000))); 6204 testST(beforeBC, 26_727, SysTime(dtBC, hnsecs(27_001))); 6205 testST(beforeBC, 1_766_725, SysTime(dtBC, hnsecs(1_766_999))); 6206 testST(beforeBC, 1_766_726, SysTime(dtBC, hnsecs(1_767_000))); 6207 testST(beforeBC, 1_000_000, SysTime(dtBC, hnsecs(1_000_274))); 6208 testST(beforeBC, 60_000_000L, SysTime(dtBC, hnsecs(274))); 6209 testST(beforeBC, 3_600_000_000L, SysTime(dtBC, hnsecs(274))); 6210 testST(beforeBC, 600_000_000L, SysTime(dtBC, hnsecs(274))); 6211 testST(beforeBC, 36_000_000_000L, SysTime(dtBC, hnsecs(274))); 6212 6213 testST(beforeBC, -1, SysTime(dtBC, hnsecs(273))); 6214 testST(beforeBC, -2, SysTime(dtBC, hnsecs(272))); 6215 testST(beforeBC, -10, SysTime(dtBC, hnsecs(264))); 6216 testST(beforeBC, -100, SysTime(dtBC, hnsecs(174))); 6217 testST(beforeBC, -274, SysTime(dtBC)); 6218 testST(beforeBC, -275, SysTime(dtBC, hnsecs(9_999_999))); 6219 testST(beforeBC, -1000, SysTime(dtBC, hnsecs(9_999_274))); 6220 testST(beforeBC, -1001, SysTime(dtBC, hnsecs(9_999_273))); 6221 testST(beforeBC, -2000, SysTime(dtBC, hnsecs(9_998_274))); 6222 testST(beforeBC, -33_274, SysTime(dtBC, hnsecs(9_967_000))); 6223 testST(beforeBC, -33_275, SysTime(dtBC, hnsecs(9_966_999))); 6224 testST(beforeBC, -1_833_274, SysTime(dtBC, hnsecs(8_167_000))); 6225 testST(beforeBC, -1_833_275, SysTime(dtBC, hnsecs(8_166_999))); 6226 testST(beforeBC, -1_000_000, SysTime(dtBC, hnsecs(9_000_274))); 6227 testST(beforeBC, -60_000_000L, SysTime(dtBC, hnsecs(274))); 6228 testST(beforeBC, -3_600_000_000L, SysTime(dtBC, hnsecs(274))); 6229 testST(beforeBC, -600_000_000L, SysTime(dtBC, hnsecs(274))); 6230 testST(beforeBC, -36_000_000_000L, SysTime(dtBC, hnsecs(274))); 6231 6232 // Test Both 6233 auto dtBoth1 = DateTime(1, 1, 1, 0, 0, 0); 6234 auto beforeBoth1 = SysTime(dtBoth1); 6235 testST(beforeBoth1, 1, SysTime(dtBoth1, hnsecs(1))); 6236 testST(beforeBoth1, 0, SysTime(dtBoth1)); 6237 testST(beforeBoth1, -1, SysTime(dtBoth1, hnsecs(9_999_999))); 6238 testST(beforeBoth1, -2, SysTime(dtBoth1, hnsecs(9_999_998))); 6239 testST(beforeBoth1, -1000, SysTime(dtBoth1, hnsecs(9_999_000))); 6240 testST(beforeBoth1, -2000, SysTime(dtBoth1, hnsecs(9_998_000))); 6241 testST(beforeBoth1, -2555, SysTime(dtBoth1, hnsecs(9_997_445))); 6242 testST(beforeBoth1, -1_000_000, SysTime(dtBoth1, hnsecs(9_000_000))); 6243 testST(beforeBoth1, -2_000_000, SysTime(dtBoth1, hnsecs(8_000_000))); 6244 testST(beforeBoth1, -2_333_333, SysTime(dtBoth1, hnsecs(7_666_667))); 6245 testST(beforeBoth1, -10_000_000, SysTime(dtBoth1)); 6246 testST(beforeBoth1, -20_000_000, SysTime(dtBoth1)); 6247 testST(beforeBoth1, -20_888_888, SysTime(dtBoth1, hnsecs(9_111_112))); 6248 6249 auto dtBoth2 = DateTime(0, 12, 31, 23, 59, 59); 6250 auto beforeBoth2 = SysTime(dtBoth2, hnsecs(9_999_999)); 6251 testST(beforeBoth2, -1, SysTime(dtBoth2, hnsecs(9_999_998))); 6252 testST(beforeBoth2, 0, SysTime(dtBoth2, hnsecs(9_999_999))); 6253 testST(beforeBoth2, 1, SysTime(dtBoth2)); 6254 testST(beforeBoth2, 2, SysTime(dtBoth2, hnsecs(1))); 6255 testST(beforeBoth2, 1000, SysTime(dtBoth2, hnsecs(999))); 6256 testST(beforeBoth2, 2000, SysTime(dtBoth2, hnsecs(1999))); 6257 testST(beforeBoth2, 2555, SysTime(dtBoth2, hnsecs(2554))); 6258 testST(beforeBoth2, 1_000_000, SysTime(dtBoth2, hnsecs(999_999))); 6259 testST(beforeBoth2, 2_000_000, SysTime(dtBoth2, hnsecs(1_999_999))); 6260 testST(beforeBoth2, 2_333_333, SysTime(dtBoth2, hnsecs(2_333_332))); 6261 testST(beforeBoth2, 10_000_000, SysTime(dtBoth2, hnsecs(9_999_999))); 6262 testST(beforeBoth2, 20_000_000, SysTime(dtBoth2, hnsecs(9_999_999))); 6263 testST(beforeBoth2, 20_888_888, SysTime(dtBoth2, hnsecs(888_887))); 6264 6265 { 6266 auto st = SysTime(dtBoth2, hnsecs(9_999_999)); 6267 st.roll!"hnsecs"(70_777_222).roll!"hnsecs"(-222_555_292); 6268 assert(st == SysTime(dtBoth2, hnsecs(8_221_929))); 6269 } 6270 6271 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6272 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6273 static assert(!__traits(compiles, cst.roll!"hnsecs"(4))); 6274 static assert(!__traits(compiles, ist.roll!"hnsecs"(4))); 6275 6276 static void testScope(scope ref SysTime st) @safe 6277 { 6278 auto result = st.roll!"hnsecs"(42); 6279 } 6280 } 6281 6282 6283 /++ 6284 Gives the result of adding or subtracting a $(REF Duration, core,time) 6285 from this $(LREF SysTime). 6286 6287 The legal types of arithmetic for $(LREF SysTime) using this operator 6288 are 6289 6290 $(BOOKTABLE, 6291 $(TR $(TD SysTime) $(TD +) $(TD Duration) $(TD -->) $(TD SysTime)) 6292 $(TR $(TD SysTime) $(TD -) $(TD Duration) $(TD -->) $(TD SysTime)) 6293 ) 6294 6295 Params: 6296 duration = The $(REF Duration, core,time) to add to or subtract from 6297 this $(LREF SysTime). 6298 +/ 6299 SysTime opBinary(string op)(Duration duration) @safe const pure nothrow return scope 6300 if (op == "+" || op == "-") 6301 { 6302 SysTime retval = SysTime(this._stdTime, this._timezone); 6303 immutable hnsecs = duration.total!"hnsecs"; 6304 mixin("retval._stdTime " ~ op ~ "= hnsecs;"); 6305 return retval; 6306 } 6307 6308 /// 6309 @safe unittest 6310 { 6311 import core.time : hours, seconds; 6312 import std.datetime.date : DateTime; 6313 6314 assert(SysTime(DateTime(2015, 12, 31, 23, 59, 59)) + seconds(1) == 6315 SysTime(DateTime(2016, 1, 1, 0, 0, 0))); 6316 6317 assert(SysTime(DateTime(2015, 12, 31, 23, 59, 59)) + hours(1) == 6318 SysTime(DateTime(2016, 1, 1, 0, 59, 59))); 6319 6320 assert(SysTime(DateTime(2016, 1, 1, 0, 0, 0)) - seconds(1) == 6321 SysTime(DateTime(2015, 12, 31, 23, 59, 59))); 6322 6323 assert(SysTime(DateTime(2016, 1, 1, 0, 59, 59)) - hours(1) == 6324 SysTime(DateTime(2015, 12, 31, 23, 59, 59))); 6325 } 6326 6327 @safe unittest 6328 { 6329 import core.time; 6330 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_678)); 6331 6332 assert(st + dur!"weeks"(7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33), hnsecs(2_345_678))); 6333 assert(st + dur!"weeks"(-7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33), hnsecs(2_345_678))); 6334 assert(st + dur!"days"(7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33), hnsecs(2_345_678))); 6335 assert(st + dur!"days"(-7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33), hnsecs(2_345_678))); 6336 assert(st + dur!"hours"(7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33), hnsecs(2_345_678))); 6337 assert(st + dur!"hours"(-7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33), hnsecs(2_345_678))); 6338 assert(st + dur!"minutes"(7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33), hnsecs(2_345_678))); 6339 assert(st + dur!"minutes"(-7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33), hnsecs(2_345_678))); 6340 assert(st + dur!"seconds"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40), hnsecs(2_345_678))); 6341 assert(st + dur!"seconds"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26), hnsecs(2_345_678))); 6342 assert(st + dur!"msecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_415_678))); 6343 assert(st + dur!"msecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_275_678))); 6344 assert(st + dur!"usecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_748))); 6345 assert(st + dur!"usecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_608))); 6346 assert(st + dur!"hnsecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_685))); 6347 assert(st + dur!"hnsecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_671))); 6348 6349 assert(st - dur!"weeks"(-7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33), hnsecs(2_345_678))); 6350 assert(st - dur!"weeks"(7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33), hnsecs(2_345_678))); 6351 assert(st - dur!"days"(-7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33), hnsecs(2_345_678))); 6352 assert(st - dur!"days"(7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33), hnsecs(2_345_678))); 6353 assert(st - dur!"hours"(-7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33), hnsecs(2_345_678))); 6354 assert(st - dur!"hours"(7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33), hnsecs(2_345_678))); 6355 assert(st - dur!"minutes"(-7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33), hnsecs(2_345_678))); 6356 assert(st - dur!"minutes"(7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33), hnsecs(2_345_678))); 6357 assert(st - dur!"seconds"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40), hnsecs(2_345_678))); 6358 assert(st - dur!"seconds"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26), hnsecs(2_345_678))); 6359 assert(st - dur!"msecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_415_678))); 6360 assert(st - dur!"msecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_275_678))); 6361 assert(st - dur!"usecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_748))); 6362 assert(st - dur!"usecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_608))); 6363 assert(st - dur!"hnsecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_685))); 6364 assert(st - dur!"hnsecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_671))); 6365 6366 static void testST(SysTime orig, long hnsecs, SysTime expected, size_t line = __LINE__) @safe 6367 { 6368 auto result = orig + dur!"hnsecs"(hnsecs); 6369 if (result != expected) 6370 throw new AssertError(format("Failed. actual [%s] != expected [%s]", result, expected), __FILE__, line); 6371 } 6372 6373 // Test A.D. 6374 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274)); 6375 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274))); 6376 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(275))); 6377 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(276))); 6378 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(284))); 6379 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(374))); 6380 testST(beforeAD, 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(999))); 6381 testST(beforeAD, 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1000))); 6382 testST(beforeAD, 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1274))); 6383 testST(beforeAD, 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1275))); 6384 testST(beforeAD, 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2274))); 6385 testST(beforeAD, 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(26_999))); 6386 testST(beforeAD, 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_000))); 6387 testST(beforeAD, 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_001))); 6388 testST(beforeAD, 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_766_999))); 6389 testST(beforeAD, 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_767_000))); 6390 testST(beforeAD, 1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_000_274))); 6391 testST(beforeAD, 60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 39), hnsecs(274))); 6392 testST(beforeAD, 3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 36, 33), hnsecs(274))); 6393 testST(beforeAD, 600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 31, 33), hnsecs(274))); 6394 testST(beforeAD, 36_000_000_000L, SysTime(DateTime(1999, 7, 6, 13, 30, 33), hnsecs(274))); 6395 6396 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(273))); 6397 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(272))); 6398 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(264))); 6399 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(174))); 6400 testST(beforeAD, -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 6401 testST(beforeAD, -275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_999))); 6402 testST(beforeAD, -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_274))); 6403 testST(beforeAD, -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_273))); 6404 testST(beforeAD, -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_998_274))); 6405 testST(beforeAD, -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_967_000))); 6406 testST(beforeAD, -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_966_999))); 6407 testST(beforeAD, -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_167_000))); 6408 testST(beforeAD, -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_166_999))); 6409 testST(beforeAD, -1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_000_274))); 6410 testST(beforeAD, -60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 27), hnsecs(274))); 6411 testST(beforeAD, -3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 24, 33), hnsecs(274))); 6412 testST(beforeAD, -600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 29, 33), hnsecs(274))); 6413 testST(beforeAD, -36_000_000_000L, SysTime(DateTime(1999, 7, 6, 11, 30, 33), hnsecs(274))); 6414 6415 // Test B.C. 6416 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274)); 6417 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274))); 6418 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(275))); 6419 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(276))); 6420 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(284))); 6421 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(374))); 6422 testST(beforeBC, 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(999))); 6423 testST(beforeBC, 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1000))); 6424 testST(beforeBC, 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1274))); 6425 testST(beforeBC, 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1275))); 6426 testST(beforeBC, 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(2274))); 6427 testST(beforeBC, 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(26_999))); 6428 testST(beforeBC, 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_000))); 6429 testST(beforeBC, 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_001))); 6430 testST(beforeBC, 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_766_999))); 6431 testST(beforeBC, 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_767_000))); 6432 testST(beforeBC, 1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_000_274))); 6433 testST(beforeBC, 60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 39), hnsecs(274))); 6434 testST(beforeBC, 3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 36, 33), hnsecs(274))); 6435 testST(beforeBC, 600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), hnsecs(274))); 6436 testST(beforeBC, 36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), hnsecs(274))); 6437 6438 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(273))); 6439 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(272))); 6440 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(264))); 6441 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(174))); 6442 testST(beforeBC, -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 6443 testST(beforeBC, -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_999))); 6444 testST(beforeBC, -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_274))); 6445 testST(beforeBC, -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_273))); 6446 testST(beforeBC, -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_998_274))); 6447 testST(beforeBC, -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_967_000))); 6448 testST(beforeBC, -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_966_999))); 6449 testST(beforeBC, -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_167_000))); 6450 testST(beforeBC, -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_166_999))); 6451 testST(beforeBC, -1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_000_274))); 6452 testST(beforeBC, -60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 27), hnsecs(274))); 6453 testST(beforeBC, -3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 24, 33), hnsecs(274))); 6454 testST(beforeBC, -600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), hnsecs(274))); 6455 testST(beforeBC, -36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), hnsecs(274))); 6456 6457 // Test Both 6458 auto beforeBoth1 = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 6459 testST(beforeBoth1, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 6460 testST(beforeBoth1, 0, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6461 testST(beforeBoth1, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6462 testST(beforeBoth1, -2, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998))); 6463 testST(beforeBoth1, -1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_000))); 6464 testST(beforeBoth1, -2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_998_000))); 6465 testST(beforeBoth1, -2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_997_445))); 6466 testST(beforeBoth1, -1_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_000_000))); 6467 testST(beforeBoth1, -2_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(8_000_000))); 6468 testST(beforeBoth1, -2_333_333, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(7_666_667))); 6469 testST(beforeBoth1, -10_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59))); 6470 testST(beforeBoth1, -20_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 58))); 6471 testST(beforeBoth1, -20_888_888, SysTime(DateTime(0, 12, 31, 23, 59, 57), hnsecs(9_111_112))); 6472 6473 auto beforeBoth2 = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 6474 testST(beforeBoth2, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998))); 6475 testST(beforeBoth2, 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6476 testST(beforeBoth2, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6477 testST(beforeBoth2, 2, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 6478 testST(beforeBoth2, 1000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999))); 6479 testST(beforeBoth2, 2000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1999))); 6480 testST(beforeBoth2, 2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2554))); 6481 testST(beforeBoth2, 1_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999_999))); 6482 testST(beforeBoth2, 2_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1_999_999))); 6483 testST(beforeBoth2, 2_333_333, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2_333_332))); 6484 testST(beforeBoth2, 10_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 6485 testST(beforeBoth2, 20_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 1), hnsecs(9_999_999))); 6486 testST(beforeBoth2, 20_888_888, SysTime(DateTime(1, 1, 1, 0, 0, 2), hnsecs(888_887))); 6487 6488 auto duration = dur!"seconds"(12); 6489 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6490 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6491 assert(cst + duration == SysTime(DateTime(1999, 7, 6, 12, 30, 45))); 6492 assert(ist + duration == SysTime(DateTime(1999, 7, 6, 12, 30, 45))); 6493 assert(cst - duration == SysTime(DateTime(1999, 7, 6, 12, 30, 21))); 6494 assert(ist - duration == SysTime(DateTime(1999, 7, 6, 12, 30, 21))); 6495 6496 static void testScope(scope ref SysTime st, scope ref Duration d) @safe 6497 { 6498 auto result = st + d; 6499 } 6500 } 6501 6502 6503 /++ 6504 Gives the result of adding or subtracting a $(REF Duration, core,time) from 6505 this $(LREF SysTime), as well as assigning the result to this 6506 $(LREF SysTime). 6507 6508 The legal types of arithmetic for $(LREF SysTime) using this operator are 6509 6510 $(BOOKTABLE, 6511 $(TR $(TD SysTime) $(TD +) $(TD Duration) $(TD -->) $(TD SysTime)) 6512 $(TR $(TD SysTime) $(TD -) $(TD Duration) $(TD -->) $(TD SysTime)) 6513 ) 6514 6515 Params: 6516 duration = The $(REF Duration, core,time) to add to or subtract from 6517 this $(LREF SysTime). 6518 +/ 6519 ref SysTime opOpAssign(string op)(Duration duration) @safe pure nothrow scope 6520 if (op == "+" || op == "-") 6521 { 6522 immutable hnsecs = duration.total!"hnsecs"; 6523 mixin("_stdTime " ~ op ~ "= hnsecs;"); 6524 return this; 6525 } 6526 6527 @safe unittest 6528 { 6529 import core.time; 6530 auto before = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6531 assert(before + dur!"weeks"(7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33))); 6532 assert(before + dur!"weeks"(-7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33))); 6533 assert(before + dur!"days"(7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33))); 6534 assert(before + dur!"days"(-7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33))); 6535 6536 assert(before + dur!"hours"(7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33))); 6537 assert(before + dur!"hours"(-7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33))); 6538 assert(before + dur!"minutes"(7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33))); 6539 assert(before + dur!"minutes"(-7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33))); 6540 assert(before + dur!"seconds"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40))); 6541 assert(before + dur!"seconds"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26))); 6542 assert(before + dur!"msecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(7))); 6543 assert(before + dur!"msecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), msecs(993))); 6544 assert(before + dur!"usecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(7))); 6545 assert(before + dur!"usecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), usecs(999_993))); 6546 assert(before + dur!"hnsecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(7))); 6547 assert(before + dur!"hnsecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_993))); 6548 6549 assert(before - dur!"weeks"(-7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33))); 6550 assert(before - dur!"weeks"(7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33))); 6551 assert(before - dur!"days"(-7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33))); 6552 assert(before - dur!"days"(7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33))); 6553 6554 assert(before - dur!"hours"(-7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33))); 6555 assert(before - dur!"hours"(7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33))); 6556 assert(before - dur!"minutes"(-7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33))); 6557 assert(before - dur!"minutes"(7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33))); 6558 assert(before - dur!"seconds"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40))); 6559 assert(before - dur!"seconds"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26))); 6560 assert(before - dur!"msecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(7))); 6561 assert(before - dur!"msecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), msecs(993))); 6562 assert(before - dur!"usecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(7))); 6563 assert(before - dur!"usecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), usecs(999_993))); 6564 assert(before - dur!"hnsecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(7))); 6565 assert(before - dur!"hnsecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_993))); 6566 6567 static void testST(SysTime orig, long hnsecs, SysTime expected, size_t line = __LINE__) @safe 6568 { 6569 auto r = orig += dur!"hnsecs"(hnsecs); 6570 if (orig != expected) 6571 throw new AssertError(format("Failed 1. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 6572 if (r != expected) 6573 throw new AssertError(format("Failed 2. actual [%s] != expected [%s]", r, expected), __FILE__, line); 6574 } 6575 6576 // Test A.D. 6577 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274)); 6578 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274))); 6579 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(275))); 6580 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(276))); 6581 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(284))); 6582 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(374))); 6583 testST(beforeAD, 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(999))); 6584 testST(beforeAD, 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1000))); 6585 testST(beforeAD, 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1274))); 6586 testST(beforeAD, 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1275))); 6587 testST(beforeAD, 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2274))); 6588 testST(beforeAD, 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(26_999))); 6589 testST(beforeAD, 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_000))); 6590 testST(beforeAD, 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_001))); 6591 testST(beforeAD, 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_766_999))); 6592 testST(beforeAD, 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_767_000))); 6593 testST(beforeAD, 1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_000_274))); 6594 testST(beforeAD, 60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 39), hnsecs(274))); 6595 testST(beforeAD, 3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 36, 33), hnsecs(274))); 6596 testST(beforeAD, 600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 31, 33), hnsecs(274))); 6597 testST(beforeAD, 36_000_000_000L, SysTime(DateTime(1999, 7, 6, 13, 30, 33), hnsecs(274))); 6598 6599 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(273))); 6600 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(272))); 6601 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(264))); 6602 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(174))); 6603 testST(beforeAD, -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 6604 testST(beforeAD, -275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_999))); 6605 testST(beforeAD, -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_274))); 6606 testST(beforeAD, -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_273))); 6607 testST(beforeAD, -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_998_274))); 6608 testST(beforeAD, -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_967_000))); 6609 testST(beforeAD, -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_966_999))); 6610 testST(beforeAD, -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_167_000))); 6611 testST(beforeAD, -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_166_999))); 6612 testST(beforeAD, -1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_000_274))); 6613 testST(beforeAD, -60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 27), hnsecs(274))); 6614 testST(beforeAD, -3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 24, 33), hnsecs(274))); 6615 testST(beforeAD, -600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 29, 33), hnsecs(274))); 6616 testST(beforeAD, -36_000_000_000L, SysTime(DateTime(1999, 7, 6, 11, 30, 33), hnsecs(274))); 6617 6618 // Test B.C. 6619 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274)); 6620 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274))); 6621 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(275))); 6622 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(276))); 6623 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(284))); 6624 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(374))); 6625 testST(beforeBC, 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(999))); 6626 testST(beforeBC, 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1000))); 6627 testST(beforeBC, 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1274))); 6628 testST(beforeBC, 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1275))); 6629 testST(beforeBC, 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(2274))); 6630 testST(beforeBC, 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(26_999))); 6631 testST(beforeBC, 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_000))); 6632 testST(beforeBC, 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_001))); 6633 testST(beforeBC, 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_766_999))); 6634 testST(beforeBC, 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_767_000))); 6635 testST(beforeBC, 1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_000_274))); 6636 testST(beforeBC, 60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 39), hnsecs(274))); 6637 testST(beforeBC, 3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 36, 33), hnsecs(274))); 6638 testST(beforeBC, 600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), hnsecs(274))); 6639 testST(beforeBC, 36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), hnsecs(274))); 6640 6641 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(273))); 6642 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(272))); 6643 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(264))); 6644 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(174))); 6645 testST(beforeBC, -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 6646 testST(beforeBC, -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_999))); 6647 testST(beforeBC, -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_274))); 6648 testST(beforeBC, -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_273))); 6649 testST(beforeBC, -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_998_274))); 6650 testST(beforeBC, -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_967_000))); 6651 testST(beforeBC, -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_966_999))); 6652 testST(beforeBC, -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_167_000))); 6653 testST(beforeBC, -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_166_999))); 6654 testST(beforeBC, -1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_000_274))); 6655 testST(beforeBC, -60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 27), hnsecs(274))); 6656 testST(beforeBC, -3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 24, 33), hnsecs(274))); 6657 testST(beforeBC, -600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), hnsecs(274))); 6658 testST(beforeBC, -36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), hnsecs(274))); 6659 6660 // Test Both 6661 auto beforeBoth1 = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 6662 testST(beforeBoth1, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 6663 testST(beforeBoth1, 0, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6664 testST(beforeBoth1, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6665 testST(beforeBoth1, -2, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998))); 6666 testST(beforeBoth1, -1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_000))); 6667 testST(beforeBoth1, -2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_998_000))); 6668 testST(beforeBoth1, -2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_997_445))); 6669 testST(beforeBoth1, -1_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_000_000))); 6670 testST(beforeBoth1, -2_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(8_000_000))); 6671 testST(beforeBoth1, -2_333_333, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(7_666_667))); 6672 testST(beforeBoth1, -10_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59))); 6673 testST(beforeBoth1, -20_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 58))); 6674 testST(beforeBoth1, -20_888_888, SysTime(DateTime(0, 12, 31, 23, 59, 57), hnsecs(9_111_112))); 6675 6676 auto beforeBoth2 = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 6677 testST(beforeBoth2, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998))); 6678 testST(beforeBoth2, 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6679 testST(beforeBoth2, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6680 testST(beforeBoth2, 2, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 6681 testST(beforeBoth2, 1000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999))); 6682 testST(beforeBoth2, 2000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1999))); 6683 testST(beforeBoth2, 2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2554))); 6684 testST(beforeBoth2, 1_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999_999))); 6685 testST(beforeBoth2, 2_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1_999_999))); 6686 testST(beforeBoth2, 2_333_333, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2_333_332))); 6687 testST(beforeBoth2, 10_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 6688 testST(beforeBoth2, 20_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 1), hnsecs(9_999_999))); 6689 testST(beforeBoth2, 20_888_888, SysTime(DateTime(1, 1, 1, 0, 0, 2), hnsecs(888_887))); 6690 6691 { 6692 auto st = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 6693 (st += dur!"hnsecs"(52)) += dur!"seconds"(-907); 6694 assert(st == SysTime(DateTime(0, 12, 31, 23, 44, 53), hnsecs(51))); 6695 } 6696 6697 auto duration = dur!"seconds"(12); 6698 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6699 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6700 static assert(!__traits(compiles, cst += duration)); 6701 static assert(!__traits(compiles, ist += duration)); 6702 static assert(!__traits(compiles, cst -= duration)); 6703 static assert(!__traits(compiles, ist -= duration)); 6704 6705 static void testScope(scope ref SysTime st, scope ref Duration d) @safe 6706 { 6707 auto result1 = st += d; 6708 auto result2 = st -= d; 6709 } 6710 } 6711 6712 6713 /++ 6714 Gives the difference between two $(LREF SysTime)s. 6715 6716 The legal types of arithmetic for $(LREF SysTime) using this operator 6717 are 6718 6719 $(BOOKTABLE, 6720 $(TR $(TD SysTime) $(TD -) $(TD SysTime) $(TD -->) $(TD duration)) 6721 ) 6722 +/ 6723 Duration opBinary(string op)(SysTime rhs) @safe const pure nothrow scope 6724 if (op == "-") 6725 { 6726 return dur!"hnsecs"(_stdTime - rhs._stdTime); 6727 } 6728 6729 @safe unittest 6730 { 6731 import core.time; 6732 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1998, 7, 6, 12, 30, 33)) == 6733 dur!"seconds"(31_536_000)); 6734 assert(SysTime(DateTime(1998, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6735 dur!"seconds"(-31_536_000)); 6736 6737 assert(SysTime(DateTime(1999, 8, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6738 dur!"seconds"(26_78_400)); 6739 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 8, 6, 12, 30, 33)) == 6740 dur!"seconds"(-26_78_400)); 6741 6742 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 5, 12, 30, 33)) == 6743 dur!"seconds"(86_400)); 6744 assert(SysTime(DateTime(1999, 7, 5, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6745 dur!"seconds"(-86_400)); 6746 6747 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 11, 30, 33)) == 6748 dur!"seconds"(3600)); 6749 assert(SysTime(DateTime(1999, 7, 6, 11, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6750 dur!"seconds"(-3600)); 6751 6752 assert(SysTime(DateTime(1999, 7, 6, 12, 31, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6753 dur!"seconds"(60)); 6754 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 31, 33)) == 6755 dur!"seconds"(-60)); 6756 6757 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 34)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6758 dur!"seconds"(1)); 6759 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 34)) == 6760 dur!"seconds"(-1)); 6761 6762 { 6763 auto dt = DateTime(1999, 7, 6, 12, 30, 33); 6764 assert(SysTime(dt, msecs(532)) - SysTime(dt) == msecs(532)); 6765 assert(SysTime(dt) - SysTime(dt, msecs(532)) == msecs(-532)); 6766 6767 assert(SysTime(dt, usecs(333_347)) - SysTime(dt) == usecs(333_347)); 6768 assert(SysTime(dt) - SysTime(dt, usecs(333_347)) == usecs(-333_347)); 6769 6770 assert(SysTime(dt, hnsecs(1_234_567)) - SysTime(dt) == hnsecs(1_234_567)); 6771 assert(SysTime(dt) - SysTime(dt, hnsecs(1_234_567)) == hnsecs(-1_234_567)); 6772 } 6773 6774 assert(SysTime(DateTime(1, 1, 1, 12, 30, 33)) - SysTime(DateTime(1, 1, 1, 0, 0, 0)) == dur!"seconds"(45033)); 6775 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)) - SysTime(DateTime(1, 1, 1, 12, 30, 33)) == dur!"seconds"(-45033)); 6776 assert(SysTime(DateTime(0, 12, 31, 12, 30, 33)) - SysTime(DateTime(1, 1, 1, 0, 0, 0)) == dur!"seconds"(-41367)); 6777 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)) - SysTime(DateTime(0, 12, 31, 12, 30, 33)) == dur!"seconds"(41367)); 6778 6779 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)) - SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)) == 6780 dur!"hnsecs"(1)); 6781 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)) - SysTime(DateTime(1, 1, 1, 0, 0, 0)) == 6782 dur!"hnsecs"(-1)); 6783 6784 version (Posix) 6785 { 6786 import std.datetime.timezone : PosixTimeZone; 6787 immutable tz = PosixTimeZone.getTimeZone("America/Los_Angeles"); 6788 } 6789 else version (Windows) 6790 { 6791 import std.datetime.timezone : WindowsTimeZone; 6792 immutable tz = WindowsTimeZone.getTimeZone("Pacific Standard Time"); 6793 } 6794 6795 { 6796 auto dt = DateTime(2011, 1, 13, 8, 17, 2); 6797 auto d = msecs(296); 6798 assert(SysTime(dt, d, tz) - SysTime(dt, d, tz) == Duration.zero); 6799 assert(SysTime(dt, d, tz) - SysTime(dt, d, UTC()) == hours(8)); 6800 assert(SysTime(dt, d, UTC()) - SysTime(dt, d, tz) == hours(-8)); 6801 } 6802 6803 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6804 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6805 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6806 assert(st - st == Duration.zero); 6807 assert(cst - st == Duration.zero); 6808 assert(ist - st == Duration.zero); 6809 6810 assert(st - cst == Duration.zero); 6811 assert(cst - cst == Duration.zero); 6812 assert(ist - cst == Duration.zero); 6813 6814 assert(st - ist == Duration.zero); 6815 assert(cst - ist == Duration.zero); 6816 assert(ist - ist == Duration.zero); 6817 6818 static void testScope(scope ref SysTime left, scope ref SysTime right) @safe 6819 { 6820 auto result = left - right; 6821 } 6822 } 6823 6824 6825 /++ 6826 Returns the difference between the two $(LREF SysTime)s in months. 6827 6828 To get the difference in years, subtract the year property 6829 of two $(LREF SysTime)s. To get the difference in days or weeks, 6830 subtract the $(LREF SysTime)s themselves and use the 6831 $(REF Duration, core,time) that results. Because converting between 6832 months and smaller units requires a specific date (which 6833 $(REF Duration, core,time)s don't have), getting the difference in 6834 months requires some math using both the year and month properties, so 6835 this is a convenience function for getting the difference in months. 6836 6837 Note that the number of days in the months or how far into the month 6838 either date is is irrelevant. It is the difference in the month property 6839 combined with the difference in years * 12. So, for instance, 6840 December 31st and January 1st are one month apart just as December 1st 6841 and January 31st are one month apart. 6842 6843 Params: 6844 rhs = The $(LREF SysTime) to subtract from this one. 6845 +/ 6846 int diffMonths(scope SysTime rhs) @safe const nothrow scope 6847 { 6848 return (cast(Date) this).diffMonths(cast(Date) rhs); 6849 } 6850 6851 /// 6852 @safe unittest 6853 { 6854 import core.time; 6855 import std.datetime.date : Date; 6856 6857 assert(SysTime(Date(1999, 2, 1)).diffMonths( 6858 SysTime(Date(1999, 1, 31))) == 1); 6859 6860 assert(SysTime(Date(1999, 1, 31)).diffMonths( 6861 SysTime(Date(1999, 2, 1))) == -1); 6862 6863 assert(SysTime(Date(1999, 3, 1)).diffMonths( 6864 SysTime(Date(1999, 1, 1))) == 2); 6865 6866 assert(SysTime(Date(1999, 1, 1)).diffMonths( 6867 SysTime(Date(1999, 3, 31))) == -2); 6868 } 6869 6870 @safe unittest 6871 { 6872 import core.time; 6873 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6874 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6875 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6876 assert(st.diffMonths(st) == 0); 6877 assert(cst.diffMonths(st) == 0); 6878 assert(ist.diffMonths(st) == 0); 6879 6880 assert(st.diffMonths(cst) == 0); 6881 assert(cst.diffMonths(cst) == 0); 6882 assert(ist.diffMonths(cst) == 0); 6883 6884 assert(st.diffMonths(ist) == 0); 6885 assert(cst.diffMonths(ist) == 0); 6886 assert(ist.diffMonths(ist) == 0); 6887 6888 static void testScope(scope ref SysTime left, scope ref SysTime right) @safe 6889 { 6890 auto result = left.diffMonths(right); 6891 } 6892 } 6893 6894 6895 /++ 6896 Whether this $(LREF SysTime) is in a leap year. 6897 +/ 6898 @property bool isLeapYear() @safe const nothrow scope 6899 { 6900 return (cast(Date) this).isLeapYear; 6901 } 6902 6903 @safe unittest 6904 { 6905 import core.time; 6906 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6907 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6908 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6909 assert(!st.isLeapYear); 6910 assert(!cst.isLeapYear); 6911 assert(!ist.isLeapYear); 6912 6913 static void testScope(scope ref SysTime st) @safe 6914 { 6915 auto result = st.isLeapYear; 6916 } 6917 } 6918 6919 6920 /++ 6921 Day of the week this $(LREF SysTime) is on. 6922 +/ 6923 @property DayOfWeek dayOfWeek() @safe const nothrow scope 6924 { 6925 return getDayOfWeek(dayOfGregorianCal); 6926 } 6927 6928 @safe unittest 6929 { 6930 import core.time; 6931 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6932 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6933 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6934 assert(st.dayOfWeek == DayOfWeek.tue); 6935 assert(cst.dayOfWeek == DayOfWeek.tue); 6936 assert(ist.dayOfWeek == DayOfWeek.tue); 6937 6938 static void testScope(scope ref SysTime st) @safe 6939 { 6940 auto result = st.dayOfWeek; 6941 } 6942 } 6943 6944 6945 /++ 6946 Day of the year this $(LREF SysTime) is on. 6947 +/ 6948 @property ushort dayOfYear() @safe const nothrow scope 6949 { 6950 return (cast(Date) this).dayOfYear; 6951 } 6952 6953 /// 6954 @safe unittest 6955 { 6956 import core.time; 6957 import std.datetime.date : DateTime; 6958 6959 assert(SysTime(DateTime(1999, 1, 1, 12, 22, 7)).dayOfYear == 1); 6960 assert(SysTime(DateTime(1999, 12, 31, 7, 2, 59)).dayOfYear == 365); 6961 assert(SysTime(DateTime(2000, 12, 31, 21, 20, 0)).dayOfYear == 366); 6962 } 6963 6964 @safe unittest 6965 { 6966 import core.time; 6967 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6968 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6969 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6970 assert(st.dayOfYear == 187); 6971 assert(cst.dayOfYear == 187); 6972 assert(ist.dayOfYear == 187); 6973 6974 static void testScope(scope ref SysTime st) @safe 6975 { 6976 auto result = st.dayOfYear; 6977 } 6978 } 6979 6980 6981 /++ 6982 Day of the year. 6983 6984 Params: 6985 day = The day of the year to set which day of the year this 6986 $(LREF SysTime) is on. 6987 +/ 6988 @property void dayOfYear(int day) @safe scope 6989 { 6990 immutable hnsecs = adjTime; 6991 immutable days = convert!("hnsecs", "days")(hnsecs); 6992 immutable theRest = hnsecs - convert!("days", "hnsecs")(days); 6993 6994 auto date = Date(cast(int) days); 6995 date.dayOfYear = day; 6996 6997 immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1); 6998 6999 adjTime = newDaysHNSecs + theRest; 7000 } 7001 7002 @safe unittest 7003 { 7004 import core.time; 7005 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7006 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7007 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7008 st.dayOfYear = 12; 7009 assert(st.dayOfYear == 12); 7010 static assert(!__traits(compiles, cst.dayOfYear = 12)); 7011 static assert(!__traits(compiles, ist.dayOfYear = 12)); 7012 7013 static void testScope(scope ref SysTime st) @safe 7014 { 7015 st.dayOfYear = 42; 7016 } 7017 } 7018 7019 7020 /++ 7021 The Xth day of the Gregorian Calendar that this $(LREF SysTime) is on. 7022 +/ 7023 @property int dayOfGregorianCal() @safe const nothrow scope 7024 { 7025 immutable adjustedTime = adjTime; 7026 7027 // We have to add one because 0 would be midnight, January 1st, 1 A.D., 7028 // which would be the 1st day of the Gregorian Calendar, not the 0th. So, 7029 // simply casting to days is one day off. 7030 if (adjustedTime > 0) 7031 return cast(int) getUnitsFromHNSecs!"days"(adjustedTime) + 1; 7032 7033 long hnsecs = adjustedTime; 7034 immutable days = cast(int) splitUnitsFromHNSecs!"days"(hnsecs); 7035 7036 return hnsecs == 0 ? days + 1 : days; 7037 } 7038 7039 /// 7040 @safe unittest 7041 { 7042 import core.time; 7043 import std.datetime.date : DateTime; 7044 7045 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).dayOfGregorianCal == 1); 7046 assert(SysTime(DateTime(1, 12, 31, 23, 59, 59)).dayOfGregorianCal == 365); 7047 assert(SysTime(DateTime(2, 1, 1, 2, 2, 2)).dayOfGregorianCal == 366); 7048 7049 assert(SysTime(DateTime(0, 12, 31, 7, 7, 7)).dayOfGregorianCal == 0); 7050 assert(SysTime(DateTime(0, 1, 1, 19, 30, 0)).dayOfGregorianCal == -365); 7051 assert(SysTime(DateTime(-1, 12, 31, 4, 7, 0)).dayOfGregorianCal == -366); 7052 7053 assert(SysTime(DateTime(2000, 1, 1, 9, 30, 20)).dayOfGregorianCal == 730_120); 7054 assert(SysTime(DateTime(2010, 12, 31, 15, 45, 50)).dayOfGregorianCal == 734_137); 7055 } 7056 7057 @safe unittest 7058 { 7059 import core.time; 7060 // Test A.D. 7061 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).dayOfGregorianCal == 1); 7062 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1)).dayOfGregorianCal == 1); 7063 assert(SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)).dayOfGregorianCal == 1); 7064 7065 assert(SysTime(DateTime(1, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 1); 7066 assert(SysTime(DateTime(1, 1, 2, 12, 2, 9), msecs(212)).dayOfGregorianCal == 2); 7067 assert(SysTime(DateTime(1, 2, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 32); 7068 assert(SysTime(DateTime(2, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 366); 7069 assert(SysTime(DateTime(3, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 731); 7070 assert(SysTime(DateTime(4, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 1096); 7071 assert(SysTime(DateTime(5, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 1462); 7072 assert(SysTime(DateTime(50, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 17_898); 7073 assert(SysTime(DateTime(97, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 35_065); 7074 assert(SysTime(DateTime(100, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 36_160); 7075 assert(SysTime(DateTime(101, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 36_525); 7076 assert(SysTime(DateTime(105, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 37_986); 7077 assert(SysTime(DateTime(200, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 72_684); 7078 assert(SysTime(DateTime(201, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 73_049); 7079 assert(SysTime(DateTime(300, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 109_208); 7080 assert(SysTime(DateTime(301, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 109_573); 7081 assert(SysTime(DateTime(400, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 145_732); 7082 assert(SysTime(DateTime(401, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 146_098); 7083 assert(SysTime(DateTime(500, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 182_257); 7084 assert(SysTime(DateTime(501, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 182_622); 7085 assert(SysTime(DateTime(1000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 364_878); 7086 assert(SysTime(DateTime(1001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 365_243); 7087 assert(SysTime(DateTime(1600, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 584_023); 7088 assert(SysTime(DateTime(1601, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 584_389); 7089 assert(SysTime(DateTime(1900, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 693_596); 7090 assert(SysTime(DateTime(1901, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 693_961); 7091 assert(SysTime(DateTime(1945, 11, 12, 12, 2, 9), msecs(212)).dayOfGregorianCal == 710_347); 7092 assert(SysTime(DateTime(1999, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 729_755); 7093 assert(SysTime(DateTime(2000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 730_120); 7094 assert(SysTime(DateTime(2001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 730_486); 7095 7096 assert(SysTime(DateTime(2010, 1, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_773); 7097 assert(SysTime(DateTime(2010, 1, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_803); 7098 assert(SysTime(DateTime(2010, 2, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_804); 7099 assert(SysTime(DateTime(2010, 2, 28, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_831); 7100 assert(SysTime(DateTime(2010, 3, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_832); 7101 assert(SysTime(DateTime(2010, 3, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_862); 7102 assert(SysTime(DateTime(2010, 4, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_863); 7103 assert(SysTime(DateTime(2010, 4, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_892); 7104 assert(SysTime(DateTime(2010, 5, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_893); 7105 assert(SysTime(DateTime(2010, 5, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_923); 7106 assert(SysTime(DateTime(2010, 6, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_924); 7107 assert(SysTime(DateTime(2010, 6, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_953); 7108 assert(SysTime(DateTime(2010, 7, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_954); 7109 assert(SysTime(DateTime(2010, 7, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_984); 7110 assert(SysTime(DateTime(2010, 8, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_985); 7111 assert(SysTime(DateTime(2010, 8, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_015); 7112 assert(SysTime(DateTime(2010, 9, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_016); 7113 assert(SysTime(DateTime(2010, 9, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_045); 7114 assert(SysTime(DateTime(2010, 10, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_046); 7115 assert(SysTime(DateTime(2010, 10, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_076); 7116 assert(SysTime(DateTime(2010, 11, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_077); 7117 assert(SysTime(DateTime(2010, 11, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_106); 7118 assert(SysTime(DateTime(2010, 12, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_107); 7119 assert(SysTime(DateTime(2010, 12, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_137); 7120 7121 assert(SysTime(DateTime(2012, 2, 1, 0, 0, 0)).dayOfGregorianCal == 734_534); 7122 assert(SysTime(DateTime(2012, 2, 28, 0, 0, 0)).dayOfGregorianCal == 734_561); 7123 assert(SysTime(DateTime(2012, 2, 29, 0, 0, 0)).dayOfGregorianCal == 734_562); 7124 assert(SysTime(DateTime(2012, 3, 1, 0, 0, 0)).dayOfGregorianCal == 734_563); 7125 7126 // Test B.C. 7127 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)).dayOfGregorianCal == 0); 7128 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998)).dayOfGregorianCal == 0); 7129 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59)).dayOfGregorianCal == 0); 7130 assert(SysTime(DateTime(0, 12, 31, 0, 0, 0), hnsecs(1)).dayOfGregorianCal == 0); 7131 assert(SysTime(DateTime(0, 12, 31, 0, 0, 0)).dayOfGregorianCal == 0); 7132 7133 assert(SysTime(DateTime(-1, 12, 31, 23, 59, 59), hnsecs(9_999_999)).dayOfGregorianCal == -366); 7134 assert(SysTime(DateTime(-1, 12, 31, 23, 59, 59), hnsecs(9_999_998)).dayOfGregorianCal == -366); 7135 assert(SysTime(DateTime(-1, 12, 31, 23, 59, 59)).dayOfGregorianCal == -366); 7136 assert(SysTime(DateTime(-1, 12, 31, 0, 0, 0)).dayOfGregorianCal == -366); 7137 7138 assert(SysTime(DateTime(0, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == 0); 7139 assert(SysTime(DateTime(0, 12, 30, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1); 7140 assert(SysTime(DateTime(0, 12, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -30); 7141 assert(SysTime(DateTime(0, 11, 30, 12, 2, 9), msecs(212)).dayOfGregorianCal == -31); 7142 7143 assert(SysTime(DateTime(-1, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -366); 7144 assert(SysTime(DateTime(-1, 12, 30, 12, 2, 9), msecs(212)).dayOfGregorianCal == -367); 7145 assert(SysTime(DateTime(-1, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730); 7146 assert(SysTime(DateTime(-2, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -731); 7147 assert(SysTime(DateTime(-2, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1095); 7148 assert(SysTime(DateTime(-3, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1096); 7149 assert(SysTime(DateTime(-3, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1460); 7150 assert(SysTime(DateTime(-4, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1461); 7151 assert(SysTime(DateTime(-4, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1826); 7152 assert(SysTime(DateTime(-5, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1827); 7153 assert(SysTime(DateTime(-5, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -2191); 7154 assert(SysTime(DateTime(-9, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -3652); 7155 7156 assert(SysTime(DateTime(-49, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -18_262); 7157 assert(SysTime(DateTime(-50, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -18_627); 7158 assert(SysTime(DateTime(-97, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -35_794); 7159 assert(SysTime(DateTime(-99, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -36_160); 7160 assert(SysTime(DateTime(-99, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -36_524); 7161 assert(SysTime(DateTime(-100, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -36_889); 7162 assert(SysTime(DateTime(-101, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -37_254); 7163 assert(SysTime(DateTime(-105, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -38_715); 7164 assert(SysTime(DateTime(-200, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -73_413); 7165 assert(SysTime(DateTime(-201, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -73_778); 7166 assert(SysTime(DateTime(-300, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -109_937); 7167 assert(SysTime(DateTime(-301, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -110_302); 7168 assert(SysTime(DateTime(-400, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -146_097); 7169 assert(SysTime(DateTime(-400, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -146_462); 7170 assert(SysTime(DateTime(-401, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -146_827); 7171 assert(SysTime(DateTime(-499, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -182_621); 7172 assert(SysTime(DateTime(-500, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -182_986); 7173 assert(SysTime(DateTime(-501, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -183_351); 7174 assert(SysTime(DateTime(-1000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -365_607); 7175 assert(SysTime(DateTime(-1001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -365_972); 7176 assert(SysTime(DateTime(-1599, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -584_387); 7177 assert(SysTime(DateTime(-1600, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -584_388); 7178 assert(SysTime(DateTime(-1600, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -584_753); 7179 assert(SysTime(DateTime(-1601, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -585_118); 7180 assert(SysTime(DateTime(-1900, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -694_325); 7181 assert(SysTime(DateTime(-1901, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -694_690); 7182 assert(SysTime(DateTime(-1999, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730_484); 7183 assert(SysTime(DateTime(-2000, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730_485); 7184 assert(SysTime(DateTime(-2000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730_850); 7185 assert(SysTime(DateTime(-2001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -731_215); 7186 7187 assert(SysTime(DateTime(-2010, 1, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_502); 7188 assert(SysTime(DateTime(-2010, 1, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_472); 7189 assert(SysTime(DateTime(-2010, 2, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_471); 7190 assert(SysTime(DateTime(-2010, 2, 28, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_444); 7191 assert(SysTime(DateTime(-2010, 3, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_443); 7192 assert(SysTime(DateTime(-2010, 3, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_413); 7193 assert(SysTime(DateTime(-2010, 4, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_412); 7194 assert(SysTime(DateTime(-2010, 4, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_383); 7195 assert(SysTime(DateTime(-2010, 5, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_382); 7196 assert(SysTime(DateTime(-2010, 5, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_352); 7197 assert(SysTime(DateTime(-2010, 6, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_351); 7198 assert(SysTime(DateTime(-2010, 6, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_322); 7199 assert(SysTime(DateTime(-2010, 7, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_321); 7200 assert(SysTime(DateTime(-2010, 7, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_291); 7201 assert(SysTime(DateTime(-2010, 8, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_290); 7202 assert(SysTime(DateTime(-2010, 8, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_260); 7203 assert(SysTime(DateTime(-2010, 9, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_259); 7204 assert(SysTime(DateTime(-2010, 9, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_230); 7205 assert(SysTime(DateTime(-2010, 10, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_229); 7206 assert(SysTime(DateTime(-2010, 10, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_199); 7207 assert(SysTime(DateTime(-2010, 11, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_198); 7208 assert(SysTime(DateTime(-2010, 11, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_169); 7209 assert(SysTime(DateTime(-2010, 12, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_168); 7210 assert(SysTime(DateTime(-2010, 12, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_138); 7211 7212 assert(SysTime(DateTime(-2012, 2, 1, 0, 0, 0)).dayOfGregorianCal == -735_202); 7213 assert(SysTime(DateTime(-2012, 2, 28, 0, 0, 0)).dayOfGregorianCal == -735_175); 7214 assert(SysTime(DateTime(-2012, 2, 29, 0, 0, 0)).dayOfGregorianCal == -735_174); 7215 assert(SysTime(DateTime(-2012, 3, 1, 0, 0, 0)).dayOfGregorianCal == -735_173); 7216 7217 // Start of Hebrew Calendar 7218 assert(SysTime(DateTime(-3760, 9, 7, 0, 0, 0)).dayOfGregorianCal == -1_373_427); 7219 7220 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7221 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7222 assert(cst.dayOfGregorianCal == 729_941); 7223 assert(ist.dayOfGregorianCal == 729_941); 7224 7225 static void testScope(scope ref SysTime st) @safe 7226 { 7227 auto result = st.dayOfGregorianCal; 7228 } 7229 } 7230 7231 7232 // Test that the logic for the day of the Gregorian Calendar is consistent 7233 // between Date and SysTime. 7234 @safe unittest 7235 { 7236 import core.time; 7237 void test(Date date, SysTime st, size_t line = __LINE__) 7238 { 7239 if (date.dayOfGregorianCal != st.dayOfGregorianCal) 7240 { 7241 throw new AssertError(format("Date [%s] SysTime [%s]", date.dayOfGregorianCal, st.dayOfGregorianCal), 7242 __FILE__, line); 7243 } 7244 } 7245 7246 // Test A.D. 7247 test(Date(1, 1, 1), SysTime(DateTime(1, 1, 1, 0, 0, 0))); 7248 test(Date(1, 1, 2), SysTime(DateTime(1, 1, 2, 0, 0, 0), hnsecs(500))); 7249 test(Date(1, 2, 1), SysTime(DateTime(1, 2, 1, 0, 0, 0), hnsecs(50_000))); 7250 test(Date(2, 1, 1), SysTime(DateTime(2, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 7251 test(Date(3, 1, 1), SysTime(DateTime(3, 1, 1, 12, 13, 14))); 7252 test(Date(4, 1, 1), SysTime(DateTime(4, 1, 1, 12, 13, 14), hnsecs(500))); 7253 test(Date(5, 1, 1), SysTime(DateTime(5, 1, 1, 12, 13, 14), hnsecs(50_000))); 7254 test(Date(50, 1, 1), SysTime(DateTime(50, 1, 1, 12, 13, 14), hnsecs(9_999_999))); 7255 test(Date(97, 1, 1), SysTime(DateTime(97, 1, 1, 23, 59, 59))); 7256 test(Date(100, 1, 1), SysTime(DateTime(100, 1, 1, 23, 59, 59), hnsecs(500))); 7257 test(Date(101, 1, 1), SysTime(DateTime(101, 1, 1, 23, 59, 59), hnsecs(50_000))); 7258 test(Date(105, 1, 1), SysTime(DateTime(105, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7259 test(Date(200, 1, 1), SysTime(DateTime(200, 1, 1, 0, 0, 0))); 7260 test(Date(201, 1, 1), SysTime(DateTime(201, 1, 1, 0, 0, 0), hnsecs(500))); 7261 test(Date(300, 1, 1), SysTime(DateTime(300, 1, 1, 0, 0, 0), hnsecs(50_000))); 7262 test(Date(301, 1, 1), SysTime(DateTime(301, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 7263 test(Date(400, 1, 1), SysTime(DateTime(400, 1, 1, 12, 13, 14))); 7264 test(Date(401, 1, 1), SysTime(DateTime(401, 1, 1, 12, 13, 14), hnsecs(500))); 7265 test(Date(500, 1, 1), SysTime(DateTime(500, 1, 1, 12, 13, 14), hnsecs(50_000))); 7266 test(Date(501, 1, 1), SysTime(DateTime(501, 1, 1, 12, 13, 14), hnsecs(9_999_999))); 7267 test(Date(1000, 1, 1), SysTime(DateTime(1000, 1, 1, 23, 59, 59))); 7268 test(Date(1001, 1, 1), SysTime(DateTime(1001, 1, 1, 23, 59, 59), hnsecs(500))); 7269 test(Date(1600, 1, 1), SysTime(DateTime(1600, 1, 1, 23, 59, 59), hnsecs(50_000))); 7270 test(Date(1601, 1, 1), SysTime(DateTime(1601, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7271 test(Date(1900, 1, 1), SysTime(DateTime(1900, 1, 1, 0, 0, 0))); 7272 test(Date(1901, 1, 1), SysTime(DateTime(1901, 1, 1, 0, 0, 0), hnsecs(500))); 7273 test(Date(1945, 11, 12), SysTime(DateTime(1945, 11, 12, 0, 0, 0), hnsecs(50_000))); 7274 test(Date(1999, 1, 1), SysTime(DateTime(1999, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 7275 test(Date(1999, 7, 6), SysTime(DateTime(1999, 7, 6, 12, 13, 14))); 7276 test(Date(2000, 1, 1), SysTime(DateTime(2000, 1, 1, 12, 13, 14), hnsecs(500))); 7277 test(Date(2001, 1, 1), SysTime(DateTime(2001, 1, 1, 12, 13, 14), hnsecs(50_000))); 7278 7279 test(Date(2010, 1, 1), SysTime(DateTime(2010, 1, 1, 12, 13, 14), hnsecs(9_999_999))); 7280 test(Date(2010, 1, 31), SysTime(DateTime(2010, 1, 31, 23, 0, 0))); 7281 test(Date(2010, 2, 1), SysTime(DateTime(2010, 2, 1, 23, 59, 59), hnsecs(500))); 7282 test(Date(2010, 2, 28), SysTime(DateTime(2010, 2, 28, 23, 59, 59), hnsecs(50_000))); 7283 test(Date(2010, 3, 1), SysTime(DateTime(2010, 3, 1, 23, 59, 59), hnsecs(9_999_999))); 7284 test(Date(2010, 3, 31), SysTime(DateTime(2010, 3, 31, 0, 0, 0))); 7285 test(Date(2010, 4, 1), SysTime(DateTime(2010, 4, 1, 0, 0, 0), hnsecs(500))); 7286 test(Date(2010, 4, 30), SysTime(DateTime(2010, 4, 30, 0, 0, 0), hnsecs(50_000))); 7287 test(Date(2010, 5, 1), SysTime(DateTime(2010, 5, 1, 0, 0, 0), hnsecs(9_999_999))); 7288 test(Date(2010, 5, 31), SysTime(DateTime(2010, 5, 31, 12, 13, 14))); 7289 test(Date(2010, 6, 1), SysTime(DateTime(2010, 6, 1, 12, 13, 14), hnsecs(500))); 7290 test(Date(2010, 6, 30), SysTime(DateTime(2010, 6, 30, 12, 13, 14), hnsecs(50_000))); 7291 test(Date(2010, 7, 1), SysTime(DateTime(2010, 7, 1, 12, 13, 14), hnsecs(9_999_999))); 7292 test(Date(2010, 7, 31), SysTime(DateTime(2010, 7, 31, 23, 59, 59))); 7293 test(Date(2010, 8, 1), SysTime(DateTime(2010, 8, 1, 23, 59, 59), hnsecs(500))); 7294 test(Date(2010, 8, 31), SysTime(DateTime(2010, 8, 31, 23, 59, 59), hnsecs(50_000))); 7295 test(Date(2010, 9, 1), SysTime(DateTime(2010, 9, 1, 23, 59, 59), hnsecs(9_999_999))); 7296 test(Date(2010, 9, 30), SysTime(DateTime(2010, 9, 30, 12, 0, 0))); 7297 test(Date(2010, 10, 1), SysTime(DateTime(2010, 10, 1, 0, 12, 0), hnsecs(500))); 7298 test(Date(2010, 10, 31), SysTime(DateTime(2010, 10, 31, 0, 0, 12), hnsecs(50_000))); 7299 test(Date(2010, 11, 1), SysTime(DateTime(2010, 11, 1, 23, 0, 0), hnsecs(9_999_999))); 7300 test(Date(2010, 11, 30), SysTime(DateTime(2010, 11, 30, 0, 59, 0))); 7301 test(Date(2010, 12, 1), SysTime(DateTime(2010, 12, 1, 0, 0, 59), hnsecs(500))); 7302 test(Date(2010, 12, 31), SysTime(DateTime(2010, 12, 31, 0, 59, 59), hnsecs(50_000))); 7303 7304 test(Date(2012, 2, 1), SysTime(DateTime(2012, 2, 1, 23, 0, 59), hnsecs(9_999_999))); 7305 test(Date(2012, 2, 28), SysTime(DateTime(2012, 2, 28, 23, 59, 0))); 7306 test(Date(2012, 2, 29), SysTime(DateTime(2012, 2, 29, 7, 7, 7), hnsecs(7))); 7307 test(Date(2012, 3, 1), SysTime(DateTime(2012, 3, 1, 7, 7, 7), hnsecs(7))); 7308 7309 // Test B.C. 7310 test(Date(0, 12, 31), SysTime(DateTime(0, 12, 31, 0, 0, 0))); 7311 test(Date(0, 12, 30), SysTime(DateTime(0, 12, 30, 0, 0, 0), hnsecs(500))); 7312 test(Date(0, 12, 1), SysTime(DateTime(0, 12, 1, 0, 0, 0), hnsecs(50_000))); 7313 test(Date(0, 11, 30), SysTime(DateTime(0, 11, 30, 0, 0, 0), hnsecs(9_999_999))); 7314 7315 test(Date(-1, 12, 31), SysTime(DateTime(-1, 12, 31, 12, 13, 14))); 7316 test(Date(-1, 12, 30), SysTime(DateTime(-1, 12, 30, 12, 13, 14), hnsecs(500))); 7317 test(Date(-1, 1, 1), SysTime(DateTime(-1, 1, 1, 12, 13, 14), hnsecs(50_000))); 7318 test(Date(-2, 12, 31), SysTime(DateTime(-2, 12, 31, 12, 13, 14), hnsecs(9_999_999))); 7319 test(Date(-2, 1, 1), SysTime(DateTime(-2, 1, 1, 23, 59, 59))); 7320 test(Date(-3, 12, 31), SysTime(DateTime(-3, 12, 31, 23, 59, 59), hnsecs(500))); 7321 test(Date(-3, 1, 1), SysTime(DateTime(-3, 1, 1, 23, 59, 59), hnsecs(50_000))); 7322 test(Date(-4, 12, 31), SysTime(DateTime(-4, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 7323 test(Date(-4, 1, 1), SysTime(DateTime(-4, 1, 1, 0, 0, 0))); 7324 test(Date(-5, 12, 31), SysTime(DateTime(-5, 12, 31, 0, 0, 0), hnsecs(500))); 7325 test(Date(-5, 1, 1), SysTime(DateTime(-5, 1, 1, 0, 0, 0), hnsecs(50_000))); 7326 test(Date(-9, 1, 1), SysTime(DateTime(-9, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 7327 7328 test(Date(-49, 1, 1), SysTime(DateTime(-49, 1, 1, 12, 13, 14))); 7329 test(Date(-50, 1, 1), SysTime(DateTime(-50, 1, 1, 12, 13, 14), hnsecs(500))); 7330 test(Date(-97, 1, 1), SysTime(DateTime(-97, 1, 1, 12, 13, 14), hnsecs(50_000))); 7331 test(Date(-99, 12, 31), SysTime(DateTime(-99, 12, 31, 12, 13, 14), hnsecs(9_999_999))); 7332 test(Date(-99, 1, 1), SysTime(DateTime(-99, 1, 1, 23, 59, 59))); 7333 test(Date(-100, 1, 1), SysTime(DateTime(-100, 1, 1, 23, 59, 59), hnsecs(500))); 7334 test(Date(-101, 1, 1), SysTime(DateTime(-101, 1, 1, 23, 59, 59), hnsecs(50_000))); 7335 test(Date(-105, 1, 1), SysTime(DateTime(-105, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7336 test(Date(-200, 1, 1), SysTime(DateTime(-200, 1, 1, 0, 0, 0))); 7337 test(Date(-201, 1, 1), SysTime(DateTime(-201, 1, 1, 0, 0, 0), hnsecs(500))); 7338 test(Date(-300, 1, 1), SysTime(DateTime(-300, 1, 1, 0, 0, 0), hnsecs(50_000))); 7339 test(Date(-301, 1, 1), SysTime(DateTime(-301, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 7340 test(Date(-400, 12, 31), SysTime(DateTime(-400, 12, 31, 12, 13, 14))); 7341 test(Date(-400, 1, 1), SysTime(DateTime(-400, 1, 1, 12, 13, 14), hnsecs(500))); 7342 test(Date(-401, 1, 1), SysTime(DateTime(-401, 1, 1, 12, 13, 14), hnsecs(50_000))); 7343 test(Date(-499, 1, 1), SysTime(DateTime(-499, 1, 1, 12, 13, 14), hnsecs(9_999_999))); 7344 test(Date(-500, 1, 1), SysTime(DateTime(-500, 1, 1, 23, 59, 59))); 7345 test(Date(-501, 1, 1), SysTime(DateTime(-501, 1, 1, 23, 59, 59), hnsecs(500))); 7346 test(Date(-1000, 1, 1), SysTime(DateTime(-1000, 1, 1, 23, 59, 59), hnsecs(50_000))); 7347 test(Date(-1001, 1, 1), SysTime(DateTime(-1001, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7348 test(Date(-1599, 1, 1), SysTime(DateTime(-1599, 1, 1, 0, 0, 0))); 7349 test(Date(-1600, 12, 31), SysTime(DateTime(-1600, 12, 31, 0, 0, 0), hnsecs(500))); 7350 test(Date(-1600, 1, 1), SysTime(DateTime(-1600, 1, 1, 0, 0, 0), hnsecs(50_000))); 7351 test(Date(-1601, 1, 1), SysTime(DateTime(-1601, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 7352 test(Date(-1900, 1, 1), SysTime(DateTime(-1900, 1, 1, 12, 13, 14))); 7353 test(Date(-1901, 1, 1), SysTime(DateTime(-1901, 1, 1, 12, 13, 14), hnsecs(500))); 7354 test(Date(-1999, 1, 1), SysTime(DateTime(-1999, 1, 1, 12, 13, 14), hnsecs(50_000))); 7355 test(Date(-1999, 7, 6), SysTime(DateTime(-1999, 7, 6, 12, 13, 14), hnsecs(9_999_999))); 7356 test(Date(-2000, 12, 31), SysTime(DateTime(-2000, 12, 31, 23, 59, 59))); 7357 test(Date(-2000, 1, 1), SysTime(DateTime(-2000, 1, 1, 23, 59, 59), hnsecs(500))); 7358 test(Date(-2001, 1, 1), SysTime(DateTime(-2001, 1, 1, 23, 59, 59), hnsecs(50_000))); 7359 7360 test(Date(-2010, 1, 1), SysTime(DateTime(-2010, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7361 test(Date(-2010, 1, 31), SysTime(DateTime(-2010, 1, 31, 0, 0, 0))); 7362 test(Date(-2010, 2, 1), SysTime(DateTime(-2010, 2, 1, 0, 0, 0), hnsecs(500))); 7363 test(Date(-2010, 2, 28), SysTime(DateTime(-2010, 2, 28, 0, 0, 0), hnsecs(50_000))); 7364 test(Date(-2010, 3, 1), SysTime(DateTime(-2010, 3, 1, 0, 0, 0), hnsecs(9_999_999))); 7365 test(Date(-2010, 3, 31), SysTime(DateTime(-2010, 3, 31, 12, 13, 14))); 7366 test(Date(-2010, 4, 1), SysTime(DateTime(-2010, 4, 1, 12, 13, 14), hnsecs(500))); 7367 test(Date(-2010, 4, 30), SysTime(DateTime(-2010, 4, 30, 12, 13, 14), hnsecs(50_000))); 7368 test(Date(-2010, 5, 1), SysTime(DateTime(-2010, 5, 1, 12, 13, 14), hnsecs(9_999_999))); 7369 test(Date(-2010, 5, 31), SysTime(DateTime(-2010, 5, 31, 23, 59, 59))); 7370 test(Date(-2010, 6, 1), SysTime(DateTime(-2010, 6, 1, 23, 59, 59), hnsecs(500))); 7371 test(Date(-2010, 6, 30), SysTime(DateTime(-2010, 6, 30, 23, 59, 59), hnsecs(50_000))); 7372 test(Date(-2010, 7, 1), SysTime(DateTime(-2010, 7, 1, 23, 59, 59), hnsecs(9_999_999))); 7373 test(Date(-2010, 7, 31), SysTime(DateTime(-2010, 7, 31, 0, 0, 0))); 7374 test(Date(-2010, 8, 1), SysTime(DateTime(-2010, 8, 1, 0, 0, 0), hnsecs(500))); 7375 test(Date(-2010, 8, 31), SysTime(DateTime(-2010, 8, 31, 0, 0, 0), hnsecs(50_000))); 7376 test(Date(-2010, 9, 1), SysTime(DateTime(-2010, 9, 1, 0, 0, 0), hnsecs(9_999_999))); 7377 test(Date(-2010, 9, 30), SysTime(DateTime(-2010, 9, 30, 12, 0, 0))); 7378 test(Date(-2010, 10, 1), SysTime(DateTime(-2010, 10, 1, 0, 12, 0), hnsecs(500))); 7379 test(Date(-2010, 10, 31), SysTime(DateTime(-2010, 10, 31, 0, 0, 12), hnsecs(50_000))); 7380 test(Date(-2010, 11, 1), SysTime(DateTime(-2010, 11, 1, 23, 0, 0), hnsecs(9_999_999))); 7381 test(Date(-2010, 11, 30), SysTime(DateTime(-2010, 11, 30, 0, 59, 0))); 7382 test(Date(-2010, 12, 1), SysTime(DateTime(-2010, 12, 1, 0, 0, 59), hnsecs(500))); 7383 test(Date(-2010, 12, 31), SysTime(DateTime(-2010, 12, 31, 0, 59, 59), hnsecs(50_000))); 7384 7385 test(Date(-2012, 2, 1), SysTime(DateTime(-2012, 2, 1, 23, 0, 59), hnsecs(9_999_999))); 7386 test(Date(-2012, 2, 28), SysTime(DateTime(-2012, 2, 28, 23, 59, 0))); 7387 test(Date(-2012, 2, 29), SysTime(DateTime(-2012, 2, 29, 7, 7, 7), hnsecs(7))); 7388 test(Date(-2012, 3, 1), SysTime(DateTime(-2012, 3, 1, 7, 7, 7), hnsecs(7))); 7389 7390 test(Date(-3760, 9, 7), SysTime(DateTime(-3760, 9, 7, 0, 0, 0))); 7391 } 7392 7393 7394 /++ 7395 The Xth day of the Gregorian Calendar that this $(LREF SysTime) is on. 7396 Setting this property does not affect the time portion of $(LREF SysTime). 7397 7398 Params: 7399 days = The day of the Gregorian Calendar to set this $(LREF SysTime) 7400 to. 7401 +/ 7402 @property void dayOfGregorianCal(int days) @safe nothrow scope 7403 { 7404 auto hnsecs = adjTime; 7405 hnsecs = removeUnitsFromHNSecs!"days"(hnsecs); 7406 7407 if (hnsecs < 0) 7408 hnsecs += convert!("hours", "hnsecs")(24); 7409 7410 if (--days < 0) 7411 { 7412 hnsecs -= convert!("hours", "hnsecs")(24); 7413 ++days; 7414 } 7415 7416 immutable newDaysHNSecs = convert!("days", "hnsecs")(days); 7417 7418 adjTime = newDaysHNSecs + hnsecs; 7419 } 7420 7421 /// 7422 @safe unittest 7423 { 7424 import core.time; 7425 import std.datetime.date : DateTime; 7426 7427 auto st = SysTime(DateTime(0, 1, 1, 12, 0, 0)); 7428 st.dayOfGregorianCal = 1; 7429 assert(st == SysTime(DateTime(1, 1, 1, 12, 0, 0))); 7430 7431 st.dayOfGregorianCal = 365; 7432 assert(st == SysTime(DateTime(1, 12, 31, 12, 0, 0))); 7433 7434 st.dayOfGregorianCal = 366; 7435 assert(st == SysTime(DateTime(2, 1, 1, 12, 0, 0))); 7436 7437 st.dayOfGregorianCal = 0; 7438 assert(st == SysTime(DateTime(0, 12, 31, 12, 0, 0))); 7439 7440 st.dayOfGregorianCal = -365; 7441 assert(st == SysTime(DateTime(-0, 1, 1, 12, 0, 0))); 7442 7443 st.dayOfGregorianCal = -366; 7444 assert(st == SysTime(DateTime(-1, 12, 31, 12, 0, 0))); 7445 7446 st.dayOfGregorianCal = 730_120; 7447 assert(st == SysTime(DateTime(2000, 1, 1, 12, 0, 0))); 7448 7449 st.dayOfGregorianCal = 734_137; 7450 assert(st == SysTime(DateTime(2010, 12, 31, 12, 0, 0))); 7451 } 7452 7453 @safe unittest 7454 { 7455 import core.time; 7456 void testST(SysTime orig, int day, SysTime expected, size_t line = __LINE__) @safe 7457 { 7458 orig.dayOfGregorianCal = day; 7459 if (orig != expected) 7460 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 7461 } 7462 7463 // Test A.D. 7464 testST(SysTime(DateTime(1, 1, 1, 0, 0, 0)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 7465 testST(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 7466 testST(SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)), 1, 7467 SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7468 7469 // Test B.C. 7470 testST(SysTime(DateTime(0, 1, 1, 0, 0, 0)), 0, SysTime(DateTime(0, 12, 31, 0, 0, 0))); 7471 testST(SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)), 0, 7472 SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 7473 testST(SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(1)), 0, 7474 SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1))); 7475 testST(SysTime(DateTime(0, 1, 1, 23, 59, 59)), 0, SysTime(DateTime(0, 12, 31, 23, 59, 59))); 7476 7477 // Test Both. 7478 testST(SysTime(DateTime(-512, 7, 20, 0, 0, 0)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 7479 testST(SysTime(DateTime(-513, 6, 6, 0, 0, 0), hnsecs(1)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 7480 testST(SysTime(DateTime(-511, 5, 7, 23, 59, 59), hnsecs(9_999_999)), 1, 7481 SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7482 7483 testST(SysTime(DateTime(1607, 4, 8, 0, 0, 0)), 0, SysTime(DateTime(0, 12, 31, 0, 0, 0))); 7484 testST(SysTime(DateTime(1500, 3, 9, 23, 59, 59), hnsecs(9_999_999)), 0, 7485 SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 7486 testST(SysTime(DateTime(999, 2, 10, 23, 59, 59), hnsecs(1)), 0, 7487 SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1))); 7488 testST(SysTime(DateTime(2007, 12, 11, 23, 59, 59)), 0, SysTime(DateTime(0, 12, 31, 23, 59, 59))); 7489 7490 7491 auto st = SysTime(DateTime(1, 1, 1, 12, 2, 9), msecs(212)); 7492 7493 void testST2(int day, SysTime expected, size_t line = __LINE__) @safe 7494 { 7495 st.dayOfGregorianCal = day; 7496 if (st != expected) 7497 throw new AssertError(format("Failed. actual [%s] != expected [%s]", st, expected), __FILE__, line); 7498 } 7499 7500 // Test A.D. 7501 testST2(1, SysTime(DateTime(1, 1, 1, 12, 2, 9), msecs(212))); 7502 testST2(2, SysTime(DateTime(1, 1, 2, 12, 2, 9), msecs(212))); 7503 testST2(32, SysTime(DateTime(1, 2, 1, 12, 2, 9), msecs(212))); 7504 testST2(366, SysTime(DateTime(2, 1, 1, 12, 2, 9), msecs(212))); 7505 testST2(731, SysTime(DateTime(3, 1, 1, 12, 2, 9), msecs(212))); 7506 testST2(1096, SysTime(DateTime(4, 1, 1, 12, 2, 9), msecs(212))); 7507 testST2(1462, SysTime(DateTime(5, 1, 1, 12, 2, 9), msecs(212))); 7508 testST2(17_898, SysTime(DateTime(50, 1, 1, 12, 2, 9), msecs(212))); 7509 testST2(35_065, SysTime(DateTime(97, 1, 1, 12, 2, 9), msecs(212))); 7510 testST2(36_160, SysTime(DateTime(100, 1, 1, 12, 2, 9), msecs(212))); 7511 testST2(36_525, SysTime(DateTime(101, 1, 1, 12, 2, 9), msecs(212))); 7512 testST2(37_986, SysTime(DateTime(105, 1, 1, 12, 2, 9), msecs(212))); 7513 testST2(72_684, SysTime(DateTime(200, 1, 1, 12, 2, 9), msecs(212))); 7514 testST2(73_049, SysTime(DateTime(201, 1, 1, 12, 2, 9), msecs(212))); 7515 testST2(109_208, SysTime(DateTime(300, 1, 1, 12, 2, 9), msecs(212))); 7516 testST2(109_573, SysTime(DateTime(301, 1, 1, 12, 2, 9), msecs(212))); 7517 testST2(145_732, SysTime(DateTime(400, 1, 1, 12, 2, 9), msecs(212))); 7518 testST2(146_098, SysTime(DateTime(401, 1, 1, 12, 2, 9), msecs(212))); 7519 testST2(182_257, SysTime(DateTime(500, 1, 1, 12, 2, 9), msecs(212))); 7520 testST2(182_622, SysTime(DateTime(501, 1, 1, 12, 2, 9), msecs(212))); 7521 testST2(364_878, SysTime(DateTime(1000, 1, 1, 12, 2, 9), msecs(212))); 7522 testST2(365_243, SysTime(DateTime(1001, 1, 1, 12, 2, 9), msecs(212))); 7523 testST2(584_023, SysTime(DateTime(1600, 1, 1, 12, 2, 9), msecs(212))); 7524 testST2(584_389, SysTime(DateTime(1601, 1, 1, 12, 2, 9), msecs(212))); 7525 testST2(693_596, SysTime(DateTime(1900, 1, 1, 12, 2, 9), msecs(212))); 7526 testST2(693_961, SysTime(DateTime(1901, 1, 1, 12, 2, 9), msecs(212))); 7527 testST2(729_755, SysTime(DateTime(1999, 1, 1, 12, 2, 9), msecs(212))); 7528 testST2(730_120, SysTime(DateTime(2000, 1, 1, 12, 2, 9), msecs(212))); 7529 testST2(730_486, SysTime(DateTime(2001, 1, 1, 12, 2, 9), msecs(212))); 7530 7531 testST2(733_773, SysTime(DateTime(2010, 1, 1, 12, 2, 9), msecs(212))); 7532 testST2(733_803, SysTime(DateTime(2010, 1, 31, 12, 2, 9), msecs(212))); 7533 testST2(733_804, SysTime(DateTime(2010, 2, 1, 12, 2, 9), msecs(212))); 7534 testST2(733_831, SysTime(DateTime(2010, 2, 28, 12, 2, 9), msecs(212))); 7535 testST2(733_832, SysTime(DateTime(2010, 3, 1, 12, 2, 9), msecs(212))); 7536 testST2(733_862, SysTime(DateTime(2010, 3, 31, 12, 2, 9), msecs(212))); 7537 testST2(733_863, SysTime(DateTime(2010, 4, 1, 12, 2, 9), msecs(212))); 7538 testST2(733_892, SysTime(DateTime(2010, 4, 30, 12, 2, 9), msecs(212))); 7539 testST2(733_893, SysTime(DateTime(2010, 5, 1, 12, 2, 9), msecs(212))); 7540 testST2(733_923, SysTime(DateTime(2010, 5, 31, 12, 2, 9), msecs(212))); 7541 testST2(733_924, SysTime(DateTime(2010, 6, 1, 12, 2, 9), msecs(212))); 7542 testST2(733_953, SysTime(DateTime(2010, 6, 30, 12, 2, 9), msecs(212))); 7543 testST2(733_954, SysTime(DateTime(2010, 7, 1, 12, 2, 9), msecs(212))); 7544 testST2(733_984, SysTime(DateTime(2010, 7, 31, 12, 2, 9), msecs(212))); 7545 testST2(733_985, SysTime(DateTime(2010, 8, 1, 12, 2, 9), msecs(212))); 7546 testST2(734_015, SysTime(DateTime(2010, 8, 31, 12, 2, 9), msecs(212))); 7547 testST2(734_016, SysTime(DateTime(2010, 9, 1, 12, 2, 9), msecs(212))); 7548 testST2(734_045, SysTime(DateTime(2010, 9, 30, 12, 2, 9), msecs(212))); 7549 testST2(734_046, SysTime(DateTime(2010, 10, 1, 12, 2, 9), msecs(212))); 7550 testST2(734_076, SysTime(DateTime(2010, 10, 31, 12, 2, 9), msecs(212))); 7551 testST2(734_077, SysTime(DateTime(2010, 11, 1, 12, 2, 9), msecs(212))); 7552 testST2(734_106, SysTime(DateTime(2010, 11, 30, 12, 2, 9), msecs(212))); 7553 testST2(734_107, SysTime(DateTime(2010, 12, 1, 12, 2, 9), msecs(212))); 7554 testST2(734_137, SysTime(DateTime(2010, 12, 31, 12, 2, 9), msecs(212))); 7555 7556 testST2(734_534, SysTime(DateTime(2012, 2, 1, 12, 2, 9), msecs(212))); 7557 testST2(734_561, SysTime(DateTime(2012, 2, 28, 12, 2, 9), msecs(212))); 7558 testST2(734_562, SysTime(DateTime(2012, 2, 29, 12, 2, 9), msecs(212))); 7559 testST2(734_563, SysTime(DateTime(2012, 3, 1, 12, 2, 9), msecs(212))); 7560 7561 testST2(734_534, SysTime(DateTime(2012, 2, 1, 12, 2, 9), msecs(212))); 7562 7563 testST2(734_561, SysTime(DateTime(2012, 2, 28, 12, 2, 9), msecs(212))); 7564 testST2(734_562, SysTime(DateTime(2012, 2, 29, 12, 2, 9), msecs(212))); 7565 testST2(734_563, SysTime(DateTime(2012, 3, 1, 12, 2, 9), msecs(212))); 7566 7567 // Test B.C. 7568 testST2(0, SysTime(DateTime(0, 12, 31, 12, 2, 9), msecs(212))); 7569 testST2(-1, SysTime(DateTime(0, 12, 30, 12, 2, 9), msecs(212))); 7570 testST2(-30, SysTime(DateTime(0, 12, 1, 12, 2, 9), msecs(212))); 7571 testST2(-31, SysTime(DateTime(0, 11, 30, 12, 2, 9), msecs(212))); 7572 7573 testST2(-366, SysTime(DateTime(-1, 12, 31, 12, 2, 9), msecs(212))); 7574 testST2(-367, SysTime(DateTime(-1, 12, 30, 12, 2, 9), msecs(212))); 7575 testST2(-730, SysTime(DateTime(-1, 1, 1, 12, 2, 9), msecs(212))); 7576 testST2(-731, SysTime(DateTime(-2, 12, 31, 12, 2, 9), msecs(212))); 7577 testST2(-1095, SysTime(DateTime(-2, 1, 1, 12, 2, 9), msecs(212))); 7578 testST2(-1096, SysTime(DateTime(-3, 12, 31, 12, 2, 9), msecs(212))); 7579 testST2(-1460, SysTime(DateTime(-3, 1, 1, 12, 2, 9), msecs(212))); 7580 testST2(-1461, SysTime(DateTime(-4, 12, 31, 12, 2, 9), msecs(212))); 7581 testST2(-1826, SysTime(DateTime(-4, 1, 1, 12, 2, 9), msecs(212))); 7582 testST2(-1827, SysTime(DateTime(-5, 12, 31, 12, 2, 9), msecs(212))); 7583 testST2(-2191, SysTime(DateTime(-5, 1, 1, 12, 2, 9), msecs(212))); 7584 testST2(-3652, SysTime(DateTime(-9, 1, 1, 12, 2, 9), msecs(212))); 7585 7586 testST2(-18_262, SysTime(DateTime(-49, 1, 1, 12, 2, 9), msecs(212))); 7587 testST2(-18_627, SysTime(DateTime(-50, 1, 1, 12, 2, 9), msecs(212))); 7588 testST2(-35_794, SysTime(DateTime(-97, 1, 1, 12, 2, 9), msecs(212))); 7589 testST2(-36_160, SysTime(DateTime(-99, 12, 31, 12, 2, 9), msecs(212))); 7590 testST2(-36_524, SysTime(DateTime(-99, 1, 1, 12, 2, 9), msecs(212))); 7591 testST2(-36_889, SysTime(DateTime(-100, 1, 1, 12, 2, 9), msecs(212))); 7592 testST2(-37_254, SysTime(DateTime(-101, 1, 1, 12, 2, 9), msecs(212))); 7593 testST2(-38_715, SysTime(DateTime(-105, 1, 1, 12, 2, 9), msecs(212))); 7594 testST2(-73_413, SysTime(DateTime(-200, 1, 1, 12, 2, 9), msecs(212))); 7595 testST2(-73_778, SysTime(DateTime(-201, 1, 1, 12, 2, 9), msecs(212))); 7596 testST2(-109_937, SysTime(DateTime(-300, 1, 1, 12, 2, 9), msecs(212))); 7597 testST2(-110_302, SysTime(DateTime(-301, 1, 1, 12, 2, 9), msecs(212))); 7598 testST2(-146_097, SysTime(DateTime(-400, 12, 31, 12, 2, 9), msecs(212))); 7599 testST2(-146_462, SysTime(DateTime(-400, 1, 1, 12, 2, 9), msecs(212))); 7600 testST2(-146_827, SysTime(DateTime(-401, 1, 1, 12, 2, 9), msecs(212))); 7601 testST2(-182_621, SysTime(DateTime(-499, 1, 1, 12, 2, 9), msecs(212))); 7602 testST2(-182_986, SysTime(DateTime(-500, 1, 1, 12, 2, 9), msecs(212))); 7603 testST2(-183_351, SysTime(DateTime(-501, 1, 1, 12, 2, 9), msecs(212))); 7604 testST2(-365_607, SysTime(DateTime(-1000, 1, 1, 12, 2, 9), msecs(212))); 7605 testST2(-365_972, SysTime(DateTime(-1001, 1, 1, 12, 2, 9), msecs(212))); 7606 testST2(-584_387, SysTime(DateTime(-1599, 1, 1, 12, 2, 9), msecs(212))); 7607 testST2(-584_388, SysTime(DateTime(-1600, 12, 31, 12, 2, 9), msecs(212))); 7608 testST2(-584_753, SysTime(DateTime(-1600, 1, 1, 12, 2, 9), msecs(212))); 7609 testST2(-585_118, SysTime(DateTime(-1601, 1, 1, 12, 2, 9), msecs(212))); 7610 testST2(-694_325, SysTime(DateTime(-1900, 1, 1, 12, 2, 9), msecs(212))); 7611 testST2(-694_690, SysTime(DateTime(-1901, 1, 1, 12, 2, 9), msecs(212))); 7612 testST2(-730_484, SysTime(DateTime(-1999, 1, 1, 12, 2, 9), msecs(212))); 7613 testST2(-730_485, SysTime(DateTime(-2000, 12, 31, 12, 2, 9), msecs(212))); 7614 testST2(-730_850, SysTime(DateTime(-2000, 1, 1, 12, 2, 9), msecs(212))); 7615 testST2(-731_215, SysTime(DateTime(-2001, 1, 1, 12, 2, 9), msecs(212))); 7616 7617 testST2(-734_502, SysTime(DateTime(-2010, 1, 1, 12, 2, 9), msecs(212))); 7618 testST2(-734_472, SysTime(DateTime(-2010, 1, 31, 12, 2, 9), msecs(212))); 7619 testST2(-734_471, SysTime(DateTime(-2010, 2, 1, 12, 2, 9), msecs(212))); 7620 testST2(-734_444, SysTime(DateTime(-2010, 2, 28, 12, 2, 9), msecs(212))); 7621 testST2(-734_443, SysTime(DateTime(-2010, 3, 1, 12, 2, 9), msecs(212))); 7622 testST2(-734_413, SysTime(DateTime(-2010, 3, 31, 12, 2, 9), msecs(212))); 7623 testST2(-734_412, SysTime(DateTime(-2010, 4, 1, 12, 2, 9), msecs(212))); 7624 testST2(-734_383, SysTime(DateTime(-2010, 4, 30, 12, 2, 9), msecs(212))); 7625 testST2(-734_382, SysTime(DateTime(-2010, 5, 1, 12, 2, 9), msecs(212))); 7626 testST2(-734_352, SysTime(DateTime(-2010, 5, 31, 12, 2, 9), msecs(212))); 7627 testST2(-734_351, SysTime(DateTime(-2010, 6, 1, 12, 2, 9), msecs(212))); 7628 testST2(-734_322, SysTime(DateTime(-2010, 6, 30, 12, 2, 9), msecs(212))); 7629 testST2(-734_321, SysTime(DateTime(-2010, 7, 1, 12, 2, 9), msecs(212))); 7630 testST2(-734_291, SysTime(DateTime(-2010, 7, 31, 12, 2, 9), msecs(212))); 7631 testST2(-734_290, SysTime(DateTime(-2010, 8, 1, 12, 2, 9), msecs(212))); 7632 testST2(-734_260, SysTime(DateTime(-2010, 8, 31, 12, 2, 9), msecs(212))); 7633 testST2(-734_259, SysTime(DateTime(-2010, 9, 1, 12, 2, 9), msecs(212))); 7634 testST2(-734_230, SysTime(DateTime(-2010, 9, 30, 12, 2, 9), msecs(212))); 7635 testST2(-734_229, SysTime(DateTime(-2010, 10, 1, 12, 2, 9), msecs(212))); 7636 testST2(-734_199, SysTime(DateTime(-2010, 10, 31, 12, 2, 9), msecs(212))); 7637 testST2(-734_198, SysTime(DateTime(-2010, 11, 1, 12, 2, 9), msecs(212))); 7638 testST2(-734_169, SysTime(DateTime(-2010, 11, 30, 12, 2, 9), msecs(212))); 7639 testST2(-734_168, SysTime(DateTime(-2010, 12, 1, 12, 2, 9), msecs(212))); 7640 testST2(-734_138, SysTime(DateTime(-2010, 12, 31, 12, 2, 9), msecs(212))); 7641 7642 testST2(-735_202, SysTime(DateTime(-2012, 2, 1, 12, 2, 9), msecs(212))); 7643 testST2(-735_175, SysTime(DateTime(-2012, 2, 28, 12, 2, 9), msecs(212))); 7644 testST2(-735_174, SysTime(DateTime(-2012, 2, 29, 12, 2, 9), msecs(212))); 7645 testST2(-735_173, SysTime(DateTime(-2012, 3, 1, 12, 2, 9), msecs(212))); 7646 7647 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7648 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7649 static assert(!__traits(compiles, cst.dayOfGregorianCal = 7)); 7650 static assert(!__traits(compiles, ist.dayOfGregorianCal = 7)); 7651 7652 static void testScope(scope ref SysTime st) @safe 7653 { 7654 st.dayOfGregorianCal = 42; 7655 } 7656 } 7657 7658 7659 /++ 7660 The ISO 8601 week of the year that this $(LREF SysTime) is in. 7661 7662 See_Also: 7663 $(HTTP en.wikipedia.org/wiki/ISO_week_date, ISO Week Date). 7664 +/ 7665 @property ubyte isoWeek() @safe const nothrow scope 7666 { 7667 return (cast(Date) this).isoWeek; 7668 } 7669 7670 /// 7671 @safe unittest 7672 { 7673 import core.time; 7674 import std.datetime.date : Date; 7675 7676 auto st = SysTime(Date(1999, 7, 6)); 7677 const cst = SysTime(Date(2010, 5, 1)); 7678 immutable ist = SysTime(Date(2015, 10, 10)); 7679 7680 assert(st.isoWeek == 27); 7681 assert(cst.isoWeek == 17); 7682 assert(ist.isoWeek == 41); 7683 } 7684 7685 @safe unittest 7686 { 7687 static void testScope(scope ref SysTime st) @safe 7688 { 7689 auto result = st.isoWeek; 7690 } 7691 } 7692 7693 7694 /++ 7695 $(LREF SysTime) for the last day in the month that this Date is in. 7696 The time portion of endOfMonth is always 23:59:59.9999999. 7697 +/ 7698 @property SysTime endOfMonth() @safe const nothrow return scope 7699 { 7700 immutable hnsecs = adjTime; 7701 immutable days = getUnitsFromHNSecs!"days"(hnsecs); 7702 7703 auto date = Date(cast(int) days + 1).endOfMonth; 7704 auto newDays = date.dayOfGregorianCal - 1; 7705 long theTimeHNSecs; 7706 7707 if (newDays < 0) 7708 { 7709 theTimeHNSecs = -1; 7710 ++newDays; 7711 } 7712 else 7713 theTimeHNSecs = convert!("days", "hnsecs")(1) - 1; 7714 7715 immutable newDaysHNSecs = convert!("days", "hnsecs")(newDays); 7716 7717 auto retval = SysTime(this._stdTime, this._timezone); 7718 retval.adjTime = newDaysHNSecs + theTimeHNSecs; 7719 7720 return retval; 7721 } 7722 7723 /// 7724 @safe unittest 7725 { 7726 import core.time : msecs, usecs, hnsecs; 7727 import std.datetime.date : DateTime; 7728 7729 assert(SysTime(DateTime(1999, 1, 6, 0, 0, 0)).endOfMonth == 7730 SysTime(DateTime(1999, 1, 31, 23, 59, 59), hnsecs(9_999_999))); 7731 7732 assert(SysTime(DateTime(1999, 2, 7, 19, 30, 0), msecs(24)).endOfMonth == 7733 SysTime(DateTime(1999, 2, 28, 23, 59, 59), hnsecs(9_999_999))); 7734 7735 assert(SysTime(DateTime(2000, 2, 7, 5, 12, 27), usecs(5203)).endOfMonth == 7736 SysTime(DateTime(2000, 2, 29, 23, 59, 59), hnsecs(9_999_999))); 7737 7738 assert(SysTime(DateTime(2000, 6, 4, 12, 22, 9), hnsecs(12345)).endOfMonth == 7739 SysTime(DateTime(2000, 6, 30, 23, 59, 59), hnsecs(9_999_999))); 7740 } 7741 7742 @safe unittest 7743 { 7744 import core.time; 7745 // Test A.D. 7746 assert(SysTime(Date(1999, 1, 1)).endOfMonth == SysTime(DateTime(1999, 1, 31, 23, 59, 59), hnsecs(9_999_999))); 7747 assert(SysTime(Date(1999, 2, 1)).endOfMonth == SysTime(DateTime(1999, 2, 28, 23, 59, 59), hnsecs(9_999_999))); 7748 assert(SysTime(Date(2000, 2, 1)).endOfMonth == SysTime(DateTime(2000, 2, 29, 23, 59, 59), hnsecs(9_999_999))); 7749 assert(SysTime(Date(1999, 3, 1)).endOfMonth == SysTime(DateTime(1999, 3, 31, 23, 59, 59), hnsecs(9_999_999))); 7750 assert(SysTime(Date(1999, 4, 1)).endOfMonth == SysTime(DateTime(1999, 4, 30, 23, 59, 59), hnsecs(9_999_999))); 7751 assert(SysTime(Date(1999, 5, 1)).endOfMonth == SysTime(DateTime(1999, 5, 31, 23, 59, 59), hnsecs(9_999_999))); 7752 assert(SysTime(Date(1999, 6, 1)).endOfMonth == SysTime(DateTime(1999, 6, 30, 23, 59, 59), hnsecs(9_999_999))); 7753 assert(SysTime(Date(1999, 7, 1)).endOfMonth == SysTime(DateTime(1999, 7, 31, 23, 59, 59), hnsecs(9_999_999))); 7754 assert(SysTime(Date(1999, 8, 1)).endOfMonth == SysTime(DateTime(1999, 8, 31, 23, 59, 59), hnsecs(9_999_999))); 7755 assert(SysTime(Date(1999, 9, 1)).endOfMonth == SysTime(DateTime(1999, 9, 30, 23, 59, 59), hnsecs(9_999_999))); 7756 assert(SysTime(Date(1999, 10, 1)).endOfMonth == SysTime(DateTime(1999, 10, 31, 23, 59, 59), hnsecs(9_999_999))); 7757 assert(SysTime(Date(1999, 11, 1)).endOfMonth == SysTime(DateTime(1999, 11, 30, 23, 59, 59), hnsecs(9_999_999))); 7758 assert(SysTime(Date(1999, 12, 1)).endOfMonth == SysTime(DateTime(1999, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 7759 7760 // Test B.C. 7761 assert(SysTime(Date(-1999, 1, 1)).endOfMonth == SysTime(DateTime(-1999, 1, 31, 23, 59, 59), hnsecs(9_999_999))); 7762 assert(SysTime(Date(-1999, 2, 1)).endOfMonth == SysTime(DateTime(-1999, 2, 28, 23, 59, 59), hnsecs(9_999_999))); 7763 assert(SysTime(Date(-2000, 2, 1)).endOfMonth == SysTime(DateTime(-2000, 2, 29, 23, 59, 59), hnsecs(9_999_999))); 7764 assert(SysTime(Date(-1999, 3, 1)).endOfMonth == SysTime(DateTime(-1999, 3, 31, 23, 59, 59), hnsecs(9_999_999))); 7765 assert(SysTime(Date(-1999, 4, 1)).endOfMonth == SysTime(DateTime(-1999, 4, 30, 23, 59, 59), hnsecs(9_999_999))); 7766 assert(SysTime(Date(-1999, 5, 1)).endOfMonth == SysTime(DateTime(-1999, 5, 31, 23, 59, 59), hnsecs(9_999_999))); 7767 assert(SysTime(Date(-1999, 6, 1)).endOfMonth == SysTime(DateTime(-1999, 6, 30, 23, 59, 59), hnsecs(9_999_999))); 7768 assert(SysTime(Date(-1999, 7, 1)).endOfMonth == SysTime(DateTime(-1999, 7, 31, 23, 59, 59), hnsecs(9_999_999))); 7769 assert(SysTime(Date(-1999, 8, 1)).endOfMonth == SysTime(DateTime(-1999, 8, 31, 23, 59, 59), hnsecs(9_999_999))); 7770 assert(SysTime(Date(-1999, 9, 1)).endOfMonth == SysTime(DateTime(-1999, 9, 30, 23, 59, 59), hnsecs(9_999_999))); 7771 assert(SysTime(Date(-1999, 10, 1)).endOfMonth == 7772 SysTime(DateTime(-1999, 10, 31, 23, 59, 59), hnsecs(9_999_999))); 7773 assert(SysTime(Date(-1999, 11, 1)).endOfMonth == 7774 SysTime(DateTime(-1999, 11, 30, 23, 59, 59), hnsecs(9_999_999))); 7775 assert(SysTime(Date(-1999, 12, 1)).endOfMonth == 7776 SysTime(DateTime(-1999, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 7777 7778 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7779 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7780 assert(cst.endOfMonth == SysTime(DateTime(1999, 7, 31, 23, 59, 59), hnsecs(9_999_999))); 7781 assert(ist.endOfMonth == SysTime(DateTime(1999, 7, 31, 23, 59, 59), hnsecs(9_999_999))); 7782 7783 static void testScope(scope ref SysTime st) @safe 7784 { 7785 auto result = st.endOfMonth; 7786 } 7787 } 7788 7789 7790 /++ 7791 The last day in the month that this $(LREF SysTime) is in. 7792 +/ 7793 @property ubyte daysInMonth() @safe const nothrow scope 7794 { 7795 return Date(dayOfGregorianCal).daysInMonth; 7796 } 7797 7798 /// 7799 @safe unittest 7800 { 7801 import core.time; 7802 import std.datetime.date : DateTime; 7803 7804 assert(SysTime(DateTime(1999, 1, 6, 0, 0, 0)).daysInMonth == 31); 7805 assert(SysTime(DateTime(1999, 2, 7, 19, 30, 0)).daysInMonth == 28); 7806 assert(SysTime(DateTime(2000, 2, 7, 5, 12, 27)).daysInMonth == 29); 7807 assert(SysTime(DateTime(2000, 6, 4, 12, 22, 9)).daysInMonth == 30); 7808 } 7809 7810 @safe unittest 7811 { 7812 import core.time; 7813 // Test A.D. 7814 assert(SysTime(DateTime(1999, 1, 1, 12, 1, 13)).daysInMonth == 31); 7815 assert(SysTime(DateTime(1999, 2, 1, 17, 13, 12)).daysInMonth == 28); 7816 assert(SysTime(DateTime(2000, 2, 1, 13, 2, 12)).daysInMonth == 29); 7817 assert(SysTime(DateTime(1999, 3, 1, 12, 13, 12)).daysInMonth == 31); 7818 assert(SysTime(DateTime(1999, 4, 1, 12, 6, 13)).daysInMonth == 30); 7819 assert(SysTime(DateTime(1999, 5, 1, 15, 13, 12)).daysInMonth == 31); 7820 assert(SysTime(DateTime(1999, 6, 1, 13, 7, 12)).daysInMonth == 30); 7821 assert(SysTime(DateTime(1999, 7, 1, 12, 13, 17)).daysInMonth == 31); 7822 assert(SysTime(DateTime(1999, 8, 1, 12, 3, 13)).daysInMonth == 31); 7823 assert(SysTime(DateTime(1999, 9, 1, 12, 13, 12)).daysInMonth == 30); 7824 assert(SysTime(DateTime(1999, 10, 1, 13, 19, 12)).daysInMonth == 31); 7825 assert(SysTime(DateTime(1999, 11, 1, 12, 13, 17)).daysInMonth == 30); 7826 assert(SysTime(DateTime(1999, 12, 1, 12, 52, 13)).daysInMonth == 31); 7827 7828 // Test B.C. 7829 assert(SysTime(DateTime(-1999, 1, 1, 12, 1, 13)).daysInMonth == 31); 7830 assert(SysTime(DateTime(-1999, 2, 1, 7, 13, 12)).daysInMonth == 28); 7831 assert(SysTime(DateTime(-2000, 2, 1, 13, 2, 12)).daysInMonth == 29); 7832 assert(SysTime(DateTime(-1999, 3, 1, 12, 13, 12)).daysInMonth == 31); 7833 assert(SysTime(DateTime(-1999, 4, 1, 12, 6, 13)).daysInMonth == 30); 7834 assert(SysTime(DateTime(-1999, 5, 1, 5, 13, 12)).daysInMonth == 31); 7835 assert(SysTime(DateTime(-1999, 6, 1, 13, 7, 12)).daysInMonth == 30); 7836 assert(SysTime(DateTime(-1999, 7, 1, 12, 13, 17)).daysInMonth == 31); 7837 assert(SysTime(DateTime(-1999, 8, 1, 12, 3, 13)).daysInMonth == 31); 7838 assert(SysTime(DateTime(-1999, 9, 1, 12, 13, 12)).daysInMonth == 30); 7839 assert(SysTime(DateTime(-1999, 10, 1, 13, 19, 12)).daysInMonth == 31); 7840 assert(SysTime(DateTime(-1999, 11, 1, 12, 13, 17)).daysInMonth == 30); 7841 assert(SysTime(DateTime(-1999, 12, 1, 12, 52, 13)).daysInMonth == 31); 7842 7843 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7844 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7845 assert(cst.daysInMonth == 31); 7846 assert(ist.daysInMonth == 31); 7847 7848 static void testScope(scope ref SysTime st) @safe 7849 { 7850 auto result = st.daysInMonth; 7851 } 7852 } 7853 7854 7855 /++ 7856 Whether the current year is a date in A.D. 7857 +/ 7858 @property bool isAD() @safe const nothrow scope 7859 { 7860 return adjTime >= 0; 7861 } 7862 7863 /// 7864 @safe unittest 7865 { 7866 import core.time; 7867 import std.datetime.date : DateTime; 7868 7869 assert(SysTime(DateTime(1, 1, 1, 12, 7, 0)).isAD); 7870 assert(SysTime(DateTime(2010, 12, 31, 0, 0, 0)).isAD); 7871 assert(!SysTime(DateTime(0, 12, 31, 23, 59, 59)).isAD); 7872 assert(!SysTime(DateTime(-2010, 1, 1, 2, 2, 2)).isAD); 7873 } 7874 7875 @safe unittest 7876 { 7877 import core.time; 7878 assert(SysTime(DateTime(2010, 7, 4, 12, 0, 9)).isAD); 7879 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).isAD); 7880 assert(!SysTime(DateTime(0, 12, 31, 23, 59, 59)).isAD); 7881 assert(!SysTime(DateTime(0, 1, 1, 23, 59, 59)).isAD); 7882 assert(!SysTime(DateTime(-1, 1, 1, 23 ,59 ,59)).isAD); 7883 assert(!SysTime(DateTime(-2010, 7, 4, 12, 2, 2)).isAD); 7884 7885 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7886 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7887 assert(cst.isAD); 7888 assert(ist.isAD); 7889 7890 static void testScope(scope ref SysTime st) @safe 7891 { 7892 auto result = st.isAD; 7893 } 7894 } 7895 7896 7897 /++ 7898 The $(HTTP en.wikipedia.org/wiki/Julian_day, Julian day) 7899 for this $(LREF SysTime) at the given time. For example, 7900 prior to noon, 1996-03-31 would be the Julian day number 2_450_173, so 7901 this function returns 2_450_173, while from noon onward, the Julian 7902 day number would be 2_450_174, so this function returns 2_450_174. 7903 +/ 7904 @property long julianDay() @safe const nothrow scope 7905 { 7906 immutable jd = dayOfGregorianCal + 1_721_425; 7907 return hour < 12 ? jd - 1 : jd; 7908 } 7909 7910 @safe unittest 7911 { 7912 import core.time; 7913 assert(SysTime(DateTime(-4713, 11, 24, 0, 0, 0)).julianDay == -1); 7914 assert(SysTime(DateTime(-4713, 11, 24, 12, 0, 0)).julianDay == 0); 7915 7916 assert(SysTime(DateTime(0, 12, 31, 0, 0, 0)).julianDay == 1_721_424); 7917 assert(SysTime(DateTime(0, 12, 31, 12, 0, 0)).julianDay == 1_721_425); 7918 7919 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).julianDay == 1_721_425); 7920 assert(SysTime(DateTime(1, 1, 1, 12, 0, 0)).julianDay == 1_721_426); 7921 7922 assert(SysTime(DateTime(1582, 10, 15, 0, 0, 0)).julianDay == 2_299_160); 7923 assert(SysTime(DateTime(1582, 10, 15, 12, 0, 0)).julianDay == 2_299_161); 7924 7925 assert(SysTime(DateTime(1858, 11, 17, 0, 0, 0)).julianDay == 2_400_000); 7926 assert(SysTime(DateTime(1858, 11, 17, 12, 0, 0)).julianDay == 2_400_001); 7927 7928 assert(SysTime(DateTime(1982, 1, 4, 0, 0, 0)).julianDay == 2_444_973); 7929 assert(SysTime(DateTime(1982, 1, 4, 12, 0, 0)).julianDay == 2_444_974); 7930 7931 assert(SysTime(DateTime(1996, 3, 31, 0, 0, 0)).julianDay == 2_450_173); 7932 assert(SysTime(DateTime(1996, 3, 31, 12, 0, 0)).julianDay == 2_450_174); 7933 7934 assert(SysTime(DateTime(2010, 8, 24, 0, 0, 0)).julianDay == 2_455_432); 7935 assert(SysTime(DateTime(2010, 8, 24, 12, 0, 0)).julianDay == 2_455_433); 7936 7937 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7938 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7939 assert(cst.julianDay == 2_451_366); 7940 assert(ist.julianDay == 2_451_366); 7941 7942 static void testScope(scope ref SysTime st) @safe 7943 { 7944 auto result = st.julianDay; 7945 } 7946 } 7947 7948 7949 /++ 7950 The modified $(HTTP en.wikipedia.org/wiki/Julian_day, Julian day) for 7951 any time on this date (since, the modified Julian day changes at 7952 midnight). 7953 +/ 7954 @property long modJulianDay() @safe const nothrow scope 7955 { 7956 return dayOfGregorianCal + 1_721_425 - 2_400_001; 7957 } 7958 7959 @safe unittest 7960 { 7961 import core.time; 7962 assert(SysTime(DateTime(1858, 11, 17, 0, 0, 0)).modJulianDay == 0); 7963 assert(SysTime(DateTime(1858, 11, 17, 12, 0, 0)).modJulianDay == 0); 7964 7965 assert(SysTime(DateTime(2010, 8, 24, 0, 0, 0)).modJulianDay == 55_432); 7966 assert(SysTime(DateTime(2010, 8, 24, 12, 0, 0)).modJulianDay == 55_432); 7967 7968 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7969 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7970 assert(cst.modJulianDay == 51_365); 7971 assert(ist.modJulianDay == 51_365); 7972 7973 static void testScope(scope ref SysTime st) @safe 7974 { 7975 auto result = st.modJulianDay; 7976 } 7977 } 7978 7979 7980 /++ 7981 Returns a $(REF Date,std,datetime,date) equivalent to this $(LREF SysTime). 7982 +/ 7983 Date opCast(T)() @safe const nothrow scope 7984 if (is(immutable T == immutable Date)) 7985 { 7986 return Date(dayOfGregorianCal); 7987 } 7988 7989 @safe unittest 7990 { 7991 import core.time; 7992 assert(cast(Date) SysTime(Date(1999, 7, 6)) == Date(1999, 7, 6)); 7993 assert(cast(Date) SysTime(Date(2000, 12, 31)) == Date(2000, 12, 31)); 7994 assert(cast(Date) SysTime(Date(2001, 1, 1)) == Date(2001, 1, 1)); 7995 7996 assert(cast(Date) SysTime(DateTime(1999, 7, 6, 12, 10, 9)) == Date(1999, 7, 6)); 7997 assert(cast(Date) SysTime(DateTime(2000, 12, 31, 13, 11, 10)) == Date(2000, 12, 31)); 7998 assert(cast(Date) SysTime(DateTime(2001, 1, 1, 14, 12, 11)) == Date(2001, 1, 1)); 7999 8000 assert(cast(Date) SysTime(Date(-1999, 7, 6)) == Date(-1999, 7, 6)); 8001 assert(cast(Date) SysTime(Date(-2000, 12, 31)) == Date(-2000, 12, 31)); 8002 assert(cast(Date) SysTime(Date(-2001, 1, 1)) == Date(-2001, 1, 1)); 8003 8004 assert(cast(Date) SysTime(DateTime(-1999, 7, 6, 12, 10, 9)) == Date(-1999, 7, 6)); 8005 assert(cast(Date) SysTime(DateTime(-2000, 12, 31, 13, 11, 10)) == Date(-2000, 12, 31)); 8006 assert(cast(Date) SysTime(DateTime(-2001, 1, 1, 14, 12, 11)) == Date(-2001, 1, 1)); 8007 8008 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8009 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8010 assert(cast(Date) cst != Date.init); 8011 assert(cast(Date) ist != Date.init); 8012 8013 static void testScope(scope ref SysTime st) @safe 8014 { 8015 auto result = cast(Date) st; 8016 } 8017 } 8018 8019 8020 /++ 8021 Returns a $(REF DateTime,std,datetime,date) equivalent to this 8022 $(LREF SysTime). 8023 +/ 8024 DateTime opCast(T)() @safe const nothrow scope 8025 if (is(immutable T == immutable DateTime)) 8026 { 8027 try 8028 { 8029 auto hnsecs = adjTime; 8030 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 8031 8032 if (hnsecs < 0) 8033 { 8034 hnsecs += convert!("hours", "hnsecs")(24); 8035 --days; 8036 } 8037 8038 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 8039 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 8040 immutable second = getUnitsFromHNSecs!"seconds"(hnsecs); 8041 8042 return DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour, cast(int) minute, cast(int) second)); 8043 } 8044 catch (Exception e) 8045 assert(0, "Either DateTime's constructor or TimeOfDay's constructor threw."); 8046 } 8047 8048 @safe unittest 8049 { 8050 import core.time; 8051 assert(cast(DateTime) SysTime(DateTime(1, 1, 6, 7, 12, 22)) == DateTime(1, 1, 6, 7, 12, 22)); 8052 assert(cast(DateTime) SysTime(DateTime(1, 1, 6, 7, 12, 22), msecs(22)) == DateTime(1, 1, 6, 7, 12, 22)); 8053 assert(cast(DateTime) SysTime(Date(1999, 7, 6)) == DateTime(1999, 7, 6, 0, 0, 0)); 8054 assert(cast(DateTime) SysTime(Date(2000, 12, 31)) == DateTime(2000, 12, 31, 0, 0, 0)); 8055 assert(cast(DateTime) SysTime(Date(2001, 1, 1)) == DateTime(2001, 1, 1, 0, 0, 0)); 8056 8057 assert(cast(DateTime) SysTime(DateTime(1999, 7, 6, 12, 10, 9)) == DateTime(1999, 7, 6, 12, 10, 9)); 8058 assert(cast(DateTime) SysTime(DateTime(2000, 12, 31, 13, 11, 10)) == DateTime(2000, 12, 31, 13, 11, 10)); 8059 assert(cast(DateTime) SysTime(DateTime(2001, 1, 1, 14, 12, 11)) == DateTime(2001, 1, 1, 14, 12, 11)); 8060 8061 assert(cast(DateTime) SysTime(DateTime(-1, 1, 6, 7, 12, 22)) == DateTime(-1, 1, 6, 7, 12, 22)); 8062 assert(cast(DateTime) SysTime(DateTime(-1, 1, 6, 7, 12, 22), msecs(22)) == DateTime(-1, 1, 6, 7, 12, 22)); 8063 assert(cast(DateTime) SysTime(Date(-1999, 7, 6)) == DateTime(-1999, 7, 6, 0, 0, 0)); 8064 assert(cast(DateTime) SysTime(Date(-2000, 12, 31)) == DateTime(-2000, 12, 31, 0, 0, 0)); 8065 assert(cast(DateTime) SysTime(Date(-2001, 1, 1)) == DateTime(-2001, 1, 1, 0, 0, 0)); 8066 8067 assert(cast(DateTime) SysTime(DateTime(-1999, 7, 6, 12, 10, 9)) == DateTime(-1999, 7, 6, 12, 10, 9)); 8068 assert(cast(DateTime) SysTime(DateTime(-2000, 12, 31, 13, 11, 10)) == DateTime(-2000, 12, 31, 13, 11, 10)); 8069 assert(cast(DateTime) SysTime(DateTime(-2001, 1, 1, 14, 12, 11)) == DateTime(-2001, 1, 1, 14, 12, 11)); 8070 8071 assert(cast(DateTime) SysTime(DateTime(2011, 1, 13, 8, 17, 2), msecs(296), LocalTime()) == 8072 DateTime(2011, 1, 13, 8, 17, 2)); 8073 8074 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8075 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8076 assert(cast(DateTime) cst != DateTime.init); 8077 assert(cast(DateTime) ist != DateTime.init); 8078 8079 static void testScope(scope ref SysTime st) @safe 8080 { 8081 auto result = cast(DateTime) st; 8082 } 8083 } 8084 8085 8086 /++ 8087 Returns a $(REF TimeOfDay,std,datetime,date) equivalent to this 8088 $(LREF SysTime). 8089 +/ 8090 TimeOfDay opCast(T)() @safe const nothrow scope 8091 if (is(immutable T == immutable TimeOfDay)) 8092 { 8093 try 8094 { 8095 auto hnsecs = adjTime; 8096 hnsecs = removeUnitsFromHNSecs!"days"(hnsecs); 8097 8098 if (hnsecs < 0) 8099 hnsecs += convert!("hours", "hnsecs")(24); 8100 8101 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 8102 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 8103 immutable second = getUnitsFromHNSecs!"seconds"(hnsecs); 8104 8105 return TimeOfDay(cast(int) hour, cast(int) minute, cast(int) second); 8106 } 8107 catch (Exception e) 8108 assert(0, "TimeOfDay's constructor threw."); 8109 } 8110 8111 @safe unittest 8112 { 8113 import core.time; 8114 assert(cast(TimeOfDay) SysTime(Date(1999, 7, 6)) == TimeOfDay(0, 0, 0)); 8115 assert(cast(TimeOfDay) SysTime(Date(2000, 12, 31)) == TimeOfDay(0, 0, 0)); 8116 assert(cast(TimeOfDay) SysTime(Date(2001, 1, 1)) == TimeOfDay(0, 0, 0)); 8117 8118 assert(cast(TimeOfDay) SysTime(DateTime(1999, 7, 6, 12, 10, 9)) == TimeOfDay(12, 10, 9)); 8119 assert(cast(TimeOfDay) SysTime(DateTime(2000, 12, 31, 13, 11, 10)) == TimeOfDay(13, 11, 10)); 8120 assert(cast(TimeOfDay) SysTime(DateTime(2001, 1, 1, 14, 12, 11)) == TimeOfDay(14, 12, 11)); 8121 8122 assert(cast(TimeOfDay) SysTime(Date(-1999, 7, 6)) == TimeOfDay(0, 0, 0)); 8123 assert(cast(TimeOfDay) SysTime(Date(-2000, 12, 31)) == TimeOfDay(0, 0, 0)); 8124 assert(cast(TimeOfDay) SysTime(Date(-2001, 1, 1)) == TimeOfDay(0, 0, 0)); 8125 8126 assert(cast(TimeOfDay) SysTime(DateTime(-1999, 7, 6, 12, 10, 9)) == TimeOfDay(12, 10, 9)); 8127 assert(cast(TimeOfDay) SysTime(DateTime(-2000, 12, 31, 13, 11, 10)) == TimeOfDay(13, 11, 10)); 8128 assert(cast(TimeOfDay) SysTime(DateTime(-2001, 1, 1, 14, 12, 11)) == TimeOfDay(14, 12, 11)); 8129 8130 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8131 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8132 assert(cast(TimeOfDay) cst != TimeOfDay.init); 8133 assert(cast(TimeOfDay) ist != TimeOfDay.init); 8134 8135 static void testScope(scope ref SysTime st) @safe 8136 { 8137 auto result = cast(TimeOfDay) st; 8138 } 8139 } 8140 8141 8142 // Temporary hack until bug https://issues.dlang.org/show_bug.cgi?id=4867 is fixed. 8143 // This allows assignment from const(SysTime) to SysTime. 8144 // It may be a good idea to keep it though, since casting from a type to itself 8145 // should be allowed, and it doesn't work without this opCast() since opCast() 8146 // has already been defined for other types. 8147 SysTime opCast(T)() @safe const pure nothrow scope 8148 if (is(immutable T == immutable SysTime)) 8149 { 8150 return SysTime(_stdTime, _timezone); 8151 } 8152 8153 @safe unittest 8154 { 8155 static void testScope(scope ref SysTime st) @safe 8156 { 8157 auto result = cast(SysTime) st; 8158 } 8159 } 8160 8161 8162 /++ 8163 Converts this $(LREF SysTime) to a string with the format 8164 YYYYMMDDTHHMMSS.FFFFFFFTZ (where F is fractional seconds and TZ is time 8165 zone). 8166 8167 Note that the number of digits in the fractional seconds varies with the 8168 number of fractional seconds. It's a maximum of 7 (which would be 8169 hnsecs), but only has as many as are necessary to hold the correct value 8170 (so no trailing zeroes), and if there are no fractional seconds, then 8171 there is no decimal point. 8172 8173 If this $(LREF SysTime)'s time zone is 8174 $(REF LocalTime,std,datetime,timezone), then TZ is empty. If its time 8175 zone is `UTC`, then it is "Z". Otherwise, it is the offset from UTC 8176 (e.g. +0100 or -0700). Note that the offset from UTC is $(I not) enough 8177 to uniquely identify the time zone. 8178 8179 Time zone offsets will be in the form +HHMM or -HHMM. 8180 8181 $(RED Warning: 8182 Previously, toISOString did the same as $(LREF toISOExtString) and 8183 generated +HH:MM or -HH:MM for the time zone when it was not 8184 $(REF LocalTime,std,datetime,timezone) or 8185 $(REF UTC,std,datetime,timezone), which is not in conformance with 8186 ISO 8601 for the non-extended string format. This has now been 8187 fixed. However, for now, fromISOString will continue to accept the 8188 extended format for the time zone so that any code which has been 8189 writing out the result of toISOString to read in later will continue 8190 to work. The current behavior will be kept until July 2019 at which 8191 point, fromISOString will be fixed to be standards compliant.) 8192 8193 Params: 8194 writer = A `char` accepting 8195 $(REF_ALTTEXT output range, isOutputRange, std, range, primitives) 8196 Returns: 8197 A `string` when not using an output range; `void` otherwise. 8198 +/ 8199 string toISOString() @safe const nothrow scope 8200 { 8201 import std.array : appender; 8202 auto app = appender!string(); 8203 app.reserve(30); 8204 try 8205 toISOString(app); 8206 catch (Exception e) 8207 assert(0, "toISOString() threw."); 8208 return app.data; 8209 } 8210 8211 /// ditto 8212 void toISOString(W)(ref W writer) const scope 8213 if (isOutputRange!(W, char)) 8214 { 8215 immutable adjustedTime = adjTime; 8216 long hnsecs = adjustedTime; 8217 8218 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 8219 8220 if (hnsecs < 0) 8221 { 8222 hnsecs += convert!("hours", "hnsecs")(24); 8223 --days; 8224 } 8225 8226 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 8227 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 8228 immutable second = splitUnitsFromHNSecs!"seconds"(hnsecs); 8229 8230 auto dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour, 8231 cast(int) minute, cast(int) second)); 8232 8233 if (_timezone is LocalTime()) 8234 { 8235 dateTime.toISOString(writer); 8236 fracSecsToISOString(writer, cast(int) hnsecs); 8237 return; 8238 } 8239 8240 if (_timezone is UTC()) 8241 { 8242 dateTime.toISOString(writer); 8243 fracSecsToISOString(writer, cast(int) hnsecs); 8244 put(writer, 'Z'); 8245 return; 8246 } 8247 8248 immutable utcOffset = dur!"hnsecs"(adjustedTime - stdTime); 8249 8250 dateTime.toISOString(writer); 8251 fracSecsToISOString(writer, cast(int) hnsecs); 8252 SimpleTimeZone.toISOExtString(writer, utcOffset); 8253 } 8254 8255 /// 8256 @safe unittest 8257 { 8258 import core.time : msecs, hnsecs; 8259 import std.datetime.date : DateTime; 8260 8261 assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toISOString() == 8262 "20100704T070612"); 8263 8264 assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(24)).toISOString() == 8265 "19981225T021500.024"); 8266 8267 assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toISOString() == 8268 "00000105T230959"); 8269 8270 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toISOString() == 8271 "-00040105T000002.052092"); 8272 } 8273 8274 @safe unittest 8275 { 8276 import core.time; 8277 // Test A.D. 8278 assert(SysTime(DateTime.init, UTC()).toISOString() == "00010101T000000Z"); 8279 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC()).toISOString() == "00010101T000000.0000001Z"); 8280 8281 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0)).toISOString() == "00091204T000000"); 8282 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12)).toISOString() == "00991204T050612"); 8283 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59)).toISOString() == "09991204T134459"); 8284 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59)).toISOString() == "99990704T235959"); 8285 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1)).toISOString() == "+100001020T010101"); 8286 8287 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0), msecs(42)).toISOString() == "00091204T000000.042"); 8288 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12), msecs(100)).toISOString() == "00991204T050612.1"); 8289 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59), usecs(45020)).toISOString() == "09991204T134459.04502"); 8290 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOString() == "99990704T235959.0000012"); 8291 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOString() == "+100001020T010101.050789"); 8292 8293 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 8294 new immutable SimpleTimeZone(dur!"minutes"(-360))).toISOString() == 8295 "20121221T121212-06:00"); 8296 8297 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 8298 new immutable SimpleTimeZone(dur!"minutes"(420))).toISOString() == 8299 "20121221T121212+07:00"); 8300 8301 // Test B.C. 8302 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toISOString() == 8303 "00001231T235959.9999999Z"); 8304 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC()).toISOString() == "00001231T235959.0000001Z"); 8305 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), UTC()).toISOString() == "00001231T235959Z"); 8306 8307 assert(SysTime(DateTime(0, 12, 4, 0, 12, 4)).toISOString() == "00001204T001204"); 8308 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0)).toISOString() == "-00091204T000000"); 8309 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12)).toISOString() == "-00991204T050612"); 8310 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59)).toISOString() == "-09991204T134459"); 8311 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59)).toISOString() == "-99990704T235959"); 8312 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1)).toISOString() == "-100001020T010101"); 8313 8314 assert(SysTime(DateTime(0, 12, 4, 0, 0, 0), msecs(7)).toISOString() == "00001204T000000.007"); 8315 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0), msecs(42)).toISOString() == "-00091204T000000.042"); 8316 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12), msecs(100)).toISOString() == "-00991204T050612.1"); 8317 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59), usecs(45020)).toISOString() == "-09991204T134459.04502"); 8318 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOString() == "-99990704T235959.0000012"); 8319 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOString() == "-100001020T010101.050789"); 8320 8321 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8322 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8323 assert(cst.toISOString() == "19990706T123033"); 8324 assert(ist.toISOString() == "19990706T123033"); 8325 8326 static void testScope(scope ref SysTime st) @safe 8327 { 8328 auto result = st.toISOString(); 8329 } 8330 } 8331 8332 8333 8334 /++ 8335 Converts this $(LREF SysTime) to a string with the format 8336 YYYY-MM-DDTHH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ 8337 is the time zone). 8338 8339 Default behaviour: 8340 Note that the number of digits in the fractional seconds varies with the 8341 number of fractional seconds. It's a maximum of 7 (which would be 8342 hnsecs), but only has as many as are necessary to hold the correct value 8343 (so no trailing zeroes), and if there are no fractional seconds, then 8344 there is no decimal point. 8345 8346 The optional parameter "prec" allows to change the default behavior by 8347 specifying the precision of the fractional seconds. The accepted values 8348 are in the range [-1, 7], where -1 represents the default behavior. 8349 8350 If this $(LREF SysTime)'s time zone is 8351 $(REF LocalTime,std,datetime,timezone), then TZ is empty. If its time 8352 zone is `UTC`, then it is "Z". Otherwise, it is the offset from UTC 8353 (e.g. +01:00 or -07:00). Note that the offset from UTC is $(I not) 8354 enough to uniquely identify the time zone. 8355 8356 Time zone offsets will be in the form +HH:MM or -HH:MM. 8357 8358 Params: 8359 writer = A `char` accepting 8360 $(REF_ALTTEXT output range, isOutputRange, std, range, primitives) 8361 prec = An `int` representing the desired precision. Acceptable values range from -1 to 7, where -1 represents the default behavior. 8362 Returns: 8363 A `string` when not using an output range; `void` otherwise. 8364 +/ 8365 string toISOExtString(int prec = -1) @safe const nothrow scope 8366 { 8367 assert(prec >= -1 && prec <= 7, "Precision must be in the range [-1, 7]"); 8368 8369 import std.array : appender; 8370 auto app = appender!string(); 8371 app.reserve(35); 8372 try 8373 toISOExtString(app, prec); 8374 catch (Exception e) 8375 assert(0, "toISOExtString() threw."); 8376 return app.data; 8377 } 8378 8379 /// ditto 8380 void toISOExtString(W)(ref W writer, int prec = -1) const scope 8381 if (isOutputRange!(W, char)) 8382 { 8383 assert(prec >= -1 && prec <= 7, "Precision must be in the range [-1, 7]"); 8384 8385 immutable adjustedTime = adjTime; 8386 long hnsecs = adjustedTime; 8387 8388 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 8389 8390 if (hnsecs < 0) 8391 { 8392 hnsecs += convert!("hours", "hnsecs")(24); 8393 --days; 8394 } 8395 8396 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 8397 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 8398 immutable second = splitUnitsFromHNSecs!"seconds"(hnsecs); 8399 8400 immutable dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour, 8401 cast(int) minute, cast(int) second)); 8402 8403 if (_timezone is LocalTime()) 8404 { 8405 dateTime.toISOExtString(writer); 8406 fracSecsToISOString(writer, cast(int) hnsecs, prec); 8407 return; 8408 } 8409 8410 if (_timezone is UTC()) 8411 { 8412 dateTime.toISOExtString(writer); 8413 fracSecsToISOString(writer, cast(int) hnsecs, prec); 8414 put(writer, 'Z'); 8415 return; 8416 } 8417 8418 immutable utcOffset = dur!"hnsecs"(adjustedTime - stdTime); 8419 8420 dateTime.toISOExtString(writer); 8421 fracSecsToISOString(writer, cast(int) hnsecs, prec); 8422 SimpleTimeZone.toISOExtString(writer, utcOffset); 8423 } 8424 8425 /// 8426 @safe unittest 8427 { 8428 import core.time : msecs, hnsecs; 8429 import std.datetime.date : DateTime; 8430 8431 assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toISOExtString() == 8432 "2010-07-04T07:06:12"); 8433 8434 assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(24)).toISOExtString() == 8435 "1998-12-25T02:15:00.024"); 8436 8437 assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toISOExtString() == 8438 "0000-01-05T23:09:59"); 8439 8440 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toISOExtString() == 8441 "-0004-01-05T00:00:02.052092"); 8442 8443 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toISOExtString(4) == 8444 "-0004-01-05T00:00:02.0520"); 8445 8446 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toISOExtString(2) == 8447 "-0004-01-05T00:00:02.05"); 8448 8449 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toISOExtString(7) == 8450 "-0004-01-05T00:00:02.0520920"); 8451 } 8452 8453 @safe unittest 8454 { 8455 import core.time; 8456 // Test A.D. 8457 assert(SysTime(DateTime.init, UTC()).toISOExtString() == "0001-01-01T00:00:00Z"); 8458 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC()).toISOExtString() == 8459 "0001-01-01T00:00:00.0000001Z"); 8460 8461 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0)).toISOExtString() == "0009-12-04T00:00:00"); 8462 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12)).toISOExtString() == "0099-12-04T05:06:12"); 8463 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59)).toISOExtString() == "0999-12-04T13:44:59"); 8464 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59)).toISOExtString() == "9999-07-04T23:59:59"); 8465 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1)).toISOExtString() == "+10000-10-20T01:01:01"); 8466 8467 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0), msecs(42)).toISOExtString() == "0009-12-04T00:00:00.042"); 8468 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12), msecs(100)).toISOExtString() == "0099-12-04T05:06:12.1"); 8469 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59), usecs(45020)).toISOExtString() == "0999-12-04T13:44:59.04502"); 8470 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOExtString() == "9999-07-04T23:59:59.0000012"); 8471 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOExtString() == 8472 "+10000-10-20T01:01:01.050789"); 8473 8474 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 8475 new immutable SimpleTimeZone(dur!"minutes"(-360))).toISOExtString() == 8476 "2012-12-21T12:12:12-06:00"); 8477 8478 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 8479 new immutable SimpleTimeZone(dur!"minutes"(420))).toISOExtString() == 8480 "2012-12-21T12:12:12+07:00"); 8481 8482 // Test B.C. 8483 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toISOExtString() == 8484 "0000-12-31T23:59:59.9999999Z"); 8485 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC()).toISOExtString() == 8486 "0000-12-31T23:59:59.0000001Z"); 8487 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), UTC()).toISOExtString() == "0000-12-31T23:59:59Z"); 8488 8489 assert(SysTime(DateTime(0, 12, 4, 0, 12, 4)).toISOExtString() == "0000-12-04T00:12:04"); 8490 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0)).toISOExtString() == "-0009-12-04T00:00:00"); 8491 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12)).toISOExtString() == "-0099-12-04T05:06:12"); 8492 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59)).toISOExtString() == "-0999-12-04T13:44:59"); 8493 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59)).toISOExtString() == "-9999-07-04T23:59:59"); 8494 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1)).toISOExtString() == "-10000-10-20T01:01:01"); 8495 8496 assert(SysTime(DateTime(0, 12, 4, 0, 0, 0), msecs(7)).toISOExtString() == "0000-12-04T00:00:00.007"); 8497 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0), msecs(42)).toISOExtString() == "-0009-12-04T00:00:00.042"); 8498 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12), msecs(100)).toISOExtString() == "-0099-12-04T05:06:12.1"); 8499 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59), usecs(45020)).toISOExtString() == 8500 "-0999-12-04T13:44:59.04502"); 8501 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOExtString() == 8502 "-9999-07-04T23:59:59.0000012"); 8503 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOExtString() == 8504 "-10000-10-20T01:01:01.050789"); 8505 8506 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8507 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8508 assert(cst.toISOExtString() == "1999-07-06T12:30:33"); 8509 assert(ist.toISOExtString() == "1999-07-06T12:30:33"); 8510 8511 static void testScope(scope ref SysTime st) @safe 8512 { 8513 auto result = st.toISOExtString(); 8514 } 8515 } 8516 8517 /++ 8518 Converts this $(LREF SysTime) to a string with the format 8519 YYYY-Mon-DD HH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ 8520 is the time zone). 8521 8522 Note that the number of digits in the fractional seconds varies with the 8523 number of fractional seconds. It's a maximum of 7 (which would be 8524 hnsecs), but only has as many as are necessary to hold the correct value 8525 (so no trailing zeroes), and if there are no fractional seconds, then 8526 there is no decimal point. 8527 8528 If this $(LREF SysTime)'s time zone is 8529 $(REF LocalTime,std,datetime,timezone), then TZ is empty. If its time 8530 zone is `UTC`, then it is "Z". Otherwise, it is the offset from UTC 8531 (e.g. +01:00 or -07:00). Note that the offset from UTC is $(I not) 8532 enough to uniquely identify the time zone. 8533 8534 Time zone offsets will be in the form +HH:MM or -HH:MM. 8535 8536 Params: 8537 writer = A `char` accepting 8538 $(REF_ALTTEXT output range, isOutputRange, std, range, primitives) 8539 Returns: 8540 A `string` when not using an output range; `void` otherwise. 8541 +/ 8542 string toSimpleString() @safe const nothrow scope 8543 { 8544 import std.array : appender; 8545 auto app = appender!string(); 8546 app.reserve(35); 8547 try 8548 toSimpleString(app); 8549 catch (Exception e) 8550 assert(0, "toSimpleString() threw."); 8551 return app.data; 8552 } 8553 8554 /// ditto 8555 void toSimpleString(W)(ref W writer) const scope 8556 if (isOutputRange!(W, char)) 8557 { 8558 immutable adjustedTime = adjTime; 8559 long hnsecs = adjustedTime; 8560 8561 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 8562 8563 if (hnsecs < 0) 8564 { 8565 hnsecs += convert!("hours", "hnsecs")(24); 8566 --days; 8567 } 8568 8569 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 8570 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 8571 immutable second = splitUnitsFromHNSecs!"seconds"(hnsecs); 8572 8573 immutable dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour, 8574 cast(int) minute, cast(int) second)); 8575 8576 if (_timezone is LocalTime()) 8577 { 8578 dateTime.toSimpleString(writer); 8579 fracSecsToISOString(writer, cast(int) hnsecs); 8580 return; 8581 } 8582 8583 if (_timezone is UTC()) 8584 { 8585 dateTime.toSimpleString(writer); 8586 fracSecsToISOString(writer, cast(int) hnsecs); 8587 put(writer, 'Z'); 8588 return; 8589 } 8590 8591 immutable utcOffset = dur!"hnsecs"(adjustedTime - stdTime); 8592 8593 dateTime.toSimpleString(writer); 8594 fracSecsToISOString(writer, cast(int) hnsecs); 8595 SimpleTimeZone.toISOExtString(writer, utcOffset); 8596 } 8597 8598 /// 8599 @safe unittest 8600 { 8601 import core.time : msecs, hnsecs; 8602 import std.datetime.date : DateTime; 8603 8604 assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toSimpleString() == 8605 "2010-Jul-04 07:06:12"); 8606 8607 assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(24)).toSimpleString() == 8608 "1998-Dec-25 02:15:00.024"); 8609 8610 assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toSimpleString() == 8611 "0000-Jan-05 23:09:59"); 8612 8613 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toSimpleString() == 8614 "-0004-Jan-05 00:00:02.052092"); 8615 } 8616 8617 @safe unittest 8618 { 8619 import core.time; 8620 // Test A.D. 8621 assert(SysTime(DateTime.init, UTC()).toString() == "0001-Jan-01 00:00:00Z"); 8622 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC()).toString() == "0001-Jan-01 00:00:00.0000001Z"); 8623 8624 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0)).toSimpleString() == "0009-Dec-04 00:00:00"); 8625 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12)).toSimpleString() == "0099-Dec-04 05:06:12"); 8626 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59)).toSimpleString() == "0999-Dec-04 13:44:59"); 8627 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59)).toSimpleString() == "9999-Jul-04 23:59:59"); 8628 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1)).toSimpleString() == "+10000-Oct-20 01:01:01"); 8629 8630 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0), msecs(42)).toSimpleString() == "0009-Dec-04 00:00:00.042"); 8631 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12), msecs(100)).toSimpleString() == "0099-Dec-04 05:06:12.1"); 8632 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59), usecs(45020)).toSimpleString() == 8633 "0999-Dec-04 13:44:59.04502"); 8634 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59), hnsecs(12)).toSimpleString() == 8635 "9999-Jul-04 23:59:59.0000012"); 8636 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1), hnsecs(507890)).toSimpleString() == 8637 "+10000-Oct-20 01:01:01.050789"); 8638 8639 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 8640 new immutable SimpleTimeZone(dur!"minutes"(-360))).toSimpleString() == 8641 "2012-Dec-21 12:12:12-06:00"); 8642 8643 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 8644 new immutable SimpleTimeZone(dur!"minutes"(420))).toSimpleString() == 8645 "2012-Dec-21 12:12:12+07:00"); 8646 8647 // Test B.C. 8648 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toSimpleString() == 8649 "0000-Dec-31 23:59:59.9999999Z"); 8650 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC()).toSimpleString() == 8651 "0000-Dec-31 23:59:59.0000001Z"); 8652 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), UTC()).toSimpleString() == "0000-Dec-31 23:59:59Z"); 8653 8654 assert(SysTime(DateTime(0, 12, 4, 0, 12, 4)).toSimpleString() == "0000-Dec-04 00:12:04"); 8655 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0)).toSimpleString() == "-0009-Dec-04 00:00:00"); 8656 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12)).toSimpleString() == "-0099-Dec-04 05:06:12"); 8657 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59)).toSimpleString() == "-0999-Dec-04 13:44:59"); 8658 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59)).toSimpleString() == "-9999-Jul-04 23:59:59"); 8659 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1)).toSimpleString() == "-10000-Oct-20 01:01:01"); 8660 8661 assert(SysTime(DateTime(0, 12, 4, 0, 0, 0), msecs(7)).toSimpleString() == "0000-Dec-04 00:00:00.007"); 8662 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0), msecs(42)).toSimpleString() == "-0009-Dec-04 00:00:00.042"); 8663 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12), msecs(100)).toSimpleString() == "-0099-Dec-04 05:06:12.1"); 8664 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59), usecs(45020)).toSimpleString() == 8665 "-0999-Dec-04 13:44:59.04502"); 8666 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59), hnsecs(12)).toSimpleString() == 8667 "-9999-Jul-04 23:59:59.0000012"); 8668 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1), hnsecs(507890)).toSimpleString() == 8669 "-10000-Oct-20 01:01:01.050789"); 8670 8671 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8672 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8673 assert(cst.toSimpleString() == "1999-Jul-06 12:30:33"); 8674 assert(ist.toSimpleString() == "1999-Jul-06 12:30:33"); 8675 8676 static void testScope(scope ref SysTime st) @safe 8677 { 8678 auto result = st.toSimpleString(); 8679 } 8680 } 8681 8682 8683 /++ 8684 Converts this $(LREF SysTime) to a string. 8685 8686 This function exists to make it easy to convert a $(LREF SysTime) to a 8687 string for code that does not care what the exact format is - just that 8688 it presents the information in a clear manner. It also makes it easy to 8689 simply convert a $(LREF SysTime) to a string when using functions such 8690 as `to!string`, `format`, or `writeln` which use toString to convert 8691 user-defined types. So, it is unlikely that much code will call 8692 toString directly. 8693 8694 The format of the string is purposefully unspecified, and code that 8695 cares about the format of the string should use `toISOString`, 8696 `toISOExtString`, `toSimpleString`, or some other custom formatting 8697 function that explicitly generates the format that the code needs. The 8698 reason is that the code is then clear about what format it's using, 8699 making it less error-prone to maintain the code and interact with other 8700 software that consumes the generated strings. It's for this same reason 8701 that $(LREF SysTime) has no `fromString` function, whereas it does have 8702 `fromISOString`, `fromISOExtString`, and `fromSimpleString`. 8703 8704 The format returned by toString may or may not change in the future. 8705 8706 Params: 8707 writer = A `char` accepting 8708 $(REF_ALTTEXT output range, isOutputRange, std, range, primitives) 8709 Returns: 8710 A `string` when not using an output range; `void` otherwise. 8711 +/ 8712 string toString() @safe const nothrow scope 8713 { 8714 return toSimpleString(); 8715 } 8716 8717 /// ditto 8718 void toString(W)(ref W writer) const scope 8719 if (isOutputRange!(W, char)) 8720 { 8721 toSimpleString(writer); 8722 } 8723 8724 @safe unittest 8725 { 8726 import core.time; 8727 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8728 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8729 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8730 static assert(__traits(compiles, st.toString())); 8731 static assert(__traits(compiles, cst.toString())); 8732 static assert(__traits(compiles, ist.toString())); 8733 8734 static void testScope(scope ref SysTime st) @safe 8735 { 8736 auto result = st.toString(); 8737 } 8738 } 8739 8740 8741 /++ 8742 Creates a $(LREF SysTime) from a string with the format 8743 YYYYMMDDTHHMMSS.FFFFFFFTZ (where F is fractional seconds and TZ 8744 is the time zone). Whitespace is stripped from the given string. 8745 8746 The exact format is exactly as described in $(LREF toISOString) except 8747 that trailing zeroes are permitted - including having fractional seconds 8748 with all zeroes. The time zone and fractional seconds are optional, 8749 however, a decimal point with nothing following it is invalid. 8750 Also, while $(LREF toISOString) will never generate a string 8751 with more than 7 digits in the fractional seconds (because that's the 8752 limit with hecto-nanosecond precision), it will allow more than 7 digits 8753 in order to read strings from other sources that have higher precision 8754 (however, any digits beyond 7 will be truncated). 8755 8756 If there is no time zone in the string, then 8757 $(REF LocalTime,std,datetime,timezone) is used. If the time zone is "Z", 8758 then `UTC` is used. Otherwise, a 8759 $(REF SimpleTimeZone,std,datetime,timezone) which corresponds to the 8760 given offset from UTC is used. To get the returned $(LREF SysTime) to be 8761 a particular time zone, pass in that time zone and the $(LREF SysTime) 8762 to be returned will be converted to that time zone (though it will still 8763 be read in as whatever time zone is in its string). 8764 8765 The accepted formats for time zone offsets are +HH, -HH, +HHMM, and 8766 -HHMM. 8767 8768 $(RED Warning: 8769 Previously, $(LREF toISOString) did the same as 8770 $(LREF toISOExtString) and generated +HH:MM or -HH:MM for the time 8771 zone when it was not $(REF LocalTime,std,datetime,timezone) or 8772 $(REF UTC,std,datetime,timezone), which is not in conformance with 8773 ISO 8601 for the non-extended string format. This has now been 8774 fixed. However, for now, fromISOString will continue to accept the 8775 extended format for the time zone so that any code which has been 8776 writing out the result of toISOString to read in later will continue 8777 to work. The current behavior will be kept until July 2019 at which 8778 point, fromISOString will be fixed to be standards compliant.) 8779 8780 Params: 8781 isoString = A string formatted in the ISO format for dates and times. 8782 tz = The time zone to convert the given time to (no 8783 conversion occurs if null). 8784 8785 Throws: 8786 $(REF DateTimeException,std,datetime,date) if the given string is 8787 not in the ISO format or if the resulting $(LREF SysTime) would not 8788 be valid. 8789 +/ 8790 static SysTime fromISOString(S)(scope const S isoString, immutable TimeZone tz = null) @safe 8791 if (isSomeString!S) 8792 { 8793 import std.algorithm.searching : startsWith, find; 8794 import std.conv : to; 8795 import std.string : strip; 8796 import std.utf : byCodeUnit; 8797 8798 auto str = strip(isoString); 8799 immutable skipFirst = str.startsWith('+', '-'); 8800 8801 auto found = (skipFirst ? str[1..$] : str).byCodeUnit.find('.', 'Z', '+', '-'); 8802 auto dateTimeStr = str[0 .. $ - found[0].length]; 8803 8804 typeof(str.byCodeUnit) foundTZ; // needs to have longer lifetime than zoneStr 8805 typeof(str) fracSecStr; 8806 typeof(str) zoneStr; 8807 8808 if (found[1] != 0) 8809 { 8810 if (found[1] == 1) 8811 { 8812 foundTZ = found[0].find('Z', '+', '-')[0]; 8813 8814 if (foundTZ.length != 0) 8815 { 8816 static if (isNarrowString!S) 8817 { 8818 fracSecStr = found[0][0 .. $ - foundTZ.length].source; 8819 zoneStr = foundTZ.source; 8820 } 8821 else 8822 { 8823 fracSecStr = found[0][0 .. $ - foundTZ.length]; 8824 zoneStr = foundTZ; 8825 } 8826 } 8827 else 8828 { 8829 static if (isNarrowString!S) 8830 fracSecStr = found[0].source; 8831 else 8832 fracSecStr = found[0]; 8833 } 8834 } 8835 else 8836 { 8837 static if (isNarrowString!S) 8838 zoneStr = found[0].source; 8839 else 8840 zoneStr = found[0]; 8841 } 8842 } 8843 8844 try 8845 { 8846 auto dateTime = DateTime.fromISOString(dateTimeStr); 8847 auto fracSec = fracSecsFromISOString(fracSecStr); 8848 8849 Rebindable!(immutable TimeZone) parsedZone; 8850 8851 if (zoneStr.empty) 8852 parsedZone = LocalTime(); 8853 else if (zoneStr == "Z") 8854 parsedZone = UTC(); 8855 else 8856 { 8857 try 8858 parsedZone = SimpleTimeZone.fromISOString(zoneStr); 8859 catch (DateTimeException dte) 8860 parsedZone = SimpleTimeZone.fromISOExtString(zoneStr); 8861 } 8862 8863 auto retval = SysTime(dateTime, fracSec, parsedZone); 8864 8865 if (tz !is null) 8866 retval.timezone = tz; 8867 8868 return retval; 8869 } 8870 catch (DateTimeException dte) 8871 throw new DateTimeException(format("Invalid ISO String: %s", isoString)); 8872 } 8873 8874 /// 8875 @safe unittest 8876 { 8877 import core.time : hours, msecs, usecs, hnsecs; 8878 import std.datetime.date : DateTime; 8879 import std.datetime.timezone : SimpleTimeZone, UTC; 8880 8881 assert(SysTime.fromISOString("20100704T070612") == 8882 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 8883 8884 assert(SysTime.fromISOString("19981225T021500.007") == 8885 SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(7))); 8886 8887 assert(SysTime.fromISOString("00000105T230959.00002") == 8888 SysTime(DateTime(0, 1, 5, 23, 9, 59), usecs(20))); 8889 8890 assert(SysTime.fromISOString("20130207T043937.000050392") == 8891 SysTime(DateTime(2013, 2, 7, 4, 39, 37), hnsecs(503))); 8892 8893 assert(SysTime.fromISOString("-00040105T000002") == 8894 SysTime(DateTime(-4, 1, 5, 0, 0, 2))); 8895 8896 assert(SysTime.fromISOString(" 20100704T070612 ") == 8897 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 8898 8899 assert(SysTime.fromISOString("20100704T070612Z") == 8900 SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC())); 8901 8902 assert(SysTime.fromISOString("20100704T070612-0800") == 8903 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 8904 new immutable SimpleTimeZone(hours(-8)))); 8905 8906 assert(SysTime.fromISOString("20100704T070612+0800") == 8907 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 8908 new immutable SimpleTimeZone(hours(8)))); 8909 } 8910 8911 @safe unittest 8912 { 8913 import core.time; 8914 foreach (str; ["", "20100704000000", "20100704 000000", "20100704t000000", 8915 "20100704T000000.", "20100704T000000.A", "20100704T000000.Z", 8916 "20100704T000000.0000000A", "20100704T000000.00000000A", 8917 "20100704T000000+", "20100704T000000-", "20100704T000000:", 8918 "20100704T000000-:", "20100704T000000+:", "20100704T000000-1:", 8919 "20100704T000000+1:", "20100704T000000+1:0", 8920 "20100704T000000-12.00", "20100704T000000+12.00", 8921 "20100704T000000-8", "20100704T000000+8", 8922 "20100704T000000-800", "20100704T000000+800", 8923 "20100704T000000-080", "20100704T000000+080", 8924 "20100704T000000-2400", "20100704T000000+2400", 8925 "20100704T000000-1260", "20100704T000000+1260", 8926 "20100704T000000.0-8", "20100704T000000.0+8", 8927 "20100704T000000.0-800", "20100704T000000.0+800", 8928 "20100704T000000.0-080", "20100704T000000.0+080", 8929 "20100704T000000.0-2400", "20100704T000000.0+2400", 8930 "20100704T000000.0-1260", "20100704T000000.0+1260", 8931 "20100704T000000-8:00", "20100704T000000+8:00", 8932 "20100704T000000-08:0", "20100704T000000+08:0", 8933 "20100704T000000-24:00", "20100704T000000+24:00", 8934 "20100704T000000-12:60", "20100704T000000+12:60", 8935 "20100704T000000.0-8:00", "20100704T000000.0+8:00", 8936 "20100704T000000.0-08:0", "20100704T000000.0+08:0", 8937 "20100704T000000.0-24:00", "20100704T000000.0+24:00", 8938 "20100704T000000.0-12:60", "20100704T000000.0+12:60", 8939 "2010-07-0400:00:00", "2010-07-04 00:00:00", 8940 "2010-07-04t00:00:00", "2010-07-04T00:00:00.", 8941 "2010-Jul-0400:00:00", "2010-Jul-04 00:00:00", "2010-Jul-04t00:00:00", 8942 "2010-Jul-04T00:00:00", "2010-Jul-04 00:00:00.", 8943 "2010-12-22T172201", "2010-Dec-22 17:22:01"]) 8944 { 8945 assertThrown!DateTimeException(SysTime.fromISOString(str), format("[%s]", str)); 8946 } 8947 8948 static void test(string str, SysTime st, size_t line = __LINE__) 8949 { 8950 if (SysTime.fromISOString(str) != st) 8951 throw new AssertError("unittest failure", __FILE__, line); 8952 } 8953 8954 test("20101222T172201", SysTime(DateTime(2010, 12, 22, 17, 22, 1))); 8955 test("19990706T123033", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8956 test("-19990706T123033", SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 8957 test("+019990706T123033", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8958 test("19990706T123033 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8959 test(" 19990706T123033", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8960 test(" 19990706T123033 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8961 8962 test("19070707T121212.0", SysTime(DateTime(1907, 7, 7, 12, 12, 12))); 8963 test("19070707T121212.0000000", SysTime(DateTime(1907, 7, 7, 12, 12, 12))); 8964 test("19070707T121212.0000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), hnsecs(1))); 8965 test("20100704T000000.00000000", SysTime(Date(2010, 7, 4))); 8966 test("20100704T000000.00000009", SysTime(Date(2010, 7, 4))); 8967 test("20100704T000000.00000019", SysTime(DateTime(2010, 7, 4), hnsecs(1))); 8968 test("19070707T121212.000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1))); 8969 test("19070707T121212.0000010", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1))); 8970 test("19070707T121212.001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1))); 8971 test("19070707T121212.0010000", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1))); 8972 8973 auto west60 = new immutable SimpleTimeZone(hours(-1)); 8974 auto west90 = new immutable SimpleTimeZone(minutes(-90)); 8975 auto west480 = new immutable SimpleTimeZone(hours(-8)); 8976 auto east60 = new immutable SimpleTimeZone(hours(1)); 8977 auto east90 = new immutable SimpleTimeZone(minutes(90)); 8978 auto east480 = new immutable SimpleTimeZone(hours(8)); 8979 8980 test("20101222T172201Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), UTC())); 8981 test("20101222T172201-0100", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60)); 8982 test("20101222T172201-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60)); 8983 test("20101222T172201-0130", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west90)); 8984 test("20101222T172201-0800", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west480)); 8985 test("20101222T172201+0100", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 8986 test("20101222T172201+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 8987 test("20101222T172201+0130", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 8988 test("20101222T172201+0800", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east480)); 8989 8990 test("20101103T065106.57159Z", SysTime(DateTime(2010, 11, 3, 6, 51, 6), hnsecs(5715900), UTC())); 8991 test("20101222T172201.23412Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_341_200), UTC())); 8992 test("20101222T172201.23112-0100", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_311_200), west60)); 8993 test("20101222T172201.45-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), west60)); 8994 test("20101222T172201.1-0130", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_000_000), west90)); 8995 test("20101222T172201.55-0800", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(5_500_000), west480)); 8996 test("20101222T172201.1234567+0100", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_234_567), east60)); 8997 test("20101222T172201.0+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 8998 test("20101222T172201.0000000+0130", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 8999 test("20101222T172201.45+0800", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), east480)); 9000 9001 // for dstring coverage 9002 assert(SysTime.fromISOString("20101222T172201.23112-0100"d) == SysTime( 9003 DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_311_200), west60)); 9004 assert(SysTime.fromISOString("19070707T121212.0010000"d) == SysTime( 9005 DateTime(1907, 7, 7, 12, 12, 12), msecs(1))); 9006 9007 // @@@DEPRECATED_2019-07@@@ 9008 // This isn't deprecated per se, but that text will make it so that it 9009 // pops up when deprecations are moved along around July 2019. At that 9010 // time, we will update fromISOString so that it is conformant with ISO 9011 // 8601, and it will no longer accept ISO extended time zones (it does 9012 // currently because of https://issues.dlang.org/show_bug.cgi?id=15654 9013 // toISOString used to incorrectly use the ISO extended time zone format). 9014 // These tests will then start failing will need to be updated accordingly. 9015 // Also, the notes about this issue in toISOString and fromISOString's 9016 // documentation will need to be removed. 9017 test("20101222T172201-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60)); 9018 test("20101222T172201-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west90)); 9019 test("20101222T172201-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west480)); 9020 test("20101222T172201+01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9021 test("20101222T172201+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 9022 test("20101222T172201+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east480)); 9023 9024 test("20101222T172201.23112-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_311_200), west60)); 9025 test("20101222T172201.1-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_000_000), west90)); 9026 test("20101222T172201.55-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(5_500_000), west480)); 9027 test("20101222T172201.1234567+01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_234_567), east60)); 9028 test("20101222T172201.0000000+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 9029 test("20101222T172201.45+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), east480)); 9030 9031 static void testScope(scope ref string str) @safe 9032 { 9033 auto result = SysTime.fromISOString(str); 9034 } 9035 } 9036 9037 // https://issues.dlang.org/show_bug.cgi?id=17801 9038 @safe unittest 9039 { 9040 import std.conv : to; 9041 import std.meta : AliasSeq; 9042 static foreach (C; AliasSeq!(char, wchar, dchar)) 9043 { 9044 static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) 9045 { 9046 assert(SysTime.fromISOString(to!S("20121221T141516Z")) == 9047 SysTime(DateTime(2012, 12, 21, 14, 15, 16), UTC())); 9048 } 9049 } 9050 } 9051 9052 9053 /++ 9054 Creates a $(LREF SysTime) from a string with the format 9055 YYYY-MM-DDTHH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ 9056 is the time zone). Whitespace is stripped from the given string. 9057 9058 The exact format is exactly as described in $(LREF toISOExtString) 9059 except that trailing zeroes are permitted - including having fractional 9060 seconds with all zeroes. The time zone and fractional seconds are 9061 optional, however, a decimal point with nothing following it is invalid. 9062 Also, while $(LREF toISOExtString) will never generate a 9063 string with more than 7 digits in the fractional seconds (because that's 9064 the limit with hecto-nanosecond precision), it will allow more than 7 9065 digits in order to read strings from other sources that have higher 9066 precision (however, any digits beyond 7 will be truncated). 9067 9068 If there is no time zone in the string, then 9069 $(REF LocalTime,std,datetime,timezone) is used. If the time zone is "Z", 9070 then `UTC` is used. Otherwise, a 9071 $(REF SimpleTimeZone,std,datetime,timezone) which corresponds to the 9072 given offset from UTC is used. To get the returned $(LREF SysTime) to be 9073 a particular time zone, pass in that time zone and the $(LREF SysTime) 9074 to be returned will be converted to that time zone (though it will still 9075 be read in as whatever time zone is in its string). 9076 9077 The accepted formats for time zone offsets are +HH, -HH, +HH:MM, and 9078 -HH:MM. 9079 9080 Params: 9081 isoExtString = A string formatted in the ISO Extended format for 9082 dates and times. 9083 tz = The time zone to convert the given time to (no 9084 conversion occurs if null). 9085 9086 Throws: 9087 $(REF DateTimeException,std,datetime,date) if the given string is 9088 not in the ISO format or if the resulting $(LREF SysTime) would not 9089 be valid. 9090 +/ 9091 static SysTime fromISOExtString(S)(scope const S isoExtString, immutable TimeZone tz = null) @safe 9092 if (isSomeString!(S)) 9093 { 9094 import std.algorithm.searching : countUntil, find; 9095 import std.conv : to; 9096 import std.string : strip, indexOf; 9097 9098 auto str = strip(isoExtString); 9099 9100 auto tIndex = str.indexOf('T'); 9101 enforce(tIndex != -1, new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString))); 9102 9103 auto found = str[tIndex + 1 .. $].find('.', 'Z', '+', '-'); 9104 auto dateTimeStr = str[0 .. $ - found[0].length]; 9105 9106 typeof(str) foundTZ; // needs to have longer lifetime than zoneStr 9107 typeof(str) fracSecStr; 9108 typeof(str) zoneStr; 9109 9110 if (found[1] != 0) 9111 { 9112 if (found[1] == 1) 9113 { 9114 foundTZ = found[0].find('Z', '+', '-')[0]; 9115 9116 if (foundTZ.length != 0) 9117 { 9118 fracSecStr = found[0][0 .. $ - foundTZ.length]; 9119 zoneStr = foundTZ; 9120 } 9121 else 9122 fracSecStr = found[0]; 9123 } 9124 else 9125 zoneStr = found[0]; 9126 } 9127 9128 try 9129 { 9130 auto dateTime = DateTime.fromISOExtString(dateTimeStr); 9131 auto fracSec = fracSecsFromISOString(fracSecStr); 9132 Rebindable!(immutable TimeZone) parsedZone; 9133 9134 if (zoneStr.empty) 9135 parsedZone = LocalTime(); 9136 else if (zoneStr == "Z") 9137 parsedZone = UTC(); 9138 else 9139 parsedZone = SimpleTimeZone.fromISOExtString(zoneStr); 9140 9141 auto retval = SysTime(dateTime, fracSec, parsedZone); 9142 9143 if (tz !is null) 9144 retval.timezone = tz; 9145 9146 return retval; 9147 } 9148 catch (DateTimeException dte) 9149 throw new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)); 9150 } 9151 9152 /// 9153 @safe unittest 9154 { 9155 import core.time : hours, msecs, usecs, hnsecs; 9156 import std.datetime.date : DateTime; 9157 import std.datetime.timezone : SimpleTimeZone, UTC; 9158 9159 assert(SysTime.fromISOExtString("2010-07-04T07:06:12") == 9160 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 9161 9162 assert(SysTime.fromISOExtString("1998-12-25T02:15:00.007") == 9163 SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(7))); 9164 9165 assert(SysTime.fromISOExtString("0000-01-05T23:09:59.00002") == 9166 SysTime(DateTime(0, 1, 5, 23, 9, 59), usecs(20))); 9167 9168 assert(SysTime.fromISOExtString("2013-02-07T04:39:37.000050392") == 9169 SysTime(DateTime(2013, 2, 7, 4, 39, 37), hnsecs(503))); 9170 9171 assert(SysTime.fromISOExtString("-0004-01-05T00:00:02") == 9172 SysTime(DateTime(-4, 1, 5, 0, 0, 2))); 9173 9174 assert(SysTime.fromISOExtString(" 2010-07-04T07:06:12 ") == 9175 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 9176 9177 assert(SysTime.fromISOExtString("2010-07-04T07:06:12Z") == 9178 SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC())); 9179 9180 assert(SysTime.fromISOExtString("2010-07-04T07:06:12-08:00") == 9181 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 9182 new immutable SimpleTimeZone(hours(-8)))); 9183 assert(SysTime.fromISOExtString("2010-07-04T07:06:12+08:00") == 9184 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 9185 new immutable SimpleTimeZone(hours(8)))); 9186 } 9187 9188 @safe unittest 9189 { 9190 import core.time; 9191 foreach (str; ["", "20100704000000", "20100704 000000", 9192 "20100704t000000", "20100704T000000.", "20100704T000000.0", 9193 "2010-07:0400:00:00", "2010-07-04 00:00:00", 9194 "2010-07-04 00:00:00", "2010-07-04t00:00:00", 9195 "2010-07-04T00:00:00.", "2010-07-04T00:00:00.A", "2010-07-04T00:00:00.Z", 9196 "2010-07-04T00:00:00.0000000A", "2010-07-04T00:00:00.00000000A", 9197 "2010-07-04T00:00:00+", "2010-07-04T00:00:00-", 9198 "2010-07-04T00:00:00:", "2010-07-04T00:00:00-:", "2010-07-04T00:00:00+:", 9199 "2010-07-04T00:00:00-1:", "2010-07-04T00:00:00+1:", "2010-07-04T00:00:00+1:0", 9200 "2010-07-04T00:00:00-12.00", "2010-07-04T00:00:00+12.00", 9201 "2010-07-04T00:00:00-8", "2010-07-04T00:00:00+8", 9202 "20100704T000000-800", "20100704T000000+800", 9203 "20100704T000000-080", "20100704T000000+080", 9204 "20100704T000000-2400", "20100704T000000+2400", 9205 "20100704T000000-1260", "20100704T000000+1260", 9206 "20100704T000000.0-800", "20100704T000000.0+800", 9207 "20100704T000000.0-8", "20100704T000000.0+8", 9208 "20100704T000000.0-080", "20100704T000000.0+080", 9209 "20100704T000000.0-2400", "20100704T000000.0+2400", 9210 "20100704T000000.0-1260", "20100704T000000.0+1260", 9211 "2010-07-04T00:00:00-8:00", "2010-07-04T00:00:00+8:00", 9212 "2010-07-04T00:00:00-24:00", "2010-07-04T00:00:00+24:00", 9213 "2010-07-04T00:00:00-12:60", "2010-07-04T00:00:00+12:60", 9214 "2010-07-04T00:00:00.0-8:00", "2010-07-04T00:00:00.0+8:00", 9215 "2010-07-04T00:00:00.0-8", "2010-07-04T00:00:00.0+8", 9216 "2010-07-04T00:00:00.0-24:00", "2010-07-04T00:00:00.0+24:00", 9217 "2010-07-04T00:00:00.0-12:60", "2010-07-04T00:00:00.0+12:60", 9218 "2010-Jul-0400:00:00", "2010-Jul-04t00:00:00", 9219 "2010-Jul-04 00:00:00.", "2010-Jul-04 00:00:00.0", 9220 "20101222T172201", "2010-Dec-22 17:22:01"]) 9221 { 9222 assertThrown!DateTimeException(SysTime.fromISOExtString(str), format("[%s]", str)); 9223 } 9224 9225 static void test(string str, SysTime st, size_t line = __LINE__) 9226 { 9227 if (SysTime.fromISOExtString(str) != st) 9228 throw new AssertError("unittest failure", __FILE__, line); 9229 } 9230 9231 test("2010-12-22T17:22:01", SysTime(DateTime(2010, 12, 22, 17, 22, 1))); 9232 test("1999-07-06T12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9233 test("-1999-07-06T12:30:33", SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 9234 test("+01999-07-06T12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9235 test("1999-07-06T12:30:33 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9236 test(" 1999-07-06T12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9237 test(" 1999-07-06T12:30:33 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9238 9239 test("1907-07-07T12:12:12.0", SysTime(DateTime(1907, 7, 7, 12, 12, 12))); 9240 test("1907-07-07T12:12:12.0000000", SysTime(DateTime(1907, 7, 7, 12, 12, 12))); 9241 test("1907-07-07T12:12:12.0000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), hnsecs(1))); 9242 test("2010-07-04T00:00:00.00000000", SysTime(Date(2010, 7, 4))); 9243 test("2010-07-04T00:00:00.00000009", SysTime(Date(2010, 7, 4))); 9244 test("2010-07-04T00:00:00.00000019", SysTime(DateTime(2010, 7, 4), hnsecs(1))); 9245 test("1907-07-07T12:12:12.000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1))); 9246 test("1907-07-07T12:12:12.0000010", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1))); 9247 test("1907-07-07T12:12:12.001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1))); 9248 test("1907-07-07T12:12:12.0010000", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1))); 9249 9250 auto west60 = new immutable SimpleTimeZone(hours(-1)); 9251 auto west90 = new immutable SimpleTimeZone(minutes(-90)); 9252 auto west480 = new immutable SimpleTimeZone(hours(-8)); 9253 auto east60 = new immutable SimpleTimeZone(hours(1)); 9254 auto east90 = new immutable SimpleTimeZone(minutes(90)); 9255 auto east480 = new immutable SimpleTimeZone(hours(8)); 9256 9257 test("2010-12-22T17:22:01Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), UTC())); 9258 test("2010-12-22T17:22:01-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60)); 9259 test("2010-12-22T17:22:01-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60)); 9260 test("2010-12-22T17:22:01-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west90)); 9261 test("2010-12-22T17:22:01-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west480)); 9262 test("2010-12-22T17:22:01+01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9263 test("2010-12-22T17:22:01+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9264 test("2010-12-22T17:22:01+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 9265 test("2010-12-22T17:22:01+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east480)); 9266 9267 test("2010-11-03T06:51:06.57159Z", SysTime(DateTime(2010, 11, 3, 6, 51, 6), hnsecs(5715900), UTC())); 9268 test("2010-12-22T17:22:01.23412Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_341_200), UTC())); 9269 test("2010-12-22T17:22:01.23112-01:00", 9270 SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_311_200), west60)); 9271 test("2010-12-22T17:22:01.45-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), west60)); 9272 test("2010-12-22T17:22:01.1-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_000_000), west90)); 9273 test("2010-12-22T17:22:01.55-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(5_500_000), west480)); 9274 test("2010-12-22T17:22:01.1234567+01:00", 9275 SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_234_567), east60)); 9276 test("2010-12-22T17:22:01.0+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9277 test("2010-12-22T17:22:01.0000000+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 9278 test("2010-12-22T17:22:01.45+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), east480)); 9279 9280 static void testScope(scope ref string str) @safe 9281 { 9282 auto result = SysTime.fromISOExtString(str); 9283 } 9284 } 9285 9286 // https://issues.dlang.org/show_bug.cgi?id=17801 9287 @safe unittest 9288 { 9289 import core.time; 9290 import std.conv : to; 9291 import std.meta : AliasSeq; 9292 static foreach (C; AliasSeq!(char, wchar, dchar)) 9293 { 9294 static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) 9295 { 9296 assert(SysTime.fromISOExtString(to!S("2012-12-21T14:15:16Z")) == 9297 SysTime(DateTime(2012, 12, 21, 14, 15, 16), UTC())); 9298 } 9299 } 9300 } 9301 9302 9303 /++ 9304 Creates a $(LREF SysTime) from a string with the format 9305 YYYY-Mon-DD HH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ 9306 is the time zone). Whitespace is stripped from the given string. 9307 9308 The exact format is exactly as described in $(LREF toSimpleString) except 9309 that trailing zeroes are permitted - including having fractional seconds 9310 with all zeroes. The time zone and fractional seconds are optional, 9311 however, a decimal point with nothing following it is invalid. 9312 Also, while $(LREF toSimpleString) will never generate a 9313 string with more than 7 digits in the fractional seconds (because that's 9314 the limit with hecto-nanosecond precision), it will allow more than 7 9315 digits in order to read strings from other sources that have higher 9316 precision (however, any digits beyond 7 will be truncated). 9317 9318 If there is no time zone in the string, then 9319 $(REF LocalTime,std,datetime,timezone) is used. If the time zone is "Z", 9320 then `UTC` is used. Otherwise, a 9321 $(REF SimpleTimeZone,std,datetime,timezone) which corresponds to the 9322 given offset from UTC is used. To get the returned $(LREF SysTime) to be 9323 a particular time zone, pass in that time zone and the $(LREF SysTime) 9324 to be returned will be converted to that time zone (though it will still 9325 be read in as whatever time zone is in its string). 9326 9327 The accepted formats for time zone offsets are +HH, -HH, +HH:MM, and 9328 -HH:MM. 9329 9330 Params: 9331 simpleString = A string formatted in the way that 9332 `toSimpleString` formats dates and times. 9333 tz = The time zone to convert the given time to (no 9334 conversion occurs if null). 9335 9336 Throws: 9337 $(REF DateTimeException,std,datetime,date) if the given string is 9338 not in the ISO format or if the resulting $(LREF SysTime) would not 9339 be valid. 9340 +/ 9341 static SysTime fromSimpleString(S)(scope const S simpleString, immutable TimeZone tz = null) @safe 9342 if (isSomeString!(S)) 9343 { 9344 import std.algorithm.searching : find; 9345 import std.conv : to; 9346 import std.string : strip, indexOf; 9347 9348 auto str = strip(simpleString); 9349 9350 auto spaceIndex = str.indexOf(' '); 9351 enforce(spaceIndex != -1, new DateTimeException(format("Invalid Simple String: %s", simpleString))); 9352 9353 auto found = str[spaceIndex + 1 .. $].find('.', 'Z', '+', '-'); 9354 auto dateTimeStr = str[0 .. $ - found[0].length]; 9355 9356 typeof(str) foundTZ; // needs to have longer lifetime than zoneStr 9357 typeof(str) fracSecStr; 9358 typeof(str) zoneStr; 9359 9360 if (found[1] != 0) 9361 { 9362 if (found[1] == 1) 9363 { 9364 foundTZ = found[0].find('Z', '+', '-')[0]; 9365 9366 if (foundTZ.length != 0) 9367 { 9368 fracSecStr = found[0][0 .. $ - foundTZ.length]; 9369 zoneStr = foundTZ; 9370 } 9371 else 9372 fracSecStr = found[0]; 9373 } 9374 else 9375 zoneStr = found[0]; 9376 } 9377 9378 try 9379 { 9380 auto dateTime = DateTime.fromSimpleString(dateTimeStr); 9381 auto fracSec = fracSecsFromISOString(fracSecStr); 9382 Rebindable!(immutable TimeZone) parsedZone; 9383 9384 if (zoneStr.empty) 9385 parsedZone = LocalTime(); 9386 else if (zoneStr == "Z") 9387 parsedZone = UTC(); 9388 else 9389 parsedZone = SimpleTimeZone.fromISOExtString(zoneStr); 9390 9391 auto retval = SysTime(dateTime, fracSec, parsedZone); 9392 9393 if (tz !is null) 9394 retval.timezone = tz; 9395 9396 return retval; 9397 } 9398 catch (DateTimeException dte) 9399 throw new DateTimeException(format("Invalid Simple String: %s", simpleString)); 9400 } 9401 9402 /// 9403 @safe unittest 9404 { 9405 import core.time : hours, msecs, usecs, hnsecs; 9406 import std.datetime.date : DateTime; 9407 import std.datetime.timezone : SimpleTimeZone, UTC; 9408 9409 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12") == 9410 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 9411 9412 assert(SysTime.fromSimpleString("1998-Dec-25 02:15:00.007") == 9413 SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(7))); 9414 9415 assert(SysTime.fromSimpleString("0000-Jan-05 23:09:59.00002") == 9416 SysTime(DateTime(0, 1, 5, 23, 9, 59), usecs(20))); 9417 9418 assert(SysTime.fromSimpleString("2013-Feb-07 04:39:37.000050392") == 9419 SysTime(DateTime(2013, 2, 7, 4, 39, 37), hnsecs(503))); 9420 9421 assert(SysTime.fromSimpleString("-0004-Jan-05 00:00:02") == 9422 SysTime(DateTime(-4, 1, 5, 0, 0, 2))); 9423 9424 assert(SysTime.fromSimpleString(" 2010-Jul-04 07:06:12 ") == 9425 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 9426 9427 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12Z") == 9428 SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC())); 9429 9430 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12-08:00") == 9431 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 9432 new immutable SimpleTimeZone(hours(-8)))); 9433 9434 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12+08:00") == 9435 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 9436 new immutable SimpleTimeZone(hours(8)))); 9437 } 9438 9439 @safe unittest 9440 { 9441 import core.time; 9442 foreach (str; ["", "20100704000000", "20100704 000000", 9443 "20100704t000000", "20100704T000000.", "20100704T000000.0", 9444 "2010-07-0400:00:00", "2010-07-04 00:00:00", "2010-07-04t00:00:00", 9445 "2010-07-04T00:00:00.", "2010-07-04T00:00:00.0", 9446 "2010-Jul-0400:00:00", "2010-Jul-04t00:00:00", "2010-Jul-04T00:00:00", 9447 "2010-Jul-04 00:00:00.", "2010-Jul-04 00:00:00.A", "2010-Jul-04 00:00:00.Z", 9448 "2010-Jul-04 00:00:00.0000000A", "2010-Jul-04 00:00:00.00000000A", 9449 "2010-Jul-04 00:00:00+", "2010-Jul-04 00:00:00-", 9450 "2010-Jul-04 00:00:00:", "2010-Jul-04 00:00:00-:", 9451 "2010-Jul-04 00:00:00+:", "2010-Jul-04 00:00:00-1:", 9452 "2010-Jul-04 00:00:00+1:", "2010-Jul-04 00:00:00+1:0", 9453 "2010-Jul-04 00:00:00-12.00", "2010-Jul-04 00:00:00+12.00", 9454 "2010-Jul-04 00:00:00-8", "2010-Jul-04 00:00:00+8", 9455 "20100704T000000-800", "20100704T000000+800", 9456 "20100704T000000-080", "20100704T000000+080", 9457 "20100704T000000-2400", "20100704T000000+2400", 9458 "20100704T000000-1260", "20100704T000000+1260", 9459 "20100704T000000.0-800", "20100704T000000.0+800", 9460 "20100704T000000.0-8", "20100704T000000.0+8", 9461 "20100704T000000.0-080", "20100704T000000.0+080", 9462 "20100704T000000.0-2400", "20100704T000000.0+2400", 9463 "20100704T000000.0-1260", "20100704T000000.0+1260", 9464 "2010-Jul-04 00:00:00-8:00", "2010-Jul-04 00:00:00+8:00", 9465 "2010-Jul-04 00:00:00-08:0", "2010-Jul-04 00:00:00+08:0", 9466 "2010-Jul-04 00:00:00-24:00", "2010-Jul-04 00:00:00+24:00", 9467 "2010-Jul-04 00:00:00-12:60", "2010-Jul-04 00:00:00+24:60", 9468 "2010-Jul-04 00:00:00.0-8:00", "2010-Jul-04 00:00:00+8:00", 9469 "2010-Jul-04 00:00:00.0-8", "2010-Jul-04 00:00:00.0+8", 9470 "2010-Jul-04 00:00:00.0-08:0", "2010-Jul-04 00:00:00.0+08:0", 9471 "2010-Jul-04 00:00:00.0-24:00", "2010-Jul-04 00:00:00.0+24:00", 9472 "2010-Jul-04 00:00:00.0-12:60", "2010-Jul-04 00:00:00.0+24:60", 9473 "20101222T172201", "2010-12-22T172201"]) 9474 { 9475 assertThrown!DateTimeException(SysTime.fromSimpleString(str), format("[%s]", str)); 9476 } 9477 9478 static void test(string str, SysTime st, size_t line = __LINE__) 9479 { 9480 if (SysTime.fromSimpleString(str) != st) 9481 throw new AssertError("unittest failure", __FILE__, line); 9482 } 9483 9484 test("2010-Dec-22 17:22:01", SysTime(DateTime(2010, 12, 22, 17, 22, 1))); 9485 test("1999-Jul-06 12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9486 test("-1999-Jul-06 12:30:33", SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 9487 test("+01999-Jul-06 12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9488 test("1999-Jul-06 12:30:33 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9489 test(" 1999-Jul-06 12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9490 test(" 1999-Jul-06 12:30:33 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9491 9492 test("1907-Jul-07 12:12:12.0", SysTime(DateTime(1907, 7, 7, 12, 12, 12))); 9493 test("1907-Jul-07 12:12:12.0000000", SysTime(DateTime(1907, 7, 7, 12, 12, 12))); 9494 test("2010-Jul-04 00:00:00.00000000", SysTime(Date(2010, 7, 4))); 9495 test("2010-Jul-04 00:00:00.00000009", SysTime(Date(2010, 7, 4))); 9496 test("2010-Jul-04 00:00:00.00000019", SysTime(DateTime(2010, 7, 4), hnsecs(1))); 9497 test("1907-Jul-07 12:12:12.0000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), hnsecs(1))); 9498 test("1907-Jul-07 12:12:12.000001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1))); 9499 test("1907-Jul-07 12:12:12.0000010", SysTime(DateTime(1907, 7, 7, 12, 12, 12), usecs(1))); 9500 test("1907-Jul-07 12:12:12.001", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1))); 9501 test("1907-Jul-07 12:12:12.0010000", SysTime(DateTime(1907, 7, 7, 12, 12, 12), msecs(1))); 9502 9503 auto west60 = new immutable SimpleTimeZone(hours(-1)); 9504 auto west90 = new immutable SimpleTimeZone(minutes(-90)); 9505 auto west480 = new immutable SimpleTimeZone(hours(-8)); 9506 auto east60 = new immutable SimpleTimeZone(hours(1)); 9507 auto east90 = new immutable SimpleTimeZone(minutes(90)); 9508 auto east480 = new immutable SimpleTimeZone(hours(8)); 9509 9510 test("2010-Dec-22 17:22:01Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), UTC())); 9511 test("2010-Dec-22 17:22:01-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60)); 9512 test("2010-Dec-22 17:22:01-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west60)); 9513 test("2010-Dec-22 17:22:01-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west90)); 9514 test("2010-Dec-22 17:22:01-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), west480)); 9515 test("2010-Dec-22 17:22:01+01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9516 test("2010-Dec-22 17:22:01+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9517 test("2010-Dec-22 17:22:01+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 9518 test("2010-Dec-22 17:22:01+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east480)); 9519 9520 test("2010-Nov-03 06:51:06.57159Z", SysTime(DateTime(2010, 11, 3, 6, 51, 6), hnsecs(5715900), UTC())); 9521 test("2010-Dec-22 17:22:01.23412Z", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_341_200), UTC())); 9522 test("2010-Dec-22 17:22:01.23112-01:00", 9523 SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(2_311_200), west60)); 9524 test("2010-Dec-22 17:22:01.45-01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), west60)); 9525 test("2010-Dec-22 17:22:01.1-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_000_000), west90)); 9526 test("2010-Dec-22 17:22:01.55-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(5_500_000), west480)); 9527 test("2010-Dec-22 17:22:01.1234567+01:00", 9528 SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(1_234_567), east60)); 9529 test("2010-Dec-22 17:22:01.0+01", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east60)); 9530 test("2010-Dec-22 17:22:01.0000000+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 1), east90)); 9531 test("2010-Dec-22 17:22:01.45+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 1), hnsecs(4_500_000), east480)); 9532 9533 static void testScope(scope ref string str) @safe 9534 { 9535 auto result = SysTime.fromSimpleString(str); 9536 } 9537 } 9538 9539 // https://issues.dlang.org/show_bug.cgi?id=17801 9540 @safe unittest 9541 { 9542 import core.time; 9543 import std.conv : to; 9544 import std.meta : AliasSeq; 9545 static foreach (C; AliasSeq!(char, wchar, dchar)) 9546 { 9547 static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) 9548 { 9549 assert(SysTime.fromSimpleString(to!S("2012-Dec-21 14:15:16Z")) == 9550 SysTime(DateTime(2012, 12, 21, 14, 15, 16), UTC())); 9551 } 9552 } 9553 } 9554 9555 9556 /++ 9557 Returns the $(LREF SysTime) farthest in the past which is representable 9558 by $(LREF SysTime). 9559 9560 The $(LREF SysTime) which is returned is in UTC. 9561 +/ 9562 @property static SysTime min() @safe pure nothrow 9563 { 9564 return SysTime(long.min, UTC()); 9565 } 9566 9567 @safe unittest 9568 { 9569 assert(SysTime.min.year < 0); 9570 assert(SysTime.min < SysTime.max); 9571 } 9572 9573 9574 /++ 9575 Returns the $(LREF SysTime) farthest in the future which is representable 9576 by $(LREF SysTime). 9577 9578 The $(LREF SysTime) which is returned is in UTC. 9579 +/ 9580 @property static SysTime max() @safe pure nothrow 9581 { 9582 return SysTime(long.max, UTC()); 9583 } 9584 9585 @safe unittest 9586 { 9587 assert(SysTime.max.year > 0); 9588 assert(SysTime.max > SysTime.min); 9589 } 9590 9591 9592 private: 9593 9594 /+ 9595 Returns `stdTime` converted to $(LREF SysTime)'s time zone. 9596 +/ 9597 @property long adjTime() @safe const nothrow scope 9598 { 9599 return _timezone.utcToTZ(_stdTime); 9600 } 9601 9602 9603 /+ 9604 Converts the given hnsecs from $(LREF SysTime)'s time zone to std time. 9605 +/ 9606 @property void adjTime(long adjTime) @safe nothrow scope 9607 { 9608 _stdTime = _timezone.tzToUTC(adjTime); 9609 } 9610 9611 9612 final class InitTimeZone : TimeZone 9613 { 9614 public: 9615 9616 static immutable(InitTimeZone) opCall() @safe pure nothrow @nogc { return _initTimeZone; } 9617 9618 @property override bool hasDST() @safe const nothrow @nogc { return false; } 9619 9620 override bool dstInEffect(long stdTime) @safe const scope nothrow @nogc { return false; } 9621 9622 override long utcToTZ(long stdTime) @safe const scope nothrow @nogc { return 0; } 9623 9624 override long tzToUTC(long adjTime) @safe const scope nothrow @nogc { return 0; } 9625 9626 override Duration utcOffsetAt(long stdTime) @safe const scope nothrow @nogc { return Duration.zero; } 9627 9628 private: 9629 9630 this() @safe immutable pure 9631 { 9632 super("SysTime.init's timezone", "SysTime.init's timezone", "SysTime.init's timezone"); 9633 } 9634 9635 static immutable InitTimeZone _initTimeZone = new immutable(InitTimeZone); 9636 } 9637 9638 // https://issues.dlang.org/show_bug.cgi?id=17732 9639 @safe unittest 9640 { 9641 assert(SysTime.init.timezone is InitTimeZone()); 9642 assert(SysTime.init.toISOString() == "00010101T000000+00:00"); 9643 assert(SysTime.init.toISOExtString() == "0001-01-01T00:00:00+00:00"); 9644 assert(SysTime.init.toSimpleString() == "0001-Jan-01 00:00:00+00:00"); 9645 assert(SysTime.init.toString() == "0001-Jan-01 00:00:00+00:00"); 9646 } 9647 9648 // Assigning a value to _timezone in SysTime.init currently doesn't work due 9649 // to https://issues.dlang.org/show_bug.cgi?id=17740. So, to hack around 9650 // that problem, these accessors have been added so that we can insert a 9651 // runtime check for null and then use InitTimeZone for SysTime.init (which 9652 // which is the only case where _timezone would be null). This thus fixes 9653 // the problem with segfaulting when using SysTime.init but at the cost of 9654 // what should be an unnecessary null check. Once 17740 has finally been 9655 // fixed, _timezoneStorage should be removed, these accessors should be 9656 // removed, and the _timezone variable declaration should be restored. 9657 pragma(inline, true) @property _timezone() @safe const pure nothrow @nogc 9658 { 9659 return _timezoneStorage is null ? InitTimeZone() : _timezoneStorage; 9660 } 9661 9662 pragma(inline, true) @property void _timezone(return scope immutable TimeZone tz) @safe pure nothrow @nogc scope 9663 { 9664 _timezoneStorage = tz; 9665 } 9666 9667 9668 long _stdTime; 9669 Rebindable!(immutable TimeZone) _timezoneStorage; 9670 //Rebindable!(immutable TimeZone) _timezone = InitTimeZone(); 9671 } 9672 9673 /// 9674 @safe unittest 9675 { 9676 import core.time : days, hours, seconds; 9677 import std.datetime.date : DateTime; 9678 import std.datetime.timezone : SimpleTimeZone, UTC; 9679 9680 // make a specific point in time in the UTC timezone 9681 auto st = SysTime(DateTime(2018, 1, 1, 10, 30, 0), UTC()); 9682 // make a specific point in time in the New York timezone 9683 auto ny = SysTime( 9684 DateTime(2018, 1, 1, 10, 30, 0), 9685 new immutable SimpleTimeZone(-5.hours, "America/New_York") 9686 ); 9687 9688 // ISO standard time strings 9689 assert(st.toISOString() == "20180101T103000Z"); 9690 assert(st.toISOExtString() == "2018-01-01T10:30:00Z"); 9691 9692 // add two days and 30 seconds 9693 st += 2.days + 30.seconds; 9694 assert(st.toISOExtString() == "2018-01-03T10:30:30Z"); 9695 } 9696 9697 9698 /++ 9699 Converts from unix time (which uses midnight, January 1st, 1970 UTC as its 9700 epoch and seconds as its units) to "std time" (which uses midnight, 9701 January 1st, 1 A.D. UTC and hnsecs as its units). 9702 9703 The C standard does not specify the representation of time_t, so it is 9704 implementation defined. On POSIX systems, unix time is equivalent to 9705 time_t, but that's not necessarily true on other systems (e.g. it is 9706 not true for the Digital Mars C runtime). So, be careful when using unix 9707 time with C functions on non-POSIX systems. 9708 9709 "std time"'s epoch is based on the Proleptic Gregorian Calendar per ISO 9710 8601 and is what $(LREF SysTime) uses internally. However, holding the time 9711 as an integer in hnsecs since that epoch technically isn't actually part of 9712 the standard, much as it's based on it, so the name "std time" isn't 9713 particularly good, but there isn't an official name for it. C# uses "ticks" 9714 for the same thing, but they aren't actually clock ticks, and the term 9715 "ticks" $(I is) used for actual clock ticks for $(REF MonoTime, core,time), 9716 so it didn't make sense to use the term ticks here. So, for better or worse, 9717 std.datetime uses the term "std time" for this. 9718 9719 Params: 9720 unixTime = The unix time to convert. 9721 9722 See_Also: 9723 SysTime.fromUnixTime 9724 +/ 9725 long unixTimeToStdTime(long unixTime) @safe pure nothrow @nogc 9726 { 9727 return 621_355_968_000_000_000L + convert!("seconds", "hnsecs")(unixTime); 9728 } 9729 9730 /// 9731 @safe unittest 9732 { 9733 import std.datetime.date : DateTime; 9734 import std.datetime.timezone : UTC; 9735 9736 // Midnight, January 1st, 1970 9737 assert(unixTimeToStdTime(0) == 621_355_968_000_000_000L); 9738 assert(SysTime(unixTimeToStdTime(0)) == 9739 SysTime(DateTime(1970, 1, 1), UTC())); 9740 9741 assert(unixTimeToStdTime(int.max) == 642_830_804_470_000_000L); 9742 assert(SysTime(unixTimeToStdTime(int.max)) == 9743 SysTime(DateTime(2038, 1, 19, 3, 14, 7), UTC())); 9744 9745 assert(unixTimeToStdTime(-127_127) == 621_354_696_730_000_000L); 9746 assert(SysTime(unixTimeToStdTime(-127_127)) == 9747 SysTime(DateTime(1969, 12, 30, 12, 41, 13), UTC())); 9748 } 9749 9750 @safe unittest 9751 { 9752 // Midnight, January 2nd, 1970 9753 assert(unixTimeToStdTime(86_400) == 621_355_968_000_000_000L + 864_000_000_000L); 9754 // Midnight, December 31st, 1969 9755 assert(unixTimeToStdTime(-86_400) == 621_355_968_000_000_000L - 864_000_000_000L); 9756 9757 assert(unixTimeToStdTime(0) == (Date(1970, 1, 1) - Date(1, 1, 1)).total!"hnsecs"); 9758 assert(unixTimeToStdTime(0) == (DateTime(1970, 1, 1) - DateTime(1, 1, 1)).total!"hnsecs"); 9759 9760 foreach (dt; [DateTime(2010, 11, 1, 19, 5, 22), DateTime(1952, 7, 6, 2, 17, 9)]) 9761 assert(unixTimeToStdTime((dt - DateTime(1970, 1, 1)).total!"seconds") == (dt - DateTime.init).total!"hnsecs"); 9762 } 9763 9764 9765 /++ 9766 Converts std time (which uses midnight, January 1st, 1 A.D. UTC as its epoch 9767 and hnsecs as its units) to unix time (which uses midnight, January 1st, 9768 1970 UTC as its epoch and seconds as its units). 9769 9770 The C standard does not specify the representation of time_t, so it is 9771 implementation defined. On POSIX systems, unix time is equivalent to 9772 time_t, but that's not necessarily true on other systems (e.g. it is 9773 not true for the Digital Mars C runtime). So, be careful when using unix 9774 time with C functions on non-POSIX systems. 9775 9776 "std time"'s epoch is based on the Proleptic Gregorian Calendar per ISO 9777 8601 and is what $(LREF SysTime) uses internally. However, holding the time 9778 as an integer in hnescs since that epoch technically isn't actually part of 9779 the standard, much as it's based on it, so the name "std time" isn't 9780 particularly good, but there isn't an official name for it. C# uses "ticks" 9781 for the same thing, but they aren't actually clock ticks, and the term 9782 "ticks" $(I is) used for actual clock ticks for $(REF MonoTime, core,time), 9783 so it didn't make sense to use the term ticks here. So, for better or worse, 9784 std.datetime uses the term "std time" for this. 9785 9786 By default, the return type is time_t (which is normally an alias for 9787 int on 32-bit systems and long on 64-bit systems), but if a different 9788 size is required than either int or long can be passed as a template 9789 argument to get the desired size. 9790 9791 If the return type is int, and the result can't fit in an int, then the 9792 closest value that can be held in 32 bits will be used (so `int.max` 9793 if it goes over and `int.min` if it goes under). However, no attempt 9794 is made to deal with integer overflow if the return type is long. 9795 9796 Params: 9797 T = The return type (int or long). It defaults to time_t, which is 9798 normally 32 bits on a 32-bit system and 64 bits on a 64-bit 9799 system. 9800 stdTime = The std time to convert. 9801 9802 Returns: 9803 A signed integer representing the unix time which is equivalent to 9804 the given std time. 9805 9806 See_Also: 9807 SysTime.toUnixTime 9808 +/ 9809 T stdTimeToUnixTime(T = time_t)(long stdTime) @safe pure nothrow 9810 if (is(T == int) || is(T == long)) 9811 { 9812 immutable unixTime = convert!("hnsecs", "seconds")(stdTime - 621_355_968_000_000_000L); 9813 9814 static assert(is(time_t == int) || is(time_t == long), 9815 "Currently, std.datetime only supports systems where time_t is int or long"); 9816 9817 static if (is(T == long)) 9818 return unixTime; 9819 else static if (is(T == int)) 9820 { 9821 if (unixTime > int.max) 9822 return int.max; 9823 return unixTime < int.min ? int.min : cast(int) unixTime; 9824 } 9825 else 9826 static assert(0, "Bug in template constraint. Only int and long allowed."); 9827 } 9828 9829 /// 9830 @safe unittest 9831 { 9832 // Midnight, January 1st, 1970 UTC 9833 assert(stdTimeToUnixTime(621_355_968_000_000_000L) == 0); 9834 9835 // 2038-01-19 03:14:07 UTC 9836 assert(stdTimeToUnixTime(642_830_804_470_000_000L) == int.max); 9837 } 9838 9839 @safe unittest 9840 { 9841 enum unixEpochAsStdTime = (Date(1970, 1, 1) - Date.init).total!"hnsecs"; 9842 9843 assert(stdTimeToUnixTime(unixEpochAsStdTime) == 0); // Midnight, January 1st, 1970 9844 assert(stdTimeToUnixTime(unixEpochAsStdTime + 864_000_000_000L) == 86_400); // Midnight, January 2nd, 1970 9845 assert(stdTimeToUnixTime(unixEpochAsStdTime - 864_000_000_000L) == -86_400); // Midnight, December 31st, 1969 9846 9847 assert(stdTimeToUnixTime((Date(1970, 1, 1) - Date(1, 1, 1)).total!"hnsecs") == 0); 9848 assert(stdTimeToUnixTime((DateTime(1970, 1, 1) - DateTime(1, 1, 1)).total!"hnsecs") == 0); 9849 9850 foreach (dt; [DateTime(2010, 11, 1, 19, 5, 22), DateTime(1952, 7, 6, 2, 17, 9)]) 9851 assert(stdTimeToUnixTime((dt - DateTime.init).total!"hnsecs") == (dt - DateTime(1970, 1, 1)).total!"seconds"); 9852 9853 enum max = convert!("seconds", "hnsecs")(int.max); 9854 enum min = convert!("seconds", "hnsecs")(int.min); 9855 enum one = convert!("seconds", "hnsecs")(1); 9856 9857 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + max) == int.max); 9858 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + max) == int.max); 9859 9860 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + max + one) == int.max + 1L); 9861 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + max + one) == int.max); 9862 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + max + 9_999_999) == int.max); 9863 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + max + 9_999_999) == int.max); 9864 9865 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + min) == int.min); 9866 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + min) == int.min); 9867 9868 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + min - one) == int.min - 1L); 9869 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + min - one) == int.min); 9870 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + min - 9_999_999) == int.min); 9871 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + min - 9_999_999) == int.min); 9872 } 9873 9874 9875 version (StdDdoc) 9876 { 9877 version (Windows) 9878 {} 9879 else 9880 { 9881 alias SYSTEMTIME = void*; 9882 alias FILETIME = void*; 9883 } 9884 9885 /++ 9886 $(BLUE This function is Windows-Only.) 9887 9888 Converts a `SYSTEMTIME` struct to a $(LREF SysTime). 9889 9890 Params: 9891 st = The `SYSTEMTIME` struct to convert. 9892 tz = The time zone that the time in the `SYSTEMTIME` struct is 9893 assumed to be (if the `SYSTEMTIME` was supplied by a Windows 9894 system call, the `SYSTEMTIME` will either be in local time 9895 or UTC, depending on the call). 9896 9897 Throws: 9898 $(REF DateTimeException,std,datetime,date) if the given 9899 `SYSTEMTIME` will not fit in a $(LREF SysTime), which is highly 9900 unlikely to happen given that `SysTime.max` is in 29,228 A.D. and 9901 the maximum `SYSTEMTIME` is in 30,827 A.D. 9902 +/ 9903 SysTime SYSTEMTIMEToSysTime(const scope SYSTEMTIME* st, immutable TimeZone tz = LocalTime()) @safe; 9904 9905 9906 /++ 9907 $(BLUE This function is Windows-Only.) 9908 9909 Converts a $(LREF SysTime) to a `SYSTEMTIME` struct. 9910 9911 The `SYSTEMTIME` which is returned will be set using the given 9912 $(LREF SysTime)'s time zone, so to get the `SYSTEMTIME` in 9913 UTC, set the $(LREF SysTime)'s time zone to UTC. 9914 9915 Params: 9916 sysTime = The $(LREF SysTime) to convert. 9917 9918 Throws: 9919 $(REF DateTimeException,std,datetime,date) if the given 9920 $(LREF SysTime) will not fit in a `SYSTEMTIME`. This will only 9921 happen if the $(LREF SysTime)'s date is prior to 1601 A.D. 9922 +/ 9923 SYSTEMTIME SysTimeToSYSTEMTIME(scope SysTime sysTime) @safe; 9924 9925 9926 /++ 9927 $(BLUE This function is Windows-Only.) 9928 9929 Converts a `FILETIME` struct to the number of hnsecs since midnight, 9930 January 1st, 1 A.D. 9931 9932 Params: 9933 ft = The `FILETIME` struct to convert. 9934 9935 Throws: 9936 $(REF DateTimeException,std,datetime,date) if the given 9937 `FILETIME` cannot be represented as the return value. 9938 +/ 9939 long FILETIMEToStdTime(scope const FILETIME* ft) @safe; 9940 9941 9942 /++ 9943 $(BLUE This function is Windows-Only.) 9944 9945 Converts a `FILETIME` struct to a $(LREF SysTime). 9946 9947 Params: 9948 ft = The `FILETIME` struct to convert. 9949 tz = The time zone that the $(LREF SysTime) will be in 9950 (`FILETIME`s are in UTC). 9951 9952 Throws: 9953 $(REF DateTimeException,std,datetime,date) if the given 9954 `FILETIME` will not fit in a $(LREF SysTime). 9955 +/ 9956 SysTime FILETIMEToSysTime(scope const FILETIME* ft, immutable TimeZone tz = LocalTime()) @safe; 9957 9958 9959 /++ 9960 $(BLUE This function is Windows-Only.) 9961 9962 Converts a number of hnsecs since midnight, January 1st, 1 A.D. to a 9963 `FILETIME` struct. 9964 9965 Params: 9966 stdTime = The number of hnsecs since midnight, January 1st, 1 A.D. 9967 UTC. 9968 9969 Throws: 9970 $(REF DateTimeException,std,datetime,date) if the given value will 9971 not fit in a `FILETIME`. 9972 +/ 9973 FILETIME stdTimeToFILETIME(long stdTime) @safe; 9974 9975 9976 /++ 9977 $(BLUE This function is Windows-Only.) 9978 9979 Converts a $(LREF SysTime) to a `FILETIME` struct. 9980 9981 `FILETIME`s are always in UTC. 9982 9983 Params: 9984 sysTime = The $(LREF SysTime) to convert. 9985 9986 Throws: 9987 $(REF DateTimeException,std,datetime,date) if the given 9988 $(LREF SysTime) will not fit in a `FILETIME`. 9989 +/ 9990 FILETIME SysTimeToFILETIME(scope SysTime sysTime) @safe; 9991 } 9992 else version (Windows) 9993 { 9994 SysTime SYSTEMTIMEToSysTime(const scope SYSTEMTIME* st, immutable TimeZone tz = LocalTime()) @safe 9995 { 9996 const max = SysTime.max; 9997 9998 static void throwLaterThanMax() 9999 { 10000 throw new DateTimeException("The given SYSTEMTIME is for a date greater than SysTime.max."); 10001 } 10002 10003 if (st.wYear > max.year) 10004 throwLaterThanMax(); 10005 else if (st.wYear == max.year) 10006 { 10007 if (st.wMonth > max.month) 10008 throwLaterThanMax(); 10009 else if (st.wMonth == max.month) 10010 { 10011 if (st.wDay > max.day) 10012 throwLaterThanMax(); 10013 else if (st.wDay == max.day) 10014 { 10015 if (st.wHour > max.hour) 10016 throwLaterThanMax(); 10017 else if (st.wHour == max.hour) 10018 { 10019 if (st.wMinute > max.minute) 10020 throwLaterThanMax(); 10021 else if (st.wMinute == max.minute) 10022 { 10023 if (st.wSecond > max.second) 10024 throwLaterThanMax(); 10025 else if (st.wSecond == max.second) 10026 { 10027 if (st.wMilliseconds > max.fracSecs.total!"msecs") 10028 throwLaterThanMax(); 10029 } 10030 } 10031 } 10032 } 10033 } 10034 } 10035 10036 auto dt = DateTime(st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); 10037 10038 import core.time : msecs; 10039 return SysTime(dt, msecs(st.wMilliseconds), tz); 10040 } 10041 10042 @system unittest 10043 { 10044 auto sysTime = Clock.currTime(UTC()); 10045 SYSTEMTIME st = void; 10046 GetSystemTime(&st); 10047 auto converted = SYSTEMTIMEToSysTime(&st, UTC()); 10048 import core.time : abs; 10049 assert(abs((converted - sysTime)) <= dur!"seconds"(2)); 10050 10051 static void testScope(scope SYSTEMTIME* st) @safe 10052 { 10053 auto result = SYSTEMTIMEToSysTime(st); 10054 } 10055 } 10056 10057 10058 SYSTEMTIME SysTimeToSYSTEMTIME(scope SysTime sysTime) @safe 10059 { 10060 immutable dt = cast(DateTime) sysTime; 10061 10062 if (dt.year < 1601) 10063 throw new DateTimeException("SYSTEMTIME cannot hold dates prior to the year 1601."); 10064 10065 SYSTEMTIME st; 10066 10067 st.wYear = dt.year; 10068 st.wMonth = dt.month; 10069 st.wDayOfWeek = dt.dayOfWeek; 10070 st.wDay = dt.day; 10071 st.wHour = dt.hour; 10072 st.wMinute = dt.minute; 10073 st.wSecond = dt.second; 10074 st.wMilliseconds = cast(ushort) sysTime.fracSecs.total!"msecs"; 10075 10076 return st; 10077 } 10078 10079 @system unittest 10080 { 10081 SYSTEMTIME st = void; 10082 GetSystemTime(&st); 10083 auto sysTime = SYSTEMTIMEToSysTime(&st, UTC()); 10084 10085 SYSTEMTIME result = SysTimeToSYSTEMTIME(sysTime); 10086 10087 assert(st.wYear == result.wYear); 10088 assert(st.wMonth == result.wMonth); 10089 assert(st.wDayOfWeek == result.wDayOfWeek); 10090 assert(st.wDay == result.wDay); 10091 assert(st.wHour == result.wHour); 10092 assert(st.wMinute == result.wMinute); 10093 assert(st.wSecond == result.wSecond); 10094 assert(st.wMilliseconds == result.wMilliseconds); 10095 10096 static void testScope(scope ref SysTime st) @safe 10097 { 10098 auto localResult = SysTimeToSYSTEMTIME(st); 10099 } 10100 } 10101 10102 private enum hnsecsFrom1601 = 504_911_232_000_000_000L; 10103 10104 long FILETIMEToStdTime(scope const FILETIME* ft) @safe 10105 { 10106 ULARGE_INTEGER ul; 10107 ul.HighPart = ft.dwHighDateTime; 10108 ul.LowPart = ft.dwLowDateTime; 10109 ulong tempHNSecs = ul.QuadPart; 10110 10111 if (tempHNSecs > long.max - hnsecsFrom1601) 10112 throw new DateTimeException("The given FILETIME cannot be represented as a stdTime value."); 10113 10114 return cast(long) tempHNSecs + hnsecsFrom1601; 10115 } 10116 10117 SysTime FILETIMEToSysTime(scope const FILETIME* ft, immutable TimeZone tz = LocalTime()) @safe 10118 { 10119 auto sysTime = SysTime(FILETIMEToStdTime(ft), UTC()); 10120 sysTime.timezone = tz; 10121 return sysTime; 10122 } 10123 10124 @system unittest 10125 { 10126 auto sysTime = Clock.currTime(UTC()); 10127 SYSTEMTIME st = void; 10128 GetSystemTime(&st); 10129 10130 FILETIME ft = void; 10131 SystemTimeToFileTime(&st, &ft); 10132 10133 auto converted = FILETIMEToSysTime(&ft); 10134 10135 import core.time : abs; 10136 assert(abs((converted - sysTime)) <= dur!"seconds"(2)); 10137 10138 static void testScope(scope FILETIME* ft) @safe 10139 { 10140 auto result = FILETIMEToSysTime(ft); 10141 } 10142 } 10143 10144 10145 FILETIME stdTimeToFILETIME(long stdTime) @safe 10146 { 10147 if (stdTime < hnsecsFrom1601) 10148 throw new DateTimeException("The given stdTime value cannot be represented as a FILETIME."); 10149 10150 ULARGE_INTEGER ul; 10151 ul.QuadPart = cast(ulong) stdTime - hnsecsFrom1601; 10152 10153 FILETIME ft; 10154 ft.dwHighDateTime = ul.HighPart; 10155 ft.dwLowDateTime = ul.LowPart; 10156 10157 return ft; 10158 } 10159 10160 FILETIME SysTimeToFILETIME(scope SysTime sysTime) @safe 10161 { 10162 return stdTimeToFILETIME(sysTime.stdTime); 10163 } 10164 10165 @system unittest 10166 { 10167 SYSTEMTIME st = void; 10168 GetSystemTime(&st); 10169 10170 FILETIME ft = void; 10171 SystemTimeToFileTime(&st, &ft); 10172 auto sysTime = FILETIMEToSysTime(&ft, UTC()); 10173 10174 FILETIME result = SysTimeToFILETIME(sysTime); 10175 10176 assert(ft.dwLowDateTime == result.dwLowDateTime); 10177 assert(ft.dwHighDateTime == result.dwHighDateTime); 10178 10179 static void testScope(scope ref SysTime st) @safe 10180 { 10181 auto local_result = SysTimeToFILETIME(st); 10182 } 10183 } 10184 } 10185 10186 10187 /++ 10188 Type representing the DOS file date/time format. 10189 +/ 10190 alias DosFileTime = uint; 10191 10192 /++ 10193 Converts from DOS file date/time to $(LREF SysTime). 10194 10195 Params: 10196 dft = The DOS file time to convert. 10197 tz = The time zone which the DOS file time is assumed to be in. 10198 10199 Throws: 10200 $(REF DateTimeException,std,datetime,date) if the `DosFileTime` is 10201 invalid. 10202 +/ 10203 SysTime DosFileTimeToSysTime(DosFileTime dft, immutable TimeZone tz = LocalTime()) @safe 10204 { 10205 uint dt = cast(uint) dft; 10206 10207 if (dt == 0) 10208 throw new DateTimeException("Invalid DosFileTime."); 10209 10210 int year = ((dt >> 25) & 0x7F) + 1980; 10211 int month = ((dt >> 21) & 0x0F); // 1 .. 12 10212 int dayOfMonth = ((dt >> 16) & 0x1F); // 1 .. 31 10213 int hour = (dt >> 11) & 0x1F; // 0 .. 23 10214 int minute = (dt >> 5) & 0x3F; // 0 .. 59 10215 int second = (dt << 1) & 0x3E; // 0 .. 58 (in 2 second increments) 10216 10217 try 10218 return SysTime(DateTime(year, month, dayOfMonth, hour, minute, second), tz); 10219 catch (DateTimeException dte) 10220 throw new DateTimeException("Invalid DosFileTime", __FILE__, __LINE__, dte); 10221 } 10222 10223 /// 10224 @safe unittest 10225 { 10226 import std.datetime.date : DateTime; 10227 10228 assert(DosFileTimeToSysTime(0b00000000001000010000000000000000) == SysTime(DateTime(1980, 1, 1, 0, 0, 0))); 10229 assert(DosFileTimeToSysTime(0b11111111100111111011111101111101) == SysTime(DateTime(2107, 12, 31, 23, 59, 58))); 10230 assert(DosFileTimeToSysTime(0x3E3F8456) == SysTime(DateTime(2011, 1, 31, 16, 34, 44))); 10231 } 10232 10233 @safe unittest 10234 { 10235 static void testScope(scope ref DosFileTime dft) @safe 10236 { 10237 auto result = DosFileTimeToSysTime(dft); 10238 } 10239 } 10240 10241 10242 /++ 10243 Converts from $(LREF SysTime) to DOS file date/time. 10244 10245 Params: 10246 sysTime = The $(LREF SysTime) to convert. 10247 10248 Throws: 10249 $(REF DateTimeException,std,datetime,date) if the given 10250 $(LREF SysTime) cannot be converted to a `DosFileTime`. 10251 +/ 10252 DosFileTime SysTimeToDosFileTime(scope SysTime sysTime) @safe 10253 { 10254 auto dateTime = cast(DateTime) sysTime; 10255 10256 if (dateTime.year < 1980) 10257 throw new DateTimeException("DOS File Times cannot hold dates prior to 1980."); 10258 10259 if (dateTime.year > 2107) 10260 throw new DateTimeException("DOS File Times cannot hold dates past 2107."); 10261 10262 uint retval = 0; 10263 retval = (dateTime.year - 1980) << 25; 10264 retval |= (dateTime.month & 0x0F) << 21; 10265 retval |= (dateTime.day & 0x1F) << 16; 10266 retval |= (dateTime.hour & 0x1F) << 11; 10267 retval |= (dateTime.minute & 0x3F) << 5; 10268 retval |= (dateTime.second >> 1) & 0x1F; 10269 10270 return cast(DosFileTime) retval; 10271 } 10272 10273 /// 10274 @safe unittest 10275 { 10276 import std.datetime.date : DateTime; 10277 10278 assert(SysTimeToDosFileTime(SysTime(DateTime(1980, 1, 1, 0, 0, 0))) == 0b00000000001000010000000000000000); 10279 assert(SysTimeToDosFileTime(SysTime(DateTime(2107, 12, 31, 23, 59, 58))) == 0b11111111100111111011111101111101); 10280 assert(SysTimeToDosFileTime(SysTime(DateTime(2011, 1, 31, 16, 34, 44))) == 0x3E3F8456); 10281 } 10282 10283 @safe unittest 10284 { 10285 static void testScope(scope ref SysTime st) @safe 10286 { 10287 auto result = SysTimeToDosFileTime(st); 10288 } 10289 } 10290 10291 10292 /++ 10293 The given array of `char` or random-access range of `char` or 10294 `ubyte` is expected to be in the format specified in 10295 $(HTTP tools.ietf.org/html/rfc5322, RFC 5322) section 3.3 with the 10296 grammar rule $(I date-time). It is the date-time format commonly used in 10297 internet messages such as e-mail and HTTP. The corresponding 10298 $(LREF SysTime) will be returned. 10299 10300 RFC 822 was the original spec (hence the function's name), whereas RFC 5322 10301 is the current spec. 10302 10303 The day of the week is ignored beyond verifying that it's a valid day of the 10304 week, as the day of the week can be inferred from the date. It is not 10305 checked whether the given day of the week matches the actual day of the week 10306 of the given date (though it is technically invalid per the spec if the 10307 day of the week doesn't match the actual day of the week of the given date). 10308 10309 If the time zone is `"-0000"` (or considered to be equivalent to 10310 `"-0000"` by section 4.3 of the spec), a 10311 $(REF SimpleTimeZone,std,datetime,timezone) with a utc offset of `0` is 10312 used rather than $(REF UTC,std,datetime,timezone), whereas `"+0000"` uses 10313 $(REF UTC,std,datetime,timezone). 10314 10315 Note that because $(LREF SysTime) does not currently support having a second 10316 value of 60 (as is sometimes done for leap seconds), if the date-time value 10317 does have a value of 60 for the seconds, it is treated as 59. 10318 10319 The one area in which this function violates RFC 5322 is that it accepts 10320 `"\n"` in folding whitespace in the place of `"\r\n"`, because the 10321 HTTP spec requires it. 10322 10323 Throws: 10324 $(REF DateTimeException,std,datetime,date) if the given string doesn't 10325 follow the grammar for a date-time field or if the resulting 10326 $(LREF SysTime) is invalid. 10327 +/ 10328 SysTime parseRFC822DateTime()(scope const char[] value) @safe 10329 { 10330 import std.string : representation; 10331 return parseRFC822DateTime(value.representation); 10332 } 10333 10334 /++ Ditto +/ 10335 SysTime parseRFC822DateTime(R)(scope R value) 10336 if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && 10337 (is(immutable ElementType!R == immutable char) || is(immutable ElementType!R == immutable ubyte))) 10338 { 10339 import std.algorithm.searching : find, all; 10340 import std.ascii : isDigit, isAlpha, isPrintable; 10341 import std.conv : to; 10342 import std.functional : not; 10343 import std.string : capitalize, format; 10344 import std.traits : EnumMembers, isArray; 10345 import std.typecons : Rebindable; 10346 10347 void stripAndCheckLen(R valueBefore, size_t minLen, size_t line = __LINE__) 10348 { 10349 value = _stripCFWS(valueBefore); 10350 if (value.length < minLen) 10351 throw new DateTimeException("date-time value too short", __FILE__, line); 10352 } 10353 stripAndCheckLen(value, "7Dec1200:00A".length); 10354 10355 static if (isArray!R && (is(ElementEncodingType!R == char) || is(ElementEncodingType!R == ubyte))) 10356 { 10357 static string sliceAsString(R str) @trusted 10358 { 10359 return cast(string) str; 10360 } 10361 } 10362 else 10363 { 10364 char[4] temp; 10365 char[] sliceAsString(R str) @trusted 10366 { 10367 size_t i = 0; 10368 foreach (c; str) 10369 temp[i++] = cast(char) c; 10370 return temp[0 .. str.length]; 10371 } 10372 } 10373 10374 // day-of-week 10375 if (isAlpha(value[0])) 10376 { 10377 auto dowStr = sliceAsString(value[0 .. 3]); 10378 switch (dowStr) 10379 { 10380 foreach (dow; EnumMembers!DayOfWeek) 10381 { 10382 enum dowC = capitalize(to!string(dow)); 10383 case dowC: 10384 goto afterDoW; 10385 } 10386 default: throw new DateTimeException(format("Invalid day-of-week: %s", dowStr)); 10387 } 10388 afterDoW: stripAndCheckLen(value[3 .. value.length], ",7Dec1200:00A".length); 10389 if (value[0] != ',') 10390 throw new DateTimeException("day-of-week missing comma"); 10391 stripAndCheckLen(value[1 .. value.length], "7Dec1200:00A".length); 10392 } 10393 10394 // day 10395 immutable digits = isDigit(value[1]) ? 2 : 1; 10396 immutable day = _convDigits!short(value[0 .. digits]); 10397 if (day == -1) 10398 throw new DateTimeException("Invalid day"); 10399 stripAndCheckLen(value[digits .. value.length], "Dec1200:00A".length); 10400 10401 // month 10402 Month month; 10403 { 10404 auto monStr = sliceAsString(value[0 .. 3]); 10405 switch (monStr) 10406 { 10407 foreach (mon; EnumMembers!Month) 10408 { 10409 enum monC = capitalize(to!string(mon)); 10410 case monC: 10411 { 10412 month = mon; 10413 goto afterMon; 10414 } 10415 } 10416 default: throw new DateTimeException(format("Invalid month: %s", monStr)); 10417 } 10418 afterMon: stripAndCheckLen(value[3 .. value.length], "1200:00A".length); 10419 } 10420 10421 // year 10422 auto found = value[2 .. value.length].find!(not!(isDigit))(); 10423 size_t yearLen = value.length - found.length; 10424 if (found.length == 0) 10425 throw new DateTimeException("Invalid year"); 10426 if (found[0] == ':') 10427 yearLen -= 2; 10428 auto year = _convDigits!short(value[0 .. yearLen]); 10429 if (year < 1900) 10430 { 10431 if (year == -1) 10432 throw new DateTimeException("Invalid year"); 10433 if (yearLen < 4) 10434 { 10435 if (yearLen == 3) 10436 year += 1900; 10437 else if (yearLen == 2) 10438 year += year < 50 ? 2000 : 1900; 10439 else 10440 throw new DateTimeException("Invalid year. Too few digits."); 10441 } 10442 else 10443 throw new DateTimeException("Invalid year. Cannot be earlier than 1900."); 10444 } 10445 stripAndCheckLen(value[yearLen .. value.length], "00:00A".length); 10446 10447 // hour 10448 immutable hour = _convDigits!short(value[0 .. 2]); 10449 stripAndCheckLen(value[2 .. value.length], ":00A".length); 10450 if (value[0] != ':') 10451 throw new DateTimeException("Invalid hour"); 10452 stripAndCheckLen(value[1 .. value.length], "00A".length); 10453 10454 // minute 10455 immutable minute = _convDigits!short(value[0 .. 2]); 10456 stripAndCheckLen(value[2 .. value.length], "A".length); 10457 10458 // second 10459 short second; 10460 if (value[0] == ':') 10461 { 10462 stripAndCheckLen(value[1 .. value.length], "00A".length); 10463 second = _convDigits!short(value[0 .. 2]); 10464 // this is just if/until SysTime is sorted out to fully support leap seconds 10465 if (second == 60) 10466 second = 59; 10467 stripAndCheckLen(value[2 .. value.length], "A".length); 10468 } 10469 10470 immutable(TimeZone) parseTZ(int sign) 10471 { 10472 if (value.length < 5) 10473 throw new DateTimeException("Invalid timezone"); 10474 immutable zoneHours = _convDigits!short(value[1 .. 3]); 10475 immutable zoneMinutes = _convDigits!short(value[3 .. 5]); 10476 if (zoneHours == -1 || zoneMinutes == -1 || zoneMinutes > 59) 10477 throw new DateTimeException("Invalid timezone"); 10478 value = value[5 .. value.length]; 10479 immutable utcOffset = (dur!"hours"(zoneHours) + dur!"minutes"(zoneMinutes)) * sign; 10480 if (utcOffset == Duration.zero) 10481 { 10482 return sign == 1 ? cast(immutable(TimeZone))UTC() 10483 : cast(immutable(TimeZone))new immutable SimpleTimeZone(Duration.zero); 10484 } 10485 return new immutable(SimpleTimeZone)(utcOffset); 10486 } 10487 10488 // zone 10489 Rebindable!(immutable TimeZone) tz; 10490 if (value[0] == '-') 10491 tz = parseTZ(-1); 10492 else if (value[0] == '+') 10493 tz = parseTZ(1); 10494 else 10495 { 10496 // obs-zone 10497 immutable tzLen = value.length - find(value, ' ', '\t', '(')[0].length; 10498 switch (sliceAsString(value[0 .. tzLen <= 4 ? tzLen : 4])) 10499 { 10500 case "UT": case "GMT": tz = UTC(); break; 10501 case "EST": tz = new immutable SimpleTimeZone(dur!"hours"(-5)); break; 10502 case "EDT": tz = new immutable SimpleTimeZone(dur!"hours"(-4)); break; 10503 case "CST": tz = new immutable SimpleTimeZone(dur!"hours"(-6)); break; 10504 case "CDT": tz = new immutable SimpleTimeZone(dur!"hours"(-5)); break; 10505 case "MST": tz = new immutable SimpleTimeZone(dur!"hours"(-7)); break; 10506 case "MDT": tz = new immutable SimpleTimeZone(dur!"hours"(-6)); break; 10507 case "PST": tz = new immutable SimpleTimeZone(dur!"hours"(-8)); break; 10508 case "PDT": tz = new immutable SimpleTimeZone(dur!"hours"(-7)); break; 10509 case "J": case "j": throw new DateTimeException("Invalid timezone"); 10510 default: 10511 { 10512 if (all!(isAlpha)(value[0 .. tzLen])) 10513 { 10514 tz = new immutable SimpleTimeZone(Duration.zero); 10515 break; 10516 } 10517 throw new DateTimeException("Invalid timezone"); 10518 } 10519 } 10520 value = value[tzLen .. value.length]; 10521 } 10522 10523 // This is kind of arbitrary. Technically, nothing but CFWS is legal past 10524 // the end of the timezone, but we don't want to be picky about that in a 10525 // function that's just parsing rather than validating. So, the idea here is 10526 // that if the next character is printable (and not part of CFWS), then it 10527 // might be part of the timezone and thus affect what the timezone was 10528 // supposed to be, so we'll throw, but otherwise, we'll just ignore it. 10529 if (!value.empty && isPrintable(value[0]) && value[0] != ' ' && value[0] != '(') 10530 throw new DateTimeException("Invalid timezone"); 10531 10532 try 10533 return SysTime(DateTime(year, month, day, hour, minute, second), tz); 10534 catch (DateTimeException dte) 10535 throw new DateTimeException("date-time format is correct, but the resulting SysTime is invalid.", dte); 10536 } 10537 10538 /// 10539 @safe unittest 10540 { 10541 import core.time : hours; 10542 import std.datetime.date : DateTime, DateTimeException; 10543 import std.datetime.timezone : SimpleTimeZone, UTC; 10544 import std.exception : assertThrown; 10545 10546 auto tz = new immutable SimpleTimeZone(hours(-8)); 10547 assert(parseRFC822DateTime("Sat, 6 Jan 1990 12:14:19 -0800") == 10548 SysTime(DateTime(1990, 1, 6, 12, 14, 19), tz)); 10549 10550 assert(parseRFC822DateTime("9 Jul 2002 13:11 +0000") == 10551 SysTime(DateTime(2002, 7, 9, 13, 11, 0), UTC())); 10552 10553 auto badStr = "29 Feb 2001 12:17:16 +0200"; 10554 assertThrown!DateTimeException(parseRFC822DateTime(badStr)); 10555 } 10556 10557 version (StdUnittest) private void testParse822(alias cr)(string str, SysTime expected, size_t line = __LINE__) 10558 { 10559 import std.format : format; 10560 auto value = cr(str); 10561 auto result = parseRFC822DateTime(value); 10562 if (result != expected) 10563 throw new AssertError(format("wrong result. expected [%s], actual[%s]", expected, result), __FILE__, line); 10564 } 10565 10566 version (StdUnittest) private void testBadParse822(alias cr)(string str, size_t line = __LINE__) 10567 { 10568 try 10569 parseRFC822DateTime(cr(str)); 10570 catch (DateTimeException) 10571 return; 10572 throw new AssertError("No DateTimeException was thrown", __FILE__, line); 10573 } 10574 10575 @system unittest 10576 { 10577 import core.time; 10578 import std.algorithm.iteration : filter, map; 10579 import std.algorithm.searching : canFind; 10580 import std.array : array; 10581 import std.ascii : letters; 10582 import std.format : format; 10583 import std.meta : AliasSeq; 10584 import std.range : chain, iota, take; 10585 import std.stdio : writefln, writeln; 10586 import std.string : representation; 10587 10588 static struct Rand3Letters 10589 { 10590 enum empty = false; 10591 @property auto front() { return _mon; } 10592 void popFront() 10593 { 10594 import std.exception : assumeUnique; 10595 import std.random : rndGen; 10596 _mon = rndGen.map!(a => letters[a % letters.length])().take(3).array().assumeUnique(); 10597 } 10598 string _mon; 10599 static auto start() { Rand3Letters retval; retval.popFront(); return retval; } 10600 } 10601 10602 static foreach (cr; AliasSeq!(function(string a){return cast(char[]) a;}, 10603 function(string a){return cast(ubyte[]) a;}, 10604 function(string a){return a;}, 10605 function(string a){return map!(b => cast(char) b)(a.representation);})) 10606 {(){ // workaround slow optimizations for large functions 10607 // https://issues.dlang.org/show_bug.cgi?id=2396 10608 scope(failure) writeln(typeof(cr).stringof); 10609 alias test = testParse822!cr; 10610 alias testBad = testBadParse822!cr; 10611 10612 immutable std1 = DateTime(2012, 12, 21, 13, 14, 15); 10613 immutable std2 = DateTime(2012, 12, 21, 13, 14, 0); 10614 immutable dst1 = DateTime(1976, 7, 4, 5, 4, 22); 10615 immutable dst2 = DateTime(1976, 7, 4, 5, 4, 0); 10616 10617 test("21 Dec 2012 13:14:15 +0000", SysTime(std1, UTC())); 10618 test("21 Dec 2012 13:14 +0000", SysTime(std2, UTC())); 10619 test("Fri, 21 Dec 2012 13:14 +0000", SysTime(std2, UTC())); 10620 test("Fri, 21 Dec 2012 13:14:15 +0000", SysTime(std1, UTC())); 10621 10622 test("04 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC())); 10623 test("04 Jul 1976 05:04 +0000", SysTime(dst2, UTC())); 10624 test("Sun, 04 Jul 1976 05:04 +0000", SysTime(dst2, UTC())); 10625 test("Sun, 04 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC())); 10626 10627 test("4 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC())); 10628 test("4 Jul 1976 05:04 +0000", SysTime(dst2, UTC())); 10629 test("Sun, 4 Jul 1976 05:04 +0000", SysTime(dst2, UTC())); 10630 test("Sun, 4 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC())); 10631 10632 auto badTZ = new immutable SimpleTimeZone(Duration.zero); 10633 test("21 Dec 2012 13:14:15 -0000", SysTime(std1, badTZ)); 10634 test("21 Dec 2012 13:14 -0000", SysTime(std2, badTZ)); 10635 test("Fri, 21 Dec 2012 13:14 -0000", SysTime(std2, badTZ)); 10636 test("Fri, 21 Dec 2012 13:14:15 -0000", SysTime(std1, badTZ)); 10637 10638 test("04 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ)); 10639 test("04 Jul 1976 05:04 -0000", SysTime(dst2, badTZ)); 10640 test("Sun, 04 Jul 1976 05:04 -0000", SysTime(dst2, badTZ)); 10641 test("Sun, 04 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ)); 10642 10643 test("4 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ)); 10644 test("4 Jul 1976 05:04 -0000", SysTime(dst2, badTZ)); 10645 test("Sun, 4 Jul 1976 05:04 -0000", SysTime(dst2, badTZ)); 10646 test("Sun, 4 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ)); 10647 10648 auto pst = new immutable SimpleTimeZone(dur!"hours"(-8)); 10649 auto pdt = new immutable SimpleTimeZone(dur!"hours"(-7)); 10650 test("21 Dec 2012 13:14:15 -0800", SysTime(std1, pst)); 10651 test("21 Dec 2012 13:14 -0800", SysTime(std2, pst)); 10652 test("Fri, 21 Dec 2012 13:14 -0800", SysTime(std2, pst)); 10653 test("Fri, 21 Dec 2012 13:14:15 -0800", SysTime(std1, pst)); 10654 10655 test("04 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt)); 10656 test("04 Jul 1976 05:04 -0700", SysTime(dst2, pdt)); 10657 test("Sun, 04 Jul 1976 05:04 -0700", SysTime(dst2, pdt)); 10658 test("Sun, 04 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt)); 10659 10660 test("4 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt)); 10661 test("4 Jul 1976 05:04 -0700", SysTime(dst2, pdt)); 10662 test("Sun, 4 Jul 1976 05:04 -0700", SysTime(dst2, pdt)); 10663 test("Sun, 4 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt)); 10664 10665 auto cet = new immutable SimpleTimeZone(dur!"hours"(1)); 10666 auto cest = new immutable SimpleTimeZone(dur!"hours"(2)); 10667 test("21 Dec 2012 13:14:15 +0100", SysTime(std1, cet)); 10668 test("21 Dec 2012 13:14 +0100", SysTime(std2, cet)); 10669 test("Fri, 21 Dec 2012 13:14 +0100", SysTime(std2, cet)); 10670 test("Fri, 21 Dec 2012 13:14:15 +0100", SysTime(std1, cet)); 10671 10672 test("04 Jul 1976 05:04:22 +0200", SysTime(dst1, cest)); 10673 test("04 Jul 1976 05:04 +0200", SysTime(dst2, cest)); 10674 test("Sun, 04 Jul 1976 05:04 +0200", SysTime(dst2, cest)); 10675 test("Sun, 04 Jul 1976 05:04:22 +0200", SysTime(dst1, cest)); 10676 10677 test("4 Jul 1976 05:04:22 +0200", SysTime(dst1, cest)); 10678 test("4 Jul 1976 05:04 +0200", SysTime(dst2, cest)); 10679 test("Sun, 4 Jul 1976 05:04 +0200", SysTime(dst2, cest)); 10680 test("Sun, 4 Jul 1976 05:04:22 +0200", SysTime(dst1, cest)); 10681 10682 // dst and std times are switched in the Southern Hemisphere which is why the 10683 // time zone names and DateTime variables don't match. 10684 auto cstStd = new immutable SimpleTimeZone(dur!"hours"(9) + dur!"minutes"(30)); 10685 auto cstDST = new immutable SimpleTimeZone(dur!"hours"(10) + dur!"minutes"(30)); 10686 test("21 Dec 2012 13:14:15 +1030", SysTime(std1, cstDST)); 10687 test("21 Dec 2012 13:14 +1030", SysTime(std2, cstDST)); 10688 test("Fri, 21 Dec 2012 13:14 +1030", SysTime(std2, cstDST)); 10689 test("Fri, 21 Dec 2012 13:14:15 +1030", SysTime(std1, cstDST)); 10690 10691 test("04 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 10692 test("04 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 10693 test("Sun, 04 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 10694 test("Sun, 04 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 10695 10696 test("4 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 10697 test("4 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 10698 test("Sun, 4 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 10699 test("Sun, 4 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 10700 10701 foreach (int i, mon; _monthNames) 10702 { 10703 test(format("17 %s 2012 00:05:02 +0000", mon), SysTime(DateTime(2012, i + 1, 17, 0, 5, 2), UTC())); 10704 test(format("17 %s 2012 00:05 +0000", mon), SysTime(DateTime(2012, i + 1, 17, 0, 5, 0), UTC())); 10705 } 10706 10707 import std.uni : toLower, toUpper; 10708 foreach (mon; chain(_monthNames[].map!(a => toLower(a))(), 10709 _monthNames[].map!(a => toUpper(a))(), 10710 ["Jam", "Jen", "Fec", "Fdb", "Mas", "Mbr", "Aps", "Aqr", "Mai", "Miy", 10711 "Jum", "Jbn", "Jup", "Jal", "Aur", "Apg", "Sem", "Sap", "Ocm", "Odt", 10712 "Nom", "Nav", "Dem", "Dac"], 10713 Rand3Letters.start().filter!(a => !_monthNames[].canFind(a)).take(20))) 10714 { 10715 scope(failure) writefln("Month: %s", mon); 10716 testBad(format("17 %s 2012 00:05:02 +0000", mon)); 10717 testBad(format("17 %s 2012 00:05 +0000", mon)); 10718 } 10719 10720 immutable string[7] daysOfWeekNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; 10721 10722 { 10723 auto start = SysTime(DateTime(2012, 11, 11, 9, 42, 0), UTC()); 10724 int day = 11; 10725 10726 foreach (int i, dow; daysOfWeekNames) 10727 { 10728 auto curr = start + dur!"days"(i); 10729 test(format("%s, %s Nov 2012 09:42:00 +0000", dow, day), curr); 10730 test(format("%s, %s Nov 2012 09:42 +0000", dow, day++), curr); 10731 10732 // Whether the day of the week matches the date is ignored. 10733 test(format("%s, 11 Nov 2012 09:42:00 +0000", dow), start); 10734 test(format("%s, 11 Nov 2012 09:42 +0000", dow), start); 10735 } 10736 } 10737 10738 foreach (dow; chain(daysOfWeekNames[].map!(a => toLower(a))(), 10739 daysOfWeekNames[].map!(a => toUpper(a))(), 10740 ["Sum", "Spn", "Mom", "Man", "Tuf", "Tae", "Wem", "Wdd", "The", "Tur", 10741 "Fro", "Fai", "San", "Sut"], 10742 Rand3Letters.start().filter!(a => !daysOfWeekNames[].canFind(a)).take(20))) 10743 { 10744 scope(failure) writefln("Day of Week: %s", dow); 10745 testBad(format("%s, 11 Nov 2012 09:42:00 +0000", dow)); 10746 testBad(format("%s, 11 Nov 2012 09:42 +0000", dow)); 10747 } 10748 10749 testBad("31 Dec 1899 23:59:59 +0000"); 10750 test("01 Jan 1900 00:00:00 +0000", SysTime(Date(1900, 1, 1), UTC())); 10751 test("01 Jan 1900 00:00:00 -0000", SysTime(Date(1900, 1, 1), 10752 new immutable SimpleTimeZone(Duration.zero))); 10753 test("01 Jan 1900 00:00:00 -0700", SysTime(Date(1900, 1, 1), 10754 new immutable SimpleTimeZone(dur!"hours"(-7)))); 10755 10756 { 10757 auto st1 = SysTime(Date(1900, 1, 1), UTC()); 10758 auto st2 = SysTime(Date(1900, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-11))); 10759 foreach (i; 1900 .. 2102) 10760 { 10761 test(format("1 Jan %05d 00:00 +0000", i), st1); 10762 test(format("1 Jan %05d 00:00 -1100", i), st2); 10763 st1.add!"years"(1); 10764 st2.add!"years"(1); 10765 } 10766 st1.year = 9998; 10767 st2.year = 9998; 10768 foreach (i; 9998 .. 11_002) 10769 { 10770 test(format("1 Jan %05d 00:00 +0000", i), st1); 10771 test(format("1 Jan %05d 00:00 -1100", i), st2); 10772 st1.add!"years"(1); 10773 st2.add!"years"(1); 10774 } 10775 } 10776 10777 testBad("12 Feb 1907 23:17:09 0000"); 10778 testBad("12 Feb 1907 23:17:09 +000"); 10779 testBad("12 Feb 1907 23:17:09 -000"); 10780 testBad("12 Feb 1907 23:17:09 +00000"); 10781 testBad("12 Feb 1907 23:17:09 -00000"); 10782 testBad("12 Feb 1907 23:17:09 +A"); 10783 testBad("12 Feb 1907 23:17:09 +PST"); 10784 testBad("12 Feb 1907 23:17:09 -A"); 10785 testBad("12 Feb 1907 23:17:09 -PST"); 10786 10787 // test trailing stuff that gets ignored 10788 { 10789 foreach (c; chain(iota(0, 33), ['('], iota(127, ubyte.max + 1))) 10790 { 10791 scope(failure) writefln("c: %d", c); 10792 test(format("21 Dec 2012 13:14:15 +0000%c", cast(char) c), SysTime(std1, UTC())); 10793 test(format("21 Dec 2012 13:14:15 +0000%c ", cast(char) c), SysTime(std1, UTC())); 10794 test(format("21 Dec 2012 13:14:15 +0000%chello", cast(char) c), SysTime(std1, UTC())); 10795 } 10796 } 10797 10798 // test trailing stuff that doesn't get ignored 10799 { 10800 foreach (c; chain(iota(33, '('), iota('(' + 1, 127))) 10801 { 10802 scope(failure) writefln("c: %d", c); 10803 testBad(format("21 Dec 2012 13:14:15 +0000%c", cast(char) c)); 10804 testBad(format("21 Dec 2012 13:14:15 +0000%c ", cast(char) c)); 10805 testBad(format("21 Dec 2012 13:14:15 +0000%chello", cast(char) c)); 10806 } 10807 } 10808 10809 testBad("32 Jan 2012 12:13:14 -0800"); 10810 testBad("31 Jan 2012 24:13:14 -0800"); 10811 testBad("31 Jan 2012 12:60:14 -0800"); 10812 testBad("31 Jan 2012 12:13:61 -0800"); 10813 testBad("31 Jan 2012 12:13:14 -0860"); 10814 test("31 Jan 2012 12:13:14 -0859", 10815 SysTime(DateTime(2012, 1, 31, 12, 13, 14), 10816 new immutable SimpleTimeZone(dur!"hours"(-8) + dur!"minutes"(-59)))); 10817 10818 // leap-seconds 10819 test("21 Dec 2012 15:59:60 -0800", SysTime(DateTime(2012, 12, 21, 15, 59, 59), pst)); 10820 10821 // FWS 10822 test("Sun,4 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 10823 test("Sun,4 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 10824 test("Sun,4 Jul 1976 05:04 +0930 (foo)", SysTime(dst2, cstStd)); 10825 test("Sun,4 Jul 1976 05:04:22 +0930 (foo)", SysTime(dst1, cstStd)); 10826 test("Sun,4 \r\n Jul \r\n 1976 \r\n 05:04 \r\n +0930 \r\n (foo)", SysTime(dst2, cstStd)); 10827 test("Sun,4 \r\n Jul \r\n 1976 \r\n 05:04:22 \r\n +0930 \r\n (foo)", SysTime(dst1, cstStd)); 10828 10829 auto str = "01 Jan 2012 12:13:14 -0800 "; 10830 test(str, SysTime(DateTime(2012, 1, 1, 12, 13, 14), new immutable SimpleTimeZone(hours(-8)))); 10831 foreach (i; 0 .. str.length) 10832 { 10833 auto currStr = str.dup; 10834 currStr[i] = 'x'; 10835 scope(failure) writefln("failed: %s", currStr); 10836 testBad(cast(string) currStr); 10837 } 10838 foreach (i; 2 .. str.length) 10839 { 10840 auto currStr = str[0 .. $ - i]; 10841 scope(failure) writefln("failed: %s", currStr); 10842 testBad(cast(string) currStr); 10843 testBad((cast(string) currStr) ~ " "); 10844 } 10845 }();} 10846 10847 static void testScope(scope ref string str) @safe 10848 { 10849 auto result = parseRFC822DateTime(str); 10850 } 10851 } 10852 10853 // Obsolete Format per section 4.3 of RFC 5322. 10854 @system unittest 10855 { 10856 import std.algorithm.iteration : filter, map; 10857 import std.ascii : letters; 10858 import std.exception : collectExceptionMsg; 10859 import std.format : format; 10860 import std.meta : AliasSeq; 10861 import std.range : chain, iota; 10862 import std.stdio : writefln, writeln; 10863 import std.string : representation; 10864 10865 auto std1 = SysTime(DateTime(2012, 12, 21, 13, 14, 15), UTC()); 10866 auto std2 = SysTime(DateTime(2012, 12, 21, 13, 14, 0), UTC()); 10867 auto std3 = SysTime(DateTime(1912, 12, 21, 13, 14, 15), UTC()); 10868 auto std4 = SysTime(DateTime(1912, 12, 21, 13, 14, 0), UTC()); 10869 auto dst1 = SysTime(DateTime(1976, 7, 4, 5, 4, 22), UTC()); 10870 auto dst2 = SysTime(DateTime(1976, 7, 4, 5, 4, 0), UTC()); 10871 auto tooLate1 = SysTime(Date(10_000, 1, 1), UTC()); 10872 auto tooLate2 = SysTime(DateTime(12_007, 12, 31, 12, 22, 19), UTC()); 10873 10874 static foreach (cr; AliasSeq!(function(string a){return cast(char[]) a;}, 10875 function(string a){return cast(ubyte[]) a;}, 10876 function(string a){return a;}, 10877 function(string a){return map!(b => cast(char) b)(a.representation);})) 10878 {(){ // workaround slow optimizations for large functions 10879 // https://issues.dlang.org/show_bug.cgi?id=2396 10880 scope(failure) writeln(typeof(cr).stringof); 10881 alias test = testParse822!cr; 10882 { 10883 auto list = ["", " ", " \r\n\t", "\t\r\n (hello world( frien(dog)) silly \r\n ) \t\t \r\n ()", 10884 " \n ", "\t\n\t", " \n\t (foo) \n (bar) \r\n (baz) \n "]; 10885 10886 foreach (i, cfws; list) 10887 { 10888 scope(failure) writefln("i: %s", i); 10889 10890 test(format("%1$s21%1$sDec%1$s2012%1$s13:14:15%1$s+0000%1$s", cfws), std1); 10891 test(format("%1$s21%1$sDec%1$s2012%1$s13:14%1$s+0000%1$s", cfws), std2); 10892 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s2012%1$s13:14%1$s+0000%1$s", cfws), std2); 10893 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s2012%1$s13:14:15%1$s+0000%1$s", cfws), std1); 10894 10895 test(format("%1$s04%1$sJul%1$s1976%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10896 test(format("%1$s04%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2); 10897 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2); 10898 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s1976%1$s05:04:22 +0000%1$s", cfws), dst1); 10899 10900 test(format("%1$s4%1$sJul%1$s1976%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10901 test(format("%1$s4%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2); 10902 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2); 10903 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s1976%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10904 10905 test(format("%1$s21%1$sDec%1$s12%1$s13:14:15%1$s+0000%1$s", cfws), std1); 10906 test(format("%1$s21%1$sDec%1$s12%1$s13:14%1$s+0000%1$s", cfws), std2); 10907 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s12%1$s13:14%1$s+0000%1$s", cfws), std2); 10908 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s12%1$s13:14:15%1$s+0000%1$s", cfws), std1); 10909 10910 test(format("%1$s04%1$sJul%1$s76%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10911 test(format("%1$s04%1$sJul%1$s76%1$s05:04%1$s+0000%1$s", cfws), dst2); 10912 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s76%1$s05:04%1$s+0000%1$s", cfws), dst2); 10913 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s76%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10914 10915 test(format("%1$s4%1$sJul%1$s76 05:04:22%1$s+0000%1$s", cfws), dst1); 10916 test(format("%1$s4%1$sJul%1$s76 05:04%1$s+0000%1$s", cfws), dst2); 10917 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s76%1$s05:04%1$s+0000%1$s", cfws), dst2); 10918 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s76%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10919 10920 test(format("%1$s21%1$sDec%1$s012%1$s13:14:15%1$s+0000%1$s", cfws), std3); 10921 test(format("%1$s21%1$sDec%1$s012%1$s13:14%1$s+0000%1$s", cfws), std4); 10922 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s012%1$s13:14%1$s+0000%1$s", cfws), std4); 10923 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s012%1$s13:14:15%1$s+0000%1$s", cfws), std3); 10924 10925 test(format("%1$s04%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10926 test(format("%1$s04%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2); 10927 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2); 10928 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10929 10930 test(format("%1$s4%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10931 test(format("%1$s4%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2); 10932 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2); 10933 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10934 10935 test(format("%1$s1%1$sJan%1$s10000%1$s00:00:00%1$s+0000%1$s", cfws), tooLate1); 10936 test(format("%1$s31%1$sDec%1$s12007%1$s12:22:19%1$s+0000%1$s", cfws), tooLate2); 10937 test(format("%1$sSat%1$s,%1$s1%1$sJan%1$s10000%1$s00:00:00%1$s+0000%1$s", cfws), tooLate1); 10938 test(format("%1$sSun%1$s,%1$s31%1$sDec%1$s12007%1$s12:22:19%1$s+0000%1$s", cfws), tooLate2); 10939 } 10940 } 10941 10942 // test years of 1, 2, and 3 digits. 10943 { 10944 auto st1 = SysTime(Date(2000, 1, 1), UTC()); 10945 auto st2 = SysTime(Date(2000, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-12))); 10946 foreach (i; 0 .. 50) 10947 { 10948 test(format("1 Jan %02d 00:00 GMT", i), st1); 10949 test(format("1 Jan %02d 00:00 -1200", i), st2); 10950 st1.add!"years"(1); 10951 st2.add!"years"(1); 10952 } 10953 } 10954 10955 { 10956 auto st1 = SysTime(Date(1950, 1, 1), UTC()); 10957 auto st2 = SysTime(Date(1950, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-12))); 10958 foreach (i; 50 .. 100) 10959 { 10960 test(format("1 Jan %02d 00:00 GMT", i), st1); 10961 test(format("1 Jan %02d 00:00 -1200", i), st2); 10962 st1.add!"years"(1); 10963 st2.add!"years"(1); 10964 } 10965 } 10966 10967 { 10968 auto st1 = SysTime(Date(1900, 1, 1), UTC()); 10969 auto st2 = SysTime(Date(1900, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-11))); 10970 foreach (i; 0 .. 1000) 10971 { 10972 test(format("1 Jan %03d 00:00 GMT", i), st1); 10973 test(format("1 Jan %03d 00:00 -1100", i), st2); 10974 st1.add!"years"(1); 10975 st2.add!"years"(1); 10976 } 10977 } 10978 10979 foreach (i; 0 .. 10) 10980 { 10981 auto str1 = cr(format("1 Jan %d 00:00 GMT", i)); 10982 auto str2 = cr(format("1 Jan %d 00:00 -1200", i)); 10983 assertThrown!DateTimeException(parseRFC822DateTime(str1)); 10984 assertThrown!DateTimeException(parseRFC822DateTime(str1)); 10985 } 10986 10987 // test time zones 10988 { 10989 auto dt = DateTime(1982, 5, 3, 12, 22, 4); 10990 test("Wed, 03 May 1982 12:22:04 UT", SysTime(dt, UTC())); 10991 test("Wed, 03 May 1982 12:22:04 GMT", SysTime(dt, UTC())); 10992 test("Wed, 03 May 1982 12:22:04 EST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-5)))); 10993 test("Wed, 03 May 1982 12:22:04 EDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-4)))); 10994 test("Wed, 03 May 1982 12:22:04 CST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-6)))); 10995 test("Wed, 03 May 1982 12:22:04 CDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-5)))); 10996 test("Wed, 03 May 1982 12:22:04 MST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-7)))); 10997 test("Wed, 03 May 1982 12:22:04 MDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-6)))); 10998 test("Wed, 03 May 1982 12:22:04 PST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-8)))); 10999 test("Wed, 03 May 1982 12:22:04 PDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-7)))); 11000 11001 auto badTZ = new immutable SimpleTimeZone(Duration.zero); 11002 foreach (dchar c; filter!(a => a != 'j' && a != 'J')(letters)) 11003 { 11004 scope(failure) writefln("c: %s", c); 11005 test(format("Wed, 03 May 1982 12:22:04 %s", c), SysTime(dt, badTZ)); 11006 test(format("Wed, 03 May 1982 12:22:04%s", c), SysTime(dt, badTZ)); 11007 } 11008 11009 foreach (dchar c; ['j', 'J']) 11010 { 11011 scope(failure) writefln("c: %s", c); 11012 assertThrown!DateTimeException(parseRFC822DateTime(cr(format("Wed, 03 May 1982 12:22:04 %s", c)))); 11013 assertThrown!DateTimeException(parseRFC822DateTime(cr(format("Wed, 03 May 1982 12:22:04%s", c)))); 11014 } 11015 11016 foreach (string s; ["AAA", "GQW", "DDT", "PDA", "GT", "GM"]) 11017 { 11018 scope(failure) writefln("s: %s", s); 11019 test(format("Wed, 03 May 1982 12:22:04 %s", s), SysTime(dt, badTZ)); 11020 } 11021 11022 // test trailing stuff that gets ignored 11023 { 11024 foreach (c; chain(iota(0, 33), ['('], iota(127, ubyte.max + 1))) 11025 { 11026 scope(failure) writefln("c: %d", c); 11027 test(format("21Dec1213:14:15+0000%c", cast(char) c), std1); 11028 test(format("21Dec1213:14:15+0000%c ", cast(char) c), std1); 11029 test(format("21Dec1213:14:15+0000%chello", cast(char) c), std1); 11030 } 11031 } 11032 11033 // test trailing stuff that doesn't get ignored 11034 { 11035 foreach (c; chain(iota(33, '('), iota('(' + 1, 127))) 11036 { 11037 scope(failure) writefln("c: %d", c); 11038 assertThrown!DateTimeException( 11039 parseRFC822DateTime(cr(format("21Dec1213:14:15+0000%c", cast(char) c)))); 11040 assertThrown!DateTimeException( 11041 parseRFC822DateTime(cr(format("21Dec1213:14:15+0000%c ", cast(char) c)))); 11042 assertThrown!DateTimeException( 11043 parseRFC822DateTime(cr(format("21Dec1213:14:15+0000%chello", cast(char) c)))); 11044 } 11045 } 11046 } 11047 11048 // test that the checks for minimum length work correctly and avoid 11049 // any RangeErrors. 11050 test("7Dec1200:00A", SysTime(DateTime(2012, 12, 7, 0, 0, 0), 11051 new immutable SimpleTimeZone(Duration.zero))); 11052 test("Fri,7Dec1200:00A", SysTime(DateTime(2012, 12, 7, 0, 0, 0), 11053 new immutable SimpleTimeZone(Duration.zero))); 11054 test("7Dec1200:00:00A", SysTime(DateTime(2012, 12, 7, 0, 0, 0), 11055 new immutable SimpleTimeZone(Duration.zero))); 11056 test("Fri,7Dec1200:00:00A", SysTime(DateTime(2012, 12, 7, 0, 0, 0), 11057 new immutable SimpleTimeZone(Duration.zero))); 11058 11059 auto tooShortMsg = collectExceptionMsg!DateTimeException(parseRFC822DateTime("")); 11060 foreach (str; ["Fri,7Dec1200:00:00", "7Dec1200:00:00"]) 11061 { 11062 foreach (i; 0 .. str.length) 11063 { 11064 auto value = str[0 .. $ - i]; 11065 scope(failure) writeln(value); 11066 assert(collectExceptionMsg!DateTimeException(parseRFC822DateTime(value)) == tooShortMsg); 11067 } 11068 } 11069 }();} 11070 } 11071 11072 11073 private: 11074 11075 /+ 11076 Returns the given hnsecs as an ISO string of fractional seconds. 11077 +/ 11078 string fracSecsToISOString(int hnsecs, int prec = -1) @safe pure nothrow 11079 { 11080 import std.array : appender; 11081 auto w = appender!string(); 11082 try 11083 fracSecsToISOString(w, hnsecs, prec); 11084 catch (Exception e) 11085 assert(0, "fracSecsToISOString() threw."); 11086 return w.data; 11087 } 11088 11089 void fracSecsToISOString(W)(ref W writer, int hnsecs, int prec = -1) 11090 { 11091 import std.conv : toChars; 11092 import std.range : padLeft; 11093 11094 assert(hnsecs >= 0); 11095 11096 if (prec == 0) 11097 return; 11098 11099 if (hnsecs == 0) 11100 return; 11101 11102 put(writer, '.'); 11103 auto chars = hnsecs.toChars.padLeft('0', 7); 11104 11105 if (prec == -1) 11106 { 11107 while (chars.back == '0') 11108 chars.popBack(); 11109 put(writer, chars); 11110 } 11111 else 11112 put(writer, chars[0 .. prec]); 11113 } 11114 11115 @safe unittest 11116 { 11117 assert(fracSecsToISOString(0) == ""); 11118 assert(fracSecsToISOString(1) == ".0000001"); 11119 assert(fracSecsToISOString(10) == ".000001"); 11120 assert(fracSecsToISOString(100) == ".00001"); 11121 assert(fracSecsToISOString(1000) == ".0001"); 11122 assert(fracSecsToISOString(10_000) == ".001"); 11123 assert(fracSecsToISOString(100_000) == ".01"); 11124 assert(fracSecsToISOString(1_000_000) == ".1"); 11125 assert(fracSecsToISOString(1_000_001) == ".1000001"); 11126 assert(fracSecsToISOString(1_001_001) == ".1001001"); 11127 assert(fracSecsToISOString(1_071_601) == ".1071601"); 11128 assert(fracSecsToISOString(1_271_641) == ".1271641"); 11129 assert(fracSecsToISOString(9_999_999) == ".9999999"); 11130 assert(fracSecsToISOString(9_999_990) == ".999999"); 11131 assert(fracSecsToISOString(9_999_900) == ".99999"); 11132 assert(fracSecsToISOString(9_999_000) == ".9999"); 11133 assert(fracSecsToISOString(9_990_000) == ".999"); 11134 assert(fracSecsToISOString(9_900_000) == ".99"); 11135 assert(fracSecsToISOString(9_000_000) == ".9"); 11136 assert(fracSecsToISOString(999) == ".0000999"); 11137 assert(fracSecsToISOString(9990) == ".000999"); 11138 assert(fracSecsToISOString(99_900) == ".00999"); 11139 assert(fracSecsToISOString(999_000) == ".0999"); 11140 } 11141 11142 11143 /+ 11144 Returns a Duration corresponding to to the given ISO string of 11145 fractional seconds. 11146 +/ 11147 static Duration fracSecsFromISOString(S)(scope const S isoString) @safe pure 11148 if (isSomeString!S) 11149 { 11150 import std.algorithm.searching : all; 11151 import std.ascii : isDigit; 11152 import std.conv : to; 11153 import std.string : representation; 11154 11155 if (isoString.empty) 11156 return Duration.zero; 11157 11158 auto str = isoString.representation; 11159 11160 enforce(str[0] == '.', new DateTimeException("Invalid ISO String")); 11161 str.popFront(); 11162 11163 enforce(!str.empty && all!isDigit(str), new DateTimeException("Invalid ISO String")); 11164 11165 dchar[7] fullISOString = void; 11166 foreach (i, ref dchar c; fullISOString) 11167 { 11168 if (i < str.length) 11169 c = str[i]; 11170 else 11171 c = '0'; 11172 } 11173 11174 return hnsecs(to!int(fullISOString[])); 11175 } 11176 11177 @safe unittest 11178 { 11179 import core.time; 11180 static void testFSInvalid(string isoString) 11181 { 11182 fracSecsFromISOString(isoString); 11183 } 11184 11185 assertThrown!DateTimeException(testFSInvalid(".")); 11186 assertThrown!DateTimeException(testFSInvalid("0.")); 11187 assertThrown!DateTimeException(testFSInvalid("0")); 11188 assertThrown!DateTimeException(testFSInvalid("0000000")); 11189 assertThrown!DateTimeException(testFSInvalid("T")); 11190 assertThrown!DateTimeException(testFSInvalid("T.")); 11191 assertThrown!DateTimeException(testFSInvalid(".T")); 11192 assertThrown!DateTimeException(testFSInvalid(".00000Q0")); 11193 assertThrown!DateTimeException(testFSInvalid(".000000Q")); 11194 assertThrown!DateTimeException(testFSInvalid(".0000000Q")); 11195 assertThrown!DateTimeException(testFSInvalid(".0000000000Q")); 11196 11197 assert(fracSecsFromISOString("") == Duration.zero); 11198 assert(fracSecsFromISOString(".0000001") == hnsecs(1)); 11199 assert(fracSecsFromISOString(".000001") == hnsecs(10)); 11200 assert(fracSecsFromISOString(".00001") == hnsecs(100)); 11201 assert(fracSecsFromISOString(".0001") == hnsecs(1000)); 11202 assert(fracSecsFromISOString(".001") == hnsecs(10_000)); 11203 assert(fracSecsFromISOString(".01") == hnsecs(100_000)); 11204 assert(fracSecsFromISOString(".1") == hnsecs(1_000_000)); 11205 assert(fracSecsFromISOString(".1000001") == hnsecs(1_000_001)); 11206 assert(fracSecsFromISOString(".1001001") == hnsecs(1_001_001)); 11207 assert(fracSecsFromISOString(".1071601") == hnsecs(1_071_601)); 11208 assert(fracSecsFromISOString(".1271641") == hnsecs(1_271_641)); 11209 assert(fracSecsFromISOString(".9999999") == hnsecs(9_999_999)); 11210 assert(fracSecsFromISOString(".9999990") == hnsecs(9_999_990)); 11211 assert(fracSecsFromISOString(".999999") == hnsecs(9_999_990)); 11212 assert(fracSecsFromISOString(".9999900") == hnsecs(9_999_900)); 11213 assert(fracSecsFromISOString(".99999") == hnsecs(9_999_900)); 11214 assert(fracSecsFromISOString(".9999000") == hnsecs(9_999_000)); 11215 assert(fracSecsFromISOString(".9999") == hnsecs(9_999_000)); 11216 assert(fracSecsFromISOString(".9990000") == hnsecs(9_990_000)); 11217 assert(fracSecsFromISOString(".999") == hnsecs(9_990_000)); 11218 assert(fracSecsFromISOString(".9900000") == hnsecs(9_900_000)); 11219 assert(fracSecsFromISOString(".9900") == hnsecs(9_900_000)); 11220 assert(fracSecsFromISOString(".99") == hnsecs(9_900_000)); 11221 assert(fracSecsFromISOString(".9000000") == hnsecs(9_000_000)); 11222 assert(fracSecsFromISOString(".9") == hnsecs(9_000_000)); 11223 assert(fracSecsFromISOString(".0000999") == hnsecs(999)); 11224 assert(fracSecsFromISOString(".0009990") == hnsecs(9990)); 11225 assert(fracSecsFromISOString(".000999") == hnsecs(9990)); 11226 assert(fracSecsFromISOString(".0099900") == hnsecs(99_900)); 11227 assert(fracSecsFromISOString(".00999") == hnsecs(99_900)); 11228 assert(fracSecsFromISOString(".0999000") == hnsecs(999_000)); 11229 assert(fracSecsFromISOString(".0999") == hnsecs(999_000)); 11230 assert(fracSecsFromISOString(".00000000") == Duration.zero); 11231 assert(fracSecsFromISOString(".00000001") == Duration.zero); 11232 assert(fracSecsFromISOString(".00000009") == Duration.zero); 11233 assert(fracSecsFromISOString(".1234567890") == hnsecs(1_234_567)); 11234 assert(fracSecsFromISOString(".12345678901234567890") == hnsecs(1_234_567)); 11235 } 11236 11237 11238 /+ 11239 This function is used to split out the units without getting the remaining 11240 hnsecs. 11241 11242 Params: 11243 units = The units to split out. 11244 hnsecs = The current total hnsecs. 11245 11246 Returns: 11247 The split out value. 11248 +/ 11249 long getUnitsFromHNSecs(string units)(long hnsecs) @safe pure nothrow 11250 if (validTimeUnits(units) && 11251 CmpTimeUnits!(units, "months") < 0) 11252 { 11253 return convert!("hnsecs", units)(hnsecs); 11254 } 11255 11256 @safe unittest 11257 { 11258 auto hnsecs = 2595000000007L; 11259 immutable days = getUnitsFromHNSecs!"days"(hnsecs); 11260 assert(days == 3); 11261 assert(hnsecs == 2595000000007L); 11262 } 11263 11264 11265 /+ 11266 This function is used to split out the units without getting the units but 11267 just the remaining hnsecs. 11268 11269 Params: 11270 units = The units to split out. 11271 hnsecs = The current total hnsecs. 11272 11273 Returns: 11274 The remaining hnsecs. 11275 +/ 11276 long removeUnitsFromHNSecs(string units)(long hnsecs) @safe pure nothrow 11277 if (validTimeUnits(units) && 11278 CmpTimeUnits!(units, "months") < 0) 11279 { 11280 immutable value = convert!("hnsecs", units)(hnsecs); 11281 return hnsecs - convert!(units, "hnsecs")(value); 11282 } 11283 11284 @safe unittest 11285 { 11286 auto hnsecs = 2595000000007L; 11287 auto returned = removeUnitsFromHNSecs!"days"(hnsecs); 11288 assert(returned == 3000000007); 11289 assert(hnsecs == 2595000000007L); 11290 } 11291 11292 11293 /+ 11294 Strips what RFC 5322, section 3.2.2 refers to as CFWS from the left-hand 11295 side of the given range (it strips comments delimited by $(D '(') and 11296 `'`') as well as folding whitespace). 11297 11298 It is assumed that the given range contains the value of a header field and 11299 no terminating CRLF for the line (though the CRLF for folding whitespace is 11300 of course expected and stripped) and thus that the only case of CR or LF is 11301 in folding whitespace. 11302 11303 If a comment does not terminate correctly (e.g. mismatched parens) or if the 11304 the FWS is malformed, then the range will be empty when stripCWFS is done. 11305 However, only minimal validation of the content is done (e.g. quoted pairs 11306 within a comment aren't validated beyond \$LPAREN or \$RPAREN, because 11307 they're inside a comment, and thus their value doesn't matter anyway). It's 11308 only when the content does not conform to the grammar rules for FWS and thus 11309 literally cannot be parsed that content is considered invalid, and an empty 11310 range is returned. 11311 11312 Note that _stripCFWS is eager, not lazy. It does not create a new range. 11313 Rather, it pops off the CFWS from the range and returns it. 11314 +/ 11315 R _stripCFWS(R)(R range) 11316 if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && 11317 (is(immutable ElementType!R == immutable char) || is(immutable ElementType!R == immutable ubyte))) 11318 { 11319 immutable e = range.length; 11320 outer: for (size_t i = 0; i < e; ) 11321 { 11322 switch (range[i]) 11323 { 11324 case ' ': case '\t': 11325 { 11326 ++i; 11327 break; 11328 } 11329 case '\r': 11330 { 11331 if (i + 2 < e && range[i + 1] == '\n' && (range[i + 2] == ' ' || range[i + 2] == '\t')) 11332 { 11333 i += 3; 11334 break; 11335 } 11336 break outer; 11337 } 11338 case '\n': 11339 { 11340 if (i + 1 < e && (range[i + 1] == ' ' || range[i + 1] == '\t')) 11341 { 11342 i += 2; 11343 break; 11344 } 11345 break outer; 11346 } 11347 case '(': 11348 { 11349 ++i; 11350 size_t commentLevel = 1; 11351 while (i < e) 11352 { 11353 if (range[i] == '(') 11354 ++commentLevel; 11355 else if (range[i] == ')') 11356 { 11357 ++i; 11358 if (--commentLevel == 0) 11359 continue outer; 11360 continue; 11361 } 11362 else if (range[i] == '\\') 11363 { 11364 if (++i == e) 11365 break outer; 11366 } 11367 ++i; 11368 } 11369 break outer; 11370 } 11371 default: return range[i .. e]; 11372 } 11373 } 11374 return range[e .. e]; 11375 } 11376 11377 @system unittest 11378 { 11379 import std.algorithm.comparison : equal; 11380 import std.algorithm.iteration : map; 11381 import std.meta : AliasSeq; 11382 import std.stdio : writeln; 11383 import std.string : representation; 11384 11385 static foreach (cr; AliasSeq!(function(string a){return cast(ubyte[]) a;}, 11386 function(string a){return map!(b => cast(char) b)(a.representation);})) 11387 { 11388 scope(failure) writeln(typeof(cr).stringof); 11389 11390 assert(_stripCFWS(cr("")).empty); 11391 assert(_stripCFWS(cr("\r")).empty); 11392 assert(_stripCFWS(cr("\r\n")).empty); 11393 assert(_stripCFWS(cr("\r\n ")).empty); 11394 assert(_stripCFWS(cr(" \t\r\n")).empty); 11395 assert(equal(_stripCFWS(cr(" \t\r\n hello")), cr("hello"))); 11396 assert(_stripCFWS(cr(" \t\r\nhello")).empty); 11397 assert(_stripCFWS(cr(" \t\r\n\v")).empty); 11398 assert(equal(_stripCFWS(cr("\v \t\r\n\v")), cr("\v \t\r\n\v"))); 11399 assert(_stripCFWS(cr("()")).empty); 11400 assert(_stripCFWS(cr("(hello world)")).empty); 11401 assert(_stripCFWS(cr("(hello world)(hello world)")).empty); 11402 assert(_stripCFWS(cr("(hello world\r\n foo\r where's\nwaldo)")).empty); 11403 assert(_stripCFWS(cr(" \t (hello \tworld\r\n foo\r where's\nwaldo)\t\t ")).empty); 11404 assert(_stripCFWS(cr(" ")).empty); 11405 assert(_stripCFWS(cr("\t\t\t")).empty); 11406 assert(_stripCFWS(cr("\t \r\n\r \n")).empty); 11407 assert(_stripCFWS(cr("(hello world) (can't find waldo) (he's lost)")).empty); 11408 assert(_stripCFWS(cr("(hello\\) world) (can't \\(find waldo) (he's \\(\\)lost)")).empty); 11409 assert(_stripCFWS(cr("(((((")).empty); 11410 assert(_stripCFWS(cr("(((()))")).empty); 11411 assert(_stripCFWS(cr("(((())))")).empty); 11412 assert(equal(_stripCFWS(cr("(((()))))")), cr(")"))); 11413 assert(equal(_stripCFWS(cr(")))))")), cr(")))))"))); 11414 assert(equal(_stripCFWS(cr("()))))")), cr("))))"))); 11415 assert(equal(_stripCFWS(cr(" hello hello ")), cr("hello hello "))); 11416 assert(equal(_stripCFWS(cr("\thello (world)")), cr("hello (world)"))); 11417 assert(equal(_stripCFWS(cr(" \r\n \\((\\)) foo")), cr("\\((\\)) foo"))); 11418 assert(equal(_stripCFWS(cr(" \r\n (\\((\\))) foo")), cr("foo"))); 11419 assert(equal(_stripCFWS(cr(" \r\n (\\(())) foo")), cr(") foo"))); 11420 assert(_stripCFWS(cr(" \r\n (((\\))) foo")).empty); 11421 11422 assert(_stripCFWS(cr("(hello)(hello)")).empty); 11423 assert(_stripCFWS(cr(" \r\n (hello)\r\n (hello)")).empty); 11424 assert(_stripCFWS(cr(" \r\n (hello) \r\n (hello) \r\n ")).empty); 11425 assert(_stripCFWS(cr("\t\t\t\t(hello)\t\t\t\t(hello)\t\t\t\t")).empty); 11426 assert(equal(_stripCFWS(cr(" \r\n (hello)\r\n (hello) \r\n hello")), cr("hello"))); 11427 assert(equal(_stripCFWS(cr(" \r\n (hello) \r\n (hello) \r\n hello")), cr("hello"))); 11428 assert(equal(_stripCFWS(cr("\t\r\n\t(hello)\r\n\t(hello)\t\r\n hello")), cr("hello"))); 11429 assert(equal(_stripCFWS(cr("\t\r\n\t(hello)\t\r\n\t(hello)\t\r\n hello")), cr("hello"))); 11430 assert(equal(_stripCFWS(cr(" \r\n (hello) \r\n \r\n (hello) \r\n hello")), cr("hello"))); 11431 assert(equal(_stripCFWS(cr(" \r\n (hello) \r\n (hello) \r\n \r\n hello")), cr("hello"))); 11432 assert(equal(_stripCFWS(cr(" \r\n \r\n (hello)\t\r\n (hello) \r\n hello")), cr("hello"))); 11433 assert(equal(_stripCFWS(cr(" \r\n\t\r\n\t(hello)\t\r\n (hello) \r\n hello")), cr("hello"))); 11434 11435 assert(equal(_stripCFWS(cr(" (\r\n ( \r\n ) \r\n ) foo")), cr("foo"))); 11436 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n ) foo")), cr("foo"))); 11437 assert(equal(_stripCFWS(cr(" (\t\r\n ( \r\n ) \r\n ) foo")), cr("foo"))); 11438 assert(equal(_stripCFWS(cr(" (\r\n\t( \r\n ) \r\n ) foo")), cr("foo"))); 11439 assert(equal(_stripCFWS(cr(" ( \r\n (\t\r\n ) \r\n ) foo")), cr("foo"))); 11440 assert(equal(_stripCFWS(cr(" ( \r\n (\r\n ) \r\n ) foo")), cr("foo"))); 11441 assert(equal(_stripCFWS(cr(" ( \r\n (\r\n\t) \r\n ) foo")), cr("foo"))); 11442 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n) \r\n ) foo")), cr("foo"))); 11443 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n )\t\r\n ) foo")), cr("foo"))); 11444 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n )\r\n ) foo")), cr("foo"))); 11445 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n) foo")), cr("foo"))); 11446 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n\t) foo")), cr("foo"))); 11447 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n ) \r\n foo")), cr("foo"))); 11448 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n )\t\r\n foo")), cr("foo"))); 11449 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n )\r\n foo")), cr("foo"))); 11450 11451 assert(equal(_stripCFWS(cr(" ( \r\n \r\n ( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 11452 assert(equal(_stripCFWS(cr(" ( \r\n \r\n ( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 11453 assert(equal(_stripCFWS(cr(" (\t\r\n \r\n ( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 11454 assert(equal(_stripCFWS(cr(" (\r\n \r\n\t( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 11455 assert(equal(_stripCFWS(cr(" (\r\n \r\n( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 11456 assert(equal(_stripCFWS(cr(" (\r\n \r\n ( \r\n \r\n\t) \r\n ) foo")), cr("foo"))); 11457 assert(equal(_stripCFWS(cr(" (\r\n \r\n ( \r\n \r\n )\t\r\n ) foo")), cr("foo"))); 11458 assert(equal(_stripCFWS(cr(" (\r\n \r\n ( \r\n \r\n )\r\n ) foo")), cr("foo"))); 11459 11460 assert(equal(_stripCFWS(cr(" ( \r\n bar \r\n ( \r\n bar \r\n ) \r\n ) foo")), cr("foo"))); 11461 assert(equal(_stripCFWS(cr(" ( \r\n () \r\n ( \r\n () \r\n ) \r\n ) foo")), cr("foo"))); 11462 assert(equal(_stripCFWS(cr(" ( \r\n \\\\ \r\n ( \r\n \\\\ \r\n ) \r\n ) foo")), cr("foo"))); 11463 11464 assert(_stripCFWS(cr("(hello)(hello)")).empty); 11465 assert(_stripCFWS(cr(" \n (hello)\n (hello) \n ")).empty); 11466 assert(_stripCFWS(cr(" \n (hello) \n (hello) \n ")).empty); 11467 assert(equal(_stripCFWS(cr(" \n (hello)\n (hello) \n hello")), cr("hello"))); 11468 assert(equal(_stripCFWS(cr(" \n (hello) \n (hello) \n hello")), cr("hello"))); 11469 assert(equal(_stripCFWS(cr("\t\n\t(hello)\n\t(hello)\t\n hello")), cr("hello"))); 11470 assert(equal(_stripCFWS(cr("\t\n\t(hello)\t\n\t(hello)\t\n hello")), cr("hello"))); 11471 assert(equal(_stripCFWS(cr(" \n (hello) \n \n (hello) \n hello")), cr("hello"))); 11472 assert(equal(_stripCFWS(cr(" \n (hello) \n (hello) \n \n hello")), cr("hello"))); 11473 assert(equal(_stripCFWS(cr(" \n \n (hello)\t\n (hello) \n hello")), cr("hello"))); 11474 assert(equal(_stripCFWS(cr(" \n\t\n\t(hello)\t\n (hello) \n hello")), cr("hello"))); 11475 } 11476 } 11477 11478 // This is so that we don't have to worry about std.conv.to throwing. It also 11479 // doesn't have to worry about quite as many cases as std.conv.to, since it 11480 // doesn't have to worry about a sign on the value or about whether it fits. 11481 T _convDigits(T, R)(R str) 11482 if (isIntegral!T && isSigned!T) // The constraints on R were already covered by parseRFC822DateTime. 11483 { 11484 import std.ascii : isDigit; 11485 11486 assert(!str.empty); 11487 T num = 0; 11488 foreach (i; 0 .. str.length) 11489 { 11490 if (i != 0) 11491 num *= 10; 11492 if (!isDigit(str[i])) 11493 return -1; 11494 num += str[i] - '0'; 11495 } 11496 return num; 11497 } 11498 11499 @safe unittest 11500 { 11501 import std.conv : to; 11502 import std.range : chain, iota; 11503 foreach (i; chain(iota(0, 101), [250, 999, 1000, 1001, 2345, 9999])) 11504 { 11505 assert(_convDigits!int(to!string(i)) == i, i.to!string); 11506 } 11507 foreach (str; ["-42", "+42", "1a", "1 ", " ", " 42 "]) 11508 { 11509 assert(_convDigits!int(str) == -1, str); 11510 } 11511 } 11512 11513 11514 // NOTE: all the non-simple array literals are wrapped in functions, because 11515 // otherwise importing causes re-evaluation of the static initializers using 11516 // CTFE with unittests enabled 11517 version (StdUnittest) 11518 { 11519 private @safe: 11520 // Variables to help in testing. 11521 Duration currLocalDiffFromUTC; 11522 immutable (TimeZone)[] testTZs; 11523 11524 // All of these helper arrays are sorted in ascending order. 11525 auto testYearsBC = [-1999, -1200, -600, -4, -1, 0]; 11526 auto testYearsAD = [1, 4, 1000, 1999, 2000, 2012]; 11527 11528 // I'd use a Tuple, but I get forward reference errors if I try. 11529 struct MonthDay 11530 { 11531 Month month; 11532 short day; 11533 11534 this(int m, short d) 11535 { 11536 month = cast(Month) m; 11537 day = d; 11538 } 11539 } 11540 11541 MonthDay[] testMonthDays() 11542 { 11543 static result = [MonthDay(1, 1), 11544 MonthDay(1, 2), 11545 MonthDay(3, 17), 11546 MonthDay(7, 4), 11547 MonthDay(10, 27), 11548 MonthDay(12, 30), 11549 MonthDay(12, 31)]; 11550 return result; 11551 } 11552 11553 auto testDays = [1, 2, 9, 10, 16, 20, 25, 28, 29, 30, 31]; 11554 11555 TimeOfDay[] testTODs() 11556 { 11557 static result = [TimeOfDay(0, 0, 0), 11558 TimeOfDay(0, 0, 1), 11559 TimeOfDay(0, 1, 0), 11560 TimeOfDay(1, 0, 0), 11561 TimeOfDay(13, 13, 13), 11562 TimeOfDay(23, 59, 59)]; 11563 return result; 11564 } 11565 11566 auto testHours = [0, 1, 12, 22, 23]; 11567 auto testMinSecs = [0, 1, 30, 58, 59]; 11568 11569 // Throwing exceptions is incredibly expensive, so we want to use a smaller 11570 // set of values for tests using assertThrown. 11571 TimeOfDay[] testTODsThrown() 11572 { 11573 static result = [TimeOfDay(0, 0, 0), 11574 TimeOfDay(13, 13, 13), 11575 TimeOfDay(23, 59, 59)]; 11576 return result; 11577 } 11578 11579 Date[] testDatesBC; 11580 Date[] testDatesAD; 11581 11582 DateTime[] testDateTimesBC; 11583 DateTime[] testDateTimesAD; 11584 11585 Duration[] testFracSecs; 11586 11587 SysTime[] testSysTimesBC; 11588 SysTime[] testSysTimesAD; 11589 11590 // I'd use a Tuple, but I get forward reference errors if I try. 11591 struct GregDay { int day; Date date; } 11592 GregDay[] testGregDaysBC() 11593 { 11594 static result = [GregDay(-1_373_427, Date(-3760, 9, 7)), // Start of the Hebrew Calendar 11595 GregDay(-735_233, Date(-2012, 1, 1)), 11596 GregDay(-735_202, Date(-2012, 2, 1)), 11597 GregDay(-735_175, Date(-2012, 2, 28)), 11598 GregDay(-735_174, Date(-2012, 2, 29)), 11599 GregDay(-735_173, Date(-2012, 3, 1)), 11600 GregDay(-734_502, Date(-2010, 1, 1)), 11601 GregDay(-734_472, Date(-2010, 1, 31)), 11602 GregDay(-734_471, Date(-2010, 2, 1)), 11603 GregDay(-734_444, Date(-2010, 2, 28)), 11604 GregDay(-734_443, Date(-2010, 3, 1)), 11605 GregDay(-734_413, Date(-2010, 3, 31)), 11606 GregDay(-734_412, Date(-2010, 4, 1)), 11607 GregDay(-734_383, Date(-2010, 4, 30)), 11608 GregDay(-734_382, Date(-2010, 5, 1)), 11609 GregDay(-734_352, Date(-2010, 5, 31)), 11610 GregDay(-734_351, Date(-2010, 6, 1)), 11611 GregDay(-734_322, Date(-2010, 6, 30)), 11612 GregDay(-734_321, Date(-2010, 7, 1)), 11613 GregDay(-734_291, Date(-2010, 7, 31)), 11614 GregDay(-734_290, Date(-2010, 8, 1)), 11615 GregDay(-734_260, Date(-2010, 8, 31)), 11616 GregDay(-734_259, Date(-2010, 9, 1)), 11617 GregDay(-734_230, Date(-2010, 9, 30)), 11618 GregDay(-734_229, Date(-2010, 10, 1)), 11619 GregDay(-734_199, Date(-2010, 10, 31)), 11620 GregDay(-734_198, Date(-2010, 11, 1)), 11621 GregDay(-734_169, Date(-2010, 11, 30)), 11622 GregDay(-734_168, Date(-2010, 12, 1)), 11623 GregDay(-734_139, Date(-2010, 12, 30)), 11624 GregDay(-734_138, Date(-2010, 12, 31)), 11625 GregDay(-731_215, Date(-2001, 1, 1)), 11626 GregDay(-730_850, Date(-2000, 1, 1)), 11627 GregDay(-730_849, Date(-2000, 1, 2)), 11628 GregDay(-730_486, Date(-2000, 12, 30)), 11629 GregDay(-730_485, Date(-2000, 12, 31)), 11630 GregDay(-730_484, Date(-1999, 1, 1)), 11631 GregDay(-694_690, Date(-1901, 1, 1)), 11632 GregDay(-694_325, Date(-1900, 1, 1)), 11633 GregDay(-585_118, Date(-1601, 1, 1)), 11634 GregDay(-584_753, Date(-1600, 1, 1)), 11635 GregDay(-584_388, Date(-1600, 12, 31)), 11636 GregDay(-584_387, Date(-1599, 1, 1)), 11637 GregDay(-365_972, Date(-1001, 1, 1)), 11638 GregDay(-365_607, Date(-1000, 1, 1)), 11639 GregDay(-183_351, Date(-501, 1, 1)), 11640 GregDay(-182_986, Date(-500, 1, 1)), 11641 GregDay(-182_621, Date(-499, 1, 1)), 11642 GregDay(-146_827, Date(-401, 1, 1)), 11643 GregDay(-146_462, Date(-400, 1, 1)), 11644 GregDay(-146_097, Date(-400, 12, 31)), 11645 GregDay(-110_302, Date(-301, 1, 1)), 11646 GregDay(-109_937, Date(-300, 1, 1)), 11647 GregDay(-73_778, Date(-201, 1, 1)), 11648 GregDay(-73_413, Date(-200, 1, 1)), 11649 GregDay(-38_715, Date(-105, 1, 1)), 11650 GregDay(-37_254, Date(-101, 1, 1)), 11651 GregDay(-36_889, Date(-100, 1, 1)), 11652 GregDay(-36_524, Date(-99, 1, 1)), 11653 GregDay(-36_160, Date(-99, 12, 31)), 11654 GregDay(-35_794, Date(-97, 1, 1)), 11655 GregDay(-18_627, Date(-50, 1, 1)), 11656 GregDay(-18_262, Date(-49, 1, 1)), 11657 GregDay(-3652, Date(-9, 1, 1)), 11658 GregDay(-2191, Date(-5, 1, 1)), 11659 GregDay(-1827, Date(-5, 12, 31)), 11660 GregDay(-1826, Date(-4, 1, 1)), 11661 GregDay(-1825, Date(-4, 1, 2)), 11662 GregDay(-1462, Date(-4, 12, 30)), 11663 GregDay(-1461, Date(-4, 12, 31)), 11664 GregDay(-1460, Date(-3, 1, 1)), 11665 GregDay(-1096, Date(-3, 12, 31)), 11666 GregDay(-1095, Date(-2, 1, 1)), 11667 GregDay(-731, Date(-2, 12, 31)), 11668 GregDay(-730, Date(-1, 1, 1)), 11669 GregDay(-367, Date(-1, 12, 30)), 11670 GregDay(-366, Date(-1, 12, 31)), 11671 GregDay(-365, Date(0, 1, 1)), 11672 GregDay(-31, Date(0, 11, 30)), 11673 GregDay(-30, Date(0, 12, 1)), 11674 GregDay(-1, Date(0, 12, 30)), 11675 GregDay(0, Date(0, 12, 31))]; 11676 return result; 11677 } 11678 11679 GregDay[] testGregDaysAD() 11680 { 11681 static result = [GregDay(1, Date(1, 1, 1)), 11682 GregDay(2, Date(1, 1, 2)), 11683 GregDay(32, Date(1, 2, 1)), 11684 GregDay(365, Date(1, 12, 31)), 11685 GregDay(366, Date(2, 1, 1)), 11686 GregDay(731, Date(3, 1, 1)), 11687 GregDay(1096, Date(4, 1, 1)), 11688 GregDay(1097, Date(4, 1, 2)), 11689 GregDay(1460, Date(4, 12, 30)), 11690 GregDay(1461, Date(4, 12, 31)), 11691 GregDay(1462, Date(5, 1, 1)), 11692 GregDay(17_898, Date(50, 1, 1)), 11693 GregDay(35_065, Date(97, 1, 1)), 11694 GregDay(36_160, Date(100, 1, 1)), 11695 GregDay(36_525, Date(101, 1, 1)), 11696 GregDay(37_986, Date(105, 1, 1)), 11697 GregDay(72_684, Date(200, 1, 1)), 11698 GregDay(73_049, Date(201, 1, 1)), 11699 GregDay(109_208, Date(300, 1, 1)), 11700 GregDay(109_573, Date(301, 1, 1)), 11701 GregDay(145_732, Date(400, 1, 1)), 11702 GregDay(146_098, Date(401, 1, 1)), 11703 GregDay(182_257, Date(500, 1, 1)), 11704 GregDay(182_622, Date(501, 1, 1)), 11705 GregDay(364_878, Date(1000, 1, 1)), 11706 GregDay(365_243, Date(1001, 1, 1)), 11707 GregDay(584_023, Date(1600, 1, 1)), 11708 GregDay(584_389, Date(1601, 1, 1)), 11709 GregDay(693_596, Date(1900, 1, 1)), 11710 GregDay(693_961, Date(1901, 1, 1)), 11711 GregDay(729_755, Date(1999, 1, 1)), 11712 GregDay(730_120, Date(2000, 1, 1)), 11713 GregDay(730_121, Date(2000, 1, 2)), 11714 GregDay(730_484, Date(2000, 12, 30)), 11715 GregDay(730_485, Date(2000, 12, 31)), 11716 GregDay(730_486, Date(2001, 1, 1)), 11717 GregDay(733_773, Date(2010, 1, 1)), 11718 GregDay(733_774, Date(2010, 1, 2)), 11719 GregDay(733_803, Date(2010, 1, 31)), 11720 GregDay(733_804, Date(2010, 2, 1)), 11721 GregDay(733_831, Date(2010, 2, 28)), 11722 GregDay(733_832, Date(2010, 3, 1)), 11723 GregDay(733_862, Date(2010, 3, 31)), 11724 GregDay(733_863, Date(2010, 4, 1)), 11725 GregDay(733_892, Date(2010, 4, 30)), 11726 GregDay(733_893, Date(2010, 5, 1)), 11727 GregDay(733_923, Date(2010, 5, 31)), 11728 GregDay(733_924, Date(2010, 6, 1)), 11729 GregDay(733_953, Date(2010, 6, 30)), 11730 GregDay(733_954, Date(2010, 7, 1)), 11731 GregDay(733_984, Date(2010, 7, 31)), 11732 GregDay(733_985, Date(2010, 8, 1)), 11733 GregDay(734_015, Date(2010, 8, 31)), 11734 GregDay(734_016, Date(2010, 9, 1)), 11735 GregDay(734_045, Date(2010, 9, 30)), 11736 GregDay(734_046, Date(2010, 10, 1)), 11737 GregDay(734_076, Date(2010, 10, 31)), 11738 GregDay(734_077, Date(2010, 11, 1)), 11739 GregDay(734_106, Date(2010, 11, 30)), 11740 GregDay(734_107, Date(2010, 12, 1)), 11741 GregDay(734_136, Date(2010, 12, 30)), 11742 GregDay(734_137, Date(2010, 12, 31)), 11743 GregDay(734_503, Date(2012, 1, 1)), 11744 GregDay(734_534, Date(2012, 2, 1)), 11745 GregDay(734_561, Date(2012, 2, 28)), 11746 GregDay(734_562, Date(2012, 2, 29)), 11747 GregDay(734_563, Date(2012, 3, 1)), 11748 GregDay(734_858, Date(2012, 12, 21))]; 11749 return result; 11750 } 11751 11752 // I'd use a Tuple, but I get forward reference errors if I try. 11753 struct DayOfYear { int day; MonthDay md; } 11754 DayOfYear[] testDaysOfYear() 11755 { 11756 static result = [DayOfYear(1, MonthDay(1, 1)), 11757 DayOfYear(2, MonthDay(1, 2)), 11758 DayOfYear(3, MonthDay(1, 3)), 11759 DayOfYear(31, MonthDay(1, 31)), 11760 DayOfYear(32, MonthDay(2, 1)), 11761 DayOfYear(59, MonthDay(2, 28)), 11762 DayOfYear(60, MonthDay(3, 1)), 11763 DayOfYear(90, MonthDay(3, 31)), 11764 DayOfYear(91, MonthDay(4, 1)), 11765 DayOfYear(120, MonthDay(4, 30)), 11766 DayOfYear(121, MonthDay(5, 1)), 11767 DayOfYear(151, MonthDay(5, 31)), 11768 DayOfYear(152, MonthDay(6, 1)), 11769 DayOfYear(181, MonthDay(6, 30)), 11770 DayOfYear(182, MonthDay(7, 1)), 11771 DayOfYear(212, MonthDay(7, 31)), 11772 DayOfYear(213, MonthDay(8, 1)), 11773 DayOfYear(243, MonthDay(8, 31)), 11774 DayOfYear(244, MonthDay(9, 1)), 11775 DayOfYear(273, MonthDay(9, 30)), 11776 DayOfYear(274, MonthDay(10, 1)), 11777 DayOfYear(304, MonthDay(10, 31)), 11778 DayOfYear(305, MonthDay(11, 1)), 11779 DayOfYear(334, MonthDay(11, 30)), 11780 DayOfYear(335, MonthDay(12, 1)), 11781 DayOfYear(363, MonthDay(12, 29)), 11782 DayOfYear(364, MonthDay(12, 30)), 11783 DayOfYear(365, MonthDay(12, 31))]; 11784 return result; 11785 } 11786 11787 DayOfYear[] testDaysOfLeapYear() 11788 { 11789 static result = [DayOfYear(1, MonthDay(1, 1)), 11790 DayOfYear(2, MonthDay(1, 2)), 11791 DayOfYear(3, MonthDay(1, 3)), 11792 DayOfYear(31, MonthDay(1, 31)), 11793 DayOfYear(32, MonthDay(2, 1)), 11794 DayOfYear(59, MonthDay(2, 28)), 11795 DayOfYear(60, MonthDay(2, 29)), 11796 DayOfYear(61, MonthDay(3, 1)), 11797 DayOfYear(91, MonthDay(3, 31)), 11798 DayOfYear(92, MonthDay(4, 1)), 11799 DayOfYear(121, MonthDay(4, 30)), 11800 DayOfYear(122, MonthDay(5, 1)), 11801 DayOfYear(152, MonthDay(5, 31)), 11802 DayOfYear(153, MonthDay(6, 1)), 11803 DayOfYear(182, MonthDay(6, 30)), 11804 DayOfYear(183, MonthDay(7, 1)), 11805 DayOfYear(213, MonthDay(7, 31)), 11806 DayOfYear(214, MonthDay(8, 1)), 11807 DayOfYear(244, MonthDay(8, 31)), 11808 DayOfYear(245, MonthDay(9, 1)), 11809 DayOfYear(274, MonthDay(9, 30)), 11810 DayOfYear(275, MonthDay(10, 1)), 11811 DayOfYear(305, MonthDay(10, 31)), 11812 DayOfYear(306, MonthDay(11, 1)), 11813 DayOfYear(335, MonthDay(11, 30)), 11814 DayOfYear(336, MonthDay(12, 1)), 11815 DayOfYear(364, MonthDay(12, 29)), 11816 DayOfYear(365, MonthDay(12, 30)), 11817 DayOfYear(366, MonthDay(12, 31))]; 11818 return result; 11819 } 11820 11821 void initializeTests() 11822 { 11823 import std.algorithm.sorting : sort; 11824 import std.typecons : Rebindable; 11825 immutable lt = LocalTime().utcToTZ(0); 11826 currLocalDiffFromUTC = dur!"hnsecs"(lt); 11827 11828 version (Posix) 11829 { 11830 import std.datetime.timezone : PosixTimeZone; 11831 immutable otherTZ = lt < 0 ? PosixTimeZone.getTimeZone("Australia/Sydney") 11832 : PosixTimeZone.getTimeZone("America/Denver"); 11833 } 11834 else version (Windows) 11835 { 11836 import std.datetime.timezone : WindowsTimeZone; 11837 immutable otherTZ = lt < 0 ? WindowsTimeZone.getTimeZone("AUS Eastern Standard Time") 11838 : WindowsTimeZone.getTimeZone("Mountain Standard Time"); 11839 } 11840 11841 immutable ot = otherTZ.utcToTZ(0); 11842 11843 auto diffs = [0L, lt, ot]; 11844 auto diffAA = [0L : Rebindable!(immutable TimeZone)(UTC())]; 11845 diffAA[lt] = Rebindable!(immutable TimeZone)(LocalTime()); 11846 diffAA[ot] = Rebindable!(immutable TimeZone)(otherTZ); 11847 11848 sort(diffs); 11849 testTZs = [diffAA[diffs[0]], diffAA[diffs[1]], diffAA[diffs[2]]]; 11850 11851 testFracSecs = [Duration.zero, hnsecs(1), hnsecs(5007), hnsecs(9_999_999)]; 11852 11853 foreach (year; testYearsBC) 11854 { 11855 foreach (md; testMonthDays) 11856 testDatesBC ~= Date(year, md.month, md.day); 11857 } 11858 11859 foreach (year; testYearsAD) 11860 { 11861 foreach (md; testMonthDays) 11862 testDatesAD ~= Date(year, md.month, md.day); 11863 } 11864 11865 foreach (dt; testDatesBC) 11866 { 11867 foreach (tod; testTODs) 11868 testDateTimesBC ~= DateTime(dt, tod); 11869 } 11870 11871 foreach (dt; testDatesAD) 11872 { 11873 foreach (tod; testTODs) 11874 testDateTimesAD ~= DateTime(dt, tod); 11875 } 11876 11877 foreach (dt; testDateTimesBC) 11878 { 11879 foreach (tz; testTZs) 11880 { 11881 foreach (fs; testFracSecs) 11882 testSysTimesBC ~= SysTime(dt, fs, tz); 11883 } 11884 } 11885 11886 foreach (dt; testDateTimesAD) 11887 { 11888 foreach (tz; testTZs) 11889 { 11890 foreach (fs; testFracSecs) 11891 testSysTimesAD ~= SysTime(dt, fs, tz); 11892 } 11893 } 11894 } 11895 }