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 117 /++ 118 Effectively a namespace to make it clear that the methods it contains are 119 getting the time from the system clock. It cannot be instantiated. 120 +/ 121 final class Clock 122 { 123 public: 124 125 /++ 126 Returns the current time in the given time zone. 127 128 Params: 129 clockType = The $(REF ClockType, core,time) indicates which system 130 clock to use to get the current time. Very few programs 131 need to use anything other than the default. 132 tz = The time zone for the SysTime that's returned. 133 134 Throws: 135 $(REF DateTimeException,std,datetime,date) if it fails to get the 136 time. 137 +/ 138 static SysTime currTime(ClockType clockType = ClockType.normal)(immutable TimeZone tz = LocalTime()) @safe 139 { 140 return SysTime(currStdTime!clockType, tz); 141 } 142 143 @safe unittest 144 { 145 import std.format : format; 146 import core.time; 147 assert(currTime().timezone is LocalTime()); 148 assert(currTime(UTC()).timezone is UTC()); 149 150 // core.stdc.time.time does not always use unix time on Windows systems. 151 // In particular, dmc does not use unix time. If we can guarantee that 152 // the MS runtime uses unix time, then we may be able run this test 153 // then, but for now, we're just not going to run this test on Windows. 154 version (Posix) 155 { 156 static import core.stdc.time; 157 static import std.math; 158 immutable unixTimeD = currTime().toUnixTime(); 159 immutable unixTimeC = core.stdc.time.time(null); 160 assert(std.math.abs(unixTimeC - unixTimeD) <= 2); 161 } 162 163 auto norm1 = Clock.currTime; 164 auto norm2 = Clock.currTime(UTC()); 165 assert(norm1 <= norm2, format("%s %s", norm1, norm2)); 166 assert(abs(norm1 - norm2) <= seconds(2)); 167 168 import std.meta : AliasSeq; 169 static foreach (ct; AliasSeq!(ClockType.coarse, ClockType.precise, ClockType.second)) 170 {{ 171 auto value1 = Clock.currTime!ct; 172 auto value2 = Clock.currTime!ct(UTC()); 173 assert(value1 <= value2, format("%s %s (ClockType: %s)", value1, value2, ct)); 174 assert(abs(value1 - value2) <= seconds(2), format("ClockType.%s", ct)); 175 }} 176 } 177 178 179 /++ 180 Returns the number of hnsecs since midnight, January 1st, 1 A.D. for the 181 current time. 182 183 Params: 184 clockType = The $(REF ClockType, core,time) indicates which system 185 clock to use to get the current time. Very few programs 186 need to use anything other than the default. 187 188 Throws: 189 $(REF DateTimeException,std,datetime,date) if it fails to get the 190 time. 191 +/ 192 static @property long currStdTime(ClockType clockType = ClockType.normal)() @trusted 193 { 194 static if (clockType != ClockType.coarse && 195 clockType != ClockType.normal && 196 clockType != ClockType.precise && 197 clockType != ClockType.second) 198 { 199 static assert(0, format("ClockType.%s is not supported by Clock.currTime or Clock.currStdTime", clockType)); 200 } 201 202 version (Windows) 203 { 204 FILETIME fileTime; 205 GetSystemTimeAsFileTime(&fileTime); 206 immutable result = FILETIMEToStdTime(&fileTime); 207 static if (clockType == ClockType.second) 208 { 209 // Ideally, this would use core.std.time.time, but the C runtime 210 // has to be using unix time for that to work, and that's not 211 // guaranteed on Windows. Digital Mars does not use unix time. 212 // MS may or may not. If it does, then this can be made to use 213 // core.stdc.time for MS, but for now, we'll leave it like this. 214 return convert!("seconds", "hnsecs")(convert!("hnsecs", "seconds")(result)); 215 } 216 else 217 return result; 218 } 219 else version (Posix) 220 { 221 static import core.stdc.time; 222 enum hnsecsToUnixEpoch = unixTimeToStdTime(0); 223 224 version (Darwin) 225 { 226 static if (clockType == ClockType.second) 227 return unixTimeToStdTime(core.stdc.time.time(null)); 228 else 229 { 230 import core.sys.posix.sys.time : gettimeofday, timeval; 231 timeval tv = void; 232 // Posix gettimeofday called with a valid timeval address 233 // and a null second parameter doesn't fail. 234 gettimeofday(&tv, null); 235 return convert!("seconds", "hnsecs")(tv.tv_sec) + 236 tv.tv_usec * 10 + 237 hnsecsToUnixEpoch; 238 } 239 } 240 else version (linux) 241 { 242 static if (clockType == ClockType.second) 243 return unixTimeToStdTime(core.stdc.time.time(null)); 244 else 245 { 246 import core.sys.linux.time : CLOCK_REALTIME_COARSE; 247 import core.sys.posix.time : clock_gettime, CLOCK_REALTIME; 248 static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME_COARSE; 249 else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME; 250 else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME; 251 else static assert(0, "Previous static if is wrong."); 252 timespec ts = void; 253 immutable error = clock_gettime(clockArg, &ts); 254 // Posix clock_gettime called with a valid address and valid clock_id is only 255 // permitted to fail if the number of seconds does not fit in time_t. If tv_sec 256 // is long or larger overflow won't happen before 292 billion years A.D. 257 static if (ts.tv_sec.max < long.max) 258 { 259 if (error) 260 throw new TimeException("Call to clock_gettime() failed"); 261 } 262 return convert!("seconds", "hnsecs")(ts.tv_sec) + 263 ts.tv_nsec / 100 + 264 hnsecsToUnixEpoch; 265 } 266 } 267 else version (FreeBSD) 268 { 269 import core.sys.freebsd.time : clock_gettime, CLOCK_REALTIME, 270 CLOCK_REALTIME_FAST, CLOCK_REALTIME_PRECISE, CLOCK_SECOND; 271 static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME_FAST; 272 else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME; 273 else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME_PRECISE; 274 else static if (clockType == ClockType.second) alias clockArg = CLOCK_SECOND; 275 else static assert(0, "Previous static if is wrong."); 276 timespec ts = void; 277 immutable error = clock_gettime(clockArg, &ts); 278 // Posix clock_gettime called with a valid address and valid clock_id is only 279 // permitted to fail if the number of seconds does not fit in time_t. If tv_sec 280 // is long or larger overflow won't happen before 292 billion years A.D. 281 static if (ts.tv_sec.max < long.max) 282 { 283 if (error) 284 throw new TimeException("Call to clock_gettime() failed"); 285 } 286 return convert!("seconds", "hnsecs")(ts.tv_sec) + 287 ts.tv_nsec / 100 + 288 hnsecsToUnixEpoch; 289 } 290 else version (NetBSD) 291 { 292 static if (clockType == ClockType.second) 293 return unixTimeToStdTime(core.stdc.time.time(null)); 294 else 295 { 296 import core.sys.netbsd.time : clock_gettime, CLOCK_REALTIME; 297 timespec ts = void; 298 immutable error = clock_gettime(CLOCK_REALTIME, &ts); 299 // Posix clock_gettime called with a valid address and valid clock_id is only 300 // permitted to fail if the number of seconds does not fit in time_t. If tv_sec 301 // is long or larger overflow won't happen before 292 billion years A.D. 302 static if (ts.tv_sec.max < long.max) 303 { 304 if (error) 305 throw new TimeException("Call to clock_gettime() failed"); 306 } 307 return convert!("seconds", "hnsecs")(ts.tv_sec) + 308 ts.tv_nsec / 100 + 309 hnsecsToUnixEpoch; 310 } 311 } 312 else version (DragonFlyBSD) 313 { 314 import core.sys.dragonflybsd.time : clock_gettime, CLOCK_REALTIME, 315 CLOCK_REALTIME_FAST, CLOCK_REALTIME_PRECISE, CLOCK_SECOND; 316 static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME_FAST; 317 else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME; 318 else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME_PRECISE; 319 else static if (clockType == ClockType.second) alias clockArg = CLOCK_SECOND; 320 else static assert(0, "Previous static if is wrong."); 321 timespec ts = void; 322 immutable error = clock_gettime(clockArg, &ts); 323 // Posix clock_gettime called with a valid address and valid clock_id is only 324 // permitted to fail if the number of seconds does not fit in time_t. If tv_sec 325 // is long or larger overflow won't happen before 292 billion years A.D. 326 static if (ts.tv_sec.max < long.max) 327 { 328 if (error) 329 throw new TimeException("Call to clock_gettime() failed"); 330 } 331 return convert!("seconds", "hnsecs")(ts.tv_sec) + 332 ts.tv_nsec / 100 + 333 hnsecsToUnixEpoch; 334 } 335 else version (Solaris) 336 { 337 static if (clockType == ClockType.second) 338 return unixTimeToStdTime(core.stdc.time.time(null)); 339 else 340 { 341 import core.sys.solaris.time : clock_gettime, CLOCK_REALTIME; 342 static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME; 343 else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME; 344 else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME; 345 else static assert(0, "Previous static if is wrong."); 346 timespec ts = void; 347 immutable error = clock_gettime(clockArg, &ts); 348 // Posix clock_gettime called with a valid address and valid clock_id is only 349 // permitted to fail if the number of seconds does not fit in time_t. If tv_sec 350 // is long or larger overflow won't happen before 292 billion years A.D. 351 static if (ts.tv_sec.max < long.max) 352 { 353 if (error) 354 throw new TimeException("Call to clock_gettime() failed"); 355 } 356 return convert!("seconds", "hnsecs")(ts.tv_sec) + 357 ts.tv_nsec / 100 + 358 hnsecsToUnixEpoch; 359 } 360 } 361 else static assert(0, "Unsupported OS"); 362 } 363 else static assert(0, "Unsupported OS"); 364 } 365 366 @safe unittest 367 { 368 import std.format : format; 369 import std.math : abs; 370 import std.meta : AliasSeq; 371 enum limit = convert!("seconds", "hnsecs")(2); 372 373 auto norm1 = Clock.currStdTime; 374 auto norm2 = Clock.currStdTime; 375 assert(norm1 <= norm2, format("%s %s", norm1, norm2)); 376 assert(abs(norm1 - norm2) <= limit); 377 378 static foreach (ct; AliasSeq!(ClockType.coarse, ClockType.precise, ClockType.second)) 379 {{ 380 auto value1 = Clock.currStdTime!ct; 381 auto value2 = Clock.currStdTime!ct; 382 assert(value1 <= value2, format("%s %s (ClockType: %s)", value1, value2, ct)); 383 assert(abs(value1 - value2) <= limit); 384 }} 385 } 386 387 388 private: 389 390 @disable this(); 391 } 392 393 /// Get the current time as a $(LREF SysTime) 394 @safe unittest 395 { 396 import std.datetime.timezone : LocalTime; 397 SysTime today = Clock.currTime(); 398 assert(today.timezone is LocalTime()); 399 } 400 401 402 /++ 403 `SysTime` is the type used to get the current time from the 404 system or doing anything that involves time zones. Unlike 405 $(REF DateTime,std,datetime,date), the time zone is an integral part of 406 `SysTime` (though for local time applications, time zones can be ignored 407 and it will work, since it defaults to using the local time zone). It holds 408 its internal time in std time (hnsecs since midnight, January 1st, 1 A.D. 409 UTC), so it interfaces well with the system time. However, that means that, 410 unlike $(REF DateTime,std,datetime,date), it is not optimized for 411 calendar-based operations, and getting individual units from it such as 412 years or days is going to involve conversions and be less efficient. 413 414 For calendar-based operations that don't 415 care about time zones, then $(REF DateTime,std,datetime,date) would be 416 the type to use. For system time, use `SysTime`. 417 418 $(LREF Clock.currTime) will return the current time as a `SysTime`. 419 To convert a `SysTime` to a $(REF Date,std,datetime,date) or 420 $(REF DateTime,std,datetime,date), simply cast it. To convert a 421 $(REF Date,std,datetime,date) or $(REF DateTime,std,datetime,date) to a 422 `SysTime`, use `SysTime`'s constructor, and pass in the intended time 423 zone with it (or don't pass in a $(REF TimeZone,std,datetime,timezone), and 424 the local time zone will be used). Be aware, however, that converting from a 425 $(REF DateTime,std,datetime,date) to a `SysTime` will not necessarily 426 be 100% accurate due to DST (one hour of the year doesn't exist and another 427 occurs twice). To not risk any conversion errors, keep times as 428 `SysTime`s. Aside from DST though, there shouldn't be any conversion 429 problems. 430 431 For using time zones other than local time or UTC, use 432 $(REF PosixTimeZone,std,datetime,timezone) on Posix systems (or on Windows, 433 if providing the TZ Database files), and use 434 $(REF WindowsTimeZone,std,datetime,timezone) on Windows systems. The time in 435 `SysTime` is kept internally in hnsecs from midnight, January 1st, 1 A.D. 436 UTC. Conversion error cannot happen when changing the time zone of a 437 `SysTime`. $(REF LocalTime,std,datetime,timezone) is the 438 $(REF TimeZone,std,datetime,timezone) class which represents the local time, 439 and `UTC` is the $(REF TimeZone,std,datetime,timezone) class which 440 represents UTC. `SysTime` uses $(REF LocalTime,std,datetime,timezone) if 441 no $(REF TimeZone,std,datetime,timezone) is provided. For more details on 442 time zones, see the documentation for $(REF TimeZone,std,datetime,timezone), 443 $(REF PosixTimeZone,std,datetime,timezone), and 444 $(REF WindowsTimeZone,std,datetime,timezone). 445 446 `SysTime`'s range is from approximately 29,000 B.C. to approximately 447 29,000 A.D. 448 +/ 449 struct SysTime 450 { 451 import core.stdc.time : tm; 452 version (Posix) import core.sys.posix.sys.time : timeval; 453 import std.typecons : Rebindable; 454 455 public: 456 457 /++ 458 Params: 459 dateTime = The $(REF DateTime,std,datetime,date) to use to set 460 this $(LREF SysTime)'s internal std time. As 461 $(REF DateTime,std,datetime,date) has no concept of 462 time zone, tz is used as its time zone. 463 tz = The $(REF TimeZone,std,datetime,timezone) to use for this 464 $(LREF SysTime). If null, 465 $(REF LocalTime,std,datetime,timezone) will be used. The 466 given $(REF DateTime,std,datetime,date) is assumed to 467 be in the given time zone. 468 +/ 469 this(DateTime dateTime, immutable TimeZone tz = null) @safe nothrow 470 { 471 try 472 this(dateTime, Duration.zero, tz); 473 catch (Exception e) 474 assert(0, "SysTime's constructor threw when it shouldn't have."); 475 } 476 477 @safe unittest 478 { 479 static void test(DateTime dt, immutable TimeZone tz, long expected) 480 { 481 auto sysTime = SysTime(dt, tz); 482 assert(sysTime._stdTime == expected); 483 assert(sysTime._timezone is (tz is null ? LocalTime() : tz), format("Given DateTime: %s", dt)); 484 } 485 486 test(DateTime.init, UTC(), 0); 487 test(DateTime(1, 1, 1, 12, 30, 33), UTC(), 450_330_000_000L); 488 test(DateTime(0, 12, 31, 12, 30, 33), UTC(), -413_670_000_000L); 489 test(DateTime(1, 1, 1, 0, 0, 0), UTC(), 0); 490 test(DateTime(1, 1, 1, 0, 0, 1), UTC(), 10_000_000L); 491 test(DateTime(0, 12, 31, 23, 59, 59), UTC(), -10_000_000L); 492 493 test(DateTime(1, 1, 1, 0, 0, 0), new immutable SimpleTimeZone(dur!"minutes"(-60)), 36_000_000_000L); 494 test(DateTime(1, 1, 1, 0, 0, 0), new immutable SimpleTimeZone(Duration.zero), 0); 495 test(DateTime(1, 1, 1, 0, 0, 0), new immutable SimpleTimeZone(dur!"minutes"(60)), -36_000_000_000L); 496 497 static void testScope(scope ref DateTime dt) @safe 498 { 499 auto st = SysTime(dt); 500 } 501 } 502 503 /++ 504 Params: 505 dateTime = The $(REF DateTime,std,datetime,date) to use to set 506 this $(LREF SysTime)'s internal std time. As 507 $(REF DateTime,std,datetime,date) has no concept of 508 time zone, tz is used as its time zone. 509 fracSecs = The fractional seconds portion of the time. 510 tz = The $(REF TimeZone,std,datetime,timezone) to use for this 511 $(LREF SysTime). If null, 512 $(REF LocalTime,std,datetime,timezone) will be used. The 513 given $(REF DateTime,std,datetime,date) is assumed to 514 be in the given time zone. 515 516 Throws: 517 $(REF DateTimeException,std,datetime,date) if `fracSecs` is negative or if it's 518 greater than or equal to one second. 519 +/ 520 this(DateTime dateTime, Duration fracSecs, immutable TimeZone tz = null) @safe 521 { 522 enforce(fracSecs >= Duration.zero, new DateTimeException("A SysTime cannot have negative fractional seconds.")); 523 enforce(fracSecs < seconds(1), new DateTimeException("Fractional seconds must be less than one second.")); 524 auto nonNullTZ = tz is null ? LocalTime() : tz; 525 526 immutable dateDiff = dateTime.date - Date.init; 527 immutable todDiff = dateTime.timeOfDay - TimeOfDay.init; 528 529 immutable adjustedTime = dateDiff + todDiff + fracSecs; 530 immutable standardTime = nonNullTZ.tzToUTC(adjustedTime.total!"hnsecs"); 531 532 this(standardTime, nonNullTZ); 533 } 534 535 @safe unittest 536 { 537 import core.time; 538 static void test(DateTime dt, Duration fracSecs, immutable TimeZone tz, long expected) 539 { 540 auto sysTime = SysTime(dt, fracSecs, tz); 541 assert(sysTime._stdTime == expected); 542 assert(sysTime._timezone is (tz is null ? LocalTime() : tz), 543 format("Given DateTime: %s, Given Duration: %s", dt, fracSecs)); 544 } 545 546 test(DateTime.init, Duration.zero, UTC(), 0); 547 test(DateTime(1, 1, 1, 12, 30, 33), Duration.zero, UTC(), 450_330_000_000L); 548 test(DateTime(0, 12, 31, 12, 30, 33), Duration.zero, UTC(), -413_670_000_000L); 549 test(DateTime(1, 1, 1, 0, 0, 0), msecs(1), UTC(), 10_000L); 550 test(DateTime(0, 12, 31, 23, 59, 59), msecs(999), UTC(), -10_000L); 551 552 test(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC(), -1); 553 test(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC(), -9_999_999); 554 test(DateTime(0, 12, 31, 23, 59, 59), Duration.zero, UTC(), -10_000_000); 555 556 assertThrown!DateTimeException(SysTime(DateTime.init, hnsecs(-1), UTC())); 557 assertThrown!DateTimeException(SysTime(DateTime.init, seconds(1), UTC())); 558 559 static void testScope(scope ref DateTime dt, scope ref Duration d) @safe 560 { 561 auto st = SysTime(dt, d); 562 } 563 } 564 565 /++ 566 Params: 567 date = The $(REF Date,std,datetime,date) to use to set this 568 $(LREF SysTime)'s internal std time. As 569 $(REF Date,std,datetime,date) has no concept of time zone, tz 570 is used as its time zone. 571 tz = The $(REF TimeZone,std,datetime,timezone) to use for this 572 $(LREF SysTime). If null, 573 $(REF LocalTime,std,datetime,timezone) will be used. The 574 given $(REF Date,std,datetime,date) is assumed to be in the 575 given time zone. 576 +/ 577 this(Date date, immutable TimeZone tz = null) @safe nothrow 578 { 579 _timezone = tz is null ? LocalTime() : tz; 580 581 try 582 { 583 immutable adjustedTime = (date - Date(1, 1, 1)).total!"hnsecs"; 584 immutable standardTime = _timezone.tzToUTC(adjustedTime); 585 586 this(standardTime, _timezone); 587 } 588 catch (Exception e) 589 assert(0, "Date's constructor through when it shouldn't have."); 590 } 591 592 @safe unittest 593 { 594 static void test(Date d, immutable TimeZone tz, long expected) 595 { 596 auto sysTime = SysTime(d, tz); 597 assert(sysTime._stdTime == expected); 598 assert(sysTime._timezone is (tz is null ? LocalTime() : tz), format("Given Date: %s", d)); 599 } 600 601 test(Date.init, UTC(), 0); 602 test(Date(1, 1, 1), UTC(), 0); 603 test(Date(1, 1, 2), UTC(), 864000000000); 604 test(Date(0, 12, 31), UTC(), -864000000000); 605 606 static void testScope(scope ref Date d) @safe 607 { 608 auto st = SysTime(d); 609 } 610 } 611 612 /++ 613 Note: 614 Whereas the other constructors take in the given date/time, assume 615 that it's in the given time zone, and convert it to hnsecs in UTC 616 since midnight, January 1st, 1 A.D. UTC - i.e. std time - this 617 constructor takes a std time, which is specifically already in UTC, 618 so no conversion takes place. Of course, the various getter 619 properties and functions will use the given time zone's conversion 620 function to convert the results to that time zone, but no conversion 621 of the arguments to this constructor takes place. 622 623 Params: 624 stdTime = The number of hnsecs since midnight, January 1st, 1 A.D. 625 UTC. 626 tz = The $(REF TimeZone,std,datetime,timezone) to use for this 627 $(LREF SysTime). If null, 628 $(REF LocalTime,std,datetime,timezone) will be used. 629 +/ 630 this(long stdTime, immutable TimeZone tz = null) @safe pure nothrow 631 { 632 _stdTime = stdTime; 633 _timezone = tz is null ? LocalTime() : tz; 634 } 635 636 @safe unittest 637 { 638 static void test(long stdTime, immutable TimeZone tz) 639 { 640 auto sysTime = SysTime(stdTime, tz); 641 assert(sysTime._stdTime == stdTime); 642 assert(sysTime._timezone is (tz is null ? LocalTime() : tz), format("Given stdTime: %s", stdTime)); 643 } 644 645 foreach (stdTime; [-1234567890L, -250, 0, 250, 1235657390L]) 646 { 647 foreach (tz; testTZs) 648 test(stdTime, tz); 649 } 650 } 651 652 653 /++ 654 Params: 655 rhs = The $(LREF SysTime) to assign to this one. 656 657 Returns: The `this` of this `SysTime`. 658 +/ 659 ref SysTime opAssign()(auto ref const(SysTime) rhs) return @safe pure nothrow scope 660 { 661 _stdTime = rhs._stdTime; 662 _timezone = rhs._timezone; 663 return this; 664 } 665 666 @safe unittest 667 { 668 SysTime st; 669 st = SysTime(DateTime(2012, 12, 21, 1, 2, 3), UTC()); 670 assert(st == SysTime(DateTime(2012, 12, 21, 1, 2, 3), UTC())); 671 672 const other = SysTime(DateTime(19, 1, 7, 13, 14, 15), LocalTime()); 673 st = other; 674 assert(st == other); 675 676 static void testScope(scope ref SysTime left, const scope SysTime right) @safe 677 { 678 left = right; 679 } 680 } 681 682 683 /++ 684 Checks for equality between this $(LREF SysTime) and the given 685 $(LREF SysTime). 686 687 Note that the time zone is ignored. Only the internal 688 std times (which are in UTC) are compared. 689 +/ 690 bool opEquals()(auto ref const(SysTime) rhs) @safe const pure nothrow scope 691 { 692 return _stdTime == rhs._stdTime; 693 } 694 695 @safe unittest 696 { 697 import std.range : chain; 698 699 assert(SysTime(DateTime.init, UTC()) == SysTime(0, UTC())); 700 assert(SysTime(DateTime.init, UTC()) == SysTime(0)); 701 assert(SysTime(Date.init, UTC()) == SysTime(0)); 702 assert(SysTime(0) == SysTime(0)); 703 704 static void test(DateTime dt, immutable TimeZone tz1, immutable TimeZone tz2) 705 { 706 auto st1 = SysTime(dt); 707 st1.timezone = tz1; 708 709 auto st2 = SysTime(dt); 710 st2.timezone = tz2; 711 712 assert(st1 == st2); 713 } 714 715 foreach (tz1; testTZs) 716 { 717 foreach (tz2; testTZs) 718 { 719 foreach (dt; chain(testDateTimesBC, testDateTimesAD)) 720 test(dt, tz1, tz2); 721 } 722 } 723 724 auto st = SysTime(DateTime(1999, 7, 6, 12, 33, 30)); 725 const cst = SysTime(DateTime(1999, 7, 6, 12, 33, 30)); 726 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 33, 30)); 727 assert(st == st); 728 assert(st == cst); 729 assert(st == ist); 730 assert(cst == st); 731 assert(cst == cst); 732 assert(cst == ist); 733 assert(ist == st); 734 assert(ist == cst); 735 assert(ist == ist); 736 737 static void testScope(scope ref SysTime left, const scope SysTime right) @safe 738 { 739 assert(left == right); 740 assert(right == left); 741 } 742 } 743 744 745 /++ 746 Compares this $(LREF SysTime) with the given $(LREF SysTime). 747 748 Time zone is irrelevant when comparing $(LREF SysTime)s. 749 750 Returns: 751 $(BOOKTABLE, 752 $(TR $(TD this < rhs) $(TD < 0)) 753 $(TR $(TD this == rhs) $(TD 0)) 754 $(TR $(TD this > rhs) $(TD > 0)) 755 ) 756 +/ 757 int opCmp()(auto ref const(SysTime) rhs) @safe const pure nothrow scope 758 { 759 if (_stdTime < rhs._stdTime) 760 return -1; 761 if (_stdTime > rhs._stdTime) 762 return 1; 763 return 0; 764 } 765 766 @safe unittest 767 { 768 import std.algorithm.iteration : map; 769 import std.array : array; 770 import std.range : chain; 771 772 assert(SysTime(DateTime.init, UTC()).opCmp(SysTime(0, UTC())) == 0); 773 assert(SysTime(DateTime.init, UTC()).opCmp(SysTime(0)) == 0); 774 assert(SysTime(Date.init, UTC()).opCmp(SysTime(0)) == 0); 775 assert(SysTime(0).opCmp(SysTime(0)) == 0); 776 777 static void testEqual(SysTime st, immutable TimeZone tz1, immutable TimeZone tz2) 778 { 779 auto st1 = st; 780 st1.timezone = tz1; 781 782 auto st2 = st; 783 st2.timezone = tz2; 784 785 assert(st1.opCmp(st2) == 0); 786 } 787 788 auto sts = array(map!SysTime(chain(testDateTimesBC, testDateTimesAD))); 789 790 foreach (st; sts) 791 { 792 foreach (tz1; testTZs) 793 { 794 foreach (tz2; testTZs) 795 testEqual(st, tz1, tz2); 796 } 797 } 798 799 static void testCmp(SysTime st1, immutable TimeZone tz1, SysTime st2, immutable TimeZone tz2) 800 { 801 st1.timezone = tz1; 802 st2.timezone = tz2; 803 assert(st1.opCmp(st2) < 0); 804 assert(st2.opCmp(st1) > 0); 805 } 806 807 foreach (si, st1; sts) 808 { 809 foreach (st2; sts[si + 1 .. $]) 810 { 811 foreach (tz1; testTZs) 812 { 813 foreach (tz2; testTZs) 814 testCmp(st1, tz1, st2, tz2); 815 } 816 } 817 } 818 819 auto st = SysTime(DateTime(1999, 7, 6, 12, 33, 30)); 820 const cst = SysTime(DateTime(1999, 7, 6, 12, 33, 30)); 821 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 33, 30)); 822 assert(st.opCmp(st) == 0); 823 assert(st.opCmp(cst) == 0); 824 assert(st.opCmp(ist) == 0); 825 assert(cst.opCmp(st) == 0); 826 assert(cst.opCmp(cst) == 0); 827 assert(cst.opCmp(ist) == 0); 828 assert(ist.opCmp(st) == 0); 829 assert(ist.opCmp(cst) == 0); 830 assert(ist.opCmp(ist) == 0); 831 832 static void testScope(scope ref SysTime left, const scope SysTime right) @safe 833 { 834 assert(left < right); 835 assert(right > left); 836 } 837 } 838 839 840 /++ 841 Returns: A hash of the $(LREF SysTime). 842 +/ 843 size_t toHash() const @nogc pure nothrow @safe scope 844 { 845 static if (is(size_t == ulong)) 846 return _stdTime; 847 else 848 { 849 // MurmurHash2 850 enum ulong m = 0xc6a4a7935bd1e995UL; 851 enum ulong n = m * 16; 852 enum uint r = 47; 853 854 ulong k = _stdTime; 855 k *= m; 856 k ^= k >> r; 857 k *= m; 858 859 ulong h = n; 860 h ^= k; 861 h *= m; 862 863 return cast(size_t) h; 864 } 865 } 866 867 @safe unittest 868 { 869 assert(SysTime(0).toHash == SysTime(0).toHash); 870 assert(SysTime(DateTime(2000, 1, 1)).toHash == SysTime(DateTime(2000, 1, 1)).toHash); 871 assert(SysTime(DateTime(2000, 1, 1)).toHash != SysTime(DateTime(2000, 1, 2)).toHash); 872 873 // test that timezones aren't taken into account 874 assert(SysTime(0, LocalTime()).toHash == SysTime(0, LocalTime()).toHash); 875 assert(SysTime(0, LocalTime()).toHash == SysTime(0, UTC()).toHash); 876 assert(SysTime(DateTime(2000, 1, 1), LocalTime()).toHash == SysTime(DateTime(2000, 1, 1), LocalTime()).toHash); 877 immutable zone = new SimpleTimeZone(dur!"minutes"(60)); 878 assert(SysTime(DateTime(2000, 1, 1, 1), zone).toHash == SysTime(DateTime(2000, 1, 1), UTC()).toHash); 879 assert(SysTime(DateTime(2000, 1, 1), zone).toHash != SysTime(DateTime(2000, 1, 1), UTC()).toHash); 880 881 static void testScope(scope ref SysTime st) @safe 882 { 883 auto result = st.toHash(); 884 } 885 } 886 887 888 /++ 889 Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive 890 are B.C. 891 +/ 892 @property short year() @safe const nothrow scope 893 { 894 return (cast(Date) this).year; 895 } 896 897 @safe unittest 898 { 899 import std.range : chain; 900 static void test(SysTime sysTime, long expected) 901 { 902 assert(sysTime.year == expected, format("Value given: %s", sysTime)); 903 } 904 905 test(SysTime(0, UTC()), 1); 906 test(SysTime(1, UTC()), 1); 907 test(SysTime(-1, UTC()), 0); 908 909 foreach (year; chain(testYearsBC, testYearsAD)) 910 { 911 foreach (md; testMonthDays) 912 { 913 foreach (tod; testTODs) 914 { 915 auto dt = DateTime(Date(year, md.month, md.day), tod); 916 foreach (tz; testTZs) 917 { 918 foreach (fs; testFracSecs) 919 test(SysTime(dt, fs, tz), year); 920 } 921 } 922 } 923 } 924 925 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 926 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 927 assert(cst.year == 1999); 928 assert(ist.year == 1999); 929 930 static void testScope(scope ref SysTime st) @safe 931 { 932 auto result = st.year; 933 } 934 } 935 936 /++ 937 Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive 938 are B.C. 939 940 Params: 941 year = The year to set this $(LREF SysTime)'s year to. 942 943 Throws: 944 $(REF DateTimeException,std,datetime,date) if the new year is not 945 a leap year and the resulting date would be on February 29th. 946 +/ 947 @property void year(int year) @safe scope 948 { 949 auto hnsecs = adjTime; 950 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 951 952 if (hnsecs < 0) 953 { 954 hnsecs += convert!("hours", "hnsecs")(24); 955 --days; 956 } 957 958 auto date = Date(cast(int) days); 959 date.year = year; 960 961 immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1); 962 adjTime = newDaysHNSecs + hnsecs; 963 } 964 965 /// 966 @safe unittest 967 { 968 import std.datetime.date : DateTime; 969 970 assert(SysTime(DateTime(1999, 7, 6, 9, 7, 5)).year == 1999); 971 assert(SysTime(DateTime(2010, 10, 4, 0, 0, 30)).year == 2010); 972 assert(SysTime(DateTime(-7, 4, 5, 7, 45, 2)).year == -7); 973 } 974 975 @safe unittest 976 { 977 import std.range : chain; 978 979 static void test(SysTime st, int year, SysTime expected) 980 { 981 st.year = year; 982 assert(st == expected); 983 } 984 985 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 986 { 987 auto dt = cast(DateTime) st; 988 989 foreach (year; chain(testYearsBC, testYearsAD)) 990 { 991 auto e = SysTime(DateTime(year, dt.month, dt.day, dt.hour, dt.minute, dt.second), 992 st.fracSecs, 993 st.timezone); 994 test(st, year, e); 995 } 996 } 997 998 foreach (fs; testFracSecs) 999 { 1000 foreach (tz; testTZs) 1001 { 1002 foreach (tod; testTODs) 1003 { 1004 test(SysTime(DateTime(Date(1999, 2, 28), tod), fs, tz), 2000, 1005 SysTime(DateTime(Date(2000, 2, 28), tod), fs, tz)); 1006 test(SysTime(DateTime(Date(2000, 2, 28), tod), fs, tz), 1999, 1007 SysTime(DateTime(Date(1999, 2, 28), tod), fs, tz)); 1008 } 1009 1010 foreach (tod; testTODsThrown) 1011 { 1012 auto st = SysTime(DateTime(Date(2000, 2, 29), tod), fs, tz); 1013 assertThrown!DateTimeException(st.year = 1999); 1014 } 1015 } 1016 } 1017 1018 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1019 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1020 static assert(!__traits(compiles, cst.year = 7)); 1021 static assert(!__traits(compiles, ist.year = 7)); 1022 1023 static void testScope(scope ref SysTime st) @safe 1024 { 1025 st.year = 42; 1026 } 1027 } 1028 1029 /++ 1030 Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C. 1031 1032 Throws: 1033 $(REF DateTimeException,std,datetime,date) if `isAD` is true. 1034 +/ 1035 @property ushort yearBC() @safe const scope 1036 { 1037 return (cast(Date) this).yearBC; 1038 } 1039 1040 /// 1041 @safe unittest 1042 { 1043 import std.datetime.date : DateTime; 1044 1045 assert(SysTime(DateTime(0, 1, 1, 12, 30, 33)).yearBC == 1); 1046 assert(SysTime(DateTime(-1, 1, 1, 10, 7, 2)).yearBC == 2); 1047 assert(SysTime(DateTime(-100, 1, 1, 4, 59, 0)).yearBC == 101); 1048 } 1049 1050 @safe unittest 1051 { 1052 import std.exception : assertNotThrown; 1053 foreach (st; testSysTimesBC) 1054 { 1055 auto msg = format("SysTime: %s", st); 1056 assertNotThrown!DateTimeException(st.yearBC, msg); 1057 assert(st.yearBC == (st.year * -1) + 1, msg); 1058 } 1059 1060 foreach (st; [testSysTimesAD[0], testSysTimesAD[$/2], testSysTimesAD[$-1]]) 1061 assertThrown!DateTimeException(st.yearBC, format("SysTime: %s", st)); 1062 1063 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1064 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1065 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1066 st.year = 12; 1067 assert(st.year == 12); 1068 static assert(!__traits(compiles, cst.year = 12)); 1069 static assert(!__traits(compiles, ist.year = 12)); 1070 1071 static void testScope(scope ref SysTime st) @safe 1072 { 1073 auto result = st.yearBC; 1074 } 1075 } 1076 1077 1078 /++ 1079 Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C. 1080 1081 Params: 1082 year = The year B.C. to set this $(LREF SysTime)'s year to. 1083 1084 Throws: 1085 $(REF DateTimeException,std,datetime,date) if a non-positive value 1086 is given. 1087 +/ 1088 @property void yearBC(int year) @safe scope 1089 { 1090 auto hnsecs = adjTime; 1091 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 1092 1093 if (hnsecs < 0) 1094 { 1095 hnsecs += convert!("hours", "hnsecs")(24); 1096 --days; 1097 } 1098 1099 auto date = Date(cast(int) days); 1100 date.yearBC = year; 1101 1102 immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1); 1103 adjTime = newDaysHNSecs + hnsecs; 1104 } 1105 1106 @safe unittest 1107 { 1108 auto st = SysTime(DateTime(2010, 1, 1, 7, 30, 0)); 1109 st.yearBC = 1; 1110 assert(st == SysTime(DateTime(0, 1, 1, 7, 30, 0))); 1111 1112 st.yearBC = 10; 1113 assert(st == SysTime(DateTime(-9, 1, 1, 7, 30, 0))); 1114 } 1115 1116 @safe unittest 1117 { 1118 import std.range : chain; 1119 static void test(SysTime st, int year, SysTime expected) 1120 { 1121 st.yearBC = year; 1122 assert(st == expected, format("SysTime: %s", st)); 1123 } 1124 1125 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 1126 { 1127 auto dt = cast(DateTime) st; 1128 1129 foreach (year; testYearsBC) 1130 { 1131 auto e = SysTime(DateTime(year, dt.month, dt.day, dt.hour, dt.minute, dt.second), 1132 st.fracSecs, 1133 st.timezone); 1134 test(st, (year * -1) + 1, e); 1135 } 1136 } 1137 1138 foreach (st; [testSysTimesBC[0], testSysTimesBC[$ - 1], testSysTimesAD[0], testSysTimesAD[$ - 1]]) 1139 { 1140 foreach (year; testYearsBC) 1141 assertThrown!DateTimeException(st.yearBC = year); 1142 } 1143 1144 foreach (fs; testFracSecs) 1145 { 1146 foreach (tz; testTZs) 1147 { 1148 foreach (tod; testTODs) 1149 { 1150 test(SysTime(DateTime(Date(-1999, 2, 28), tod), fs, tz), 2001, 1151 SysTime(DateTime(Date(-2000, 2, 28), tod), fs, tz)); 1152 test(SysTime(DateTime(Date(-2000, 2, 28), tod), fs, tz), 2000, 1153 SysTime(DateTime(Date(-1999, 2, 28), tod), fs, tz)); 1154 } 1155 1156 foreach (tod; testTODsThrown) 1157 { 1158 auto st = SysTime(DateTime(Date(-2000, 2, 29), tod), fs, tz); 1159 assertThrown!DateTimeException(st.year = -1999); 1160 } 1161 } 1162 } 1163 1164 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1165 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1166 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1167 st.yearBC = 12; 1168 assert(st.yearBC == 12); 1169 static assert(!__traits(compiles, cst.yearBC = 12)); 1170 static assert(!__traits(compiles, ist.yearBC = 12)); 1171 1172 static void testScope(scope ref SysTime st) @safe 1173 { 1174 st.yearBC = 42; 1175 } 1176 } 1177 1178 1179 /++ 1180 Month of a Gregorian Year. 1181 +/ 1182 @property Month month() @safe const nothrow scope 1183 { 1184 return (cast(Date) this).month; 1185 } 1186 1187 /// 1188 @safe unittest 1189 { 1190 import std.datetime.date : DateTime; 1191 1192 assert(SysTime(DateTime(1999, 7, 6, 9, 7, 5)).month == 7); 1193 assert(SysTime(DateTime(2010, 10, 4, 0, 0, 30)).month == 10); 1194 assert(SysTime(DateTime(-7, 4, 5, 7, 45, 2)).month == 4); 1195 } 1196 1197 @safe unittest 1198 { 1199 import std.range : chain; 1200 1201 static void test(SysTime sysTime, Month expected) 1202 { 1203 assert(sysTime.month == expected, format("Value given: %s", sysTime)); 1204 } 1205 1206 test(SysTime(0, UTC()), Month.jan); 1207 test(SysTime(1, UTC()), Month.jan); 1208 test(SysTime(-1, UTC()), Month.dec); 1209 1210 foreach (year; chain(testYearsBC, testYearsAD)) 1211 { 1212 foreach (md; testMonthDays) 1213 { 1214 foreach (tod; testTODs) 1215 { 1216 auto dt = DateTime(Date(year, md.month, md.day), tod); 1217 foreach (fs; testFracSecs) 1218 { 1219 foreach (tz; testTZs) 1220 test(SysTime(dt, fs, tz), md.month); 1221 } 1222 } 1223 } 1224 } 1225 1226 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1227 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1228 assert(cst.month == 7); 1229 assert(ist.month == 7); 1230 1231 static void testScope(scope ref SysTime st) @safe 1232 { 1233 auto result = st.month; 1234 } 1235 } 1236 1237 1238 /++ 1239 Month of a Gregorian Year. 1240 1241 Params: 1242 month = The month to set this $(LREF SysTime)'s month to. 1243 1244 Throws: 1245 $(REF DateTimeException,std,datetime,date) if the given month is 1246 not a valid month. 1247 +/ 1248 @property void month(Month month) @safe scope 1249 { 1250 auto hnsecs = adjTime; 1251 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 1252 1253 if (hnsecs < 0) 1254 { 1255 hnsecs += convert!("hours", "hnsecs")(24); 1256 --days; 1257 } 1258 1259 auto date = Date(cast(int) days); 1260 date.month = month; 1261 1262 immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1); 1263 adjTime = newDaysHNSecs + hnsecs; 1264 } 1265 1266 @safe unittest 1267 { 1268 import std.algorithm.iteration : filter; 1269 import std.range : chain; 1270 1271 static void test(SysTime st, Month month, SysTime expected) 1272 { 1273 st.month = cast(Month) month; 1274 assert(st == expected); 1275 } 1276 1277 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 1278 { 1279 auto dt = cast(DateTime) st; 1280 1281 foreach (md; testMonthDays) 1282 { 1283 if (st.day > maxDay(dt.year, md.month)) 1284 continue; 1285 auto e = SysTime(DateTime(dt.year, md.month, dt.day, dt.hour, dt.minute, dt.second), 1286 st.fracSecs, 1287 st.timezone); 1288 test(st, md.month, e); 1289 } 1290 } 1291 1292 foreach (fs; testFracSecs) 1293 { 1294 foreach (tz; testTZs) 1295 { 1296 foreach (tod; testTODs) 1297 { 1298 foreach (year; filter!((a){return yearIsLeapYear(a);}) (chain(testYearsBC, testYearsAD))) 1299 { 1300 test(SysTime(DateTime(Date(year, 1, 29), tod), fs, tz), 1301 Month.feb, 1302 SysTime(DateTime(Date(year, 2, 29), tod), fs, tz)); 1303 } 1304 1305 foreach (year; chain(testYearsBC, testYearsAD)) 1306 { 1307 test(SysTime(DateTime(Date(year, 1, 28), tod), fs, tz), 1308 Month.feb, 1309 SysTime(DateTime(Date(year, 2, 28), tod), fs, tz)); 1310 test(SysTime(DateTime(Date(year, 7, 30), tod), fs, tz), 1311 Month.jun, 1312 SysTime(DateTime(Date(year, 6, 30), tod), fs, tz)); 1313 } 1314 } 1315 } 1316 } 1317 1318 foreach (fs; [testFracSecs[0], testFracSecs[$-1]]) 1319 { 1320 foreach (tz; testTZs) 1321 { 1322 foreach (tod; testTODsThrown) 1323 { 1324 foreach (year; [testYearsBC[$-3], testYearsBC[$-2], 1325 testYearsBC[$-2], testYearsAD[0], 1326 testYearsAD[$-2], testYearsAD[$-1]]) 1327 { 1328 auto day = yearIsLeapYear(year) ? 30 : 29; 1329 auto st1 = SysTime(DateTime(Date(year, 1, day), tod), fs, tz); 1330 assertThrown!DateTimeException(st1.month = Month.feb); 1331 1332 auto st2 = SysTime(DateTime(Date(year, 7, 31), tod), fs, tz); 1333 assertThrown!DateTimeException(st2.month = Month.jun); 1334 } 1335 } 1336 } 1337 } 1338 1339 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1340 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1341 static assert(!__traits(compiles, cst.month = Month.dec)); 1342 static assert(!__traits(compiles, ist.month = Month.dec)); 1343 1344 static void testScope(scope ref SysTime st) @safe 1345 { 1346 st.month = Month.dec; 1347 } 1348 } 1349 1350 /++ 1351 Day of a Gregorian Month. 1352 +/ 1353 @property ubyte day() @safe const nothrow scope 1354 { 1355 return (cast(Date) this).day; 1356 } 1357 1358 /// 1359 @safe unittest 1360 { 1361 import std.datetime.date : DateTime; 1362 1363 assert(SysTime(DateTime(1999, 7, 6, 9, 7, 5)).day == 6); 1364 assert(SysTime(DateTime(2010, 10, 4, 0, 0, 30)).day == 4); 1365 assert(SysTime(DateTime(-7, 4, 5, 7, 45, 2)).day == 5); 1366 } 1367 1368 @safe unittest 1369 { 1370 import std.range : chain; 1371 1372 static void test(SysTime sysTime, int expected) 1373 { 1374 assert(sysTime.day == expected, format("Value given: %s", sysTime)); 1375 } 1376 1377 test(SysTime(0, UTC()), 1); 1378 test(SysTime(1, UTC()), 1); 1379 test(SysTime(-1, UTC()), 31); 1380 1381 foreach (year; chain(testYearsBC, testYearsAD)) 1382 { 1383 foreach (md; testMonthDays) 1384 { 1385 foreach (tod; testTODs) 1386 { 1387 auto dt = DateTime(Date(year, md.month, md.day), tod); 1388 1389 foreach (tz; testTZs) 1390 { 1391 foreach (fs; testFracSecs) 1392 test(SysTime(dt, fs, tz), md.day); 1393 } 1394 } 1395 } 1396 } 1397 1398 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1399 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1400 assert(cst.day == 6); 1401 assert(ist.day == 6); 1402 1403 static void testScope(scope ref SysTime st) @safe 1404 { 1405 auto result = st.day; 1406 } 1407 } 1408 1409 1410 /++ 1411 Day of a Gregorian Month. 1412 1413 Params: 1414 day = The day of the month to set this $(LREF SysTime)'s day to. 1415 1416 Throws: 1417 $(REF DateTimeException,std,datetime,date) if the given day is not 1418 a valid day of the current month. 1419 +/ 1420 @property void day(int day) @safe scope 1421 { 1422 auto hnsecs = adjTime; 1423 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 1424 1425 if (hnsecs < 0) 1426 { 1427 hnsecs += convert!("hours", "hnsecs")(24); 1428 --days; 1429 } 1430 1431 auto date = Date(cast(int) days); 1432 date.day = day; 1433 1434 immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1); 1435 adjTime = newDaysHNSecs + hnsecs; 1436 } 1437 1438 @safe unittest 1439 { 1440 import std.range : chain; 1441 import std.traits : EnumMembers; 1442 1443 foreach (day; chain(testDays)) 1444 { 1445 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 1446 { 1447 auto dt = cast(DateTime) st; 1448 1449 if (day > maxDay(dt.year, dt.month)) 1450 continue; 1451 auto expected = SysTime(DateTime(dt.year, dt.month, day, dt.hour, dt.minute, dt.second), 1452 st.fracSecs, 1453 st.timezone); 1454 st.day = day; 1455 assert(st == expected, format("[%s] [%s]", st, expected)); 1456 } 1457 } 1458 1459 foreach (tz; testTZs) 1460 { 1461 foreach (tod; testTODs) 1462 { 1463 foreach (fs; testFracSecs) 1464 { 1465 foreach (year; chain(testYearsBC, testYearsAD)) 1466 { 1467 foreach (month; EnumMembers!Month) 1468 { 1469 auto st = SysTime(DateTime(Date(year, month, 1), tod), fs, tz); 1470 immutable max = maxDay(year, month); 1471 auto expected = SysTime(DateTime(Date(year, month, max), tod), fs, tz); 1472 1473 st.day = max; 1474 assert(st == expected, format("[%s] [%s]", st, expected)); 1475 } 1476 } 1477 } 1478 } 1479 } 1480 1481 foreach (tz; testTZs) 1482 { 1483 foreach (tod; testTODsThrown) 1484 { 1485 foreach (fs; [testFracSecs[0], testFracSecs[$-1]]) 1486 { 1487 foreach (year; [testYearsBC[$-3], testYearsBC[$-2], 1488 testYearsBC[$-2], testYearsAD[0], 1489 testYearsAD[$-2], testYearsAD[$-1]]) 1490 { 1491 foreach (month; EnumMembers!Month) 1492 { 1493 auto st = SysTime(DateTime(Date(year, month, 1), tod), fs, tz); 1494 immutable max = maxDay(year, month); 1495 1496 assertThrown!DateTimeException(st.day = max + 1); 1497 } 1498 } 1499 } 1500 } 1501 } 1502 1503 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1504 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1505 static assert(!__traits(compiles, cst.day = 27)); 1506 static assert(!__traits(compiles, ist.day = 27)); 1507 1508 static void testScope(scope ref SysTime st) @safe 1509 { 1510 st.day = 12; 1511 } 1512 } 1513 1514 1515 /++ 1516 Hours past midnight. 1517 +/ 1518 @property ubyte hour() @safe const nothrow scope 1519 { 1520 auto hnsecs = adjTime; 1521 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 1522 1523 if (hnsecs < 0) 1524 { 1525 hnsecs += convert!("hours", "hnsecs")(24); 1526 --days; 1527 } 1528 1529 return cast(ubyte) getUnitsFromHNSecs!"hours"(hnsecs); 1530 } 1531 1532 @safe unittest 1533 { 1534 import std.range : chain; 1535 1536 static void test(SysTime sysTime, int expected) 1537 { 1538 assert(sysTime.hour == expected, format("Value given: %s", sysTime)); 1539 } 1540 1541 test(SysTime(0, UTC()), 0); 1542 test(SysTime(1, UTC()), 0); 1543 test(SysTime(-1, UTC()), 23); 1544 1545 foreach (tz; testTZs) 1546 { 1547 foreach (year; chain(testYearsBC, testYearsAD)) 1548 { 1549 foreach (md; testMonthDays) 1550 { 1551 foreach (hour; testHours) 1552 { 1553 foreach (minute; testMinSecs) 1554 { 1555 foreach (second; testMinSecs) 1556 { 1557 auto dt = DateTime(Date(year, md.month, md.day), TimeOfDay(hour, minute, second)); 1558 foreach (fs; testFracSecs) 1559 test(SysTime(dt, fs, tz), hour); 1560 } 1561 } 1562 } 1563 } 1564 } 1565 } 1566 1567 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1568 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1569 assert(cst.hour == 12); 1570 assert(ist.hour == 12); 1571 1572 static void testScope(scope ref SysTime st) @safe 1573 { 1574 auto result = st.hour; 1575 } 1576 } 1577 1578 1579 /++ 1580 Hours past midnight. 1581 1582 Params: 1583 hour = The hours to set this $(LREF SysTime)'s hour to. 1584 1585 Throws: 1586 $(REF DateTimeException,std,datetime,date) if the given hour are 1587 not a valid hour of the day. 1588 +/ 1589 @property void hour(int hour) @safe scope 1590 { 1591 enforceValid!"hours"(hour); 1592 1593 auto hnsecs = adjTime; 1594 auto days = splitUnitsFromHNSecs!"days"(hnsecs); 1595 immutable daysHNSecs = convert!("days", "hnsecs")(days); 1596 immutable negative = hnsecs < 0; 1597 1598 if (negative) 1599 hnsecs += convert!("hours", "hnsecs")(24); 1600 1601 hnsecs = removeUnitsFromHNSecs!"hours"(hnsecs); 1602 hnsecs += convert!("hours", "hnsecs")(hour); 1603 1604 if (negative) 1605 hnsecs -= convert!("hours", "hnsecs")(24); 1606 1607 adjTime = daysHNSecs + hnsecs; 1608 } 1609 1610 @safe unittest 1611 { 1612 import std.range : chain; 1613 1614 foreach (hour; chain(testHours)) 1615 { 1616 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 1617 { 1618 auto dt = cast(DateTime) st; 1619 auto expected = SysTime(DateTime(dt.year, dt.month, dt.day, hour, dt.minute, dt.second), 1620 st.fracSecs, 1621 st.timezone); 1622 st.hour = hour; 1623 assert(st == expected, format("[%s] [%s]", st, expected)); 1624 } 1625 } 1626 1627 auto st = testSysTimesAD[0]; 1628 assertThrown!DateTimeException(st.hour = -1); 1629 assertThrown!DateTimeException(st.hour = 60); 1630 1631 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1632 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1633 static assert(!__traits(compiles, cst.hour = 27)); 1634 static assert(!__traits(compiles, ist.hour = 27)); 1635 1636 static void testScope(scope ref SysTime st) @safe 1637 { 1638 st.hour = 12; 1639 } 1640 } 1641 1642 1643 /++ 1644 Minutes past the current hour. 1645 +/ 1646 @property ubyte minute() @safe const nothrow scope 1647 { 1648 auto hnsecs = adjTime; 1649 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 1650 1651 if (hnsecs < 0) 1652 { 1653 hnsecs += convert!("hours", "hnsecs")(24); 1654 --days; 1655 } 1656 1657 hnsecs = removeUnitsFromHNSecs!"hours"(hnsecs); 1658 1659 return cast(ubyte) getUnitsFromHNSecs!"minutes"(hnsecs); 1660 } 1661 1662 @safe unittest 1663 { 1664 import std.range : chain; 1665 1666 static void test(SysTime sysTime, int expected) 1667 { 1668 assert(sysTime.minute == expected, format("Value given: %s", sysTime)); 1669 } 1670 1671 test(SysTime(0, UTC()), 0); 1672 test(SysTime(1, UTC()), 0); 1673 test(SysTime(-1, UTC()), 59); 1674 1675 foreach (tz; testTZs) 1676 { 1677 foreach (year; chain(testYearsBC, testYearsAD)) 1678 { 1679 foreach (md; testMonthDays) 1680 { 1681 foreach (hour; testHours) 1682 { 1683 foreach (minute; testMinSecs) 1684 { 1685 foreach (second; testMinSecs) 1686 { 1687 auto dt = DateTime(Date(year, md.month, md.day), TimeOfDay(hour, minute, second)); 1688 foreach (fs; testFracSecs) 1689 test(SysTime(dt, fs, tz), minute); 1690 } 1691 } 1692 } 1693 } 1694 } 1695 } 1696 1697 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1698 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1699 assert(cst.minute == 30); 1700 assert(ist.minute == 30); 1701 1702 static void testScope(scope ref SysTime st) @safe 1703 { 1704 auto result = st.minute; 1705 } 1706 } 1707 1708 1709 /++ 1710 Minutes past the current hour. 1711 1712 Params: 1713 minute = The minute to set this $(LREF SysTime)'s minute to. 1714 1715 Throws: 1716 $(REF DateTimeException,std,datetime,date) if the given minute are 1717 not a valid minute of an hour. 1718 +/ 1719 @property void minute(int minute) @safe scope 1720 { 1721 enforceValid!"minutes"(minute); 1722 1723 auto hnsecs = adjTime; 1724 auto days = splitUnitsFromHNSecs!"days"(hnsecs); 1725 immutable daysHNSecs = convert!("days", "hnsecs")(days); 1726 immutable negative = hnsecs < 0; 1727 1728 if (negative) 1729 hnsecs += convert!("hours", "hnsecs")(24); 1730 1731 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 1732 hnsecs = removeUnitsFromHNSecs!"minutes"(hnsecs); 1733 1734 hnsecs += convert!("hours", "hnsecs")(hour); 1735 hnsecs += convert!("minutes", "hnsecs")(minute); 1736 1737 if (negative) 1738 hnsecs -= convert!("hours", "hnsecs")(24); 1739 1740 adjTime = daysHNSecs + hnsecs; 1741 } 1742 1743 @safe unittest 1744 { 1745 import std.range : chain; 1746 1747 foreach (minute; testMinSecs) 1748 { 1749 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 1750 { 1751 auto dt = cast(DateTime) st; 1752 auto expected = SysTime(DateTime(dt.year, dt.month, dt.day, dt.hour, minute, dt.second), 1753 st.fracSecs, 1754 st.timezone); 1755 st.minute = minute; 1756 assert(st == expected, format("[%s] [%s]", st, expected)); 1757 } 1758 } 1759 1760 auto st = testSysTimesAD[0]; 1761 assertThrown!DateTimeException(st.minute = -1); 1762 assertThrown!DateTimeException(st.minute = 60); 1763 1764 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1765 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1766 static assert(!__traits(compiles, cst.minute = 27)); 1767 static assert(!__traits(compiles, ist.minute = 27)); 1768 1769 static void testScope(scope ref SysTime st) @safe 1770 { 1771 st.minute = 12; 1772 } 1773 } 1774 1775 1776 /++ 1777 Seconds past the current minute. 1778 +/ 1779 @property ubyte second() @safe const nothrow scope 1780 { 1781 auto hnsecs = adjTime; 1782 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 1783 1784 if (hnsecs < 0) 1785 { 1786 hnsecs += convert!("hours", "hnsecs")(24); 1787 --days; 1788 } 1789 1790 hnsecs = removeUnitsFromHNSecs!"hours"(hnsecs); 1791 hnsecs = removeUnitsFromHNSecs!"minutes"(hnsecs); 1792 1793 return cast(ubyte) getUnitsFromHNSecs!"seconds"(hnsecs); 1794 } 1795 1796 @safe unittest 1797 { 1798 import std.range : chain; 1799 1800 static void test(SysTime sysTime, int expected) 1801 { 1802 assert(sysTime.second == expected, format("Value given: %s", sysTime)); 1803 } 1804 1805 test(SysTime(0, UTC()), 0); 1806 test(SysTime(1, UTC()), 0); 1807 test(SysTime(-1, UTC()), 59); 1808 1809 foreach (tz; testTZs) 1810 { 1811 foreach (year; chain(testYearsBC, testYearsAD)) 1812 { 1813 foreach (md; testMonthDays) 1814 { 1815 foreach (hour; testHours) 1816 { 1817 foreach (minute; testMinSecs) 1818 { 1819 foreach (second; testMinSecs) 1820 { 1821 auto dt = DateTime(Date(year, md.month, md.day), TimeOfDay(hour, minute, second)); 1822 foreach (fs; testFracSecs) 1823 test(SysTime(dt, fs, tz), second); 1824 } 1825 } 1826 } 1827 } 1828 } 1829 } 1830 1831 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1832 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1833 assert(cst.second == 33); 1834 assert(ist.second == 33); 1835 1836 static void testScope(scope ref SysTime st) @safe 1837 { 1838 auto result = st.second; 1839 } 1840 } 1841 1842 1843 /++ 1844 Seconds past the current minute. 1845 1846 Params: 1847 second = The second to set this $(LREF SysTime)'s second to. 1848 1849 Throws: 1850 $(REF DateTimeException,std,datetime,date) if the given second are 1851 not a valid second of a minute. 1852 +/ 1853 @property void second(int second) @safe scope 1854 { 1855 enforceValid!"seconds"(second); 1856 1857 auto hnsecs = adjTime; 1858 auto days = splitUnitsFromHNSecs!"days"(hnsecs); 1859 immutable daysHNSecs = convert!("days", "hnsecs")(days); 1860 immutable negative = hnsecs < 0; 1861 1862 if (negative) 1863 hnsecs += convert!("hours", "hnsecs")(24); 1864 1865 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 1866 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 1867 hnsecs = removeUnitsFromHNSecs!"seconds"(hnsecs); 1868 1869 hnsecs += convert!("hours", "hnsecs")(hour); 1870 hnsecs += convert!("minutes", "hnsecs")(minute); 1871 hnsecs += convert!("seconds", "hnsecs")(second); 1872 1873 if (negative) 1874 hnsecs -= convert!("hours", "hnsecs")(24); 1875 1876 adjTime = daysHNSecs + hnsecs; 1877 } 1878 1879 @safe unittest 1880 { 1881 import std.range : chain; 1882 1883 foreach (second; testMinSecs) 1884 { 1885 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 1886 { 1887 auto dt = cast(DateTime) st; 1888 auto expected = SysTime(DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, second), 1889 st.fracSecs, 1890 st.timezone); 1891 st.second = second; 1892 assert(st == expected, format("[%s] [%s]", st, expected)); 1893 } 1894 } 1895 1896 auto st = testSysTimesAD[0]; 1897 assertThrown!DateTimeException(st.second = -1); 1898 assertThrown!DateTimeException(st.second = 60); 1899 1900 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1901 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1902 static assert(!__traits(compiles, cst.seconds = 27)); 1903 static assert(!__traits(compiles, ist.seconds = 27)); 1904 1905 static void testScope(scope ref SysTime st) @safe 1906 { 1907 st.second = 12; 1908 } 1909 } 1910 1911 1912 /++ 1913 Fractional seconds past the second (i.e. the portion of a 1914 $(LREF SysTime) which is less than a second). 1915 +/ 1916 @property Duration fracSecs() @safe const nothrow scope 1917 { 1918 auto hnsecs = removeUnitsFromHNSecs!"days"(adjTime); 1919 1920 if (hnsecs < 0) 1921 hnsecs += convert!("hours", "hnsecs")(24); 1922 1923 return dur!"hnsecs"(removeUnitsFromHNSecs!"seconds"(hnsecs)); 1924 } 1925 1926 /// 1927 @safe unittest 1928 { 1929 import core.time : msecs, usecs, hnsecs, nsecs; 1930 import std.datetime.date : DateTime; 1931 1932 auto dt = DateTime(1982, 4, 1, 20, 59, 22); 1933 assert(SysTime(dt, msecs(213)).fracSecs == msecs(213)); 1934 assert(SysTime(dt, usecs(5202)).fracSecs == usecs(5202)); 1935 assert(SysTime(dt, hnsecs(1234567)).fracSecs == hnsecs(1234567)); 1936 1937 // SysTime and Duration both have a precision of hnsecs (100 ns), 1938 // so nsecs are going to be truncated. 1939 assert(SysTime(dt, nsecs(123456789)).fracSecs == nsecs(123456700)); 1940 } 1941 1942 @safe unittest 1943 { 1944 import std.range : chain; 1945 import core.time; 1946 1947 assert(SysTime(0, UTC()).fracSecs == Duration.zero); 1948 assert(SysTime(1, UTC()).fracSecs == hnsecs(1)); 1949 assert(SysTime(-1, UTC()).fracSecs == hnsecs(9_999_999)); 1950 1951 foreach (tz; testTZs) 1952 { 1953 foreach (year; chain(testYearsBC, testYearsAD)) 1954 { 1955 foreach (md; testMonthDays) 1956 { 1957 foreach (hour; testHours) 1958 { 1959 foreach (minute; testMinSecs) 1960 { 1961 foreach (second; testMinSecs) 1962 { 1963 auto dt = DateTime(Date(year, md.month, md.day), TimeOfDay(hour, minute, second)); 1964 foreach (fs; testFracSecs) 1965 assert(SysTime(dt, fs, tz).fracSecs == fs); 1966 } 1967 } 1968 } 1969 } 1970 } 1971 } 1972 1973 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1974 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 1975 assert(cst.fracSecs == Duration.zero); 1976 assert(ist.fracSecs == Duration.zero); 1977 1978 static void testScope(scope ref SysTime st) @safe 1979 { 1980 auto result = st.fracSecs; 1981 } 1982 } 1983 1984 1985 /++ 1986 Fractional seconds past the second (i.e. the portion of a 1987 $(LREF SysTime) which is less than a second). 1988 1989 Params: 1990 fracSecs = The duration to set this $(LREF SysTime)'s fractional 1991 seconds to. 1992 1993 Throws: 1994 $(REF DateTimeException,std,datetime,date) if the given duration 1995 is negative or if it's greater than or equal to one second. 1996 +/ 1997 @property void fracSecs(Duration fracSecs) @safe scope 1998 { 1999 enforce(fracSecs >= Duration.zero, new DateTimeException("A SysTime cannot have negative fractional seconds.")); 2000 enforce(fracSecs < seconds(1), new DateTimeException("Fractional seconds must be less than one second.")); 2001 2002 auto oldHNSecs = adjTime; 2003 auto days = splitUnitsFromHNSecs!"days"(oldHNSecs); 2004 immutable daysHNSecs = convert!("days", "hnsecs")(days); 2005 immutable negative = oldHNSecs < 0; 2006 2007 if (negative) 2008 oldHNSecs += convert!("hours", "hnsecs")(24); 2009 2010 immutable seconds = splitUnitsFromHNSecs!"seconds"(oldHNSecs); 2011 immutable secondsHNSecs = convert!("seconds", "hnsecs")(seconds); 2012 auto newHNSecs = fracSecs.total!"hnsecs" + secondsHNSecs; 2013 2014 if (negative) 2015 newHNSecs -= convert!("hours", "hnsecs")(24); 2016 2017 adjTime = daysHNSecs + newHNSecs; 2018 } 2019 2020 /// 2021 @safe unittest 2022 { 2023 import core.time : Duration, msecs, hnsecs, nsecs; 2024 import std.datetime.date : DateTime; 2025 2026 auto st = SysTime(DateTime(1982, 4, 1, 20, 59, 22)); 2027 assert(st.fracSecs == Duration.zero); 2028 2029 st.fracSecs = msecs(213); 2030 assert(st.fracSecs == msecs(213)); 2031 2032 st.fracSecs = hnsecs(1234567); 2033 assert(st.fracSecs == hnsecs(1234567)); 2034 2035 // SysTime has a precision of hnsecs (100 ns), so nsecs are 2036 // going to be truncated. 2037 st.fracSecs = nsecs(123456789); 2038 assert(st.fracSecs == hnsecs(1234567)); 2039 } 2040 2041 @safe unittest 2042 { 2043 import std.range : chain; 2044 import core.time; 2045 2046 foreach (fracSec; testFracSecs) 2047 { 2048 foreach (st; chain(testSysTimesBC, testSysTimesAD)) 2049 { 2050 auto dt = cast(DateTime) st; 2051 auto expected = SysTime(dt, fracSec, st.timezone); 2052 st.fracSecs = fracSec; 2053 assert(st == expected, format("[%s] [%s]", st, expected)); 2054 } 2055 } 2056 2057 auto st = testSysTimesAD[0]; 2058 assertThrown!DateTimeException(st.fracSecs = hnsecs(-1)); 2059 assertThrown!DateTimeException(st.fracSecs = seconds(1)); 2060 2061 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 2062 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 2063 static assert(!__traits(compiles, cst.fracSecs = msecs(7))); 2064 static assert(!__traits(compiles, ist.fracSecs = msecs(7))); 2065 2066 static void testScope(scope ref SysTime st) @safe 2067 { 2068 st.fracSecs = Duration.zero; 2069 } 2070 } 2071 2072 2073 /++ 2074 The total hnsecs from midnight, January 1st, 1 A.D. UTC. This is the 2075 internal representation of $(LREF SysTime). 2076 +/ 2077 @property long stdTime() @safe const pure nothrow scope 2078 { 2079 return _stdTime; 2080 } 2081 2082 @safe unittest 2083 { 2084 import core.time; 2085 assert(SysTime(0).stdTime == 0); 2086 assert(SysTime(1).stdTime == 1); 2087 assert(SysTime(-1).stdTime == -1); 2088 assert(SysTime(DateTime(1, 1, 1, 0, 0, 33), hnsecs(502), UTC()).stdTime == 330_000_502L); 2089 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 0), UTC()).stdTime == 621_355_968_000_000_000L); 2090 2091 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 2092 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 2093 assert(cst.stdTime > 0); 2094 assert(ist.stdTime > 0); 2095 2096 static void testScope(scope ref SysTime st) @safe 2097 { 2098 auto result = st.stdTime; 2099 } 2100 } 2101 2102 2103 /++ 2104 The total hnsecs from midnight, January 1st, 1 A.D. UTC. This is the 2105 internal representation of $(LREF SysTime). 2106 2107 Params: 2108 stdTime = The number of hnsecs since January 1st, 1 A.D. UTC. 2109 +/ 2110 @property void stdTime(long stdTime) @safe pure nothrow scope 2111 { 2112 _stdTime = stdTime; 2113 } 2114 2115 @safe unittest 2116 { 2117 import core.time; 2118 static void test(long stdTime, SysTime expected, size_t line = __LINE__) 2119 { 2120 auto st = SysTime(0, UTC()); 2121 st.stdTime = stdTime; 2122 assert(st == expected); 2123 } 2124 2125 test(0, SysTime(Date(1, 1, 1), UTC())); 2126 test(1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC())); 2127 test(-1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC())); 2128 test(330_000_502L, SysTime(DateTime(1, 1, 1, 0, 0, 33), hnsecs(502), UTC())); 2129 test(621_355_968_000_000_000L, SysTime(DateTime(1970, 1, 1, 0, 0, 0), UTC())); 2130 2131 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 2132 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 2133 static assert(!__traits(compiles, cst.stdTime = 27)); 2134 static assert(!__traits(compiles, ist.stdTime = 27)); 2135 2136 static void testScope(scope ref SysTime st) @safe 2137 { 2138 st.stdTime = 42; 2139 } 2140 } 2141 2142 2143 /++ 2144 The current time zone of this $(LREF SysTime). Its internal time is 2145 always kept in UTC, so there are no conversion issues between time zones 2146 due to DST. Functions which return all or part of the time - such as 2147 hours - adjust the time to this $(LREF SysTime)'s time zone before 2148 returning. 2149 +/ 2150 @property immutable(TimeZone) timezone() @safe const pure nothrow scope 2151 { 2152 return _timezone; 2153 } 2154 2155 @safe unittest 2156 { 2157 assert(SysTime.init.timezone is InitTimeZone()); 2158 assert(SysTime(DateTime.init, UTC()).timezone is UTC()); 2159 2160 static void testScope(scope ref SysTime st) @safe 2161 { 2162 auto result = st.timezone; 2163 } 2164 } 2165 2166 2167 /++ 2168 The current time zone of this $(LREF SysTime). It's internal time is 2169 always kept in UTC, so there are no conversion issues between time zones 2170 due to DST. Functions which return all or part of the time - such as 2171 hours - adjust the time to this $(LREF SysTime)'s time zone before 2172 returning. 2173 2174 Params: 2175 timezone = The $(REF _TimeZone,std,datetime,_timezone) to set this 2176 $(LREF SysTime)'s time zone to. 2177 +/ 2178 @property void timezone(immutable TimeZone timezone) @safe pure nothrow scope 2179 { 2180 if (timezone is null) 2181 _timezone = LocalTime(); 2182 else 2183 _timezone = timezone; 2184 } 2185 2186 @safe unittest 2187 { 2188 SysTime st; 2189 st.timezone = null; 2190 assert(st.timezone is LocalTime()); 2191 st.timezone = UTC(); 2192 assert(st.timezone is UTC()); 2193 2194 static void testScope(scope ref SysTime st) @safe 2195 { 2196 st.timezone = UTC(); 2197 } 2198 } 2199 2200 2201 /++ 2202 Returns whether DST is in effect for this $(LREF SysTime). 2203 +/ 2204 @property bool dstInEffect() @safe const nothrow scope 2205 { 2206 return _timezone.dstInEffect(_stdTime); 2207 } 2208 2209 // This function's full unit testing is done in the time zone classes, but 2210 // this verifies that SysTime.init works correctly, since historically, it 2211 // has segfaulted due to a null _timezone. 2212 @safe unittest 2213 { 2214 assert(!SysTime.init.dstInEffect); 2215 2216 static void testScope(scope ref SysTime st) @safe 2217 { 2218 auto result = st.dstInEffect; 2219 } 2220 } 2221 2222 2223 /++ 2224 Returns what the offset from UTC is for this $(LREF SysTime). 2225 It includes the DST offset in effect at that time (if any). 2226 +/ 2227 @property Duration utcOffset() @safe const nothrow scope 2228 { 2229 return _timezone.utcOffsetAt(_stdTime); 2230 } 2231 2232 // This function's full unit testing is done in the time zone classes, but 2233 // this verifies that SysTime.init works correctly, since historically, it 2234 // has segfaulted due to a null _timezone. 2235 @safe unittest 2236 { 2237 assert(SysTime.init.utcOffset == Duration.zero); 2238 2239 static void testScope(scope ref SysTime st) @safe 2240 { 2241 auto result = st.utcOffset; 2242 } 2243 } 2244 2245 2246 /++ 2247 Returns a $(LREF SysTime) with the same std time as this one, but with 2248 $(REF LocalTime,std,datetime,timezone) as its time zone. 2249 +/ 2250 SysTime toLocalTime() @safe const pure nothrow scope 2251 { 2252 return SysTime(_stdTime, LocalTime()); 2253 } 2254 2255 @safe unittest 2256 { 2257 import core.time; 2258 { 2259 auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), hnsecs(27)); 2260 assert(sysTime == sysTime.toLocalTime()); 2261 assert(sysTime._stdTime == sysTime.toLocalTime()._stdTime); 2262 assert(sysTime.toLocalTime().timezone is LocalTime()); 2263 assert(sysTime.toLocalTime().timezone is sysTime.timezone); 2264 assert(sysTime.toLocalTime().timezone !is UTC()); 2265 } 2266 2267 { 2268 auto stz = new immutable SimpleTimeZone(dur!"minutes"(-3 * 60)); 2269 auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), hnsecs(27), stz); 2270 assert(sysTime == sysTime.toLocalTime()); 2271 assert(sysTime._stdTime == sysTime.toLocalTime()._stdTime); 2272 assert(sysTime.toLocalTime().timezone is LocalTime()); 2273 assert(sysTime.toLocalTime().timezone !is UTC()); 2274 assert(sysTime.toLocalTime().timezone !is stz); 2275 } 2276 2277 static void testScope(scope ref SysTime st) @safe 2278 { 2279 auto result = st.toLocalTime(); 2280 } 2281 } 2282 2283 2284 /++ 2285 Returns a $(LREF SysTime) with the same std time as this one, but with 2286 `UTC` as its time zone. 2287 +/ 2288 SysTime toUTC() @safe const pure nothrow scope 2289 { 2290 return SysTime(_stdTime, UTC()); 2291 } 2292 2293 @safe unittest 2294 { 2295 import core.time; 2296 auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), hnsecs(27)); 2297 assert(sysTime == sysTime.toUTC()); 2298 assert(sysTime._stdTime == sysTime.toUTC()._stdTime); 2299 assert(sysTime.toUTC().timezone is UTC()); 2300 assert(sysTime.toUTC().timezone !is LocalTime()); 2301 assert(sysTime.toUTC().timezone !is sysTime.timezone); 2302 2303 static void testScope(scope ref SysTime st) @safe 2304 { 2305 auto result = st.toUTC(); 2306 } 2307 } 2308 2309 2310 /++ 2311 Returns a $(LREF SysTime) with the same std time as this one, but with 2312 given time zone as its time zone. 2313 +/ 2314 SysTime toOtherTZ(immutable TimeZone tz) @safe const pure nothrow scope 2315 { 2316 if (tz is null) 2317 return SysTime(_stdTime, LocalTime()); 2318 else 2319 return SysTime(_stdTime, tz); 2320 } 2321 2322 @safe unittest 2323 { 2324 import core.time; 2325 auto stz = new immutable SimpleTimeZone(dur!"minutes"(11 * 60)); 2326 auto sysTime = SysTime(DateTime(1982, 1, 4, 8, 59, 7), hnsecs(27)); 2327 assert(sysTime == sysTime.toOtherTZ(stz)); 2328 assert(sysTime._stdTime == sysTime.toOtherTZ(stz)._stdTime); 2329 assert(sysTime.toOtherTZ(stz).timezone is stz); 2330 assert(sysTime.toOtherTZ(stz).timezone !is LocalTime()); 2331 assert(sysTime.toOtherTZ(stz).timezone !is UTC()); 2332 assert(sysTime.toOtherTZ(null).timezone is LocalTime()); 2333 2334 static void testScope(scope ref SysTime st) @safe 2335 { 2336 auto result = st.toOtherTZ(null); 2337 } 2338 } 2339 2340 2341 /++ 2342 Converts this $(LREF SysTime) to unix time (i.e. seconds from midnight, 2343 January 1st, 1970 in UTC). 2344 2345 The C standard does not specify the representation of time_t, so it is 2346 implementation defined. On POSIX systems, unix time is equivalent to 2347 time_t, but that's not necessarily true on other systems (e.g. it is 2348 not true for the Digital Mars C runtime). So, be careful when using unix 2349 time with C functions on non-POSIX systems. 2350 2351 By default, the return type is time_t (which is normally an alias for 2352 int on 32-bit systems and long on 64-bit systems), but if a different 2353 size is required than either int or long can be passed as a template 2354 argument to get the desired size. 2355 2356 If the return type is int, and the result can't fit in an int, then the 2357 closest value that can be held in 32 bits will be used (so `int.max` 2358 if it goes over and `int.min` if it goes under). However, no attempt 2359 is made to deal with integer overflow if the return type is long. 2360 2361 Params: 2362 T = The return type (int or long). It defaults to time_t, which is 2363 normally 32 bits on a 32-bit system and 64 bits on a 64-bit 2364 system. 2365 2366 Returns: 2367 A signed integer representing the unix time which is equivalent to 2368 this SysTime. 2369 +/ 2370 T toUnixTime(T = time_t)() @safe const pure nothrow scope 2371 if (is(T == int) || is(T == long)) 2372 { 2373 return stdTimeToUnixTime!T(_stdTime); 2374 } 2375 2376 /// 2377 @safe unittest 2378 { 2379 import core.time : hours; 2380 import std.datetime.date : DateTime; 2381 import std.datetime.timezone : SimpleTimeZone, UTC; 2382 2383 assert(SysTime(DateTime(1970, 1, 1), UTC()).toUnixTime() == 0); 2384 2385 auto pst = new immutable SimpleTimeZone(hours(-8)); 2386 assert(SysTime(DateTime(1970, 1, 1), pst).toUnixTime() == 28800); 2387 2388 auto utc = SysTime(DateTime(2007, 12, 22, 8, 14, 45), UTC()); 2389 assert(utc.toUnixTime() == 1_198_311_285); 2390 2391 auto ca = SysTime(DateTime(2007, 12, 22, 8, 14, 45), pst); 2392 assert(ca.toUnixTime() == 1_198_340_085); 2393 2394 static void testScope(scope ref SysTime st) @safe 2395 { 2396 auto result = st.toUnixTime(); 2397 } 2398 } 2399 2400 @safe unittest 2401 { 2402 import std.meta : AliasSeq; 2403 import core.time; 2404 assert(SysTime(DateTime(1970, 1, 1), UTC()).toUnixTime() == 0); 2405 static foreach (units; ["hnsecs", "usecs", "msecs"]) 2406 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 0), dur!units(1), UTC()).toUnixTime() == 0); 2407 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), UTC()).toUnixTime() == 1); 2408 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toUnixTime() == 0); 2409 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999_999), UTC()).toUnixTime() == 0); 2410 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), msecs(999), UTC()).toUnixTime() == 0); 2411 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), UTC()).toUnixTime() == -1); 2412 } 2413 2414 2415 /++ 2416 Converts from unix time (i.e. seconds from midnight, January 1st, 1970 2417 in UTC) to a $(LREF SysTime). 2418 2419 The C standard does not specify the representation of time_t, so it is 2420 implementation defined. On POSIX systems, unix time is equivalent to 2421 time_t, but that's not necessarily true on other systems (e.g. it is 2422 not true for the Digital Mars C runtime). So, be careful when using unix 2423 time with C functions on non-POSIX systems. 2424 2425 Params: 2426 unixTime = Seconds from midnight, January 1st, 1970 in UTC. 2427 tz = The time zone for the SysTime that's returned. 2428 +/ 2429 static SysTime fromUnixTime(long unixTime, immutable TimeZone tz = LocalTime()) @safe pure nothrow 2430 { 2431 return SysTime(unixTimeToStdTime(unixTime), tz); 2432 } 2433 2434 /// 2435 @safe unittest 2436 { 2437 import core.time : hours; 2438 import std.datetime.date : DateTime; 2439 import std.datetime.timezone : SimpleTimeZone, UTC; 2440 2441 assert(SysTime.fromUnixTime(0) == 2442 SysTime(DateTime(1970, 1, 1), UTC())); 2443 2444 auto pst = new immutable SimpleTimeZone(hours(-8)); 2445 assert(SysTime.fromUnixTime(28800) == 2446 SysTime(DateTime(1970, 1, 1), pst)); 2447 2448 auto st1 = SysTime.fromUnixTime(1_198_311_285, UTC()); 2449 assert(st1 == SysTime(DateTime(2007, 12, 22, 8, 14, 45), UTC())); 2450 assert(st1.timezone is UTC()); 2451 assert(st1 == SysTime(DateTime(2007, 12, 22, 0, 14, 45), pst)); 2452 2453 auto st2 = SysTime.fromUnixTime(1_198_311_285, pst); 2454 assert(st2 == SysTime(DateTime(2007, 12, 22, 8, 14, 45), UTC())); 2455 assert(st2.timezone is pst); 2456 assert(st2 == SysTime(DateTime(2007, 12, 22, 0, 14, 45), pst)); 2457 } 2458 2459 @safe unittest 2460 { 2461 import core.time; 2462 assert(SysTime.fromUnixTime(0) == SysTime(DateTime(1970, 1, 1), UTC())); 2463 assert(SysTime.fromUnixTime(1) == SysTime(DateTime(1970, 1, 1, 0, 0, 1), UTC())); 2464 assert(SysTime.fromUnixTime(-1) == SysTime(DateTime(1969, 12, 31, 23, 59, 59), UTC())); 2465 2466 auto st = SysTime.fromUnixTime(0); 2467 auto dt = cast(DateTime) st; 2468 assert(dt <= DateTime(1970, 2, 1) && dt >= DateTime(1969, 12, 31)); 2469 assert(st.timezone is LocalTime()); 2470 2471 auto aest = new immutable SimpleTimeZone(hours(10)); 2472 assert(SysTime.fromUnixTime(-36000) == SysTime(DateTime(1970, 1, 1), aest)); 2473 } 2474 2475 2476 /++ 2477 Returns a `timeval` which represents this $(LREF SysTime). 2478 2479 Note that like all conversions in std.datetime, this is a truncating 2480 conversion. 2481 2482 If `timeval.tv_sec` is int, and the result can't fit in an int, then 2483 the closest value that can be held in 32 bits will be used for 2484 `tv_sec`. (so `int.max` if it goes over and `int.min` if it 2485 goes under). 2486 +/ 2487 timeval toTimeVal() @safe const pure nothrow scope 2488 { 2489 immutable tv_sec = toUnixTime!(typeof(timeval.tv_sec))(); 2490 immutable fracHNSecs = removeUnitsFromHNSecs!"seconds"(_stdTime - 621_355_968_000_000_000L); 2491 immutable tv_usec = cast(typeof(timeval.tv_usec))convert!("hnsecs", "usecs")(fracHNSecs); 2492 return timeval(tv_sec, tv_usec); 2493 } 2494 2495 @safe unittest 2496 { 2497 import core.time; 2498 assert(SysTime(DateTime(1970, 1, 1), UTC()).toTimeVal() == timeval(0, 0)); 2499 assert(SysTime(DateTime(1970, 1, 1), hnsecs(9), UTC()).toTimeVal() == timeval(0, 0)); 2500 assert(SysTime(DateTime(1970, 1, 1), hnsecs(10), UTC()).toTimeVal() == timeval(0, 1)); 2501 assert(SysTime(DateTime(1970, 1, 1), usecs(7), UTC()).toTimeVal() == timeval(0, 7)); 2502 2503 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), UTC()).toTimeVal() == timeval(1, 0)); 2504 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), hnsecs(9), UTC()).toTimeVal() == timeval(1, 0)); 2505 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), hnsecs(10), UTC()).toTimeVal() == timeval(1, 1)); 2506 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), usecs(7), UTC()).toTimeVal() == timeval(1, 7)); 2507 2508 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toTimeVal() == timeval(0, 0)); 2509 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_990), UTC()).toTimeVal() == timeval(0, -1)); 2510 2511 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999_999), UTC()).toTimeVal() == timeval(0, -1)); 2512 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999), UTC()).toTimeVal() == timeval(0, -999_001)); 2513 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), msecs(999), UTC()).toTimeVal() == timeval(0, -1000)); 2514 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), UTC()).toTimeVal() == timeval(-1, 0)); 2515 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 58), usecs(17), UTC()).toTimeVal() == timeval(-1, -999_983)); 2516 2517 static void testScope(scope ref SysTime st) @safe 2518 { 2519 auto result = st.toTimeVal(); 2520 } 2521 } 2522 2523 2524 version (StdDdoc) 2525 { 2526 private struct timespec {} 2527 /++ 2528 Returns a `timespec` which represents this $(LREF SysTime). 2529 2530 $(BLUE This function is Posix-Only.) 2531 +/ 2532 timespec toTimeSpec() @safe const pure nothrow scope; 2533 } 2534 else version (Posix) 2535 { 2536 timespec toTimeSpec() @safe const pure nothrow scope 2537 { 2538 immutable tv_sec = toUnixTime!(typeof(timespec.tv_sec))(); 2539 immutable fracHNSecs = removeUnitsFromHNSecs!"seconds"(_stdTime - 621_355_968_000_000_000L); 2540 immutable tv_nsec = cast(typeof(timespec.tv_nsec))convert!("hnsecs", "nsecs")(fracHNSecs); 2541 return timespec(tv_sec, tv_nsec); 2542 } 2543 2544 @safe unittest 2545 { 2546 import core.time; 2547 assert(SysTime(DateTime(1970, 1, 1), UTC()).toTimeSpec() == timespec(0, 0)); 2548 assert(SysTime(DateTime(1970, 1, 1), hnsecs(9), UTC()).toTimeSpec() == timespec(0, 900)); 2549 assert(SysTime(DateTime(1970, 1, 1), hnsecs(10), UTC()).toTimeSpec() == timespec(0, 1000)); 2550 assert(SysTime(DateTime(1970, 1, 1), usecs(7), UTC()).toTimeSpec() == timespec(0, 7000)); 2551 2552 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), UTC()).toTimeSpec() == timespec(1, 0)); 2553 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), hnsecs(9), UTC()).toTimeSpec() == timespec(1, 900)); 2554 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), hnsecs(10), UTC()).toTimeSpec() == timespec(1, 1000)); 2555 assert(SysTime(DateTime(1970, 1, 1, 0, 0, 1), usecs(7), UTC()).toTimeSpec() == timespec(1, 7000)); 2556 2557 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toTimeSpec() == 2558 timespec(0, -100)); 2559 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), hnsecs(9_999_990), UTC()).toTimeSpec() == 2560 timespec(0, -1000)); 2561 2562 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999_999), UTC()).toTimeSpec() == 2563 timespec(0, -1_000)); 2564 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), usecs(999), UTC()).toTimeSpec() == 2565 timespec(0, -999_001_000)); 2566 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), msecs(999), UTC()).toTimeSpec() == 2567 timespec(0, -1_000_000)); 2568 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 59), UTC()).toTimeSpec() == 2569 timespec(-1, 0)); 2570 assert(SysTime(DateTime(1969, 12, 31, 23, 59, 58), usecs(17), UTC()).toTimeSpec() == 2571 timespec(-1, -999_983_000)); 2572 2573 static void testScope(scope ref SysTime st) @safe 2574 { 2575 auto result = st.toTimeSpec(); 2576 } 2577 } 2578 } 2579 2580 /++ 2581 Returns a `tm` which represents this $(LREF SysTime). 2582 +/ 2583 tm toTM() @safe const nothrow scope 2584 { 2585 auto dateTime = cast(DateTime) this; 2586 tm timeInfo; 2587 2588 timeInfo.tm_sec = dateTime.second; 2589 timeInfo.tm_min = dateTime.minute; 2590 timeInfo.tm_hour = dateTime.hour; 2591 timeInfo.tm_mday = dateTime.day; 2592 timeInfo.tm_mon = dateTime.month - 1; 2593 timeInfo.tm_year = dateTime.year - 1900; 2594 timeInfo.tm_wday = dateTime.dayOfWeek; 2595 timeInfo.tm_yday = dateTime.dayOfYear - 1; 2596 timeInfo.tm_isdst = _timezone.dstInEffect(_stdTime); 2597 2598 version (Posix) 2599 { 2600 import std.utf : toUTFz; 2601 timeInfo.tm_gmtoff = cast(int) convert!("hnsecs", "seconds")(adjTime - _stdTime); 2602 auto zone = timeInfo.tm_isdst ? _timezone.dstName : _timezone.stdName; 2603 timeInfo.tm_zone = zone.toUTFz!(char*)(); 2604 } 2605 2606 return timeInfo; 2607 } 2608 2609 @system unittest 2610 { 2611 import std.conv : to; 2612 import core.time; 2613 2614 version (Posix) 2615 { 2616 import std.datetime.timezone : clearTZEnvVar, setTZEnvVar; 2617 setTZEnvVar("America/Los_Angeles"); 2618 scope(exit) clearTZEnvVar(); 2619 } 2620 2621 { 2622 auto timeInfo = SysTime(DateTime(1970, 1, 1)).toTM(); 2623 2624 assert(timeInfo.tm_sec == 0); 2625 assert(timeInfo.tm_min == 0); 2626 assert(timeInfo.tm_hour == 0); 2627 assert(timeInfo.tm_mday == 1); 2628 assert(timeInfo.tm_mon == 0); 2629 assert(timeInfo.tm_year == 70); 2630 assert(timeInfo.tm_wday == 4); 2631 assert(timeInfo.tm_yday == 0); 2632 2633 version (Posix) 2634 assert(timeInfo.tm_isdst == 0); 2635 else version (Windows) 2636 assert(timeInfo.tm_isdst == 0 || timeInfo.tm_isdst == 1); 2637 2638 version (Posix) 2639 { 2640 assert(timeInfo.tm_gmtoff == -8 * 60 * 60); 2641 assert(to!string(timeInfo.tm_zone) == "PST"); 2642 } 2643 } 2644 2645 { 2646 auto timeInfo = SysTime(DateTime(2010, 7, 4, 12, 15, 7), hnsecs(15)).toTM(); 2647 2648 assert(timeInfo.tm_sec == 7); 2649 assert(timeInfo.tm_min == 15); 2650 assert(timeInfo.tm_hour == 12); 2651 assert(timeInfo.tm_mday == 4); 2652 assert(timeInfo.tm_mon == 6); 2653 assert(timeInfo.tm_year == 110); 2654 assert(timeInfo.tm_wday == 0); 2655 assert(timeInfo.tm_yday == 184); 2656 2657 version (Posix) 2658 assert(timeInfo.tm_isdst == 1); 2659 else version (Windows) 2660 assert(timeInfo.tm_isdst == 0 || timeInfo.tm_isdst == 1); 2661 2662 version (Posix) 2663 { 2664 assert(timeInfo.tm_gmtoff == -7 * 60 * 60); 2665 assert(to!string(timeInfo.tm_zone) == "PDT"); 2666 } 2667 } 2668 2669 // This is more to verify that SysTime.init.toTM() doesn't segfault and 2670 // does something sane rather than that the value is anything 2671 // particularly useful. 2672 { 2673 auto timeInfo = SysTime.init.toTM(); 2674 2675 assert(timeInfo.tm_sec == 0); 2676 assert(timeInfo.tm_min == 0); 2677 assert(timeInfo.tm_hour == 0); 2678 assert(timeInfo.tm_mday == 1); 2679 assert(timeInfo.tm_mon == 0); 2680 assert(timeInfo.tm_year == -1899); 2681 assert(timeInfo.tm_wday == 1); 2682 assert(timeInfo.tm_yday == 0); 2683 assert(timeInfo.tm_isdst == 0); 2684 2685 version (Posix) 2686 { 2687 assert(timeInfo.tm_gmtoff == 0); 2688 assert(to!string(timeInfo.tm_zone) == "SysTime.init's timezone"); 2689 } 2690 } 2691 2692 static void testScope(scope ref SysTime st) @safe 2693 { 2694 auto result = st.toTM(); 2695 } 2696 } 2697 2698 2699 /++ 2700 Adds the given number of years or months to this $(LREF SysTime). A 2701 negative number will subtract. 2702 2703 Note that if day overflow is allowed, and the date with the adjusted 2704 year/month overflows the number of days in the new month, then the month 2705 will be incremented by one, and the day set to the number of days 2706 overflowed. (e.g. if the day were 31 and the new month were June, then 2707 the month would be incremented to July, and the new day would be 1). If 2708 day overflow is not allowed, then the day will be set to the last valid 2709 day in the month (e.g. June 31st would become June 30th). 2710 2711 Params: 2712 units = The type of units to add ("years" or "months"). 2713 value = The number of months or years to add to this 2714 $(LREF SysTime). 2715 allowOverflow = Whether the days should be allowed to overflow, 2716 causing the month to increment. 2717 +/ 2718 ref SysTime add(string units)(long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe nothrow scope 2719 if (units == "years" || units == "months") 2720 { 2721 auto hnsecs = adjTime; 2722 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 2723 2724 if (hnsecs < 0) 2725 { 2726 hnsecs += convert!("hours", "hnsecs")(24); 2727 --days; 2728 } 2729 2730 auto date = Date(cast(int) days); 2731 date.add!units(value, allowOverflow); 2732 days = date.dayOfGregorianCal - 1; 2733 2734 if (days < 0) 2735 { 2736 hnsecs -= convert!("hours", "hnsecs")(24); 2737 ++days; 2738 } 2739 2740 immutable newDaysHNSecs = convert!("days", "hnsecs")(days); 2741 2742 adjTime = newDaysHNSecs + hnsecs; 2743 2744 return this; 2745 } 2746 2747 @safe unittest 2748 { 2749 auto st1 = SysTime(DateTime(2010, 1, 1, 12, 30, 33)); 2750 st1.add!"months"(11); 2751 assert(st1 == SysTime(DateTime(2010, 12, 1, 12, 30, 33))); 2752 2753 auto st2 = SysTime(DateTime(2010, 1, 1, 12, 30, 33)); 2754 st2.add!"months"(-11); 2755 assert(st2 == SysTime(DateTime(2009, 2, 1, 12, 30, 33))); 2756 2757 auto st3 = SysTime(DateTime(2000, 2, 29, 12, 30, 33)); 2758 st3.add!"years"(1); 2759 assert(st3 == SysTime(DateTime(2001, 3, 1, 12, 30, 33))); 2760 2761 auto st4 = SysTime(DateTime(2000, 2, 29, 12, 30, 33)); 2762 st4.add!"years"(1, AllowDayOverflow.no); 2763 assert(st4 == SysTime(DateTime(2001, 2, 28, 12, 30, 33))); 2764 } 2765 2766 // Test add!"years"() with AllowDayOverflow.yes 2767 @safe unittest 2768 { 2769 import core.time; 2770 // Test A.D. 2771 { 2772 auto sysTime = SysTime(Date(1999, 7, 6)); 2773 sysTime.add!"years"(7); 2774 assert(sysTime == SysTime(Date(2006, 7, 6))); 2775 sysTime.add!"years"(-9); 2776 assert(sysTime == SysTime(Date(1997, 7, 6))); 2777 } 2778 2779 { 2780 auto sysTime = SysTime(Date(1999, 2, 28)); 2781 sysTime.add!"years"(1); 2782 assert(sysTime == SysTime(Date(2000, 2, 28))); 2783 } 2784 2785 { 2786 auto sysTime = SysTime(Date(2000, 2, 29)); 2787 sysTime.add!"years"(-1); 2788 assert(sysTime == SysTime(Date(1999, 3, 1))); 2789 } 2790 2791 { 2792 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 7, 3), msecs(234)); 2793 sysTime.add!"years"(7); 2794 assert(sysTime == SysTime(DateTime(2006, 7, 6, 12, 7, 3), msecs(234))); 2795 sysTime.add!"years"(-9); 2796 assert(sysTime == SysTime(DateTime(1997, 7, 6, 12, 7, 3), msecs(234))); 2797 } 2798 2799 { 2800 auto sysTime = SysTime(DateTime(1999, 2, 28, 0, 7, 2), usecs(1207)); 2801 sysTime.add!"years"(1); 2802 assert(sysTime == SysTime(DateTime(2000, 2, 28, 0, 7, 2), usecs(1207))); 2803 } 2804 2805 { 2806 auto sysTime = SysTime(DateTime(2000, 2, 29, 0, 7, 2), usecs(1207)); 2807 sysTime.add!"years"(-1); 2808 assert(sysTime == SysTime(DateTime(1999, 3, 1, 0, 7, 2), usecs(1207))); 2809 } 2810 2811 // Test B.C. 2812 { 2813 auto sysTime = SysTime(Date(-1999, 7, 6)); 2814 sysTime.add!"years"(-7); 2815 assert(sysTime == SysTime(Date(-2006, 7, 6))); 2816 sysTime.add!"years"(9); 2817 assert(sysTime == SysTime(Date(-1997, 7, 6))); 2818 } 2819 2820 { 2821 auto sysTime = SysTime(Date(-1999, 2, 28)); 2822 sysTime.add!"years"(-1); 2823 assert(sysTime == SysTime(Date(-2000, 2, 28))); 2824 } 2825 2826 { 2827 auto sysTime = SysTime(Date(-2000, 2, 29)); 2828 sysTime.add!"years"(1); 2829 assert(sysTime == SysTime(Date(-1999, 3, 1))); 2830 } 2831 2832 { 2833 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 7, 3), msecs(234)); 2834 sysTime.add!"years"(-7); 2835 assert(sysTime == SysTime(DateTime(-2006, 7, 6, 12, 7, 3), msecs(234))); 2836 sysTime.add!"years"(9); 2837 assert(sysTime == SysTime(DateTime(-1997, 7, 6, 12, 7, 3), msecs(234))); 2838 } 2839 2840 { 2841 auto sysTime = SysTime(DateTime(-1999, 2, 28, 3, 3, 3), hnsecs(3)); 2842 sysTime.add!"years"(-1); 2843 assert(sysTime == SysTime(DateTime(-2000, 2, 28, 3, 3, 3), hnsecs(3))); 2844 } 2845 2846 { 2847 auto sysTime = SysTime(DateTime(-2000, 2, 29, 3, 3, 3), hnsecs(3)); 2848 sysTime.add!"years"(1); 2849 assert(sysTime == SysTime(DateTime(-1999, 3, 1, 3, 3, 3), hnsecs(3))); 2850 } 2851 2852 // Test Both 2853 { 2854 auto sysTime = SysTime(Date(4, 7, 6)); 2855 sysTime.add!"years"(-5); 2856 assert(sysTime == SysTime(Date(-1, 7, 6))); 2857 sysTime.add!"years"(5); 2858 assert(sysTime == SysTime(Date(4, 7, 6))); 2859 } 2860 2861 { 2862 auto sysTime = SysTime(Date(-4, 7, 6)); 2863 sysTime.add!"years"(5); 2864 assert(sysTime == SysTime(Date(1, 7, 6))); 2865 sysTime.add!"years"(-5); 2866 assert(sysTime == SysTime(Date(-4, 7, 6))); 2867 } 2868 2869 { 2870 auto sysTime = SysTime(Date(4, 7, 6)); 2871 sysTime.add!"years"(-8); 2872 assert(sysTime == SysTime(Date(-4, 7, 6))); 2873 sysTime.add!"years"(8); 2874 assert(sysTime == SysTime(Date(4, 7, 6))); 2875 } 2876 2877 { 2878 auto sysTime = SysTime(Date(-4, 7, 6)); 2879 sysTime.add!"years"(8); 2880 assert(sysTime == SysTime(Date(4, 7, 6))); 2881 sysTime.add!"years"(-8); 2882 assert(sysTime == SysTime(Date(-4, 7, 6))); 2883 } 2884 2885 { 2886 auto sysTime = SysTime(Date(-4, 2, 29)); 2887 sysTime.add!"years"(5); 2888 assert(sysTime == SysTime(Date(1, 3, 1))); 2889 } 2890 2891 { 2892 auto sysTime = SysTime(Date(4, 2, 29)); 2893 sysTime.add!"years"(-5); 2894 assert(sysTime == SysTime(Date(-1, 3, 1))); 2895 } 2896 2897 { 2898 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 2899 sysTime.add!"years"(-1); 2900 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0))); 2901 sysTime.add!"years"(1); 2902 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 2903 } 2904 2905 { 2906 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 2907 sysTime.add!"years"(-1); 2908 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 2909 sysTime.add!"years"(1); 2910 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 2911 } 2912 2913 { 2914 auto sysTime = SysTime(DateTime(0, 1, 1, 0, 0, 0)); 2915 sysTime.add!"years"(1); 2916 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 2917 sysTime.add!"years"(-1); 2918 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0))); 2919 } 2920 2921 { 2922 auto sysTime = SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 2923 sysTime.add!"years"(1); 2924 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 2925 sysTime.add!"years"(-1); 2926 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 2927 } 2928 2929 { 2930 auto sysTime = SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329)); 2931 sysTime.add!"years"(-5); 2932 assert(sysTime == SysTime(DateTime(-1, 7, 6, 14, 7, 1), usecs(54329))); 2933 sysTime.add!"years"(5); 2934 assert(sysTime == SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329))); 2935 } 2936 2937 { 2938 auto sysTime = SysTime(DateTime(-4, 7, 6, 14, 7, 1), usecs(54329)); 2939 sysTime.add!"years"(5); 2940 assert(sysTime == SysTime(DateTime(1, 7, 6, 14, 7, 1), usecs(54329))); 2941 sysTime.add!"years"(-5); 2942 assert(sysTime == SysTime(DateTime(-4, 7, 6, 14, 7, 1), usecs(54329))); 2943 } 2944 2945 { 2946 auto sysTime = SysTime(DateTime(-4, 2, 29, 5, 5, 5), msecs(555)); 2947 sysTime.add!"years"(5); 2948 assert(sysTime == SysTime(DateTime(1, 3, 1, 5, 5, 5), msecs(555))); 2949 } 2950 2951 { 2952 auto sysTime = SysTime(DateTime(4, 2, 29, 5, 5, 5), msecs(555)); 2953 sysTime.add!"years"(-5); 2954 assert(sysTime == SysTime(DateTime(-1, 3, 1, 5, 5, 5), msecs(555))); 2955 } 2956 2957 { 2958 auto sysTime = SysTime(DateTime(4, 2, 29, 5, 5, 5), msecs(555)); 2959 sysTime.add!"years"(-5).add!"years"(7); 2960 assert(sysTime == SysTime(DateTime(6, 3, 1, 5, 5, 5), msecs(555))); 2961 } 2962 2963 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 2964 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 2965 static assert(!__traits(compiles, cst.add!"years"(4))); 2966 static assert(!__traits(compiles, ist.add!"years"(4))); 2967 2968 static void testScope(scope ref SysTime st) @safe 2969 { 2970 auto result = st.add!"years"(42); 2971 } 2972 } 2973 2974 // Test add!"years"() with AllowDayOverflow.no 2975 @safe unittest 2976 { 2977 import core.time; 2978 // Test A.D. 2979 { 2980 auto sysTime = SysTime(Date(1999, 7, 6)); 2981 sysTime.add!"years"(7, AllowDayOverflow.no); 2982 assert(sysTime == SysTime(Date(2006, 7, 6))); 2983 sysTime.add!"years"(-9, AllowDayOverflow.no); 2984 assert(sysTime == SysTime(Date(1997, 7, 6))); 2985 } 2986 2987 { 2988 auto sysTime = SysTime(Date(1999, 2, 28)); 2989 sysTime.add!"years"(1, AllowDayOverflow.no); 2990 assert(sysTime == SysTime(Date(2000, 2, 28))); 2991 } 2992 2993 { 2994 auto sysTime = SysTime(Date(2000, 2, 29)); 2995 sysTime.add!"years"(-1, AllowDayOverflow.no); 2996 assert(sysTime == SysTime(Date(1999, 2, 28))); 2997 } 2998 2999 { 3000 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 7, 3), msecs(234)); 3001 sysTime.add!"years"(7, AllowDayOverflow.no); 3002 assert(sysTime == SysTime(DateTime(2006, 7, 6, 12, 7, 3), msecs(234))); 3003 sysTime.add!"years"(-9, AllowDayOverflow.no); 3004 assert(sysTime == SysTime(DateTime(1997, 7, 6, 12, 7, 3), msecs(234))); 3005 } 3006 3007 { 3008 auto sysTime = SysTime(DateTime(1999, 2, 28, 0, 7, 2), usecs(1207)); 3009 sysTime.add!"years"(1, AllowDayOverflow.no); 3010 assert(sysTime == SysTime(DateTime(2000, 2, 28, 0, 7, 2), usecs(1207))); 3011 } 3012 3013 { 3014 auto sysTime = SysTime(DateTime(2000, 2, 29, 0, 7, 2), usecs(1207)); 3015 sysTime.add!"years"(-1, AllowDayOverflow.no); 3016 assert(sysTime == SysTime(DateTime(1999, 2, 28, 0, 7, 2), usecs(1207))); 3017 } 3018 3019 // Test B.C. 3020 { 3021 auto sysTime = SysTime(Date(-1999, 7, 6)); 3022 sysTime.add!"years"(-7, AllowDayOverflow.no); 3023 assert(sysTime == SysTime(Date(-2006, 7, 6))); 3024 sysTime.add!"years"(9, AllowDayOverflow.no); 3025 assert(sysTime == SysTime(Date(-1997, 7, 6))); 3026 } 3027 3028 { 3029 auto sysTime = SysTime(Date(-1999, 2, 28)); 3030 sysTime.add!"years"(-1, AllowDayOverflow.no); 3031 assert(sysTime == SysTime(Date(-2000, 2, 28))); 3032 } 3033 3034 { 3035 auto sysTime = SysTime(Date(-2000, 2, 29)); 3036 sysTime.add!"years"(1, AllowDayOverflow.no); 3037 assert(sysTime == SysTime(Date(-1999, 2, 28))); 3038 } 3039 3040 { 3041 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 7, 3), msecs(234)); 3042 sysTime.add!"years"(-7, AllowDayOverflow.no); 3043 assert(sysTime == SysTime(DateTime(-2006, 7, 6, 12, 7, 3), msecs(234))); 3044 sysTime.add!"years"(9, AllowDayOverflow.no); 3045 assert(sysTime == SysTime(DateTime(-1997, 7, 6, 12, 7, 3), msecs(234))); 3046 } 3047 3048 { 3049 auto sysTime = SysTime(DateTime(-1999, 2, 28, 3, 3, 3), hnsecs(3)); 3050 sysTime.add!"years"(-1, AllowDayOverflow.no); 3051 assert(sysTime == SysTime(DateTime(-2000, 2, 28, 3, 3, 3), hnsecs(3))); 3052 } 3053 3054 { 3055 auto sysTime = SysTime(DateTime(-2000, 2, 29, 3, 3, 3), hnsecs(3)); 3056 sysTime.add!"years"(1, AllowDayOverflow.no); 3057 assert(sysTime == SysTime(DateTime(-1999, 2, 28, 3, 3, 3), hnsecs(3))); 3058 } 3059 3060 // Test Both 3061 { 3062 auto sysTime = SysTime(Date(4, 7, 6)); 3063 sysTime.add!"years"(-5, AllowDayOverflow.no); 3064 assert(sysTime == SysTime(Date(-1, 7, 6))); 3065 sysTime.add!"years"(5, AllowDayOverflow.no); 3066 assert(sysTime == SysTime(Date(4, 7, 6))); 3067 } 3068 3069 { 3070 auto sysTime = SysTime(Date(-4, 7, 6)); 3071 sysTime.add!"years"(5, AllowDayOverflow.no); 3072 assert(sysTime == SysTime(Date(1, 7, 6))); 3073 sysTime.add!"years"(-5, AllowDayOverflow.no); 3074 assert(sysTime == SysTime(Date(-4, 7, 6))); 3075 } 3076 3077 { 3078 auto sysTime = SysTime(Date(4, 7, 6)); 3079 sysTime.add!"years"(-8, AllowDayOverflow.no); 3080 assert(sysTime == SysTime(Date(-4, 7, 6))); 3081 sysTime.add!"years"(8, AllowDayOverflow.no); 3082 assert(sysTime == SysTime(Date(4, 7, 6))); 3083 } 3084 3085 { 3086 auto sysTime = SysTime(Date(-4, 7, 6)); 3087 sysTime.add!"years"(8, AllowDayOverflow.no); 3088 assert(sysTime == SysTime(Date(4, 7, 6))); 3089 sysTime.add!"years"(-8, AllowDayOverflow.no); 3090 assert(sysTime == SysTime(Date(-4, 7, 6))); 3091 } 3092 3093 { 3094 auto sysTime = SysTime(Date(-4, 2, 29)); 3095 sysTime.add!"years"(5, AllowDayOverflow.no); 3096 assert(sysTime == SysTime(Date(1, 2, 28))); 3097 } 3098 3099 { 3100 auto sysTime = SysTime(Date(4, 2, 29)); 3101 sysTime.add!"years"(-5, AllowDayOverflow.no); 3102 assert(sysTime == SysTime(Date(-1, 2, 28))); 3103 } 3104 3105 { 3106 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 3107 sysTime.add!"years"(-1, AllowDayOverflow.no); 3108 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0))); 3109 sysTime.add!"years"(1, AllowDayOverflow.no); 3110 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 3111 } 3112 3113 { 3114 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 3115 sysTime.add!"years"(-1, AllowDayOverflow.no); 3116 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3117 sysTime.add!"years"(1, AllowDayOverflow.no); 3118 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3119 } 3120 3121 { 3122 auto sysTime = SysTime(DateTime(0, 1, 1, 0, 0, 0)); 3123 sysTime.add!"years"(1, AllowDayOverflow.no); 3124 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 3125 sysTime.add!"years"(-1, AllowDayOverflow.no); 3126 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0))); 3127 } 3128 3129 { 3130 auto sysTime = SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 3131 sysTime.add!"years"(1, AllowDayOverflow.no); 3132 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3133 sysTime.add!"years"(-1, AllowDayOverflow.no); 3134 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3135 } 3136 3137 { 3138 auto sysTime = SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329)); 3139 sysTime.add!"years"(-5); 3140 assert(sysTime == SysTime(DateTime(-1, 7, 6, 14, 7, 1), usecs(54329))); 3141 sysTime.add!"years"(5); 3142 assert(sysTime == SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329))); 3143 } 3144 3145 { 3146 auto sysTime = SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329)); 3147 sysTime.add!"years"(-5, AllowDayOverflow.no); 3148 assert(sysTime == SysTime(DateTime(-1, 7, 6, 14, 7, 1), usecs(54329))); 3149 sysTime.add!"years"(5, AllowDayOverflow.no); 3150 assert(sysTime == SysTime(DateTime(4, 7, 6, 14, 7, 1), usecs(54329))); 3151 } 3152 3153 { 3154 auto sysTime = SysTime(DateTime(-4, 7, 6, 14, 7, 1), usecs(54329)); 3155 sysTime.add!"years"(5, AllowDayOverflow.no); 3156 assert(sysTime == SysTime(DateTime(1, 7, 6, 14, 7, 1), usecs(54329))); 3157 sysTime.add!"years"(-5, AllowDayOverflow.no); 3158 assert(sysTime == SysTime(DateTime(-4, 7, 6, 14, 7, 1), usecs(54329))); 3159 } 3160 3161 { 3162 auto sysTime = SysTime(DateTime(-4, 2, 29, 5, 5, 5), msecs(555)); 3163 sysTime.add!"years"(5, AllowDayOverflow.no); 3164 assert(sysTime == SysTime(DateTime(1, 2, 28, 5, 5, 5), msecs(555))); 3165 } 3166 3167 { 3168 auto sysTime = SysTime(DateTime(4, 2, 29, 5, 5, 5), msecs(555)); 3169 sysTime.add!"years"(-5, AllowDayOverflow.no); 3170 assert(sysTime == SysTime(DateTime(-1, 2, 28, 5, 5, 5), msecs(555))); 3171 } 3172 3173 { 3174 auto sysTime = SysTime(DateTime(4, 2, 29, 5, 5, 5), msecs(555)); 3175 sysTime.add!"years"(-5, AllowDayOverflow.no).add!"years"(7, AllowDayOverflow.no); 3176 assert(sysTime == SysTime(DateTime(6, 2, 28, 5, 5, 5), msecs(555))); 3177 } 3178 } 3179 3180 // Test add!"months"() with AllowDayOverflow.yes 3181 @safe unittest 3182 { 3183 import core.time; 3184 // Test A.D. 3185 { 3186 auto sysTime = SysTime(Date(1999, 7, 6)); 3187 sysTime.add!"months"(3); 3188 assert(sysTime == SysTime(Date(1999, 10, 6))); 3189 sysTime.add!"months"(-4); 3190 assert(sysTime == SysTime(Date(1999, 6, 6))); 3191 } 3192 3193 { 3194 auto sysTime = SysTime(Date(1999, 7, 6)); 3195 sysTime.add!"months"(6); 3196 assert(sysTime == SysTime(Date(2000, 1, 6))); 3197 sysTime.add!"months"(-6); 3198 assert(sysTime == SysTime(Date(1999, 7, 6))); 3199 } 3200 3201 { 3202 auto sysTime = SysTime(Date(1999, 7, 6)); 3203 sysTime.add!"months"(27); 3204 assert(sysTime == SysTime(Date(2001, 10, 6))); 3205 sysTime.add!"months"(-28); 3206 assert(sysTime == SysTime(Date(1999, 6, 6))); 3207 } 3208 3209 { 3210 auto sysTime = SysTime(Date(1999, 5, 31)); 3211 sysTime.add!"months"(1); 3212 assert(sysTime == SysTime(Date(1999, 7, 1))); 3213 } 3214 3215 { 3216 auto sysTime = SysTime(Date(1999, 5, 31)); 3217 sysTime.add!"months"(-1); 3218 assert(sysTime == SysTime(Date(1999, 5, 1))); 3219 } 3220 3221 { 3222 auto sysTime = SysTime(Date(1999, 2, 28)); 3223 sysTime.add!"months"(12); 3224 assert(sysTime == SysTime(Date(2000, 2, 28))); 3225 } 3226 3227 { 3228 auto sysTime = SysTime(Date(2000, 2, 29)); 3229 sysTime.add!"months"(12); 3230 assert(sysTime == SysTime(Date(2001, 3, 1))); 3231 } 3232 3233 { 3234 auto sysTime = SysTime(Date(1999, 7, 31)); 3235 sysTime.add!"months"(1); 3236 assert(sysTime == SysTime(Date(1999, 8, 31))); 3237 sysTime.add!"months"(1); 3238 assert(sysTime == SysTime(Date(1999, 10, 1))); 3239 } 3240 3241 { 3242 auto sysTime = SysTime(Date(1998, 8, 31)); 3243 sysTime.add!"months"(13); 3244 assert(sysTime == SysTime(Date(1999, 10, 1))); 3245 sysTime.add!"months"(-13); 3246 assert(sysTime == SysTime(Date(1998, 9, 1))); 3247 } 3248 3249 { 3250 auto sysTime = SysTime(Date(1997, 12, 31)); 3251 sysTime.add!"months"(13); 3252 assert(sysTime == SysTime(Date(1999, 1, 31))); 3253 sysTime.add!"months"(-13); 3254 assert(sysTime == SysTime(Date(1997, 12, 31))); 3255 } 3256 3257 { 3258 auto sysTime = SysTime(Date(1997, 12, 31)); 3259 sysTime.add!"months"(14); 3260 assert(sysTime == SysTime(Date(1999, 3, 3))); 3261 sysTime.add!"months"(-14); 3262 assert(sysTime == SysTime(Date(1998, 1, 3))); 3263 } 3264 3265 { 3266 auto sysTime = SysTime(Date(1998, 12, 31)); 3267 sysTime.add!"months"(14); 3268 assert(sysTime == SysTime(Date(2000, 3, 2))); 3269 sysTime.add!"months"(-14); 3270 assert(sysTime == SysTime(Date(1999, 1, 2))); 3271 } 3272 3273 { 3274 auto sysTime = SysTime(Date(1999, 12, 31)); 3275 sysTime.add!"months"(14); 3276 assert(sysTime == SysTime(Date(2001, 3, 3))); 3277 sysTime.add!"months"(-14); 3278 assert(sysTime == SysTime(Date(2000, 1, 3))); 3279 } 3280 3281 { 3282 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), usecs(5007)); 3283 sysTime.add!"months"(3); 3284 assert(sysTime == SysTime(DateTime(1999, 10, 6, 12, 2, 7), usecs(5007))); 3285 sysTime.add!"months"(-4); 3286 assert(sysTime == SysTime(DateTime(1999, 6, 6, 12, 2, 7), usecs(5007))); 3287 } 3288 3289 { 3290 auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), hnsecs(422202)); 3291 sysTime.add!"months"(14); 3292 assert(sysTime == SysTime(DateTime(2000, 3, 2, 7, 7, 7), hnsecs(422202))); 3293 sysTime.add!"months"(-14); 3294 assert(sysTime == SysTime(DateTime(1999, 1, 2, 7, 7, 7), hnsecs(422202))); 3295 } 3296 3297 { 3298 auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), hnsecs(422202)); 3299 sysTime.add!"months"(14); 3300 assert(sysTime == SysTime(DateTime(2001, 3, 3, 7, 7, 7), hnsecs(422202))); 3301 sysTime.add!"months"(-14); 3302 assert(sysTime == SysTime(DateTime(2000, 1, 3, 7, 7, 7), hnsecs(422202))); 3303 } 3304 3305 // Test B.C. 3306 { 3307 auto sysTime = SysTime(Date(-1999, 7, 6)); 3308 sysTime.add!"months"(3); 3309 assert(sysTime == SysTime(Date(-1999, 10, 6))); 3310 sysTime.add!"months"(-4); 3311 assert(sysTime == SysTime(Date(-1999, 6, 6))); 3312 } 3313 3314 { 3315 auto sysTime = SysTime(Date(-1999, 7, 6)); 3316 sysTime.add!"months"(6); 3317 assert(sysTime == SysTime(Date(-1998, 1, 6))); 3318 sysTime.add!"months"(-6); 3319 assert(sysTime == SysTime(Date(-1999, 7, 6))); 3320 } 3321 3322 { 3323 auto sysTime = SysTime(Date(-1999, 7, 6)); 3324 sysTime.add!"months"(-27); 3325 assert(sysTime == SysTime(Date(-2001, 4, 6))); 3326 sysTime.add!"months"(28); 3327 assert(sysTime == SysTime(Date(-1999, 8, 6))); 3328 } 3329 3330 { 3331 auto sysTime = SysTime(Date(-1999, 5, 31)); 3332 sysTime.add!"months"(1); 3333 assert(sysTime == SysTime(Date(-1999, 7, 1))); 3334 } 3335 3336 { 3337 auto sysTime = SysTime(Date(-1999, 5, 31)); 3338 sysTime.add!"months"(-1); 3339 assert(sysTime == SysTime(Date(-1999, 5, 1))); 3340 } 3341 3342 { 3343 auto sysTime = SysTime(Date(-1999, 2, 28)); 3344 sysTime.add!"months"(-12); 3345 assert(sysTime == SysTime(Date(-2000, 2, 28))); 3346 } 3347 3348 { 3349 auto sysTime = SysTime(Date(-2000, 2, 29)); 3350 sysTime.add!"months"(-12); 3351 assert(sysTime == SysTime(Date(-2001, 3, 1))); 3352 } 3353 3354 { 3355 auto sysTime = SysTime(Date(-1999, 7, 31)); 3356 sysTime.add!"months"(1); 3357 assert(sysTime == SysTime(Date(-1999, 8, 31))); 3358 sysTime.add!"months"(1); 3359 assert(sysTime == SysTime(Date(-1999, 10, 1))); 3360 } 3361 3362 { 3363 auto sysTime = SysTime(Date(-1998, 8, 31)); 3364 sysTime.add!"months"(13); 3365 assert(sysTime == SysTime(Date(-1997, 10, 1))); 3366 sysTime.add!"months"(-13); 3367 assert(sysTime == SysTime(Date(-1998, 9, 1))); 3368 } 3369 3370 { 3371 auto sysTime = SysTime(Date(-1997, 12, 31)); 3372 sysTime.add!"months"(13); 3373 assert(sysTime == SysTime(Date(-1995, 1, 31))); 3374 sysTime.add!"months"(-13); 3375 assert(sysTime == SysTime(Date(-1997, 12, 31))); 3376 } 3377 3378 { 3379 auto sysTime = SysTime(Date(-1997, 12, 31)); 3380 sysTime.add!"months"(14); 3381 assert(sysTime == SysTime(Date(-1995, 3, 3))); 3382 sysTime.add!"months"(-14); 3383 assert(sysTime == SysTime(Date(-1996, 1, 3))); 3384 } 3385 3386 { 3387 auto sysTime = SysTime(Date(-2002, 12, 31)); 3388 sysTime.add!"months"(14); 3389 assert(sysTime == SysTime(Date(-2000, 3, 2))); 3390 sysTime.add!"months"(-14); 3391 assert(sysTime == SysTime(Date(-2001, 1, 2))); 3392 } 3393 3394 { 3395 auto sysTime = SysTime(Date(-2001, 12, 31)); 3396 sysTime.add!"months"(14); 3397 assert(sysTime == SysTime(Date(-1999, 3, 3))); 3398 sysTime.add!"months"(-14); 3399 assert(sysTime == SysTime(Date(-2000, 1, 3))); 3400 } 3401 3402 { 3403 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), usecs(5007)); 3404 sysTime.add!"months"(3); 3405 assert(sysTime == SysTime(DateTime(-1999, 10, 6, 12, 2, 7), usecs(5007))); 3406 sysTime.add!"months"(-4); 3407 assert(sysTime == SysTime(DateTime(-1999, 6, 6, 12, 2, 7), usecs(5007))); 3408 } 3409 3410 { 3411 auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), hnsecs(422202)); 3412 sysTime.add!"months"(14); 3413 assert(sysTime == SysTime(DateTime(-2000, 3, 2, 7, 7, 7), hnsecs(422202))); 3414 sysTime.add!"months"(-14); 3415 assert(sysTime == SysTime(DateTime(-2001, 1, 2, 7, 7, 7), hnsecs(422202))); 3416 } 3417 3418 { 3419 auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), hnsecs(422202)); 3420 sysTime.add!"months"(14); 3421 assert(sysTime == SysTime(DateTime(-1999, 3, 3, 7, 7, 7), hnsecs(422202))); 3422 sysTime.add!"months"(-14); 3423 assert(sysTime == SysTime(DateTime(-2000, 1, 3, 7, 7, 7), hnsecs(422202))); 3424 } 3425 3426 // Test Both 3427 { 3428 auto sysTime = SysTime(Date(1, 1, 1)); 3429 sysTime.add!"months"(-1); 3430 assert(sysTime == SysTime(Date(0, 12, 1))); 3431 sysTime.add!"months"(1); 3432 assert(sysTime == SysTime(Date(1, 1, 1))); 3433 } 3434 3435 { 3436 auto sysTime = SysTime(Date(4, 1, 1)); 3437 sysTime.add!"months"(-48); 3438 assert(sysTime == SysTime(Date(0, 1, 1))); 3439 sysTime.add!"months"(48); 3440 assert(sysTime == SysTime(Date(4, 1, 1))); 3441 } 3442 3443 { 3444 auto sysTime = SysTime(Date(4, 3, 31)); 3445 sysTime.add!"months"(-49); 3446 assert(sysTime == SysTime(Date(0, 3, 2))); 3447 sysTime.add!"months"(49); 3448 assert(sysTime == SysTime(Date(4, 4, 2))); 3449 } 3450 3451 { 3452 auto sysTime = SysTime(Date(4, 3, 31)); 3453 sysTime.add!"months"(-85); 3454 assert(sysTime == SysTime(Date(-3, 3, 3))); 3455 sysTime.add!"months"(85); 3456 assert(sysTime == SysTime(Date(4, 4, 3))); 3457 } 3458 3459 { 3460 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 3461 sysTime.add!"months"(-1); 3462 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 3463 sysTime.add!"months"(1); 3464 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 3465 } 3466 3467 { 3468 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 3469 sysTime.add!"months"(-1); 3470 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 3471 sysTime.add!"months"(1); 3472 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3473 } 3474 3475 { 3476 auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0)); 3477 sysTime.add!"months"(1); 3478 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 3479 sysTime.add!"months"(-1); 3480 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 3481 } 3482 3483 { 3484 auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)); 3485 sysTime.add!"months"(1); 3486 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3487 sysTime.add!"months"(-1); 3488 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 3489 } 3490 3491 { 3492 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17)); 3493 sysTime.add!"months"(-1); 3494 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 7, 9), hnsecs(17))); 3495 sysTime.add!"months"(1); 3496 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17))); 3497 } 3498 3499 { 3500 auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), msecs(9)); 3501 sysTime.add!"months"(-85); 3502 assert(sysTime == SysTime(DateTime(-3, 3, 3, 12, 11, 10), msecs(9))); 3503 sysTime.add!"months"(85); 3504 assert(sysTime == SysTime(DateTime(4, 4, 3, 12, 11, 10), msecs(9))); 3505 } 3506 3507 { 3508 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 3509 sysTime.add!"months"(85); 3510 assert(sysTime == SysTime(DateTime(4, 5, 1, 12, 11, 10), msecs(9))); 3511 sysTime.add!"months"(-85); 3512 assert(sysTime == SysTime(DateTime(-3, 4, 1, 12, 11, 10), msecs(9))); 3513 } 3514 3515 { 3516 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 3517 sysTime.add!"months"(85).add!"months"(-83); 3518 assert(sysTime == SysTime(DateTime(-3, 6, 1, 12, 11, 10), msecs(9))); 3519 } 3520 3521 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 3522 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 3523 static assert(!__traits(compiles, cst.add!"months"(4))); 3524 static assert(!__traits(compiles, ist.add!"months"(4))); 3525 3526 static void testScope(scope ref SysTime st) @safe 3527 { 3528 auto result = st.add!"months"(42); 3529 } 3530 } 3531 3532 // Test add!"months"() with AllowDayOverflow.no 3533 @safe unittest 3534 { 3535 import core.time; 3536 // Test A.D. 3537 { 3538 auto sysTime = SysTime(Date(1999, 7, 6)); 3539 sysTime.add!"months"(3, AllowDayOverflow.no); 3540 assert(sysTime == SysTime(Date(1999, 10, 6))); 3541 sysTime.add!"months"(-4, AllowDayOverflow.no); 3542 assert(sysTime == SysTime(Date(1999, 6, 6))); 3543 } 3544 3545 { 3546 auto sysTime = SysTime(Date(1999, 7, 6)); 3547 sysTime.add!"months"(6, AllowDayOverflow.no); 3548 assert(sysTime == SysTime(Date(2000, 1, 6))); 3549 sysTime.add!"months"(-6, AllowDayOverflow.no); 3550 assert(sysTime == SysTime(Date(1999, 7, 6))); 3551 } 3552 3553 { 3554 auto sysTime = SysTime(Date(1999, 7, 6)); 3555 sysTime.add!"months"(27, AllowDayOverflow.no); 3556 assert(sysTime == SysTime(Date(2001, 10, 6))); 3557 sysTime.add!"months"(-28, AllowDayOverflow.no); 3558 assert(sysTime == SysTime(Date(1999, 6, 6))); 3559 } 3560 3561 { 3562 auto sysTime = SysTime(Date(1999, 5, 31)); 3563 sysTime.add!"months"(1, AllowDayOverflow.no); 3564 assert(sysTime == SysTime(Date(1999, 6, 30))); 3565 } 3566 3567 { 3568 auto sysTime = SysTime(Date(1999, 5, 31)); 3569 sysTime.add!"months"(-1, AllowDayOverflow.no); 3570 assert(sysTime == SysTime(Date(1999, 4, 30))); 3571 } 3572 3573 { 3574 auto sysTime = SysTime(Date(1999, 2, 28)); 3575 sysTime.add!"months"(12, AllowDayOverflow.no); 3576 assert(sysTime == SysTime(Date(2000, 2, 28))); 3577 } 3578 3579 { 3580 auto sysTime = SysTime(Date(2000, 2, 29)); 3581 sysTime.add!"months"(12, AllowDayOverflow.no); 3582 assert(sysTime == SysTime(Date(2001, 2, 28))); 3583 } 3584 3585 { 3586 auto sysTime = SysTime(Date(1999, 7, 31)); 3587 sysTime.add!"months"(1, AllowDayOverflow.no); 3588 assert(sysTime == SysTime(Date(1999, 8, 31))); 3589 sysTime.add!"months"(1, AllowDayOverflow.no); 3590 assert(sysTime == SysTime(Date(1999, 9, 30))); 3591 } 3592 3593 { 3594 auto sysTime = SysTime(Date(1998, 8, 31)); 3595 sysTime.add!"months"(13, AllowDayOverflow.no); 3596 assert(sysTime == SysTime(Date(1999, 9, 30))); 3597 sysTime.add!"months"(-13, AllowDayOverflow.no); 3598 assert(sysTime == SysTime(Date(1998, 8, 30))); 3599 } 3600 3601 { 3602 auto sysTime = SysTime(Date(1997, 12, 31)); 3603 sysTime.add!"months"(13, AllowDayOverflow.no); 3604 assert(sysTime == SysTime(Date(1999, 1, 31))); 3605 sysTime.add!"months"(-13, AllowDayOverflow.no); 3606 assert(sysTime == SysTime(Date(1997, 12, 31))); 3607 } 3608 3609 { 3610 auto sysTime = SysTime(Date(1997, 12, 31)); 3611 sysTime.add!"months"(14, AllowDayOverflow.no); 3612 assert(sysTime == SysTime(Date(1999, 2, 28))); 3613 sysTime.add!"months"(-14, AllowDayOverflow.no); 3614 assert(sysTime == SysTime(Date(1997, 12, 28))); 3615 } 3616 3617 { 3618 auto sysTime = SysTime(Date(1998, 12, 31)); 3619 sysTime.add!"months"(14, AllowDayOverflow.no); 3620 assert(sysTime == SysTime(Date(2000, 2, 29))); 3621 sysTime.add!"months"(-14, AllowDayOverflow.no); 3622 assert(sysTime == SysTime(Date(1998, 12, 29))); 3623 } 3624 3625 { 3626 auto sysTime = SysTime(Date(1999, 12, 31)); 3627 sysTime.add!"months"(14, AllowDayOverflow.no); 3628 assert(sysTime == SysTime(Date(2001, 2, 28))); 3629 sysTime.add!"months"(-14, AllowDayOverflow.no); 3630 assert(sysTime == SysTime(Date(1999, 12, 28))); 3631 } 3632 3633 { 3634 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), usecs(5007)); 3635 sysTime.add!"months"(3, AllowDayOverflow.no); 3636 assert(sysTime == SysTime(DateTime(1999, 10, 6, 12, 2, 7), usecs(5007))); 3637 sysTime.add!"months"(-4, AllowDayOverflow.no); 3638 assert(sysTime == SysTime(DateTime(1999, 6, 6, 12, 2, 7), usecs(5007))); 3639 } 3640 3641 { 3642 auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), hnsecs(422202)); 3643 sysTime.add!"months"(14, AllowDayOverflow.no); 3644 assert(sysTime == SysTime(DateTime(2000, 2, 29, 7, 7, 7), hnsecs(422202))); 3645 sysTime.add!"months"(-14, AllowDayOverflow.no); 3646 assert(sysTime == SysTime(DateTime(1998, 12, 29, 7, 7, 7), hnsecs(422202))); 3647 } 3648 3649 { 3650 auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), hnsecs(422202)); 3651 sysTime.add!"months"(14, AllowDayOverflow.no); 3652 assert(sysTime == SysTime(DateTime(2001, 2, 28, 7, 7, 7), hnsecs(422202))); 3653 sysTime.add!"months"(-14, AllowDayOverflow.no); 3654 assert(sysTime == SysTime(DateTime(1999, 12, 28, 7, 7, 7), hnsecs(422202))); 3655 } 3656 3657 // Test B.C. 3658 { 3659 auto sysTime = SysTime(Date(-1999, 7, 6)); 3660 sysTime.add!"months"(3, AllowDayOverflow.no); 3661 assert(sysTime == SysTime(Date(-1999, 10, 6))); 3662 sysTime.add!"months"(-4, AllowDayOverflow.no); 3663 assert(sysTime == SysTime(Date(-1999, 6, 6))); 3664 } 3665 3666 { 3667 auto sysTime = SysTime(Date(-1999, 7, 6)); 3668 sysTime.add!"months"(6, AllowDayOverflow.no); 3669 assert(sysTime == SysTime(Date(-1998, 1, 6))); 3670 sysTime.add!"months"(-6, AllowDayOverflow.no); 3671 assert(sysTime == SysTime(Date(-1999, 7, 6))); 3672 } 3673 3674 { 3675 auto sysTime = SysTime(Date(-1999, 7, 6)); 3676 sysTime.add!"months"(-27, AllowDayOverflow.no); 3677 assert(sysTime == SysTime(Date(-2001, 4, 6))); 3678 sysTime.add!"months"(28, AllowDayOverflow.no); 3679 assert(sysTime == SysTime(Date(-1999, 8, 6))); 3680 } 3681 3682 { 3683 auto sysTime = SysTime(Date(-1999, 5, 31)); 3684 sysTime.add!"months"(1, AllowDayOverflow.no); 3685 assert(sysTime == SysTime(Date(-1999, 6, 30))); 3686 } 3687 3688 { 3689 auto sysTime = SysTime(Date(-1999, 5, 31)); 3690 sysTime.add!"months"(-1, AllowDayOverflow.no); 3691 assert(sysTime == SysTime(Date(-1999, 4, 30))); 3692 } 3693 3694 { 3695 auto sysTime = SysTime(Date(-1999, 2, 28)); 3696 sysTime.add!"months"(-12, AllowDayOverflow.no); 3697 assert(sysTime == SysTime(Date(-2000, 2, 28))); 3698 } 3699 3700 { 3701 auto sysTime = SysTime(Date(-2000, 2, 29)); 3702 sysTime.add!"months"(-12, AllowDayOverflow.no); 3703 assert(sysTime == SysTime(Date(-2001, 2, 28))); 3704 } 3705 3706 { 3707 auto sysTime = SysTime(Date(-1999, 7, 31)); 3708 sysTime.add!"months"(1, AllowDayOverflow.no); 3709 assert(sysTime == SysTime(Date(-1999, 8, 31))); 3710 sysTime.add!"months"(1, AllowDayOverflow.no); 3711 assert(sysTime == SysTime(Date(-1999, 9, 30))); 3712 } 3713 3714 { 3715 auto sysTime = SysTime(Date(-1998, 8, 31)); 3716 sysTime.add!"months"(13, AllowDayOverflow.no); 3717 assert(sysTime == SysTime(Date(-1997, 9, 30))); 3718 sysTime.add!"months"(-13, AllowDayOverflow.no); 3719 assert(sysTime == SysTime(Date(-1998, 8, 30))); 3720 } 3721 3722 { 3723 auto sysTime = SysTime(Date(-1997, 12, 31)); 3724 sysTime.add!"months"(13, AllowDayOverflow.no); 3725 assert(sysTime == SysTime(Date(-1995, 1, 31))); 3726 sysTime.add!"months"(-13, AllowDayOverflow.no); 3727 assert(sysTime == SysTime(Date(-1997, 12, 31))); 3728 } 3729 3730 { 3731 auto sysTime = SysTime(Date(-1997, 12, 31)); 3732 sysTime.add!"months"(14, AllowDayOverflow.no); 3733 assert(sysTime == SysTime(Date(-1995, 2, 28))); 3734 sysTime.add!"months"(-14, AllowDayOverflow.no); 3735 assert(sysTime == SysTime(Date(-1997, 12, 28))); 3736 } 3737 3738 { 3739 auto sysTime = SysTime(Date(-2002, 12, 31)); 3740 sysTime.add!"months"(14, AllowDayOverflow.no); 3741 assert(sysTime == SysTime(Date(-2000, 2, 29))); 3742 sysTime.add!"months"(-14, AllowDayOverflow.no); 3743 assert(sysTime == SysTime(Date(-2002, 12, 29))); 3744 } 3745 3746 { 3747 auto sysTime = SysTime(Date(-2001, 12, 31)); 3748 sysTime.add!"months"(14, AllowDayOverflow.no); 3749 assert(sysTime == SysTime(Date(-1999, 2, 28))); 3750 sysTime.add!"months"(-14, AllowDayOverflow.no); 3751 assert(sysTime == SysTime(Date(-2001, 12, 28))); 3752 } 3753 3754 { 3755 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), usecs(5007)); 3756 sysTime.add!"months"(3, AllowDayOverflow.no); 3757 assert(sysTime == SysTime(DateTime(-1999, 10, 6, 12, 2, 7), usecs(5007))); 3758 sysTime.add!"months"(-4, AllowDayOverflow.no); 3759 assert(sysTime == SysTime(DateTime(-1999, 6, 6, 12, 2, 7), usecs(5007))); 3760 } 3761 3762 { 3763 auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), hnsecs(422202)); 3764 sysTime.add!"months"(14, AllowDayOverflow.no); 3765 assert(sysTime == SysTime(DateTime(-2000, 2, 29, 7, 7, 7), hnsecs(422202))); 3766 sysTime.add!"months"(-14, AllowDayOverflow.no); 3767 assert(sysTime == SysTime(DateTime(-2002, 12, 29, 7, 7, 7), hnsecs(422202))); 3768 } 3769 3770 { 3771 auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), hnsecs(422202)); 3772 sysTime.add!"months"(14, AllowDayOverflow.no); 3773 assert(sysTime == SysTime(DateTime(-1999, 2, 28, 7, 7, 7), hnsecs(422202))); 3774 sysTime.add!"months"(-14, AllowDayOverflow.no); 3775 assert(sysTime == SysTime(DateTime(-2001, 12, 28, 7, 7, 7), hnsecs(422202))); 3776 } 3777 3778 // Test Both 3779 { 3780 auto sysTime = SysTime(Date(1, 1, 1)); 3781 sysTime.add!"months"(-1, AllowDayOverflow.no); 3782 assert(sysTime == SysTime(Date(0, 12, 1))); 3783 sysTime.add!"months"(1, AllowDayOverflow.no); 3784 assert(sysTime == SysTime(Date(1, 1, 1))); 3785 } 3786 3787 { 3788 auto sysTime = SysTime(Date(4, 1, 1)); 3789 sysTime.add!"months"(-48, AllowDayOverflow.no); 3790 assert(sysTime == SysTime(Date(0, 1, 1))); 3791 sysTime.add!"months"(48, AllowDayOverflow.no); 3792 assert(sysTime == SysTime(Date(4, 1, 1))); 3793 } 3794 3795 { 3796 auto sysTime = SysTime(Date(4, 3, 31)); 3797 sysTime.add!"months"(-49, AllowDayOverflow.no); 3798 assert(sysTime == SysTime(Date(0, 2, 29))); 3799 sysTime.add!"months"(49, AllowDayOverflow.no); 3800 assert(sysTime == SysTime(Date(4, 3, 29))); 3801 } 3802 3803 { 3804 auto sysTime = SysTime(Date(4, 3, 31)); 3805 sysTime.add!"months"(-85, AllowDayOverflow.no); 3806 assert(sysTime == SysTime(Date(-3, 2, 28))); 3807 sysTime.add!"months"(85, AllowDayOverflow.no); 3808 assert(sysTime == SysTime(Date(4, 3, 28))); 3809 } 3810 3811 { 3812 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 3813 sysTime.add!"months"(-1, AllowDayOverflow.no); 3814 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 3815 sysTime.add!"months"(1, AllowDayOverflow.no); 3816 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 3817 } 3818 3819 { 3820 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 3821 sysTime.add!"months"(-1, AllowDayOverflow.no); 3822 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 3823 sysTime.add!"months"(1, AllowDayOverflow.no); 3824 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3825 } 3826 3827 { 3828 auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0)); 3829 sysTime.add!"months"(1, AllowDayOverflow.no); 3830 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 3831 sysTime.add!"months"(-1, AllowDayOverflow.no); 3832 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 3833 } 3834 3835 { 3836 auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)); 3837 sysTime.add!"months"(1, AllowDayOverflow.no); 3838 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 3839 sysTime.add!"months"(-1, AllowDayOverflow.no); 3840 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 3841 } 3842 3843 { 3844 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17)); 3845 sysTime.add!"months"(-1, AllowDayOverflow.no); 3846 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 7, 9), hnsecs(17))); 3847 sysTime.add!"months"(1, AllowDayOverflow.no); 3848 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17))); 3849 } 3850 3851 { 3852 auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), msecs(9)); 3853 sysTime.add!"months"(-85, AllowDayOverflow.no); 3854 assert(sysTime == SysTime(DateTime(-3, 2, 28, 12, 11, 10), msecs(9))); 3855 sysTime.add!"months"(85, AllowDayOverflow.no); 3856 assert(sysTime == SysTime(DateTime(4, 3, 28, 12, 11, 10), msecs(9))); 3857 } 3858 3859 { 3860 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 3861 sysTime.add!"months"(85, AllowDayOverflow.no); 3862 assert(sysTime == SysTime(DateTime(4, 4, 30, 12, 11, 10), msecs(9))); 3863 sysTime.add!"months"(-85, AllowDayOverflow.no); 3864 assert(sysTime == SysTime(DateTime(-3, 3, 30, 12, 11, 10), msecs(9))); 3865 } 3866 3867 { 3868 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 3869 sysTime.add!"months"(85, AllowDayOverflow.no).add!"months"(-83, AllowDayOverflow.no); 3870 assert(sysTime == SysTime(DateTime(-3, 5, 30, 12, 11, 10), msecs(9))); 3871 } 3872 } 3873 3874 3875 /++ 3876 Adds the given number of years or months to this $(LREF SysTime). A 3877 negative number will subtract. 3878 3879 The difference between rolling and adding is that rolling does not 3880 affect larger units. Rolling a $(LREF SysTime) 12 months 3881 gets the exact same $(LREF SysTime). However, the days can still be 3882 affected due to the differing number of days in each month. 3883 3884 Because there are no units larger than years, there is no difference 3885 between adding and rolling years. 3886 3887 Params: 3888 units = The type of units to add ("years" or "months"). 3889 value = The number of months or years to add to this 3890 $(LREF SysTime). 3891 allowOverflow = Whether the days should be allowed to overflow, 3892 causing the month to increment. 3893 +/ 3894 ref SysTime roll(string units) 3895 (long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe nothrow scope 3896 if (units == "years") 3897 { 3898 return add!"years"(value, allowOverflow); 3899 } 3900 3901 /// 3902 @safe unittest 3903 { 3904 import std.datetime.date : AllowDayOverflow, DateTime; 3905 3906 auto st1 = SysTime(DateTime(2010, 1, 1, 12, 33, 33)); 3907 st1.roll!"months"(1); 3908 assert(st1 == SysTime(DateTime(2010, 2, 1, 12, 33, 33))); 3909 3910 auto st2 = SysTime(DateTime(2010, 1, 1, 12, 33, 33)); 3911 st2.roll!"months"(-1); 3912 assert(st2 == SysTime(DateTime(2010, 12, 1, 12, 33, 33))); 3913 3914 auto st3 = SysTime(DateTime(1999, 1, 29, 12, 33, 33)); 3915 st3.roll!"months"(1); 3916 assert(st3 == SysTime(DateTime(1999, 3, 1, 12, 33, 33))); 3917 3918 auto st4 = SysTime(DateTime(1999, 1, 29, 12, 33, 33)); 3919 st4.roll!"months"(1, AllowDayOverflow.no); 3920 assert(st4 == SysTime(DateTime(1999, 2, 28, 12, 33, 33))); 3921 3922 auto st5 = SysTime(DateTime(2000, 2, 29, 12, 30, 33)); 3923 st5.roll!"years"(1); 3924 assert(st5 == SysTime(DateTime(2001, 3, 1, 12, 30, 33))); 3925 3926 auto st6 = SysTime(DateTime(2000, 2, 29, 12, 30, 33)); 3927 st6.roll!"years"(1, AllowDayOverflow.no); 3928 assert(st6 == SysTime(DateTime(2001, 2, 28, 12, 30, 33))); 3929 } 3930 3931 @safe unittest 3932 { 3933 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 3934 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 3935 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 3936 st.roll!"years"(4); 3937 static assert(!__traits(compiles, cst.roll!"years"(4))); 3938 static assert(!__traits(compiles, ist.roll!"years"(4))); 3939 3940 static void testScope(scope ref SysTime st) @safe 3941 { 3942 auto result = st.roll!"years"(42); 3943 } 3944 } 3945 3946 3947 // Shares documentation with "years" overload. 3948 ref SysTime roll(string units) 3949 (long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe nothrow scope 3950 if (units == "months") 3951 { 3952 auto hnsecs = adjTime; 3953 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 3954 3955 if (hnsecs < 0) 3956 { 3957 hnsecs += convert!("hours", "hnsecs")(24); 3958 --days; 3959 } 3960 3961 auto date = Date(cast(int) days); 3962 date.roll!"months"(value, allowOverflow); 3963 days = date.dayOfGregorianCal - 1; 3964 3965 if (days < 0) 3966 { 3967 hnsecs -= convert!("hours", "hnsecs")(24); 3968 ++days; 3969 } 3970 3971 immutable newDaysHNSecs = convert!("days", "hnsecs")(days); 3972 adjTime = newDaysHNSecs + hnsecs; 3973 return this; 3974 } 3975 3976 // Test roll!"months"() with AllowDayOverflow.yes 3977 @safe unittest 3978 { 3979 import core.time; 3980 // Test A.D. 3981 { 3982 auto sysTime = SysTime(Date(1999, 7, 6)); 3983 sysTime.roll!"months"(3); 3984 assert(sysTime == SysTime(Date(1999, 10, 6))); 3985 sysTime.roll!"months"(-4); 3986 assert(sysTime == SysTime(Date(1999, 6, 6))); 3987 } 3988 3989 { 3990 auto sysTime = SysTime(Date(1999, 7, 6)); 3991 sysTime.roll!"months"(6); 3992 assert(sysTime == SysTime(Date(1999, 1, 6))); 3993 sysTime.roll!"months"(-6); 3994 assert(sysTime == SysTime(Date(1999, 7, 6))); 3995 } 3996 3997 { 3998 auto sysTime = SysTime(Date(1999, 7, 6)); 3999 sysTime.roll!"months"(27); 4000 assert(sysTime == SysTime(Date(1999, 10, 6))); 4001 sysTime.roll!"months"(-28); 4002 assert(sysTime == SysTime(Date(1999, 6, 6))); 4003 } 4004 4005 { 4006 auto sysTime = SysTime(Date(1999, 5, 31)); 4007 sysTime.roll!"months"(1); 4008 assert(sysTime == SysTime(Date(1999, 7, 1))); 4009 } 4010 4011 { 4012 auto sysTime = SysTime(Date(1999, 5, 31)); 4013 sysTime.roll!"months"(-1); 4014 assert(sysTime == SysTime(Date(1999, 5, 1))); 4015 } 4016 4017 { 4018 auto sysTime = SysTime(Date(1999, 2, 28)); 4019 sysTime.roll!"months"(12); 4020 assert(sysTime == SysTime(Date(1999, 2, 28))); 4021 } 4022 4023 { 4024 auto sysTime = SysTime(Date(2000, 2, 29)); 4025 sysTime.roll!"months"(12); 4026 assert(sysTime == SysTime(Date(2000, 2, 29))); 4027 } 4028 4029 { 4030 auto sysTime = SysTime(Date(1999, 7, 31)); 4031 sysTime.roll!"months"(1); 4032 assert(sysTime == SysTime(Date(1999, 8, 31))); 4033 sysTime.roll!"months"(1); 4034 assert(sysTime == SysTime(Date(1999, 10, 1))); 4035 } 4036 4037 { 4038 auto sysTime = SysTime(Date(1998, 8, 31)); 4039 sysTime.roll!"months"(13); 4040 assert(sysTime == SysTime(Date(1998, 10, 1))); 4041 sysTime.roll!"months"(-13); 4042 assert(sysTime == SysTime(Date(1998, 9, 1))); 4043 } 4044 4045 { 4046 auto sysTime = SysTime(Date(1997, 12, 31)); 4047 sysTime.roll!"months"(13); 4048 assert(sysTime == SysTime(Date(1997, 1, 31))); 4049 sysTime.roll!"months"(-13); 4050 assert(sysTime == SysTime(Date(1997, 12, 31))); 4051 } 4052 4053 { 4054 auto sysTime = SysTime(Date(1997, 12, 31)); 4055 sysTime.roll!"months"(14); 4056 assert(sysTime == SysTime(Date(1997, 3, 3))); 4057 sysTime.roll!"months"(-14); 4058 assert(sysTime == SysTime(Date(1997, 1, 3))); 4059 } 4060 4061 { 4062 auto sysTime = SysTime(Date(1998, 12, 31)); 4063 sysTime.roll!"months"(14); 4064 assert(sysTime == SysTime(Date(1998, 3, 3))); 4065 sysTime.roll!"months"(-14); 4066 assert(sysTime == SysTime(Date(1998, 1, 3))); 4067 } 4068 4069 { 4070 auto sysTime = SysTime(Date(1999, 12, 31)); 4071 sysTime.roll!"months"(14); 4072 assert(sysTime == SysTime(Date(1999, 3, 3))); 4073 sysTime.roll!"months"(-14); 4074 assert(sysTime == SysTime(Date(1999, 1, 3))); 4075 } 4076 4077 { 4078 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), usecs(5007)); 4079 sysTime.roll!"months"(3); 4080 assert(sysTime == SysTime(DateTime(1999, 10, 6, 12, 2, 7), usecs(5007))); 4081 sysTime.roll!"months"(-4); 4082 assert(sysTime == SysTime(DateTime(1999, 6, 6, 12, 2, 7), usecs(5007))); 4083 } 4084 4085 { 4086 auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), hnsecs(422202)); 4087 sysTime.roll!"months"(14); 4088 assert(sysTime == SysTime(DateTime(1998, 3, 3, 7, 7, 7), hnsecs(422202))); 4089 sysTime.roll!"months"(-14); 4090 assert(sysTime == SysTime(DateTime(1998, 1, 3, 7, 7, 7), hnsecs(422202))); 4091 } 4092 4093 { 4094 auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), hnsecs(422202)); 4095 sysTime.roll!"months"(14); 4096 assert(sysTime == SysTime(DateTime(1999, 3, 3, 7, 7, 7), hnsecs(422202))); 4097 sysTime.roll!"months"(-14); 4098 assert(sysTime == SysTime(DateTime(1999, 1, 3, 7, 7, 7), hnsecs(422202))); 4099 } 4100 4101 // Test B.C. 4102 { 4103 auto sysTime = SysTime(Date(-1999, 7, 6)); 4104 sysTime.roll!"months"(3); 4105 assert(sysTime == SysTime(Date(-1999, 10, 6))); 4106 sysTime.roll!"months"(-4); 4107 assert(sysTime == SysTime(Date(-1999, 6, 6))); 4108 } 4109 4110 { 4111 auto sysTime = SysTime(Date(-1999, 7, 6)); 4112 sysTime.roll!"months"(6); 4113 assert(sysTime == SysTime(Date(-1999, 1, 6))); 4114 sysTime.roll!"months"(-6); 4115 assert(sysTime == SysTime(Date(-1999, 7, 6))); 4116 } 4117 4118 { 4119 auto sysTime = SysTime(Date(-1999, 7, 6)); 4120 sysTime.roll!"months"(-27); 4121 assert(sysTime == SysTime(Date(-1999, 4, 6))); 4122 sysTime.roll!"months"(28); 4123 assert(sysTime == SysTime(Date(-1999, 8, 6))); 4124 } 4125 4126 { 4127 auto sysTime = SysTime(Date(-1999, 5, 31)); 4128 sysTime.roll!"months"(1); 4129 assert(sysTime == SysTime(Date(-1999, 7, 1))); 4130 } 4131 4132 { 4133 auto sysTime = SysTime(Date(-1999, 5, 31)); 4134 sysTime.roll!"months"(-1); 4135 assert(sysTime == SysTime(Date(-1999, 5, 1))); 4136 } 4137 4138 { 4139 auto sysTime = SysTime(Date(-1999, 2, 28)); 4140 sysTime.roll!"months"(-12); 4141 assert(sysTime == SysTime(Date(-1999, 2, 28))); 4142 } 4143 4144 { 4145 auto sysTime = SysTime(Date(-2000, 2, 29)); 4146 sysTime.roll!"months"(-12); 4147 assert(sysTime == SysTime(Date(-2000, 2, 29))); 4148 } 4149 4150 { 4151 auto sysTime = SysTime(Date(-1999, 7, 31)); 4152 sysTime.roll!"months"(1); 4153 assert(sysTime == SysTime(Date(-1999, 8, 31))); 4154 sysTime.roll!"months"(1); 4155 assert(sysTime == SysTime(Date(-1999, 10, 1))); 4156 } 4157 4158 { 4159 auto sysTime = SysTime(Date(-1998, 8, 31)); 4160 sysTime.roll!"months"(13); 4161 assert(sysTime == SysTime(Date(-1998, 10, 1))); 4162 sysTime.roll!"months"(-13); 4163 assert(sysTime == SysTime(Date(-1998, 9, 1))); 4164 } 4165 4166 { 4167 auto sysTime = SysTime(Date(-1997, 12, 31)); 4168 sysTime.roll!"months"(13); 4169 assert(sysTime == SysTime(Date(-1997, 1, 31))); 4170 sysTime.roll!"months"(-13); 4171 assert(sysTime == SysTime(Date(-1997, 12, 31))); 4172 } 4173 4174 { 4175 auto sysTime = SysTime(Date(-1997, 12, 31)); 4176 sysTime.roll!"months"(14); 4177 assert(sysTime == SysTime(Date(-1997, 3, 3))); 4178 sysTime.roll!"months"(-14); 4179 assert(sysTime == SysTime(Date(-1997, 1, 3))); 4180 } 4181 4182 { 4183 auto sysTime = SysTime(Date(-2002, 12, 31)); 4184 sysTime.roll!"months"(14); 4185 assert(sysTime == SysTime(Date(-2002, 3, 3))); 4186 sysTime.roll!"months"(-14); 4187 assert(sysTime == SysTime(Date(-2002, 1, 3))); 4188 } 4189 4190 { 4191 auto sysTime = SysTime(Date(-2001, 12, 31)); 4192 sysTime.roll!"months"(14); 4193 assert(sysTime == SysTime(Date(-2001, 3, 3))); 4194 sysTime.roll!"months"(-14); 4195 assert(sysTime == SysTime(Date(-2001, 1, 3))); 4196 } 4197 4198 { 4199 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 4200 sysTime.roll!"months"(-1); 4201 assert(sysTime == SysTime(DateTime(1, 12, 1, 0, 0, 0))); 4202 sysTime.roll!"months"(1); 4203 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 4204 } 4205 4206 { 4207 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 4208 sysTime.roll!"months"(-1); 4209 assert(sysTime == SysTime(DateTime(1, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 4210 sysTime.roll!"months"(1); 4211 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 4212 } 4213 4214 { 4215 auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0)); 4216 sysTime.roll!"months"(1); 4217 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0))); 4218 sysTime.roll!"months"(-1); 4219 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 4220 } 4221 4222 { 4223 auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)); 4224 sysTime.roll!"months"(1); 4225 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 4226 sysTime.roll!"months"(-1); 4227 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 4228 } 4229 4230 { 4231 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), hnsecs(5007)); 4232 sysTime.roll!"months"(3); 4233 assert(sysTime == SysTime(DateTime(-1999, 10, 6, 12, 2, 7), hnsecs(5007))); 4234 sysTime.roll!"months"(-4); 4235 assert(sysTime == SysTime(DateTime(-1999, 6, 6, 12, 2, 7), hnsecs(5007))); 4236 } 4237 4238 { 4239 auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), hnsecs(422202)); 4240 sysTime.roll!"months"(14); 4241 assert(sysTime == SysTime(DateTime(-2002, 3, 3, 7, 7, 7), hnsecs(422202))); 4242 sysTime.roll!"months"(-14); 4243 assert(sysTime == SysTime(DateTime(-2002, 1, 3, 7, 7, 7), hnsecs(422202))); 4244 } 4245 4246 { 4247 auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), hnsecs(422202)); 4248 sysTime.roll!"months"(14); 4249 assert(sysTime == SysTime(DateTime(-2001, 3, 3, 7, 7, 7), hnsecs(422202))); 4250 sysTime.roll!"months"(-14); 4251 assert(sysTime == SysTime(DateTime(-2001, 1, 3, 7, 7, 7), hnsecs(422202))); 4252 } 4253 4254 // Test Both 4255 { 4256 auto sysTime = SysTime(Date(1, 1, 1)); 4257 sysTime.roll!"months"(-1); 4258 assert(sysTime == SysTime(Date(1, 12, 1))); 4259 sysTime.roll!"months"(1); 4260 assert(sysTime == SysTime(Date(1, 1, 1))); 4261 } 4262 4263 { 4264 auto sysTime = SysTime(Date(4, 1, 1)); 4265 sysTime.roll!"months"(-48); 4266 assert(sysTime == SysTime(Date(4, 1, 1))); 4267 sysTime.roll!"months"(48); 4268 assert(sysTime == SysTime(Date(4, 1, 1))); 4269 } 4270 4271 { 4272 auto sysTime = SysTime(Date(4, 3, 31)); 4273 sysTime.roll!"months"(-49); 4274 assert(sysTime == SysTime(Date(4, 3, 2))); 4275 sysTime.roll!"months"(49); 4276 assert(sysTime == SysTime(Date(4, 4, 2))); 4277 } 4278 4279 { 4280 auto sysTime = SysTime(Date(4, 3, 31)); 4281 sysTime.roll!"months"(-85); 4282 assert(sysTime == SysTime(Date(4, 3, 2))); 4283 sysTime.roll!"months"(85); 4284 assert(sysTime == SysTime(Date(4, 4, 2))); 4285 } 4286 4287 { 4288 auto sysTime = SysTime(Date(-1, 1, 1)); 4289 sysTime.roll!"months"(-1); 4290 assert(sysTime == SysTime(Date(-1, 12, 1))); 4291 sysTime.roll!"months"(1); 4292 assert(sysTime == SysTime(Date(-1, 1, 1))); 4293 } 4294 4295 { 4296 auto sysTime = SysTime(Date(-4, 1, 1)); 4297 sysTime.roll!"months"(-48); 4298 assert(sysTime == SysTime(Date(-4, 1, 1))); 4299 sysTime.roll!"months"(48); 4300 assert(sysTime == SysTime(Date(-4, 1, 1))); 4301 } 4302 4303 { 4304 auto sysTime = SysTime(Date(-4, 3, 31)); 4305 sysTime.roll!"months"(-49); 4306 assert(sysTime == SysTime(Date(-4, 3, 2))); 4307 sysTime.roll!"months"(49); 4308 assert(sysTime == SysTime(Date(-4, 4, 2))); 4309 } 4310 4311 { 4312 auto sysTime = SysTime(Date(-4, 3, 31)); 4313 sysTime.roll!"months"(-85); 4314 assert(sysTime == SysTime(Date(-4, 3, 2))); 4315 sysTime.roll!"months"(85); 4316 assert(sysTime == SysTime(Date(-4, 4, 2))); 4317 } 4318 4319 { 4320 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17)); 4321 sysTime.roll!"months"(-1); 4322 assert(sysTime == SysTime(DateTime(1, 12, 1, 0, 7, 9), hnsecs(17))); 4323 sysTime.roll!"months"(1); 4324 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17))); 4325 } 4326 4327 { 4328 auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), msecs(9)); 4329 sysTime.roll!"months"(-85); 4330 assert(sysTime == SysTime(DateTime(4, 3, 2, 12, 11, 10), msecs(9))); 4331 sysTime.roll!"months"(85); 4332 assert(sysTime == SysTime(DateTime(4, 4, 2, 12, 11, 10), msecs(9))); 4333 } 4334 4335 { 4336 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 4337 sysTime.roll!"months"(85); 4338 assert(sysTime == SysTime(DateTime(-3, 5, 1, 12, 11, 10), msecs(9))); 4339 sysTime.roll!"months"(-85); 4340 assert(sysTime == SysTime(DateTime(-3, 4, 1, 12, 11, 10), msecs(9))); 4341 } 4342 4343 { 4344 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 4345 sysTime.roll!"months"(85).roll!"months"(-83); 4346 assert(sysTime == SysTime(DateTime(-3, 6, 1, 12, 11, 10), msecs(9))); 4347 } 4348 4349 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 4350 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 4351 static assert(!__traits(compiles, cst.roll!"months"(4))); 4352 static assert(!__traits(compiles, ist.roll!"months"(4))); 4353 4354 static void testScope(scope ref SysTime st) @safe 4355 { 4356 auto result = st.roll!"months"(42); 4357 } 4358 } 4359 4360 // Test roll!"months"() with AllowDayOverflow.no 4361 @safe unittest 4362 { 4363 import core.time; 4364 // Test A.D. 4365 { 4366 auto sysTime = SysTime(Date(1999, 7, 6)); 4367 sysTime.roll!"months"(3, AllowDayOverflow.no); 4368 assert(sysTime == SysTime(Date(1999, 10, 6))); 4369 sysTime.roll!"months"(-4, AllowDayOverflow.no); 4370 assert(sysTime == SysTime(Date(1999, 6, 6))); 4371 } 4372 4373 { 4374 auto sysTime = SysTime(Date(1999, 7, 6)); 4375 sysTime.roll!"months"(6, AllowDayOverflow.no); 4376 assert(sysTime == SysTime(Date(1999, 1, 6))); 4377 sysTime.roll!"months"(-6, AllowDayOverflow.no); 4378 assert(sysTime == SysTime(Date(1999, 7, 6))); 4379 } 4380 4381 { 4382 auto sysTime = SysTime(Date(1999, 7, 6)); 4383 sysTime.roll!"months"(27, AllowDayOverflow.no); 4384 assert(sysTime == SysTime(Date(1999, 10, 6))); 4385 sysTime.roll!"months"(-28, AllowDayOverflow.no); 4386 assert(sysTime == SysTime(Date(1999, 6, 6))); 4387 } 4388 4389 { 4390 auto sysTime = SysTime(Date(1999, 5, 31)); 4391 sysTime.roll!"months"(1, AllowDayOverflow.no); 4392 assert(sysTime == SysTime(Date(1999, 6, 30))); 4393 } 4394 4395 { 4396 auto sysTime = SysTime(Date(1999, 5, 31)); 4397 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4398 assert(sysTime == SysTime(Date(1999, 4, 30))); 4399 } 4400 4401 { 4402 auto sysTime = SysTime(Date(1999, 2, 28)); 4403 sysTime.roll!"months"(12, AllowDayOverflow.no); 4404 assert(sysTime == SysTime(Date(1999, 2, 28))); 4405 } 4406 4407 { 4408 auto sysTime = SysTime(Date(2000, 2, 29)); 4409 sysTime.roll!"months"(12, AllowDayOverflow.no); 4410 assert(sysTime == SysTime(Date(2000, 2, 29))); 4411 } 4412 4413 { 4414 auto sysTime = SysTime(Date(1999, 7, 31)); 4415 sysTime.roll!"months"(1, AllowDayOverflow.no); 4416 assert(sysTime == SysTime(Date(1999, 8, 31))); 4417 sysTime.roll!"months"(1, AllowDayOverflow.no); 4418 assert(sysTime == SysTime(Date(1999, 9, 30))); 4419 } 4420 4421 { 4422 auto sysTime = SysTime(Date(1998, 8, 31)); 4423 sysTime.roll!"months"(13, AllowDayOverflow.no); 4424 assert(sysTime == SysTime(Date(1998, 9, 30))); 4425 sysTime.roll!"months"(-13, AllowDayOverflow.no); 4426 assert(sysTime == SysTime(Date(1998, 8, 30))); 4427 } 4428 4429 { 4430 auto sysTime = SysTime(Date(1997, 12, 31)); 4431 sysTime.roll!"months"(13, AllowDayOverflow.no); 4432 assert(sysTime == SysTime(Date(1997, 1, 31))); 4433 sysTime.roll!"months"(-13, AllowDayOverflow.no); 4434 assert(sysTime == SysTime(Date(1997, 12, 31))); 4435 } 4436 4437 { 4438 auto sysTime = SysTime(Date(1997, 12, 31)); 4439 sysTime.roll!"months"(14, AllowDayOverflow.no); 4440 assert(sysTime == SysTime(Date(1997, 2, 28))); 4441 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4442 assert(sysTime == SysTime(Date(1997, 12, 28))); 4443 } 4444 4445 { 4446 auto sysTime = SysTime(Date(1998, 12, 31)); 4447 sysTime.roll!"months"(14, AllowDayOverflow.no); 4448 assert(sysTime == SysTime(Date(1998, 2, 28))); 4449 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4450 assert(sysTime == SysTime(Date(1998, 12, 28))); 4451 } 4452 4453 { 4454 auto sysTime = SysTime(Date(1999, 12, 31)); 4455 sysTime.roll!"months"(14, AllowDayOverflow.no); 4456 assert(sysTime == SysTime(Date(1999, 2, 28))); 4457 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4458 assert(sysTime == SysTime(Date(1999, 12, 28))); 4459 } 4460 4461 { 4462 auto sysTime = SysTime(DateTime(1999, 7, 6, 12, 2, 7), usecs(5007)); 4463 sysTime.roll!"months"(3, AllowDayOverflow.no); 4464 assert(sysTime == SysTime(DateTime(1999, 10, 6, 12, 2, 7), usecs(5007))); 4465 sysTime.roll!"months"(-4, AllowDayOverflow.no); 4466 assert(sysTime == SysTime(DateTime(1999, 6, 6, 12, 2, 7), usecs(5007))); 4467 } 4468 4469 { 4470 auto sysTime = SysTime(DateTime(1998, 12, 31, 7, 7, 7), hnsecs(422202)); 4471 sysTime.roll!"months"(14, AllowDayOverflow.no); 4472 assert(sysTime == SysTime(DateTime(1998, 2, 28, 7, 7, 7), hnsecs(422202))); 4473 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4474 assert(sysTime == SysTime(DateTime(1998, 12, 28, 7, 7, 7), hnsecs(422202))); 4475 } 4476 4477 { 4478 auto sysTime = SysTime(DateTime(1999, 12, 31, 7, 7, 7), hnsecs(422202)); 4479 sysTime.roll!"months"(14, AllowDayOverflow.no); 4480 assert(sysTime == SysTime(DateTime(1999, 2, 28, 7, 7, 7), hnsecs(422202))); 4481 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4482 assert(sysTime == SysTime(DateTime(1999, 12, 28, 7, 7, 7), hnsecs(422202))); 4483 } 4484 4485 // Test B.C. 4486 { 4487 auto sysTime = SysTime(Date(-1999, 7, 6)); 4488 sysTime.roll!"months"(3, AllowDayOverflow.no); 4489 assert(sysTime == SysTime(Date(-1999, 10, 6))); 4490 sysTime.roll!"months"(-4, AllowDayOverflow.no); 4491 assert(sysTime == SysTime(Date(-1999, 6, 6))); 4492 } 4493 4494 { 4495 auto sysTime = SysTime(Date(-1999, 7, 6)); 4496 sysTime.roll!"months"(6, AllowDayOverflow.no); 4497 assert(sysTime == SysTime(Date(-1999, 1, 6))); 4498 sysTime.roll!"months"(-6, AllowDayOverflow.no); 4499 assert(sysTime == SysTime(Date(-1999, 7, 6))); 4500 } 4501 4502 { 4503 auto sysTime = SysTime(Date(-1999, 7, 6)); 4504 sysTime.roll!"months"(-27, AllowDayOverflow.no); 4505 assert(sysTime == SysTime(Date(-1999, 4, 6))); 4506 sysTime.roll!"months"(28, AllowDayOverflow.no); 4507 assert(sysTime == SysTime(Date(-1999, 8, 6))); 4508 } 4509 4510 { 4511 auto sysTime = SysTime(Date(-1999, 5, 31)); 4512 sysTime.roll!"months"(1, AllowDayOverflow.no); 4513 assert(sysTime == SysTime(Date(-1999, 6, 30))); 4514 } 4515 4516 { 4517 auto sysTime = SysTime(Date(-1999, 5, 31)); 4518 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4519 assert(sysTime == SysTime(Date(-1999, 4, 30))); 4520 } 4521 4522 { 4523 auto sysTime = SysTime(Date(-1999, 2, 28)); 4524 sysTime.roll!"months"(-12, AllowDayOverflow.no); 4525 assert(sysTime == SysTime(Date(-1999, 2, 28))); 4526 } 4527 4528 { 4529 auto sysTime = SysTime(Date(-2000, 2, 29)); 4530 sysTime.roll!"months"(-12, AllowDayOverflow.no); 4531 assert(sysTime == SysTime(Date(-2000, 2, 29))); 4532 } 4533 4534 { 4535 auto sysTime = SysTime(Date(-1999, 7, 31)); 4536 sysTime.roll!"months"(1, AllowDayOverflow.no); 4537 assert(sysTime == SysTime(Date(-1999, 8, 31))); 4538 sysTime.roll!"months"(1, AllowDayOverflow.no); 4539 assert(sysTime == SysTime(Date(-1999, 9, 30))); 4540 } 4541 4542 { 4543 auto sysTime = SysTime(Date(-1998, 8, 31)); 4544 sysTime.roll!"months"(13, AllowDayOverflow.no); 4545 assert(sysTime == SysTime(Date(-1998, 9, 30))); 4546 sysTime.roll!"months"(-13, AllowDayOverflow.no); 4547 assert(sysTime == SysTime(Date(-1998, 8, 30))); 4548 } 4549 4550 { 4551 auto sysTime = SysTime(Date(-1997, 12, 31)); 4552 sysTime.roll!"months"(13, AllowDayOverflow.no); 4553 assert(sysTime == SysTime(Date(-1997, 1, 31))); 4554 sysTime.roll!"months"(-13, AllowDayOverflow.no); 4555 assert(sysTime == SysTime(Date(-1997, 12, 31))); 4556 } 4557 4558 { 4559 auto sysTime = SysTime(Date(-1997, 12, 31)); 4560 sysTime.roll!"months"(14, AllowDayOverflow.no); 4561 assert(sysTime == SysTime(Date(-1997, 2, 28))); 4562 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4563 assert(sysTime == SysTime(Date(-1997, 12, 28))); 4564 } 4565 4566 { 4567 auto sysTime = SysTime(Date(-2002, 12, 31)); 4568 sysTime.roll!"months"(14, AllowDayOverflow.no); 4569 assert(sysTime == SysTime(Date(-2002, 2, 28))); 4570 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4571 assert(sysTime == SysTime(Date(-2002, 12, 28))); 4572 } 4573 4574 { 4575 auto sysTime = SysTime(Date(-2001, 12, 31)); 4576 sysTime.roll!"months"(14, AllowDayOverflow.no); 4577 assert(sysTime == SysTime(Date(-2001, 2, 28))); 4578 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4579 assert(sysTime == SysTime(Date(-2001, 12, 28))); 4580 } 4581 4582 { 4583 auto sysTime = SysTime(DateTime(-1999, 7, 6, 12, 2, 7), usecs(5007)); 4584 sysTime.roll!"months"(3, AllowDayOverflow.no); 4585 assert(sysTime == SysTime(DateTime(-1999, 10, 6, 12, 2, 7), usecs(5007))); 4586 sysTime.roll!"months"(-4, AllowDayOverflow.no); 4587 assert(sysTime == SysTime(DateTime(-1999, 6, 6, 12, 2, 7), usecs(5007))); 4588 } 4589 4590 { 4591 auto sysTime = SysTime(DateTime(-2002, 12, 31, 7, 7, 7), hnsecs(422202)); 4592 sysTime.roll!"months"(14, AllowDayOverflow.no); 4593 assert(sysTime == SysTime(DateTime(-2002, 2, 28, 7, 7, 7), hnsecs(422202))); 4594 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4595 assert(sysTime == SysTime(DateTime(-2002, 12, 28, 7, 7, 7), hnsecs(422202))); 4596 } 4597 4598 { 4599 auto sysTime = SysTime(DateTime(-2001, 12, 31, 7, 7, 7), hnsecs(422202)); 4600 sysTime.roll!"months"(14, AllowDayOverflow.no); 4601 assert(sysTime == SysTime(DateTime(-2001, 2, 28, 7, 7, 7), hnsecs(422202))); 4602 sysTime.roll!"months"(-14, AllowDayOverflow.no); 4603 assert(sysTime == SysTime(DateTime(-2001, 12, 28, 7, 7, 7), hnsecs(422202))); 4604 } 4605 4606 // Test Both 4607 { 4608 auto sysTime = SysTime(Date(1, 1, 1)); 4609 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4610 assert(sysTime == SysTime(Date(1, 12, 1))); 4611 sysTime.roll!"months"(1, AllowDayOverflow.no); 4612 assert(sysTime == SysTime(Date(1, 1, 1))); 4613 } 4614 4615 { 4616 auto sysTime = SysTime(Date(4, 1, 1)); 4617 sysTime.roll!"months"(-48, AllowDayOverflow.no); 4618 assert(sysTime == SysTime(Date(4, 1, 1))); 4619 sysTime.roll!"months"(48, AllowDayOverflow.no); 4620 assert(sysTime == SysTime(Date(4, 1, 1))); 4621 } 4622 4623 { 4624 auto sysTime = SysTime(Date(4, 3, 31)); 4625 sysTime.roll!"months"(-49, AllowDayOverflow.no); 4626 assert(sysTime == SysTime(Date(4, 2, 29))); 4627 sysTime.roll!"months"(49, AllowDayOverflow.no); 4628 assert(sysTime == SysTime(Date(4, 3, 29))); 4629 } 4630 4631 { 4632 auto sysTime = SysTime(Date(4, 3, 31)); 4633 sysTime.roll!"months"(-85, AllowDayOverflow.no); 4634 assert(sysTime == SysTime(Date(4, 2, 29))); 4635 sysTime.roll!"months"(85, AllowDayOverflow.no); 4636 assert(sysTime == SysTime(Date(4, 3, 29))); 4637 } 4638 4639 { 4640 auto sysTime = SysTime(Date(-1, 1, 1)); 4641 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4642 assert(sysTime == SysTime(Date(-1, 12, 1))); 4643 sysTime.roll!"months"(1, AllowDayOverflow.no); 4644 assert(sysTime == SysTime(Date(-1, 1, 1))); 4645 } 4646 4647 { 4648 auto sysTime = SysTime(Date(-4, 1, 1)); 4649 sysTime.roll!"months"(-48, AllowDayOverflow.no); 4650 assert(sysTime == SysTime(Date(-4, 1, 1))); 4651 sysTime.roll!"months"(48, AllowDayOverflow.no); 4652 assert(sysTime == SysTime(Date(-4, 1, 1))); 4653 } 4654 4655 { 4656 auto sysTime = SysTime(Date(-4, 3, 31)); 4657 sysTime.roll!"months"(-49, AllowDayOverflow.no); 4658 assert(sysTime == SysTime(Date(-4, 2, 29))); 4659 sysTime.roll!"months"(49, AllowDayOverflow.no); 4660 assert(sysTime == SysTime(Date(-4, 3, 29))); 4661 } 4662 4663 { 4664 auto sysTime = SysTime(Date(-4, 3, 31)); 4665 sysTime.roll!"months"(-85, AllowDayOverflow.no); 4666 assert(sysTime == SysTime(Date(-4, 2, 29))); 4667 sysTime.roll!"months"(85, AllowDayOverflow.no); 4668 assert(sysTime == SysTime(Date(-4, 3, 29))); 4669 } 4670 4671 { 4672 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 4673 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4674 assert(sysTime == SysTime(DateTime(1, 12, 1, 0, 0, 0))); 4675 sysTime.roll!"months"(1, AllowDayOverflow.no); 4676 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 4677 } 4678 4679 { 4680 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 4681 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4682 assert(sysTime == SysTime(DateTime(1, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 4683 sysTime.roll!"months"(1, AllowDayOverflow.no); 4684 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 4685 } 4686 4687 { 4688 auto sysTime = SysTime(DateTime(0, 12, 1, 0, 0, 0)); 4689 sysTime.roll!"months"(1, AllowDayOverflow.no); 4690 assert(sysTime == SysTime(DateTime(0, 1, 1, 0, 0, 0))); 4691 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4692 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 4693 } 4694 4695 { 4696 auto sysTime = SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999)); 4697 sysTime.roll!"months"(1, AllowDayOverflow.no); 4698 assert(sysTime == SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 4699 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4700 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 4701 } 4702 4703 { 4704 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17)); 4705 sysTime.roll!"months"(-1, AllowDayOverflow.no); 4706 assert(sysTime == SysTime(DateTime(1, 12, 1, 0, 7, 9), hnsecs(17))); 4707 sysTime.roll!"months"(1, AllowDayOverflow.no); 4708 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 7, 9), hnsecs(17))); 4709 } 4710 4711 { 4712 auto sysTime = SysTime(DateTime(4, 3, 31, 12, 11, 10), msecs(9)); 4713 sysTime.roll!"months"(-85, AllowDayOverflow.no); 4714 assert(sysTime == SysTime(DateTime(4, 2, 29, 12, 11, 10), msecs(9))); 4715 sysTime.roll!"months"(85, AllowDayOverflow.no); 4716 assert(sysTime == SysTime(DateTime(4, 3, 29, 12, 11, 10), msecs(9))); 4717 } 4718 4719 { 4720 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 4721 sysTime.roll!"months"(85, AllowDayOverflow.no); 4722 assert(sysTime == SysTime(DateTime(-3, 4, 30, 12, 11, 10), msecs(9))); 4723 sysTime.roll!"months"(-85, AllowDayOverflow.no); 4724 assert(sysTime == SysTime(DateTime(-3, 3, 30, 12, 11, 10), msecs(9))); 4725 } 4726 4727 { 4728 auto sysTime = SysTime(DateTime(-3, 3, 31, 12, 11, 10), msecs(9)); 4729 sysTime.roll!"months"(85, AllowDayOverflow.no).roll!"months"(-83, AllowDayOverflow.no); 4730 assert(sysTime == SysTime(DateTime(-3, 5, 30, 12, 11, 10), msecs(9))); 4731 } 4732 } 4733 4734 4735 /++ 4736 Adds the given number of units to this $(LREF SysTime). A negative number 4737 will subtract. 4738 4739 The difference between rolling and adding is that rolling does not 4740 affect larger units. For instance, rolling a $(LREF SysTime) one 4741 year's worth of days gets the exact same $(LREF SysTime). 4742 4743 Accepted units are `"days"`, `"minutes"`, `"hours"`, 4744 `"minutes"`, `"seconds"`, `"msecs"`, `"usecs"`, and 4745 `"hnsecs"`. 4746 4747 Note that when rolling msecs, usecs or hnsecs, they all add up to a 4748 second. So, for example, rolling 1000 msecs is exactly the same as 4749 rolling 100,000 usecs. 4750 4751 Params: 4752 units = The units to add. 4753 value = The number of $(D_PARAM units) to add to this 4754 $(LREF SysTime). 4755 +/ 4756 ref SysTime roll(string units)(long value) @safe nothrow scope 4757 if (units == "days") 4758 { 4759 auto hnsecs = adjTime; 4760 auto gdays = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 4761 4762 if (hnsecs < 0) 4763 { 4764 hnsecs += convert!("hours", "hnsecs")(24); 4765 --gdays; 4766 } 4767 4768 auto date = Date(cast(int) gdays); 4769 date.roll!"days"(value); 4770 gdays = date.dayOfGregorianCal - 1; 4771 4772 if (gdays < 0) 4773 { 4774 hnsecs -= convert!("hours", "hnsecs")(24); 4775 ++gdays; 4776 } 4777 4778 immutable newDaysHNSecs = convert!("days", "hnsecs")(gdays); 4779 adjTime = newDaysHNSecs + hnsecs; 4780 return this; 4781 } 4782 4783 /// 4784 @safe unittest 4785 { 4786 import core.time : msecs, hnsecs; 4787 import std.datetime.date : DateTime; 4788 4789 auto st1 = SysTime(DateTime(2010, 1, 1, 11, 23, 12)); 4790 st1.roll!"days"(1); 4791 assert(st1 == SysTime(DateTime(2010, 1, 2, 11, 23, 12))); 4792 st1.roll!"days"(365); 4793 assert(st1 == SysTime(DateTime(2010, 1, 26, 11, 23, 12))); 4794 st1.roll!"days"(-32); 4795 assert(st1 == SysTime(DateTime(2010, 1, 25, 11, 23, 12))); 4796 4797 auto st2 = SysTime(DateTime(2010, 7, 4, 12, 0, 0)); 4798 st2.roll!"hours"(1); 4799 assert(st2 == SysTime(DateTime(2010, 7, 4, 13, 0, 0))); 4800 4801 auto st3 = SysTime(DateTime(2010, 2, 12, 12, 0, 0)); 4802 st3.roll!"hours"(-1); 4803 assert(st3 == SysTime(DateTime(2010, 2, 12, 11, 0, 0))); 4804 4805 auto st4 = SysTime(DateTime(2009, 12, 31, 0, 0, 0)); 4806 st4.roll!"minutes"(1); 4807 assert(st4 == SysTime(DateTime(2009, 12, 31, 0, 1, 0))); 4808 4809 auto st5 = SysTime(DateTime(2010, 1, 1, 0, 0, 0)); 4810 st5.roll!"minutes"(-1); 4811 assert(st5 == SysTime(DateTime(2010, 1, 1, 0, 59, 0))); 4812 4813 auto st6 = SysTime(DateTime(2009, 12, 31, 0, 0, 0)); 4814 st6.roll!"seconds"(1); 4815 assert(st6 == SysTime(DateTime(2009, 12, 31, 0, 0, 1))); 4816 4817 auto st7 = SysTime(DateTime(2010, 1, 1, 0, 0, 0)); 4818 st7.roll!"seconds"(-1); 4819 assert(st7 == SysTime(DateTime(2010, 1, 1, 0, 0, 59))); 4820 4821 auto dt = DateTime(2010, 1, 1, 0, 0, 0); 4822 auto st8 = SysTime(dt); 4823 st8.roll!"msecs"(1); 4824 assert(st8 == SysTime(dt, msecs(1))); 4825 4826 auto st9 = SysTime(dt); 4827 st9.roll!"msecs"(-1); 4828 assert(st9 == SysTime(dt, msecs(999))); 4829 4830 auto st10 = SysTime(dt); 4831 st10.roll!"hnsecs"(1); 4832 assert(st10 == SysTime(dt, hnsecs(1))); 4833 4834 auto st11 = SysTime(dt); 4835 st11.roll!"hnsecs"(-1); 4836 assert(st11 == SysTime(dt, hnsecs(9_999_999))); 4837 } 4838 4839 @safe unittest 4840 { 4841 import core.time; 4842 // Test A.D. 4843 { 4844 auto sysTime = SysTime(Date(1999, 2, 28)); 4845 sysTime.roll!"days"(1); 4846 assert(sysTime == SysTime(Date(1999, 2, 1))); 4847 sysTime.roll!"days"(-1); 4848 assert(sysTime == SysTime(Date(1999, 2, 28))); 4849 } 4850 4851 { 4852 auto sysTime = SysTime(Date(2000, 2, 28)); 4853 sysTime.roll!"days"(1); 4854 assert(sysTime == SysTime(Date(2000, 2, 29))); 4855 sysTime.roll!"days"(1); 4856 assert(sysTime == SysTime(Date(2000, 2, 1))); 4857 sysTime.roll!"days"(-1); 4858 assert(sysTime == SysTime(Date(2000, 2, 29))); 4859 } 4860 4861 { 4862 auto sysTime = SysTime(Date(1999, 6, 30)); 4863 sysTime.roll!"days"(1); 4864 assert(sysTime == SysTime(Date(1999, 6, 1))); 4865 sysTime.roll!"days"(-1); 4866 assert(sysTime == SysTime(Date(1999, 6, 30))); 4867 } 4868 4869 { 4870 auto sysTime = SysTime(Date(1999, 7, 31)); 4871 sysTime.roll!"days"(1); 4872 assert(sysTime == SysTime(Date(1999, 7, 1))); 4873 sysTime.roll!"days"(-1); 4874 assert(sysTime == SysTime(Date(1999, 7, 31))); 4875 } 4876 4877 { 4878 auto sysTime = SysTime(Date(1999, 1, 1)); 4879 sysTime.roll!"days"(-1); 4880 assert(sysTime == SysTime(Date(1999, 1, 31))); 4881 sysTime.roll!"days"(1); 4882 assert(sysTime == SysTime(Date(1999, 1, 1))); 4883 } 4884 4885 { 4886 auto sysTime = SysTime(Date(1999, 7, 6)); 4887 sysTime.roll!"days"(9); 4888 assert(sysTime == SysTime(Date(1999, 7, 15))); 4889 sysTime.roll!"days"(-11); 4890 assert(sysTime == SysTime(Date(1999, 7, 4))); 4891 sysTime.roll!"days"(30); 4892 assert(sysTime == SysTime(Date(1999, 7, 3))); 4893 sysTime.roll!"days"(-3); 4894 assert(sysTime == SysTime(Date(1999, 7, 31))); 4895 } 4896 4897 { 4898 auto sysTime = SysTime(Date(1999, 7, 6)); 4899 sysTime.roll!"days"(365); 4900 assert(sysTime == SysTime(Date(1999, 7, 30))); 4901 sysTime.roll!"days"(-365); 4902 assert(sysTime == SysTime(Date(1999, 7, 6))); 4903 sysTime.roll!"days"(366); 4904 assert(sysTime == SysTime(Date(1999, 7, 31))); 4905 sysTime.roll!"days"(730); 4906 assert(sysTime == SysTime(Date(1999, 7, 17))); 4907 sysTime.roll!"days"(-1096); 4908 assert(sysTime == SysTime(Date(1999, 7, 6))); 4909 } 4910 4911 { 4912 auto sysTime = SysTime(Date(1999, 2, 6)); 4913 sysTime.roll!"days"(365); 4914 assert(sysTime == SysTime(Date(1999, 2, 7))); 4915 sysTime.roll!"days"(-365); 4916 assert(sysTime == SysTime(Date(1999, 2, 6))); 4917 sysTime.roll!"days"(366); 4918 assert(sysTime == SysTime(Date(1999, 2, 8))); 4919 sysTime.roll!"days"(730); 4920 assert(sysTime == SysTime(Date(1999, 2, 10))); 4921 sysTime.roll!"days"(-1096); 4922 assert(sysTime == SysTime(Date(1999, 2, 6))); 4923 } 4924 4925 { 4926 auto sysTime = SysTime(DateTime(1999, 2, 28, 7, 9, 2), usecs(234578)); 4927 sysTime.roll!"days"(1); 4928 assert(sysTime == SysTime(DateTime(1999, 2, 1, 7, 9, 2), usecs(234578))); 4929 sysTime.roll!"days"(-1); 4930 assert(sysTime == SysTime(DateTime(1999, 2, 28, 7, 9, 2), usecs(234578))); 4931 } 4932 4933 { 4934 auto sysTime = SysTime(DateTime(1999, 7, 6, 7, 9, 2), usecs(234578)); 4935 sysTime.roll!"days"(9); 4936 assert(sysTime == SysTime(DateTime(1999, 7, 15, 7, 9, 2), usecs(234578))); 4937 sysTime.roll!"days"(-11); 4938 assert(sysTime == SysTime(DateTime(1999, 7, 4, 7, 9, 2), usecs(234578))); 4939 sysTime.roll!"days"(30); 4940 assert(sysTime == SysTime(DateTime(1999, 7, 3, 7, 9, 2), usecs(234578))); 4941 sysTime.roll!"days"(-3); 4942 assert(sysTime == SysTime(DateTime(1999, 7, 31, 7, 9, 2), usecs(234578))); 4943 } 4944 4945 // Test B.C. 4946 { 4947 auto sysTime = SysTime(Date(-1999, 2, 28)); 4948 sysTime.roll!"days"(1); 4949 assert(sysTime == SysTime(Date(-1999, 2, 1))); 4950 sysTime.roll!"days"(-1); 4951 assert(sysTime == SysTime(Date(-1999, 2, 28))); 4952 } 4953 4954 { 4955 auto sysTime = SysTime(Date(-2000, 2, 28)); 4956 sysTime.roll!"days"(1); 4957 assert(sysTime == SysTime(Date(-2000, 2, 29))); 4958 sysTime.roll!"days"(1); 4959 assert(sysTime == SysTime(Date(-2000, 2, 1))); 4960 sysTime.roll!"days"(-1); 4961 assert(sysTime == SysTime(Date(-2000, 2, 29))); 4962 } 4963 4964 { 4965 auto sysTime = SysTime(Date(-1999, 6, 30)); 4966 sysTime.roll!"days"(1); 4967 assert(sysTime == SysTime(Date(-1999, 6, 1))); 4968 sysTime.roll!"days"(-1); 4969 assert(sysTime == SysTime(Date(-1999, 6, 30))); 4970 } 4971 4972 { 4973 auto sysTime = SysTime(Date(-1999, 7, 31)); 4974 sysTime.roll!"days"(1); 4975 assert(sysTime == SysTime(Date(-1999, 7, 1))); 4976 sysTime.roll!"days"(-1); 4977 assert(sysTime == SysTime(Date(-1999, 7, 31))); 4978 } 4979 4980 { 4981 auto sysTime = SysTime(Date(-1999, 1, 1)); 4982 sysTime.roll!"days"(-1); 4983 assert(sysTime == SysTime(Date(-1999, 1, 31))); 4984 sysTime.roll!"days"(1); 4985 assert(sysTime == SysTime(Date(-1999, 1, 1))); 4986 } 4987 4988 { 4989 auto sysTime = SysTime(Date(-1999, 7, 6)); 4990 sysTime.roll!"days"(9); 4991 assert(sysTime == SysTime(Date(-1999, 7, 15))); 4992 sysTime.roll!"days"(-11); 4993 assert(sysTime == SysTime(Date(-1999, 7, 4))); 4994 sysTime.roll!"days"(30); 4995 assert(sysTime == SysTime(Date(-1999, 7, 3))); 4996 sysTime.roll!"days"(-3); 4997 assert(sysTime == SysTime(Date(-1999, 7, 31))); 4998 } 4999 5000 { 5001 auto sysTime = SysTime(Date(-1999, 7, 6)); 5002 sysTime.roll!"days"(365); 5003 assert(sysTime == SysTime(Date(-1999, 7, 30))); 5004 sysTime.roll!"days"(-365); 5005 assert(sysTime == SysTime(Date(-1999, 7, 6))); 5006 sysTime.roll!"days"(366); 5007 assert(sysTime == SysTime(Date(-1999, 7, 31))); 5008 sysTime.roll!"days"(730); 5009 assert(sysTime == SysTime(Date(-1999, 7, 17))); 5010 sysTime.roll!"days"(-1096); 5011 assert(sysTime == SysTime(Date(-1999, 7, 6))); 5012 } 5013 5014 { 5015 auto sysTime = SysTime(DateTime(-1999, 2, 28, 7, 9, 2), usecs(234578)); 5016 sysTime.roll!"days"(1); 5017 assert(sysTime == SysTime(DateTime(-1999, 2, 1, 7, 9, 2), usecs(234578))); 5018 sysTime.roll!"days"(-1); 5019 assert(sysTime == SysTime(DateTime(-1999, 2, 28, 7, 9, 2), usecs(234578))); 5020 } 5021 5022 { 5023 auto sysTime = SysTime(DateTime(-1999, 7, 6, 7, 9, 2), usecs(234578)); 5024 sysTime.roll!"days"(9); 5025 assert(sysTime == SysTime(DateTime(-1999, 7, 15, 7, 9, 2), usecs(234578))); 5026 sysTime.roll!"days"(-11); 5027 assert(sysTime == SysTime(DateTime(-1999, 7, 4, 7, 9, 2), usecs(234578))); 5028 sysTime.roll!"days"(30); 5029 assert(sysTime == SysTime(DateTime(-1999, 7, 3, 7, 9, 2), usecs(234578))); 5030 sysTime.roll!"days"(-3); 5031 } 5032 5033 // Test Both 5034 { 5035 auto sysTime = SysTime(Date(1, 7, 6)); 5036 sysTime.roll!"days"(-365); 5037 assert(sysTime == SysTime(Date(1, 7, 13))); 5038 sysTime.roll!"days"(365); 5039 assert(sysTime == SysTime(Date(1, 7, 6))); 5040 sysTime.roll!"days"(-731); 5041 assert(sysTime == SysTime(Date(1, 7, 19))); 5042 sysTime.roll!"days"(730); 5043 assert(sysTime == SysTime(Date(1, 7, 5))); 5044 } 5045 5046 { 5047 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 5048 sysTime.roll!"days"(-1); 5049 assert(sysTime == SysTime(DateTime(1, 1, 31, 0, 0, 0))); 5050 sysTime.roll!"days"(1); 5051 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5052 } 5053 5054 { 5055 auto sysTime = SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)); 5056 sysTime.roll!"days"(-1); 5057 assert(sysTime == SysTime(DateTime(1, 1, 31, 23, 59, 59), hnsecs(9_999_999))); 5058 sysTime.roll!"days"(1); 5059 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 5060 } 5061 5062 { 5063 auto sysTime = SysTime(DateTime(0, 12, 31, 0, 0, 0)); 5064 sysTime.roll!"days"(1); 5065 assert(sysTime == SysTime(DateTime(0, 12, 1, 0, 0, 0))); 5066 sysTime.roll!"days"(-1); 5067 assert(sysTime == SysTime(DateTime(0, 12, 31, 0, 0, 0))); 5068 } 5069 5070 { 5071 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5072 sysTime.roll!"days"(1); 5073 assert(sysTime == SysTime(DateTime(0, 12, 1, 23, 59, 59), hnsecs(9_999_999))); 5074 sysTime.roll!"days"(-1); 5075 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5076 } 5077 5078 { 5079 auto sysTime = SysTime(DateTime(1, 7, 6, 13, 13, 9), msecs(22)); 5080 sysTime.roll!"days"(-365); 5081 assert(sysTime == SysTime(DateTime(1, 7, 13, 13, 13, 9), msecs(22))); 5082 sysTime.roll!"days"(365); 5083 assert(sysTime == SysTime(DateTime(1, 7, 6, 13, 13, 9), msecs(22))); 5084 sysTime.roll!"days"(-731); 5085 assert(sysTime == SysTime(DateTime(1, 7, 19, 13, 13, 9), msecs(22))); 5086 sysTime.roll!"days"(730); 5087 assert(sysTime == SysTime(DateTime(1, 7, 5, 13, 13, 9), msecs(22))); 5088 } 5089 5090 { 5091 auto sysTime = SysTime(DateTime(0, 7, 6, 13, 13, 9), msecs(22)); 5092 sysTime.roll!"days"(-365); 5093 assert(sysTime == SysTime(DateTime(0, 7, 13, 13, 13, 9), msecs(22))); 5094 sysTime.roll!"days"(365); 5095 assert(sysTime == SysTime(DateTime(0, 7, 6, 13, 13, 9), msecs(22))); 5096 sysTime.roll!"days"(-731); 5097 assert(sysTime == SysTime(DateTime(0, 7, 19, 13, 13, 9), msecs(22))); 5098 sysTime.roll!"days"(730); 5099 assert(sysTime == SysTime(DateTime(0, 7, 5, 13, 13, 9), msecs(22))); 5100 } 5101 5102 { 5103 auto sysTime = SysTime(DateTime(0, 7, 6, 13, 13, 9), msecs(22)); 5104 sysTime.roll!"days"(-365).roll!"days"(362).roll!"days"(-12).roll!"days"(730); 5105 assert(sysTime == SysTime(DateTime(0, 7, 8, 13, 13, 9), msecs(22))); 5106 } 5107 5108 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5109 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5110 static assert(!__traits(compiles, cst.roll!"days"(4))); 5111 static assert(!__traits(compiles, ist.roll!"days"(4))); 5112 5113 static void testScope(scope ref SysTime st) @safe 5114 { 5115 auto result = st.roll!"days"(42); 5116 } 5117 } 5118 5119 5120 // Shares documentation with "days" version. 5121 ref SysTime roll(string units)(long value) @safe nothrow scope 5122 if (units == "hours" || units == "minutes" || units == "seconds") 5123 { 5124 try 5125 { 5126 auto hnsecs = adjTime; 5127 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 5128 5129 if (hnsecs < 0) 5130 { 5131 hnsecs += convert!("hours", "hnsecs")(24); 5132 --days; 5133 } 5134 5135 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 5136 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 5137 immutable second = splitUnitsFromHNSecs!"seconds"(hnsecs); 5138 5139 auto dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour, 5140 cast(int) minute, cast(int) second)); 5141 dateTime.roll!units(value); 5142 --days; 5143 5144 hnsecs += convert!("hours", "hnsecs")(dateTime.hour); 5145 hnsecs += convert!("minutes", "hnsecs")(dateTime.minute); 5146 hnsecs += convert!("seconds", "hnsecs")(dateTime.second); 5147 5148 if (days < 0) 5149 { 5150 hnsecs -= convert!("hours", "hnsecs")(24); 5151 ++days; 5152 } 5153 5154 immutable newDaysHNSecs = convert!("days", "hnsecs")(days); 5155 adjTime = newDaysHNSecs + hnsecs; 5156 return this; 5157 } 5158 catch (Exception e) 5159 assert(0, "Either DateTime's constructor or TimeOfDay's constructor threw."); 5160 } 5161 5162 // Test roll!"hours"(). 5163 @safe unittest 5164 { 5165 import core.time; 5166 static void testST(SysTime orig, int hours, SysTime expected, size_t line = __LINE__) @safe 5167 { 5168 orig.roll!"hours"(hours); 5169 if (orig != expected) 5170 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 5171 } 5172 5173 // Test A.D. 5174 immutable d = msecs(45); 5175 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), d); 5176 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5177 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 13, 30, 33), d)); 5178 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 14, 30, 33), d)); 5179 testST(beforeAD, 3, SysTime(DateTime(1999, 7, 6, 15, 30, 33), d)); 5180 testST(beforeAD, 4, SysTime(DateTime(1999, 7, 6, 16, 30, 33), d)); 5181 testST(beforeAD, 5, SysTime(DateTime(1999, 7, 6, 17, 30, 33), d)); 5182 testST(beforeAD, 6, SysTime(DateTime(1999, 7, 6, 18, 30, 33), d)); 5183 testST(beforeAD, 7, SysTime(DateTime(1999, 7, 6, 19, 30, 33), d)); 5184 testST(beforeAD, 8, SysTime(DateTime(1999, 7, 6, 20, 30, 33), d)); 5185 testST(beforeAD, 9, SysTime(DateTime(1999, 7, 6, 21, 30, 33), d)); 5186 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 22, 30, 33), d)); 5187 testST(beforeAD, 11, SysTime(DateTime(1999, 7, 6, 23, 30, 33), d)); 5188 testST(beforeAD, 12, SysTime(DateTime(1999, 7, 6, 0, 30, 33), d)); 5189 testST(beforeAD, 13, SysTime(DateTime(1999, 7, 6, 1, 30, 33), d)); 5190 testST(beforeAD, 14, SysTime(DateTime(1999, 7, 6, 2, 30, 33), d)); 5191 testST(beforeAD, 15, SysTime(DateTime(1999, 7, 6, 3, 30, 33), d)); 5192 testST(beforeAD, 16, SysTime(DateTime(1999, 7, 6, 4, 30, 33), d)); 5193 testST(beforeAD, 17, SysTime(DateTime(1999, 7, 6, 5, 30, 33), d)); 5194 testST(beforeAD, 18, SysTime(DateTime(1999, 7, 6, 6, 30, 33), d)); 5195 testST(beforeAD, 19, SysTime(DateTime(1999, 7, 6, 7, 30, 33), d)); 5196 testST(beforeAD, 20, SysTime(DateTime(1999, 7, 6, 8, 30, 33), d)); 5197 testST(beforeAD, 21, SysTime(DateTime(1999, 7, 6, 9, 30, 33), d)); 5198 testST(beforeAD, 22, SysTime(DateTime(1999, 7, 6, 10, 30, 33), d)); 5199 testST(beforeAD, 23, SysTime(DateTime(1999, 7, 6, 11, 30, 33), d)); 5200 testST(beforeAD, 24, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5201 testST(beforeAD, 25, SysTime(DateTime(1999, 7, 6, 13, 30, 33), d)); 5202 testST(beforeAD, 50, SysTime(DateTime(1999, 7, 6, 14, 30, 33), d)); 5203 testST(beforeAD, 10_000, SysTime(DateTime(1999, 7, 6, 4, 30, 33), d)); 5204 5205 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 11, 30, 33), d)); 5206 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 10, 30, 33), d)); 5207 testST(beforeAD, -3, SysTime(DateTime(1999, 7, 6, 9, 30, 33), d)); 5208 testST(beforeAD, -4, SysTime(DateTime(1999, 7, 6, 8, 30, 33), d)); 5209 testST(beforeAD, -5, SysTime(DateTime(1999, 7, 6, 7, 30, 33), d)); 5210 testST(beforeAD, -6, SysTime(DateTime(1999, 7, 6, 6, 30, 33), d)); 5211 testST(beforeAD, -7, SysTime(DateTime(1999, 7, 6, 5, 30, 33), d)); 5212 testST(beforeAD, -8, SysTime(DateTime(1999, 7, 6, 4, 30, 33), d)); 5213 testST(beforeAD, -9, SysTime(DateTime(1999, 7, 6, 3, 30, 33), d)); 5214 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 2, 30, 33), d)); 5215 testST(beforeAD, -11, SysTime(DateTime(1999, 7, 6, 1, 30, 33), d)); 5216 testST(beforeAD, -12, SysTime(DateTime(1999, 7, 6, 0, 30, 33), d)); 5217 testST(beforeAD, -13, SysTime(DateTime(1999, 7, 6, 23, 30, 33), d)); 5218 testST(beforeAD, -14, SysTime(DateTime(1999, 7, 6, 22, 30, 33), d)); 5219 testST(beforeAD, -15, SysTime(DateTime(1999, 7, 6, 21, 30, 33), d)); 5220 testST(beforeAD, -16, SysTime(DateTime(1999, 7, 6, 20, 30, 33), d)); 5221 testST(beforeAD, -17, SysTime(DateTime(1999, 7, 6, 19, 30, 33), d)); 5222 testST(beforeAD, -18, SysTime(DateTime(1999, 7, 6, 18, 30, 33), d)); 5223 testST(beforeAD, -19, SysTime(DateTime(1999, 7, 6, 17, 30, 33), d)); 5224 testST(beforeAD, -20, SysTime(DateTime(1999, 7, 6, 16, 30, 33), d)); 5225 testST(beforeAD, -21, SysTime(DateTime(1999, 7, 6, 15, 30, 33), d)); 5226 testST(beforeAD, -22, SysTime(DateTime(1999, 7, 6, 14, 30, 33), d)); 5227 testST(beforeAD, -23, SysTime(DateTime(1999, 7, 6, 13, 30, 33), d)); 5228 testST(beforeAD, -24, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5229 testST(beforeAD, -25, SysTime(DateTime(1999, 7, 6, 11, 30, 33), d)); 5230 testST(beforeAD, -50, SysTime(DateTime(1999, 7, 6, 10, 30, 33), d)); 5231 testST(beforeAD, -10_000, SysTime(DateTime(1999, 7, 6, 20, 30, 33), d)); 5232 5233 testST(SysTime(DateTime(1999, 7, 6, 0, 30, 33), d), 1, SysTime(DateTime(1999, 7, 6, 1, 30, 33), d)); 5234 testST(SysTime(DateTime(1999, 7, 6, 0, 30, 33), d), 0, SysTime(DateTime(1999, 7, 6, 0, 30, 33), d)); 5235 testST(SysTime(DateTime(1999, 7, 6, 0, 30, 33), d), -1, SysTime(DateTime(1999, 7, 6, 23, 30, 33), d)); 5236 5237 testST(SysTime(DateTime(1999, 7, 6, 23, 30, 33), d), 1, SysTime(DateTime(1999, 7, 6, 0, 30, 33), d)); 5238 testST(SysTime(DateTime(1999, 7, 6, 23, 30, 33), d), 0, SysTime(DateTime(1999, 7, 6, 23, 30, 33), d)); 5239 testST(SysTime(DateTime(1999, 7, 6, 23, 30, 33), d), -1, SysTime(DateTime(1999, 7, 6, 22, 30, 33), d)); 5240 5241 testST(SysTime(DateTime(1999, 7, 31, 23, 30, 33), d), 1, SysTime(DateTime(1999, 7, 31, 0, 30, 33), d)); 5242 testST(SysTime(DateTime(1999, 8, 1, 0, 30, 33), d), -1, SysTime(DateTime(1999, 8, 1, 23, 30, 33), d)); 5243 5244 testST(SysTime(DateTime(1999, 12, 31, 23, 30, 33), d), 1, SysTime(DateTime(1999, 12, 31, 0, 30, 33), d)); 5245 testST(SysTime(DateTime(2000, 1, 1, 0, 30, 33), d), -1, SysTime(DateTime(2000, 1, 1, 23, 30, 33), d)); 5246 5247 testST(SysTime(DateTime(1999, 2, 28, 23, 30, 33), d), 25, SysTime(DateTime(1999, 2, 28, 0, 30, 33), d)); 5248 testST(SysTime(DateTime(1999, 3, 2, 0, 30, 33), d), -25, SysTime(DateTime(1999, 3, 2, 23, 30, 33), d)); 5249 5250 testST(SysTime(DateTime(2000, 2, 28, 23, 30, 33), d), 25, SysTime(DateTime(2000, 2, 28, 0, 30, 33), d)); 5251 testST(SysTime(DateTime(2000, 3, 1, 0, 30, 33), d), -25, SysTime(DateTime(2000, 3, 1, 23, 30, 33), d)); 5252 5253 // Test B.C. 5254 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d); 5255 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5256 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), d)); 5257 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 14, 30, 33), d)); 5258 testST(beforeBC, 3, SysTime(DateTime(-1999, 7, 6, 15, 30, 33), d)); 5259 testST(beforeBC, 4, SysTime(DateTime(-1999, 7, 6, 16, 30, 33), d)); 5260 testST(beforeBC, 5, SysTime(DateTime(-1999, 7, 6, 17, 30, 33), d)); 5261 testST(beforeBC, 6, SysTime(DateTime(-1999, 7, 6, 18, 30, 33), d)); 5262 testST(beforeBC, 7, SysTime(DateTime(-1999, 7, 6, 19, 30, 33), d)); 5263 testST(beforeBC, 8, SysTime(DateTime(-1999, 7, 6, 20, 30, 33), d)); 5264 testST(beforeBC, 9, SysTime(DateTime(-1999, 7, 6, 21, 30, 33), d)); 5265 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 22, 30, 33), d)); 5266 testST(beforeBC, 11, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d)); 5267 testST(beforeBC, 12, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d)); 5268 testST(beforeBC, 13, SysTime(DateTime(-1999, 7, 6, 1, 30, 33), d)); 5269 testST(beforeBC, 14, SysTime(DateTime(-1999, 7, 6, 2, 30, 33), d)); 5270 testST(beforeBC, 15, SysTime(DateTime(-1999, 7, 6, 3, 30, 33), d)); 5271 testST(beforeBC, 16, SysTime(DateTime(-1999, 7, 6, 4, 30, 33), d)); 5272 testST(beforeBC, 17, SysTime(DateTime(-1999, 7, 6, 5, 30, 33), d)); 5273 testST(beforeBC, 18, SysTime(DateTime(-1999, 7, 6, 6, 30, 33), d)); 5274 testST(beforeBC, 19, SysTime(DateTime(-1999, 7, 6, 7, 30, 33), d)); 5275 testST(beforeBC, 20, SysTime(DateTime(-1999, 7, 6, 8, 30, 33), d)); 5276 testST(beforeBC, 21, SysTime(DateTime(-1999, 7, 6, 9, 30, 33), d)); 5277 testST(beforeBC, 22, SysTime(DateTime(-1999, 7, 6, 10, 30, 33), d)); 5278 testST(beforeBC, 23, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), d)); 5279 testST(beforeBC, 24, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5280 testST(beforeBC, 25, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), d)); 5281 testST(beforeBC, 50, SysTime(DateTime(-1999, 7, 6, 14, 30, 33), d)); 5282 testST(beforeBC, 10_000, SysTime(DateTime(-1999, 7, 6, 4, 30, 33), d)); 5283 5284 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), d)); 5285 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 10, 30, 33), d)); 5286 testST(beforeBC, -3, SysTime(DateTime(-1999, 7, 6, 9, 30, 33), d)); 5287 testST(beforeBC, -4, SysTime(DateTime(-1999, 7, 6, 8, 30, 33), d)); 5288 testST(beforeBC, -5, SysTime(DateTime(-1999, 7, 6, 7, 30, 33), d)); 5289 testST(beforeBC, -6, SysTime(DateTime(-1999, 7, 6, 6, 30, 33), d)); 5290 testST(beforeBC, -7, SysTime(DateTime(-1999, 7, 6, 5, 30, 33), d)); 5291 testST(beforeBC, -8, SysTime(DateTime(-1999, 7, 6, 4, 30, 33), d)); 5292 testST(beforeBC, -9, SysTime(DateTime(-1999, 7, 6, 3, 30, 33), d)); 5293 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 2, 30, 33), d)); 5294 testST(beforeBC, -11, SysTime(DateTime(-1999, 7, 6, 1, 30, 33), d)); 5295 testST(beforeBC, -12, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d)); 5296 testST(beforeBC, -13, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d)); 5297 testST(beforeBC, -14, SysTime(DateTime(-1999, 7, 6, 22, 30, 33), d)); 5298 testST(beforeBC, -15, SysTime(DateTime(-1999, 7, 6, 21, 30, 33), d)); 5299 testST(beforeBC, -16, SysTime(DateTime(-1999, 7, 6, 20, 30, 33), d)); 5300 testST(beforeBC, -17, SysTime(DateTime(-1999, 7, 6, 19, 30, 33), d)); 5301 testST(beforeBC, -18, SysTime(DateTime(-1999, 7, 6, 18, 30, 33), d)); 5302 testST(beforeBC, -19, SysTime(DateTime(-1999, 7, 6, 17, 30, 33), d)); 5303 testST(beforeBC, -20, SysTime(DateTime(-1999, 7, 6, 16, 30, 33), d)); 5304 testST(beforeBC, -21, SysTime(DateTime(-1999, 7, 6, 15, 30, 33), d)); 5305 testST(beforeBC, -22, SysTime(DateTime(-1999, 7, 6, 14, 30, 33), d)); 5306 testST(beforeBC, -23, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), d)); 5307 testST(beforeBC, -24, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5308 testST(beforeBC, -25, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), d)); 5309 testST(beforeBC, -50, SysTime(DateTime(-1999, 7, 6, 10, 30, 33), d)); 5310 testST(beforeBC, -10_000, SysTime(DateTime(-1999, 7, 6, 20, 30, 33), d)); 5311 5312 testST(SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 1, 30, 33), d)); 5313 testST(SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d)); 5314 testST(SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d)); 5315 5316 testST(SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 0, 30, 33), d)); 5317 testST(SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d)); 5318 testST(SysTime(DateTime(-1999, 7, 6, 23, 30, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 22, 30, 33), d)); 5319 5320 testST(SysTime(DateTime(-1999, 7, 31, 23, 30, 33), d), 1, SysTime(DateTime(-1999, 7, 31, 0, 30, 33), d)); 5321 testST(SysTime(DateTime(-1999, 8, 1, 0, 30, 33), d), -1, SysTime(DateTime(-1999, 8, 1, 23, 30, 33), d)); 5322 5323 testST(SysTime(DateTime(-2001, 12, 31, 23, 30, 33), d), 1, SysTime(DateTime(-2001, 12, 31, 0, 30, 33), d)); 5324 testST(SysTime(DateTime(-2000, 1, 1, 0, 30, 33), d), -1, SysTime(DateTime(-2000, 1, 1, 23, 30, 33), d)); 5325 5326 testST(SysTime(DateTime(-2001, 2, 28, 23, 30, 33), d), 25, SysTime(DateTime(-2001, 2, 28, 0, 30, 33), d)); 5327 testST(SysTime(DateTime(-2001, 3, 2, 0, 30, 33), d), -25, SysTime(DateTime(-2001, 3, 2, 23, 30, 33), d)); 5328 5329 testST(SysTime(DateTime(-2000, 2, 28, 23, 30, 33), d), 25, SysTime(DateTime(-2000, 2, 28, 0, 30, 33), d)); 5330 testST(SysTime(DateTime(-2000, 3, 1, 0, 30, 33), d), -25, SysTime(DateTime(-2000, 3, 1, 23, 30, 33), d)); 5331 5332 // Test Both 5333 testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 17_546, SysTime(DateTime(-1, 1, 1, 13, 30, 33), d)); 5334 testST(SysTime(DateTime(1, 1, 1, 13, 30, 33), d), -17_546, SysTime(DateTime(1, 1, 1, 11, 30, 33), d)); 5335 5336 { 5337 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 5338 sysTime.roll!"hours"(-1); 5339 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 0, 0))); 5340 sysTime.roll!"hours"(1); 5341 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5342 } 5343 5344 { 5345 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 59, 59), hnsecs(9_999_999)); 5346 sysTime.roll!"hours"(-1); 5347 assert(sysTime == SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 5348 sysTime.roll!"hours"(1); 5349 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 59, 59), hnsecs(9_999_999))); 5350 } 5351 5352 { 5353 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 0, 0)); 5354 sysTime.roll!"hours"(1); 5355 assert(sysTime == SysTime(DateTime(0, 12, 31, 0, 0, 0))); 5356 sysTime.roll!"hours"(-1); 5357 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 0, 0))); 5358 } 5359 5360 { 5361 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5362 sysTime.roll!"hours"(1); 5363 assert(sysTime == SysTime(DateTime(0, 12, 31, 0, 59, 59), hnsecs(9_999_999))); 5364 sysTime.roll!"hours"(-1); 5365 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5366 } 5367 5368 { 5369 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5370 sysTime.roll!"hours"(1).roll!"hours"(-67); 5371 assert(sysTime == SysTime(DateTime(0, 12, 31, 5, 59, 59), hnsecs(9_999_999))); 5372 } 5373 5374 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5375 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5376 static assert(!__traits(compiles, cst.roll!"hours"(4))); 5377 static assert(!__traits(compiles, ist.roll!"hours"(4))); 5378 5379 static void testScope(scope ref SysTime st) @safe 5380 { 5381 auto result = st.roll!"hours"(42); 5382 } 5383 } 5384 5385 // Test roll!"minutes"(). 5386 @safe unittest 5387 { 5388 import core.time; 5389 static void testST(SysTime orig, int minutes, SysTime expected, size_t line = __LINE__) @safe 5390 { 5391 orig.roll!"minutes"(minutes); 5392 if (orig != expected) 5393 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 5394 } 5395 5396 // Test A.D. 5397 immutable d = usecs(7203); 5398 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), d); 5399 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5400 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 31, 33), d)); 5401 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 32, 33), d)); 5402 testST(beforeAD, 3, SysTime(DateTime(1999, 7, 6, 12, 33, 33), d)); 5403 testST(beforeAD, 4, SysTime(DateTime(1999, 7, 6, 12, 34, 33), d)); 5404 testST(beforeAD, 5, SysTime(DateTime(1999, 7, 6, 12, 35, 33), d)); 5405 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 40, 33), d)); 5406 testST(beforeAD, 15, SysTime(DateTime(1999, 7, 6, 12, 45, 33), d)); 5407 testST(beforeAD, 29, SysTime(DateTime(1999, 7, 6, 12, 59, 33), d)); 5408 testST(beforeAD, 30, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5409 testST(beforeAD, 45, SysTime(DateTime(1999, 7, 6, 12, 15, 33), d)); 5410 testST(beforeAD, 60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5411 testST(beforeAD, 75, SysTime(DateTime(1999, 7, 6, 12, 45, 33), d)); 5412 testST(beforeAD, 90, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5413 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 10, 33), d)); 5414 5415 testST(beforeAD, 689, SysTime(DateTime(1999, 7, 6, 12, 59, 33), d)); 5416 testST(beforeAD, 690, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5417 testST(beforeAD, 691, SysTime(DateTime(1999, 7, 6, 12, 1, 33), d)); 5418 testST(beforeAD, 960, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5419 testST(beforeAD, 1439, SysTime(DateTime(1999, 7, 6, 12, 29, 33), d)); 5420 testST(beforeAD, 1440, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5421 testST(beforeAD, 1441, SysTime(DateTime(1999, 7, 6, 12, 31, 33), d)); 5422 testST(beforeAD, 2880, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5423 5424 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 29, 33), d)); 5425 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 28, 33), d)); 5426 testST(beforeAD, -3, SysTime(DateTime(1999, 7, 6, 12, 27, 33), d)); 5427 testST(beforeAD, -4, SysTime(DateTime(1999, 7, 6, 12, 26, 33), d)); 5428 testST(beforeAD, -5, SysTime(DateTime(1999, 7, 6, 12, 25, 33), d)); 5429 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 20, 33), d)); 5430 testST(beforeAD, -15, SysTime(DateTime(1999, 7, 6, 12, 15, 33), d)); 5431 testST(beforeAD, -29, SysTime(DateTime(1999, 7, 6, 12, 1, 33), d)); 5432 testST(beforeAD, -30, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5433 testST(beforeAD, -45, SysTime(DateTime(1999, 7, 6, 12, 45, 33), d)); 5434 testST(beforeAD, -60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5435 testST(beforeAD, -75, SysTime(DateTime(1999, 7, 6, 12, 15, 33), d)); 5436 testST(beforeAD, -90, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5437 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 50, 33), d)); 5438 5439 testST(beforeAD, -749, SysTime(DateTime(1999, 7, 6, 12, 1, 33), d)); 5440 testST(beforeAD, -750, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5441 testST(beforeAD, -751, SysTime(DateTime(1999, 7, 6, 12, 59, 33), d)); 5442 testST(beforeAD, -960, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5443 testST(beforeAD, -1439, SysTime(DateTime(1999, 7, 6, 12, 31, 33), d)); 5444 testST(beforeAD, -1440, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5445 testST(beforeAD, -1441, SysTime(DateTime(1999, 7, 6, 12, 29, 33), d)); 5446 testST(beforeAD, -2880, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5447 5448 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 33), d), 1, SysTime(DateTime(1999, 7, 6, 12, 1, 33), d)); 5449 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 33), d), 0, SysTime(DateTime(1999, 7, 6, 12, 0, 33), d)); 5450 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 33), d), -1, SysTime(DateTime(1999, 7, 6, 12, 59, 33), d)); 5451 5452 testST(SysTime(DateTime(1999, 7, 6, 11, 59, 33), d), 1, SysTime(DateTime(1999, 7, 6, 11, 0, 33), d)); 5453 testST(SysTime(DateTime(1999, 7, 6, 11, 59, 33), d), 0, SysTime(DateTime(1999, 7, 6, 11, 59, 33), d)); 5454 testST(SysTime(DateTime(1999, 7, 6, 11, 59, 33), d), -1, SysTime(DateTime(1999, 7, 6, 11, 58, 33), d)); 5455 5456 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 33), d), 1, SysTime(DateTime(1999, 7, 6, 0, 1, 33), d)); 5457 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 33), d), 0, SysTime(DateTime(1999, 7, 6, 0, 0, 33), d)); 5458 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 33), d), -1, SysTime(DateTime(1999, 7, 6, 0, 59, 33), d)); 5459 5460 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 33), d), 1, SysTime(DateTime(1999, 7, 5, 23, 0, 33), d)); 5461 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 33), d), 0, SysTime(DateTime(1999, 7, 5, 23, 59, 33), d)); 5462 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 33), d), -1, SysTime(DateTime(1999, 7, 5, 23, 58, 33), d)); 5463 5464 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 33), d), 1, SysTime(DateTime(1998, 12, 31, 23, 0, 33), d)); 5465 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 33), d), 0, SysTime(DateTime(1998, 12, 31, 23, 59, 33), d)); 5466 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 33), d), -1, SysTime(DateTime(1998, 12, 31, 23, 58, 33), d)); 5467 5468 // Test B.C. 5469 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d); 5470 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5471 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), d)); 5472 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 32, 33), d)); 5473 testST(beforeBC, 3, SysTime(DateTime(-1999, 7, 6, 12, 33, 33), d)); 5474 testST(beforeBC, 4, SysTime(DateTime(-1999, 7, 6, 12, 34, 33), d)); 5475 testST(beforeBC, 5, SysTime(DateTime(-1999, 7, 6, 12, 35, 33), d)); 5476 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 40, 33), d)); 5477 testST(beforeBC, 15, SysTime(DateTime(-1999, 7, 6, 12, 45, 33), d)); 5478 testST(beforeBC, 29, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), d)); 5479 testST(beforeBC, 30, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5480 testST(beforeBC, 45, SysTime(DateTime(-1999, 7, 6, 12, 15, 33), d)); 5481 testST(beforeBC, 60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5482 testST(beforeBC, 75, SysTime(DateTime(-1999, 7, 6, 12, 45, 33), d)); 5483 testST(beforeBC, 90, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5484 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 10, 33), d)); 5485 5486 testST(beforeBC, 689, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), d)); 5487 testST(beforeBC, 690, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5488 testST(beforeBC, 691, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), d)); 5489 testST(beforeBC, 960, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5490 testST(beforeBC, 1439, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), d)); 5491 testST(beforeBC, 1440, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5492 testST(beforeBC, 1441, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), d)); 5493 testST(beforeBC, 2880, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5494 5495 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), d)); 5496 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 28, 33), d)); 5497 testST(beforeBC, -3, SysTime(DateTime(-1999, 7, 6, 12, 27, 33), d)); 5498 testST(beforeBC, -4, SysTime(DateTime(-1999, 7, 6, 12, 26, 33), d)); 5499 testST(beforeBC, -5, SysTime(DateTime(-1999, 7, 6, 12, 25, 33), d)); 5500 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 20, 33), d)); 5501 testST(beforeBC, -15, SysTime(DateTime(-1999, 7, 6, 12, 15, 33), d)); 5502 testST(beforeBC, -29, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), d)); 5503 testST(beforeBC, -30, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5504 testST(beforeBC, -45, SysTime(DateTime(-1999, 7, 6, 12, 45, 33), d)); 5505 testST(beforeBC, -60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5506 testST(beforeBC, -75, SysTime(DateTime(-1999, 7, 6, 12, 15, 33), d)); 5507 testST(beforeBC, -90, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5508 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 50, 33), d)); 5509 5510 testST(beforeBC, -749, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), d)); 5511 testST(beforeBC, -750, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5512 testST(beforeBC, -751, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), d)); 5513 testST(beforeBC, -960, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5514 testST(beforeBC, -1439, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), d)); 5515 testST(beforeBC, -1440, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5516 testST(beforeBC, -1441, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), d)); 5517 testST(beforeBC, -2880, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5518 5519 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 12, 1, 33), d)); 5520 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d)); 5521 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 12, 59, 33), d)); 5522 5523 testST(SysTime(DateTime(-1999, 7, 6, 11, 59, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 11, 0, 33), d)); 5524 testST(SysTime(DateTime(-1999, 7, 6, 11, 59, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 11, 59, 33), d)); 5525 testST(SysTime(DateTime(-1999, 7, 6, 11, 59, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 11, 58, 33), d)); 5526 5527 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 33), d), 1, SysTime(DateTime(-1999, 7, 6, 0, 1, 33), d)); 5528 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 33), d), 0, SysTime(DateTime(-1999, 7, 6, 0, 0, 33), d)); 5529 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 33), d), -1, SysTime(DateTime(-1999, 7, 6, 0, 59, 33), d)); 5530 5531 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 33), d), 1, SysTime(DateTime(-1999, 7, 5, 23, 0, 33), d)); 5532 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 33), d), 0, SysTime(DateTime(-1999, 7, 5, 23, 59, 33), d)); 5533 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 33), d), -1, SysTime(DateTime(-1999, 7, 5, 23, 58, 33), d)); 5534 5535 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 33), d), 1, SysTime(DateTime(-2000, 12, 31, 23, 0, 33), d)); 5536 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 33), d), 0, SysTime(DateTime(-2000, 12, 31, 23, 59, 33), d)); 5537 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 33), d), -1, SysTime(DateTime(-2000, 12, 31, 23, 58, 33), d)); 5538 5539 // Test Both 5540 testST(SysTime(DateTime(1, 1, 1, 0, 0, 0)), -1, SysTime(DateTime(1, 1, 1, 0, 59, 0))); 5541 testST(SysTime(DateTime(0, 12, 31, 23, 59, 0)), 1, SysTime(DateTime(0, 12, 31, 23, 0, 0))); 5542 5543 testST(SysTime(DateTime(0, 1, 1, 0, 0, 0)), -1, SysTime(DateTime(0, 1, 1, 0, 59, 0))); 5544 testST(SysTime(DateTime(-1, 12, 31, 23, 59, 0)), 1, SysTime(DateTime(-1, 12, 31, 23, 0, 0))); 5545 5546 testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 1_052_760, SysTime(DateTime(-1, 1, 1, 11, 30, 33), d)); 5547 testST(SysTime(DateTime(1, 1, 1, 13, 30, 33), d), -1_052_760, SysTime(DateTime(1, 1, 1, 13, 30, 33), d)); 5548 5549 testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 1_052_782, SysTime(DateTime(-1, 1, 1, 11, 52, 33), d)); 5550 testST(SysTime(DateTime(1, 1, 1, 13, 52, 33), d), -1_052_782, SysTime(DateTime(1, 1, 1, 13, 30, 33), d)); 5551 5552 { 5553 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 5554 sysTime.roll!"minutes"(-1); 5555 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 59, 0))); 5556 sysTime.roll!"minutes"(1); 5557 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5558 } 5559 5560 { 5561 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 59), hnsecs(9_999_999)); 5562 sysTime.roll!"minutes"(-1); 5563 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 59, 59), hnsecs(9_999_999))); 5564 sysTime.roll!"minutes"(1); 5565 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 59), hnsecs(9_999_999))); 5566 } 5567 5568 { 5569 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 0)); 5570 sysTime.roll!"minutes"(1); 5571 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 0, 0))); 5572 sysTime.roll!"minutes"(-1); 5573 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 0))); 5574 } 5575 5576 { 5577 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5578 sysTime.roll!"minutes"(1); 5579 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 0, 59), hnsecs(9_999_999))); 5580 sysTime.roll!"minutes"(-1); 5581 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5582 } 5583 5584 { 5585 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5586 sysTime.roll!"minutes"(1).roll!"minutes"(-79); 5587 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 41, 59), hnsecs(9_999_999))); 5588 } 5589 5590 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5591 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5592 static assert(!__traits(compiles, cst.roll!"minutes"(4))); 5593 static assert(!__traits(compiles, ist.roll!"minutes"(4))); 5594 5595 static void testScope(scope ref SysTime st) @safe 5596 { 5597 auto result = st.roll!"minutes"(42); 5598 } 5599 } 5600 5601 // Test roll!"seconds"(). 5602 @safe unittest 5603 { 5604 import core.time; 5605 static void testST(SysTime orig, int seconds, SysTime expected, size_t line = __LINE__) @safe 5606 { 5607 orig.roll!"seconds"(seconds); 5608 if (orig != expected) 5609 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 5610 } 5611 5612 // Test A.D. 5613 immutable d = msecs(274); 5614 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), d); 5615 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5616 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 34), d)); 5617 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 35), d)); 5618 testST(beforeAD, 3, SysTime(DateTime(1999, 7, 6, 12, 30, 36), d)); 5619 testST(beforeAD, 4, SysTime(DateTime(1999, 7, 6, 12, 30, 37), d)); 5620 testST(beforeAD, 5, SysTime(DateTime(1999, 7, 6, 12, 30, 38), d)); 5621 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 43), d)); 5622 testST(beforeAD, 15, SysTime(DateTime(1999, 7, 6, 12, 30, 48), d)); 5623 testST(beforeAD, 26, SysTime(DateTime(1999, 7, 6, 12, 30, 59), d)); 5624 testST(beforeAD, 27, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d)); 5625 testST(beforeAD, 30, SysTime(DateTime(1999, 7, 6, 12, 30, 3), d)); 5626 testST(beforeAD, 59, SysTime(DateTime(1999, 7, 6, 12, 30, 32), d)); 5627 testST(beforeAD, 60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5628 testST(beforeAD, 61, SysTime(DateTime(1999, 7, 6, 12, 30, 34), d)); 5629 5630 testST(beforeAD, 1766, SysTime(DateTime(1999, 7, 6, 12, 30, 59), d)); 5631 testST(beforeAD, 1767, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d)); 5632 testST(beforeAD, 1768, SysTime(DateTime(1999, 7, 6, 12, 30, 1), d)); 5633 testST(beforeAD, 2007, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d)); 5634 testST(beforeAD, 3599, SysTime(DateTime(1999, 7, 6, 12, 30, 32), d)); 5635 testST(beforeAD, 3600, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5636 testST(beforeAD, 3601, SysTime(DateTime(1999, 7, 6, 12, 30, 34), d)); 5637 testST(beforeAD, 7200, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5638 5639 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 32), d)); 5640 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 31), d)); 5641 testST(beforeAD, -3, SysTime(DateTime(1999, 7, 6, 12, 30, 30), d)); 5642 testST(beforeAD, -4, SysTime(DateTime(1999, 7, 6, 12, 30, 29), d)); 5643 testST(beforeAD, -5, SysTime(DateTime(1999, 7, 6, 12, 30, 28), d)); 5644 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 23), d)); 5645 testST(beforeAD, -15, SysTime(DateTime(1999, 7, 6, 12, 30, 18), d)); 5646 testST(beforeAD, -33, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d)); 5647 testST(beforeAD, -34, SysTime(DateTime(1999, 7, 6, 12, 30, 59), d)); 5648 testST(beforeAD, -35, SysTime(DateTime(1999, 7, 6, 12, 30, 58), d)); 5649 testST(beforeAD, -59, SysTime(DateTime(1999, 7, 6, 12, 30, 34), d)); 5650 testST(beforeAD, -60, SysTime(DateTime(1999, 7, 6, 12, 30, 33), d)); 5651 testST(beforeAD, -61, SysTime(DateTime(1999, 7, 6, 12, 30, 32), d)); 5652 5653 testST(SysTime(DateTime(1999, 7, 6, 12, 30, 0), d), 1, SysTime(DateTime(1999, 7, 6, 12, 30, 1), d)); 5654 testST(SysTime(DateTime(1999, 7, 6, 12, 30, 0), d), 0, SysTime(DateTime(1999, 7, 6, 12, 30, 0), d)); 5655 testST(SysTime(DateTime(1999, 7, 6, 12, 30, 0), d), -1, SysTime(DateTime(1999, 7, 6, 12, 30, 59), d)); 5656 5657 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 0), d), 1, SysTime(DateTime(1999, 7, 6, 12, 0, 1), d)); 5658 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 0), d), 0, SysTime(DateTime(1999, 7, 6, 12, 0, 0), d)); 5659 testST(SysTime(DateTime(1999, 7, 6, 12, 0, 0), d), -1, SysTime(DateTime(1999, 7, 6, 12, 0, 59), d)); 5660 5661 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 0), d), 1, SysTime(DateTime(1999, 7, 6, 0, 0, 1), d)); 5662 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 0), d), 0, SysTime(DateTime(1999, 7, 6, 0, 0, 0), d)); 5663 testST(SysTime(DateTime(1999, 7, 6, 0, 0, 0), d), -1, SysTime(DateTime(1999, 7, 6, 0, 0, 59), d)); 5664 5665 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 59), d), 1, SysTime(DateTime(1999, 7, 5, 23, 59, 0), d)); 5666 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 59), d), 0, SysTime(DateTime(1999, 7, 5, 23, 59, 59), d)); 5667 testST(SysTime(DateTime(1999, 7, 5, 23, 59, 59), d), -1, SysTime(DateTime(1999, 7, 5, 23, 59, 58), d)); 5668 5669 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 59), d), 1, SysTime(DateTime(1998, 12, 31, 23, 59, 0), d)); 5670 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 59), d), 0, SysTime(DateTime(1998, 12, 31, 23, 59, 59), d)); 5671 testST(SysTime(DateTime(1998, 12, 31, 23, 59, 59), d), -1, SysTime(DateTime(1998, 12, 31, 23, 59, 58), d)); 5672 5673 // Test B.C. 5674 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d); 5675 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5676 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), d)); 5677 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 35), d)); 5678 testST(beforeBC, 3, SysTime(DateTime(-1999, 7, 6, 12, 30, 36), d)); 5679 testST(beforeBC, 4, SysTime(DateTime(-1999, 7, 6, 12, 30, 37), d)); 5680 testST(beforeBC, 5, SysTime(DateTime(-1999, 7, 6, 12, 30, 38), d)); 5681 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 43), d)); 5682 testST(beforeBC, 15, SysTime(DateTime(-1999, 7, 6, 12, 30, 48), d)); 5683 testST(beforeBC, 26, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), d)); 5684 testST(beforeBC, 27, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d)); 5685 testST(beforeBC, 30, SysTime(DateTime(-1999, 7, 6, 12, 30, 3), d)); 5686 testST(beforeBC, 59, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), d)); 5687 testST(beforeBC, 60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5688 testST(beforeBC, 61, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), d)); 5689 5690 testST(beforeBC, 1766, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), d)); 5691 testST(beforeBC, 1767, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d)); 5692 testST(beforeBC, 1768, SysTime(DateTime(-1999, 7, 6, 12, 30, 1), d)); 5693 testST(beforeBC, 2007, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d)); 5694 testST(beforeBC, 3599, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), d)); 5695 testST(beforeBC, 3600, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5696 testST(beforeBC, 3601, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), d)); 5697 testST(beforeBC, 7200, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5698 5699 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), d)); 5700 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 31), d)); 5701 testST(beforeBC, -3, SysTime(DateTime(-1999, 7, 6, 12, 30, 30), d)); 5702 testST(beforeBC, -4, SysTime(DateTime(-1999, 7, 6, 12, 30, 29), d)); 5703 testST(beforeBC, -5, SysTime(DateTime(-1999, 7, 6, 12, 30, 28), d)); 5704 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 23), d)); 5705 testST(beforeBC, -15, SysTime(DateTime(-1999, 7, 6, 12, 30, 18), d)); 5706 testST(beforeBC, -33, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d)); 5707 testST(beforeBC, -34, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), d)); 5708 testST(beforeBC, -35, SysTime(DateTime(-1999, 7, 6, 12, 30, 58), d)); 5709 testST(beforeBC, -59, SysTime(DateTime(-1999, 7, 6, 12, 30, 34), d)); 5710 testST(beforeBC, -60, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), d)); 5711 testST(beforeBC, -61, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), d)); 5712 5713 testST(SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d), 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 1), d)); 5714 testST(SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d), 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d)); 5715 testST(SysTime(DateTime(-1999, 7, 6, 12, 30, 0), d), -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 59), d)); 5716 5717 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 0), d), 1, SysTime(DateTime(-1999, 7, 6, 12, 0, 1), d)); 5718 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 0), d), 0, SysTime(DateTime(-1999, 7, 6, 12, 0, 0), d)); 5719 testST(SysTime(DateTime(-1999, 7, 6, 12, 0, 0), d), -1, SysTime(DateTime(-1999, 7, 6, 12, 0, 59), d)); 5720 5721 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 0), d), 1, SysTime(DateTime(-1999, 7, 6, 0, 0, 1), d)); 5722 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 0), d), 0, SysTime(DateTime(-1999, 7, 6, 0, 0, 0), d)); 5723 testST(SysTime(DateTime(-1999, 7, 6, 0, 0, 0), d), -1, SysTime(DateTime(-1999, 7, 6, 0, 0, 59), d)); 5724 5725 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 59), d), 1, SysTime(DateTime(-1999, 7, 5, 23, 59, 0), d)); 5726 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 59), d), 0, SysTime(DateTime(-1999, 7, 5, 23, 59, 59), d)); 5727 testST(SysTime(DateTime(-1999, 7, 5, 23, 59, 59), d), -1, SysTime(DateTime(-1999, 7, 5, 23, 59, 58), d)); 5728 5729 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 59), d), 1, SysTime(DateTime(-2000, 12, 31, 23, 59, 0), d)); 5730 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 59), d), 0, SysTime(DateTime(-2000, 12, 31, 23, 59, 59), d)); 5731 testST(SysTime(DateTime(-2000, 12, 31, 23, 59, 59), d), -1, SysTime(DateTime(-2000, 12, 31, 23, 59, 58), d)); 5732 5733 // Test Both 5734 testST(SysTime(DateTime(1, 1, 1, 0, 0, 0), d), -1, SysTime(DateTime(1, 1, 1, 0, 0, 59), d)); 5735 testST(SysTime(DateTime(0, 12, 31, 23, 59, 59), d), 1, SysTime(DateTime(0, 12, 31, 23, 59, 0), d)); 5736 5737 testST(SysTime(DateTime(0, 1, 1, 0, 0, 0), d), -1, SysTime(DateTime(0, 1, 1, 0, 0, 59), d)); 5738 testST(SysTime(DateTime(-1, 12, 31, 23, 59, 59), d), 1, SysTime(DateTime(-1, 12, 31, 23, 59, 0), d)); 5739 5740 testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 63_165_600L, SysTime(DateTime(-1, 1, 1, 11, 30, 33), d)); 5741 testST(SysTime(DateTime(1, 1, 1, 13, 30, 33), d), -63_165_600L, SysTime(DateTime(1, 1, 1, 13, 30, 33), d)); 5742 5743 testST(SysTime(DateTime(-1, 1, 1, 11, 30, 33), d), 63_165_617L, SysTime(DateTime(-1, 1, 1, 11, 30, 50), d)); 5744 testST(SysTime(DateTime(1, 1, 1, 13, 30, 50), d), -63_165_617L, SysTime(DateTime(1, 1, 1, 13, 30, 33), d)); 5745 5746 { 5747 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 5748 sysTime.roll!"seconds"(-1); 5749 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 59))); 5750 sysTime.roll!"seconds"(1); 5751 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5752 } 5753 5754 { 5755 auto sysTime = SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(9_999_999)); 5756 sysTime.roll!"seconds"(-1); 5757 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 59), hnsecs(9_999_999))); 5758 sysTime.roll!"seconds"(1); 5759 assert(sysTime == SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 5760 } 5761 5762 { 5763 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59)); 5764 sysTime.roll!"seconds"(1); 5765 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 0))); 5766 sysTime.roll!"seconds"(-1); 5767 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59))); 5768 } 5769 5770 { 5771 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5772 sysTime.roll!"seconds"(1); 5773 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 0), hnsecs(9_999_999))); 5774 sysTime.roll!"seconds"(-1); 5775 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5776 } 5777 5778 { 5779 auto sysTime = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5780 sysTime.roll!"seconds"(1).roll!"seconds"(-102); 5781 assert(sysTime == SysTime(DateTime(0, 12, 31, 23, 59, 18), hnsecs(9_999_999))); 5782 } 5783 5784 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5785 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5786 static assert(!__traits(compiles, cst.roll!"seconds"(4))); 5787 static assert(!__traits(compiles, ist.roll!"seconds"(4))); 5788 5789 static void testScope(scope ref SysTime st) @safe 5790 { 5791 auto result = st.roll!"seconds"(42); 5792 } 5793 } 5794 5795 5796 // Shares documentation with "days" version. 5797 ref SysTime roll(string units)(long value) @safe nothrow scope 5798 if (units == "msecs" || units == "usecs" || units == "hnsecs") 5799 { 5800 auto hnsecs = adjTime; 5801 immutable days = splitUnitsFromHNSecs!"days"(hnsecs); 5802 immutable negative = hnsecs < 0; 5803 5804 if (negative) 5805 hnsecs += convert!("hours", "hnsecs")(24); 5806 5807 immutable seconds = splitUnitsFromHNSecs!"seconds"(hnsecs); 5808 hnsecs += convert!(units, "hnsecs")(value); 5809 hnsecs %= convert!("seconds", "hnsecs")(1); 5810 5811 if (hnsecs < 0) 5812 hnsecs += convert!("seconds", "hnsecs")(1); 5813 hnsecs += convert!("seconds", "hnsecs")(seconds); 5814 5815 if (negative) 5816 hnsecs -= convert!("hours", "hnsecs")(24); 5817 5818 immutable newDaysHNSecs = convert!("days", "hnsecs")(days); 5819 adjTime = newDaysHNSecs + hnsecs; 5820 return this; 5821 } 5822 5823 5824 // Test roll!"msecs"(). 5825 @safe unittest 5826 { 5827 import core.time; 5828 static void testST(SysTime orig, int milliseconds, SysTime expected, size_t line = __LINE__) @safe 5829 { 5830 orig.roll!"msecs"(milliseconds); 5831 if (orig != expected) 5832 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 5833 } 5834 5835 // Test A.D. 5836 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274)); 5837 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274))); 5838 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(275))); 5839 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(276))); 5840 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(284))); 5841 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(374))); 5842 testST(beforeAD, 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999))); 5843 testST(beforeAD, 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5844 testST(beforeAD, 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274))); 5845 testST(beforeAD, 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(275))); 5846 testST(beforeAD, 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274))); 5847 testST(beforeAD, 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999))); 5848 testST(beforeAD, 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5849 testST(beforeAD, 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(1))); 5850 testST(beforeAD, 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999))); 5851 testST(beforeAD, 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5852 5853 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(273))); 5854 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(272))); 5855 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(264))); 5856 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(174))); 5857 testST(beforeAD, -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5858 testST(beforeAD, -275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999))); 5859 testST(beforeAD, -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274))); 5860 testST(beforeAD, -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(273))); 5861 testST(beforeAD, -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(274))); 5862 testST(beforeAD, -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5863 testST(beforeAD, -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999))); 5864 testST(beforeAD, -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5865 testST(beforeAD, -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(999))); 5866 5867 // Test B.C. 5868 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274)); 5869 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274))); 5870 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(275))); 5871 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(276))); 5872 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(284))); 5873 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(374))); 5874 testST(beforeBC, 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999))); 5875 testST(beforeBC, 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 5876 testST(beforeBC, 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274))); 5877 testST(beforeBC, 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(275))); 5878 testST(beforeBC, 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274))); 5879 testST(beforeBC, 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999))); 5880 testST(beforeBC, 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 5881 testST(beforeBC, 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(1))); 5882 testST(beforeBC, 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999))); 5883 testST(beforeBC, 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 5884 5885 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(273))); 5886 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(272))); 5887 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(264))); 5888 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(174))); 5889 testST(beforeBC, -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 5890 testST(beforeBC, -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999))); 5891 testST(beforeBC, -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274))); 5892 testST(beforeBC, -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(273))); 5893 testST(beforeBC, -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(274))); 5894 testST(beforeBC, -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 5895 testST(beforeBC, -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999))); 5896 testST(beforeBC, -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 5897 testST(beforeBC, -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), msecs(999))); 5898 5899 // Test Both 5900 auto beforeBoth1 = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 5901 testST(beforeBoth1, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), msecs(1))); 5902 testST(beforeBoth1, 0, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5903 testST(beforeBoth1, -1, SysTime(DateTime(1, 1, 1, 0, 0, 0), msecs(999))); 5904 testST(beforeBoth1, -2, SysTime(DateTime(1, 1, 1, 0, 0, 0), msecs(998))); 5905 testST(beforeBoth1, -1000, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5906 testST(beforeBoth1, -2000, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 5907 testST(beforeBoth1, -2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), msecs(445))); 5908 5909 auto beforeBoth2 = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5910 testST(beforeBoth2, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_989_999))); 5911 testST(beforeBoth2, 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5912 testST(beforeBoth2, 1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9999))); 5913 testST(beforeBoth2, 2, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(19_999))); 5914 testST(beforeBoth2, 1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5915 testST(beforeBoth2, 2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 5916 testST(beforeBoth2, 2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(5_549_999))); 5917 5918 { 5919 auto st = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 5920 st.roll!"msecs"(1202).roll!"msecs"(-703); 5921 assert(st == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(4_989_999))); 5922 } 5923 5924 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5925 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 5926 static assert(!__traits(compiles, cst.roll!"msecs"(4))); 5927 static assert(!__traits(compiles, ist.roll!"msecs"(4))); 5928 5929 static void testScope(scope ref SysTime st) @safe 5930 { 5931 auto result = st.roll!"msecs"(42); 5932 } 5933 } 5934 5935 // Test roll!"usecs"(). 5936 @safe unittest 5937 { 5938 import core.time; 5939 static void testST(SysTime orig, long microseconds, SysTime expected, size_t line = __LINE__) @safe 5940 { 5941 orig.roll!"usecs"(microseconds); 5942 if (orig != expected) 5943 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 5944 } 5945 5946 // Test A.D. 5947 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274)); 5948 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 5949 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(275))); 5950 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(276))); 5951 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(284))); 5952 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(374))); 5953 testST(beforeAD, 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(999))); 5954 testST(beforeAD, 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(1000))); 5955 testST(beforeAD, 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(1274))); 5956 testST(beforeAD, 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(1275))); 5957 testST(beforeAD, 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(2274))); 5958 testST(beforeAD, 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(26_999))); 5959 testST(beforeAD, 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(27_000))); 5960 testST(beforeAD, 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(27_001))); 5961 testST(beforeAD, 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(766_999))); 5962 testST(beforeAD, 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(767_000))); 5963 testST(beforeAD, 1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 5964 testST(beforeAD, 60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 5965 testST(beforeAD, 3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 5966 5967 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(273))); 5968 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(272))); 5969 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(264))); 5970 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(174))); 5971 testST(beforeAD, -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 5972 testST(beforeAD, -275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(999_999))); 5973 testST(beforeAD, -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(999_274))); 5974 testST(beforeAD, -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(999_273))); 5975 testST(beforeAD, -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(998_274))); 5976 testST(beforeAD, -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(967_000))); 5977 testST(beforeAD, -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(966_999))); 5978 testST(beforeAD, -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(167_000))); 5979 testST(beforeAD, -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(166_999))); 5980 testST(beforeAD, -1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 5981 testST(beforeAD, -60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 5982 testST(beforeAD, -3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(274))); 5983 5984 // Test B.C. 5985 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274)); 5986 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 5987 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(275))); 5988 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(276))); 5989 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(284))); 5990 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(374))); 5991 testST(beforeBC, 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(999))); 5992 testST(beforeBC, 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(1000))); 5993 testST(beforeBC, 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(1274))); 5994 testST(beforeBC, 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(1275))); 5995 testST(beforeBC, 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(2274))); 5996 testST(beforeBC, 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(26_999))); 5997 testST(beforeBC, 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(27_000))); 5998 testST(beforeBC, 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(27_001))); 5999 testST(beforeBC, 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(766_999))); 6000 testST(beforeBC, 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(767_000))); 6001 testST(beforeBC, 1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 6002 testST(beforeBC, 60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 6003 testST(beforeBC, 3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 6004 6005 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(273))); 6006 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(272))); 6007 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(264))); 6008 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(174))); 6009 testST(beforeBC, -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 6010 testST(beforeBC, -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(999_999))); 6011 testST(beforeBC, -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(999_274))); 6012 testST(beforeBC, -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(999_273))); 6013 testST(beforeBC, -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(998_274))); 6014 testST(beforeBC, -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(967_000))); 6015 testST(beforeBC, -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(966_999))); 6016 testST(beforeBC, -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(167_000))); 6017 testST(beforeBC, -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(166_999))); 6018 testST(beforeBC, -1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 6019 testST(beforeBC, -60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 6020 testST(beforeBC, -3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), usecs(274))); 6021 6022 // Test Both 6023 auto beforeBoth1 = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 6024 testST(beforeBoth1, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(1))); 6025 testST(beforeBoth1, 0, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6026 testST(beforeBoth1, -1, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(999_999))); 6027 testST(beforeBoth1, -2, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(999_998))); 6028 testST(beforeBoth1, -1000, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(999_000))); 6029 testST(beforeBoth1, -2000, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(998_000))); 6030 testST(beforeBoth1, -2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(997_445))); 6031 testST(beforeBoth1, -1_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6032 testST(beforeBoth1, -2_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6033 testST(beforeBoth1, -2_333_333, SysTime(DateTime(1, 1, 1, 0, 0, 0), usecs(666_667))); 6034 6035 auto beforeBoth2 = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 6036 testST(beforeBoth2, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_989))); 6037 testST(beforeBoth2, 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6038 testST(beforeBoth2, 1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9))); 6039 testST(beforeBoth2, 2, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(19))); 6040 testST(beforeBoth2, 1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9999))); 6041 testST(beforeBoth2, 2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(19_999))); 6042 testST(beforeBoth2, 2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(25_549))); 6043 testST(beforeBoth2, 1_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6044 testST(beforeBoth2, 2_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6045 testST(beforeBoth2, 2_333_333, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(3_333_329))); 6046 6047 { 6048 auto st = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 6049 st.roll!"usecs"(9_020_027); 6050 assert(st == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(200_269))); 6051 } 6052 6053 { 6054 auto st = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 6055 st.roll!"usecs"(9_020_027).roll!"usecs"(-70_034); 6056 assert(st == SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_499_929))); 6057 } 6058 6059 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6060 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6061 static assert(!__traits(compiles, cst.roll!"usecs"(4))); 6062 static assert(!__traits(compiles, ist.roll!"usecs"(4))); 6063 6064 static void testScope(scope ref SysTime st) @safe 6065 { 6066 auto result = st.roll!"usecs"(42); 6067 } 6068 } 6069 6070 // Test roll!"hnsecs"(). 6071 @safe unittest 6072 { 6073 import core.time; 6074 static void testST(SysTime orig, long hnsecs, SysTime expected, size_t line = __LINE__) @safe 6075 { 6076 orig.roll!"hnsecs"(hnsecs); 6077 if (orig != expected) 6078 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 6079 } 6080 6081 // Test A.D. 6082 auto dtAD = DateTime(1999, 7, 6, 12, 30, 33); 6083 auto beforeAD = SysTime(dtAD, hnsecs(274)); 6084 testST(beforeAD, 0, SysTime(dtAD, hnsecs(274))); 6085 testST(beforeAD, 1, SysTime(dtAD, hnsecs(275))); 6086 testST(beforeAD, 2, SysTime(dtAD, hnsecs(276))); 6087 testST(beforeAD, 10, SysTime(dtAD, hnsecs(284))); 6088 testST(beforeAD, 100, SysTime(dtAD, hnsecs(374))); 6089 testST(beforeAD, 725, SysTime(dtAD, hnsecs(999))); 6090 testST(beforeAD, 726, SysTime(dtAD, hnsecs(1000))); 6091 testST(beforeAD, 1000, SysTime(dtAD, hnsecs(1274))); 6092 testST(beforeAD, 1001, SysTime(dtAD, hnsecs(1275))); 6093 testST(beforeAD, 2000, SysTime(dtAD, hnsecs(2274))); 6094 testST(beforeAD, 26_725, SysTime(dtAD, hnsecs(26_999))); 6095 testST(beforeAD, 26_726, SysTime(dtAD, hnsecs(27_000))); 6096 testST(beforeAD, 26_727, SysTime(dtAD, hnsecs(27_001))); 6097 testST(beforeAD, 1_766_725, SysTime(dtAD, hnsecs(1_766_999))); 6098 testST(beforeAD, 1_766_726, SysTime(dtAD, hnsecs(1_767_000))); 6099 testST(beforeAD, 1_000_000, SysTime(dtAD, hnsecs(1_000_274))); 6100 testST(beforeAD, 60_000_000L, SysTime(dtAD, hnsecs(274))); 6101 testST(beforeAD, 3_600_000_000L, SysTime(dtAD, hnsecs(274))); 6102 testST(beforeAD, 600_000_000L, SysTime(dtAD, hnsecs(274))); 6103 testST(beforeAD, 36_000_000_000L, SysTime(dtAD, hnsecs(274))); 6104 6105 testST(beforeAD, -1, SysTime(dtAD, hnsecs(273))); 6106 testST(beforeAD, -2, SysTime(dtAD, hnsecs(272))); 6107 testST(beforeAD, -10, SysTime(dtAD, hnsecs(264))); 6108 testST(beforeAD, -100, SysTime(dtAD, hnsecs(174))); 6109 testST(beforeAD, -274, SysTime(dtAD)); 6110 testST(beforeAD, -275, SysTime(dtAD, hnsecs(9_999_999))); 6111 testST(beforeAD, -1000, SysTime(dtAD, hnsecs(9_999_274))); 6112 testST(beforeAD, -1001, SysTime(dtAD, hnsecs(9_999_273))); 6113 testST(beforeAD, -2000, SysTime(dtAD, hnsecs(9_998_274))); 6114 testST(beforeAD, -33_274, SysTime(dtAD, hnsecs(9_967_000))); 6115 testST(beforeAD, -33_275, SysTime(dtAD, hnsecs(9_966_999))); 6116 testST(beforeAD, -1_833_274, SysTime(dtAD, hnsecs(8_167_000))); 6117 testST(beforeAD, -1_833_275, SysTime(dtAD, hnsecs(8_166_999))); 6118 testST(beforeAD, -1_000_000, SysTime(dtAD, hnsecs(9_000_274))); 6119 testST(beforeAD, -60_000_000L, SysTime(dtAD, hnsecs(274))); 6120 testST(beforeAD, -3_600_000_000L, SysTime(dtAD, hnsecs(274))); 6121 testST(beforeAD, -600_000_000L, SysTime(dtAD, hnsecs(274))); 6122 testST(beforeAD, -36_000_000_000L, SysTime(dtAD, hnsecs(274))); 6123 6124 // Test B.C. 6125 auto dtBC = DateTime(-1999, 7, 6, 12, 30, 33); 6126 auto beforeBC = SysTime(dtBC, hnsecs(274)); 6127 testST(beforeBC, 0, SysTime(dtBC, hnsecs(274))); 6128 testST(beforeBC, 1, SysTime(dtBC, hnsecs(275))); 6129 testST(beforeBC, 2, SysTime(dtBC, hnsecs(276))); 6130 testST(beforeBC, 10, SysTime(dtBC, hnsecs(284))); 6131 testST(beforeBC, 100, SysTime(dtBC, hnsecs(374))); 6132 testST(beforeBC, 725, SysTime(dtBC, hnsecs(999))); 6133 testST(beforeBC, 726, SysTime(dtBC, hnsecs(1000))); 6134 testST(beforeBC, 1000, SysTime(dtBC, hnsecs(1274))); 6135 testST(beforeBC, 1001, SysTime(dtBC, hnsecs(1275))); 6136 testST(beforeBC, 2000, SysTime(dtBC, hnsecs(2274))); 6137 testST(beforeBC, 26_725, SysTime(dtBC, hnsecs(26_999))); 6138 testST(beforeBC, 26_726, SysTime(dtBC, hnsecs(27_000))); 6139 testST(beforeBC, 26_727, SysTime(dtBC, hnsecs(27_001))); 6140 testST(beforeBC, 1_766_725, SysTime(dtBC, hnsecs(1_766_999))); 6141 testST(beforeBC, 1_766_726, SysTime(dtBC, hnsecs(1_767_000))); 6142 testST(beforeBC, 1_000_000, SysTime(dtBC, hnsecs(1_000_274))); 6143 testST(beforeBC, 60_000_000L, SysTime(dtBC, hnsecs(274))); 6144 testST(beforeBC, 3_600_000_000L, SysTime(dtBC, hnsecs(274))); 6145 testST(beforeBC, 600_000_000L, SysTime(dtBC, hnsecs(274))); 6146 testST(beforeBC, 36_000_000_000L, SysTime(dtBC, hnsecs(274))); 6147 6148 testST(beforeBC, -1, SysTime(dtBC, hnsecs(273))); 6149 testST(beforeBC, -2, SysTime(dtBC, hnsecs(272))); 6150 testST(beforeBC, -10, SysTime(dtBC, hnsecs(264))); 6151 testST(beforeBC, -100, SysTime(dtBC, hnsecs(174))); 6152 testST(beforeBC, -274, SysTime(dtBC)); 6153 testST(beforeBC, -275, SysTime(dtBC, hnsecs(9_999_999))); 6154 testST(beforeBC, -1000, SysTime(dtBC, hnsecs(9_999_274))); 6155 testST(beforeBC, -1001, SysTime(dtBC, hnsecs(9_999_273))); 6156 testST(beforeBC, -2000, SysTime(dtBC, hnsecs(9_998_274))); 6157 testST(beforeBC, -33_274, SysTime(dtBC, hnsecs(9_967_000))); 6158 testST(beforeBC, -33_275, SysTime(dtBC, hnsecs(9_966_999))); 6159 testST(beforeBC, -1_833_274, SysTime(dtBC, hnsecs(8_167_000))); 6160 testST(beforeBC, -1_833_275, SysTime(dtBC, hnsecs(8_166_999))); 6161 testST(beforeBC, -1_000_000, SysTime(dtBC, hnsecs(9_000_274))); 6162 testST(beforeBC, -60_000_000L, SysTime(dtBC, hnsecs(274))); 6163 testST(beforeBC, -3_600_000_000L, SysTime(dtBC, hnsecs(274))); 6164 testST(beforeBC, -600_000_000L, SysTime(dtBC, hnsecs(274))); 6165 testST(beforeBC, -36_000_000_000L, SysTime(dtBC, hnsecs(274))); 6166 6167 // Test Both 6168 auto dtBoth1 = DateTime(1, 1, 1, 0, 0, 0); 6169 auto beforeBoth1 = SysTime(dtBoth1); 6170 testST(beforeBoth1, 1, SysTime(dtBoth1, hnsecs(1))); 6171 testST(beforeBoth1, 0, SysTime(dtBoth1)); 6172 testST(beforeBoth1, -1, SysTime(dtBoth1, hnsecs(9_999_999))); 6173 testST(beforeBoth1, -2, SysTime(dtBoth1, hnsecs(9_999_998))); 6174 testST(beforeBoth1, -1000, SysTime(dtBoth1, hnsecs(9_999_000))); 6175 testST(beforeBoth1, -2000, SysTime(dtBoth1, hnsecs(9_998_000))); 6176 testST(beforeBoth1, -2555, SysTime(dtBoth1, hnsecs(9_997_445))); 6177 testST(beforeBoth1, -1_000_000, SysTime(dtBoth1, hnsecs(9_000_000))); 6178 testST(beforeBoth1, -2_000_000, SysTime(dtBoth1, hnsecs(8_000_000))); 6179 testST(beforeBoth1, -2_333_333, SysTime(dtBoth1, hnsecs(7_666_667))); 6180 testST(beforeBoth1, -10_000_000, SysTime(dtBoth1)); 6181 testST(beforeBoth1, -20_000_000, SysTime(dtBoth1)); 6182 testST(beforeBoth1, -20_888_888, SysTime(dtBoth1, hnsecs(9_111_112))); 6183 6184 auto dtBoth2 = DateTime(0, 12, 31, 23, 59, 59); 6185 auto beforeBoth2 = SysTime(dtBoth2, hnsecs(9_999_999)); 6186 testST(beforeBoth2, -1, SysTime(dtBoth2, hnsecs(9_999_998))); 6187 testST(beforeBoth2, 0, SysTime(dtBoth2, hnsecs(9_999_999))); 6188 testST(beforeBoth2, 1, SysTime(dtBoth2)); 6189 testST(beforeBoth2, 2, SysTime(dtBoth2, hnsecs(1))); 6190 testST(beforeBoth2, 1000, SysTime(dtBoth2, hnsecs(999))); 6191 testST(beforeBoth2, 2000, SysTime(dtBoth2, hnsecs(1999))); 6192 testST(beforeBoth2, 2555, SysTime(dtBoth2, hnsecs(2554))); 6193 testST(beforeBoth2, 1_000_000, SysTime(dtBoth2, hnsecs(999_999))); 6194 testST(beforeBoth2, 2_000_000, SysTime(dtBoth2, hnsecs(1_999_999))); 6195 testST(beforeBoth2, 2_333_333, SysTime(dtBoth2, hnsecs(2_333_332))); 6196 testST(beforeBoth2, 10_000_000, SysTime(dtBoth2, hnsecs(9_999_999))); 6197 testST(beforeBoth2, 20_000_000, SysTime(dtBoth2, hnsecs(9_999_999))); 6198 testST(beforeBoth2, 20_888_888, SysTime(dtBoth2, hnsecs(888_887))); 6199 6200 { 6201 auto st = SysTime(dtBoth2, hnsecs(9_999_999)); 6202 st.roll!"hnsecs"(70_777_222).roll!"hnsecs"(-222_555_292); 6203 assert(st == SysTime(dtBoth2, hnsecs(8_221_929))); 6204 } 6205 6206 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6207 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6208 static assert(!__traits(compiles, cst.roll!"hnsecs"(4))); 6209 static assert(!__traits(compiles, ist.roll!"hnsecs"(4))); 6210 6211 static void testScope(scope ref SysTime st) @safe 6212 { 6213 auto result = st.roll!"hnsecs"(42); 6214 } 6215 } 6216 6217 6218 /++ 6219 Gives the result of adding or subtracting a $(REF Duration, core,time) 6220 from this $(LREF SysTime). 6221 6222 The legal types of arithmetic for $(LREF SysTime) using this operator 6223 are 6224 6225 $(BOOKTABLE, 6226 $(TR $(TD SysTime) $(TD +) $(TD Duration) $(TD -->) $(TD SysTime)) 6227 $(TR $(TD SysTime) $(TD -) $(TD Duration) $(TD -->) $(TD SysTime)) 6228 ) 6229 6230 Params: 6231 duration = The $(REF Duration, core,time) to add to or subtract from 6232 this $(LREF SysTime). 6233 +/ 6234 SysTime opBinary(string op)(Duration duration) @safe const pure nothrow scope 6235 if (op == "+" || op == "-") 6236 { 6237 SysTime retval = SysTime(this._stdTime, this._timezone); 6238 immutable hnsecs = duration.total!"hnsecs"; 6239 mixin("retval._stdTime " ~ op ~ "= hnsecs;"); 6240 return retval; 6241 } 6242 6243 /// 6244 @safe unittest 6245 { 6246 import core.time : hours, seconds; 6247 import std.datetime.date : DateTime; 6248 6249 assert(SysTime(DateTime(2015, 12, 31, 23, 59, 59)) + seconds(1) == 6250 SysTime(DateTime(2016, 1, 1, 0, 0, 0))); 6251 6252 assert(SysTime(DateTime(2015, 12, 31, 23, 59, 59)) + hours(1) == 6253 SysTime(DateTime(2016, 1, 1, 0, 59, 59))); 6254 6255 assert(SysTime(DateTime(2016, 1, 1, 0, 0, 0)) - seconds(1) == 6256 SysTime(DateTime(2015, 12, 31, 23, 59, 59))); 6257 6258 assert(SysTime(DateTime(2016, 1, 1, 0, 59, 59)) - hours(1) == 6259 SysTime(DateTime(2015, 12, 31, 23, 59, 59))); 6260 } 6261 6262 @safe unittest 6263 { 6264 import core.time; 6265 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_678)); 6266 6267 assert(st + dur!"weeks"(7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33), hnsecs(2_345_678))); 6268 assert(st + dur!"weeks"(-7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33), hnsecs(2_345_678))); 6269 assert(st + dur!"days"(7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33), hnsecs(2_345_678))); 6270 assert(st + dur!"days"(-7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33), hnsecs(2_345_678))); 6271 assert(st + dur!"hours"(7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33), hnsecs(2_345_678))); 6272 assert(st + dur!"hours"(-7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33), hnsecs(2_345_678))); 6273 assert(st + dur!"minutes"(7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33), hnsecs(2_345_678))); 6274 assert(st + dur!"minutes"(-7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33), hnsecs(2_345_678))); 6275 assert(st + dur!"seconds"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40), hnsecs(2_345_678))); 6276 assert(st + dur!"seconds"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26), hnsecs(2_345_678))); 6277 assert(st + dur!"msecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_415_678))); 6278 assert(st + dur!"msecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_275_678))); 6279 assert(st + dur!"usecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_748))); 6280 assert(st + dur!"usecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_608))); 6281 assert(st + dur!"hnsecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_685))); 6282 assert(st + dur!"hnsecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_671))); 6283 6284 assert(st - dur!"weeks"(-7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33), hnsecs(2_345_678))); 6285 assert(st - dur!"weeks"(7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33), hnsecs(2_345_678))); 6286 assert(st - dur!"days"(-7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33), hnsecs(2_345_678))); 6287 assert(st - dur!"days"(7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33), hnsecs(2_345_678))); 6288 assert(st - dur!"hours"(-7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33), hnsecs(2_345_678))); 6289 assert(st - dur!"hours"(7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33), hnsecs(2_345_678))); 6290 assert(st - dur!"minutes"(-7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33), hnsecs(2_345_678))); 6291 assert(st - dur!"minutes"(7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33), hnsecs(2_345_678))); 6292 assert(st - dur!"seconds"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40), hnsecs(2_345_678))); 6293 assert(st - dur!"seconds"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26), hnsecs(2_345_678))); 6294 assert(st - dur!"msecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_415_678))); 6295 assert(st - dur!"msecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_275_678))); 6296 assert(st - dur!"usecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_748))); 6297 assert(st - dur!"usecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_608))); 6298 assert(st - dur!"hnsecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_685))); 6299 assert(st - dur!"hnsecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2_345_671))); 6300 6301 static void testST(SysTime orig, long hnsecs, SysTime expected, size_t line = __LINE__) @safe 6302 { 6303 auto result = orig + dur!"hnsecs"(hnsecs); 6304 if (result != expected) 6305 throw new AssertError(format("Failed. actual [%s] != expected [%s]", result, expected), __FILE__, line); 6306 } 6307 6308 // Test A.D. 6309 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274)); 6310 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274))); 6311 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(275))); 6312 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(276))); 6313 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(284))); 6314 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(374))); 6315 testST(beforeAD, 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(999))); 6316 testST(beforeAD, 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1000))); 6317 testST(beforeAD, 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1274))); 6318 testST(beforeAD, 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1275))); 6319 testST(beforeAD, 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2274))); 6320 testST(beforeAD, 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(26_999))); 6321 testST(beforeAD, 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_000))); 6322 testST(beforeAD, 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_001))); 6323 testST(beforeAD, 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_766_999))); 6324 testST(beforeAD, 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_767_000))); 6325 testST(beforeAD, 1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_000_274))); 6326 testST(beforeAD, 60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 39), hnsecs(274))); 6327 testST(beforeAD, 3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 36, 33), hnsecs(274))); 6328 testST(beforeAD, 600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 31, 33), hnsecs(274))); 6329 testST(beforeAD, 36_000_000_000L, SysTime(DateTime(1999, 7, 6, 13, 30, 33), hnsecs(274))); 6330 6331 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(273))); 6332 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(272))); 6333 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(264))); 6334 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(174))); 6335 testST(beforeAD, -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 6336 testST(beforeAD, -275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_999))); 6337 testST(beforeAD, -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_274))); 6338 testST(beforeAD, -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_273))); 6339 testST(beforeAD, -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_998_274))); 6340 testST(beforeAD, -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_967_000))); 6341 testST(beforeAD, -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_966_999))); 6342 testST(beforeAD, -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_167_000))); 6343 testST(beforeAD, -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_166_999))); 6344 testST(beforeAD, -1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_000_274))); 6345 testST(beforeAD, -60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 27), hnsecs(274))); 6346 testST(beforeAD, -3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 24, 33), hnsecs(274))); 6347 testST(beforeAD, -600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 29, 33), hnsecs(274))); 6348 testST(beforeAD, -36_000_000_000L, SysTime(DateTime(1999, 7, 6, 11, 30, 33), hnsecs(274))); 6349 6350 // Test B.C. 6351 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274)); 6352 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274))); 6353 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(275))); 6354 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(276))); 6355 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(284))); 6356 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(374))); 6357 testST(beforeBC, 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(999))); 6358 testST(beforeBC, 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1000))); 6359 testST(beforeBC, 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1274))); 6360 testST(beforeBC, 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1275))); 6361 testST(beforeBC, 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(2274))); 6362 testST(beforeBC, 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(26_999))); 6363 testST(beforeBC, 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_000))); 6364 testST(beforeBC, 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_001))); 6365 testST(beforeBC, 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_766_999))); 6366 testST(beforeBC, 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_767_000))); 6367 testST(beforeBC, 1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_000_274))); 6368 testST(beforeBC, 60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 39), hnsecs(274))); 6369 testST(beforeBC, 3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 36, 33), hnsecs(274))); 6370 testST(beforeBC, 600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), hnsecs(274))); 6371 testST(beforeBC, 36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), hnsecs(274))); 6372 6373 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(273))); 6374 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(272))); 6375 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(264))); 6376 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(174))); 6377 testST(beforeBC, -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 6378 testST(beforeBC, -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_999))); 6379 testST(beforeBC, -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_274))); 6380 testST(beforeBC, -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_273))); 6381 testST(beforeBC, -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_998_274))); 6382 testST(beforeBC, -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_967_000))); 6383 testST(beforeBC, -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_966_999))); 6384 testST(beforeBC, -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_167_000))); 6385 testST(beforeBC, -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_166_999))); 6386 testST(beforeBC, -1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_000_274))); 6387 testST(beforeBC, -60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 27), hnsecs(274))); 6388 testST(beforeBC, -3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 24, 33), hnsecs(274))); 6389 testST(beforeBC, -600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), hnsecs(274))); 6390 testST(beforeBC, -36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), hnsecs(274))); 6391 6392 // Test Both 6393 auto beforeBoth1 = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 6394 testST(beforeBoth1, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 6395 testST(beforeBoth1, 0, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6396 testST(beforeBoth1, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6397 testST(beforeBoth1, -2, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998))); 6398 testST(beforeBoth1, -1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_000))); 6399 testST(beforeBoth1, -2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_998_000))); 6400 testST(beforeBoth1, -2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_997_445))); 6401 testST(beforeBoth1, -1_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_000_000))); 6402 testST(beforeBoth1, -2_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(8_000_000))); 6403 testST(beforeBoth1, -2_333_333, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(7_666_667))); 6404 testST(beforeBoth1, -10_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59))); 6405 testST(beforeBoth1, -20_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 58))); 6406 testST(beforeBoth1, -20_888_888, SysTime(DateTime(0, 12, 31, 23, 59, 57), hnsecs(9_111_112))); 6407 6408 auto beforeBoth2 = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 6409 testST(beforeBoth2, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998))); 6410 testST(beforeBoth2, 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6411 testST(beforeBoth2, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6412 testST(beforeBoth2, 2, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 6413 testST(beforeBoth2, 1000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999))); 6414 testST(beforeBoth2, 2000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1999))); 6415 testST(beforeBoth2, 2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2554))); 6416 testST(beforeBoth2, 1_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999_999))); 6417 testST(beforeBoth2, 2_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1_999_999))); 6418 testST(beforeBoth2, 2_333_333, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2_333_332))); 6419 testST(beforeBoth2, 10_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 6420 testST(beforeBoth2, 20_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 1), hnsecs(9_999_999))); 6421 testST(beforeBoth2, 20_888_888, SysTime(DateTime(1, 1, 1, 0, 0, 2), hnsecs(888_887))); 6422 6423 auto duration = dur!"seconds"(12); 6424 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6425 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6426 assert(cst + duration == SysTime(DateTime(1999, 7, 6, 12, 30, 45))); 6427 assert(ist + duration == SysTime(DateTime(1999, 7, 6, 12, 30, 45))); 6428 assert(cst - duration == SysTime(DateTime(1999, 7, 6, 12, 30, 21))); 6429 assert(ist - duration == SysTime(DateTime(1999, 7, 6, 12, 30, 21))); 6430 6431 static void testScope(scope ref SysTime st, scope ref Duration d) @safe 6432 { 6433 auto result = st + d; 6434 } 6435 } 6436 6437 6438 /++ 6439 Gives the result of adding or subtracting a $(REF Duration, core,time) from 6440 this $(LREF SysTime), as well as assigning the result to this 6441 $(LREF SysTime). 6442 6443 The legal types of arithmetic for $(LREF SysTime) using this operator are 6444 6445 $(BOOKTABLE, 6446 $(TR $(TD SysTime) $(TD +) $(TD Duration) $(TD -->) $(TD SysTime)) 6447 $(TR $(TD SysTime) $(TD -) $(TD Duration) $(TD -->) $(TD SysTime)) 6448 ) 6449 6450 Params: 6451 duration = The $(REF Duration, core,time) to add to or subtract from 6452 this $(LREF SysTime). 6453 +/ 6454 ref SysTime opOpAssign(string op)(Duration duration) @safe pure nothrow scope 6455 if (op == "+" || op == "-") 6456 { 6457 immutable hnsecs = duration.total!"hnsecs"; 6458 mixin("_stdTime " ~ op ~ "= hnsecs;"); 6459 return this; 6460 } 6461 6462 @safe unittest 6463 { 6464 import core.time; 6465 auto before = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6466 assert(before + dur!"weeks"(7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33))); 6467 assert(before + dur!"weeks"(-7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33))); 6468 assert(before + dur!"days"(7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33))); 6469 assert(before + dur!"days"(-7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33))); 6470 6471 assert(before + dur!"hours"(7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33))); 6472 assert(before + dur!"hours"(-7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33))); 6473 assert(before + dur!"minutes"(7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33))); 6474 assert(before + dur!"minutes"(-7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33))); 6475 assert(before + dur!"seconds"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40))); 6476 assert(before + dur!"seconds"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26))); 6477 assert(before + dur!"msecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(7))); 6478 assert(before + dur!"msecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), msecs(993))); 6479 assert(before + dur!"usecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(7))); 6480 assert(before + dur!"usecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), usecs(999_993))); 6481 assert(before + dur!"hnsecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(7))); 6482 assert(before + dur!"hnsecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_993))); 6483 6484 assert(before - dur!"weeks"(-7) == SysTime(DateTime(1999, 8, 24, 12, 30, 33))); 6485 assert(before - dur!"weeks"(7) == SysTime(DateTime(1999, 5, 18, 12, 30, 33))); 6486 assert(before - dur!"days"(-7) == SysTime(DateTime(1999, 7, 13, 12, 30, 33))); 6487 assert(before - dur!"days"(7) == SysTime(DateTime(1999, 6, 29, 12, 30, 33))); 6488 6489 assert(before - dur!"hours"(-7) == SysTime(DateTime(1999, 7, 6, 19, 30, 33))); 6490 assert(before - dur!"hours"(7) == SysTime(DateTime(1999, 7, 6, 5, 30, 33))); 6491 assert(before - dur!"minutes"(-7) == SysTime(DateTime(1999, 7, 6, 12, 37, 33))); 6492 assert(before - dur!"minutes"(7) == SysTime(DateTime(1999, 7, 6, 12, 23, 33))); 6493 assert(before - dur!"seconds"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 40))); 6494 assert(before - dur!"seconds"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 26))); 6495 assert(before - dur!"msecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), msecs(7))); 6496 assert(before - dur!"msecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), msecs(993))); 6497 assert(before - dur!"usecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), usecs(7))); 6498 assert(before - dur!"usecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), usecs(999_993))); 6499 assert(before - dur!"hnsecs"(-7) == SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(7))); 6500 assert(before - dur!"hnsecs"(7) == SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_993))); 6501 6502 static void testST(SysTime orig, long hnsecs, SysTime expected, size_t line = __LINE__) @safe 6503 { 6504 auto r = orig += dur!"hnsecs"(hnsecs); 6505 if (orig != expected) 6506 throw new AssertError(format("Failed 1. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 6507 if (r != expected) 6508 throw new AssertError(format("Failed 2. actual [%s] != expected [%s]", r, expected), __FILE__, line); 6509 } 6510 6511 // Test A.D. 6512 auto beforeAD = SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274)); 6513 testST(beforeAD, 0, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(274))); 6514 testST(beforeAD, 1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(275))); 6515 testST(beforeAD, 2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(276))); 6516 testST(beforeAD, 10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(284))); 6517 testST(beforeAD, 100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(374))); 6518 testST(beforeAD, 725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(999))); 6519 testST(beforeAD, 726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1000))); 6520 testST(beforeAD, 1000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1274))); 6521 testST(beforeAD, 1001, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1275))); 6522 testST(beforeAD, 2000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(2274))); 6523 testST(beforeAD, 26_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(26_999))); 6524 testST(beforeAD, 26_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_000))); 6525 testST(beforeAD, 26_727, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(27_001))); 6526 testST(beforeAD, 1_766_725, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_766_999))); 6527 testST(beforeAD, 1_766_726, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_767_000))); 6528 testST(beforeAD, 1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(1_000_274))); 6529 testST(beforeAD, 60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 39), hnsecs(274))); 6530 testST(beforeAD, 3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 36, 33), hnsecs(274))); 6531 testST(beforeAD, 600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 31, 33), hnsecs(274))); 6532 testST(beforeAD, 36_000_000_000L, SysTime(DateTime(1999, 7, 6, 13, 30, 33), hnsecs(274))); 6533 6534 testST(beforeAD, -1, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(273))); 6535 testST(beforeAD, -2, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(272))); 6536 testST(beforeAD, -10, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(264))); 6537 testST(beforeAD, -100, SysTime(DateTime(1999, 7, 6, 12, 30, 33), hnsecs(174))); 6538 testST(beforeAD, -274, SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 6539 testST(beforeAD, -275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_999))); 6540 testST(beforeAD, -1000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_274))); 6541 testST(beforeAD, -1001, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_999_273))); 6542 testST(beforeAD, -2000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_998_274))); 6543 testST(beforeAD, -33_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_967_000))); 6544 testST(beforeAD, -33_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_966_999))); 6545 testST(beforeAD, -1_833_274, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_167_000))); 6546 testST(beforeAD, -1_833_275, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(8_166_999))); 6547 testST(beforeAD, -1_000_000, SysTime(DateTime(1999, 7, 6, 12, 30, 32), hnsecs(9_000_274))); 6548 testST(beforeAD, -60_000_000L, SysTime(DateTime(1999, 7, 6, 12, 30, 27), hnsecs(274))); 6549 testST(beforeAD, -3_600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 24, 33), hnsecs(274))); 6550 testST(beforeAD, -600_000_000L, SysTime(DateTime(1999, 7, 6, 12, 29, 33), hnsecs(274))); 6551 testST(beforeAD, -36_000_000_000L, SysTime(DateTime(1999, 7, 6, 11, 30, 33), hnsecs(274))); 6552 6553 // Test B.C. 6554 auto beforeBC = SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274)); 6555 testST(beforeBC, 0, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(274))); 6556 testST(beforeBC, 1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(275))); 6557 testST(beforeBC, 2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(276))); 6558 testST(beforeBC, 10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(284))); 6559 testST(beforeBC, 100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(374))); 6560 testST(beforeBC, 725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(999))); 6561 testST(beforeBC, 726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1000))); 6562 testST(beforeBC, 1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1274))); 6563 testST(beforeBC, 1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1275))); 6564 testST(beforeBC, 2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(2274))); 6565 testST(beforeBC, 26_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(26_999))); 6566 testST(beforeBC, 26_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_000))); 6567 testST(beforeBC, 26_727, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(27_001))); 6568 testST(beforeBC, 1_766_725, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_766_999))); 6569 testST(beforeBC, 1_766_726, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_767_000))); 6570 testST(beforeBC, 1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(1_000_274))); 6571 testST(beforeBC, 60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 39), hnsecs(274))); 6572 testST(beforeBC, 3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 36, 33), hnsecs(274))); 6573 testST(beforeBC, 600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 31, 33), hnsecs(274))); 6574 testST(beforeBC, 36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 13, 30, 33), hnsecs(274))); 6575 6576 testST(beforeBC, -1, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(273))); 6577 testST(beforeBC, -2, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(272))); 6578 testST(beforeBC, -10, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(264))); 6579 testST(beforeBC, -100, SysTime(DateTime(-1999, 7, 6, 12, 30, 33), hnsecs(174))); 6580 testST(beforeBC, -274, SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 6581 testST(beforeBC, -275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_999))); 6582 testST(beforeBC, -1000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_274))); 6583 testST(beforeBC, -1001, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_999_273))); 6584 testST(beforeBC, -2000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_998_274))); 6585 testST(beforeBC, -33_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_967_000))); 6586 testST(beforeBC, -33_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_966_999))); 6587 testST(beforeBC, -1_833_274, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_167_000))); 6588 testST(beforeBC, -1_833_275, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(8_166_999))); 6589 testST(beforeBC, -1_000_000, SysTime(DateTime(-1999, 7, 6, 12, 30, 32), hnsecs(9_000_274))); 6590 testST(beforeBC, -60_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 30, 27), hnsecs(274))); 6591 testST(beforeBC, -3_600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 24, 33), hnsecs(274))); 6592 testST(beforeBC, -600_000_000L, SysTime(DateTime(-1999, 7, 6, 12, 29, 33), hnsecs(274))); 6593 testST(beforeBC, -36_000_000_000L, SysTime(DateTime(-1999, 7, 6, 11, 30, 33), hnsecs(274))); 6594 6595 // Test Both 6596 auto beforeBoth1 = SysTime(DateTime(1, 1, 1, 0, 0, 0)); 6597 testST(beforeBoth1, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 6598 testST(beforeBoth1, 0, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6599 testST(beforeBoth1, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6600 testST(beforeBoth1, -2, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998))); 6601 testST(beforeBoth1, -1000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_000))); 6602 testST(beforeBoth1, -2000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_998_000))); 6603 testST(beforeBoth1, -2555, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_997_445))); 6604 testST(beforeBoth1, -1_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_000_000))); 6605 testST(beforeBoth1, -2_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(8_000_000))); 6606 testST(beforeBoth1, -2_333_333, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(7_666_667))); 6607 testST(beforeBoth1, -10_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 59))); 6608 testST(beforeBoth1, -20_000_000, SysTime(DateTime(0, 12, 31, 23, 59, 58))); 6609 testST(beforeBoth1, -20_888_888, SysTime(DateTime(0, 12, 31, 23, 59, 57), hnsecs(9_111_112))); 6610 6611 auto beforeBoth2 = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 6612 testST(beforeBoth2, -1, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998))); 6613 testST(beforeBoth2, 0, SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 6614 testST(beforeBoth2, 1, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 6615 testST(beforeBoth2, 2, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 6616 testST(beforeBoth2, 1000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999))); 6617 testST(beforeBoth2, 2000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1999))); 6618 testST(beforeBoth2, 2555, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2554))); 6619 testST(beforeBoth2, 1_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(999_999))); 6620 testST(beforeBoth2, 2_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1_999_999))); 6621 testST(beforeBoth2, 2_333_333, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(2_333_332))); 6622 testST(beforeBoth2, 10_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 6623 testST(beforeBoth2, 20_000_000, SysTime(DateTime(1, 1, 1, 0, 0, 1), hnsecs(9_999_999))); 6624 testST(beforeBoth2, 20_888_888, SysTime(DateTime(1, 1, 1, 0, 0, 2), hnsecs(888_887))); 6625 6626 { 6627 auto st = SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)); 6628 (st += dur!"hnsecs"(52)) += dur!"seconds"(-907); 6629 assert(st == SysTime(DateTime(0, 12, 31, 23, 44, 53), hnsecs(51))); 6630 } 6631 6632 auto duration = dur!"seconds"(12); 6633 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6634 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6635 static assert(!__traits(compiles, cst += duration)); 6636 static assert(!__traits(compiles, ist += duration)); 6637 static assert(!__traits(compiles, cst -= duration)); 6638 static assert(!__traits(compiles, ist -= duration)); 6639 6640 static void testScope(scope ref SysTime st, scope ref Duration d) @safe 6641 { 6642 auto result1 = st += d; 6643 auto result2 = st -= d; 6644 } 6645 } 6646 6647 6648 /++ 6649 Gives the difference between two $(LREF SysTime)s. 6650 6651 The legal types of arithmetic for $(LREF SysTime) using this operator 6652 are 6653 6654 $(BOOKTABLE, 6655 $(TR $(TD SysTime) $(TD -) $(TD SysTime) $(TD -->) $(TD duration)) 6656 ) 6657 +/ 6658 Duration opBinary(string op)(SysTime rhs) @safe const pure nothrow scope 6659 if (op == "-") 6660 { 6661 return dur!"hnsecs"(_stdTime - rhs._stdTime); 6662 } 6663 6664 @safe unittest 6665 { 6666 import core.time; 6667 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1998, 7, 6, 12, 30, 33)) == 6668 dur!"seconds"(31_536_000)); 6669 assert(SysTime(DateTime(1998, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6670 dur!"seconds"(-31_536_000)); 6671 6672 assert(SysTime(DateTime(1999, 8, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6673 dur!"seconds"(26_78_400)); 6674 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 8, 6, 12, 30, 33)) == 6675 dur!"seconds"(-26_78_400)); 6676 6677 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 5, 12, 30, 33)) == 6678 dur!"seconds"(86_400)); 6679 assert(SysTime(DateTime(1999, 7, 5, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6680 dur!"seconds"(-86_400)); 6681 6682 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 11, 30, 33)) == 6683 dur!"seconds"(3600)); 6684 assert(SysTime(DateTime(1999, 7, 6, 11, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6685 dur!"seconds"(-3600)); 6686 6687 assert(SysTime(DateTime(1999, 7, 6, 12, 31, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6688 dur!"seconds"(60)); 6689 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 31, 33)) == 6690 dur!"seconds"(-60)); 6691 6692 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 34)) - SysTime(DateTime(1999, 7, 6, 12, 30, 33)) == 6693 dur!"seconds"(1)); 6694 assert(SysTime(DateTime(1999, 7, 6, 12, 30, 33)) - SysTime(DateTime(1999, 7, 6, 12, 30, 34)) == 6695 dur!"seconds"(-1)); 6696 6697 { 6698 auto dt = DateTime(1999, 7, 6, 12, 30, 33); 6699 assert(SysTime(dt, msecs(532)) - SysTime(dt) == msecs(532)); 6700 assert(SysTime(dt) - SysTime(dt, msecs(532)) == msecs(-532)); 6701 6702 assert(SysTime(dt, usecs(333_347)) - SysTime(dt) == usecs(333_347)); 6703 assert(SysTime(dt) - SysTime(dt, usecs(333_347)) == usecs(-333_347)); 6704 6705 assert(SysTime(dt, hnsecs(1_234_567)) - SysTime(dt) == hnsecs(1_234_567)); 6706 assert(SysTime(dt) - SysTime(dt, hnsecs(1_234_567)) == hnsecs(-1_234_567)); 6707 } 6708 6709 assert(SysTime(DateTime(1, 1, 1, 12, 30, 33)) - SysTime(DateTime(1, 1, 1, 0, 0, 0)) == dur!"seconds"(45033)); 6710 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)) - SysTime(DateTime(1, 1, 1, 12, 30, 33)) == dur!"seconds"(-45033)); 6711 assert(SysTime(DateTime(0, 12, 31, 12, 30, 33)) - SysTime(DateTime(1, 1, 1, 0, 0, 0)) == dur!"seconds"(-41367)); 6712 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)) - SysTime(DateTime(0, 12, 31, 12, 30, 33)) == dur!"seconds"(41367)); 6713 6714 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)) - SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)) == 6715 dur!"hnsecs"(1)); 6716 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)) - SysTime(DateTime(1, 1, 1, 0, 0, 0)) == 6717 dur!"hnsecs"(-1)); 6718 6719 version (Posix) 6720 { 6721 import std.datetime.timezone : PosixTimeZone; 6722 immutable tz = PosixTimeZone.getTimeZone("America/Los_Angeles"); 6723 } 6724 else version (Windows) 6725 { 6726 import std.datetime.timezone : WindowsTimeZone; 6727 immutable tz = WindowsTimeZone.getTimeZone("Pacific Standard Time"); 6728 } 6729 6730 { 6731 auto dt = DateTime(2011, 1, 13, 8, 17, 2); 6732 auto d = msecs(296); 6733 assert(SysTime(dt, d, tz) - SysTime(dt, d, tz) == Duration.zero); 6734 assert(SysTime(dt, d, tz) - SysTime(dt, d, UTC()) == hours(8)); 6735 assert(SysTime(dt, d, UTC()) - SysTime(dt, d, tz) == hours(-8)); 6736 } 6737 6738 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6739 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6740 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6741 assert(st - st == Duration.zero); 6742 assert(cst - st == Duration.zero); 6743 assert(ist - st == Duration.zero); 6744 6745 assert(st - cst == Duration.zero); 6746 assert(cst - cst == Duration.zero); 6747 assert(ist - cst == Duration.zero); 6748 6749 assert(st - ist == Duration.zero); 6750 assert(cst - ist == Duration.zero); 6751 assert(ist - ist == Duration.zero); 6752 6753 static void testScope(scope ref SysTime left, scope ref SysTime right) @safe 6754 { 6755 auto result = left - right; 6756 } 6757 } 6758 6759 6760 /++ 6761 Returns the difference between the two $(LREF SysTime)s in months. 6762 6763 To get the difference in years, subtract the year property 6764 of two $(LREF SysTime)s. To get the difference in days or weeks, 6765 subtract the $(LREF SysTime)s themselves and use the 6766 $(REF Duration, core,time) that results. Because converting between 6767 months and smaller units requires a specific date (which 6768 $(REF Duration, core,time)s don't have), getting the difference in 6769 months requires some math using both the year and month properties, so 6770 this is a convenience function for getting the difference in months. 6771 6772 Note that the number of days in the months or how far into the month 6773 either date is is irrelevant. It is the difference in the month property 6774 combined with the difference in years * 12. So, for instance, 6775 December 31st and January 1st are one month apart just as December 1st 6776 and January 31st are one month apart. 6777 6778 Params: 6779 rhs = The $(LREF SysTime) to subtract from this one. 6780 +/ 6781 int diffMonths(scope SysTime rhs) @safe const nothrow scope 6782 { 6783 return (cast(Date) this).diffMonths(cast(Date) rhs); 6784 } 6785 6786 /// 6787 @safe unittest 6788 { 6789 import core.time; 6790 import std.datetime.date : Date; 6791 6792 assert(SysTime(Date(1999, 2, 1)).diffMonths( 6793 SysTime(Date(1999, 1, 31))) == 1); 6794 6795 assert(SysTime(Date(1999, 1, 31)).diffMonths( 6796 SysTime(Date(1999, 2, 1))) == -1); 6797 6798 assert(SysTime(Date(1999, 3, 1)).diffMonths( 6799 SysTime(Date(1999, 1, 1))) == 2); 6800 6801 assert(SysTime(Date(1999, 1, 1)).diffMonths( 6802 SysTime(Date(1999, 3, 31))) == -2); 6803 } 6804 6805 @safe unittest 6806 { 6807 import core.time; 6808 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6809 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6810 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6811 assert(st.diffMonths(st) == 0); 6812 assert(cst.diffMonths(st) == 0); 6813 assert(ist.diffMonths(st) == 0); 6814 6815 assert(st.diffMonths(cst) == 0); 6816 assert(cst.diffMonths(cst) == 0); 6817 assert(ist.diffMonths(cst) == 0); 6818 6819 assert(st.diffMonths(ist) == 0); 6820 assert(cst.diffMonths(ist) == 0); 6821 assert(ist.diffMonths(ist) == 0); 6822 6823 static void testScope(scope ref SysTime left, scope ref SysTime right) @safe 6824 { 6825 auto result = left.diffMonths(right); 6826 } 6827 } 6828 6829 6830 /++ 6831 Whether this $(LREF SysTime) is in a leap year. 6832 +/ 6833 @property bool isLeapYear() @safe const nothrow scope 6834 { 6835 return (cast(Date) this).isLeapYear; 6836 } 6837 6838 @safe unittest 6839 { 6840 import core.time; 6841 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6842 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6843 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6844 assert(!st.isLeapYear); 6845 assert(!cst.isLeapYear); 6846 assert(!ist.isLeapYear); 6847 6848 static void testScope(scope ref SysTime st) @safe 6849 { 6850 auto result = st.isLeapYear; 6851 } 6852 } 6853 6854 6855 /++ 6856 Day of the week this $(LREF SysTime) is on. 6857 +/ 6858 @property DayOfWeek dayOfWeek() @safe const nothrow scope 6859 { 6860 return getDayOfWeek(dayOfGregorianCal); 6861 } 6862 6863 @safe unittest 6864 { 6865 import core.time; 6866 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6867 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6868 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6869 assert(st.dayOfWeek == DayOfWeek.tue); 6870 assert(cst.dayOfWeek == DayOfWeek.tue); 6871 assert(ist.dayOfWeek == DayOfWeek.tue); 6872 6873 static void testScope(scope ref SysTime st) @safe 6874 { 6875 auto result = st.dayOfWeek; 6876 } 6877 } 6878 6879 6880 /++ 6881 Day of the year this $(LREF SysTime) is on. 6882 +/ 6883 @property ushort dayOfYear() @safe const nothrow scope 6884 { 6885 return (cast(Date) this).dayOfYear; 6886 } 6887 6888 /// 6889 @safe unittest 6890 { 6891 import core.time; 6892 import std.datetime.date : DateTime; 6893 6894 assert(SysTime(DateTime(1999, 1, 1, 12, 22, 7)).dayOfYear == 1); 6895 assert(SysTime(DateTime(1999, 12, 31, 7, 2, 59)).dayOfYear == 365); 6896 assert(SysTime(DateTime(2000, 12, 31, 21, 20, 0)).dayOfYear == 366); 6897 } 6898 6899 @safe unittest 6900 { 6901 import core.time; 6902 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6903 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6904 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6905 assert(st.dayOfYear == 187); 6906 assert(cst.dayOfYear == 187); 6907 assert(ist.dayOfYear == 187); 6908 6909 static void testScope(scope ref SysTime st) @safe 6910 { 6911 auto result = st.dayOfYear; 6912 } 6913 } 6914 6915 6916 /++ 6917 Day of the year. 6918 6919 Params: 6920 day = The day of the year to set which day of the year this 6921 $(LREF SysTime) is on. 6922 +/ 6923 @property void dayOfYear(int day) @safe scope 6924 { 6925 immutable hnsecs = adjTime; 6926 immutable days = convert!("hnsecs", "days")(hnsecs); 6927 immutable theRest = hnsecs - convert!("days", "hnsecs")(days); 6928 6929 auto date = Date(cast(int) days); 6930 date.dayOfYear = day; 6931 6932 immutable newDaysHNSecs = convert!("days", "hnsecs")(date.dayOfGregorianCal - 1); 6933 6934 adjTime = newDaysHNSecs + theRest; 6935 } 6936 6937 @safe unittest 6938 { 6939 import core.time; 6940 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6941 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6942 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 6943 st.dayOfYear = 12; 6944 assert(st.dayOfYear == 12); 6945 static assert(!__traits(compiles, cst.dayOfYear = 12)); 6946 static assert(!__traits(compiles, ist.dayOfYear = 12)); 6947 6948 static void testScope(scope ref SysTime st) @safe 6949 { 6950 st.dayOfYear = 42; 6951 } 6952 } 6953 6954 6955 /++ 6956 The Xth day of the Gregorian Calendar that this $(LREF SysTime) is on. 6957 +/ 6958 @property int dayOfGregorianCal() @safe const nothrow scope 6959 { 6960 immutable adjustedTime = adjTime; 6961 6962 // We have to add one because 0 would be midnight, January 1st, 1 A.D., 6963 // which would be the 1st day of the Gregorian Calendar, not the 0th. So, 6964 // simply casting to days is one day off. 6965 if (adjustedTime > 0) 6966 return cast(int) getUnitsFromHNSecs!"days"(adjustedTime) + 1; 6967 6968 long hnsecs = adjustedTime; 6969 immutable days = cast(int) splitUnitsFromHNSecs!"days"(hnsecs); 6970 6971 return hnsecs == 0 ? days + 1 : days; 6972 } 6973 6974 /// 6975 @safe unittest 6976 { 6977 import core.time; 6978 import std.datetime.date : DateTime; 6979 6980 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).dayOfGregorianCal == 1); 6981 assert(SysTime(DateTime(1, 12, 31, 23, 59, 59)).dayOfGregorianCal == 365); 6982 assert(SysTime(DateTime(2, 1, 1, 2, 2, 2)).dayOfGregorianCal == 366); 6983 6984 assert(SysTime(DateTime(0, 12, 31, 7, 7, 7)).dayOfGregorianCal == 0); 6985 assert(SysTime(DateTime(0, 1, 1, 19, 30, 0)).dayOfGregorianCal == -365); 6986 assert(SysTime(DateTime(-1, 12, 31, 4, 7, 0)).dayOfGregorianCal == -366); 6987 6988 assert(SysTime(DateTime(2000, 1, 1, 9, 30, 20)).dayOfGregorianCal == 730_120); 6989 assert(SysTime(DateTime(2010, 12, 31, 15, 45, 50)).dayOfGregorianCal == 734_137); 6990 } 6991 6992 @safe unittest 6993 { 6994 import core.time; 6995 // Test A.D. 6996 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).dayOfGregorianCal == 1); 6997 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1)).dayOfGregorianCal == 1); 6998 assert(SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)).dayOfGregorianCal == 1); 6999 7000 assert(SysTime(DateTime(1, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 1); 7001 assert(SysTime(DateTime(1, 1, 2, 12, 2, 9), msecs(212)).dayOfGregorianCal == 2); 7002 assert(SysTime(DateTime(1, 2, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 32); 7003 assert(SysTime(DateTime(2, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 366); 7004 assert(SysTime(DateTime(3, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 731); 7005 assert(SysTime(DateTime(4, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 1096); 7006 assert(SysTime(DateTime(5, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 1462); 7007 assert(SysTime(DateTime(50, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 17_898); 7008 assert(SysTime(DateTime(97, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 35_065); 7009 assert(SysTime(DateTime(100, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 36_160); 7010 assert(SysTime(DateTime(101, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 36_525); 7011 assert(SysTime(DateTime(105, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 37_986); 7012 assert(SysTime(DateTime(200, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 72_684); 7013 assert(SysTime(DateTime(201, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 73_049); 7014 assert(SysTime(DateTime(300, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 109_208); 7015 assert(SysTime(DateTime(301, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 109_573); 7016 assert(SysTime(DateTime(400, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 145_732); 7017 assert(SysTime(DateTime(401, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 146_098); 7018 assert(SysTime(DateTime(500, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 182_257); 7019 assert(SysTime(DateTime(501, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 182_622); 7020 assert(SysTime(DateTime(1000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 364_878); 7021 assert(SysTime(DateTime(1001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 365_243); 7022 assert(SysTime(DateTime(1600, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 584_023); 7023 assert(SysTime(DateTime(1601, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 584_389); 7024 assert(SysTime(DateTime(1900, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 693_596); 7025 assert(SysTime(DateTime(1901, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 693_961); 7026 assert(SysTime(DateTime(1945, 11, 12, 12, 2, 9), msecs(212)).dayOfGregorianCal == 710_347); 7027 assert(SysTime(DateTime(1999, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 729_755); 7028 assert(SysTime(DateTime(2000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 730_120); 7029 assert(SysTime(DateTime(2001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == 730_486); 7030 7031 assert(SysTime(DateTime(2010, 1, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_773); 7032 assert(SysTime(DateTime(2010, 1, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_803); 7033 assert(SysTime(DateTime(2010, 2, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_804); 7034 assert(SysTime(DateTime(2010, 2, 28, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_831); 7035 assert(SysTime(DateTime(2010, 3, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_832); 7036 assert(SysTime(DateTime(2010, 3, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_862); 7037 assert(SysTime(DateTime(2010, 4, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_863); 7038 assert(SysTime(DateTime(2010, 4, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_892); 7039 assert(SysTime(DateTime(2010, 5, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_893); 7040 assert(SysTime(DateTime(2010, 5, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_923); 7041 assert(SysTime(DateTime(2010, 6, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_924); 7042 assert(SysTime(DateTime(2010, 6, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_953); 7043 assert(SysTime(DateTime(2010, 7, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_954); 7044 assert(SysTime(DateTime(2010, 7, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_984); 7045 assert(SysTime(DateTime(2010, 8, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 733_985); 7046 assert(SysTime(DateTime(2010, 8, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_015); 7047 assert(SysTime(DateTime(2010, 9, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_016); 7048 assert(SysTime(DateTime(2010, 9, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_045); 7049 assert(SysTime(DateTime(2010, 10, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_046); 7050 assert(SysTime(DateTime(2010, 10, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_076); 7051 assert(SysTime(DateTime(2010, 11, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_077); 7052 assert(SysTime(DateTime(2010, 11, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_106); 7053 assert(SysTime(DateTime(2010, 12, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_107); 7054 assert(SysTime(DateTime(2010, 12, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == 734_137); 7055 7056 assert(SysTime(DateTime(2012, 2, 1, 0, 0, 0)).dayOfGregorianCal == 734_534); 7057 assert(SysTime(DateTime(2012, 2, 28, 0, 0, 0)).dayOfGregorianCal == 734_561); 7058 assert(SysTime(DateTime(2012, 2, 29, 0, 0, 0)).dayOfGregorianCal == 734_562); 7059 assert(SysTime(DateTime(2012, 3, 1, 0, 0, 0)).dayOfGregorianCal == 734_563); 7060 7061 // Test B.C. 7062 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999)).dayOfGregorianCal == 0); 7063 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_998)).dayOfGregorianCal == 0); 7064 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59)).dayOfGregorianCal == 0); 7065 assert(SysTime(DateTime(0, 12, 31, 0, 0, 0), hnsecs(1)).dayOfGregorianCal == 0); 7066 assert(SysTime(DateTime(0, 12, 31, 0, 0, 0)).dayOfGregorianCal == 0); 7067 7068 assert(SysTime(DateTime(-1, 12, 31, 23, 59, 59), hnsecs(9_999_999)).dayOfGregorianCal == -366); 7069 assert(SysTime(DateTime(-1, 12, 31, 23, 59, 59), hnsecs(9_999_998)).dayOfGregorianCal == -366); 7070 assert(SysTime(DateTime(-1, 12, 31, 23, 59, 59)).dayOfGregorianCal == -366); 7071 assert(SysTime(DateTime(-1, 12, 31, 0, 0, 0)).dayOfGregorianCal == -366); 7072 7073 assert(SysTime(DateTime(0, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == 0); 7074 assert(SysTime(DateTime(0, 12, 30, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1); 7075 assert(SysTime(DateTime(0, 12, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -30); 7076 assert(SysTime(DateTime(0, 11, 30, 12, 2, 9), msecs(212)).dayOfGregorianCal == -31); 7077 7078 assert(SysTime(DateTime(-1, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -366); 7079 assert(SysTime(DateTime(-1, 12, 30, 12, 2, 9), msecs(212)).dayOfGregorianCal == -367); 7080 assert(SysTime(DateTime(-1, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730); 7081 assert(SysTime(DateTime(-2, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -731); 7082 assert(SysTime(DateTime(-2, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1095); 7083 assert(SysTime(DateTime(-3, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1096); 7084 assert(SysTime(DateTime(-3, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1460); 7085 assert(SysTime(DateTime(-4, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1461); 7086 assert(SysTime(DateTime(-4, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1826); 7087 assert(SysTime(DateTime(-5, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -1827); 7088 assert(SysTime(DateTime(-5, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -2191); 7089 assert(SysTime(DateTime(-9, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -3652); 7090 7091 assert(SysTime(DateTime(-49, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -18_262); 7092 assert(SysTime(DateTime(-50, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -18_627); 7093 assert(SysTime(DateTime(-97, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -35_794); 7094 assert(SysTime(DateTime(-99, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -36_160); 7095 assert(SysTime(DateTime(-99, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -36_524); 7096 assert(SysTime(DateTime(-100, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -36_889); 7097 assert(SysTime(DateTime(-101, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -37_254); 7098 assert(SysTime(DateTime(-105, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -38_715); 7099 assert(SysTime(DateTime(-200, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -73_413); 7100 assert(SysTime(DateTime(-201, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -73_778); 7101 assert(SysTime(DateTime(-300, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -109_937); 7102 assert(SysTime(DateTime(-301, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -110_302); 7103 assert(SysTime(DateTime(-400, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -146_097); 7104 assert(SysTime(DateTime(-400, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -146_462); 7105 assert(SysTime(DateTime(-401, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -146_827); 7106 assert(SysTime(DateTime(-499, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -182_621); 7107 assert(SysTime(DateTime(-500, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -182_986); 7108 assert(SysTime(DateTime(-501, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -183_351); 7109 assert(SysTime(DateTime(-1000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -365_607); 7110 assert(SysTime(DateTime(-1001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -365_972); 7111 assert(SysTime(DateTime(-1599, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -584_387); 7112 assert(SysTime(DateTime(-1600, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -584_388); 7113 assert(SysTime(DateTime(-1600, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -584_753); 7114 assert(SysTime(DateTime(-1601, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -585_118); 7115 assert(SysTime(DateTime(-1900, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -694_325); 7116 assert(SysTime(DateTime(-1901, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -694_690); 7117 assert(SysTime(DateTime(-1999, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730_484); 7118 assert(SysTime(DateTime(-2000, 12, 31, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730_485); 7119 assert(SysTime(DateTime(-2000, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -730_850); 7120 assert(SysTime(DateTime(-2001, 1, 1, 12, 2, 9), msecs(212)).dayOfGregorianCal == -731_215); 7121 7122 assert(SysTime(DateTime(-2010, 1, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_502); 7123 assert(SysTime(DateTime(-2010, 1, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_472); 7124 assert(SysTime(DateTime(-2010, 2, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_471); 7125 assert(SysTime(DateTime(-2010, 2, 28, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_444); 7126 assert(SysTime(DateTime(-2010, 3, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_443); 7127 assert(SysTime(DateTime(-2010, 3, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_413); 7128 assert(SysTime(DateTime(-2010, 4, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_412); 7129 assert(SysTime(DateTime(-2010, 4, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_383); 7130 assert(SysTime(DateTime(-2010, 5, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_382); 7131 assert(SysTime(DateTime(-2010, 5, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_352); 7132 assert(SysTime(DateTime(-2010, 6, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_351); 7133 assert(SysTime(DateTime(-2010, 6, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_322); 7134 assert(SysTime(DateTime(-2010, 7, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_321); 7135 assert(SysTime(DateTime(-2010, 7, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_291); 7136 assert(SysTime(DateTime(-2010, 8, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_290); 7137 assert(SysTime(DateTime(-2010, 8, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_260); 7138 assert(SysTime(DateTime(-2010, 9, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_259); 7139 assert(SysTime(DateTime(-2010, 9, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_230); 7140 assert(SysTime(DateTime(-2010, 10, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_229); 7141 assert(SysTime(DateTime(-2010, 10, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_199); 7142 assert(SysTime(DateTime(-2010, 11, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_198); 7143 assert(SysTime(DateTime(-2010, 11, 30, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_169); 7144 assert(SysTime(DateTime(-2010, 12, 1, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_168); 7145 assert(SysTime(DateTime(-2010, 12, 31, 23, 59, 59), msecs(999)).dayOfGregorianCal == -734_138); 7146 7147 assert(SysTime(DateTime(-2012, 2, 1, 0, 0, 0)).dayOfGregorianCal == -735_202); 7148 assert(SysTime(DateTime(-2012, 2, 28, 0, 0, 0)).dayOfGregorianCal == -735_175); 7149 assert(SysTime(DateTime(-2012, 2, 29, 0, 0, 0)).dayOfGregorianCal == -735_174); 7150 assert(SysTime(DateTime(-2012, 3, 1, 0, 0, 0)).dayOfGregorianCal == -735_173); 7151 7152 // Start of Hebrew Calendar 7153 assert(SysTime(DateTime(-3760, 9, 7, 0, 0, 0)).dayOfGregorianCal == -1_373_427); 7154 7155 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7156 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7157 assert(cst.dayOfGregorianCal == 729_941); 7158 assert(ist.dayOfGregorianCal == 729_941); 7159 7160 static void testScope(scope ref SysTime st) @safe 7161 { 7162 auto result = st.dayOfGregorianCal; 7163 } 7164 } 7165 7166 7167 // Test that the logic for the day of the Gregorian Calendar is consistent 7168 // between Date and SysTime. 7169 @safe unittest 7170 { 7171 import core.time; 7172 void test(Date date, SysTime st, size_t line = __LINE__) 7173 { 7174 if (date.dayOfGregorianCal != st.dayOfGregorianCal) 7175 { 7176 throw new AssertError(format("Date [%s] SysTime [%s]", date.dayOfGregorianCal, st.dayOfGregorianCal), 7177 __FILE__, line); 7178 } 7179 } 7180 7181 // Test A.D. 7182 test(Date(1, 1, 1), SysTime(DateTime(1, 1, 1, 0, 0, 0))); 7183 test(Date(1, 1, 2), SysTime(DateTime(1, 1, 2, 0, 0, 0), hnsecs(500))); 7184 test(Date(1, 2, 1), SysTime(DateTime(1, 2, 1, 0, 0, 0), hnsecs(50_000))); 7185 test(Date(2, 1, 1), SysTime(DateTime(2, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 7186 test(Date(3, 1, 1), SysTime(DateTime(3, 1, 1, 12, 13, 14))); 7187 test(Date(4, 1, 1), SysTime(DateTime(4, 1, 1, 12, 13, 14), hnsecs(500))); 7188 test(Date(5, 1, 1), SysTime(DateTime(5, 1, 1, 12, 13, 14), hnsecs(50_000))); 7189 test(Date(50, 1, 1), SysTime(DateTime(50, 1, 1, 12, 13, 14), hnsecs(9_999_999))); 7190 test(Date(97, 1, 1), SysTime(DateTime(97, 1, 1, 23, 59, 59))); 7191 test(Date(100, 1, 1), SysTime(DateTime(100, 1, 1, 23, 59, 59), hnsecs(500))); 7192 test(Date(101, 1, 1), SysTime(DateTime(101, 1, 1, 23, 59, 59), hnsecs(50_000))); 7193 test(Date(105, 1, 1), SysTime(DateTime(105, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7194 test(Date(200, 1, 1), SysTime(DateTime(200, 1, 1, 0, 0, 0))); 7195 test(Date(201, 1, 1), SysTime(DateTime(201, 1, 1, 0, 0, 0), hnsecs(500))); 7196 test(Date(300, 1, 1), SysTime(DateTime(300, 1, 1, 0, 0, 0), hnsecs(50_000))); 7197 test(Date(301, 1, 1), SysTime(DateTime(301, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 7198 test(Date(400, 1, 1), SysTime(DateTime(400, 1, 1, 12, 13, 14))); 7199 test(Date(401, 1, 1), SysTime(DateTime(401, 1, 1, 12, 13, 14), hnsecs(500))); 7200 test(Date(500, 1, 1), SysTime(DateTime(500, 1, 1, 12, 13, 14), hnsecs(50_000))); 7201 test(Date(501, 1, 1), SysTime(DateTime(501, 1, 1, 12, 13, 14), hnsecs(9_999_999))); 7202 test(Date(1000, 1, 1), SysTime(DateTime(1000, 1, 1, 23, 59, 59))); 7203 test(Date(1001, 1, 1), SysTime(DateTime(1001, 1, 1, 23, 59, 59), hnsecs(500))); 7204 test(Date(1600, 1, 1), SysTime(DateTime(1600, 1, 1, 23, 59, 59), hnsecs(50_000))); 7205 test(Date(1601, 1, 1), SysTime(DateTime(1601, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7206 test(Date(1900, 1, 1), SysTime(DateTime(1900, 1, 1, 0, 0, 0))); 7207 test(Date(1901, 1, 1), SysTime(DateTime(1901, 1, 1, 0, 0, 0), hnsecs(500))); 7208 test(Date(1945, 11, 12), SysTime(DateTime(1945, 11, 12, 0, 0, 0), hnsecs(50_000))); 7209 test(Date(1999, 1, 1), SysTime(DateTime(1999, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 7210 test(Date(1999, 7, 6), SysTime(DateTime(1999, 7, 6, 12, 13, 14))); 7211 test(Date(2000, 1, 1), SysTime(DateTime(2000, 1, 1, 12, 13, 14), hnsecs(500))); 7212 test(Date(2001, 1, 1), SysTime(DateTime(2001, 1, 1, 12, 13, 14), hnsecs(50_000))); 7213 7214 test(Date(2010, 1, 1), SysTime(DateTime(2010, 1, 1, 12, 13, 14), hnsecs(9_999_999))); 7215 test(Date(2010, 1, 31), SysTime(DateTime(2010, 1, 31, 23, 0, 0))); 7216 test(Date(2010, 2, 1), SysTime(DateTime(2010, 2, 1, 23, 59, 59), hnsecs(500))); 7217 test(Date(2010, 2, 28), SysTime(DateTime(2010, 2, 28, 23, 59, 59), hnsecs(50_000))); 7218 test(Date(2010, 3, 1), SysTime(DateTime(2010, 3, 1, 23, 59, 59), hnsecs(9_999_999))); 7219 test(Date(2010, 3, 31), SysTime(DateTime(2010, 3, 31, 0, 0, 0))); 7220 test(Date(2010, 4, 1), SysTime(DateTime(2010, 4, 1, 0, 0, 0), hnsecs(500))); 7221 test(Date(2010, 4, 30), SysTime(DateTime(2010, 4, 30, 0, 0, 0), hnsecs(50_000))); 7222 test(Date(2010, 5, 1), SysTime(DateTime(2010, 5, 1, 0, 0, 0), hnsecs(9_999_999))); 7223 test(Date(2010, 5, 31), SysTime(DateTime(2010, 5, 31, 12, 13, 14))); 7224 test(Date(2010, 6, 1), SysTime(DateTime(2010, 6, 1, 12, 13, 14), hnsecs(500))); 7225 test(Date(2010, 6, 30), SysTime(DateTime(2010, 6, 30, 12, 13, 14), hnsecs(50_000))); 7226 test(Date(2010, 7, 1), SysTime(DateTime(2010, 7, 1, 12, 13, 14), hnsecs(9_999_999))); 7227 test(Date(2010, 7, 31), SysTime(DateTime(2010, 7, 31, 23, 59, 59))); 7228 test(Date(2010, 8, 1), SysTime(DateTime(2010, 8, 1, 23, 59, 59), hnsecs(500))); 7229 test(Date(2010, 8, 31), SysTime(DateTime(2010, 8, 31, 23, 59, 59), hnsecs(50_000))); 7230 test(Date(2010, 9, 1), SysTime(DateTime(2010, 9, 1, 23, 59, 59), hnsecs(9_999_999))); 7231 test(Date(2010, 9, 30), SysTime(DateTime(2010, 9, 30, 12, 0, 0))); 7232 test(Date(2010, 10, 1), SysTime(DateTime(2010, 10, 1, 0, 12, 0), hnsecs(500))); 7233 test(Date(2010, 10, 31), SysTime(DateTime(2010, 10, 31, 0, 0, 12), hnsecs(50_000))); 7234 test(Date(2010, 11, 1), SysTime(DateTime(2010, 11, 1, 23, 0, 0), hnsecs(9_999_999))); 7235 test(Date(2010, 11, 30), SysTime(DateTime(2010, 11, 30, 0, 59, 0))); 7236 test(Date(2010, 12, 1), SysTime(DateTime(2010, 12, 1, 0, 0, 59), hnsecs(500))); 7237 test(Date(2010, 12, 31), SysTime(DateTime(2010, 12, 31, 0, 59, 59), hnsecs(50_000))); 7238 7239 test(Date(2012, 2, 1), SysTime(DateTime(2012, 2, 1, 23, 0, 59), hnsecs(9_999_999))); 7240 test(Date(2012, 2, 28), SysTime(DateTime(2012, 2, 28, 23, 59, 0))); 7241 test(Date(2012, 2, 29), SysTime(DateTime(2012, 2, 29, 7, 7, 7), hnsecs(7))); 7242 test(Date(2012, 3, 1), SysTime(DateTime(2012, 3, 1, 7, 7, 7), hnsecs(7))); 7243 7244 // Test B.C. 7245 test(Date(0, 12, 31), SysTime(DateTime(0, 12, 31, 0, 0, 0))); 7246 test(Date(0, 12, 30), SysTime(DateTime(0, 12, 30, 0, 0, 0), hnsecs(500))); 7247 test(Date(0, 12, 1), SysTime(DateTime(0, 12, 1, 0, 0, 0), hnsecs(50_000))); 7248 test(Date(0, 11, 30), SysTime(DateTime(0, 11, 30, 0, 0, 0), hnsecs(9_999_999))); 7249 7250 test(Date(-1, 12, 31), SysTime(DateTime(-1, 12, 31, 12, 13, 14))); 7251 test(Date(-1, 12, 30), SysTime(DateTime(-1, 12, 30, 12, 13, 14), hnsecs(500))); 7252 test(Date(-1, 1, 1), SysTime(DateTime(-1, 1, 1, 12, 13, 14), hnsecs(50_000))); 7253 test(Date(-2, 12, 31), SysTime(DateTime(-2, 12, 31, 12, 13, 14), hnsecs(9_999_999))); 7254 test(Date(-2, 1, 1), SysTime(DateTime(-2, 1, 1, 23, 59, 59))); 7255 test(Date(-3, 12, 31), SysTime(DateTime(-3, 12, 31, 23, 59, 59), hnsecs(500))); 7256 test(Date(-3, 1, 1), SysTime(DateTime(-3, 1, 1, 23, 59, 59), hnsecs(50_000))); 7257 test(Date(-4, 12, 31), SysTime(DateTime(-4, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 7258 test(Date(-4, 1, 1), SysTime(DateTime(-4, 1, 1, 0, 0, 0))); 7259 test(Date(-5, 12, 31), SysTime(DateTime(-5, 12, 31, 0, 0, 0), hnsecs(500))); 7260 test(Date(-5, 1, 1), SysTime(DateTime(-5, 1, 1, 0, 0, 0), hnsecs(50_000))); 7261 test(Date(-9, 1, 1), SysTime(DateTime(-9, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 7262 7263 test(Date(-49, 1, 1), SysTime(DateTime(-49, 1, 1, 12, 13, 14))); 7264 test(Date(-50, 1, 1), SysTime(DateTime(-50, 1, 1, 12, 13, 14), hnsecs(500))); 7265 test(Date(-97, 1, 1), SysTime(DateTime(-97, 1, 1, 12, 13, 14), hnsecs(50_000))); 7266 test(Date(-99, 12, 31), SysTime(DateTime(-99, 12, 31, 12, 13, 14), hnsecs(9_999_999))); 7267 test(Date(-99, 1, 1), SysTime(DateTime(-99, 1, 1, 23, 59, 59))); 7268 test(Date(-100, 1, 1), SysTime(DateTime(-100, 1, 1, 23, 59, 59), hnsecs(500))); 7269 test(Date(-101, 1, 1), SysTime(DateTime(-101, 1, 1, 23, 59, 59), hnsecs(50_000))); 7270 test(Date(-105, 1, 1), SysTime(DateTime(-105, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7271 test(Date(-200, 1, 1), SysTime(DateTime(-200, 1, 1, 0, 0, 0))); 7272 test(Date(-201, 1, 1), SysTime(DateTime(-201, 1, 1, 0, 0, 0), hnsecs(500))); 7273 test(Date(-300, 1, 1), SysTime(DateTime(-300, 1, 1, 0, 0, 0), hnsecs(50_000))); 7274 test(Date(-301, 1, 1), SysTime(DateTime(-301, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 7275 test(Date(-400, 12, 31), SysTime(DateTime(-400, 12, 31, 12, 13, 14))); 7276 test(Date(-400, 1, 1), SysTime(DateTime(-400, 1, 1, 12, 13, 14), hnsecs(500))); 7277 test(Date(-401, 1, 1), SysTime(DateTime(-401, 1, 1, 12, 13, 14), hnsecs(50_000))); 7278 test(Date(-499, 1, 1), SysTime(DateTime(-499, 1, 1, 12, 13, 14), hnsecs(9_999_999))); 7279 test(Date(-500, 1, 1), SysTime(DateTime(-500, 1, 1, 23, 59, 59))); 7280 test(Date(-501, 1, 1), SysTime(DateTime(-501, 1, 1, 23, 59, 59), hnsecs(500))); 7281 test(Date(-1000, 1, 1), SysTime(DateTime(-1000, 1, 1, 23, 59, 59), hnsecs(50_000))); 7282 test(Date(-1001, 1, 1), SysTime(DateTime(-1001, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7283 test(Date(-1599, 1, 1), SysTime(DateTime(-1599, 1, 1, 0, 0, 0))); 7284 test(Date(-1600, 12, 31), SysTime(DateTime(-1600, 12, 31, 0, 0, 0), hnsecs(500))); 7285 test(Date(-1600, 1, 1), SysTime(DateTime(-1600, 1, 1, 0, 0, 0), hnsecs(50_000))); 7286 test(Date(-1601, 1, 1), SysTime(DateTime(-1601, 1, 1, 0, 0, 0), hnsecs(9_999_999))); 7287 test(Date(-1900, 1, 1), SysTime(DateTime(-1900, 1, 1, 12, 13, 14))); 7288 test(Date(-1901, 1, 1), SysTime(DateTime(-1901, 1, 1, 12, 13, 14), hnsecs(500))); 7289 test(Date(-1999, 1, 1), SysTime(DateTime(-1999, 1, 1, 12, 13, 14), hnsecs(50_000))); 7290 test(Date(-1999, 7, 6), SysTime(DateTime(-1999, 7, 6, 12, 13, 14), hnsecs(9_999_999))); 7291 test(Date(-2000, 12, 31), SysTime(DateTime(-2000, 12, 31, 23, 59, 59))); 7292 test(Date(-2000, 1, 1), SysTime(DateTime(-2000, 1, 1, 23, 59, 59), hnsecs(500))); 7293 test(Date(-2001, 1, 1), SysTime(DateTime(-2001, 1, 1, 23, 59, 59), hnsecs(50_000))); 7294 7295 test(Date(-2010, 1, 1), SysTime(DateTime(-2010, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7296 test(Date(-2010, 1, 31), SysTime(DateTime(-2010, 1, 31, 0, 0, 0))); 7297 test(Date(-2010, 2, 1), SysTime(DateTime(-2010, 2, 1, 0, 0, 0), hnsecs(500))); 7298 test(Date(-2010, 2, 28), SysTime(DateTime(-2010, 2, 28, 0, 0, 0), hnsecs(50_000))); 7299 test(Date(-2010, 3, 1), SysTime(DateTime(-2010, 3, 1, 0, 0, 0), hnsecs(9_999_999))); 7300 test(Date(-2010, 3, 31), SysTime(DateTime(-2010, 3, 31, 12, 13, 14))); 7301 test(Date(-2010, 4, 1), SysTime(DateTime(-2010, 4, 1, 12, 13, 14), hnsecs(500))); 7302 test(Date(-2010, 4, 30), SysTime(DateTime(-2010, 4, 30, 12, 13, 14), hnsecs(50_000))); 7303 test(Date(-2010, 5, 1), SysTime(DateTime(-2010, 5, 1, 12, 13, 14), hnsecs(9_999_999))); 7304 test(Date(-2010, 5, 31), SysTime(DateTime(-2010, 5, 31, 23, 59, 59))); 7305 test(Date(-2010, 6, 1), SysTime(DateTime(-2010, 6, 1, 23, 59, 59), hnsecs(500))); 7306 test(Date(-2010, 6, 30), SysTime(DateTime(-2010, 6, 30, 23, 59, 59), hnsecs(50_000))); 7307 test(Date(-2010, 7, 1), SysTime(DateTime(-2010, 7, 1, 23, 59, 59), hnsecs(9_999_999))); 7308 test(Date(-2010, 7, 31), SysTime(DateTime(-2010, 7, 31, 0, 0, 0))); 7309 test(Date(-2010, 8, 1), SysTime(DateTime(-2010, 8, 1, 0, 0, 0), hnsecs(500))); 7310 test(Date(-2010, 8, 31), SysTime(DateTime(-2010, 8, 31, 0, 0, 0), hnsecs(50_000))); 7311 test(Date(-2010, 9, 1), SysTime(DateTime(-2010, 9, 1, 0, 0, 0), hnsecs(9_999_999))); 7312 test(Date(-2010, 9, 30), SysTime(DateTime(-2010, 9, 30, 12, 0, 0))); 7313 test(Date(-2010, 10, 1), SysTime(DateTime(-2010, 10, 1, 0, 12, 0), hnsecs(500))); 7314 test(Date(-2010, 10, 31), SysTime(DateTime(-2010, 10, 31, 0, 0, 12), hnsecs(50_000))); 7315 test(Date(-2010, 11, 1), SysTime(DateTime(-2010, 11, 1, 23, 0, 0), hnsecs(9_999_999))); 7316 test(Date(-2010, 11, 30), SysTime(DateTime(-2010, 11, 30, 0, 59, 0))); 7317 test(Date(-2010, 12, 1), SysTime(DateTime(-2010, 12, 1, 0, 0, 59), hnsecs(500))); 7318 test(Date(-2010, 12, 31), SysTime(DateTime(-2010, 12, 31, 0, 59, 59), hnsecs(50_000))); 7319 7320 test(Date(-2012, 2, 1), SysTime(DateTime(-2012, 2, 1, 23, 0, 59), hnsecs(9_999_999))); 7321 test(Date(-2012, 2, 28), SysTime(DateTime(-2012, 2, 28, 23, 59, 0))); 7322 test(Date(-2012, 2, 29), SysTime(DateTime(-2012, 2, 29, 7, 7, 7), hnsecs(7))); 7323 test(Date(-2012, 3, 1), SysTime(DateTime(-2012, 3, 1, 7, 7, 7), hnsecs(7))); 7324 7325 test(Date(-3760, 9, 7), SysTime(DateTime(-3760, 9, 7, 0, 0, 0))); 7326 } 7327 7328 7329 /++ 7330 The Xth day of the Gregorian Calendar that this $(LREF SysTime) is on. 7331 Setting this property does not affect the time portion of $(LREF SysTime). 7332 7333 Params: 7334 days = The day of the Gregorian Calendar to set this $(LREF SysTime) 7335 to. 7336 +/ 7337 @property void dayOfGregorianCal(int days) @safe nothrow scope 7338 { 7339 auto hnsecs = adjTime; 7340 hnsecs = removeUnitsFromHNSecs!"days"(hnsecs); 7341 7342 if (hnsecs < 0) 7343 hnsecs += convert!("hours", "hnsecs")(24); 7344 7345 if (--days < 0) 7346 { 7347 hnsecs -= convert!("hours", "hnsecs")(24); 7348 ++days; 7349 } 7350 7351 immutable newDaysHNSecs = convert!("days", "hnsecs")(days); 7352 7353 adjTime = newDaysHNSecs + hnsecs; 7354 } 7355 7356 /// 7357 @safe unittest 7358 { 7359 import core.time; 7360 import std.datetime.date : DateTime; 7361 7362 auto st = SysTime(DateTime(0, 1, 1, 12, 0, 0)); 7363 st.dayOfGregorianCal = 1; 7364 assert(st == SysTime(DateTime(1, 1, 1, 12, 0, 0))); 7365 7366 st.dayOfGregorianCal = 365; 7367 assert(st == SysTime(DateTime(1, 12, 31, 12, 0, 0))); 7368 7369 st.dayOfGregorianCal = 366; 7370 assert(st == SysTime(DateTime(2, 1, 1, 12, 0, 0))); 7371 7372 st.dayOfGregorianCal = 0; 7373 assert(st == SysTime(DateTime(0, 12, 31, 12, 0, 0))); 7374 7375 st.dayOfGregorianCal = -365; 7376 assert(st == SysTime(DateTime(-0, 1, 1, 12, 0, 0))); 7377 7378 st.dayOfGregorianCal = -366; 7379 assert(st == SysTime(DateTime(-1, 12, 31, 12, 0, 0))); 7380 7381 st.dayOfGregorianCal = 730_120; 7382 assert(st == SysTime(DateTime(2000, 1, 1, 12, 0, 0))); 7383 7384 st.dayOfGregorianCal = 734_137; 7385 assert(st == SysTime(DateTime(2010, 12, 31, 12, 0, 0))); 7386 } 7387 7388 @safe unittest 7389 { 7390 import core.time; 7391 void testST(SysTime orig, int day, SysTime expected, size_t line = __LINE__) @safe 7392 { 7393 orig.dayOfGregorianCal = day; 7394 if (orig != expected) 7395 throw new AssertError(format("Failed. actual [%s] != expected [%s]", orig, expected), __FILE__, line); 7396 } 7397 7398 // Test A.D. 7399 testST(SysTime(DateTime(1, 1, 1, 0, 0, 0)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 7400 testST(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 7401 testST(SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999)), 1, 7402 SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7403 7404 // Test B.C. 7405 testST(SysTime(DateTime(0, 1, 1, 0, 0, 0)), 0, SysTime(DateTime(0, 12, 31, 0, 0, 0))); 7406 testST(SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(9_999_999)), 0, 7407 SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 7408 testST(SysTime(DateTime(0, 1, 1, 23, 59, 59), hnsecs(1)), 0, 7409 SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1))); 7410 testST(SysTime(DateTime(0, 1, 1, 23, 59, 59)), 0, SysTime(DateTime(0, 12, 31, 23, 59, 59))); 7411 7412 // Test Both. 7413 testST(SysTime(DateTime(-512, 7, 20, 0, 0, 0)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0))); 7414 testST(SysTime(DateTime(-513, 6, 6, 0, 0, 0), hnsecs(1)), 1, SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1))); 7415 testST(SysTime(DateTime(-511, 5, 7, 23, 59, 59), hnsecs(9_999_999)), 1, 7416 SysTime(DateTime(1, 1, 1, 23, 59, 59), hnsecs(9_999_999))); 7417 7418 testST(SysTime(DateTime(1607, 4, 8, 0, 0, 0)), 0, SysTime(DateTime(0, 12, 31, 0, 0, 0))); 7419 testST(SysTime(DateTime(1500, 3, 9, 23, 59, 59), hnsecs(9_999_999)), 0, 7420 SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 7421 testST(SysTime(DateTime(999, 2, 10, 23, 59, 59), hnsecs(1)), 0, 7422 SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1))); 7423 testST(SysTime(DateTime(2007, 12, 11, 23, 59, 59)), 0, SysTime(DateTime(0, 12, 31, 23, 59, 59))); 7424 7425 7426 auto st = SysTime(DateTime(1, 1, 1, 12, 2, 9), msecs(212)); 7427 7428 void testST2(int day, SysTime expected, size_t line = __LINE__) @safe 7429 { 7430 st.dayOfGregorianCal = day; 7431 if (st != expected) 7432 throw new AssertError(format("Failed. actual [%s] != expected [%s]", st, expected), __FILE__, line); 7433 } 7434 7435 // Test A.D. 7436 testST2(1, SysTime(DateTime(1, 1, 1, 12, 2, 9), msecs(212))); 7437 testST2(2, SysTime(DateTime(1, 1, 2, 12, 2, 9), msecs(212))); 7438 testST2(32, SysTime(DateTime(1, 2, 1, 12, 2, 9), msecs(212))); 7439 testST2(366, SysTime(DateTime(2, 1, 1, 12, 2, 9), msecs(212))); 7440 testST2(731, SysTime(DateTime(3, 1, 1, 12, 2, 9), msecs(212))); 7441 testST2(1096, SysTime(DateTime(4, 1, 1, 12, 2, 9), msecs(212))); 7442 testST2(1462, SysTime(DateTime(5, 1, 1, 12, 2, 9), msecs(212))); 7443 testST2(17_898, SysTime(DateTime(50, 1, 1, 12, 2, 9), msecs(212))); 7444 testST2(35_065, SysTime(DateTime(97, 1, 1, 12, 2, 9), msecs(212))); 7445 testST2(36_160, SysTime(DateTime(100, 1, 1, 12, 2, 9), msecs(212))); 7446 testST2(36_525, SysTime(DateTime(101, 1, 1, 12, 2, 9), msecs(212))); 7447 testST2(37_986, SysTime(DateTime(105, 1, 1, 12, 2, 9), msecs(212))); 7448 testST2(72_684, SysTime(DateTime(200, 1, 1, 12, 2, 9), msecs(212))); 7449 testST2(73_049, SysTime(DateTime(201, 1, 1, 12, 2, 9), msecs(212))); 7450 testST2(109_208, SysTime(DateTime(300, 1, 1, 12, 2, 9), msecs(212))); 7451 testST2(109_573, SysTime(DateTime(301, 1, 1, 12, 2, 9), msecs(212))); 7452 testST2(145_732, SysTime(DateTime(400, 1, 1, 12, 2, 9), msecs(212))); 7453 testST2(146_098, SysTime(DateTime(401, 1, 1, 12, 2, 9), msecs(212))); 7454 testST2(182_257, SysTime(DateTime(500, 1, 1, 12, 2, 9), msecs(212))); 7455 testST2(182_622, SysTime(DateTime(501, 1, 1, 12, 2, 9), msecs(212))); 7456 testST2(364_878, SysTime(DateTime(1000, 1, 1, 12, 2, 9), msecs(212))); 7457 testST2(365_243, SysTime(DateTime(1001, 1, 1, 12, 2, 9), msecs(212))); 7458 testST2(584_023, SysTime(DateTime(1600, 1, 1, 12, 2, 9), msecs(212))); 7459 testST2(584_389, SysTime(DateTime(1601, 1, 1, 12, 2, 9), msecs(212))); 7460 testST2(693_596, SysTime(DateTime(1900, 1, 1, 12, 2, 9), msecs(212))); 7461 testST2(693_961, SysTime(DateTime(1901, 1, 1, 12, 2, 9), msecs(212))); 7462 testST2(729_755, SysTime(DateTime(1999, 1, 1, 12, 2, 9), msecs(212))); 7463 testST2(730_120, SysTime(DateTime(2000, 1, 1, 12, 2, 9), msecs(212))); 7464 testST2(730_486, SysTime(DateTime(2001, 1, 1, 12, 2, 9), msecs(212))); 7465 7466 testST2(733_773, SysTime(DateTime(2010, 1, 1, 12, 2, 9), msecs(212))); 7467 testST2(733_803, SysTime(DateTime(2010, 1, 31, 12, 2, 9), msecs(212))); 7468 testST2(733_804, SysTime(DateTime(2010, 2, 1, 12, 2, 9), msecs(212))); 7469 testST2(733_831, SysTime(DateTime(2010, 2, 28, 12, 2, 9), msecs(212))); 7470 testST2(733_832, SysTime(DateTime(2010, 3, 1, 12, 2, 9), msecs(212))); 7471 testST2(733_862, SysTime(DateTime(2010, 3, 31, 12, 2, 9), msecs(212))); 7472 testST2(733_863, SysTime(DateTime(2010, 4, 1, 12, 2, 9), msecs(212))); 7473 testST2(733_892, SysTime(DateTime(2010, 4, 30, 12, 2, 9), msecs(212))); 7474 testST2(733_893, SysTime(DateTime(2010, 5, 1, 12, 2, 9), msecs(212))); 7475 testST2(733_923, SysTime(DateTime(2010, 5, 31, 12, 2, 9), msecs(212))); 7476 testST2(733_924, SysTime(DateTime(2010, 6, 1, 12, 2, 9), msecs(212))); 7477 testST2(733_953, SysTime(DateTime(2010, 6, 30, 12, 2, 9), msecs(212))); 7478 testST2(733_954, SysTime(DateTime(2010, 7, 1, 12, 2, 9), msecs(212))); 7479 testST2(733_984, SysTime(DateTime(2010, 7, 31, 12, 2, 9), msecs(212))); 7480 testST2(733_985, SysTime(DateTime(2010, 8, 1, 12, 2, 9), msecs(212))); 7481 testST2(734_015, SysTime(DateTime(2010, 8, 31, 12, 2, 9), msecs(212))); 7482 testST2(734_016, SysTime(DateTime(2010, 9, 1, 12, 2, 9), msecs(212))); 7483 testST2(734_045, SysTime(DateTime(2010, 9, 30, 12, 2, 9), msecs(212))); 7484 testST2(734_046, SysTime(DateTime(2010, 10, 1, 12, 2, 9), msecs(212))); 7485 testST2(734_076, SysTime(DateTime(2010, 10, 31, 12, 2, 9), msecs(212))); 7486 testST2(734_077, SysTime(DateTime(2010, 11, 1, 12, 2, 9), msecs(212))); 7487 testST2(734_106, SysTime(DateTime(2010, 11, 30, 12, 2, 9), msecs(212))); 7488 testST2(734_107, SysTime(DateTime(2010, 12, 1, 12, 2, 9), msecs(212))); 7489 testST2(734_137, SysTime(DateTime(2010, 12, 31, 12, 2, 9), msecs(212))); 7490 7491 testST2(734_534, SysTime(DateTime(2012, 2, 1, 12, 2, 9), msecs(212))); 7492 testST2(734_561, SysTime(DateTime(2012, 2, 28, 12, 2, 9), msecs(212))); 7493 testST2(734_562, SysTime(DateTime(2012, 2, 29, 12, 2, 9), msecs(212))); 7494 testST2(734_563, SysTime(DateTime(2012, 3, 1, 12, 2, 9), msecs(212))); 7495 7496 testST2(734_534, SysTime(DateTime(2012, 2, 1, 12, 2, 9), msecs(212))); 7497 7498 testST2(734_561, SysTime(DateTime(2012, 2, 28, 12, 2, 9), msecs(212))); 7499 testST2(734_562, SysTime(DateTime(2012, 2, 29, 12, 2, 9), msecs(212))); 7500 testST2(734_563, SysTime(DateTime(2012, 3, 1, 12, 2, 9), msecs(212))); 7501 7502 // Test B.C. 7503 testST2(0, SysTime(DateTime(0, 12, 31, 12, 2, 9), msecs(212))); 7504 testST2(-1, SysTime(DateTime(0, 12, 30, 12, 2, 9), msecs(212))); 7505 testST2(-30, SysTime(DateTime(0, 12, 1, 12, 2, 9), msecs(212))); 7506 testST2(-31, SysTime(DateTime(0, 11, 30, 12, 2, 9), msecs(212))); 7507 7508 testST2(-366, SysTime(DateTime(-1, 12, 31, 12, 2, 9), msecs(212))); 7509 testST2(-367, SysTime(DateTime(-1, 12, 30, 12, 2, 9), msecs(212))); 7510 testST2(-730, SysTime(DateTime(-1, 1, 1, 12, 2, 9), msecs(212))); 7511 testST2(-731, SysTime(DateTime(-2, 12, 31, 12, 2, 9), msecs(212))); 7512 testST2(-1095, SysTime(DateTime(-2, 1, 1, 12, 2, 9), msecs(212))); 7513 testST2(-1096, SysTime(DateTime(-3, 12, 31, 12, 2, 9), msecs(212))); 7514 testST2(-1460, SysTime(DateTime(-3, 1, 1, 12, 2, 9), msecs(212))); 7515 testST2(-1461, SysTime(DateTime(-4, 12, 31, 12, 2, 9), msecs(212))); 7516 testST2(-1826, SysTime(DateTime(-4, 1, 1, 12, 2, 9), msecs(212))); 7517 testST2(-1827, SysTime(DateTime(-5, 12, 31, 12, 2, 9), msecs(212))); 7518 testST2(-2191, SysTime(DateTime(-5, 1, 1, 12, 2, 9), msecs(212))); 7519 testST2(-3652, SysTime(DateTime(-9, 1, 1, 12, 2, 9), msecs(212))); 7520 7521 testST2(-18_262, SysTime(DateTime(-49, 1, 1, 12, 2, 9), msecs(212))); 7522 testST2(-18_627, SysTime(DateTime(-50, 1, 1, 12, 2, 9), msecs(212))); 7523 testST2(-35_794, SysTime(DateTime(-97, 1, 1, 12, 2, 9), msecs(212))); 7524 testST2(-36_160, SysTime(DateTime(-99, 12, 31, 12, 2, 9), msecs(212))); 7525 testST2(-36_524, SysTime(DateTime(-99, 1, 1, 12, 2, 9), msecs(212))); 7526 testST2(-36_889, SysTime(DateTime(-100, 1, 1, 12, 2, 9), msecs(212))); 7527 testST2(-37_254, SysTime(DateTime(-101, 1, 1, 12, 2, 9), msecs(212))); 7528 testST2(-38_715, SysTime(DateTime(-105, 1, 1, 12, 2, 9), msecs(212))); 7529 testST2(-73_413, SysTime(DateTime(-200, 1, 1, 12, 2, 9), msecs(212))); 7530 testST2(-73_778, SysTime(DateTime(-201, 1, 1, 12, 2, 9), msecs(212))); 7531 testST2(-109_937, SysTime(DateTime(-300, 1, 1, 12, 2, 9), msecs(212))); 7532 testST2(-110_302, SysTime(DateTime(-301, 1, 1, 12, 2, 9), msecs(212))); 7533 testST2(-146_097, SysTime(DateTime(-400, 12, 31, 12, 2, 9), msecs(212))); 7534 testST2(-146_462, SysTime(DateTime(-400, 1, 1, 12, 2, 9), msecs(212))); 7535 testST2(-146_827, SysTime(DateTime(-401, 1, 1, 12, 2, 9), msecs(212))); 7536 testST2(-182_621, SysTime(DateTime(-499, 1, 1, 12, 2, 9), msecs(212))); 7537 testST2(-182_986, SysTime(DateTime(-500, 1, 1, 12, 2, 9), msecs(212))); 7538 testST2(-183_351, SysTime(DateTime(-501, 1, 1, 12, 2, 9), msecs(212))); 7539 testST2(-365_607, SysTime(DateTime(-1000, 1, 1, 12, 2, 9), msecs(212))); 7540 testST2(-365_972, SysTime(DateTime(-1001, 1, 1, 12, 2, 9), msecs(212))); 7541 testST2(-584_387, SysTime(DateTime(-1599, 1, 1, 12, 2, 9), msecs(212))); 7542 testST2(-584_388, SysTime(DateTime(-1600, 12, 31, 12, 2, 9), msecs(212))); 7543 testST2(-584_753, SysTime(DateTime(-1600, 1, 1, 12, 2, 9), msecs(212))); 7544 testST2(-585_118, SysTime(DateTime(-1601, 1, 1, 12, 2, 9), msecs(212))); 7545 testST2(-694_325, SysTime(DateTime(-1900, 1, 1, 12, 2, 9), msecs(212))); 7546 testST2(-694_690, SysTime(DateTime(-1901, 1, 1, 12, 2, 9), msecs(212))); 7547 testST2(-730_484, SysTime(DateTime(-1999, 1, 1, 12, 2, 9), msecs(212))); 7548 testST2(-730_485, SysTime(DateTime(-2000, 12, 31, 12, 2, 9), msecs(212))); 7549 testST2(-730_850, SysTime(DateTime(-2000, 1, 1, 12, 2, 9), msecs(212))); 7550 testST2(-731_215, SysTime(DateTime(-2001, 1, 1, 12, 2, 9), msecs(212))); 7551 7552 testST2(-734_502, SysTime(DateTime(-2010, 1, 1, 12, 2, 9), msecs(212))); 7553 testST2(-734_472, SysTime(DateTime(-2010, 1, 31, 12, 2, 9), msecs(212))); 7554 testST2(-734_471, SysTime(DateTime(-2010, 2, 1, 12, 2, 9), msecs(212))); 7555 testST2(-734_444, SysTime(DateTime(-2010, 2, 28, 12, 2, 9), msecs(212))); 7556 testST2(-734_443, SysTime(DateTime(-2010, 3, 1, 12, 2, 9), msecs(212))); 7557 testST2(-734_413, SysTime(DateTime(-2010, 3, 31, 12, 2, 9), msecs(212))); 7558 testST2(-734_412, SysTime(DateTime(-2010, 4, 1, 12, 2, 9), msecs(212))); 7559 testST2(-734_383, SysTime(DateTime(-2010, 4, 30, 12, 2, 9), msecs(212))); 7560 testST2(-734_382, SysTime(DateTime(-2010, 5, 1, 12, 2, 9), msecs(212))); 7561 testST2(-734_352, SysTime(DateTime(-2010, 5, 31, 12, 2, 9), msecs(212))); 7562 testST2(-734_351, SysTime(DateTime(-2010, 6, 1, 12, 2, 9), msecs(212))); 7563 testST2(-734_322, SysTime(DateTime(-2010, 6, 30, 12, 2, 9), msecs(212))); 7564 testST2(-734_321, SysTime(DateTime(-2010, 7, 1, 12, 2, 9), msecs(212))); 7565 testST2(-734_291, SysTime(DateTime(-2010, 7, 31, 12, 2, 9), msecs(212))); 7566 testST2(-734_290, SysTime(DateTime(-2010, 8, 1, 12, 2, 9), msecs(212))); 7567 testST2(-734_260, SysTime(DateTime(-2010, 8, 31, 12, 2, 9), msecs(212))); 7568 testST2(-734_259, SysTime(DateTime(-2010, 9, 1, 12, 2, 9), msecs(212))); 7569 testST2(-734_230, SysTime(DateTime(-2010, 9, 30, 12, 2, 9), msecs(212))); 7570 testST2(-734_229, SysTime(DateTime(-2010, 10, 1, 12, 2, 9), msecs(212))); 7571 testST2(-734_199, SysTime(DateTime(-2010, 10, 31, 12, 2, 9), msecs(212))); 7572 testST2(-734_198, SysTime(DateTime(-2010, 11, 1, 12, 2, 9), msecs(212))); 7573 testST2(-734_169, SysTime(DateTime(-2010, 11, 30, 12, 2, 9), msecs(212))); 7574 testST2(-734_168, SysTime(DateTime(-2010, 12, 1, 12, 2, 9), msecs(212))); 7575 testST2(-734_138, SysTime(DateTime(-2010, 12, 31, 12, 2, 9), msecs(212))); 7576 7577 testST2(-735_202, SysTime(DateTime(-2012, 2, 1, 12, 2, 9), msecs(212))); 7578 testST2(-735_175, SysTime(DateTime(-2012, 2, 28, 12, 2, 9), msecs(212))); 7579 testST2(-735_174, SysTime(DateTime(-2012, 2, 29, 12, 2, 9), msecs(212))); 7580 testST2(-735_173, SysTime(DateTime(-2012, 3, 1, 12, 2, 9), msecs(212))); 7581 7582 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7583 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7584 static assert(!__traits(compiles, cst.dayOfGregorianCal = 7)); 7585 static assert(!__traits(compiles, ist.dayOfGregorianCal = 7)); 7586 7587 static void testScope(scope ref SysTime st) @safe 7588 { 7589 st.dayOfGregorianCal = 42; 7590 } 7591 } 7592 7593 7594 /++ 7595 The ISO 8601 week of the year that this $(LREF SysTime) is in. 7596 7597 See_Also: 7598 $(HTTP en.wikipedia.org/wiki/ISO_week_date, ISO Week Date). 7599 +/ 7600 @property ubyte isoWeek() @safe const nothrow scope 7601 { 7602 return (cast(Date) this).isoWeek; 7603 } 7604 7605 /// 7606 @safe unittest 7607 { 7608 import core.time; 7609 import std.datetime.date : Date; 7610 7611 auto st = SysTime(Date(1999, 7, 6)); 7612 const cst = SysTime(Date(2010, 5, 1)); 7613 immutable ist = SysTime(Date(2015, 10, 10)); 7614 7615 assert(st.isoWeek == 27); 7616 assert(cst.isoWeek == 17); 7617 assert(ist.isoWeek == 41); 7618 } 7619 7620 @safe unittest 7621 { 7622 static void testScope(scope ref SysTime st) @safe 7623 { 7624 auto result = st.isoWeek; 7625 } 7626 } 7627 7628 7629 /++ 7630 $(LREF SysTime) for the last day in the month that this Date is in. 7631 The time portion of endOfMonth is always 23:59:59.9999999. 7632 +/ 7633 @property SysTime endOfMonth() @safe const nothrow scope 7634 { 7635 immutable hnsecs = adjTime; 7636 immutable days = getUnitsFromHNSecs!"days"(hnsecs); 7637 7638 auto date = Date(cast(int) days + 1).endOfMonth; 7639 auto newDays = date.dayOfGregorianCal - 1; 7640 long theTimeHNSecs; 7641 7642 if (newDays < 0) 7643 { 7644 theTimeHNSecs = -1; 7645 ++newDays; 7646 } 7647 else 7648 theTimeHNSecs = convert!("days", "hnsecs")(1) - 1; 7649 7650 immutable newDaysHNSecs = convert!("days", "hnsecs")(newDays); 7651 7652 auto retval = SysTime(this._stdTime, this._timezone); 7653 retval.adjTime = newDaysHNSecs + theTimeHNSecs; 7654 7655 return retval; 7656 } 7657 7658 /// 7659 @safe unittest 7660 { 7661 import core.time : msecs, usecs, hnsecs; 7662 import std.datetime.date : DateTime; 7663 7664 assert(SysTime(DateTime(1999, 1, 6, 0, 0, 0)).endOfMonth == 7665 SysTime(DateTime(1999, 1, 31, 23, 59, 59), hnsecs(9_999_999))); 7666 7667 assert(SysTime(DateTime(1999, 2, 7, 19, 30, 0), msecs(24)).endOfMonth == 7668 SysTime(DateTime(1999, 2, 28, 23, 59, 59), hnsecs(9_999_999))); 7669 7670 assert(SysTime(DateTime(2000, 2, 7, 5, 12, 27), usecs(5203)).endOfMonth == 7671 SysTime(DateTime(2000, 2, 29, 23, 59, 59), hnsecs(9_999_999))); 7672 7673 assert(SysTime(DateTime(2000, 6, 4, 12, 22, 9), hnsecs(12345)).endOfMonth == 7674 SysTime(DateTime(2000, 6, 30, 23, 59, 59), hnsecs(9_999_999))); 7675 } 7676 7677 @safe unittest 7678 { 7679 import core.time; 7680 // Test A.D. 7681 assert(SysTime(Date(1999, 1, 1)).endOfMonth == SysTime(DateTime(1999, 1, 31, 23, 59, 59), hnsecs(9_999_999))); 7682 assert(SysTime(Date(1999, 2, 1)).endOfMonth == SysTime(DateTime(1999, 2, 28, 23, 59, 59), hnsecs(9_999_999))); 7683 assert(SysTime(Date(2000, 2, 1)).endOfMonth == SysTime(DateTime(2000, 2, 29, 23, 59, 59), hnsecs(9_999_999))); 7684 assert(SysTime(Date(1999, 3, 1)).endOfMonth == SysTime(DateTime(1999, 3, 31, 23, 59, 59), hnsecs(9_999_999))); 7685 assert(SysTime(Date(1999, 4, 1)).endOfMonth == SysTime(DateTime(1999, 4, 30, 23, 59, 59), hnsecs(9_999_999))); 7686 assert(SysTime(Date(1999, 5, 1)).endOfMonth == SysTime(DateTime(1999, 5, 31, 23, 59, 59), hnsecs(9_999_999))); 7687 assert(SysTime(Date(1999, 6, 1)).endOfMonth == SysTime(DateTime(1999, 6, 30, 23, 59, 59), hnsecs(9_999_999))); 7688 assert(SysTime(Date(1999, 7, 1)).endOfMonth == SysTime(DateTime(1999, 7, 31, 23, 59, 59), hnsecs(9_999_999))); 7689 assert(SysTime(Date(1999, 8, 1)).endOfMonth == SysTime(DateTime(1999, 8, 31, 23, 59, 59), hnsecs(9_999_999))); 7690 assert(SysTime(Date(1999, 9, 1)).endOfMonth == SysTime(DateTime(1999, 9, 30, 23, 59, 59), hnsecs(9_999_999))); 7691 assert(SysTime(Date(1999, 10, 1)).endOfMonth == SysTime(DateTime(1999, 10, 31, 23, 59, 59), hnsecs(9_999_999))); 7692 assert(SysTime(Date(1999, 11, 1)).endOfMonth == SysTime(DateTime(1999, 11, 30, 23, 59, 59), hnsecs(9_999_999))); 7693 assert(SysTime(Date(1999, 12, 1)).endOfMonth == SysTime(DateTime(1999, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 7694 7695 // Test B.C. 7696 assert(SysTime(Date(-1999, 1, 1)).endOfMonth == SysTime(DateTime(-1999, 1, 31, 23, 59, 59), hnsecs(9_999_999))); 7697 assert(SysTime(Date(-1999, 2, 1)).endOfMonth == SysTime(DateTime(-1999, 2, 28, 23, 59, 59), hnsecs(9_999_999))); 7698 assert(SysTime(Date(-2000, 2, 1)).endOfMonth == SysTime(DateTime(-2000, 2, 29, 23, 59, 59), hnsecs(9_999_999))); 7699 assert(SysTime(Date(-1999, 3, 1)).endOfMonth == SysTime(DateTime(-1999, 3, 31, 23, 59, 59), hnsecs(9_999_999))); 7700 assert(SysTime(Date(-1999, 4, 1)).endOfMonth == SysTime(DateTime(-1999, 4, 30, 23, 59, 59), hnsecs(9_999_999))); 7701 assert(SysTime(Date(-1999, 5, 1)).endOfMonth == SysTime(DateTime(-1999, 5, 31, 23, 59, 59), hnsecs(9_999_999))); 7702 assert(SysTime(Date(-1999, 6, 1)).endOfMonth == SysTime(DateTime(-1999, 6, 30, 23, 59, 59), hnsecs(9_999_999))); 7703 assert(SysTime(Date(-1999, 7, 1)).endOfMonth == SysTime(DateTime(-1999, 7, 31, 23, 59, 59), hnsecs(9_999_999))); 7704 assert(SysTime(Date(-1999, 8, 1)).endOfMonth == SysTime(DateTime(-1999, 8, 31, 23, 59, 59), hnsecs(9_999_999))); 7705 assert(SysTime(Date(-1999, 9, 1)).endOfMonth == SysTime(DateTime(-1999, 9, 30, 23, 59, 59), hnsecs(9_999_999))); 7706 assert(SysTime(Date(-1999, 10, 1)).endOfMonth == 7707 SysTime(DateTime(-1999, 10, 31, 23, 59, 59), hnsecs(9_999_999))); 7708 assert(SysTime(Date(-1999, 11, 1)).endOfMonth == 7709 SysTime(DateTime(-1999, 11, 30, 23, 59, 59), hnsecs(9_999_999))); 7710 assert(SysTime(Date(-1999, 12, 1)).endOfMonth == 7711 SysTime(DateTime(-1999, 12, 31, 23, 59, 59), hnsecs(9_999_999))); 7712 7713 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7714 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7715 assert(cst.endOfMonth == SysTime(DateTime(1999, 7, 31, 23, 59, 59), hnsecs(9_999_999))); 7716 assert(ist.endOfMonth == SysTime(DateTime(1999, 7, 31, 23, 59, 59), hnsecs(9_999_999))); 7717 7718 static void testScope(scope ref SysTime st) @safe 7719 { 7720 auto result = st.endOfMonth; 7721 } 7722 } 7723 7724 7725 /++ 7726 The last day in the month that this $(LREF SysTime) is in. 7727 +/ 7728 @property ubyte daysInMonth() @safe const nothrow scope 7729 { 7730 return Date(dayOfGregorianCal).daysInMonth; 7731 } 7732 7733 /// 7734 @safe unittest 7735 { 7736 import core.time; 7737 import std.datetime.date : DateTime; 7738 7739 assert(SysTime(DateTime(1999, 1, 6, 0, 0, 0)).daysInMonth == 31); 7740 assert(SysTime(DateTime(1999, 2, 7, 19, 30, 0)).daysInMonth == 28); 7741 assert(SysTime(DateTime(2000, 2, 7, 5, 12, 27)).daysInMonth == 29); 7742 assert(SysTime(DateTime(2000, 6, 4, 12, 22, 9)).daysInMonth == 30); 7743 } 7744 7745 @safe unittest 7746 { 7747 import core.time; 7748 // Test A.D. 7749 assert(SysTime(DateTime(1999, 1, 1, 12, 1, 13)).daysInMonth == 31); 7750 assert(SysTime(DateTime(1999, 2, 1, 17, 13, 12)).daysInMonth == 28); 7751 assert(SysTime(DateTime(2000, 2, 1, 13, 2, 12)).daysInMonth == 29); 7752 assert(SysTime(DateTime(1999, 3, 1, 12, 13, 12)).daysInMonth == 31); 7753 assert(SysTime(DateTime(1999, 4, 1, 12, 6, 13)).daysInMonth == 30); 7754 assert(SysTime(DateTime(1999, 5, 1, 15, 13, 12)).daysInMonth == 31); 7755 assert(SysTime(DateTime(1999, 6, 1, 13, 7, 12)).daysInMonth == 30); 7756 assert(SysTime(DateTime(1999, 7, 1, 12, 13, 17)).daysInMonth == 31); 7757 assert(SysTime(DateTime(1999, 8, 1, 12, 3, 13)).daysInMonth == 31); 7758 assert(SysTime(DateTime(1999, 9, 1, 12, 13, 12)).daysInMonth == 30); 7759 assert(SysTime(DateTime(1999, 10, 1, 13, 19, 12)).daysInMonth == 31); 7760 assert(SysTime(DateTime(1999, 11, 1, 12, 13, 17)).daysInMonth == 30); 7761 assert(SysTime(DateTime(1999, 12, 1, 12, 52, 13)).daysInMonth == 31); 7762 7763 // Test B.C. 7764 assert(SysTime(DateTime(-1999, 1, 1, 12, 1, 13)).daysInMonth == 31); 7765 assert(SysTime(DateTime(-1999, 2, 1, 7, 13, 12)).daysInMonth == 28); 7766 assert(SysTime(DateTime(-2000, 2, 1, 13, 2, 12)).daysInMonth == 29); 7767 assert(SysTime(DateTime(-1999, 3, 1, 12, 13, 12)).daysInMonth == 31); 7768 assert(SysTime(DateTime(-1999, 4, 1, 12, 6, 13)).daysInMonth == 30); 7769 assert(SysTime(DateTime(-1999, 5, 1, 5, 13, 12)).daysInMonth == 31); 7770 assert(SysTime(DateTime(-1999, 6, 1, 13, 7, 12)).daysInMonth == 30); 7771 assert(SysTime(DateTime(-1999, 7, 1, 12, 13, 17)).daysInMonth == 31); 7772 assert(SysTime(DateTime(-1999, 8, 1, 12, 3, 13)).daysInMonth == 31); 7773 assert(SysTime(DateTime(-1999, 9, 1, 12, 13, 12)).daysInMonth == 30); 7774 assert(SysTime(DateTime(-1999, 10, 1, 13, 19, 12)).daysInMonth == 31); 7775 assert(SysTime(DateTime(-1999, 11, 1, 12, 13, 17)).daysInMonth == 30); 7776 assert(SysTime(DateTime(-1999, 12, 1, 12, 52, 13)).daysInMonth == 31); 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.daysInMonth == 31); 7781 assert(ist.daysInMonth == 31); 7782 7783 static void testScope(scope ref SysTime st) @safe 7784 { 7785 auto result = st.daysInMonth; 7786 } 7787 } 7788 7789 7790 /++ 7791 Whether the current year is a date in A.D. 7792 +/ 7793 @property bool isAD() @safe const nothrow scope 7794 { 7795 return adjTime >= 0; 7796 } 7797 7798 /// 7799 @safe unittest 7800 { 7801 import core.time; 7802 import std.datetime.date : DateTime; 7803 7804 assert(SysTime(DateTime(1, 1, 1, 12, 7, 0)).isAD); 7805 assert(SysTime(DateTime(2010, 12, 31, 0, 0, 0)).isAD); 7806 assert(!SysTime(DateTime(0, 12, 31, 23, 59, 59)).isAD); 7807 assert(!SysTime(DateTime(-2010, 1, 1, 2, 2, 2)).isAD); 7808 } 7809 7810 @safe unittest 7811 { 7812 import core.time; 7813 assert(SysTime(DateTime(2010, 7, 4, 12, 0, 9)).isAD); 7814 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).isAD); 7815 assert(!SysTime(DateTime(0, 12, 31, 23, 59, 59)).isAD); 7816 assert(!SysTime(DateTime(0, 1, 1, 23, 59, 59)).isAD); 7817 assert(!SysTime(DateTime(-1, 1, 1, 23 ,59 ,59)).isAD); 7818 assert(!SysTime(DateTime(-2010, 7, 4, 12, 2, 2)).isAD); 7819 7820 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7821 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7822 assert(cst.isAD); 7823 assert(ist.isAD); 7824 7825 static void testScope(scope ref SysTime st) @safe 7826 { 7827 auto result = st.isAD; 7828 } 7829 } 7830 7831 7832 /++ 7833 The $(HTTP en.wikipedia.org/wiki/Julian_day, Julian day) 7834 for this $(LREF SysTime) at the given time. For example, 7835 prior to noon, 1996-03-31 would be the Julian day number 2_450_173, so 7836 this function returns 2_450_173, while from noon onward, the Julian 7837 day number would be 2_450_174, so this function returns 2_450_174. 7838 +/ 7839 @property long julianDay() @safe const nothrow scope 7840 { 7841 immutable jd = dayOfGregorianCal + 1_721_425; 7842 return hour < 12 ? jd - 1 : jd; 7843 } 7844 7845 @safe unittest 7846 { 7847 import core.time; 7848 assert(SysTime(DateTime(-4713, 11, 24, 0, 0, 0)).julianDay == -1); 7849 assert(SysTime(DateTime(-4713, 11, 24, 12, 0, 0)).julianDay == 0); 7850 7851 assert(SysTime(DateTime(0, 12, 31, 0, 0, 0)).julianDay == 1_721_424); 7852 assert(SysTime(DateTime(0, 12, 31, 12, 0, 0)).julianDay == 1_721_425); 7853 7854 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0)).julianDay == 1_721_425); 7855 assert(SysTime(DateTime(1, 1, 1, 12, 0, 0)).julianDay == 1_721_426); 7856 7857 assert(SysTime(DateTime(1582, 10, 15, 0, 0, 0)).julianDay == 2_299_160); 7858 assert(SysTime(DateTime(1582, 10, 15, 12, 0, 0)).julianDay == 2_299_161); 7859 7860 assert(SysTime(DateTime(1858, 11, 17, 0, 0, 0)).julianDay == 2_400_000); 7861 assert(SysTime(DateTime(1858, 11, 17, 12, 0, 0)).julianDay == 2_400_001); 7862 7863 assert(SysTime(DateTime(1982, 1, 4, 0, 0, 0)).julianDay == 2_444_973); 7864 assert(SysTime(DateTime(1982, 1, 4, 12, 0, 0)).julianDay == 2_444_974); 7865 7866 assert(SysTime(DateTime(1996, 3, 31, 0, 0, 0)).julianDay == 2_450_173); 7867 assert(SysTime(DateTime(1996, 3, 31, 12, 0, 0)).julianDay == 2_450_174); 7868 7869 assert(SysTime(DateTime(2010, 8, 24, 0, 0, 0)).julianDay == 2_455_432); 7870 assert(SysTime(DateTime(2010, 8, 24, 12, 0, 0)).julianDay == 2_455_433); 7871 7872 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7873 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7874 assert(cst.julianDay == 2_451_366); 7875 assert(ist.julianDay == 2_451_366); 7876 7877 static void testScope(scope ref SysTime st) @safe 7878 { 7879 auto result = st.julianDay; 7880 } 7881 } 7882 7883 7884 /++ 7885 The modified $(HTTP en.wikipedia.org/wiki/Julian_day, Julian day) for 7886 any time on this date (since, the modified Julian day changes at 7887 midnight). 7888 +/ 7889 @property long modJulianDay() @safe const nothrow scope 7890 { 7891 return dayOfGregorianCal + 1_721_425 - 2_400_001; 7892 } 7893 7894 @safe unittest 7895 { 7896 import core.time; 7897 assert(SysTime(DateTime(1858, 11, 17, 0, 0, 0)).modJulianDay == 0); 7898 assert(SysTime(DateTime(1858, 11, 17, 12, 0, 0)).modJulianDay == 0); 7899 7900 assert(SysTime(DateTime(2010, 8, 24, 0, 0, 0)).modJulianDay == 55_432); 7901 assert(SysTime(DateTime(2010, 8, 24, 12, 0, 0)).modJulianDay == 55_432); 7902 7903 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7904 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7905 assert(cst.modJulianDay == 51_365); 7906 assert(ist.modJulianDay == 51_365); 7907 7908 static void testScope(scope ref SysTime st) @safe 7909 { 7910 auto result = st.modJulianDay; 7911 } 7912 } 7913 7914 7915 /++ 7916 Returns a $(REF Date,std,datetime,date) equivalent to this $(LREF SysTime). 7917 +/ 7918 Date opCast(T)() @safe const nothrow scope 7919 if (is(immutable T == immutable Date)) 7920 { 7921 return Date(dayOfGregorianCal); 7922 } 7923 7924 @safe unittest 7925 { 7926 import core.time; 7927 assert(cast(Date) SysTime(Date(1999, 7, 6)) == Date(1999, 7, 6)); 7928 assert(cast(Date) SysTime(Date(2000, 12, 31)) == Date(2000, 12, 31)); 7929 assert(cast(Date) SysTime(Date(2001, 1, 1)) == Date(2001, 1, 1)); 7930 7931 assert(cast(Date) SysTime(DateTime(1999, 7, 6, 12, 10, 9)) == Date(1999, 7, 6)); 7932 assert(cast(Date) SysTime(DateTime(2000, 12, 31, 13, 11, 10)) == Date(2000, 12, 31)); 7933 assert(cast(Date) SysTime(DateTime(2001, 1, 1, 14, 12, 11)) == Date(2001, 1, 1)); 7934 7935 assert(cast(Date) SysTime(Date(-1999, 7, 6)) == Date(-1999, 7, 6)); 7936 assert(cast(Date) SysTime(Date(-2000, 12, 31)) == Date(-2000, 12, 31)); 7937 assert(cast(Date) SysTime(Date(-2001, 1, 1)) == Date(-2001, 1, 1)); 7938 7939 assert(cast(Date) SysTime(DateTime(-1999, 7, 6, 12, 10, 9)) == Date(-1999, 7, 6)); 7940 assert(cast(Date) SysTime(DateTime(-2000, 12, 31, 13, 11, 10)) == Date(-2000, 12, 31)); 7941 assert(cast(Date) SysTime(DateTime(-2001, 1, 1, 14, 12, 11)) == Date(-2001, 1, 1)); 7942 7943 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7944 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 7945 assert(cast(Date) cst != Date.init); 7946 assert(cast(Date) ist != Date.init); 7947 7948 static void testScope(scope ref SysTime st) @safe 7949 { 7950 auto result = cast(Date) st; 7951 } 7952 } 7953 7954 7955 /++ 7956 Returns a $(REF DateTime,std,datetime,date) equivalent to this 7957 $(LREF SysTime). 7958 +/ 7959 DateTime opCast(T)() @safe const nothrow scope 7960 if (is(immutable T == immutable DateTime)) 7961 { 7962 try 7963 { 7964 auto hnsecs = adjTime; 7965 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 7966 7967 if (hnsecs < 0) 7968 { 7969 hnsecs += convert!("hours", "hnsecs")(24); 7970 --days; 7971 } 7972 7973 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 7974 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 7975 immutable second = getUnitsFromHNSecs!"seconds"(hnsecs); 7976 7977 return DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour, cast(int) minute, cast(int) second)); 7978 } 7979 catch (Exception e) 7980 assert(0, "Either DateTime's constructor or TimeOfDay's constructor threw."); 7981 } 7982 7983 @safe unittest 7984 { 7985 import core.time; 7986 assert(cast(DateTime) SysTime(DateTime(1, 1, 6, 7, 12, 22)) == DateTime(1, 1, 6, 7, 12, 22)); 7987 assert(cast(DateTime) SysTime(DateTime(1, 1, 6, 7, 12, 22), msecs(22)) == DateTime(1, 1, 6, 7, 12, 22)); 7988 assert(cast(DateTime) SysTime(Date(1999, 7, 6)) == DateTime(1999, 7, 6, 0, 0, 0)); 7989 assert(cast(DateTime) SysTime(Date(2000, 12, 31)) == DateTime(2000, 12, 31, 0, 0, 0)); 7990 assert(cast(DateTime) SysTime(Date(2001, 1, 1)) == DateTime(2001, 1, 1, 0, 0, 0)); 7991 7992 assert(cast(DateTime) SysTime(DateTime(1999, 7, 6, 12, 10, 9)) == DateTime(1999, 7, 6, 12, 10, 9)); 7993 assert(cast(DateTime) SysTime(DateTime(2000, 12, 31, 13, 11, 10)) == DateTime(2000, 12, 31, 13, 11, 10)); 7994 assert(cast(DateTime) SysTime(DateTime(2001, 1, 1, 14, 12, 11)) == DateTime(2001, 1, 1, 14, 12, 11)); 7995 7996 assert(cast(DateTime) SysTime(DateTime(-1, 1, 6, 7, 12, 22)) == DateTime(-1, 1, 6, 7, 12, 22)); 7997 assert(cast(DateTime) SysTime(DateTime(-1, 1, 6, 7, 12, 22), msecs(22)) == DateTime(-1, 1, 6, 7, 12, 22)); 7998 assert(cast(DateTime) SysTime(Date(-1999, 7, 6)) == DateTime(-1999, 7, 6, 0, 0, 0)); 7999 assert(cast(DateTime) SysTime(Date(-2000, 12, 31)) == DateTime(-2000, 12, 31, 0, 0, 0)); 8000 assert(cast(DateTime) SysTime(Date(-2001, 1, 1)) == DateTime(-2001, 1, 1, 0, 0, 0)); 8001 8002 assert(cast(DateTime) SysTime(DateTime(-1999, 7, 6, 12, 10, 9)) == DateTime(-1999, 7, 6, 12, 10, 9)); 8003 assert(cast(DateTime) SysTime(DateTime(-2000, 12, 31, 13, 11, 10)) == DateTime(-2000, 12, 31, 13, 11, 10)); 8004 assert(cast(DateTime) SysTime(DateTime(-2001, 1, 1, 14, 12, 11)) == DateTime(-2001, 1, 1, 14, 12, 11)); 8005 8006 assert(cast(DateTime) SysTime(DateTime(2011, 1, 13, 8, 17, 2), msecs(296), LocalTime()) == 8007 DateTime(2011, 1, 13, 8, 17, 2)); 8008 8009 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8010 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8011 assert(cast(DateTime) cst != DateTime.init); 8012 assert(cast(DateTime) ist != DateTime.init); 8013 8014 static void testScope(scope ref SysTime st) @safe 8015 { 8016 auto result = cast(DateTime) st; 8017 } 8018 } 8019 8020 8021 /++ 8022 Returns a $(REF TimeOfDay,std,datetime,date) equivalent to this 8023 $(LREF SysTime). 8024 +/ 8025 TimeOfDay opCast(T)() @safe const nothrow scope 8026 if (is(immutable T == immutable TimeOfDay)) 8027 { 8028 try 8029 { 8030 auto hnsecs = adjTime; 8031 hnsecs = removeUnitsFromHNSecs!"days"(hnsecs); 8032 8033 if (hnsecs < 0) 8034 hnsecs += convert!("hours", "hnsecs")(24); 8035 8036 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 8037 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 8038 immutable second = getUnitsFromHNSecs!"seconds"(hnsecs); 8039 8040 return TimeOfDay(cast(int) hour, cast(int) minute, cast(int) second); 8041 } 8042 catch (Exception e) 8043 assert(0, "TimeOfDay's constructor threw."); 8044 } 8045 8046 @safe unittest 8047 { 8048 import core.time; 8049 assert(cast(TimeOfDay) SysTime(Date(1999, 7, 6)) == TimeOfDay(0, 0, 0)); 8050 assert(cast(TimeOfDay) SysTime(Date(2000, 12, 31)) == TimeOfDay(0, 0, 0)); 8051 assert(cast(TimeOfDay) SysTime(Date(2001, 1, 1)) == TimeOfDay(0, 0, 0)); 8052 8053 assert(cast(TimeOfDay) SysTime(DateTime(1999, 7, 6, 12, 10, 9)) == TimeOfDay(12, 10, 9)); 8054 assert(cast(TimeOfDay) SysTime(DateTime(2000, 12, 31, 13, 11, 10)) == TimeOfDay(13, 11, 10)); 8055 assert(cast(TimeOfDay) SysTime(DateTime(2001, 1, 1, 14, 12, 11)) == TimeOfDay(14, 12, 11)); 8056 8057 assert(cast(TimeOfDay) SysTime(Date(-1999, 7, 6)) == TimeOfDay(0, 0, 0)); 8058 assert(cast(TimeOfDay) SysTime(Date(-2000, 12, 31)) == TimeOfDay(0, 0, 0)); 8059 assert(cast(TimeOfDay) SysTime(Date(-2001, 1, 1)) == TimeOfDay(0, 0, 0)); 8060 8061 assert(cast(TimeOfDay) SysTime(DateTime(-1999, 7, 6, 12, 10, 9)) == TimeOfDay(12, 10, 9)); 8062 assert(cast(TimeOfDay) SysTime(DateTime(-2000, 12, 31, 13, 11, 10)) == TimeOfDay(13, 11, 10)); 8063 assert(cast(TimeOfDay) SysTime(DateTime(-2001, 1, 1, 14, 12, 11)) == TimeOfDay(14, 12, 11)); 8064 8065 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8066 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8067 assert(cast(TimeOfDay) cst != TimeOfDay.init); 8068 assert(cast(TimeOfDay) ist != TimeOfDay.init); 8069 8070 static void testScope(scope ref SysTime st) @safe 8071 { 8072 auto result = cast(TimeOfDay) st; 8073 } 8074 } 8075 8076 8077 // Temporary hack until bug https://issues.dlang.org/show_bug.cgi?id=4867 is fixed. 8078 // This allows assignment from const(SysTime) to SysTime. 8079 // It may be a good idea to keep it though, since casting from a type to itself 8080 // should be allowed, and it doesn't work without this opCast() since opCast() 8081 // has already been defined for other types. 8082 SysTime opCast(T)() @safe const pure nothrow scope 8083 if (is(immutable T == immutable SysTime)) 8084 { 8085 return SysTime(_stdTime, _timezone); 8086 } 8087 8088 @safe unittest 8089 { 8090 static void testScope(scope ref SysTime st) @safe 8091 { 8092 auto result = cast(SysTime) st; 8093 } 8094 } 8095 8096 8097 /++ 8098 Converts this $(LREF SysTime) to a string with the format 8099 YYYYMMDDTHHMMSS.FFFFFFFTZ (where F is fractional seconds and TZ is time 8100 zone). 8101 8102 Note that the number of digits in the fractional seconds varies with the 8103 number of fractional seconds. It's a maximum of 7 (which would be 8104 hnsecs), but only has as many as are necessary to hold the correct value 8105 (so no trailing zeroes), and if there are no fractional seconds, then 8106 there is no decimal point. 8107 8108 If this $(LREF SysTime)'s time zone is 8109 $(REF LocalTime,std,datetime,timezone), then TZ is empty. If its time 8110 zone is `UTC`, then it is "Z". Otherwise, it is the offset from UTC 8111 (e.g. +0100 or -0700). Note that the offset from UTC is $(I not) enough 8112 to uniquely identify the time zone. 8113 8114 Time zone offsets will be in the form +HHMM or -HHMM. 8115 8116 $(RED Warning: 8117 Previously, toISOString did the same as $(LREF toISOExtString) and 8118 generated +HH:MM or -HH:MM for the time zone when it was not 8119 $(REF LocalTime,std,datetime,timezone) or 8120 $(REF UTC,std,datetime,timezone), which is not in conformance with 8121 ISO 8601 for the non-extended string format. This has now been 8122 fixed. However, for now, fromISOString will continue to accept the 8123 extended format for the time zone so that any code which has been 8124 writing out the result of toISOString to read in later will continue 8125 to work. The current behavior will be kept until July 2019 at which 8126 point, fromISOString will be fixed to be standards compliant.) 8127 8128 Params: 8129 writer = A `char` accepting 8130 $(REF_ALTTEXT output range, isOutputRange, std, range, primitives) 8131 Returns: 8132 A `string` when not using an output range; `void` otherwise. 8133 +/ 8134 string toISOString() @safe const nothrow scope 8135 { 8136 import std.array : appender; 8137 auto app = appender!string(); 8138 app.reserve(30); 8139 try 8140 toISOString(app); 8141 catch (Exception e) 8142 assert(0, "toISOString() threw."); 8143 return app.data; 8144 } 8145 8146 /// ditto 8147 void toISOString(W)(ref W writer) const scope 8148 if (isOutputRange!(W, char)) 8149 { 8150 immutable adjustedTime = adjTime; 8151 long hnsecs = adjustedTime; 8152 8153 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 8154 8155 if (hnsecs < 0) 8156 { 8157 hnsecs += convert!("hours", "hnsecs")(24); 8158 --days; 8159 } 8160 8161 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 8162 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 8163 immutable second = splitUnitsFromHNSecs!"seconds"(hnsecs); 8164 8165 auto dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour, 8166 cast(int) minute, cast(int) second)); 8167 8168 if (_timezone is LocalTime()) 8169 { 8170 dateTime.toISOString(writer); 8171 fracSecsToISOString(writer, cast(int) hnsecs); 8172 return; 8173 } 8174 8175 if (_timezone is UTC()) 8176 { 8177 dateTime.toISOString(writer); 8178 fracSecsToISOString(writer, cast(int) hnsecs); 8179 put(writer, 'Z'); 8180 return; 8181 } 8182 8183 immutable utcOffset = dur!"hnsecs"(adjustedTime - stdTime); 8184 8185 dateTime.toISOString(writer); 8186 fracSecsToISOString(writer, cast(int) hnsecs); 8187 SimpleTimeZone.toISOExtString(writer, utcOffset); 8188 } 8189 8190 /// 8191 @safe unittest 8192 { 8193 import core.time : msecs, hnsecs; 8194 import std.datetime.date : DateTime; 8195 8196 assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toISOString() == 8197 "20100704T070612"); 8198 8199 assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(24)).toISOString() == 8200 "19981225T021500.024"); 8201 8202 assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toISOString() == 8203 "00000105T230959"); 8204 8205 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toISOString() == 8206 "-00040105T000002.052092"); 8207 } 8208 8209 @safe unittest 8210 { 8211 import core.time; 8212 // Test A.D. 8213 assert(SysTime(DateTime.init, UTC()).toISOString() == "00010101T000000Z"); 8214 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC()).toISOString() == "00010101T000000.0000001Z"); 8215 8216 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0)).toISOString() == "00091204T000000"); 8217 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12)).toISOString() == "00991204T050612"); 8218 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59)).toISOString() == "09991204T134459"); 8219 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59)).toISOString() == "99990704T235959"); 8220 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1)).toISOString() == "+100001020T010101"); 8221 8222 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0), msecs(42)).toISOString() == "00091204T000000.042"); 8223 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12), msecs(100)).toISOString() == "00991204T050612.1"); 8224 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59), usecs(45020)).toISOString() == "09991204T134459.04502"); 8225 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOString() == "99990704T235959.0000012"); 8226 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOString() == "+100001020T010101.050789"); 8227 8228 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 8229 new immutable SimpleTimeZone(dur!"minutes"(-360))).toISOString() == 8230 "20121221T121212-06:00"); 8231 8232 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 8233 new immutable SimpleTimeZone(dur!"minutes"(420))).toISOString() == 8234 "20121221T121212+07:00"); 8235 8236 // Test B.C. 8237 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toISOString() == 8238 "00001231T235959.9999999Z"); 8239 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC()).toISOString() == "00001231T235959.0000001Z"); 8240 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), UTC()).toISOString() == "00001231T235959Z"); 8241 8242 assert(SysTime(DateTime(0, 12, 4, 0, 12, 4)).toISOString() == "00001204T001204"); 8243 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0)).toISOString() == "-00091204T000000"); 8244 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12)).toISOString() == "-00991204T050612"); 8245 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59)).toISOString() == "-09991204T134459"); 8246 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59)).toISOString() == "-99990704T235959"); 8247 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1)).toISOString() == "-100001020T010101"); 8248 8249 assert(SysTime(DateTime(0, 12, 4, 0, 0, 0), msecs(7)).toISOString() == "00001204T000000.007"); 8250 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0), msecs(42)).toISOString() == "-00091204T000000.042"); 8251 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12), msecs(100)).toISOString() == "-00991204T050612.1"); 8252 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59), usecs(45020)).toISOString() == "-09991204T134459.04502"); 8253 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOString() == "-99990704T235959.0000012"); 8254 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOString() == "-100001020T010101.050789"); 8255 8256 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8257 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8258 assert(cst.toISOString() == "19990706T123033"); 8259 assert(ist.toISOString() == "19990706T123033"); 8260 8261 static void testScope(scope ref SysTime st) @safe 8262 { 8263 auto result = st.toISOString(); 8264 } 8265 } 8266 8267 8268 8269 /++ 8270 Converts this $(LREF SysTime) to a string with the format 8271 YYYY-MM-DDTHH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ 8272 is the time zone). 8273 8274 Note that the number of digits in the fractional seconds varies with the 8275 number of fractional seconds. It's a maximum of 7 (which would be 8276 hnsecs), but only has as many as are necessary to hold the correct value 8277 (so no trailing zeroes), and if there are no fractional seconds, then 8278 there is no decimal point. 8279 8280 If this $(LREF SysTime)'s time zone is 8281 $(REF LocalTime,std,datetime,timezone), then TZ is empty. If its time 8282 zone is `UTC`, then it is "Z". Otherwise, it is the offset from UTC 8283 (e.g. +01:00 or -07:00). Note that the offset from UTC is $(I not) 8284 enough to uniquely identify the time zone. 8285 8286 Time zone offsets will be in the form +HH:MM or -HH:MM. 8287 8288 Params: 8289 writer = A `char` accepting 8290 $(REF_ALTTEXT output range, isOutputRange, std, range, primitives) 8291 Returns: 8292 A `string` when not using an output range; `void` otherwise. 8293 +/ 8294 string toISOExtString() @safe const nothrow scope 8295 { 8296 import std.array : appender; 8297 auto app = appender!string(); 8298 app.reserve(35); 8299 try 8300 toISOExtString(app); 8301 catch (Exception e) 8302 assert(0, "toISOExtString() threw."); 8303 return app.data; 8304 } 8305 8306 /// ditto 8307 void toISOExtString(W)(ref W writer) const scope 8308 if (isOutputRange!(W, char)) 8309 { 8310 immutable adjustedTime = adjTime; 8311 long hnsecs = adjustedTime; 8312 8313 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 8314 8315 if (hnsecs < 0) 8316 { 8317 hnsecs += convert!("hours", "hnsecs")(24); 8318 --days; 8319 } 8320 8321 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 8322 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 8323 immutable second = splitUnitsFromHNSecs!"seconds"(hnsecs); 8324 8325 immutable dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour, 8326 cast(int) minute, cast(int) second)); 8327 8328 if (_timezone is LocalTime()) 8329 { 8330 dateTime.toISOExtString(writer); 8331 fracSecsToISOString(writer, cast(int) hnsecs); 8332 return; 8333 } 8334 8335 if (_timezone is UTC()) 8336 { 8337 dateTime.toISOExtString(writer); 8338 fracSecsToISOString(writer, cast(int) hnsecs); 8339 put(writer, 'Z'); 8340 return; 8341 } 8342 8343 immutable utcOffset = dur!"hnsecs"(adjustedTime - stdTime); 8344 8345 dateTime.toISOExtString(writer); 8346 fracSecsToISOString(writer, cast(int) hnsecs); 8347 SimpleTimeZone.toISOExtString(writer, utcOffset); 8348 } 8349 8350 /// 8351 @safe unittest 8352 { 8353 import core.time : msecs, hnsecs; 8354 import std.datetime.date : DateTime; 8355 8356 assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toISOExtString() == 8357 "2010-07-04T07:06:12"); 8358 8359 assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(24)).toISOExtString() == 8360 "1998-12-25T02:15:00.024"); 8361 8362 assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toISOExtString() == 8363 "0000-01-05T23:09:59"); 8364 8365 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toISOExtString() == 8366 "-0004-01-05T00:00:02.052092"); 8367 } 8368 8369 @safe unittest 8370 { 8371 import core.time; 8372 // Test A.D. 8373 assert(SysTime(DateTime.init, UTC()).toISOExtString() == "0001-01-01T00:00:00Z"); 8374 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC()).toISOExtString() == 8375 "0001-01-01T00:00:00.0000001Z"); 8376 8377 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0)).toISOExtString() == "0009-12-04T00:00:00"); 8378 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12)).toISOExtString() == "0099-12-04T05:06:12"); 8379 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59)).toISOExtString() == "0999-12-04T13:44:59"); 8380 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59)).toISOExtString() == "9999-07-04T23:59:59"); 8381 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1)).toISOExtString() == "+10000-10-20T01:01:01"); 8382 8383 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0), msecs(42)).toISOExtString() == "0009-12-04T00:00:00.042"); 8384 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12), msecs(100)).toISOExtString() == "0099-12-04T05:06:12.1"); 8385 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59), usecs(45020)).toISOExtString() == "0999-12-04T13:44:59.04502"); 8386 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOExtString() == "9999-07-04T23:59:59.0000012"); 8387 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOExtString() == 8388 "+10000-10-20T01:01:01.050789"); 8389 8390 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 8391 new immutable SimpleTimeZone(dur!"minutes"(-360))).toISOExtString() == 8392 "2012-12-21T12:12:12-06:00"); 8393 8394 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 8395 new immutable SimpleTimeZone(dur!"minutes"(420))).toISOExtString() == 8396 "2012-12-21T12:12:12+07:00"); 8397 8398 // Test B.C. 8399 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toISOExtString() == 8400 "0000-12-31T23:59:59.9999999Z"); 8401 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC()).toISOExtString() == 8402 "0000-12-31T23:59:59.0000001Z"); 8403 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), UTC()).toISOExtString() == "0000-12-31T23:59:59Z"); 8404 8405 assert(SysTime(DateTime(0, 12, 4, 0, 12, 4)).toISOExtString() == "0000-12-04T00:12:04"); 8406 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0)).toISOExtString() == "-0009-12-04T00:00:00"); 8407 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12)).toISOExtString() == "-0099-12-04T05:06:12"); 8408 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59)).toISOExtString() == "-0999-12-04T13:44:59"); 8409 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59)).toISOExtString() == "-9999-07-04T23:59:59"); 8410 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1)).toISOExtString() == "-10000-10-20T01:01:01"); 8411 8412 assert(SysTime(DateTime(0, 12, 4, 0, 0, 0), msecs(7)).toISOExtString() == "0000-12-04T00:00:00.007"); 8413 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0), msecs(42)).toISOExtString() == "-0009-12-04T00:00:00.042"); 8414 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12), msecs(100)).toISOExtString() == "-0099-12-04T05:06:12.1"); 8415 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59), usecs(45020)).toISOExtString() == 8416 "-0999-12-04T13:44:59.04502"); 8417 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59), hnsecs(12)).toISOExtString() == 8418 "-9999-07-04T23:59:59.0000012"); 8419 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1), hnsecs(507890)).toISOExtString() == 8420 "-10000-10-20T01:01:01.050789"); 8421 8422 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8423 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8424 assert(cst.toISOExtString() == "1999-07-06T12:30:33"); 8425 assert(ist.toISOExtString() == "1999-07-06T12:30:33"); 8426 8427 static void testScope(scope ref SysTime st) @safe 8428 { 8429 auto result = st.toISOExtString(); 8430 } 8431 } 8432 8433 /++ 8434 Converts this $(LREF SysTime) to a string with the format 8435 YYYY-Mon-DD HH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ 8436 is the time zone). 8437 8438 Note that the number of digits in the fractional seconds varies with the 8439 number of fractional seconds. It's a maximum of 7 (which would be 8440 hnsecs), but only has as many as are necessary to hold the correct value 8441 (so no trailing zeroes), and if there are no fractional seconds, then 8442 there is no decimal point. 8443 8444 If this $(LREF SysTime)'s time zone is 8445 $(REF LocalTime,std,datetime,timezone), then TZ is empty. If its time 8446 zone is `UTC`, then it is "Z". Otherwise, it is the offset from UTC 8447 (e.g. +01:00 or -07:00). Note that the offset from UTC is $(I not) 8448 enough to uniquely identify the time zone. 8449 8450 Time zone offsets will be in the form +HH:MM or -HH:MM. 8451 8452 Params: 8453 writer = A `char` accepting 8454 $(REF_ALTTEXT output range, isOutputRange, std, range, primitives) 8455 Returns: 8456 A `string` when not using an output range; `void` otherwise. 8457 +/ 8458 string toSimpleString() @safe const nothrow scope 8459 { 8460 import std.array : appender; 8461 auto app = appender!string(); 8462 app.reserve(35); 8463 try 8464 toSimpleString(app); 8465 catch (Exception e) 8466 assert(0, "toSimpleString() threw."); 8467 return app.data; 8468 } 8469 8470 /// ditto 8471 void toSimpleString(W)(ref W writer) const scope 8472 if (isOutputRange!(W, char)) 8473 { 8474 immutable adjustedTime = adjTime; 8475 long hnsecs = adjustedTime; 8476 8477 auto days = splitUnitsFromHNSecs!"days"(hnsecs) + 1; 8478 8479 if (hnsecs < 0) 8480 { 8481 hnsecs += convert!("hours", "hnsecs")(24); 8482 --days; 8483 } 8484 8485 immutable hour = splitUnitsFromHNSecs!"hours"(hnsecs); 8486 immutable minute = splitUnitsFromHNSecs!"minutes"(hnsecs); 8487 immutable second = splitUnitsFromHNSecs!"seconds"(hnsecs); 8488 8489 immutable dateTime = DateTime(Date(cast(int) days), TimeOfDay(cast(int) hour, 8490 cast(int) minute, cast(int) second)); 8491 8492 if (_timezone is LocalTime()) 8493 { 8494 dateTime.toSimpleString(writer); 8495 fracSecsToISOString(writer, cast(int) hnsecs); 8496 return; 8497 } 8498 8499 if (_timezone is UTC()) 8500 { 8501 dateTime.toSimpleString(writer); 8502 fracSecsToISOString(writer, cast(int) hnsecs); 8503 put(writer, 'Z'); 8504 return; 8505 } 8506 8507 immutable utcOffset = dur!"hnsecs"(adjustedTime - stdTime); 8508 8509 dateTime.toSimpleString(writer); 8510 fracSecsToISOString(writer, cast(int) hnsecs); 8511 SimpleTimeZone.toISOExtString(writer, utcOffset); 8512 } 8513 8514 /// 8515 @safe unittest 8516 { 8517 import core.time : msecs, hnsecs; 8518 import std.datetime.date : DateTime; 8519 8520 assert(SysTime(DateTime(2010, 7, 4, 7, 6, 12)).toSimpleString() == 8521 "2010-Jul-04 07:06:12"); 8522 8523 assert(SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(24)).toSimpleString() == 8524 "1998-Dec-25 02:15:00.024"); 8525 8526 assert(SysTime(DateTime(0, 1, 5, 23, 9, 59)).toSimpleString() == 8527 "0000-Jan-05 23:09:59"); 8528 8529 assert(SysTime(DateTime(-4, 1, 5, 0, 0, 2), hnsecs(520_920)).toSimpleString() == 8530 "-0004-Jan-05 00:00:02.052092"); 8531 } 8532 8533 @safe unittest 8534 { 8535 import core.time; 8536 // Test A.D. 8537 assert(SysTime(DateTime.init, UTC()).toString() == "0001-Jan-01 00:00:00Z"); 8538 assert(SysTime(DateTime(1, 1, 1, 0, 0, 0), hnsecs(1), UTC()).toString() == "0001-Jan-01 00:00:00.0000001Z"); 8539 8540 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0)).toSimpleString() == "0009-Dec-04 00:00:00"); 8541 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12)).toSimpleString() == "0099-Dec-04 05:06:12"); 8542 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59)).toSimpleString() == "0999-Dec-04 13:44:59"); 8543 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59)).toSimpleString() == "9999-Jul-04 23:59:59"); 8544 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1)).toSimpleString() == "+10000-Oct-20 01:01:01"); 8545 8546 assert(SysTime(DateTime(9, 12, 4, 0, 0, 0), msecs(42)).toSimpleString() == "0009-Dec-04 00:00:00.042"); 8547 assert(SysTime(DateTime(99, 12, 4, 5, 6, 12), msecs(100)).toSimpleString() == "0099-Dec-04 05:06:12.1"); 8548 assert(SysTime(DateTime(999, 12, 4, 13, 44, 59), usecs(45020)).toSimpleString() == 8549 "0999-Dec-04 13:44:59.04502"); 8550 assert(SysTime(DateTime(9999, 7, 4, 23, 59, 59), hnsecs(12)).toSimpleString() == 8551 "9999-Jul-04 23:59:59.0000012"); 8552 assert(SysTime(DateTime(10000, 10, 20, 1, 1, 1), hnsecs(507890)).toSimpleString() == 8553 "+10000-Oct-20 01:01:01.050789"); 8554 8555 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 8556 new immutable SimpleTimeZone(dur!"minutes"(-360))).toSimpleString() == 8557 "2012-Dec-21 12:12:12-06:00"); 8558 8559 assert(SysTime(DateTime(2012, 12, 21, 12, 12, 12), 8560 new immutable SimpleTimeZone(dur!"minutes"(420))).toSimpleString() == 8561 "2012-Dec-21 12:12:12+07:00"); 8562 8563 // Test B.C. 8564 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(9_999_999), UTC()).toSimpleString() == 8565 "0000-Dec-31 23:59:59.9999999Z"); 8566 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), hnsecs(1), UTC()).toSimpleString() == 8567 "0000-Dec-31 23:59:59.0000001Z"); 8568 assert(SysTime(DateTime(0, 12, 31, 23, 59, 59), UTC()).toSimpleString() == "0000-Dec-31 23:59:59Z"); 8569 8570 assert(SysTime(DateTime(0, 12, 4, 0, 12, 4)).toSimpleString() == "0000-Dec-04 00:12:04"); 8571 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0)).toSimpleString() == "-0009-Dec-04 00:00:00"); 8572 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12)).toSimpleString() == "-0099-Dec-04 05:06:12"); 8573 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59)).toSimpleString() == "-0999-Dec-04 13:44:59"); 8574 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59)).toSimpleString() == "-9999-Jul-04 23:59:59"); 8575 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1)).toSimpleString() == "-10000-Oct-20 01:01:01"); 8576 8577 assert(SysTime(DateTime(0, 12, 4, 0, 0, 0), msecs(7)).toSimpleString() == "0000-Dec-04 00:00:00.007"); 8578 assert(SysTime(DateTime(-9, 12, 4, 0, 0, 0), msecs(42)).toSimpleString() == "-0009-Dec-04 00:00:00.042"); 8579 assert(SysTime(DateTime(-99, 12, 4, 5, 6, 12), msecs(100)).toSimpleString() == "-0099-Dec-04 05:06:12.1"); 8580 assert(SysTime(DateTime(-999, 12, 4, 13, 44, 59), usecs(45020)).toSimpleString() == 8581 "-0999-Dec-04 13:44:59.04502"); 8582 assert(SysTime(DateTime(-9999, 7, 4, 23, 59, 59), hnsecs(12)).toSimpleString() == 8583 "-9999-Jul-04 23:59:59.0000012"); 8584 assert(SysTime(DateTime(-10000, 10, 20, 1, 1, 1), hnsecs(507890)).toSimpleString() == 8585 "-10000-Oct-20 01:01:01.050789"); 8586 8587 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8588 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8589 assert(cst.toSimpleString() == "1999-Jul-06 12:30:33"); 8590 assert(ist.toSimpleString() == "1999-Jul-06 12:30:33"); 8591 8592 static void testScope(scope ref SysTime st) @safe 8593 { 8594 auto result = st.toSimpleString(); 8595 } 8596 } 8597 8598 8599 /++ 8600 Converts this $(LREF SysTime) to a string. 8601 8602 This function exists to make it easy to convert a $(LREF SysTime) to a 8603 string for code that does not care what the exact format is - just that 8604 it presents the information in a clear manner. It also makes it easy to 8605 simply convert a $(LREF SysTime) to a string when using functions such 8606 as `to!string`, `format`, or `writeln` which use toString to convert 8607 user-defined types. So, it is unlikely that much code will call 8608 toString directly. 8609 8610 The format of the string is purposefully unspecified, and code that 8611 cares about the format of the string should use `toISOString`, 8612 `toISOExtString`, `toSimpleString`, or some other custom formatting 8613 function that explicitly generates the format that the code needs. The 8614 reason is that the code is then clear about what format it's using, 8615 making it less error-prone to maintain the code and interact with other 8616 software that consumes the generated strings. It's for this same reason 8617 that $(LREF SysTime) has no `fromString` function, whereas it does have 8618 `fromISOString`, `fromISOExtString`, and `fromSimpleString`. 8619 8620 The format returned by toString may or may not change in the future. 8621 8622 Params: 8623 writer = A `char` accepting 8624 $(REF_ALTTEXT output range, isOutputRange, std, range, primitives) 8625 Returns: 8626 A `string` when not using an output range; `void` otherwise. 8627 +/ 8628 string toString() @safe const nothrow scope 8629 { 8630 return toSimpleString(); 8631 } 8632 8633 /// ditto 8634 void toString(W)(ref W writer) const scope 8635 if (isOutputRange!(W, char)) 8636 { 8637 toSimpleString(writer); 8638 } 8639 8640 @safe unittest 8641 { 8642 import core.time; 8643 auto st = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8644 const cst = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8645 immutable ist = SysTime(DateTime(1999, 7, 6, 12, 30, 33)); 8646 static assert(__traits(compiles, st.toString())); 8647 static assert(__traits(compiles, cst.toString())); 8648 static assert(__traits(compiles, ist.toString())); 8649 8650 static void testScope(scope ref SysTime st) @safe 8651 { 8652 auto result = st.toString(); 8653 } 8654 } 8655 8656 8657 /++ 8658 Creates a $(LREF SysTime) from a string with the format 8659 YYYYMMDDTHHMMSS.FFFFFFFTZ (where F is fractional seconds is the time 8660 zone). Whitespace is stripped from the given string. 8661 8662 The exact format is exactly as described in `toISOString` except that 8663 trailing zeroes are permitted - including having fractional seconds with 8664 all zeroes. However, a decimal point with nothing following it is 8665 invalid. Also, while $(LREF toISOString) will never generate a string 8666 with more than 7 digits in the fractional seconds (because that's the 8667 limit with hecto-nanosecond precision), it will allow more than 7 digits 8668 in order to read strings from other sources that have higher precision 8669 (however, any digits beyond 7 will be truncated). 8670 8671 If there is no time zone in the string, then 8672 $(REF LocalTime,std,datetime,timezone) is used. If the time zone is "Z", 8673 then `UTC` is used. Otherwise, a 8674 $(REF SimpleTimeZone,std,datetime,timezone) which corresponds to the 8675 given offset from UTC is used. To get the returned $(LREF SysTime) to be 8676 a particular time zone, pass in that time zone and the $(LREF SysTime) 8677 to be returned will be converted to that time zone (though it will still 8678 be read in as whatever time zone is in its string). 8679 8680 The accepted formats for time zone offsets are +HH, -HH, +HHMM, and 8681 -HHMM. 8682 8683 $(RED Warning: 8684 Previously, $(LREF toISOString) did the same as 8685 $(LREF toISOExtString) and generated +HH:MM or -HH:MM for the time 8686 zone when it was not $(REF LocalTime,std,datetime,timezone) or 8687 $(REF UTC,std,datetime,timezone), which is not in conformance with 8688 ISO 8601 for the non-extended string format. This has now been 8689 fixed. However, for now, fromISOString will continue to accept the 8690 extended format for the time zone so that any code which has been 8691 writing out the result of toISOString to read in later will continue 8692 to work. The current behavior will be kept until July 2019 at which 8693 point, fromISOString will be fixed to be standards compliant.) 8694 8695 Params: 8696 isoString = A string formatted in the ISO format for dates and times. 8697 tz = The time zone to convert the given time to (no 8698 conversion occurs if null). 8699 8700 Throws: 8701 $(REF DateTimeException,std,datetime,date) if the given string is 8702 not in the ISO format or if the resulting $(LREF SysTime) would not 8703 be valid. 8704 +/ 8705 static SysTime fromISOString(S)(scope const S isoString, immutable TimeZone tz = null) @safe 8706 if (isSomeString!S) 8707 { 8708 import std.algorithm.searching : startsWith, find; 8709 import std.conv : to; 8710 import std..string : strip; 8711 import std.utf : byCodeUnit; 8712 8713 auto str = strip(isoString); 8714 immutable skipFirst = str.startsWith('+', '-'); 8715 8716 auto found = (skipFirst ? str[1..$] : str).byCodeUnit.find('.', 'Z', '+', '-'); 8717 auto dateTimeStr = str[0 .. $ - found[0].length]; 8718 8719 typeof(str) fracSecStr; 8720 typeof(str) zoneStr; 8721 8722 if (found[1] != 0) 8723 { 8724 if (found[1] == 1) 8725 { 8726 auto foundTZ = found[0].find('Z', '+', '-'); 8727 8728 if (foundTZ[1] != 0) 8729 { 8730 static if (isNarrowString!S) 8731 { 8732 fracSecStr = found[0][0 .. $ - foundTZ[0].length].source; 8733 zoneStr = foundTZ[0].source; 8734 } 8735 else 8736 { 8737 fracSecStr = found[0][0 .. $ - foundTZ[0].length]; 8738 zoneStr = foundTZ[0]; 8739 } 8740 } 8741 else 8742 { 8743 static if (isNarrowString!S) 8744 fracSecStr = found[0].source; 8745 else 8746 fracSecStr = found[0]; 8747 } 8748 } 8749 else 8750 { 8751 static if (isNarrowString!S) 8752 zoneStr = found[0].source; 8753 else 8754 zoneStr = found[0]; 8755 } 8756 } 8757 8758 try 8759 { 8760 auto dateTime = DateTime.fromISOString(dateTimeStr); 8761 auto fracSec = fracSecsFromISOString(fracSecStr); 8762 8763 Rebindable!(immutable TimeZone) parsedZone; 8764 8765 if (zoneStr.empty) 8766 parsedZone = LocalTime(); 8767 else if (zoneStr == "Z") 8768 parsedZone = UTC(); 8769 else 8770 { 8771 try 8772 parsedZone = SimpleTimeZone.fromISOString(zoneStr); 8773 catch (DateTimeException dte) 8774 parsedZone = SimpleTimeZone.fromISOExtString(zoneStr); 8775 } 8776 8777 auto retval = SysTime(dateTime, fracSec, parsedZone); 8778 8779 if (tz !is null) 8780 retval.timezone = tz; 8781 8782 return retval; 8783 } 8784 catch (DateTimeException dte) 8785 throw new DateTimeException(format("Invalid ISO String: %s", isoString)); 8786 } 8787 8788 /// 8789 @safe unittest 8790 { 8791 import core.time : hours, msecs, usecs, hnsecs; 8792 import std.datetime.date : DateTime; 8793 import std.datetime.timezone : SimpleTimeZone, UTC; 8794 8795 assert(SysTime.fromISOString("20100704T070612") == 8796 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 8797 8798 assert(SysTime.fromISOString("19981225T021500.007") == 8799 SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(7))); 8800 8801 assert(SysTime.fromISOString("00000105T230959.00002") == 8802 SysTime(DateTime(0, 1, 5, 23, 9, 59), usecs(20))); 8803 8804 assert(SysTime.fromISOString("20130207T043937.000050392") == 8805 SysTime(DateTime(2013, 2, 7, 4, 39, 37), hnsecs(503))); 8806 8807 assert(SysTime.fromISOString("-00040105T000002") == 8808 SysTime(DateTime(-4, 1, 5, 0, 0, 2))); 8809 8810 assert(SysTime.fromISOString(" 20100704T070612 ") == 8811 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 8812 8813 assert(SysTime.fromISOString("20100704T070612Z") == 8814 SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC())); 8815 8816 assert(SysTime.fromISOString("20100704T070612-0800") == 8817 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 8818 new immutable SimpleTimeZone(hours(-8)))); 8819 8820 assert(SysTime.fromISOString("20100704T070612+0800") == 8821 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 8822 new immutable SimpleTimeZone(hours(8)))); 8823 } 8824 8825 @safe unittest 8826 { 8827 import core.time; 8828 foreach (str; ["", "20100704000000", "20100704 000000", "20100704t000000", 8829 "20100704T000000.", "20100704T000000.A", "20100704T000000.Z", 8830 "20100704T000000.0000000A", "20100704T000000.00000000A", 8831 "20100704T000000+", "20100704T000000-", "20100704T000000:", 8832 "20100704T000000-:", "20100704T000000+:", "20100704T000000-1:", 8833 "20100704T000000+1:", "20100704T000000+1:0", 8834 "20100704T000000-12.00", "20100704T000000+12.00", 8835 "20100704T000000-8", "20100704T000000+8", 8836 "20100704T000000-800", "20100704T000000+800", 8837 "20100704T000000-080", "20100704T000000+080", 8838 "20100704T000000-2400", "20100704T000000+2400", 8839 "20100704T000000-1260", "20100704T000000+1260", 8840 "20100704T000000.0-8", "20100704T000000.0+8", 8841 "20100704T000000.0-800", "20100704T000000.0+800", 8842 "20100704T000000.0-080", "20100704T000000.0+080", 8843 "20100704T000000.0-2400", "20100704T000000.0+2400", 8844 "20100704T000000.0-1260", "20100704T000000.0+1260", 8845 "20100704T000000-8:00", "20100704T000000+8:00", 8846 "20100704T000000-08:0", "20100704T000000+08:0", 8847 "20100704T000000-24:00", "20100704T000000+24:00", 8848 "20100704T000000-12:60", "20100704T000000+12:60", 8849 "20100704T000000.0-8:00", "20100704T000000.0+8:00", 8850 "20100704T000000.0-08:0", "20100704T000000.0+08:0", 8851 "20100704T000000.0-24:00", "20100704T000000.0+24:00", 8852 "20100704T000000.0-12:60", "20100704T000000.0+12:60", 8853 "2010-07-0400:00:00", "2010-07-04 00:00:00", 8854 "2010-07-04t00:00:00", "2010-07-04T00:00:00.", 8855 "2010-Jul-0400:00:00", "2010-Jul-04 00:00:00", "2010-Jul-04t00:00:00", 8856 "2010-Jul-04T00:00:00", "2010-Jul-04 00:00:00.", 8857 "2010-12-22T172201", "2010-Dec-22 17:22:01"]) 8858 { 8859 assertThrown!DateTimeException(SysTime.fromISOString(str), format("[%s]", str)); 8860 } 8861 8862 static void test(string str, SysTime st, size_t line = __LINE__) 8863 { 8864 if (SysTime.fromISOString(str) != st) 8865 throw new AssertError("unittest failure", __FILE__, line); 8866 } 8867 8868 test("20101222T172201", SysTime(DateTime(2010, 12, 22, 17, 22, 01))); 8869 test("19990706T123033", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8870 test("-19990706T123033", SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 8871 test("+019990706T123033", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8872 test("19990706T123033 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8873 test(" 19990706T123033", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8874 test(" 19990706T123033 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 8875 8876 test("19070707T121212.0", SysTime(DateTime(1907, 07, 07, 12, 12, 12))); 8877 test("19070707T121212.0000000", SysTime(DateTime(1907, 07, 07, 12, 12, 12))); 8878 test("19070707T121212.0000001", SysTime(DateTime(1907, 07, 07, 12, 12, 12), hnsecs(1))); 8879 test("20100704T000000.00000000", SysTime(Date(2010, 07, 04))); 8880 test("20100704T000000.00000009", SysTime(Date(2010, 07, 04))); 8881 test("20100704T000000.00000019", SysTime(DateTime(2010, 07, 04), hnsecs(1))); 8882 test("19070707T121212.000001", SysTime(DateTime(1907, 07, 07, 12, 12, 12), usecs(1))); 8883 test("19070707T121212.0000010", SysTime(DateTime(1907, 07, 07, 12, 12, 12), usecs(1))); 8884 test("19070707T121212.001", SysTime(DateTime(1907, 07, 07, 12, 12, 12), msecs(1))); 8885 test("19070707T121212.0010000", SysTime(DateTime(1907, 07, 07, 12, 12, 12), msecs(1))); 8886 8887 auto west60 = new immutable SimpleTimeZone(hours(-1)); 8888 auto west90 = new immutable SimpleTimeZone(minutes(-90)); 8889 auto west480 = new immutable SimpleTimeZone(hours(-8)); 8890 auto east60 = new immutable SimpleTimeZone(hours(1)); 8891 auto east90 = new immutable SimpleTimeZone(minutes(90)); 8892 auto east480 = new immutable SimpleTimeZone(hours(8)); 8893 8894 test("20101222T172201Z", SysTime(DateTime(2010, 12, 22, 17, 22, 01), UTC())); 8895 test("20101222T172201-0100", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west60)); 8896 test("20101222T172201-01", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west60)); 8897 test("20101222T172201-0130", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west90)); 8898 test("20101222T172201-0800", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west480)); 8899 test("20101222T172201+0100", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60)); 8900 test("20101222T172201+01", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60)); 8901 test("20101222T172201+0130", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east90)); 8902 test("20101222T172201+0800", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east480)); 8903 8904 test("20101103T065106.57159Z", SysTime(DateTime(2010, 11, 3, 6, 51, 6), hnsecs(5715900), UTC())); 8905 test("20101222T172201.23412Z", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(2_341_200), UTC())); 8906 test("20101222T172201.23112-0100", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(2_311_200), west60)); 8907 test("20101222T172201.45-01", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(4_500_000), west60)); 8908 test("20101222T172201.1-0130", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(1_000_000), west90)); 8909 test("20101222T172201.55-0800", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(5_500_000), west480)); 8910 test("20101222T172201.1234567+0100", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(1_234_567), east60)); 8911 test("20101222T172201.0+01", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60)); 8912 test("20101222T172201.0000000+0130", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east90)); 8913 test("20101222T172201.45+0800", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(4_500_000), east480)); 8914 8915 // for dstring coverage 8916 assert(SysTime.fromISOString("20101222T172201.23112-0100"d) == SysTime( 8917 DateTime(2010, 12, 22, 17, 22, 01), hnsecs(2_311_200), west60)); 8918 assert(SysTime.fromISOString("19070707T121212.0010000"d) == SysTime( 8919 DateTime(1907, 07, 07, 12, 12, 12), msecs(1))); 8920 8921 // @@@DEPRECATED_2019-07@@@ 8922 // This isn't deprecated per se, but that text will make it so that it 8923 // pops up when deprecations are moved along around July 2019. At that 8924 // time, we will update fromISOString so that it is conformant with ISO 8925 // 8601, and it will no longer accept ISO extended time zones (it does 8926 // currently because of https://issues.dlang.org/show_bug.cgi?id=15654 8927 // toISOString used to incorrectly use the ISO extended time zone format). 8928 // These tests will then start failing will need to be updated accordingly. 8929 // Also, the notes about this issue in toISOString and fromISOString's 8930 // documentation will need to be removed. 8931 test("20101222T172201-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west60)); 8932 test("20101222T172201-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west90)); 8933 test("20101222T172201-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west480)); 8934 test("20101222T172201+01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60)); 8935 test("20101222T172201+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east90)); 8936 test("20101222T172201+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east480)); 8937 8938 test("20101222T172201.23112-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(2_311_200), west60)); 8939 test("20101222T172201.1-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(1_000_000), west90)); 8940 test("20101222T172201.55-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(5_500_000), west480)); 8941 test("20101222T172201.1234567+01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(1_234_567), east60)); 8942 test("20101222T172201.0000000+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east90)); 8943 test("20101222T172201.45+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(4_500_000), east480)); 8944 8945 static void testScope(scope ref string str) @safe 8946 { 8947 auto result = SysTime.fromISOString(str); 8948 } 8949 } 8950 8951 // https://issues.dlang.org/show_bug.cgi?id=17801 8952 @safe unittest 8953 { 8954 import std.conv : to; 8955 import std.meta : AliasSeq; 8956 static foreach (C; AliasSeq!(char, wchar, dchar)) 8957 { 8958 static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) 8959 { 8960 assert(SysTime.fromISOString(to!S("20121221T141516Z")) == 8961 SysTime(DateTime(2012, 12, 21, 14, 15, 16), UTC())); 8962 } 8963 } 8964 } 8965 8966 8967 /++ 8968 Creates a $(LREF SysTime) from a string with the format 8969 YYYY-MM-DDTHH:MM:SS.FFFFFFFTZ (where F is fractional seconds is the 8970 time zone). Whitespace is stripped from the given string. 8971 8972 The exact format is exactly as described in `toISOExtString` 8973 except that trailing zeroes are permitted - including having fractional 8974 seconds with all zeroes. However, a decimal point with nothing following 8975 it is invalid. Also, while $(LREF toISOExtString) will never generate a 8976 string with more than 7 digits in the fractional seconds (because that's 8977 the limit with hecto-nanosecond precision), it will allow more than 7 8978 digits in order to read strings from other sources that have higher 8979 precision (however, any digits beyond 7 will be truncated). 8980 8981 If there is no time zone in the string, then 8982 $(REF LocalTime,std,datetime,timezone) is used. If the time zone is "Z", 8983 then `UTC` is used. Otherwise, a 8984 $(REF SimpleTimeZone,std,datetime,timezone) which corresponds to the 8985 given offset from UTC is used. To get the returned $(LREF SysTime) to be 8986 a particular time zone, pass in that time zone and the $(LREF SysTime) 8987 to be returned will be converted to that time zone (though it will still 8988 be read in as whatever time zone is in its string). 8989 8990 The accepted formats for time zone offsets are +HH, -HH, +HH:MM, and 8991 -HH:MM. 8992 8993 Params: 8994 isoExtString = A string formatted in the ISO Extended format for 8995 dates and times. 8996 tz = The time zone to convert the given time to (no 8997 conversion occurs if null). 8998 8999 Throws: 9000 $(REF DateTimeException,std,datetime,date) if the given string is 9001 not in the ISO format or if the resulting $(LREF SysTime) would not 9002 be valid. 9003 +/ 9004 static SysTime fromISOExtString(S)(scope const S isoExtString, immutable TimeZone tz = null) @safe 9005 if (isSomeString!(S)) 9006 { 9007 import std.algorithm.searching : countUntil, find; 9008 import std.conv : to; 9009 import std..string : strip, indexOf; 9010 9011 auto str = strip(isoExtString); 9012 9013 auto tIndex = str.indexOf('T'); 9014 enforce(tIndex != -1, new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString))); 9015 9016 auto found = str[tIndex + 1 .. $].find('.', 'Z', '+', '-'); 9017 auto dateTimeStr = str[0 .. $ - found[0].length]; 9018 9019 typeof(str) fracSecStr; 9020 typeof(str) zoneStr; 9021 9022 if (found[1] != 0) 9023 { 9024 if (found[1] == 1) 9025 { 9026 auto foundTZ = found[0].find('Z', '+', '-'); 9027 9028 if (foundTZ[1] != 0) 9029 { 9030 fracSecStr = found[0][0 .. $ - foundTZ[0].length]; 9031 zoneStr = foundTZ[0]; 9032 } 9033 else 9034 fracSecStr = found[0]; 9035 } 9036 else 9037 zoneStr = found[0]; 9038 } 9039 9040 try 9041 { 9042 auto dateTime = DateTime.fromISOExtString(dateTimeStr); 9043 auto fracSec = fracSecsFromISOString(fracSecStr); 9044 Rebindable!(immutable TimeZone) parsedZone; 9045 9046 if (zoneStr.empty) 9047 parsedZone = LocalTime(); 9048 else if (zoneStr == "Z") 9049 parsedZone = UTC(); 9050 else 9051 parsedZone = SimpleTimeZone.fromISOExtString(zoneStr); 9052 9053 auto retval = SysTime(dateTime, fracSec, parsedZone); 9054 9055 if (tz !is null) 9056 retval.timezone = tz; 9057 9058 return retval; 9059 } 9060 catch (DateTimeException dte) 9061 throw new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString)); 9062 } 9063 9064 /// 9065 @safe unittest 9066 { 9067 import core.time : hours, msecs, usecs, hnsecs; 9068 import std.datetime.date : DateTime; 9069 import std.datetime.timezone : SimpleTimeZone, UTC; 9070 9071 assert(SysTime.fromISOExtString("2010-07-04T07:06:12") == 9072 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 9073 9074 assert(SysTime.fromISOExtString("1998-12-25T02:15:00.007") == 9075 SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(7))); 9076 9077 assert(SysTime.fromISOExtString("0000-01-05T23:09:59.00002") == 9078 SysTime(DateTime(0, 1, 5, 23, 9, 59), usecs(20))); 9079 9080 assert(SysTime.fromISOExtString("2013-02-07T04:39:37.000050392") == 9081 SysTime(DateTime(2013, 2, 7, 4, 39, 37), hnsecs(503))); 9082 9083 assert(SysTime.fromISOExtString("-0004-01-05T00:00:02") == 9084 SysTime(DateTime(-4, 1, 5, 0, 0, 2))); 9085 9086 assert(SysTime.fromISOExtString(" 2010-07-04T07:06:12 ") == 9087 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 9088 9089 assert(SysTime.fromISOExtString("2010-07-04T07:06:12Z") == 9090 SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC())); 9091 9092 assert(SysTime.fromISOExtString("2010-07-04T07:06:12-08:00") == 9093 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 9094 new immutable SimpleTimeZone(hours(-8)))); 9095 assert(SysTime.fromISOExtString("2010-07-04T07:06:12+08:00") == 9096 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 9097 new immutable SimpleTimeZone(hours(8)))); 9098 } 9099 9100 @safe unittest 9101 { 9102 import core.time; 9103 foreach (str; ["", "20100704000000", "20100704 000000", 9104 "20100704t000000", "20100704T000000.", "20100704T000000.0", 9105 "2010-07:0400:00:00", "2010-07-04 00:00:00", 9106 "2010-07-04 00:00:00", "2010-07-04t00:00:00", 9107 "2010-07-04T00:00:00.", "2010-07-04T00:00:00.A", "2010-07-04T00:00:00.Z", 9108 "2010-07-04T00:00:00.0000000A", "2010-07-04T00:00:00.00000000A", 9109 "2010-07-04T00:00:00+", "2010-07-04T00:00:00-", 9110 "2010-07-04T00:00:00:", "2010-07-04T00:00:00-:", "2010-07-04T00:00:00+:", 9111 "2010-07-04T00:00:00-1:", "2010-07-04T00:00:00+1:", "2010-07-04T00:00:00+1:0", 9112 "2010-07-04T00:00:00-12.00", "2010-07-04T00:00:00+12.00", 9113 "2010-07-04T00:00:00-8", "2010-07-04T00:00:00+8", 9114 "20100704T000000-800", "20100704T000000+800", 9115 "20100704T000000-080", "20100704T000000+080", 9116 "20100704T000000-2400", "20100704T000000+2400", 9117 "20100704T000000-1260", "20100704T000000+1260", 9118 "20100704T000000.0-800", "20100704T000000.0+800", 9119 "20100704T000000.0-8", "20100704T000000.0+8", 9120 "20100704T000000.0-080", "20100704T000000.0+080", 9121 "20100704T000000.0-2400", "20100704T000000.0+2400", 9122 "20100704T000000.0-1260", "20100704T000000.0+1260", 9123 "2010-07-04T00:00:00-8:00", "2010-07-04T00:00:00+8:00", 9124 "2010-07-04T00:00:00-24:00", "2010-07-04T00:00:00+24:00", 9125 "2010-07-04T00:00:00-12:60", "2010-07-04T00:00:00+12:60", 9126 "2010-07-04T00:00:00.0-8:00", "2010-07-04T00:00:00.0+8:00", 9127 "2010-07-04T00:00:00.0-8", "2010-07-04T00:00:00.0+8", 9128 "2010-07-04T00:00:00.0-24:00", "2010-07-04T00:00:00.0+24:00", 9129 "2010-07-04T00:00:00.0-12:60", "2010-07-04T00:00:00.0+12:60", 9130 "2010-Jul-0400:00:00", "2010-Jul-04t00:00:00", 9131 "2010-Jul-04 00:00:00.", "2010-Jul-04 00:00:00.0", 9132 "20101222T172201", "2010-Dec-22 17:22:01"]) 9133 { 9134 assertThrown!DateTimeException(SysTime.fromISOExtString(str), format("[%s]", str)); 9135 } 9136 9137 static void test(string str, SysTime st, size_t line = __LINE__) 9138 { 9139 if (SysTime.fromISOExtString(str) != st) 9140 throw new AssertError("unittest failure", __FILE__, line); 9141 } 9142 9143 test("2010-12-22T17:22:01", SysTime(DateTime(2010, 12, 22, 17, 22, 01))); 9144 test("1999-07-06T12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9145 test("-1999-07-06T12:30:33", SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 9146 test("+01999-07-06T12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9147 test("1999-07-06T12:30:33 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9148 test(" 1999-07-06T12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9149 test(" 1999-07-06T12:30:33 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9150 9151 test("1907-07-07T12:12:12.0", SysTime(DateTime(1907, 07, 07, 12, 12, 12))); 9152 test("1907-07-07T12:12:12.0000000", SysTime(DateTime(1907, 07, 07, 12, 12, 12))); 9153 test("1907-07-07T12:12:12.0000001", SysTime(DateTime(1907, 07, 07, 12, 12, 12), hnsecs(1))); 9154 test("2010-07-04T00:00:00.00000000", SysTime(Date(2010, 07, 04))); 9155 test("2010-07-04T00:00:00.00000009", SysTime(Date(2010, 07, 04))); 9156 test("2010-07-04T00:00:00.00000019", SysTime(DateTime(2010, 07, 04), hnsecs(1))); 9157 test("1907-07-07T12:12:12.000001", SysTime(DateTime(1907, 07, 07, 12, 12, 12), usecs(1))); 9158 test("1907-07-07T12:12:12.0000010", SysTime(DateTime(1907, 07, 07, 12, 12, 12), usecs(1))); 9159 test("1907-07-07T12:12:12.001", SysTime(DateTime(1907, 07, 07, 12, 12, 12), msecs(1))); 9160 test("1907-07-07T12:12:12.0010000", SysTime(DateTime(1907, 07, 07, 12, 12, 12), msecs(1))); 9161 9162 auto west60 = new immutable SimpleTimeZone(hours(-1)); 9163 auto west90 = new immutable SimpleTimeZone(minutes(-90)); 9164 auto west480 = new immutable SimpleTimeZone(hours(-8)); 9165 auto east60 = new immutable SimpleTimeZone(hours(1)); 9166 auto east90 = new immutable SimpleTimeZone(minutes(90)); 9167 auto east480 = new immutable SimpleTimeZone(hours(8)); 9168 9169 test("2010-12-22T17:22:01Z", SysTime(DateTime(2010, 12, 22, 17, 22, 01), UTC())); 9170 test("2010-12-22T17:22:01-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west60)); 9171 test("2010-12-22T17:22:01-01", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west60)); 9172 test("2010-12-22T17:22:01-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west90)); 9173 test("2010-12-22T17:22:01-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west480)); 9174 test("2010-12-22T17:22:01+01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60)); 9175 test("2010-12-22T17:22:01+01", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60)); 9176 test("2010-12-22T17:22:01+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east90)); 9177 test("2010-12-22T17:22:01+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east480)); 9178 9179 test("2010-11-03T06:51:06.57159Z", SysTime(DateTime(2010, 11, 3, 6, 51, 6), hnsecs(5715900), UTC())); 9180 test("2010-12-22T17:22:01.23412Z", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(2_341_200), UTC())); 9181 test("2010-12-22T17:22:01.23112-01:00", 9182 SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(2_311_200), west60)); 9183 test("2010-12-22T17:22:01.45-01", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(4_500_000), west60)); 9184 test("2010-12-22T17:22:01.1-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(1_000_000), west90)); 9185 test("2010-12-22T17:22:01.55-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(5_500_000), west480)); 9186 test("2010-12-22T17:22:01.1234567+01:00", 9187 SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(1_234_567), east60)); 9188 test("2010-12-22T17:22:01.0+01", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60)); 9189 test("2010-12-22T17:22:01.0000000+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east90)); 9190 test("2010-12-22T17:22:01.45+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(4_500_000), east480)); 9191 9192 static void testScope(scope ref string str) @safe 9193 { 9194 auto result = SysTime.fromISOExtString(str); 9195 } 9196 } 9197 9198 // https://issues.dlang.org/show_bug.cgi?id=17801 9199 @safe unittest 9200 { 9201 import core.time; 9202 import std.conv : to; 9203 import std.meta : AliasSeq; 9204 static foreach (C; AliasSeq!(char, wchar, dchar)) 9205 { 9206 static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) 9207 { 9208 assert(SysTime.fromISOExtString(to!S("2012-12-21T14:15:16Z")) == 9209 SysTime(DateTime(2012, 12, 21, 14, 15, 16), UTC())); 9210 } 9211 } 9212 } 9213 9214 9215 /++ 9216 Creates a $(LREF SysTime) from a string with the format 9217 YYYY-MM-DD HH:MM:SS.FFFFFFFTZ (where F is fractional seconds is the 9218 time zone). Whitespace is stripped from the given string. 9219 9220 The exact format is exactly as described in `toSimpleString` except 9221 that trailing zeroes are permitted - including having fractional seconds 9222 with all zeroes. However, a decimal point with nothing following it is 9223 invalid. Also, while $(LREF toSimpleString) will never generate a 9224 string with more than 7 digits in the fractional seconds (because that's 9225 the limit with hecto-nanosecond precision), it will allow more than 7 9226 digits in order to read strings from other sources that have higher 9227 precision (however, any digits beyond 7 will be truncated). 9228 9229 If there is no time zone in the string, then 9230 $(REF LocalTime,std,datetime,timezone) is used. If the time zone is "Z", 9231 then `UTC` is used. Otherwise, a 9232 $(REF SimpleTimeZone,std,datetime,timezone) which corresponds to the 9233 given offset from UTC is used. To get the returned $(LREF SysTime) to be 9234 a particular time zone, pass in that time zone and the $(LREF SysTime) 9235 to be returned will be converted to that time zone (though it will still 9236 be read in as whatever time zone is in its string). 9237 9238 The accepted formats for time zone offsets are +HH, -HH, +HH:MM, and 9239 -HH:MM. 9240 9241 Params: 9242 simpleString = A string formatted in the way that 9243 `toSimpleString` formats dates and times. 9244 tz = The time zone to convert the given time to (no 9245 conversion occurs if null). 9246 9247 Throws: 9248 $(REF DateTimeException,std,datetime,date) if the given string is 9249 not in the ISO format or if the resulting $(LREF SysTime) would not 9250 be valid. 9251 +/ 9252 static SysTime fromSimpleString(S)(scope const S simpleString, immutable TimeZone tz = null) @safe 9253 if (isSomeString!(S)) 9254 { 9255 import std.algorithm.searching : find; 9256 import std.conv : to; 9257 import std..string : strip, indexOf; 9258 9259 auto str = strip(simpleString); 9260 9261 auto spaceIndex = str.indexOf(' '); 9262 enforce(spaceIndex != -1, new DateTimeException(format("Invalid Simple String: %s", simpleString))); 9263 9264 auto found = str[spaceIndex + 1 .. $].find('.', 'Z', '+', '-'); 9265 auto dateTimeStr = str[0 .. $ - found[0].length]; 9266 9267 typeof(str) fracSecStr; 9268 typeof(str) zoneStr; 9269 9270 if (found[1] != 0) 9271 { 9272 if (found[1] == 1) 9273 { 9274 auto foundTZ = found[0].find('Z', '+', '-'); 9275 9276 if (foundTZ[1] != 0) 9277 { 9278 fracSecStr = found[0][0 .. $ - foundTZ[0].length]; 9279 zoneStr = foundTZ[0]; 9280 } 9281 else 9282 fracSecStr = found[0]; 9283 } 9284 else 9285 zoneStr = found[0]; 9286 } 9287 9288 try 9289 { 9290 auto dateTime = DateTime.fromSimpleString(dateTimeStr); 9291 auto fracSec = fracSecsFromISOString(fracSecStr); 9292 Rebindable!(immutable TimeZone) parsedZone; 9293 9294 if (zoneStr.empty) 9295 parsedZone = LocalTime(); 9296 else if (zoneStr == "Z") 9297 parsedZone = UTC(); 9298 else 9299 parsedZone = SimpleTimeZone.fromISOExtString(zoneStr); 9300 9301 auto retval = SysTime(dateTime, fracSec, parsedZone); 9302 9303 if (tz !is null) 9304 retval.timezone = tz; 9305 9306 return retval; 9307 } 9308 catch (DateTimeException dte) 9309 throw new DateTimeException(format("Invalid Simple String: %s", simpleString)); 9310 } 9311 9312 /// 9313 @safe unittest 9314 { 9315 import core.time : hours, msecs, usecs, hnsecs; 9316 import std.datetime.date : DateTime; 9317 import std.datetime.timezone : SimpleTimeZone, UTC; 9318 9319 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12") == 9320 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 9321 9322 assert(SysTime.fromSimpleString("1998-Dec-25 02:15:00.007") == 9323 SysTime(DateTime(1998, 12, 25, 2, 15, 0), msecs(7))); 9324 9325 assert(SysTime.fromSimpleString("0000-Jan-05 23:09:59.00002") == 9326 SysTime(DateTime(0, 1, 5, 23, 9, 59), usecs(20))); 9327 9328 assert(SysTime.fromSimpleString("2013-Feb-07 04:39:37.000050392") == 9329 SysTime(DateTime(2013, 2, 7, 4, 39, 37), hnsecs(503))); 9330 9331 assert(SysTime.fromSimpleString("-0004-Jan-05 00:00:02") == 9332 SysTime(DateTime(-4, 1, 5, 0, 0, 2))); 9333 9334 assert(SysTime.fromSimpleString(" 2010-Jul-04 07:06:12 ") == 9335 SysTime(DateTime(2010, 7, 4, 7, 6, 12))); 9336 9337 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12Z") == 9338 SysTime(DateTime(2010, 7, 4, 7, 6, 12), UTC())); 9339 9340 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12-08:00") == 9341 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 9342 new immutable SimpleTimeZone(hours(-8)))); 9343 9344 assert(SysTime.fromSimpleString("2010-Jul-04 07:06:12+08:00") == 9345 SysTime(DateTime(2010, 7, 4, 7, 6, 12), 9346 new immutable SimpleTimeZone(hours(8)))); 9347 } 9348 9349 @safe unittest 9350 { 9351 import core.time; 9352 foreach (str; ["", "20100704000000", "20100704 000000", 9353 "20100704t000000", "20100704T000000.", "20100704T000000.0", 9354 "2010-07-0400:00:00", "2010-07-04 00:00:00", "2010-07-04t00:00:00", 9355 "2010-07-04T00:00:00.", "2010-07-04T00:00:00.0", 9356 "2010-Jul-0400:00:00", "2010-Jul-04t00:00:00", "2010-Jul-04T00:00:00", 9357 "2010-Jul-04 00:00:00.", "2010-Jul-04 00:00:00.A", "2010-Jul-04 00:00:00.Z", 9358 "2010-Jul-04 00:00:00.0000000A", "2010-Jul-04 00:00:00.00000000A", 9359 "2010-Jul-04 00:00:00+", "2010-Jul-04 00:00:00-", 9360 "2010-Jul-04 00:00:00:", "2010-Jul-04 00:00:00-:", 9361 "2010-Jul-04 00:00:00+:", "2010-Jul-04 00:00:00-1:", 9362 "2010-Jul-04 00:00:00+1:", "2010-Jul-04 00:00:00+1:0", 9363 "2010-Jul-04 00:00:00-12.00", "2010-Jul-04 00:00:00+12.00", 9364 "2010-Jul-04 00:00:00-8", "2010-Jul-04 00:00:00+8", 9365 "20100704T000000-800", "20100704T000000+800", 9366 "20100704T000000-080", "20100704T000000+080", 9367 "20100704T000000-2400", "20100704T000000+2400", 9368 "20100704T000000-1260", "20100704T000000+1260", 9369 "20100704T000000.0-800", "20100704T000000.0+800", 9370 "20100704T000000.0-8", "20100704T000000.0+8", 9371 "20100704T000000.0-080", "20100704T000000.0+080", 9372 "20100704T000000.0-2400", "20100704T000000.0+2400", 9373 "20100704T000000.0-1260", "20100704T000000.0+1260", 9374 "2010-Jul-04 00:00:00-8:00", "2010-Jul-04 00:00:00+8:00", 9375 "2010-Jul-04 00:00:00-08:0", "2010-Jul-04 00:00:00+08:0", 9376 "2010-Jul-04 00:00:00-24:00", "2010-Jul-04 00:00:00+24:00", 9377 "2010-Jul-04 00:00:00-12:60", "2010-Jul-04 00:00:00+24:60", 9378 "2010-Jul-04 00:00:00.0-8:00", "2010-Jul-04 00:00:00+8:00", 9379 "2010-Jul-04 00:00:00.0-8", "2010-Jul-04 00:00:00.0+8", 9380 "2010-Jul-04 00:00:00.0-08:0", "2010-Jul-04 00:00:00.0+08:0", 9381 "2010-Jul-04 00:00:00.0-24:00", "2010-Jul-04 00:00:00.0+24:00", 9382 "2010-Jul-04 00:00:00.0-12:60", "2010-Jul-04 00:00:00.0+24:60", 9383 "20101222T172201", "2010-12-22T172201"]) 9384 { 9385 assertThrown!DateTimeException(SysTime.fromSimpleString(str), format("[%s]", str)); 9386 } 9387 9388 static void test(string str, SysTime st, size_t line = __LINE__) 9389 { 9390 if (SysTime.fromSimpleString(str) != st) 9391 throw new AssertError("unittest failure", __FILE__, line); 9392 } 9393 9394 test("2010-Dec-22 17:22:01", SysTime(DateTime(2010, 12, 22, 17, 22, 01))); 9395 test("1999-Jul-06 12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9396 test("-1999-Jul-06 12:30:33", SysTime(DateTime(-1999, 7, 6, 12, 30, 33))); 9397 test("+01999-Jul-06 12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9398 test("1999-Jul-06 12:30:33 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9399 test(" 1999-Jul-06 12:30:33", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9400 test(" 1999-Jul-06 12:30:33 ", SysTime(DateTime(1999, 7, 6, 12, 30, 33))); 9401 9402 test("1907-Jul-07 12:12:12.0", SysTime(DateTime(1907, 07, 07, 12, 12, 12))); 9403 test("1907-Jul-07 12:12:12.0000000", SysTime(DateTime(1907, 07, 07, 12, 12, 12))); 9404 test("2010-Jul-04 00:00:00.00000000", SysTime(Date(2010, 07, 04))); 9405 test("2010-Jul-04 00:00:00.00000009", SysTime(Date(2010, 07, 04))); 9406 test("2010-Jul-04 00:00:00.00000019", SysTime(DateTime(2010, 07, 04), hnsecs(1))); 9407 test("1907-Jul-07 12:12:12.0000001", SysTime(DateTime(1907, 07, 07, 12, 12, 12), hnsecs(1))); 9408 test("1907-Jul-07 12:12:12.000001", SysTime(DateTime(1907, 07, 07, 12, 12, 12), usecs(1))); 9409 test("1907-Jul-07 12:12:12.0000010", SysTime(DateTime(1907, 07, 07, 12, 12, 12), usecs(1))); 9410 test("1907-Jul-07 12:12:12.001", SysTime(DateTime(1907, 07, 07, 12, 12, 12), msecs(1))); 9411 test("1907-Jul-07 12:12:12.0010000", SysTime(DateTime(1907, 07, 07, 12, 12, 12), msecs(1))); 9412 9413 auto west60 = new immutable SimpleTimeZone(hours(-1)); 9414 auto west90 = new immutable SimpleTimeZone(minutes(-90)); 9415 auto west480 = new immutable SimpleTimeZone(hours(-8)); 9416 auto east60 = new immutable SimpleTimeZone(hours(1)); 9417 auto east90 = new immutable SimpleTimeZone(minutes(90)); 9418 auto east480 = new immutable SimpleTimeZone(hours(8)); 9419 9420 test("2010-Dec-22 17:22:01Z", SysTime(DateTime(2010, 12, 22, 17, 22, 01), UTC())); 9421 test("2010-Dec-22 17:22:01-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west60)); 9422 test("2010-Dec-22 17:22:01-01", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west60)); 9423 test("2010-Dec-22 17:22:01-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west90)); 9424 test("2010-Dec-22 17:22:01-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west480)); 9425 test("2010-Dec-22 17:22:01+01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60)); 9426 test("2010-Dec-22 17:22:01+01", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60)); 9427 test("2010-Dec-22 17:22:01+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east90)); 9428 test("2010-Dec-22 17:22:01+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east480)); 9429 9430 test("2010-Nov-03 06:51:06.57159Z", SysTime(DateTime(2010, 11, 3, 6, 51, 6), hnsecs(5715900), UTC())); 9431 test("2010-Dec-22 17:22:01.23412Z", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(2_341_200), UTC())); 9432 test("2010-Dec-22 17:22:01.23112-01:00", 9433 SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(2_311_200), west60)); 9434 test("2010-Dec-22 17:22:01.45-01", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(4_500_000), west60)); 9435 test("2010-Dec-22 17:22:01.1-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(1_000_000), west90)); 9436 test("2010-Dec-22 17:22:01.55-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(5_500_000), west480)); 9437 test("2010-Dec-22 17:22:01.1234567+01:00", 9438 SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(1_234_567), east60)); 9439 test("2010-Dec-22 17:22:01.0+01", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east60)); 9440 test("2010-Dec-22 17:22:01.0000000+01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east90)); 9441 test("2010-Dec-22 17:22:01.45+08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(4_500_000), east480)); 9442 9443 static void testScope(scope ref string str) @safe 9444 { 9445 auto result = SysTime.fromSimpleString(str); 9446 } 9447 } 9448 9449 // https://issues.dlang.org/show_bug.cgi?id=17801 9450 @safe unittest 9451 { 9452 import core.time; 9453 import std.conv : to; 9454 import std.meta : AliasSeq; 9455 static foreach (C; AliasSeq!(char, wchar, dchar)) 9456 { 9457 static foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) 9458 { 9459 assert(SysTime.fromSimpleString(to!S("2012-Dec-21 14:15:16Z")) == 9460 SysTime(DateTime(2012, 12, 21, 14, 15, 16), UTC())); 9461 } 9462 } 9463 } 9464 9465 9466 /++ 9467 Returns the $(LREF SysTime) farthest in the past which is representable 9468 by $(LREF SysTime). 9469 9470 The $(LREF SysTime) which is returned is in UTC. 9471 +/ 9472 @property static SysTime min() @safe pure nothrow 9473 { 9474 return SysTime(long.min, UTC()); 9475 } 9476 9477 @safe unittest 9478 { 9479 assert(SysTime.min.year < 0); 9480 assert(SysTime.min < SysTime.max); 9481 } 9482 9483 9484 /++ 9485 Returns the $(LREF SysTime) farthest in the future which is representable 9486 by $(LREF SysTime). 9487 9488 The $(LREF SysTime) which is returned is in UTC. 9489 +/ 9490 @property static SysTime max() @safe pure nothrow 9491 { 9492 return SysTime(long.max, UTC()); 9493 } 9494 9495 @safe unittest 9496 { 9497 assert(SysTime.max.year > 0); 9498 assert(SysTime.max > SysTime.min); 9499 } 9500 9501 9502 private: 9503 9504 /+ 9505 Returns `stdTime` converted to $(LREF SysTime)'s time zone. 9506 +/ 9507 @property long adjTime() @safe const nothrow scope 9508 { 9509 return _timezone.utcToTZ(_stdTime); 9510 } 9511 9512 9513 /+ 9514 Converts the given hnsecs from $(LREF SysTime)'s time zone to std time. 9515 +/ 9516 @property void adjTime(long adjTime) @safe nothrow scope 9517 { 9518 _stdTime = _timezone.tzToUTC(adjTime); 9519 } 9520 9521 9522 final class InitTimeZone : TimeZone 9523 { 9524 public: 9525 9526 static immutable(InitTimeZone) opCall() @safe pure nothrow @nogc { return _initTimeZone; } 9527 9528 @property override bool hasDST() @safe const nothrow @nogc { return false; } 9529 9530 override bool dstInEffect(long stdTime) @safe const nothrow @nogc { return false; } 9531 9532 override long utcToTZ(long stdTime) @safe const nothrow @nogc { return 0; } 9533 9534 override long tzToUTC(long adjTime) @safe const nothrow @nogc { return 0; } 9535 9536 override Duration utcOffsetAt(long stdTime) @safe const nothrow @nogc { return Duration.zero; } 9537 9538 private: 9539 9540 this() @safe immutable pure 9541 { 9542 super("SysTime.init's timezone", "SysTime.init's timezone", "SysTime.init's timezone"); 9543 } 9544 9545 static immutable InitTimeZone _initTimeZone = new immutable(InitTimeZone); 9546 } 9547 9548 // https://issues.dlang.org/show_bug.cgi?id=17732 9549 @safe unittest 9550 { 9551 assert(SysTime.init.timezone is InitTimeZone()); 9552 assert(SysTime.init.toISOString() == "00010101T000000+00:00"); 9553 assert(SysTime.init.toISOExtString() == "0001-01-01T00:00:00+00:00"); 9554 assert(SysTime.init.toSimpleString() == "0001-Jan-01 00:00:00+00:00"); 9555 assert(SysTime.init.toString() == "0001-Jan-01 00:00:00+00:00"); 9556 } 9557 9558 // Assigning a value to _timezone in SysTime.init currently doesn't work due 9559 // to https://issues.dlang.org/show_bug.cgi?id=17740. So, to hack around 9560 // that problem, these accessors have been added so that we can insert a 9561 // runtime check for null and then use InitTimeZone for SysTime.init (which 9562 // which is the only case where _timezone would be null). This thus fixes 9563 // the problem with segfaulting when using SysTime.init but at the cost of 9564 // what should be an unnecessary null check. Once 17740 has finally been 9565 // fixed, _timezoneStorage should be removed, these accessors should be 9566 // removed, and the _timezone variable declaration should be restored. 9567 pragma(inline, true) @property _timezone() @safe const pure nothrow @nogc 9568 { 9569 return _timezoneStorage is null ? InitTimeZone() : _timezoneStorage; 9570 } 9571 9572 pragma(inline, true) @property void _timezone(immutable TimeZone tz) @safe pure nothrow @nogc scope 9573 { 9574 _timezoneStorage = tz; 9575 } 9576 9577 9578 long _stdTime; 9579 Rebindable!(immutable TimeZone) _timezoneStorage; 9580 //Rebindable!(immutable TimeZone) _timezone = InitTimeZone(); 9581 } 9582 9583 /// 9584 @safe unittest 9585 { 9586 import core.time : days, hours, seconds; 9587 import std.datetime.date : DateTime; 9588 import std.datetime.timezone : SimpleTimeZone, UTC; 9589 9590 // make a specific point in time in the UTC timezone 9591 auto st = SysTime(DateTime(2018, 1, 1, 10, 30, 0), UTC()); 9592 // make a specific point in time in the New York timezone 9593 auto ny = SysTime( 9594 DateTime(2018, 1, 1, 10, 30, 0), 9595 new immutable SimpleTimeZone(-5.hours, "America/New_York") 9596 ); 9597 9598 // ISO standard time strings 9599 assert(st.toISOString() == "20180101T103000Z"); 9600 assert(st.toISOExtString() == "2018-01-01T10:30:00Z"); 9601 9602 // add two days and 30 seconds 9603 st += 2.days + 30.seconds; 9604 assert(st.toISOExtString() == "2018-01-03T10:30:30Z"); 9605 } 9606 9607 9608 /++ 9609 Converts from unix time (which uses midnight, January 1st, 1970 UTC as its 9610 epoch and seconds as its units) to "std time" (which uses midnight, 9611 January 1st, 1 A.D. UTC and hnsecs as its units). 9612 9613 The C standard does not specify the representation of time_t, so it is 9614 implementation defined. On POSIX systems, unix time is equivalent to 9615 time_t, but that's not necessarily true on other systems (e.g. it is 9616 not true for the Digital Mars C runtime). So, be careful when using unix 9617 time with C functions on non-POSIX systems. 9618 9619 "std time"'s epoch is based on the Proleptic Gregorian Calendar per ISO 9620 8601 and is what $(LREF SysTime) uses internally. However, holding the time 9621 as an integer in hnsecs since that epoch technically isn't actually part of 9622 the standard, much as it's based on it, so the name "std time" isn't 9623 particularly good, but there isn't an official name for it. C# uses "ticks" 9624 for the same thing, but they aren't actually clock ticks, and the term 9625 "ticks" $(I is) used for actual clock ticks for $(REF MonoTime, core,time), 9626 so it didn't make sense to use the term ticks here. So, for better or worse, 9627 std.datetime uses the term "std time" for this. 9628 9629 Params: 9630 unixTime = The unix time to convert. 9631 9632 See_Also: 9633 SysTime.fromUnixTime 9634 +/ 9635 long unixTimeToStdTime(long unixTime) @safe pure nothrow @nogc 9636 { 9637 return 621_355_968_000_000_000L + convert!("seconds", "hnsecs")(unixTime); 9638 } 9639 9640 /// 9641 @safe unittest 9642 { 9643 import std.datetime.date : DateTime; 9644 import std.datetime.timezone : UTC; 9645 9646 // Midnight, January 1st, 1970 9647 assert(unixTimeToStdTime(0) == 621_355_968_000_000_000L); 9648 assert(SysTime(unixTimeToStdTime(0)) == 9649 SysTime(DateTime(1970, 1, 1), UTC())); 9650 9651 assert(unixTimeToStdTime(int.max) == 642_830_804_470_000_000L); 9652 assert(SysTime(unixTimeToStdTime(int.max)) == 9653 SysTime(DateTime(2038, 1, 19, 3, 14, 07), UTC())); 9654 9655 assert(unixTimeToStdTime(-127_127) == 621_354_696_730_000_000L); 9656 assert(SysTime(unixTimeToStdTime(-127_127)) == 9657 SysTime(DateTime(1969, 12, 30, 12, 41, 13), UTC())); 9658 } 9659 9660 @safe unittest 9661 { 9662 // Midnight, January 2nd, 1970 9663 assert(unixTimeToStdTime(86_400) == 621_355_968_000_000_000L + 864_000_000_000L); 9664 // Midnight, December 31st, 1969 9665 assert(unixTimeToStdTime(-86_400) == 621_355_968_000_000_000L - 864_000_000_000L); 9666 9667 assert(unixTimeToStdTime(0) == (Date(1970, 1, 1) - Date(1, 1, 1)).total!"hnsecs"); 9668 assert(unixTimeToStdTime(0) == (DateTime(1970, 1, 1) - DateTime(1, 1, 1)).total!"hnsecs"); 9669 9670 foreach (dt; [DateTime(2010, 11, 1, 19, 5, 22), DateTime(1952, 7, 6, 2, 17, 9)]) 9671 assert(unixTimeToStdTime((dt - DateTime(1970, 1, 1)).total!"seconds") == (dt - DateTime.init).total!"hnsecs"); 9672 } 9673 9674 9675 /++ 9676 Converts std time (which uses midnight, January 1st, 1 A.D. UTC as its epoch 9677 and hnsecs as its units) to unix time (which uses midnight, January 1st, 9678 1970 UTC as its epoch and seconds as its units). 9679 9680 The C standard does not specify the representation of time_t, so it is 9681 implementation defined. On POSIX systems, unix time is equivalent to 9682 time_t, but that's not necessarily true on other systems (e.g. it is 9683 not true for the Digital Mars C runtime). So, be careful when using unix 9684 time with C functions on non-POSIX systems. 9685 9686 "std time"'s epoch is based on the Proleptic Gregorian Calendar per ISO 9687 8601 and is what $(LREF SysTime) uses internally. However, holding the time 9688 as an integer in hnescs since that epoch technically isn't actually part of 9689 the standard, much as it's based on it, so the name "std time" isn't 9690 particularly good, but there isn't an official name for it. C# uses "ticks" 9691 for the same thing, but they aren't actually clock ticks, and the term 9692 "ticks" $(I is) used for actual clock ticks for $(REF MonoTime, core,time), 9693 so it didn't make sense to use the term ticks here. So, for better or worse, 9694 std.datetime uses the term "std time" for this. 9695 9696 By default, the return type is time_t (which is normally an alias for 9697 int on 32-bit systems and long on 64-bit systems), but if a different 9698 size is required than either int or long can be passed as a template 9699 argument to get the desired size. 9700 9701 If the return type is int, and the result can't fit in an int, then the 9702 closest value that can be held in 32 bits will be used (so `int.max` 9703 if it goes over and `int.min` if it goes under). However, no attempt 9704 is made to deal with integer overflow if the return type is long. 9705 9706 Params: 9707 T = The return type (int or long). It defaults to time_t, which is 9708 normally 32 bits on a 32-bit system and 64 bits on a 64-bit 9709 system. 9710 stdTime = The std time to convert. 9711 9712 Returns: 9713 A signed integer representing the unix time which is equivalent to 9714 the given std time. 9715 9716 See_Also: 9717 SysTime.toUnixTime 9718 +/ 9719 T stdTimeToUnixTime(T = time_t)(long stdTime) @safe pure nothrow 9720 if (is(T == int) || is(T == long)) 9721 { 9722 immutable unixTime = convert!("hnsecs", "seconds")(stdTime - 621_355_968_000_000_000L); 9723 9724 static assert(is(time_t == int) || is(time_t == long), 9725 "Currently, std.datetime only supports systems where time_t is int or long"); 9726 9727 static if (is(T == long)) 9728 return unixTime; 9729 else static if (is(T == int)) 9730 { 9731 if (unixTime > int.max) 9732 return int.max; 9733 return unixTime < int.min ? int.min : cast(int) unixTime; 9734 } 9735 else 9736 static assert(0, "Bug in template constraint. Only int and long allowed."); 9737 } 9738 9739 /// 9740 @safe unittest 9741 { 9742 // Midnight, January 1st, 1970 UTC 9743 assert(stdTimeToUnixTime(621_355_968_000_000_000L) == 0); 9744 9745 // 2038-01-19 03:14:07 UTC 9746 assert(stdTimeToUnixTime(642_830_804_470_000_000L) == int.max); 9747 } 9748 9749 @safe unittest 9750 { 9751 enum unixEpochAsStdTime = (Date(1970, 1, 1) - Date.init).total!"hnsecs"; 9752 9753 assert(stdTimeToUnixTime(unixEpochAsStdTime) == 0); // Midnight, January 1st, 1970 9754 assert(stdTimeToUnixTime(unixEpochAsStdTime + 864_000_000_000L) == 86_400); // Midnight, January 2nd, 1970 9755 assert(stdTimeToUnixTime(unixEpochAsStdTime - 864_000_000_000L) == -86_400); // Midnight, December 31st, 1969 9756 9757 assert(stdTimeToUnixTime((Date(1970, 1, 1) - Date(1, 1, 1)).total!"hnsecs") == 0); 9758 assert(stdTimeToUnixTime((DateTime(1970, 1, 1) - DateTime(1, 1, 1)).total!"hnsecs") == 0); 9759 9760 foreach (dt; [DateTime(2010, 11, 1, 19, 5, 22), DateTime(1952, 7, 6, 2, 17, 9)]) 9761 assert(stdTimeToUnixTime((dt - DateTime.init).total!"hnsecs") == (dt - DateTime(1970, 1, 1)).total!"seconds"); 9762 9763 enum max = convert!("seconds", "hnsecs")(int.max); 9764 enum min = convert!("seconds", "hnsecs")(int.min); 9765 enum one = convert!("seconds", "hnsecs")(1); 9766 9767 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + max) == int.max); 9768 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + max) == int.max); 9769 9770 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + max + one) == int.max + 1L); 9771 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + max + one) == int.max); 9772 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + max + 9_999_999) == int.max); 9773 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + max + 9_999_999) == int.max); 9774 9775 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + min) == int.min); 9776 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + min) == int.min); 9777 9778 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + min - one) == int.min - 1L); 9779 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + min - one) == int.min); 9780 assert(stdTimeToUnixTime!long(unixEpochAsStdTime + min - 9_999_999) == int.min); 9781 assert(stdTimeToUnixTime!int(unixEpochAsStdTime + min - 9_999_999) == int.min); 9782 } 9783 9784 9785 version (StdDdoc) 9786 { 9787 version (Windows) 9788 {} 9789 else 9790 { 9791 alias SYSTEMTIME = void*; 9792 alias FILETIME = void*; 9793 } 9794 9795 /++ 9796 $(BLUE This function is Windows-Only.) 9797 9798 Converts a `SYSTEMTIME` struct to a $(LREF SysTime). 9799 9800 Params: 9801 st = The `SYSTEMTIME` struct to convert. 9802 tz = The time zone that the time in the `SYSTEMTIME` struct is 9803 assumed to be (if the `SYSTEMTIME` was supplied by a Windows 9804 system call, the `SYSTEMTIME` will either be in local time 9805 or UTC, depending on the call). 9806 9807 Throws: 9808 $(REF DateTimeException,std,datetime,date) if the given 9809 `SYSTEMTIME` will not fit in a $(LREF SysTime), which is highly 9810 unlikely to happen given that `SysTime.max` is in 29,228 A.D. and 9811 the maximum `SYSTEMTIME` is in 30,827 A.D. 9812 +/ 9813 SysTime SYSTEMTIMEToSysTime(const scope SYSTEMTIME* st, immutable TimeZone tz = LocalTime()) @safe; 9814 9815 9816 /++ 9817 $(BLUE This function is Windows-Only.) 9818 9819 Converts a $(LREF SysTime) to a `SYSTEMTIME` struct. 9820 9821 The `SYSTEMTIME` which is returned will be set using the given 9822 $(LREF SysTime)'s time zone, so to get the `SYSTEMTIME` in 9823 UTC, set the $(LREF SysTime)'s time zone to UTC. 9824 9825 Params: 9826 sysTime = The $(LREF SysTime) to convert. 9827 9828 Throws: 9829 $(REF DateTimeException,std,datetime,date) if the given 9830 $(LREF SysTime) will not fit in a `SYSTEMTIME`. This will only 9831 happen if the $(LREF SysTime)'s date is prior to 1601 A.D. 9832 +/ 9833 SYSTEMTIME SysTimeToSYSTEMTIME(scope SysTime sysTime) @safe; 9834 9835 9836 /++ 9837 $(BLUE This function is Windows-Only.) 9838 9839 Converts a `FILETIME` struct to the number of hnsecs since midnight, 9840 January 1st, 1 A.D. 9841 9842 Params: 9843 ft = The `FILETIME` struct to convert. 9844 9845 Throws: 9846 $(REF DateTimeException,std,datetime,date) if the given 9847 `FILETIME` cannot be represented as the return value. 9848 +/ 9849 long FILETIMEToStdTime(scope const FILETIME* ft) @safe; 9850 9851 9852 /++ 9853 $(BLUE This function is Windows-Only.) 9854 9855 Converts a `FILETIME` struct to a $(LREF SysTime). 9856 9857 Params: 9858 ft = The `FILETIME` struct to convert. 9859 tz = The time zone that the $(LREF SysTime) will be in 9860 (`FILETIME`s are in UTC). 9861 9862 Throws: 9863 $(REF DateTimeException,std,datetime,date) if the given 9864 `FILETIME` will not fit in a $(LREF SysTime). 9865 +/ 9866 SysTime FILETIMEToSysTime(scope const FILETIME* ft, immutable TimeZone tz = LocalTime()) @safe; 9867 9868 9869 /++ 9870 $(BLUE This function is Windows-Only.) 9871 9872 Converts a number of hnsecs since midnight, January 1st, 1 A.D. to a 9873 `FILETIME` struct. 9874 9875 Params: 9876 stdTime = The number of hnsecs since midnight, January 1st, 1 A.D. 9877 UTC. 9878 9879 Throws: 9880 $(REF DateTimeException,std,datetime,date) if the given value will 9881 not fit in a `FILETIME`. 9882 +/ 9883 FILETIME stdTimeToFILETIME(long stdTime) @safe; 9884 9885 9886 /++ 9887 $(BLUE This function is Windows-Only.) 9888 9889 Converts a $(LREF SysTime) to a `FILETIME` struct. 9890 9891 `FILETIME`s are always in UTC. 9892 9893 Params: 9894 sysTime = The $(LREF SysTime) to convert. 9895 9896 Throws: 9897 $(REF DateTimeException,std,datetime,date) if the given 9898 $(LREF SysTime) will not fit in a `FILETIME`. 9899 +/ 9900 FILETIME SysTimeToFILETIME(scope SysTime sysTime) @safe; 9901 } 9902 else version (Windows) 9903 { 9904 SysTime SYSTEMTIMEToSysTime(const scope SYSTEMTIME* st, immutable TimeZone tz = LocalTime()) @safe 9905 { 9906 const max = SysTime.max; 9907 9908 static void throwLaterThanMax() 9909 { 9910 throw new DateTimeException("The given SYSTEMTIME is for a date greater than SysTime.max."); 9911 } 9912 9913 if (st.wYear > max.year) 9914 throwLaterThanMax(); 9915 else if (st.wYear == max.year) 9916 { 9917 if (st.wMonth > max.month) 9918 throwLaterThanMax(); 9919 else if (st.wMonth == max.month) 9920 { 9921 if (st.wDay > max.day) 9922 throwLaterThanMax(); 9923 else if (st.wDay == max.day) 9924 { 9925 if (st.wHour > max.hour) 9926 throwLaterThanMax(); 9927 else if (st.wHour == max.hour) 9928 { 9929 if (st.wMinute > max.minute) 9930 throwLaterThanMax(); 9931 else if (st.wMinute == max.minute) 9932 { 9933 if (st.wSecond > max.second) 9934 throwLaterThanMax(); 9935 else if (st.wSecond == max.second) 9936 { 9937 if (st.wMilliseconds > max.fracSecs.total!"msecs") 9938 throwLaterThanMax(); 9939 } 9940 } 9941 } 9942 } 9943 } 9944 } 9945 9946 auto dt = DateTime(st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); 9947 9948 import core.time : msecs; 9949 return SysTime(dt, msecs(st.wMilliseconds), tz); 9950 } 9951 9952 @system unittest 9953 { 9954 auto sysTime = Clock.currTime(UTC()); 9955 SYSTEMTIME st = void; 9956 GetSystemTime(&st); 9957 auto converted = SYSTEMTIMEToSysTime(&st, UTC()); 9958 import core.time : abs; 9959 assert(abs((converted - sysTime)) <= dur!"seconds"(2)); 9960 9961 static void testScope(scope SYSTEMTIME* st) @safe 9962 { 9963 auto result = SYSTEMTIMEToSysTime(st); 9964 } 9965 } 9966 9967 9968 SYSTEMTIME SysTimeToSYSTEMTIME(scope SysTime sysTime) @safe 9969 { 9970 immutable dt = cast(DateTime) sysTime; 9971 9972 if (dt.year < 1601) 9973 throw new DateTimeException("SYSTEMTIME cannot hold dates prior to the year 1601."); 9974 9975 SYSTEMTIME st; 9976 9977 st.wYear = dt.year; 9978 st.wMonth = dt.month; 9979 st.wDayOfWeek = dt.dayOfWeek; 9980 st.wDay = dt.day; 9981 st.wHour = dt.hour; 9982 st.wMinute = dt.minute; 9983 st.wSecond = dt.second; 9984 st.wMilliseconds = cast(ushort) sysTime.fracSecs.total!"msecs"; 9985 9986 return st; 9987 } 9988 9989 @system unittest 9990 { 9991 SYSTEMTIME st = void; 9992 GetSystemTime(&st); 9993 auto sysTime = SYSTEMTIMEToSysTime(&st, UTC()); 9994 9995 SYSTEMTIME result = SysTimeToSYSTEMTIME(sysTime); 9996 9997 assert(st.wYear == result.wYear); 9998 assert(st.wMonth == result.wMonth); 9999 assert(st.wDayOfWeek == result.wDayOfWeek); 10000 assert(st.wDay == result.wDay); 10001 assert(st.wHour == result.wHour); 10002 assert(st.wMinute == result.wMinute); 10003 assert(st.wSecond == result.wSecond); 10004 assert(st.wMilliseconds == result.wMilliseconds); 10005 10006 static void testScope(scope ref SysTime st) @safe 10007 { 10008 auto result = SysTimeToSYSTEMTIME(st); 10009 } 10010 } 10011 10012 private enum hnsecsFrom1601 = 504_911_232_000_000_000L; 10013 10014 long FILETIMEToStdTime(scope const FILETIME* ft) @safe 10015 { 10016 ULARGE_INTEGER ul; 10017 ul.HighPart = ft.dwHighDateTime; 10018 ul.LowPart = ft.dwLowDateTime; 10019 ulong tempHNSecs = ul.QuadPart; 10020 10021 if (tempHNSecs > long.max - hnsecsFrom1601) 10022 throw new DateTimeException("The given FILETIME cannot be represented as a stdTime value."); 10023 10024 return cast(long) tempHNSecs + hnsecsFrom1601; 10025 } 10026 10027 SysTime FILETIMEToSysTime(scope const FILETIME* ft, immutable TimeZone tz = LocalTime()) @safe 10028 { 10029 auto sysTime = SysTime(FILETIMEToStdTime(ft), UTC()); 10030 sysTime.timezone = tz; 10031 return sysTime; 10032 } 10033 10034 @system unittest 10035 { 10036 auto sysTime = Clock.currTime(UTC()); 10037 SYSTEMTIME st = void; 10038 GetSystemTime(&st); 10039 10040 FILETIME ft = void; 10041 SystemTimeToFileTime(&st, &ft); 10042 10043 auto converted = FILETIMEToSysTime(&ft); 10044 10045 import core.time : abs; 10046 assert(abs((converted - sysTime)) <= dur!"seconds"(2)); 10047 10048 static void testScope(scope FILETIME* ft) @safe 10049 { 10050 auto result = FILETIMEToSysTime(ft); 10051 } 10052 } 10053 10054 10055 FILETIME stdTimeToFILETIME(long stdTime) @safe 10056 { 10057 if (stdTime < hnsecsFrom1601) 10058 throw new DateTimeException("The given stdTime value cannot be represented as a FILETIME."); 10059 10060 ULARGE_INTEGER ul; 10061 ul.QuadPart = cast(ulong) stdTime - hnsecsFrom1601; 10062 10063 FILETIME ft; 10064 ft.dwHighDateTime = ul.HighPart; 10065 ft.dwLowDateTime = ul.LowPart; 10066 10067 return ft; 10068 } 10069 10070 FILETIME SysTimeToFILETIME(scope SysTime sysTime) @safe 10071 { 10072 return stdTimeToFILETIME(sysTime.stdTime); 10073 } 10074 10075 @system unittest 10076 { 10077 SYSTEMTIME st = void; 10078 GetSystemTime(&st); 10079 10080 FILETIME ft = void; 10081 SystemTimeToFileTime(&st, &ft); 10082 auto sysTime = FILETIMEToSysTime(&ft, UTC()); 10083 10084 FILETIME result = SysTimeToFILETIME(sysTime); 10085 10086 assert(ft.dwLowDateTime == result.dwLowDateTime); 10087 assert(ft.dwHighDateTime == result.dwHighDateTime); 10088 10089 static void testScope(scope ref SysTime st) @safe 10090 { 10091 auto result = SysTimeToFILETIME(st); 10092 } 10093 } 10094 } 10095 10096 10097 /++ 10098 Type representing the DOS file date/time format. 10099 +/ 10100 alias DosFileTime = uint; 10101 10102 /++ 10103 Converts from DOS file date/time to $(LREF SysTime). 10104 10105 Params: 10106 dft = The DOS file time to convert. 10107 tz = The time zone which the DOS file time is assumed to be in. 10108 10109 Throws: 10110 $(REF DateTimeException,std,datetime,date) if the `DosFileTime` is 10111 invalid. 10112 +/ 10113 SysTime DosFileTimeToSysTime(DosFileTime dft, immutable TimeZone tz = LocalTime()) @safe 10114 { 10115 uint dt = cast(uint) dft; 10116 10117 if (dt == 0) 10118 throw new DateTimeException("Invalid DosFileTime."); 10119 10120 int year = ((dt >> 25) & 0x7F) + 1980; 10121 int month = ((dt >> 21) & 0x0F); // 1 .. 12 10122 int dayOfMonth = ((dt >> 16) & 0x1F); // 1 .. 31 10123 int hour = (dt >> 11) & 0x1F; // 0 .. 23 10124 int minute = (dt >> 5) & 0x3F; // 0 .. 59 10125 int second = (dt << 1) & 0x3E; // 0 .. 58 (in 2 second increments) 10126 10127 try 10128 return SysTime(DateTime(year, month, dayOfMonth, hour, minute, second), tz); 10129 catch (DateTimeException dte) 10130 throw new DateTimeException("Invalid DosFileTime", __FILE__, __LINE__, dte); 10131 } 10132 10133 /// 10134 @safe unittest 10135 { 10136 import std.datetime.date : DateTime; 10137 10138 assert(DosFileTimeToSysTime(0b00000000001000010000000000000000) == SysTime(DateTime(1980, 1, 1, 0, 0, 0))); 10139 assert(DosFileTimeToSysTime(0b11111111100111111011111101111101) == SysTime(DateTime(2107, 12, 31, 23, 59, 58))); 10140 assert(DosFileTimeToSysTime(0x3E3F8456) == SysTime(DateTime(2011, 1, 31, 16, 34, 44))); 10141 } 10142 10143 @safe unittest 10144 { 10145 static void testScope(scope ref DosFileTime dft) @safe 10146 { 10147 auto result = DosFileTimeToSysTime(dft); 10148 } 10149 } 10150 10151 10152 /++ 10153 Converts from $(LREF SysTime) to DOS file date/time. 10154 10155 Params: 10156 sysTime = The $(LREF SysTime) to convert. 10157 10158 Throws: 10159 $(REF DateTimeException,std,datetime,date) if the given 10160 $(LREF SysTime) cannot be converted to a `DosFileTime`. 10161 +/ 10162 DosFileTime SysTimeToDosFileTime(scope SysTime sysTime) @safe 10163 { 10164 auto dateTime = cast(DateTime) sysTime; 10165 10166 if (dateTime.year < 1980) 10167 throw new DateTimeException("DOS File Times cannot hold dates prior to 1980."); 10168 10169 if (dateTime.year > 2107) 10170 throw new DateTimeException("DOS File Times cannot hold dates past 2107."); 10171 10172 uint retval = 0; 10173 retval = (dateTime.year - 1980) << 25; 10174 retval |= (dateTime.month & 0x0F) << 21; 10175 retval |= (dateTime.day & 0x1F) << 16; 10176 retval |= (dateTime.hour & 0x1F) << 11; 10177 retval |= (dateTime.minute & 0x3F) << 5; 10178 retval |= (dateTime.second >> 1) & 0x1F; 10179 10180 return cast(DosFileTime) retval; 10181 } 10182 10183 /// 10184 @safe unittest 10185 { 10186 import std.datetime.date : DateTime; 10187 10188 assert(SysTimeToDosFileTime(SysTime(DateTime(1980, 1, 1, 0, 0, 0))) == 0b00000000001000010000000000000000); 10189 assert(SysTimeToDosFileTime(SysTime(DateTime(2107, 12, 31, 23, 59, 58))) == 0b11111111100111111011111101111101); 10190 assert(SysTimeToDosFileTime(SysTime(DateTime(2011, 1, 31, 16, 34, 44))) == 0x3E3F8456); 10191 } 10192 10193 @safe unittest 10194 { 10195 static void testScope(scope ref SysTime st) @safe 10196 { 10197 auto result = SysTimeToDosFileTime(st); 10198 } 10199 } 10200 10201 10202 /++ 10203 The given array of `char` or random-access range of `char` or 10204 `ubyte` is expected to be in the format specified in 10205 $(HTTP tools.ietf.org/html/rfc5322, RFC 5322) section 3.3 with the 10206 grammar rule $(I date-time). It is the date-time format commonly used in 10207 internet messages such as e-mail and HTTP. The corresponding 10208 $(LREF SysTime) will be returned. 10209 10210 RFC 822 was the original spec (hence the function's name), whereas RFC 5322 10211 is the current spec. 10212 10213 The day of the week is ignored beyond verifying that it's a valid day of the 10214 week, as the day of the week can be inferred from the date. It is not 10215 checked whether the given day of the week matches the actual day of the week 10216 of the given date (though it is technically invalid per the spec if the 10217 day of the week doesn't match the actual day of the week of the given date). 10218 10219 If the time zone is `"-0000"` (or considered to be equivalent to 10220 `"-0000"` by section 4.3 of the spec), a 10221 $(REF SimpleTimeZone,std,datetime,timezone) with a utc offset of `0` is 10222 used rather than $(REF UTC,std,datetime,timezone), whereas `"+0000"` uses 10223 $(REF UTC,std,datetime,timezone). 10224 10225 Note that because $(LREF SysTime) does not currently support having a second 10226 value of 60 (as is sometimes done for leap seconds), if the date-time value 10227 does have a value of 60 for the seconds, it is treated as 59. 10228 10229 The one area in which this function violates RFC 5322 is that it accepts 10230 `"\n"` in folding whitespace in the place of `"\r\n"`, because the 10231 HTTP spec requires it. 10232 10233 Throws: 10234 $(REF DateTimeException,std,datetime,date) if the given string doesn't 10235 follow the grammar for a date-time field or if the resulting 10236 $(LREF SysTime) is invalid. 10237 +/ 10238 SysTime parseRFC822DateTime()(scope const char[] value) @safe 10239 { 10240 import std..string : representation; 10241 return parseRFC822DateTime(value.representation); 10242 } 10243 10244 /++ Ditto +/ 10245 SysTime parseRFC822DateTime(R)(scope R value) 10246 if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && 10247 (is(immutable ElementType!R == immutable char) || is(immutable ElementType!R == immutable ubyte))) 10248 { 10249 import std.algorithm.searching : find, all; 10250 import std.ascii : isDigit, isAlpha, isPrintable; 10251 import std.conv : to; 10252 import std.functional : not; 10253 import std..string : capitalize, format; 10254 import std.traits : EnumMembers, isArray; 10255 import std.typecons : Rebindable; 10256 10257 void stripAndCheckLen(R valueBefore, size_t minLen, size_t line = __LINE__) 10258 { 10259 value = _stripCFWS(valueBefore); 10260 if (value.length < minLen) 10261 throw new DateTimeException("date-time value too short", __FILE__, line); 10262 } 10263 stripAndCheckLen(value, "7Dec1200:00A".length); 10264 10265 static if (isArray!R && (is(ElementEncodingType!R == char) || is(ElementEncodingType!R == ubyte))) 10266 { 10267 static string sliceAsString(R str) @trusted 10268 { 10269 return cast(string) str; 10270 } 10271 } 10272 else 10273 { 10274 char[4] temp; 10275 char[] sliceAsString(R str) @trusted 10276 { 10277 size_t i = 0; 10278 foreach (c; str) 10279 temp[i++] = cast(char) c; 10280 return temp[0 .. str.length]; 10281 } 10282 } 10283 10284 // day-of-week 10285 if (isAlpha(value[0])) 10286 { 10287 auto dowStr = sliceAsString(value[0 .. 3]); 10288 switch (dowStr) 10289 { 10290 foreach (dow; EnumMembers!DayOfWeek) 10291 { 10292 enum dowC = capitalize(to!string(dow)); 10293 case dowC: 10294 goto afterDoW; 10295 } 10296 default: throw new DateTimeException(format("Invalid day-of-week: %s", dowStr)); 10297 } 10298 afterDoW: stripAndCheckLen(value[3 .. value.length], ",7Dec1200:00A".length); 10299 if (value[0] != ',') 10300 throw new DateTimeException("day-of-week missing comma"); 10301 stripAndCheckLen(value[1 .. value.length], "7Dec1200:00A".length); 10302 } 10303 10304 // day 10305 immutable digits = isDigit(value[1]) ? 2 : 1; 10306 immutable day = _convDigits!short(value[0 .. digits]); 10307 if (day == -1) 10308 throw new DateTimeException("Invalid day"); 10309 stripAndCheckLen(value[digits .. value.length], "Dec1200:00A".length); 10310 10311 // month 10312 Month month; 10313 { 10314 auto monStr = sliceAsString(value[0 .. 3]); 10315 switch (monStr) 10316 { 10317 foreach (mon; EnumMembers!Month) 10318 { 10319 enum monC = capitalize(to!string(mon)); 10320 case monC: 10321 { 10322 month = mon; 10323 goto afterMon; 10324 } 10325 } 10326 default: throw new DateTimeException(format("Invalid month: %s", monStr)); 10327 } 10328 afterMon: stripAndCheckLen(value[3 .. value.length], "1200:00A".length); 10329 } 10330 10331 // year 10332 auto found = value[2 .. value.length].find!(not!(std.ascii.isDigit))(); 10333 size_t yearLen = value.length - found.length; 10334 if (found.length == 0) 10335 throw new DateTimeException("Invalid year"); 10336 if (found[0] == ':') 10337 yearLen -= 2; 10338 auto year = _convDigits!short(value[0 .. yearLen]); 10339 if (year < 1900) 10340 { 10341 if (year == -1) 10342 throw new DateTimeException("Invalid year"); 10343 if (yearLen < 4) 10344 { 10345 if (yearLen == 3) 10346 year += 1900; 10347 else if (yearLen == 2) 10348 year += year < 50 ? 2000 : 1900; 10349 else 10350 throw new DateTimeException("Invalid year. Too few digits."); 10351 } 10352 else 10353 throw new DateTimeException("Invalid year. Cannot be earlier than 1900."); 10354 } 10355 stripAndCheckLen(value[yearLen .. value.length], "00:00A".length); 10356 10357 // hour 10358 immutable hour = _convDigits!short(value[0 .. 2]); 10359 stripAndCheckLen(value[2 .. value.length], ":00A".length); 10360 if (value[0] != ':') 10361 throw new DateTimeException("Invalid hour"); 10362 stripAndCheckLen(value[1 .. value.length], "00A".length); 10363 10364 // minute 10365 immutable minute = _convDigits!short(value[0 .. 2]); 10366 stripAndCheckLen(value[2 .. value.length], "A".length); 10367 10368 // second 10369 short second; 10370 if (value[0] == ':') 10371 { 10372 stripAndCheckLen(value[1 .. value.length], "00A".length); 10373 second = _convDigits!short(value[0 .. 2]); 10374 // this is just if/until SysTime is sorted out to fully support leap seconds 10375 if (second == 60) 10376 second = 59; 10377 stripAndCheckLen(value[2 .. value.length], "A".length); 10378 } 10379 10380 immutable(TimeZone) parseTZ(int sign) 10381 { 10382 if (value.length < 5) 10383 throw new DateTimeException("Invalid timezone"); 10384 immutable zoneHours = _convDigits!short(value[1 .. 3]); 10385 immutable zoneMinutes = _convDigits!short(value[3 .. 5]); 10386 if (zoneHours == -1 || zoneMinutes == -1 || zoneMinutes > 59) 10387 throw new DateTimeException("Invalid timezone"); 10388 value = value[5 .. value.length]; 10389 immutable utcOffset = (dur!"hours"(zoneHours) + dur!"minutes"(zoneMinutes)) * sign; 10390 if (utcOffset == Duration.zero) 10391 { 10392 return sign == 1 ? cast(immutable(TimeZone))UTC() 10393 : cast(immutable(TimeZone))new immutable SimpleTimeZone(Duration.zero); 10394 } 10395 return new immutable(SimpleTimeZone)(utcOffset); 10396 } 10397 10398 // zone 10399 Rebindable!(immutable TimeZone) tz; 10400 if (value[0] == '-') 10401 tz = parseTZ(-1); 10402 else if (value[0] == '+') 10403 tz = parseTZ(1); 10404 else 10405 { 10406 // obs-zone 10407 immutable tzLen = value.length - find(value, ' ', '\t', '(')[0].length; 10408 switch (sliceAsString(value[0 .. tzLen <= 4 ? tzLen : 4])) 10409 { 10410 case "UT": case "GMT": tz = UTC(); break; 10411 case "EST": tz = new immutable SimpleTimeZone(dur!"hours"(-5)); break; 10412 case "EDT": tz = new immutable SimpleTimeZone(dur!"hours"(-4)); break; 10413 case "CST": tz = new immutable SimpleTimeZone(dur!"hours"(-6)); break; 10414 case "CDT": tz = new immutable SimpleTimeZone(dur!"hours"(-5)); break; 10415 case "MST": tz = new immutable SimpleTimeZone(dur!"hours"(-7)); break; 10416 case "MDT": tz = new immutable SimpleTimeZone(dur!"hours"(-6)); break; 10417 case "PST": tz = new immutable SimpleTimeZone(dur!"hours"(-8)); break; 10418 case "PDT": tz = new immutable SimpleTimeZone(dur!"hours"(-7)); break; 10419 case "J": case "j": throw new DateTimeException("Invalid timezone"); 10420 default: 10421 { 10422 if (all!(std.ascii.isAlpha)(value[0 .. tzLen])) 10423 { 10424 tz = new immutable SimpleTimeZone(Duration.zero); 10425 break; 10426 } 10427 throw new DateTimeException("Invalid timezone"); 10428 } 10429 } 10430 value = value[tzLen .. value.length]; 10431 } 10432 10433 // This is kind of arbitrary. Technically, nothing but CFWS is legal past 10434 // the end of the timezone, but we don't want to be picky about that in a 10435 // function that's just parsing rather than validating. So, the idea here is 10436 // that if the next character is printable (and not part of CFWS), then it 10437 // might be part of the timezone and thus affect what the timezone was 10438 // supposed to be, so we'll throw, but otherwise, we'll just ignore it. 10439 if (!value.empty && isPrintable(value[0]) && value[0] != ' ' && value[0] != '(') 10440 throw new DateTimeException("Invalid timezone"); 10441 10442 try 10443 return SysTime(DateTime(year, month, day, hour, minute, second), tz); 10444 catch (DateTimeException dte) 10445 throw new DateTimeException("date-time format is correct, but the resulting SysTime is invalid.", dte); 10446 } 10447 10448 /// 10449 @safe unittest 10450 { 10451 import core.time : hours; 10452 import std.datetime.date : DateTime, DateTimeException; 10453 import std.datetime.timezone : SimpleTimeZone, UTC; 10454 import std.exception : assertThrown; 10455 10456 auto tz = new immutable SimpleTimeZone(hours(-8)); 10457 assert(parseRFC822DateTime("Sat, 6 Jan 1990 12:14:19 -0800") == 10458 SysTime(DateTime(1990, 1, 6, 12, 14, 19), tz)); 10459 10460 assert(parseRFC822DateTime("9 Jul 2002 13:11 +0000") == 10461 SysTime(DateTime(2002, 7, 9, 13, 11, 0), UTC())); 10462 10463 auto badStr = "29 Feb 2001 12:17:16 +0200"; 10464 assertThrown!DateTimeException(parseRFC822DateTime(badStr)); 10465 } 10466 10467 version (StdUnittest) private void testParse822(alias cr)(string str, SysTime expected, size_t line = __LINE__) 10468 { 10469 import std.format : format; 10470 auto value = cr(str); 10471 auto result = parseRFC822DateTime(value); 10472 if (result != expected) 10473 throw new AssertError(format("wrong result. expected [%s], actual[%s]", expected, result), __FILE__, line); 10474 } 10475 10476 version (StdUnittest) private void testBadParse822(alias cr)(string str, size_t line = __LINE__) 10477 { 10478 try 10479 parseRFC822DateTime(cr(str)); 10480 catch (DateTimeException) 10481 return; 10482 throw new AssertError("No DateTimeException was thrown", __FILE__, line); 10483 } 10484 10485 @system unittest 10486 { 10487 import core.time; 10488 import std.algorithm.iteration : filter, map; 10489 import std.algorithm.searching : canFind; 10490 import std.array : array; 10491 import std.ascii : letters; 10492 import std.format : format; 10493 import std.meta : AliasSeq; 10494 import std.range : chain, iota, take; 10495 import std.stdio : writefln, writeln; 10496 import std..string : representation; 10497 10498 static struct Rand3Letters 10499 { 10500 enum empty = false; 10501 @property auto front() { return _mon; } 10502 void popFront() 10503 { 10504 import std.exception : assumeUnique; 10505 import std.random : rndGen; 10506 _mon = rndGen.map!(a => letters[a % letters.length])().take(3).array().assumeUnique(); 10507 } 10508 string _mon; 10509 static auto start() { Rand3Letters retval; retval.popFront(); return retval; } 10510 } 10511 10512 static foreach (cr; AliasSeq!(function(string a){return cast(char[]) a;}, 10513 function(string a){return cast(ubyte[]) a;}, 10514 function(string a){return a;}, 10515 function(string a){return map!(b => cast(char) b)(a.representation);})) 10516 {(){ // workaround slow optimizations for large functions 10517 // https://issues.dlang.org/show_bug.cgi?id=2396 10518 scope(failure) writeln(typeof(cr).stringof); 10519 alias test = testParse822!cr; 10520 alias testBad = testBadParse822!cr; 10521 10522 immutable std1 = DateTime(2012, 12, 21, 13, 14, 15); 10523 immutable std2 = DateTime(2012, 12, 21, 13, 14, 0); 10524 immutable dst1 = DateTime(1976, 7, 4, 5, 4, 22); 10525 immutable dst2 = DateTime(1976, 7, 4, 5, 4, 0); 10526 10527 test("21 Dec 2012 13:14:15 +0000", SysTime(std1, UTC())); 10528 test("21 Dec 2012 13:14 +0000", SysTime(std2, UTC())); 10529 test("Fri, 21 Dec 2012 13:14 +0000", SysTime(std2, UTC())); 10530 test("Fri, 21 Dec 2012 13:14:15 +0000", SysTime(std1, UTC())); 10531 10532 test("04 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC())); 10533 test("04 Jul 1976 05:04 +0000", SysTime(dst2, UTC())); 10534 test("Sun, 04 Jul 1976 05:04 +0000", SysTime(dst2, UTC())); 10535 test("Sun, 04 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC())); 10536 10537 test("4 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC())); 10538 test("4 Jul 1976 05:04 +0000", SysTime(dst2, UTC())); 10539 test("Sun, 4 Jul 1976 05:04 +0000", SysTime(dst2, UTC())); 10540 test("Sun, 4 Jul 1976 05:04:22 +0000", SysTime(dst1, UTC())); 10541 10542 auto badTZ = new immutable SimpleTimeZone(Duration.zero); 10543 test("21 Dec 2012 13:14:15 -0000", SysTime(std1, badTZ)); 10544 test("21 Dec 2012 13:14 -0000", SysTime(std2, badTZ)); 10545 test("Fri, 21 Dec 2012 13:14 -0000", SysTime(std2, badTZ)); 10546 test("Fri, 21 Dec 2012 13:14:15 -0000", SysTime(std1, badTZ)); 10547 10548 test("04 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ)); 10549 test("04 Jul 1976 05:04 -0000", SysTime(dst2, badTZ)); 10550 test("Sun, 04 Jul 1976 05:04 -0000", SysTime(dst2, badTZ)); 10551 test("Sun, 04 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ)); 10552 10553 test("4 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ)); 10554 test("4 Jul 1976 05:04 -0000", SysTime(dst2, badTZ)); 10555 test("Sun, 4 Jul 1976 05:04 -0000", SysTime(dst2, badTZ)); 10556 test("Sun, 4 Jul 1976 05:04:22 -0000", SysTime(dst1, badTZ)); 10557 10558 auto pst = new immutable SimpleTimeZone(dur!"hours"(-8)); 10559 auto pdt = new immutable SimpleTimeZone(dur!"hours"(-7)); 10560 test("21 Dec 2012 13:14:15 -0800", SysTime(std1, pst)); 10561 test("21 Dec 2012 13:14 -0800", SysTime(std2, pst)); 10562 test("Fri, 21 Dec 2012 13:14 -0800", SysTime(std2, pst)); 10563 test("Fri, 21 Dec 2012 13:14:15 -0800", SysTime(std1, pst)); 10564 10565 test("04 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt)); 10566 test("04 Jul 1976 05:04 -0700", SysTime(dst2, pdt)); 10567 test("Sun, 04 Jul 1976 05:04 -0700", SysTime(dst2, pdt)); 10568 test("Sun, 04 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt)); 10569 10570 test("4 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt)); 10571 test("4 Jul 1976 05:04 -0700", SysTime(dst2, pdt)); 10572 test("Sun, 4 Jul 1976 05:04 -0700", SysTime(dst2, pdt)); 10573 test("Sun, 4 Jul 1976 05:04:22 -0700", SysTime(dst1, pdt)); 10574 10575 auto cet = new immutable SimpleTimeZone(dur!"hours"(1)); 10576 auto cest = new immutable SimpleTimeZone(dur!"hours"(2)); 10577 test("21 Dec 2012 13:14:15 +0100", SysTime(std1, cet)); 10578 test("21 Dec 2012 13:14 +0100", SysTime(std2, cet)); 10579 test("Fri, 21 Dec 2012 13:14 +0100", SysTime(std2, cet)); 10580 test("Fri, 21 Dec 2012 13:14:15 +0100", SysTime(std1, cet)); 10581 10582 test("04 Jul 1976 05:04:22 +0200", SysTime(dst1, cest)); 10583 test("04 Jul 1976 05:04 +0200", SysTime(dst2, cest)); 10584 test("Sun, 04 Jul 1976 05:04 +0200", SysTime(dst2, cest)); 10585 test("Sun, 04 Jul 1976 05:04:22 +0200", SysTime(dst1, cest)); 10586 10587 test("4 Jul 1976 05:04:22 +0200", SysTime(dst1, cest)); 10588 test("4 Jul 1976 05:04 +0200", SysTime(dst2, cest)); 10589 test("Sun, 4 Jul 1976 05:04 +0200", SysTime(dst2, cest)); 10590 test("Sun, 4 Jul 1976 05:04:22 +0200", SysTime(dst1, cest)); 10591 10592 // dst and std times are switched in the Southern Hemisphere which is why the 10593 // time zone names and DateTime variables don't match. 10594 auto cstStd = new immutable SimpleTimeZone(dur!"hours"(9) + dur!"minutes"(30)); 10595 auto cstDST = new immutable SimpleTimeZone(dur!"hours"(10) + dur!"minutes"(30)); 10596 test("21 Dec 2012 13:14:15 +1030", SysTime(std1, cstDST)); 10597 test("21 Dec 2012 13:14 +1030", SysTime(std2, cstDST)); 10598 test("Fri, 21 Dec 2012 13:14 +1030", SysTime(std2, cstDST)); 10599 test("Fri, 21 Dec 2012 13:14:15 +1030", SysTime(std1, cstDST)); 10600 10601 test("04 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 10602 test("04 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 10603 test("Sun, 04 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 10604 test("Sun, 04 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 10605 10606 test("4 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 10607 test("4 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 10608 test("Sun, 4 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 10609 test("Sun, 4 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 10610 10611 foreach (int i, mon; _monthNames) 10612 { 10613 test(format("17 %s 2012 00:05:02 +0000", mon), SysTime(DateTime(2012, i + 1, 17, 0, 5, 2), UTC())); 10614 test(format("17 %s 2012 00:05 +0000", mon), SysTime(DateTime(2012, i + 1, 17, 0, 5, 0), UTC())); 10615 } 10616 10617 import std.uni : toLower, toUpper; 10618 foreach (mon; chain(_monthNames[].map!(a => toLower(a))(), 10619 _monthNames[].map!(a => toUpper(a))(), 10620 ["Jam", "Jen", "Fec", "Fdb", "Mas", "Mbr", "Aps", "Aqr", "Mai", "Miy", 10621 "Jum", "Jbn", "Jup", "Jal", "Aur", "Apg", "Sem", "Sap", "Ocm", "Odt", 10622 "Nom", "Nav", "Dem", "Dac"], 10623 Rand3Letters.start().filter!(a => !_monthNames[].canFind(a)).take(20))) 10624 { 10625 scope(failure) writefln("Month: %s", mon); 10626 testBad(format("17 %s 2012 00:05:02 +0000", mon)); 10627 testBad(format("17 %s 2012 00:05 +0000", mon)); 10628 } 10629 10630 immutable string[7] daysOfWeekNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; 10631 10632 { 10633 auto start = SysTime(DateTime(2012, 11, 11, 9, 42, 0), UTC()); 10634 int day = 11; 10635 10636 foreach (int i, dow; daysOfWeekNames) 10637 { 10638 auto curr = start + dur!"days"(i); 10639 test(format("%s, %s Nov 2012 09:42:00 +0000", dow, day), curr); 10640 test(format("%s, %s Nov 2012 09:42 +0000", dow, day++), curr); 10641 10642 // Whether the day of the week matches the date is ignored. 10643 test(format("%s, 11 Nov 2012 09:42:00 +0000", dow), start); 10644 test(format("%s, 11 Nov 2012 09:42 +0000", dow), start); 10645 } 10646 } 10647 10648 foreach (dow; chain(daysOfWeekNames[].map!(a => toLower(a))(), 10649 daysOfWeekNames[].map!(a => toUpper(a))(), 10650 ["Sum", "Spn", "Mom", "Man", "Tuf", "Tae", "Wem", "Wdd", "The", "Tur", 10651 "Fro", "Fai", "San", "Sut"], 10652 Rand3Letters.start().filter!(a => !daysOfWeekNames[].canFind(a)).take(20))) 10653 { 10654 scope(failure) writefln("Day of Week: %s", dow); 10655 testBad(format("%s, 11 Nov 2012 09:42:00 +0000", dow)); 10656 testBad(format("%s, 11 Nov 2012 09:42 +0000", dow)); 10657 } 10658 10659 testBad("31 Dec 1899 23:59:59 +0000"); 10660 test("01 Jan 1900 00:00:00 +0000", SysTime(Date(1900, 1, 1), UTC())); 10661 test("01 Jan 1900 00:00:00 -0000", SysTime(Date(1900, 1, 1), 10662 new immutable SimpleTimeZone(Duration.zero))); 10663 test("01 Jan 1900 00:00:00 -0700", SysTime(Date(1900, 1, 1), 10664 new immutable SimpleTimeZone(dur!"hours"(-7)))); 10665 10666 { 10667 auto st1 = SysTime(Date(1900, 1, 1), UTC()); 10668 auto st2 = SysTime(Date(1900, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-11))); 10669 foreach (i; 1900 .. 2102) 10670 { 10671 test(format("1 Jan %05d 00:00 +0000", i), st1); 10672 test(format("1 Jan %05d 00:00 -1100", i), st2); 10673 st1.add!"years"(1); 10674 st2.add!"years"(1); 10675 } 10676 st1.year = 9998; 10677 st2.year = 9998; 10678 foreach (i; 9998 .. 11_002) 10679 { 10680 test(format("1 Jan %05d 00:00 +0000", i), st1); 10681 test(format("1 Jan %05d 00:00 -1100", i), st2); 10682 st1.add!"years"(1); 10683 st2.add!"years"(1); 10684 } 10685 } 10686 10687 testBad("12 Feb 1907 23:17:09 0000"); 10688 testBad("12 Feb 1907 23:17:09 +000"); 10689 testBad("12 Feb 1907 23:17:09 -000"); 10690 testBad("12 Feb 1907 23:17:09 +00000"); 10691 testBad("12 Feb 1907 23:17:09 -00000"); 10692 testBad("12 Feb 1907 23:17:09 +A"); 10693 testBad("12 Feb 1907 23:17:09 +PST"); 10694 testBad("12 Feb 1907 23:17:09 -A"); 10695 testBad("12 Feb 1907 23:17:09 -PST"); 10696 10697 // test trailing stuff that gets ignored 10698 { 10699 foreach (c; chain(iota(0, 33), ['('], iota(127, ubyte.max + 1))) 10700 { 10701 scope(failure) writefln("c: %d", c); 10702 test(format("21 Dec 2012 13:14:15 +0000%c", cast(char) c), SysTime(std1, UTC())); 10703 test(format("21 Dec 2012 13:14:15 +0000%c ", cast(char) c), SysTime(std1, UTC())); 10704 test(format("21 Dec 2012 13:14:15 +0000%chello", cast(char) c), SysTime(std1, UTC())); 10705 } 10706 } 10707 10708 // test trailing stuff that doesn't get ignored 10709 { 10710 foreach (c; chain(iota(33, '('), iota('(' + 1, 127))) 10711 { 10712 scope(failure) writefln("c: %d", c); 10713 testBad(format("21 Dec 2012 13:14:15 +0000%c", cast(char) c)); 10714 testBad(format("21 Dec 2012 13:14:15 +0000%c ", cast(char) c)); 10715 testBad(format("21 Dec 2012 13:14:15 +0000%chello", cast(char) c)); 10716 } 10717 } 10718 10719 testBad("32 Jan 2012 12:13:14 -0800"); 10720 testBad("31 Jan 2012 24:13:14 -0800"); 10721 testBad("31 Jan 2012 12:60:14 -0800"); 10722 testBad("31 Jan 2012 12:13:61 -0800"); 10723 testBad("31 Jan 2012 12:13:14 -0860"); 10724 test("31 Jan 2012 12:13:14 -0859", 10725 SysTime(DateTime(2012, 1, 31, 12, 13, 14), 10726 new immutable SimpleTimeZone(dur!"hours"(-8) + dur!"minutes"(-59)))); 10727 10728 // leap-seconds 10729 test("21 Dec 2012 15:59:60 -0800", SysTime(DateTime(2012, 12, 21, 15, 59, 59), pst)); 10730 10731 // FWS 10732 test("Sun,4 Jul 1976 05:04 +0930", SysTime(dst2, cstStd)); 10733 test("Sun,4 Jul 1976 05:04:22 +0930", SysTime(dst1, cstStd)); 10734 test("Sun,4 Jul 1976 05:04 +0930 (foo)", SysTime(dst2, cstStd)); 10735 test("Sun,4 Jul 1976 05:04:22 +0930 (foo)", SysTime(dst1, cstStd)); 10736 test("Sun,4 \r\n Jul \r\n 1976 \r\n 05:04 \r\n +0930 \r\n (foo)", SysTime(dst2, cstStd)); 10737 test("Sun,4 \r\n Jul \r\n 1976 \r\n 05:04:22 \r\n +0930 \r\n (foo)", SysTime(dst1, cstStd)); 10738 10739 auto str = "01 Jan 2012 12:13:14 -0800 "; 10740 test(str, SysTime(DateTime(2012, 1, 1, 12, 13, 14), new immutable SimpleTimeZone(hours(-8)))); 10741 foreach (i; 0 .. str.length) 10742 { 10743 auto currStr = str.dup; 10744 currStr[i] = 'x'; 10745 scope(failure) writefln("failed: %s", currStr); 10746 testBad(cast(string) currStr); 10747 } 10748 foreach (i; 2 .. str.length) 10749 { 10750 auto currStr = str[0 .. $ - i]; 10751 scope(failure) writefln("failed: %s", currStr); 10752 testBad(cast(string) currStr); 10753 testBad((cast(string) currStr) ~ " "); 10754 } 10755 }();} 10756 10757 static void testScope(scope ref string str) @safe 10758 { 10759 auto result = parseRFC822DateTime(str); 10760 } 10761 } 10762 10763 // Obsolete Format per section 4.3 of RFC 5322. 10764 @system unittest 10765 { 10766 import std.algorithm.iteration : filter, map; 10767 import std.ascii : letters; 10768 import std.exception : collectExceptionMsg; 10769 import std.format : format; 10770 import std.meta : AliasSeq; 10771 import std.range : chain, iota; 10772 import std.stdio : writefln, writeln; 10773 import std..string : representation; 10774 10775 auto std1 = SysTime(DateTime(2012, 12, 21, 13, 14, 15), UTC()); 10776 auto std2 = SysTime(DateTime(2012, 12, 21, 13, 14, 0), UTC()); 10777 auto std3 = SysTime(DateTime(1912, 12, 21, 13, 14, 15), UTC()); 10778 auto std4 = SysTime(DateTime(1912, 12, 21, 13, 14, 0), UTC()); 10779 auto dst1 = SysTime(DateTime(1976, 7, 4, 5, 4, 22), UTC()); 10780 auto dst2 = SysTime(DateTime(1976, 7, 4, 5, 4, 0), UTC()); 10781 auto tooLate1 = SysTime(Date(10_000, 1, 1), UTC()); 10782 auto tooLate2 = SysTime(DateTime(12_007, 12, 31, 12, 22, 19), UTC()); 10783 10784 static foreach (cr; AliasSeq!(function(string a){return cast(char[]) a;}, 10785 function(string a){return cast(ubyte[]) a;}, 10786 function(string a){return a;}, 10787 function(string a){return map!(b => cast(char) b)(a.representation);})) 10788 {(){ // workaround slow optimizations for large functions 10789 // https://issues.dlang.org/show_bug.cgi?id=2396 10790 scope(failure) writeln(typeof(cr).stringof); 10791 alias test = testParse822!cr; 10792 { 10793 auto list = ["", " ", " \r\n\t", "\t\r\n (hello world( frien(dog)) silly \r\n ) \t\t \r\n ()", 10794 " \n ", "\t\n\t", " \n\t (foo) \n (bar) \r\n (baz) \n "]; 10795 10796 foreach (i, cfws; list) 10797 { 10798 scope(failure) writefln("i: %s", i); 10799 10800 test(format("%1$s21%1$sDec%1$s2012%1$s13:14:15%1$s+0000%1$s", cfws), std1); 10801 test(format("%1$s21%1$sDec%1$s2012%1$s13:14%1$s+0000%1$s", cfws), std2); 10802 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s2012%1$s13:14%1$s+0000%1$s", cfws), std2); 10803 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s2012%1$s13:14:15%1$s+0000%1$s", cfws), std1); 10804 10805 test(format("%1$s04%1$sJul%1$s1976%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10806 test(format("%1$s04%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2); 10807 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2); 10808 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s1976%1$s05:04:22 +0000%1$s", cfws), dst1); 10809 10810 test(format("%1$s4%1$sJul%1$s1976%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10811 test(format("%1$s4%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2); 10812 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s1976%1$s05:04%1$s+0000%1$s", cfws), dst2); 10813 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s1976%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10814 10815 test(format("%1$s21%1$sDec%1$s12%1$s13:14:15%1$s+0000%1$s", cfws), std1); 10816 test(format("%1$s21%1$sDec%1$s12%1$s13:14%1$s+0000%1$s", cfws), std2); 10817 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s12%1$s13:14%1$s+0000%1$s", cfws), std2); 10818 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s12%1$s13:14:15%1$s+0000%1$s", cfws), std1); 10819 10820 test(format("%1$s04%1$sJul%1$s76%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10821 test(format("%1$s04%1$sJul%1$s76%1$s05:04%1$s+0000%1$s", cfws), dst2); 10822 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s76%1$s05:04%1$s+0000%1$s", cfws), dst2); 10823 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s76%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10824 10825 test(format("%1$s4%1$sJul%1$s76 05:04:22%1$s+0000%1$s", cfws), dst1); 10826 test(format("%1$s4%1$sJul%1$s76 05:04%1$s+0000%1$s", cfws), dst2); 10827 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s76%1$s05:04%1$s+0000%1$s", cfws), dst2); 10828 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s76%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10829 10830 test(format("%1$s21%1$sDec%1$s012%1$s13:14:15%1$s+0000%1$s", cfws), std3); 10831 test(format("%1$s21%1$sDec%1$s012%1$s13:14%1$s+0000%1$s", cfws), std4); 10832 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s012%1$s13:14%1$s+0000%1$s", cfws), std4); 10833 test(format("%1$sFri%1$s,%1$s21%1$sDec%1$s012%1$s13:14:15%1$s+0000%1$s", cfws), std3); 10834 10835 test(format("%1$s04%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10836 test(format("%1$s04%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2); 10837 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2); 10838 test(format("%1$sSun%1$s,%1$s04%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10839 10840 test(format("%1$s4%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10841 test(format("%1$s4%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2); 10842 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s076%1$s05:04%1$s+0000%1$s", cfws), dst2); 10843 test(format("%1$sSun%1$s,%1$s4%1$sJul%1$s076%1$s05:04:22%1$s+0000%1$s", cfws), dst1); 10844 10845 test(format("%1$s1%1$sJan%1$s10000%1$s00:00:00%1$s+0000%1$s", cfws), tooLate1); 10846 test(format("%1$s31%1$sDec%1$s12007%1$s12:22:19%1$s+0000%1$s", cfws), tooLate2); 10847 test(format("%1$sSat%1$s,%1$s1%1$sJan%1$s10000%1$s00:00:00%1$s+0000%1$s", cfws), tooLate1); 10848 test(format("%1$sSun%1$s,%1$s31%1$sDec%1$s12007%1$s12:22:19%1$s+0000%1$s", cfws), tooLate2); 10849 } 10850 } 10851 10852 // test years of 1, 2, and 3 digits. 10853 { 10854 auto st1 = SysTime(Date(2000, 1, 1), UTC()); 10855 auto st2 = SysTime(Date(2000, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-12))); 10856 foreach (i; 0 .. 50) 10857 { 10858 test(format("1 Jan %02d 00:00 GMT", i), st1); 10859 test(format("1 Jan %02d 00:00 -1200", i), st2); 10860 st1.add!"years"(1); 10861 st2.add!"years"(1); 10862 } 10863 } 10864 10865 { 10866 auto st1 = SysTime(Date(1950, 1, 1), UTC()); 10867 auto st2 = SysTime(Date(1950, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-12))); 10868 foreach (i; 50 .. 100) 10869 { 10870 test(format("1 Jan %02d 00:00 GMT", i), st1); 10871 test(format("1 Jan %02d 00:00 -1200", i), st2); 10872 st1.add!"years"(1); 10873 st2.add!"years"(1); 10874 } 10875 } 10876 10877 { 10878 auto st1 = SysTime(Date(1900, 1, 1), UTC()); 10879 auto st2 = SysTime(Date(1900, 1, 1), new immutable SimpleTimeZone(dur!"hours"(-11))); 10880 foreach (i; 0 .. 1000) 10881 { 10882 test(format("1 Jan %03d 00:00 GMT", i), st1); 10883 test(format("1 Jan %03d 00:00 -1100", i), st2); 10884 st1.add!"years"(1); 10885 st2.add!"years"(1); 10886 } 10887 } 10888 10889 foreach (i; 0 .. 10) 10890 { 10891 auto str1 = cr(format("1 Jan %d 00:00 GMT", i)); 10892 auto str2 = cr(format("1 Jan %d 00:00 -1200", i)); 10893 assertThrown!DateTimeException(parseRFC822DateTime(str1)); 10894 assertThrown!DateTimeException(parseRFC822DateTime(str1)); 10895 } 10896 10897 // test time zones 10898 { 10899 auto dt = DateTime(1982, 05, 03, 12, 22, 04); 10900 test("Wed, 03 May 1982 12:22:04 UT", SysTime(dt, UTC())); 10901 test("Wed, 03 May 1982 12:22:04 GMT", SysTime(dt, UTC())); 10902 test("Wed, 03 May 1982 12:22:04 EST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-5)))); 10903 test("Wed, 03 May 1982 12:22:04 EDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-4)))); 10904 test("Wed, 03 May 1982 12:22:04 CST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-6)))); 10905 test("Wed, 03 May 1982 12:22:04 CDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-5)))); 10906 test("Wed, 03 May 1982 12:22:04 MST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-7)))); 10907 test("Wed, 03 May 1982 12:22:04 MDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-6)))); 10908 test("Wed, 03 May 1982 12:22:04 PST", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-8)))); 10909 test("Wed, 03 May 1982 12:22:04 PDT", SysTime(dt, new immutable SimpleTimeZone(dur!"hours"(-7)))); 10910 10911 auto badTZ = new immutable SimpleTimeZone(Duration.zero); 10912 foreach (dchar c; filter!(a => a != 'j' && a != 'J')(letters)) 10913 { 10914 scope(failure) writefln("c: %s", c); 10915 test(format("Wed, 03 May 1982 12:22:04 %s", c), SysTime(dt, badTZ)); 10916 test(format("Wed, 03 May 1982 12:22:04%s", c), SysTime(dt, badTZ)); 10917 } 10918 10919 foreach (dchar c; ['j', 'J']) 10920 { 10921 scope(failure) writefln("c: %s", c); 10922 assertThrown!DateTimeException(parseRFC822DateTime(cr(format("Wed, 03 May 1982 12:22:04 %s", c)))); 10923 assertThrown!DateTimeException(parseRFC822DateTime(cr(format("Wed, 03 May 1982 12:22:04%s", c)))); 10924 } 10925 10926 foreach (string s; ["AAA", "GQW", "DDT", "PDA", "GT", "GM"]) 10927 { 10928 scope(failure) writefln("s: %s", s); 10929 test(format("Wed, 03 May 1982 12:22:04 %s", s), SysTime(dt, badTZ)); 10930 } 10931 10932 // test trailing stuff that gets ignored 10933 { 10934 foreach (c; chain(iota(0, 33), ['('], iota(127, ubyte.max + 1))) 10935 { 10936 scope(failure) writefln("c: %d", c); 10937 test(format("21Dec1213:14:15+0000%c", cast(char) c), std1); 10938 test(format("21Dec1213:14:15+0000%c ", cast(char) c), std1); 10939 test(format("21Dec1213:14:15+0000%chello", cast(char) c), std1); 10940 } 10941 } 10942 10943 // test trailing stuff that doesn't get ignored 10944 { 10945 foreach (c; chain(iota(33, '('), iota('(' + 1, 127))) 10946 { 10947 scope(failure) writefln("c: %d", c); 10948 assertThrown!DateTimeException( 10949 parseRFC822DateTime(cr(format("21Dec1213:14:15+0000%c", cast(char) c)))); 10950 assertThrown!DateTimeException( 10951 parseRFC822DateTime(cr(format("21Dec1213:14:15+0000%c ", cast(char) c)))); 10952 assertThrown!DateTimeException( 10953 parseRFC822DateTime(cr(format("21Dec1213:14:15+0000%chello", cast(char) c)))); 10954 } 10955 } 10956 } 10957 10958 // test that the checks for minimum length work correctly and avoid 10959 // any RangeErrors. 10960 test("7Dec1200:00A", SysTime(DateTime(2012, 12, 7, 00, 00, 00), 10961 new immutable SimpleTimeZone(Duration.zero))); 10962 test("Fri,7Dec1200:00A", SysTime(DateTime(2012, 12, 7, 00, 00, 00), 10963 new immutable SimpleTimeZone(Duration.zero))); 10964 test("7Dec1200:00:00A", SysTime(DateTime(2012, 12, 7, 00, 00, 00), 10965 new immutable SimpleTimeZone(Duration.zero))); 10966 test("Fri,7Dec1200:00:00A", SysTime(DateTime(2012, 12, 7, 00, 00, 00), 10967 new immutable SimpleTimeZone(Duration.zero))); 10968 10969 auto tooShortMsg = collectExceptionMsg!DateTimeException(parseRFC822DateTime("")); 10970 foreach (str; ["Fri,7Dec1200:00:00", "7Dec1200:00:00"]) 10971 { 10972 foreach (i; 0 .. str.length) 10973 { 10974 auto value = str[0 .. $ - i]; 10975 scope(failure) writeln(value); 10976 assert(collectExceptionMsg!DateTimeException(parseRFC822DateTime(value)) == tooShortMsg); 10977 } 10978 } 10979 }();} 10980 } 10981 10982 10983 private: 10984 10985 /+ 10986 Returns the given hnsecs as an ISO string of fractional seconds. 10987 +/ 10988 string fracSecsToISOString(int hnsecs) @safe pure nothrow 10989 { 10990 import std.array : appender; 10991 auto w = appender!string(); 10992 try 10993 fracSecsToISOString(w, hnsecs); 10994 catch (Exception e) 10995 assert(0, "fracSecsToISOString() threw."); 10996 return w.data; 10997 } 10998 10999 void fracSecsToISOString(W)(ref W writer, int hnsecs) 11000 { 11001 import std.conv : toChars; 11002 import std.range : padLeft; 11003 11004 assert(hnsecs >= 0); 11005 11006 if (hnsecs == 0) 11007 return; 11008 11009 put(writer, '.'); 11010 auto chars = hnsecs.toChars.padLeft('0', 7); 11011 while (chars.back == '0') 11012 chars.popBack(); 11013 put(writer, chars); 11014 } 11015 11016 @safe unittest 11017 { 11018 assert(fracSecsToISOString(0) == ""); 11019 assert(fracSecsToISOString(1) == ".0000001"); 11020 assert(fracSecsToISOString(10) == ".000001"); 11021 assert(fracSecsToISOString(100) == ".00001"); 11022 assert(fracSecsToISOString(1000) == ".0001"); 11023 assert(fracSecsToISOString(10_000) == ".001"); 11024 assert(fracSecsToISOString(100_000) == ".01"); 11025 assert(fracSecsToISOString(1_000_000) == ".1"); 11026 assert(fracSecsToISOString(1_000_001) == ".1000001"); 11027 assert(fracSecsToISOString(1_001_001) == ".1001001"); 11028 assert(fracSecsToISOString(1_071_601) == ".1071601"); 11029 assert(fracSecsToISOString(1_271_641) == ".1271641"); 11030 assert(fracSecsToISOString(9_999_999) == ".9999999"); 11031 assert(fracSecsToISOString(9_999_990) == ".999999"); 11032 assert(fracSecsToISOString(9_999_900) == ".99999"); 11033 assert(fracSecsToISOString(9_999_000) == ".9999"); 11034 assert(fracSecsToISOString(9_990_000) == ".999"); 11035 assert(fracSecsToISOString(9_900_000) == ".99"); 11036 assert(fracSecsToISOString(9_000_000) == ".9"); 11037 assert(fracSecsToISOString(999) == ".0000999"); 11038 assert(fracSecsToISOString(9990) == ".000999"); 11039 assert(fracSecsToISOString(99_900) == ".00999"); 11040 assert(fracSecsToISOString(999_000) == ".0999"); 11041 } 11042 11043 11044 /+ 11045 Returns a Duration corresponding to to the given ISO string of 11046 fractional seconds. 11047 +/ 11048 static Duration fracSecsFromISOString(S)(scope const S isoString) @safe pure 11049 if (isSomeString!S) 11050 { 11051 import std.algorithm.searching : all; 11052 import std.ascii : isDigit; 11053 import std.conv : to; 11054 import std..string : representation; 11055 11056 if (isoString.empty) 11057 return Duration.zero; 11058 11059 auto str = isoString.representation; 11060 11061 enforce(str[0] == '.', new DateTimeException("Invalid ISO String")); 11062 str.popFront(); 11063 11064 enforce(!str.empty && all!isDigit(str), new DateTimeException("Invalid ISO String")); 11065 11066 dchar[7] fullISOString = void; 11067 foreach (i, ref dchar c; fullISOString) 11068 { 11069 if (i < str.length) 11070 c = str[i]; 11071 else 11072 c = '0'; 11073 } 11074 11075 return hnsecs(to!int(fullISOString[])); 11076 } 11077 11078 @safe unittest 11079 { 11080 import core.time; 11081 static void testFSInvalid(string isoString) 11082 { 11083 fracSecsFromISOString(isoString); 11084 } 11085 11086 assertThrown!DateTimeException(testFSInvalid(".")); 11087 assertThrown!DateTimeException(testFSInvalid("0.")); 11088 assertThrown!DateTimeException(testFSInvalid("0")); 11089 assertThrown!DateTimeException(testFSInvalid("0000000")); 11090 assertThrown!DateTimeException(testFSInvalid("T")); 11091 assertThrown!DateTimeException(testFSInvalid("T.")); 11092 assertThrown!DateTimeException(testFSInvalid(".T")); 11093 assertThrown!DateTimeException(testFSInvalid(".00000Q0")); 11094 assertThrown!DateTimeException(testFSInvalid(".000000Q")); 11095 assertThrown!DateTimeException(testFSInvalid(".0000000Q")); 11096 assertThrown!DateTimeException(testFSInvalid(".0000000000Q")); 11097 11098 assert(fracSecsFromISOString("") == Duration.zero); 11099 assert(fracSecsFromISOString(".0000001") == hnsecs(1)); 11100 assert(fracSecsFromISOString(".000001") == hnsecs(10)); 11101 assert(fracSecsFromISOString(".00001") == hnsecs(100)); 11102 assert(fracSecsFromISOString(".0001") == hnsecs(1000)); 11103 assert(fracSecsFromISOString(".001") == hnsecs(10_000)); 11104 assert(fracSecsFromISOString(".01") == hnsecs(100_000)); 11105 assert(fracSecsFromISOString(".1") == hnsecs(1_000_000)); 11106 assert(fracSecsFromISOString(".1000001") == hnsecs(1_000_001)); 11107 assert(fracSecsFromISOString(".1001001") == hnsecs(1_001_001)); 11108 assert(fracSecsFromISOString(".1071601") == hnsecs(1_071_601)); 11109 assert(fracSecsFromISOString(".1271641") == hnsecs(1_271_641)); 11110 assert(fracSecsFromISOString(".9999999") == hnsecs(9_999_999)); 11111 assert(fracSecsFromISOString(".9999990") == hnsecs(9_999_990)); 11112 assert(fracSecsFromISOString(".999999") == hnsecs(9_999_990)); 11113 assert(fracSecsFromISOString(".9999900") == hnsecs(9_999_900)); 11114 assert(fracSecsFromISOString(".99999") == hnsecs(9_999_900)); 11115 assert(fracSecsFromISOString(".9999000") == hnsecs(9_999_000)); 11116 assert(fracSecsFromISOString(".9999") == hnsecs(9_999_000)); 11117 assert(fracSecsFromISOString(".9990000") == hnsecs(9_990_000)); 11118 assert(fracSecsFromISOString(".999") == hnsecs(9_990_000)); 11119 assert(fracSecsFromISOString(".9900000") == hnsecs(9_900_000)); 11120 assert(fracSecsFromISOString(".9900") == hnsecs(9_900_000)); 11121 assert(fracSecsFromISOString(".99") == hnsecs(9_900_000)); 11122 assert(fracSecsFromISOString(".9000000") == hnsecs(9_000_000)); 11123 assert(fracSecsFromISOString(".9") == hnsecs(9_000_000)); 11124 assert(fracSecsFromISOString(".0000999") == hnsecs(999)); 11125 assert(fracSecsFromISOString(".0009990") == hnsecs(9990)); 11126 assert(fracSecsFromISOString(".000999") == hnsecs(9990)); 11127 assert(fracSecsFromISOString(".0099900") == hnsecs(99_900)); 11128 assert(fracSecsFromISOString(".00999") == hnsecs(99_900)); 11129 assert(fracSecsFromISOString(".0999000") == hnsecs(999_000)); 11130 assert(fracSecsFromISOString(".0999") == hnsecs(999_000)); 11131 assert(fracSecsFromISOString(".00000000") == Duration.zero); 11132 assert(fracSecsFromISOString(".00000001") == Duration.zero); 11133 assert(fracSecsFromISOString(".00000009") == Duration.zero); 11134 assert(fracSecsFromISOString(".1234567890") == hnsecs(1_234_567)); 11135 assert(fracSecsFromISOString(".12345678901234567890") == hnsecs(1_234_567)); 11136 } 11137 11138 11139 /+ 11140 This function is used to split out the units without getting the remaining 11141 hnsecs. 11142 11143 Params: 11144 units = The units to split out. 11145 hnsecs = The current total hnsecs. 11146 11147 Returns: 11148 The split out value. 11149 +/ 11150 long getUnitsFromHNSecs(string units)(long hnsecs) @safe pure nothrow 11151 if (validTimeUnits(units) && 11152 CmpTimeUnits!(units, "months") < 0) 11153 { 11154 return convert!("hnsecs", units)(hnsecs); 11155 } 11156 11157 @safe unittest 11158 { 11159 auto hnsecs = 2595000000007L; 11160 immutable days = getUnitsFromHNSecs!"days"(hnsecs); 11161 assert(days == 3); 11162 assert(hnsecs == 2595000000007L); 11163 } 11164 11165 11166 /+ 11167 This function is used to split out the units without getting the units but 11168 just the remaining hnsecs. 11169 11170 Params: 11171 units = The units to split out. 11172 hnsecs = The current total hnsecs. 11173 11174 Returns: 11175 The remaining hnsecs. 11176 +/ 11177 long removeUnitsFromHNSecs(string units)(long hnsecs) @safe pure nothrow 11178 if (validTimeUnits(units) && 11179 CmpTimeUnits!(units, "months") < 0) 11180 { 11181 immutable value = convert!("hnsecs", units)(hnsecs); 11182 return hnsecs - convert!(units, "hnsecs")(value); 11183 } 11184 11185 @safe unittest 11186 { 11187 auto hnsecs = 2595000000007L; 11188 auto returned = removeUnitsFromHNSecs!"days"(hnsecs); 11189 assert(returned == 3000000007); 11190 assert(hnsecs == 2595000000007L); 11191 } 11192 11193 11194 /+ 11195 Strips what RFC 5322, section 3.2.2 refers to as CFWS from the left-hand 11196 side of the given range (it strips comments delimited by $(D '(') and 11197 `'`') as well as folding whitespace). 11198 11199 It is assumed that the given range contains the value of a header field and 11200 no terminating CRLF for the line (though the CRLF for folding whitespace is 11201 of course expected and stripped) and thus that the only case of CR or LF is 11202 in folding whitespace. 11203 11204 If a comment does not terminate correctly (e.g. mismatched parens) or if the 11205 the FWS is malformed, then the range will be empty when stripCWFS is done. 11206 However, only minimal validation of the content is done (e.g. quoted pairs 11207 within a comment aren't validated beyond \$LPAREN or \$RPAREN, because 11208 they're inside a comment, and thus their value doesn't matter anyway). It's 11209 only when the content does not conform to the grammar rules for FWS and thus 11210 literally cannot be parsed that content is considered invalid, and an empty 11211 range is returned. 11212 11213 Note that _stripCFWS is eager, not lazy. It does not create a new range. 11214 Rather, it pops off the CFWS from the range and returns it. 11215 +/ 11216 R _stripCFWS(R)(R range) 11217 if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && 11218 (is(immutable ElementType!R == immutable char) || is(immutable ElementType!R == immutable ubyte))) 11219 { 11220 immutable e = range.length; 11221 outer: for (size_t i = 0; i < e; ) 11222 { 11223 switch (range[i]) 11224 { 11225 case ' ': case '\t': 11226 { 11227 ++i; 11228 break; 11229 } 11230 case '\r': 11231 { 11232 if (i + 2 < e && range[i + 1] == '\n' && (range[i + 2] == ' ' || range[i + 2] == '\t')) 11233 { 11234 i += 3; 11235 break; 11236 } 11237 break outer; 11238 } 11239 case '\n': 11240 { 11241 if (i + 1 < e && (range[i + 1] == ' ' || range[i + 1] == '\t')) 11242 { 11243 i += 2; 11244 break; 11245 } 11246 break outer; 11247 } 11248 case '(': 11249 { 11250 ++i; 11251 size_t commentLevel = 1; 11252 while (i < e) 11253 { 11254 if (range[i] == '(') 11255 ++commentLevel; 11256 else if (range[i] == ')') 11257 { 11258 ++i; 11259 if (--commentLevel == 0) 11260 continue outer; 11261 continue; 11262 } 11263 else if (range[i] == '\\') 11264 { 11265 if (++i == e) 11266 break outer; 11267 } 11268 ++i; 11269 } 11270 break outer; 11271 } 11272 default: return range[i .. e]; 11273 } 11274 } 11275 return range[e .. e]; 11276 } 11277 11278 @system unittest 11279 { 11280 import std.algorithm.comparison : equal; 11281 import std.algorithm.iteration : map; 11282 import std.meta : AliasSeq; 11283 import std.stdio : writeln; 11284 import std..string : representation; 11285 11286 static foreach (cr; AliasSeq!(function(string a){return cast(ubyte[]) a;}, 11287 function(string a){return map!(b => cast(char) b)(a.representation);})) 11288 { 11289 scope(failure) writeln(typeof(cr).stringof); 11290 11291 assert(_stripCFWS(cr("")).empty); 11292 assert(_stripCFWS(cr("\r")).empty); 11293 assert(_stripCFWS(cr("\r\n")).empty); 11294 assert(_stripCFWS(cr("\r\n ")).empty); 11295 assert(_stripCFWS(cr(" \t\r\n")).empty); 11296 assert(equal(_stripCFWS(cr(" \t\r\n hello")), cr("hello"))); 11297 assert(_stripCFWS(cr(" \t\r\nhello")).empty); 11298 assert(_stripCFWS(cr(" \t\r\n\v")).empty); 11299 assert(equal(_stripCFWS(cr("\v \t\r\n\v")), cr("\v \t\r\n\v"))); 11300 assert(_stripCFWS(cr("()")).empty); 11301 assert(_stripCFWS(cr("(hello world)")).empty); 11302 assert(_stripCFWS(cr("(hello world)(hello world)")).empty); 11303 assert(_stripCFWS(cr("(hello world\r\n foo\r where's\nwaldo)")).empty); 11304 assert(_stripCFWS(cr(" \t (hello \tworld\r\n foo\r where's\nwaldo)\t\t ")).empty); 11305 assert(_stripCFWS(cr(" ")).empty); 11306 assert(_stripCFWS(cr("\t\t\t")).empty); 11307 assert(_stripCFWS(cr("\t \r\n\r \n")).empty); 11308 assert(_stripCFWS(cr("(hello world) (can't find waldo) (he's lost)")).empty); 11309 assert(_stripCFWS(cr("(hello\\) world) (can't \\(find waldo) (he's \\(\\)lost)")).empty); 11310 assert(_stripCFWS(cr("(((((")).empty); 11311 assert(_stripCFWS(cr("(((()))")).empty); 11312 assert(_stripCFWS(cr("(((())))")).empty); 11313 assert(equal(_stripCFWS(cr("(((()))))")), cr(")"))); 11314 assert(equal(_stripCFWS(cr(")))))")), cr(")))))"))); 11315 assert(equal(_stripCFWS(cr("()))))")), cr("))))"))); 11316 assert(equal(_stripCFWS(cr(" hello hello ")), cr("hello hello "))); 11317 assert(equal(_stripCFWS(cr("\thello (world)")), cr("hello (world)"))); 11318 assert(equal(_stripCFWS(cr(" \r\n \\((\\)) foo")), cr("\\((\\)) foo"))); 11319 assert(equal(_stripCFWS(cr(" \r\n (\\((\\))) foo")), cr("foo"))); 11320 assert(equal(_stripCFWS(cr(" \r\n (\\(())) foo")), cr(") foo"))); 11321 assert(_stripCFWS(cr(" \r\n (((\\))) foo")).empty); 11322 11323 assert(_stripCFWS(cr("(hello)(hello)")).empty); 11324 assert(_stripCFWS(cr(" \r\n (hello)\r\n (hello)")).empty); 11325 assert(_stripCFWS(cr(" \r\n (hello) \r\n (hello) \r\n ")).empty); 11326 assert(_stripCFWS(cr("\t\t\t\t(hello)\t\t\t\t(hello)\t\t\t\t")).empty); 11327 assert(equal(_stripCFWS(cr(" \r\n (hello)\r\n (hello) \r\n hello")), cr("hello"))); 11328 assert(equal(_stripCFWS(cr(" \r\n (hello) \r\n (hello) \r\n hello")), cr("hello"))); 11329 assert(equal(_stripCFWS(cr("\t\r\n\t(hello)\r\n\t(hello)\t\r\n hello")), cr("hello"))); 11330 assert(equal(_stripCFWS(cr("\t\r\n\t(hello)\t\r\n\t(hello)\t\r\n hello")), cr("hello"))); 11331 assert(equal(_stripCFWS(cr(" \r\n (hello) \r\n \r\n (hello) \r\n hello")), cr("hello"))); 11332 assert(equal(_stripCFWS(cr(" \r\n (hello) \r\n (hello) \r\n \r\n hello")), cr("hello"))); 11333 assert(equal(_stripCFWS(cr(" \r\n \r\n (hello)\t\r\n (hello) \r\n hello")), cr("hello"))); 11334 assert(equal(_stripCFWS(cr(" \r\n\t\r\n\t(hello)\t\r\n (hello) \r\n hello")), cr("hello"))); 11335 11336 assert(equal(_stripCFWS(cr(" (\r\n ( \r\n ) \r\n ) foo")), cr("foo"))); 11337 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n ) foo")), cr("foo"))); 11338 assert(equal(_stripCFWS(cr(" (\t\r\n ( \r\n ) \r\n ) foo")), cr("foo"))); 11339 assert(equal(_stripCFWS(cr(" (\r\n\t( \r\n ) \r\n ) foo")), cr("foo"))); 11340 assert(equal(_stripCFWS(cr(" ( \r\n (\t\r\n ) \r\n ) foo")), cr("foo"))); 11341 assert(equal(_stripCFWS(cr(" ( \r\n (\r\n ) \r\n ) foo")), cr("foo"))); 11342 assert(equal(_stripCFWS(cr(" ( \r\n (\r\n\t) \r\n ) foo")), cr("foo"))); 11343 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n) \r\n ) foo")), cr("foo"))); 11344 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n )\t\r\n ) foo")), cr("foo"))); 11345 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n )\r\n ) foo")), cr("foo"))); 11346 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n) foo")), cr("foo"))); 11347 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n\t) foo")), cr("foo"))); 11348 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n ) \r\n foo")), cr("foo"))); 11349 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n )\t\r\n foo")), cr("foo"))); 11350 assert(equal(_stripCFWS(cr(" ( \r\n ( \r\n ) \r\n )\r\n foo")), cr("foo"))); 11351 11352 assert(equal(_stripCFWS(cr(" ( \r\n \r\n ( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 11353 assert(equal(_stripCFWS(cr(" ( \r\n \r\n ( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 11354 assert(equal(_stripCFWS(cr(" (\t\r\n \r\n ( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 11355 assert(equal(_stripCFWS(cr(" (\r\n \r\n\t( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 11356 assert(equal(_stripCFWS(cr(" (\r\n \r\n( \r\n \r\n ) \r\n ) foo")), cr("foo"))); 11357 assert(equal(_stripCFWS(cr(" (\r\n \r\n ( \r\n \r\n\t) \r\n ) foo")), cr("foo"))); 11358 assert(equal(_stripCFWS(cr(" (\r\n \r\n ( \r\n \r\n )\t\r\n ) foo")), cr("foo"))); 11359 assert(equal(_stripCFWS(cr(" (\r\n \r\n ( \r\n \r\n )\r\n ) foo")), cr("foo"))); 11360 11361 assert(equal(_stripCFWS(cr(" ( \r\n bar \r\n ( \r\n bar \r\n ) \r\n ) foo")), cr("foo"))); 11362 assert(equal(_stripCFWS(cr(" ( \r\n () \r\n ( \r\n () \r\n ) \r\n ) foo")), cr("foo"))); 11363 assert(equal(_stripCFWS(cr(" ( \r\n \\\\ \r\n ( \r\n \\\\ \r\n ) \r\n ) foo")), cr("foo"))); 11364 11365 assert(_stripCFWS(cr("(hello)(hello)")).empty); 11366 assert(_stripCFWS(cr(" \n (hello)\n (hello) \n ")).empty); 11367 assert(_stripCFWS(cr(" \n (hello) \n (hello) \n ")).empty); 11368 assert(equal(_stripCFWS(cr(" \n (hello)\n (hello) \n hello")), cr("hello"))); 11369 assert(equal(_stripCFWS(cr(" \n (hello) \n (hello) \n hello")), cr("hello"))); 11370 assert(equal(_stripCFWS(cr("\t\n\t(hello)\n\t(hello)\t\n hello")), cr("hello"))); 11371 assert(equal(_stripCFWS(cr("\t\n\t(hello)\t\n\t(hello)\t\n hello")), cr("hello"))); 11372 assert(equal(_stripCFWS(cr(" \n (hello) \n \n (hello) \n hello")), cr("hello"))); 11373 assert(equal(_stripCFWS(cr(" \n (hello) \n (hello) \n \n hello")), cr("hello"))); 11374 assert(equal(_stripCFWS(cr(" \n \n (hello)\t\n (hello) \n hello")), cr("hello"))); 11375 assert(equal(_stripCFWS(cr(" \n\t\n\t(hello)\t\n (hello) \n hello")), cr("hello"))); 11376 } 11377 } 11378 11379 // This is so that we don't have to worry about std.conv.to throwing. It also 11380 // doesn't have to worry about quite as many cases as std.conv.to, since it 11381 // doesn't have to worry about a sign on the value or about whether it fits. 11382 T _convDigits(T, R)(R str) 11383 if (isIntegral!T && isSigned!T) // The constraints on R were already covered by parseRFC822DateTime. 11384 { 11385 import std.ascii : isDigit; 11386 11387 assert(!str.empty); 11388 T num = 0; 11389 foreach (i; 0 .. str.length) 11390 { 11391 if (i != 0) 11392 num *= 10; 11393 if (!isDigit(str[i])) 11394 return -1; 11395 num += str[i] - '0'; 11396 } 11397 return num; 11398 } 11399 11400 @safe unittest 11401 { 11402 import std.conv : to; 11403 import std.range : chain, iota; 11404 foreach (i; chain(iota(0, 101), [250, 999, 1000, 1001, 2345, 9999])) 11405 { 11406 assert(_convDigits!int(to!string(i)) == i, i.to!string); 11407 } 11408 foreach (str; ["-42", "+42", "1a", "1 ", " ", " 42 "]) 11409 { 11410 assert(_convDigits!int(str) == -1, str); 11411 } 11412 } 11413 11414 11415 // NOTE: all the non-simple array literals are wrapped in functions, because 11416 // otherwise importing causes re-evaluation of the static initializers using 11417 // CTFE with unittests enabled 11418 version (StdUnittest) 11419 { 11420 private @safe: 11421 // Variables to help in testing. 11422 Duration currLocalDiffFromUTC; 11423 immutable (TimeZone)[] testTZs; 11424 11425 // All of these helper arrays are sorted in ascending order. 11426 auto testYearsBC = [-1999, -1200, -600, -4, -1, 0]; 11427 auto testYearsAD = [1, 4, 1000, 1999, 2000, 2012]; 11428 11429 // I'd use a Tuple, but I get forward reference errors if I try. 11430 struct MonthDay 11431 { 11432 Month month; 11433 short day; 11434 11435 this(int m, short d) 11436 { 11437 month = cast(Month) m; 11438 day = d; 11439 } 11440 } 11441 11442 MonthDay[] testMonthDays() 11443 { 11444 static result = [MonthDay(1, 1), 11445 MonthDay(1, 2), 11446 MonthDay(3, 17), 11447 MonthDay(7, 4), 11448 MonthDay(10, 27), 11449 MonthDay(12, 30), 11450 MonthDay(12, 31)]; 11451 return result; 11452 } 11453 11454 auto testDays = [1, 2, 9, 10, 16, 20, 25, 28, 29, 30, 31]; 11455 11456 TimeOfDay[] testTODs() 11457 { 11458 static result = [TimeOfDay(0, 0, 0), 11459 TimeOfDay(0, 0, 1), 11460 TimeOfDay(0, 1, 0), 11461 TimeOfDay(1, 0, 0), 11462 TimeOfDay(13, 13, 13), 11463 TimeOfDay(23, 59, 59)]; 11464 return result; 11465 } 11466 11467 auto testHours = [0, 1, 12, 22, 23]; 11468 auto testMinSecs = [0, 1, 30, 58, 59]; 11469 11470 // Throwing exceptions is incredibly expensive, so we want to use a smaller 11471 // set of values for tests using assertThrown. 11472 TimeOfDay[] testTODsThrown() 11473 { 11474 static result = [TimeOfDay(0, 0, 0), 11475 TimeOfDay(13, 13, 13), 11476 TimeOfDay(23, 59, 59)]; 11477 return result; 11478 } 11479 11480 Date[] testDatesBC; 11481 Date[] testDatesAD; 11482 11483 DateTime[] testDateTimesBC; 11484 DateTime[] testDateTimesAD; 11485 11486 Duration[] testFracSecs; 11487 11488 SysTime[] testSysTimesBC; 11489 SysTime[] testSysTimesAD; 11490 11491 // I'd use a Tuple, but I get forward reference errors if I try. 11492 struct GregDay { int day; Date date; } 11493 GregDay[] testGregDaysBC() 11494 { 11495 static result = [GregDay(-1_373_427, Date(-3760, 9, 7)), // Start of the Hebrew Calendar 11496 GregDay(-735_233, Date(-2012, 1, 1)), 11497 GregDay(-735_202, Date(-2012, 2, 1)), 11498 GregDay(-735_175, Date(-2012, 2, 28)), 11499 GregDay(-735_174, Date(-2012, 2, 29)), 11500 GregDay(-735_173, Date(-2012, 3, 1)), 11501 GregDay(-734_502, Date(-2010, 1, 1)), 11502 GregDay(-734_472, Date(-2010, 1, 31)), 11503 GregDay(-734_471, Date(-2010, 2, 1)), 11504 GregDay(-734_444, Date(-2010, 2, 28)), 11505 GregDay(-734_443, Date(-2010, 3, 1)), 11506 GregDay(-734_413, Date(-2010, 3, 31)), 11507 GregDay(-734_412, Date(-2010, 4, 1)), 11508 GregDay(-734_383, Date(-2010, 4, 30)), 11509 GregDay(-734_382, Date(-2010, 5, 1)), 11510 GregDay(-734_352, Date(-2010, 5, 31)), 11511 GregDay(-734_351, Date(-2010, 6, 1)), 11512 GregDay(-734_322, Date(-2010, 6, 30)), 11513 GregDay(-734_321, Date(-2010, 7, 1)), 11514 GregDay(-734_291, Date(-2010, 7, 31)), 11515 GregDay(-734_290, Date(-2010, 8, 1)), 11516 GregDay(-734_260, Date(-2010, 8, 31)), 11517 GregDay(-734_259, Date(-2010, 9, 1)), 11518 GregDay(-734_230, Date(-2010, 9, 30)), 11519 GregDay(-734_229, Date(-2010, 10, 1)), 11520 GregDay(-734_199, Date(-2010, 10, 31)), 11521 GregDay(-734_198, Date(-2010, 11, 1)), 11522 GregDay(-734_169, Date(-2010, 11, 30)), 11523 GregDay(-734_168, Date(-2010, 12, 1)), 11524 GregDay(-734_139, Date(-2010, 12, 30)), 11525 GregDay(-734_138, Date(-2010, 12, 31)), 11526 GregDay(-731_215, Date(-2001, 1, 1)), 11527 GregDay(-730_850, Date(-2000, 1, 1)), 11528 GregDay(-730_849, Date(-2000, 1, 2)), 11529 GregDay(-730_486, Date(-2000, 12, 30)), 11530 GregDay(-730_485, Date(-2000, 12, 31)), 11531 GregDay(-730_484, Date(-1999, 1, 1)), 11532 GregDay(-694_690, Date(-1901, 1, 1)), 11533 GregDay(-694_325, Date(-1900, 1, 1)), 11534 GregDay(-585_118, Date(-1601, 1, 1)), 11535 GregDay(-584_753, Date(-1600, 1, 1)), 11536 GregDay(-584_388, Date(-1600, 12, 31)), 11537 GregDay(-584_387, Date(-1599, 1, 1)), 11538 GregDay(-365_972, Date(-1001, 1, 1)), 11539 GregDay(-365_607, Date(-1000, 1, 1)), 11540 GregDay(-183_351, Date(-501, 1, 1)), 11541 GregDay(-182_986, Date(-500, 1, 1)), 11542 GregDay(-182_621, Date(-499, 1, 1)), 11543 GregDay(-146_827, Date(-401, 1, 1)), 11544 GregDay(-146_462, Date(-400, 1, 1)), 11545 GregDay(-146_097, Date(-400, 12, 31)), 11546 GregDay(-110_302, Date(-301, 1, 1)), 11547 GregDay(-109_937, Date(-300, 1, 1)), 11548 GregDay(-73_778, Date(-201, 1, 1)), 11549 GregDay(-73_413, Date(-200, 1, 1)), 11550 GregDay(-38_715, Date(-105, 1, 1)), 11551 GregDay(-37_254, Date(-101, 1, 1)), 11552 GregDay(-36_889, Date(-100, 1, 1)), 11553 GregDay(-36_524, Date(-99, 1, 1)), 11554 GregDay(-36_160, Date(-99, 12, 31)), 11555 GregDay(-35_794, Date(-97, 1, 1)), 11556 GregDay(-18_627, Date(-50, 1, 1)), 11557 GregDay(-18_262, Date(-49, 1, 1)), 11558 GregDay(-3652, Date(-9, 1, 1)), 11559 GregDay(-2191, Date(-5, 1, 1)), 11560 GregDay(-1827, Date(-5, 12, 31)), 11561 GregDay(-1826, Date(-4, 1, 1)), 11562 GregDay(-1825, Date(-4, 1, 2)), 11563 GregDay(-1462, Date(-4, 12, 30)), 11564 GregDay(-1461, Date(-4, 12, 31)), 11565 GregDay(-1460, Date(-3, 1, 1)), 11566 GregDay(-1096, Date(-3, 12, 31)), 11567 GregDay(-1095, Date(-2, 1, 1)), 11568 GregDay(-731, Date(-2, 12, 31)), 11569 GregDay(-730, Date(-1, 1, 1)), 11570 GregDay(-367, Date(-1, 12, 30)), 11571 GregDay(-366, Date(-1, 12, 31)), 11572 GregDay(-365, Date(0, 1, 1)), 11573 GregDay(-31, Date(0, 11, 30)), 11574 GregDay(-30, Date(0, 12, 1)), 11575 GregDay(-1, Date(0, 12, 30)), 11576 GregDay(0, Date(0, 12, 31))]; 11577 return result; 11578 } 11579 11580 GregDay[] testGregDaysAD() 11581 { 11582 static result = [GregDay(1, Date(1, 1, 1)), 11583 GregDay(2, Date(1, 1, 2)), 11584 GregDay(32, Date(1, 2, 1)), 11585 GregDay(365, Date(1, 12, 31)), 11586 GregDay(366, Date(2, 1, 1)), 11587 GregDay(731, Date(3, 1, 1)), 11588 GregDay(1096, Date(4, 1, 1)), 11589 GregDay(1097, Date(4, 1, 2)), 11590 GregDay(1460, Date(4, 12, 30)), 11591 GregDay(1461, Date(4, 12, 31)), 11592 GregDay(1462, Date(5, 1, 1)), 11593 GregDay(17_898, Date(50, 1, 1)), 11594 GregDay(35_065, Date(97, 1, 1)), 11595 GregDay(36_160, Date(100, 1, 1)), 11596 GregDay(36_525, Date(101, 1, 1)), 11597 GregDay(37_986, Date(105, 1, 1)), 11598 GregDay(72_684, Date(200, 1, 1)), 11599 GregDay(73_049, Date(201, 1, 1)), 11600 GregDay(109_208, Date(300, 1, 1)), 11601 GregDay(109_573, Date(301, 1, 1)), 11602 GregDay(145_732, Date(400, 1, 1)), 11603 GregDay(146_098, Date(401, 1, 1)), 11604 GregDay(182_257, Date(500, 1, 1)), 11605 GregDay(182_622, Date(501, 1, 1)), 11606 GregDay(364_878, Date(1000, 1, 1)), 11607 GregDay(365_243, Date(1001, 1, 1)), 11608 GregDay(584_023, Date(1600, 1, 1)), 11609 GregDay(584_389, Date(1601, 1, 1)), 11610 GregDay(693_596, Date(1900, 1, 1)), 11611 GregDay(693_961, Date(1901, 1, 1)), 11612 GregDay(729_755, Date(1999, 1, 1)), 11613 GregDay(730_120, Date(2000, 1, 1)), 11614 GregDay(730_121, Date(2000, 1, 2)), 11615 GregDay(730_484, Date(2000, 12, 30)), 11616 GregDay(730_485, Date(2000, 12, 31)), 11617 GregDay(730_486, Date(2001, 1, 1)), 11618 GregDay(733_773, Date(2010, 1, 1)), 11619 GregDay(733_774, Date(2010, 1, 2)), 11620 GregDay(733_803, Date(2010, 1, 31)), 11621 GregDay(733_804, Date(2010, 2, 1)), 11622 GregDay(733_831, Date(2010, 2, 28)), 11623 GregDay(733_832, Date(2010, 3, 1)), 11624 GregDay(733_862, Date(2010, 3, 31)), 11625 GregDay(733_863, Date(2010, 4, 1)), 11626 GregDay(733_892, Date(2010, 4, 30)), 11627 GregDay(733_893, Date(2010, 5, 1)), 11628 GregDay(733_923, Date(2010, 5, 31)), 11629 GregDay(733_924, Date(2010, 6, 1)), 11630 GregDay(733_953, Date(2010, 6, 30)), 11631 GregDay(733_954, Date(2010, 7, 1)), 11632 GregDay(733_984, Date(2010, 7, 31)), 11633 GregDay(733_985, Date(2010, 8, 1)), 11634 GregDay(734_015, Date(2010, 8, 31)), 11635 GregDay(734_016, Date(2010, 9, 1)), 11636 GregDay(734_045, Date(2010, 9, 30)), 11637 GregDay(734_046, Date(2010, 10, 1)), 11638 GregDay(734_076, Date(2010, 10, 31)), 11639 GregDay(734_077, Date(2010, 11, 1)), 11640 GregDay(734_106, Date(2010, 11, 30)), 11641 GregDay(734_107, Date(2010, 12, 1)), 11642 GregDay(734_136, Date(2010, 12, 30)), 11643 GregDay(734_137, Date(2010, 12, 31)), 11644 GregDay(734_503, Date(2012, 1, 1)), 11645 GregDay(734_534, Date(2012, 2, 1)), 11646 GregDay(734_561, Date(2012, 2, 28)), 11647 GregDay(734_562, Date(2012, 2, 29)), 11648 GregDay(734_563, Date(2012, 3, 1)), 11649 GregDay(734_858, Date(2012, 12, 21))]; 11650 return result; 11651 } 11652 11653 // I'd use a Tuple, but I get forward reference errors if I try. 11654 struct DayOfYear { int day; MonthDay md; } 11655 DayOfYear[] testDaysOfYear() 11656 { 11657 static result = [DayOfYear(1, MonthDay(1, 1)), 11658 DayOfYear(2, MonthDay(1, 2)), 11659 DayOfYear(3, MonthDay(1, 3)), 11660 DayOfYear(31, MonthDay(1, 31)), 11661 DayOfYear(32, MonthDay(2, 1)), 11662 DayOfYear(59, MonthDay(2, 28)), 11663 DayOfYear(60, MonthDay(3, 1)), 11664 DayOfYear(90, MonthDay(3, 31)), 11665 DayOfYear(91, MonthDay(4, 1)), 11666 DayOfYear(120, MonthDay(4, 30)), 11667 DayOfYear(121, MonthDay(5, 1)), 11668 DayOfYear(151, MonthDay(5, 31)), 11669 DayOfYear(152, MonthDay(6, 1)), 11670 DayOfYear(181, MonthDay(6, 30)), 11671 DayOfYear(182, MonthDay(7, 1)), 11672 DayOfYear(212, MonthDay(7, 31)), 11673 DayOfYear(213, MonthDay(8, 1)), 11674 DayOfYear(243, MonthDay(8, 31)), 11675 DayOfYear(244, MonthDay(9, 1)), 11676 DayOfYear(273, MonthDay(9, 30)), 11677 DayOfYear(274, MonthDay(10, 1)), 11678 DayOfYear(304, MonthDay(10, 31)), 11679 DayOfYear(305, MonthDay(11, 1)), 11680 DayOfYear(334, MonthDay(11, 30)), 11681 DayOfYear(335, MonthDay(12, 1)), 11682 DayOfYear(363, MonthDay(12, 29)), 11683 DayOfYear(364, MonthDay(12, 30)), 11684 DayOfYear(365, MonthDay(12, 31))]; 11685 return result; 11686 } 11687 11688 DayOfYear[] testDaysOfLeapYear() 11689 { 11690 static result = [DayOfYear(1, MonthDay(1, 1)), 11691 DayOfYear(2, MonthDay(1, 2)), 11692 DayOfYear(3, MonthDay(1, 3)), 11693 DayOfYear(31, MonthDay(1, 31)), 11694 DayOfYear(32, MonthDay(2, 1)), 11695 DayOfYear(59, MonthDay(2, 28)), 11696 DayOfYear(60, MonthDay(2, 29)), 11697 DayOfYear(61, MonthDay(3, 1)), 11698 DayOfYear(91, MonthDay(3, 31)), 11699 DayOfYear(92, MonthDay(4, 1)), 11700 DayOfYear(121, MonthDay(4, 30)), 11701 DayOfYear(122, MonthDay(5, 1)), 11702 DayOfYear(152, MonthDay(5, 31)), 11703 DayOfYear(153, MonthDay(6, 1)), 11704 DayOfYear(182, MonthDay(6, 30)), 11705 DayOfYear(183, MonthDay(7, 1)), 11706 DayOfYear(213, MonthDay(7, 31)), 11707 DayOfYear(214, MonthDay(8, 1)), 11708 DayOfYear(244, MonthDay(8, 31)), 11709 DayOfYear(245, MonthDay(9, 1)), 11710 DayOfYear(274, MonthDay(9, 30)), 11711 DayOfYear(275, MonthDay(10, 1)), 11712 DayOfYear(305, MonthDay(10, 31)), 11713 DayOfYear(306, MonthDay(11, 1)), 11714 DayOfYear(335, MonthDay(11, 30)), 11715 DayOfYear(336, MonthDay(12, 1)), 11716 DayOfYear(364, MonthDay(12, 29)), 11717 DayOfYear(365, MonthDay(12, 30)), 11718 DayOfYear(366, MonthDay(12, 31))]; 11719 return result; 11720 } 11721 11722 void initializeTests() 11723 { 11724 import std.algorithm.sorting : sort; 11725 import std.typecons : Rebindable; 11726 immutable lt = LocalTime().utcToTZ(0); 11727 currLocalDiffFromUTC = dur!"hnsecs"(lt); 11728 11729 version (Posix) 11730 { 11731 import std.datetime.timezone : PosixTimeZone; 11732 immutable otherTZ = lt < 0 ? PosixTimeZone.getTimeZone("Australia/Sydney") 11733 : PosixTimeZone.getTimeZone("America/Denver"); 11734 } 11735 else version (Windows) 11736 { 11737 import std.datetime.timezone : WindowsTimeZone; 11738 immutable otherTZ = lt < 0 ? WindowsTimeZone.getTimeZone("AUS Eastern Standard Time") 11739 : WindowsTimeZone.getTimeZone("Mountain Standard Time"); 11740 } 11741 11742 immutable ot = otherTZ.utcToTZ(0); 11743 11744 auto diffs = [0L, lt, ot]; 11745 auto diffAA = [0L : Rebindable!(immutable TimeZone)(UTC())]; 11746 diffAA[lt] = Rebindable!(immutable TimeZone)(LocalTime()); 11747 diffAA[ot] = Rebindable!(immutable TimeZone)(otherTZ); 11748 11749 sort(diffs); 11750 testTZs = [diffAA[diffs[0]], diffAA[diffs[1]], diffAA[diffs[2]]]; 11751 11752 testFracSecs = [Duration.zero, hnsecs(1), hnsecs(5007), hnsecs(9_999_999)]; 11753 11754 foreach (year; testYearsBC) 11755 { 11756 foreach (md; testMonthDays) 11757 testDatesBC ~= Date(year, md.month, md.day); 11758 } 11759 11760 foreach (year; testYearsAD) 11761 { 11762 foreach (md; testMonthDays) 11763 testDatesAD ~= Date(year, md.month, md.day); 11764 } 11765 11766 foreach (dt; testDatesBC) 11767 { 11768 foreach (tod; testTODs) 11769 testDateTimesBC ~= DateTime(dt, tod); 11770 } 11771 11772 foreach (dt; testDatesAD) 11773 { 11774 foreach (tod; testTODs) 11775 testDateTimesAD ~= DateTime(dt, tod); 11776 } 11777 11778 foreach (dt; testDateTimesBC) 11779 { 11780 foreach (tz; testTZs) 11781 { 11782 foreach (fs; testFracSecs) 11783 testSysTimesBC ~= SysTime(dt, fs, tz); 11784 } 11785 } 11786 11787 foreach (dt; testDateTimesAD) 11788 { 11789 foreach (tz; testTZs) 11790 { 11791 foreach (fs; testFracSecs) 11792 testSysTimesAD ~= SysTime(dt, fs, tz); 11793 } 11794 } 11795 } 11796 }