1 /****************************************************************************** 2 3 copyright: Copyright (c) 2007 Tango. All rights reserved 4 5 license: BSD style: $(LICENSE) 6 7 version: mid 2005: Initial release 8 Apr 2007: heavily reshaped 9 Dec 2007: moved to tango.time 10 11 author: John Chapman, Kris, scheivguy 12 13 ******************************************************************************/ 14 15 module tango.time.Time; 16 17 /****************************************************************************** 18 19 This struct represents a length of time. The underlying representation is 20 in units of 100ns. This allows the length of time to span to roughly 21 +/- 10000 years. 22 23 Notably missing from this is a representation of weeks, months and years. 24 This is because weeks, months, and years vary according to local calendars. 25 Use tango.time.chrono.* to deal with these concepts. 26 27 Note: nobody should change this struct without really good reason as it is 28 required to be a part of some interfaces. It should be treated as a 29 builtin type. Also note that there is deliberately no opCall constructor 30 here, since it tends to produce too much overhead. If you wish to build 31 a TimeSpan struct from a ticks value, use D's builtin ability to create a 32 struct with given member values (See the description of ticks() for an 33 example of how to do this). 34 35 Example: 36 ------------------- 37 Time start = Clock.now; 38 Thread.sleep(0.150); 39 Stdout.formatln("slept for {} ms", (Clock.now-start).millis); 40 ------------------- 41 42 See_Also: tango.core.Thread, tango.time.Clock 43 44 ******************************************************************************/ 45 46 struct TimeSpan 47 { 48 // this is the only member of the struct. 49 package long ticks_; 50 51 // useful constants. Shouldn't be used in normal code, use the 52 // static TimeSpan members below instead. i.e. instead of 53 // TimeSpan.TicksPerSecond, use TimeSpan.second.ticks 54 // 55 enum : long 56 { 57 /// basic tick values 58 NanosecondsPerTick = 100, 59 TicksPerMicrosecond = 1000 / NanosecondsPerTick, 60 TicksPerMillisecond = 1000 * TicksPerMicrosecond, 61 TicksPerSecond = 1000 * TicksPerMillisecond, 62 TicksPerMinute = 60 * TicksPerSecond, 63 TicksPerHour = 60 * TicksPerMinute, 64 TicksPerDay = 24 * TicksPerHour, 65 66 // millisecond counts 67 MillisPerSecond = 1000, 68 MillisPerMinute = MillisPerSecond * 60, 69 MillisPerHour = MillisPerMinute * 60, 70 MillisPerDay = MillisPerHour * 24, 71 72 /// day counts 73 DaysPerYear = 365, 74 DaysPer4Years = DaysPerYear * 4 + 1, 75 DaysPer100Years = DaysPer4Years * 25 - 1, 76 DaysPer400Years = DaysPer100Years * 4 + 1, 77 78 // epoch counts 79 Epoch1601 = DaysPer400Years * 4 * TicksPerDay, 80 Epoch1970 = Epoch1601 + TicksPerSecond * 11644473600L, 81 } 82 83 /** 84 * Minimum TimeSpan 85 */ 86 enum TimeSpan min = TimeSpan(long.min); 87 88 /** 89 * Maximum TimeSpan 90 */ 91 enum TimeSpan max = TimeSpan(long.max); 92 93 /** 94 * Zero TimeSpan. Useful for comparisons. 95 */ 96 enum TimeSpan zero = TimeSpan(0); 97 98 /** 99 * Get the number of ticks that this timespan represents. This can be 100 * used to construct another TimeSpan: 101 * 102 * -------- 103 * long ticks = myTimeSpan.ticks; 104 * TimeSpan copyOfMyTimeSpan = TimeSpan(ticks); 105 * -------- 106 */ 107 @property const long ticks() 108 { 109 return ticks_; 110 } 111 112 /** 113 * Determines whether two TimeSpan values are equal 114 */ 115 const bool opEquals(const(TimeSpan) t) 116 { 117 return ticks_ is t.ticks_; 118 } 119 120 /** 121 * Compares this object against another TimeSpan value. 122 */ 123 int opCmp(const ref TimeSpan t) const 124 { 125 if (ticks_ < t.ticks_) 126 return -1; 127 128 if (ticks_ > t.ticks_) 129 return 1; 130 131 return 0; 132 } 133 134 /* To support manifest constants */ 135 int opCmp(const TimeSpan t) const 136 { 137 return opCmp(t); 138 } 139 140 /** 141 * Add the TimeSpan given to this TimeSpan returning a new TimeSpan. 142 * 143 * Params: t = A TimeSpan value to add 144 * Returns: A TimeSpan value that is the sum of this instance and t. 145 */ 146 const TimeSpan opBinary(immutable(char)[] o : "+")(const(TimeSpan) t) 147 { 148 return TimeSpan(ticks_ + t.ticks_); 149 } 150 151 /** 152 * Add the specified TimeSpan to this TimeSpan, assigning the result 153 * to this instance. 154 * 155 * Params: t = A TimeSpan value to add 156 * Returns: a copy of this instance after adding t. 157 */ 158 TimeSpan opOpAssign(immutable(char)[] o : "+")(const(TimeSpan) t) 159 { 160 ticks_ += t.ticks_; 161 return this; 162 } 163 164 /** 165 * Subtract the specified TimeSpan from this TimeSpan. 166 * 167 * Params: t = A TimeSpan to subtract 168 * Returns: A new timespan which is the difference between this 169 * instance and t 170 */ 171 const TimeSpan opBinary(immutable(char)[] o : "-")(const(TimeSpan) t) 172 { 173 return TimeSpan(ticks_ - t.ticks_); 174 } 175 176 /** 177 * 178 * Subtract the specified TimeSpan from this TimeSpan and assign the 179 * 180 * Params: t = A TimeSpan to subtract 181 * Returns: A copy of this instance after subtracting t. 182 */ 183 TimeSpan opOpAssign(immutable(char)[] o : "-")(const(TimeSpan) t) 184 { 185 ticks_ -= t.ticks_; 186 return this; 187 } 188 189 /** 190 * Scale the TimeSpan by the specified amount. This should not be 191 * used to convert to a different unit. Use the unit accessors 192 * instead. This should only be used as a scaling mechanism. For 193 * example, if you have a timeout and you want to sleep for twice the 194 * timeout, you would use timeout * 2. 195 * 196 * Params: v = A multiplier to use for scaling this time span. 197 * Returns: A new TimeSpan that is scaled by v 198 */ 199 const TimeSpan opBinary(immutable(char)[] o : "*")(long v) 200 { 201 return TimeSpan(ticks_ * v); 202 } 203 204 /** 205 * Scales this TimeSpan and assigns the result to this instance. 206 * 207 * Params: v = A multipler to use for scaling 208 * Returns: A copy of this instance after scaling 209 */ 210 TimeSpan opOpAssign(immutable(char)[] o : "*")(long v) 211 { 212 ticks_ *= v; 213 return this; 214 } 215 216 /** 217 * Divide the TimeSpan by the specified amount. This should not be 218 * used to convert to a different unit. Use the unit accessors 219 * instead. This should only be used as a scaling mechanism. For 220 * example, if you have a timeout and you want to sleep for half the 221 * timeout, you would use timeout / 2. 222 * 223 * 224 * Params: v = A divisor to use for scaling this time span. 225 * Returns: A new TimeSpan that is divided by v 226 */ 227 const TimeSpan opBinary(immutable(char)[] o : "/")(long v) 228 { 229 return TimeSpan(ticks_ / v); 230 } 231 232 /** 233 * Divides this TimeSpan and assigns the result to this instance. 234 * 235 * Params: v = A multipler to use for dividing 236 * Returns: A copy of this instance after dividing 237 */ 238 TimeSpan opOpAssign(immutable(char)[] o : "/")(long v) 239 { 240 ticks_ /= v; 241 return this; 242 } 243 244 /** 245 * Perform integer division with the given time span. 246 * 247 * Params: t = A divisor used for dividing 248 * Returns: The result of integer division between this instance and 249 * t. 250 */ 251 const long opBinary(immutable(char)[] o : "/")(const(TimeSpan) t) 252 { 253 return ticks_ / t.ticks; 254 } 255 256 /** 257 * Negate a time span 258 * 259 * Returns: The negative equivalent to this time span 260 */ 261 const TimeSpan opUnary(immutable(char)[] o : "-")() 262 { 263 return TimeSpan(-ticks_); 264 } 265 266 /** 267 * Convert to nanoseconds 268 * 269 * Note: this may incur loss of data because nanoseconds cannot 270 * represent the range of data a TimeSpan can represent. 271 * 272 * Returns: The number of nanoseconds that this TimeSpan represents. 273 */ 274 @property const long nanos() 275 { 276 return ticks_ * NanosecondsPerTick; 277 } 278 279 /** 280 * Convert to microseconds 281 * 282 * Returns: The number of microseconds that this TimeSpan represents. 283 */ 284 @property const long micros() 285 { 286 return ticks_ / TicksPerMicrosecond; 287 } 288 289 /** 290 * Convert to milliseconds 291 * 292 * Returns: The number of milliseconds that this TimeSpan represents. 293 */ 294 @property const long millis() 295 { 296 return ticks_ / TicksPerMillisecond; 297 } 298 299 /** 300 * Convert to seconds 301 * 302 * Returns: The number of seconds that this TimeSpan represents. 303 */ 304 @property const long seconds() 305 { 306 return ticks_ / TicksPerSecond; 307 } 308 309 /** 310 * Convert to minutes 311 * 312 * Returns: The number of minutes that this TimeSpan represents. 313 */ 314 @property const long minutes() 315 { 316 return ticks_ / TicksPerMinute; 317 } 318 319 /** 320 * Convert to hours 321 * 322 * Returns: The number of hours that this TimeSpan represents. 323 */ 324 @property const long hours() 325 { 326 return ticks_ / TicksPerHour; 327 } 328 329 /** 330 * Convert to days 331 * 332 * Returns: The number of days that this TimeSpan represents. 333 */ 334 @property const long days() 335 { 336 return ticks_ / TicksPerDay; 337 } 338 339 /** 340 * Convert to a floating point interval representing seconds. 341 * 342 * Note: This may cause a loss of precision as a double cannot exactly 343 * represent some fractional values. 344 * 345 * Returns: An interval representing the seconds and fractional 346 * seconds that this TimeSpan represents. 347 */ 348 @property const double interval() 349 { 350 return (cast(double) ticks_) / TicksPerSecond; 351 } 352 353 /** 354 * Convert to TimeOfDay 355 * 356 * Returns: the TimeOfDay this TimeSpan represents. 357 */ 358 @property const TimeOfDay time() 359 { 360 return TimeOfDay(ticks_); 361 } 362 363 /** 364 * Construct a TimeSpan from the given number of nanoseconds 365 * 366 * Note: This may cause a loss of data since a TimeSpan's resolution 367 * is in 100ns increments. 368 * 369 * Params: value = The number of nanoseconds. 370 * Returns: A TimeSpan representing the given number of nanoseconds. 371 */ 372 static TimeSpan fromNanos(long value) 373 { 374 return TimeSpan(value / NanosecondsPerTick); 375 } 376 377 /** 378 * Construct a TimeSpan from the given number of microseconds 379 * 380 * Params: value = The number of microseconds. 381 * Returns: A TimeSpan representing the given number of microseconds. 382 */ 383 static TimeSpan fromMicros(long value) 384 { 385 return TimeSpan(TicksPerMicrosecond * value); 386 } 387 388 /** 389 * Construct a TimeSpan from the given number of milliseconds 390 * 391 * Params: value = The number of milliseconds. 392 * Returns: A TimeSpan representing the given number of milliseconds. 393 */ 394 static TimeSpan fromMillis(long value) 395 { 396 return TimeSpan(TicksPerMillisecond * value); 397 } 398 399 /** 400 * Construct a TimeSpan from the given number of seconds 401 * 402 * Params: value = The number of seconds. 403 * Returns: A TimeSpan representing the given number of seconds. 404 */ 405 static TimeSpan fromSeconds(long value) 406 { 407 return TimeSpan(TicksPerSecond * value); 408 } 409 410 /** 411 * Construct a TimeSpan from the given number of minutes 412 * 413 * Params: value = The number of minutes. 414 * Returns: A TimeSpan representing the given number of minutes. 415 */ 416 static TimeSpan fromMinutes(long value) 417 { 418 return TimeSpan(TicksPerMinute * value); 419 } 420 421 /** 422 * Construct a TimeSpan from the given number of hours 423 * 424 * Params: value = The number of hours. 425 * Returns: A TimeSpan representing the given number of hours. 426 */ 427 static TimeSpan fromHours(long value) 428 { 429 return TimeSpan(TicksPerHour * value); 430 } 431 432 /** 433 * Construct a TimeSpan from the given number of days 434 * 435 * Params: value = The number of days. 436 * Returns: A TimeSpan representing the given number of days. 437 */ 438 static TimeSpan fromDays(long value) 439 { 440 return TimeSpan(TicksPerDay * value); 441 } 442 443 /** 444 * Construct a TimeSpan from the given interval. The interval 445 * represents seconds as a double. This allows both whole and 446 * fractional seconds to be passed in. 447 * 448 * Params: value = The interval to convert in seconds. 449 * Returns: A TimeSpan representing the given interval. 450 */ 451 static TimeSpan fromInterval(double sec) 452 { 453 return TimeSpan(cast(long)(sec * TicksPerSecond + .1)); 454 } 455 } 456 457 458 /****************************************************************************** 459 460 Represents a point in time. 461 462 Remarks: Time represents dates and times between 12:00:00 463 midnight on January 1, 10000 BC and 11:59:59 PM on December 31, 464 9999 AD. 465 466 Time values are measured in 100-nanosecond intervals, or ticks. 467 A date value is the number of ticks that have elapsed since 468 12:00:00 midnight on January 1, 0001 AD in the Gregorian 469 calendar. 470 471 Negative Time values are offsets from that same reference point, 472 but backwards in history. Time values are not specific to any 473 calendar, but for an example, the beginning of December 31, 1 BC 474 in the Gregorian calendar is Time.epoch - TimeSpan.days(1). 475 476 ******************************************************************************/ 477 478 struct Time 479 { 480 private long ticks_; 481 482 private enum : long 483 { 484 maximum = (TimeSpan.DaysPer400Years * 25 - 366) * TimeSpan.TicksPerDay - 1, 485 minimum = -((TimeSpan.DaysPer400Years * 25 - 366) * TimeSpan.TicksPerDay - 1), 486 } 487 488 /// Represents the smallest and largest Time value. 489 enum Time min = Time(minimum), 490 max = Time(maximum); 491 492 /// Represents the epoch (1/1/0001) 493 enum Time epoch = Time(0L); 494 495 /// Represents the epoch of 1/1/1601 (Commonly used in Windows systems) 496 enum Time epoch1601 = Time(TimeSpan.Epoch1601); 497 498 /// Represents the epoch of 1/1/1970 (Commonly used in Unix systems) 499 enum Time epoch1970 = Time(TimeSpan.Epoch1970); 500 501 /********************************************************************** 502 503 $(I Property.) Retrieves the number of ticks for this Time. 504 This value can be used to construct another Time struct by 505 writing: 506 507 --------- 508 long ticks = myTime.ticks; 509 Time copyOfMyTime = Time(ticks); 510 --------- 511 512 513 Returns: A long represented by the time of this 514 instance. 515 516 **********************************************************************/ 517 518 @property const long ticks () 519 { 520 return ticks_; 521 } 522 523 /********************************************************************** 524 525 Determines whether two Time values are equal. 526 527 Params: value = A Time _value. 528 Returns: true if both instances are equal; otherwise, false 529 530 **********************************************************************/ 531 532 const bool opEquals (const(Time) t) 533 { 534 return ticks_ is t.ticks_; 535 } 536 537 /********************************************************************** 538 539 Compares two Time values. 540 541 **********************************************************************/ 542 543 int opCmp (const ref Time t) const 544 { 545 if (ticks_ < t.ticks_) 546 return -1; 547 548 if (ticks_ > t.ticks_) 549 return 1; 550 551 return 0; 552 } 553 554 /* To support manifest constants */ 555 int opCmp (const Time t) const 556 { 557 return opCmp(t); 558 } 559 560 /********************************************************************** 561 562 Adds the specified time span to the time, returning a new 563 time. 564 565 Params: t = A TimeSpan value. 566 Returns: A Time that is the sum of this instance and t. 567 568 **********************************************************************/ 569 570 const Time opBinary(immutable(char)[] o : "+") (const(TimeSpan) t) 571 { 572 return Time (ticks_ + t.ticks_); 573 } 574 575 /********************************************************************** 576 577 Adds the specified time span to the time, assigning 578 the result to this instance. 579 580 Params: t = A TimeSpan value. 581 Returns: The current Time instance, with t added to the 582 time. 583 584 **********************************************************************/ 585 586 Time opOpAssign(immutable(char)[] o : "+") (const(TimeSpan) t) 587 { 588 ticks_ += t.ticks_; 589 return this; 590 } 591 592 /********************************************************************** 593 594 Subtracts the specified time span from the time, 595 returning a new time. 596 597 Params: t = A TimeSpan value. 598 Returns: A Time whose value is the value of this instance 599 minus the value of t. 600 601 **********************************************************************/ 602 603 const Time opBinary(immutable(char)[] o : "-") (const(TimeSpan) t) 604 { 605 return Time (ticks_ - t.ticks_); 606 } 607 608 /********************************************************************** 609 610 Returns a time span which represents the difference in time 611 between this and the given Time. 612 613 Params: t = A Time value. 614 Returns: A TimeSpan which represents the difference between 615 this and t. 616 617 **********************************************************************/ 618 619 const TimeSpan opBinary(immutable(char)[] o : "-") (const(Time) t) 620 { 621 return TimeSpan(ticks_ - t.ticks_); 622 } 623 624 /********************************************************************** 625 626 Subtracts the specified time span from the time, 627 assigning the result to this instance. 628 629 Params: t = A TimeSpan value. 630 Returns: The current Time instance, with t subtracted 631 from the time. 632 633 **********************************************************************/ 634 635 Time opOpAssign(immutable(char)[] o : "-") (const(TimeSpan) t) 636 { 637 ticks_ -= t.ticks_; 638 return this; 639 } 640 641 /********************************************************************** 642 643 $(I Property.) Retrieves the date component. 644 645 Returns: A new Time instance with the same date as 646 this instance, but with the time truncated. 647 648 **********************************************************************/ 649 650 @property const Time date () 651 { 652 return this - TimeOfDay.modulo24(ticks_); 653 } 654 655 /********************************************************************** 656 657 $(I Property.) Retrieves the time of day. 658 659 Returns: A TimeOfDay representing the fraction of the day 660 elapsed since midnight. 661 662 **********************************************************************/ 663 664 @property const TimeOfDay time () 665 { 666 return TimeOfDay (ticks_); 667 } 668 669 /********************************************************************** 670 671 $(I Property.) Retrieves the equivalent TimeSpan. 672 673 Returns: A TimeSpan representing this Time. 674 675 **********************************************************************/ 676 677 @property const TimeSpan span () 678 { 679 return TimeSpan (ticks_); 680 } 681 682 /********************************************************************** 683 684 $(I Property.) Retrieves a TimeSpan that corresponds to Unix 685 time (time since 1/1/1970). Use the TimeSpan accessors to get 686 the time in seconds, milliseconds, etc. 687 688 Returns: A TimeSpan representing this Time as Unix time. 689 690 ------------------------------------- 691 auto unixTime = Clock.now.unix.seconds; 692 auto javaTime = Clock.now.unix.millis; 693 ------------------------------------- 694 695 **********************************************************************/ 696 697 @property const TimeSpan unix() 698 { 699 return TimeSpan(ticks_ - epoch1970.ticks_); 700 } 701 } 702 703 704 /****************************************************************************** 705 706 Represents a time of day. This is different from TimeSpan in that 707 each component is represented within the limits of everyday time, 708 rather than from the start of the Epoch. Effectively, the TimeOfDay 709 epoch is the first second of each day. 710 711 This is handy for dealing strictly with a 24-hour clock instead of 712 potentially thousands of years. For example: 713 --- 714 auto time = Clock.now.time; 715 assert (time.millis < 1000); 716 assert (time.seconds < 60); 717 assert (time.minutes < 60); 718 assert (time.hours < 24); 719 --- 720 721 You can create a TimeOfDay from an existing Time or TimeSpan instance 722 via the respective time() method. To convert back to a TimeSpan, use 723 the span() method 724 725 ******************************************************************************/ 726 727 struct TimeOfDay 728 { 729 /** 730 * hours component of the time of day. This should be between 0 and 731 * 23, inclusive. 732 */ 733 public uint hours; 734 735 /** 736 * minutes component of the time of day. This should be between 0 and 737 * 59, inclusive. 738 */ 739 public uint minutes; 740 741 /** 742 * seconds component of the time of day. This should be between 0 and 743 * 59, inclusive. 744 */ 745 public uint seconds; 746 747 /** 748 * milliseconds component of the time of day. This should be between 749 * 0 and 999, inclusive. 750 */ 751 public uint millis; 752 753 /** 754 * constructor. 755 * Params: hours = number of hours since midnight 756 * minutes = number of minutes into the hour 757 * seconds = number of seconds into the minute 758 * millis = number of milliseconds into the second 759 * 760 * Returns: a TimeOfDay representing the given time fields. 761 * 762 * Note: There is no verification of the range of values, or 763 * normalization made. So if you pass in larger values than the 764 * maximum value for that field, they will be stored as that value. 765 * 766 * example: 767 * -------------- 768 * auto tod = TimeOfDay(100, 100, 100, 10000); 769 * assert(tod.hours == 100); 770 * assert(tod.minutes == 100); 771 * assert(tod.seconds == 100); 772 * assert(tod.millis == 10000); 773 * -------------- 774 */ 775 static TimeOfDay opCall (uint hours, uint minutes, uint seconds, uint millis=0) 776 { 777 TimeOfDay t = void; 778 t.hours = hours; 779 t.minutes = minutes; 780 t.seconds = seconds; 781 t.millis = millis; 782 return t; 783 } 784 785 /** 786 * constructor. 787 * Params: ticks = ticks representing a Time value. This is normalized 788 * so that it represent a time of day (modulo-24 etc) 789 * 790 * Returns: a TimeOfDay value that corresponds to the time of day of 791 * the given number of ticks. 792 */ 793 static TimeOfDay opCall (long ticks) 794 { 795 TimeOfDay t = void; 796 ticks = modulo24(ticks).ticks_; 797 t.millis = cast(uint) (ticks / TimeSpan.TicksPerMillisecond); 798 t.seconds = (t.millis / 1_000) % 60; 799 t.minutes = (t.millis / 60_000) % 60; 800 t.hours = (t.millis / 3_600_000) % 24; 801 t.millis %= 1000; 802 return t; 803 } 804 805 /** 806 * construct a TimeSpan from the current fields 807 * 808 * Returns: a TimeOfDay representing the field values. 809 * 810 * Note: that fields are not checked against a valid range, so 811 * setting 60 for minutes is allowed, and will just add 1 to the hour 812 * component, and set the minute component to 0. The result is 813 * normalized, so the hours wrap. If you pass in 25 hours, the 814 * resulting TimeOfDay will have a hour component of 1. 815 */ 816 @property const TimeSpan span () 817 { 818 return TimeSpan.fromHours(hours) + 819 TimeSpan.fromMinutes(minutes) + 820 TimeSpan.fromSeconds(seconds) + 821 TimeSpan.fromMillis(millis); 822 } 823 824 /** 825 * internal routine to adjust ticks by one day. Also adjusts for 826 * offsets in the BC era 827 */ 828 package static TimeSpan modulo24 (long ticks) 829 { 830 ticks %= TimeSpan.TicksPerDay; 831 if (ticks < 0) 832 ticks += TimeSpan.TicksPerDay; 833 return TimeSpan (ticks); 834 } 835 } 836 837 /****************************************************************************** 838 839 Generic Date representation 840 841 ******************************************************************************/ 842 843 struct Date 844 { 845 public uint era, /// AD, BC 846 day, /// 1 .. 31 847 year, /// 0 to 9999 848 month, /// 1 .. 12 849 dow, /// 0 .. 6 850 doy; /// 1 .. 366 851 } 852 853 854 /****************************************************************************** 855 856 Combination of a Date and a TimeOfDay 857 858 ******************************************************************************/ 859 860 struct DateTime 861 { 862 public Date date; /// date representation 863 public TimeOfDay time; /// time representation 864 } 865 866 867 868 869 /****************************************************************************** 870 871 ******************************************************************************/ 872 873 debug (UnitTest) 874 { 875 unittest 876 { 877 assert(TimeSpan.zero > TimeSpan.min); 878 assert(TimeSpan.max > TimeSpan.zero); 879 assert(TimeSpan.max > TimeSpan.min); 880 assert(TimeSpan.zero >= TimeSpan.zero); 881 assert(TimeSpan.zero <= TimeSpan.zero); 882 assert(TimeSpan.max >= TimeSpan.max); 883 assert(TimeSpan.max <= TimeSpan.max); 884 assert(TimeSpan.min >= TimeSpan.min); 885 assert(TimeSpan.min <= TimeSpan.min); 886 887 assert (TimeSpan.fromSeconds(50).seconds is 50); 888 assert (TimeSpan.fromSeconds(5000).seconds is 5000); 889 assert (TimeSpan.fromMinutes(50).minutes is 50); 890 assert (TimeSpan.fromMinutes(5000).minutes is 5000); 891 assert (TimeSpan.fromHours(23).hours is 23); 892 assert (TimeSpan.fromHours(5000).hours is 5000); 893 assert (TimeSpan.fromDays(6).days is 6); 894 assert (TimeSpan.fromDays(5000).days is 5000); 895 896 assert (TimeSpan.fromSeconds(50).time.seconds is 50); 897 assert (TimeSpan.fromSeconds(5000).time.seconds is 5000 % 60); 898 assert (TimeSpan.fromMinutes(50).time.minutes is 50); 899 assert (TimeSpan.fromMinutes(5000).time.minutes is 5000 % 60); 900 assert (TimeSpan.fromHours(23).time.hours is 23); 901 assert (TimeSpan.fromHours(5000).time.hours is 5000 % 24); 902 903 auto ts = TimeSpan.fromHours(20); 904 assert (TimeSpan.fromHours(10) + TimeSpan.fromHours(10) == ts); 905 assert (TimeSpan.fromHours(30) - TimeSpan.fromHours(10) == ts); 906 auto ts2 = TimeSpan.fromHours(10); 907 ts2 += TimeSpan.fromHours(10); 908 assert(ts2 == ts); 909 910 auto tod = TimeOfDay (25, 2, 3, 4); 911 tod = tod.span.time; 912 assert (tod.hours is 1); 913 assert (tod.minutes is 2); 914 assert (tod.seconds is 3); 915 assert (tod.millis is 4); 916 } 917 } 918 919 920 /******************************************************************************* 921 922 *******************************************************************************/ 923 924 debug (Time) 925 { 926 import tango.io.Stdout; 927 import tango.time.Clock; 928 import tango.time.chrono.Gregorian; 929 930 Time foo() 931 { 932 auto d = Time(10); 933 auto e = TimeSpan(20); 934 935 return d + e; 936 } 937 938 void main() 939 { 940 auto c = foo(); 941 Stdout (c.ticks).newline; 942 943 944 auto t = TimeSpan(1); 945 auto h = t.hours; 946 auto m = t.time.minutes; 947 948 auto now = Clock.now; 949 auto time = now.time; 950 auto date = Gregorian.generic.toDate (now); 951 now = Gregorian.generic.toTime (date, time); 952 } 953 } 954