| // Written in the D programming language |
| |
| /++ |
| License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). |
| Authors: Jonathan M Davis |
| Source: $(PHOBOSSRC std/datetime/_date.d) |
| +/ |
| module std.datetime.date; |
| |
| import core.time; |
| import std.traits : isSomeString, Unqual; |
| import std.typecons : Flag; |
| |
| version (unittest) import std.exception : assertThrown; |
| |
| |
| @safe unittest |
| { |
| initializeTests(); |
| } |
| |
| |
| /++ |
| Exception type used by std.datetime. It's an alias to |
| $(REF TimeException,core,time). Either can be caught without concern about |
| which module it came from. |
| +/ |
| alias DateTimeException = TimeException; |
| |
| |
| /++ |
| Represents the 12 months of the Gregorian year (January is 1). |
| +/ |
| enum Month : ubyte |
| { |
| jan = 1, /// |
| feb, /// |
| mar, /// |
| apr, /// |
| may, /// |
| jun, /// |
| jul, /// |
| aug, /// |
| sep, /// |
| oct, /// |
| nov, /// |
| dec /// |
| } |
| |
| |
| /++ |
| Represents the 7 days of the Gregorian week (Sunday is 0). |
| +/ |
| enum DayOfWeek : ubyte |
| { |
| sun = 0, /// |
| mon, /// |
| tue, /// |
| wed, /// |
| thu, /// |
| fri, /// |
| sat /// |
| } |
| |
| |
| /++ |
| In some date calculations, adding months or years can cause the date to fall |
| on a day of the month which is not valid (e.g. February 29th 2001 or |
| June 31st 2000). If overflow is allowed (as is the default), then the month |
| will be incremented accordingly (so, February 29th 2001 would become |
| March 1st 2001, and June 31st 2000 would become July 1st 2000). If overflow |
| is not allowed, then the day will be adjusted to the last valid day in that |
| month (so, February 29th 2001 would become February 28th 2001 and |
| June 31st 2000 would become June 30th 2000). |
| |
| AllowDayOverflow only applies to calculations involving months or years. |
| |
| If set to $(D AllowDayOverflow.no), then day overflow is not allowed. |
| |
| Otherwise, if set to $(D AllowDayOverflow.yes), then day overflow is |
| allowed. |
| +/ |
| alias AllowDayOverflow = Flag!"allowDayOverflow"; |
| |
| |
| /++ |
| Array of the strings representing time units, starting with the smallest |
| unit and going to the largest. It does not include $(D "nsecs"). |
| |
| Includes $(D "hnsecs") (hecto-nanoseconds (100 ns)), |
| $(D "usecs") (microseconds), $(D "msecs") (milliseconds), $(D "seconds"), |
| $(D "minutes"), $(D "hours"), $(D "days"), $(D "weeks"), $(D "months"), and |
| $(D "years") |
| +/ |
| immutable string[] timeStrings = ["hnsecs", "usecs", "msecs", "seconds", "minutes", |
| "hours", "days", "weeks", "months", "years"]; |
| |
| |
| /++ |
| Combines the $(REF Date,std,datetime,date) and |
| $(REF TimeOfDay,std,datetime,date) structs to give an object which holds |
| both the date and the time. It is optimized for calendar-based operations and |
| has no concept of time zone. For an object which is optimized for time |
| operations based on the system time, use $(REF SysTime,std,datetime,systime). |
| $(REF SysTime,std,datetime,systime) has a concept of time zone and has much |
| higher precision (hnsecs). $(D DateTime) is intended primarily for |
| calendar-based uses rather than precise time operations. |
| +/ |
| struct DateTime |
| { |
| public: |
| |
| /++ |
| Params: |
| date = The date portion of $(LREF DateTime). |
| tod = The time portion of $(LREF DateTime). |
| +/ |
| this(in Date date, in TimeOfDay tod = TimeOfDay.init) @safe pure nothrow @nogc |
| { |
| _date = date; |
| _tod = tod; |
| } |
| |
| @safe unittest |
| { |
| { |
| auto dt = DateTime.init; |
| assert(dt._date == Date.init); |
| assert(dt._tod == TimeOfDay.init); |
| } |
| |
| { |
| auto dt = DateTime(Date(1999, 7 ,6)); |
| assert(dt._date == Date(1999, 7, 6)); |
| assert(dt._tod == TimeOfDay.init); |
| } |
| |
| { |
| auto dt = DateTime(Date(1999, 7 ,6), TimeOfDay(12, 30, 33)); |
| assert(dt._date == Date(1999, 7, 6)); |
| assert(dt._tod == TimeOfDay(12, 30, 33)); |
| } |
| } |
| |
| |
| /++ |
| Params: |
| year = The year portion of the date. |
| month = The month portion of the date (January is 1). |
| day = The day portion of the date. |
| hour = The hour portion of the time; |
| minute = The minute portion of the time; |
| second = The second portion of the time; |
| +/ |
| this(int year, int month, int day, int hour = 0, int minute = 0, int second = 0) @safe pure |
| { |
| _date = Date(year, month, day); |
| _tod = TimeOfDay(hour, minute, second); |
| } |
| |
| @safe unittest |
| { |
| { |
| auto dt = DateTime(1999, 7 ,6); |
| assert(dt._date == Date(1999, 7, 6)); |
| assert(dt._tod == TimeOfDay.init); |
| } |
| |
| { |
| auto dt = DateTime(1999, 7 ,6, 12, 30, 33); |
| assert(dt._date == Date(1999, 7, 6)); |
| assert(dt._tod == TimeOfDay(12, 30, 33)); |
| } |
| } |
| |
| |
| /++ |
| Compares this $(LREF DateTime) with the given $(D DateTime.). |
| |
| Returns: |
| $(BOOKTABLE, |
| $(TR $(TD this < rhs) $(TD < 0)) |
| $(TR $(TD this == rhs) $(TD 0)) |
| $(TR $(TD this > rhs) $(TD > 0)) |
| ) |
| +/ |
| int opCmp(in DateTime rhs) const @safe pure nothrow @nogc |
| { |
| immutable dateResult = _date.opCmp(rhs._date); |
| |
| if (dateResult != 0) |
| return dateResult; |
| |
| return _tod.opCmp(rhs._tod); |
| } |
| |
| @safe unittest |
| { |
| // Test A.D. |
| assert(DateTime(Date.init, TimeOfDay.init).opCmp(DateTime.init) == 0); |
| |
| assert(DateTime(Date(1999, 1, 1)).opCmp(DateTime(Date(1999, 1, 1))) == 0); |
| assert(DateTime(Date(1, 7, 1)).opCmp(DateTime(Date(1, 7, 1))) == 0); |
| assert(DateTime(Date(1, 1, 6)).opCmp(DateTime(Date(1, 1, 6))) == 0); |
| |
| assert(DateTime(Date(1999, 7, 1)).opCmp(DateTime(Date(1999, 7, 1))) == 0); |
| assert(DateTime(Date(1999, 7, 6)).opCmp(DateTime(Date(1999, 7, 6))) == 0); |
| |
| assert(DateTime(Date(1, 7, 6)).opCmp(DateTime(Date(1, 7, 6))) == 0); |
| |
| assert(DateTime(Date(1999, 7, 6)).opCmp(DateTime(Date(2000, 7, 6))) < 0); |
| assert(DateTime(Date(2000, 7, 6)).opCmp(DateTime(Date(1999, 7, 6))) > 0); |
| assert(DateTime(Date(1999, 7, 6)).opCmp(DateTime(Date(1999, 8, 6))) < 0); |
| assert(DateTime(Date(1999, 8, 6)).opCmp(DateTime(Date(1999, 7, 6))) > 0); |
| assert(DateTime(Date(1999, 7, 6)).opCmp(DateTime(Date(1999, 7, 7))) < 0); |
| assert(DateTime(Date(1999, 7, 7)).opCmp(DateTime(Date(1999, 7, 6))) > 0); |
| |
| assert(DateTime(Date(1999, 8, 7)).opCmp(DateTime(Date(2000, 7, 6))) < 0); |
| assert(DateTime(Date(2000, 8, 6)).opCmp(DateTime(Date(1999, 7, 7))) > 0); |
| assert(DateTime(Date(1999, 7, 7)).opCmp(DateTime(Date(2000, 7, 6))) < 0); |
| assert(DateTime(Date(2000, 7, 6)).opCmp(DateTime(Date(1999, 7, 7))) > 0); |
| assert(DateTime(Date(1999, 7, 7)).opCmp(DateTime(Date(1999, 8, 6))) < 0); |
| assert(DateTime(Date(1999, 8, 6)).opCmp(DateTime(Date(1999, 7, 7))) > 0); |
| |
| |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0))) == 0); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 0)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 0))) == 0); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 0)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 0))) == 0); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33))) == 0); |
| |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0))) == 0); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) == 0); |
| |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33))) == 0); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33))) == 0); |
| |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33))) < 0); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) > 0); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33))) < 0); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) > 0); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34))) < 0); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) > 0); |
| |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34))) > 0); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33))) < 0); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33))) > 0); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33))) < 0); |
| |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34))) > 0); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33))) < 0); |
| |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)).opCmp( |
| DateTime(Date(2000, 7, 6), TimeOfDay(12, 30, 33))) < 0); |
| assert(DateTime(Date(2000, 7, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33))) > 0); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)).opCmp( |
| DateTime(Date(2000, 7, 6), TimeOfDay(12, 30, 33))) < 0); |
| assert(DateTime(Date(2000, 7, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33))) > 0); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)).opCmp( |
| DateTime(Date(2000, 7, 6), TimeOfDay(12, 30, 33))) < 0); |
| assert(DateTime(Date(2000, 7, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34))) > 0); |
| |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)).opCmp( |
| DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33))) < 0); |
| assert(DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33))) > 0); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)).opCmp( |
| DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33))) < 0); |
| assert(DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33))) > 0); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)).opCmp( |
| DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33))) < 0); |
| assert(DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34))) > 0); |
| |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33)).opCmp( |
| DateTime(Date(1999, 7, 7), TimeOfDay(12, 30, 33))) < 0); |
| assert(DateTime(Date(1999, 7, 7), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33))) > 0); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)).opCmp( |
| DateTime(Date(1999, 7, 7), TimeOfDay(12, 31, 33))) < 0); |
| assert(DateTime(Date(1999, 7, 7), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) > 0); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)).opCmp( |
| DateTime(Date(1999, 7, 7), TimeOfDay(12, 30, 33))) < 0); |
| assert(DateTime(Date(1999, 7, 7), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34))) > 0); |
| |
| // Test B.C. |
| assert(DateTime(Date(-1, 1, 1), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(-1, 1, 1), TimeOfDay(12, 30, 33))) == 0); |
| assert(DateTime(Date(-1, 7, 1), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(-1, 7, 1), TimeOfDay(12, 30, 33))) == 0); |
| assert(DateTime(Date(-1, 1, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(-1, 1, 6), TimeOfDay(12, 30, 33))) == 0); |
| |
| assert(DateTime(Date(-1999, 7, 1), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(-1999, 7, 1), TimeOfDay(12, 30, 33))) == 0); |
| assert(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))) == 0); |
| |
| assert(DateTime(Date(-1, 7, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(-1, 7, 6), TimeOfDay(12, 30, 33))) == 0); |
| |
| assert(DateTime(Date(-2000, 7, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))) < 0); |
| assert(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(-2000, 7, 6), TimeOfDay(12, 30, 33))) > 0); |
| assert(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33))) < 0); |
| assert(DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))) > 0); |
| assert(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33))) < 0); |
| assert(DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))) > 0); |
| |
| assert(DateTime(Date(-2000, 8, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33))) < 0); |
| assert(DateTime(Date(-1999, 8, 7), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(-2000, 7, 6), TimeOfDay(12, 30, 33))) > 0); |
| assert(DateTime(Date(-2000, 7, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33))) < 0); |
| assert(DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(-2000, 7, 6), TimeOfDay(12, 30, 33))) > 0); |
| assert(DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33))) < 0); |
| assert(DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33))) > 0); |
| |
| // Test Both |
| assert(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) < 0); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))) > 0); |
| |
| assert(DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) < 0); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33))) > 0); |
| |
| assert(DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) < 0); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(-1999, 7, 7), TimeOfDay(12, 30, 33))) > 0); |
| |
| assert(DateTime(Date(-1999, 8, 7), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))) < 0); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(-1999, 8, 7), TimeOfDay(12, 30, 33))) > 0); |
| |
| assert(DateTime(Date(-1999, 8, 6), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(1999, 6, 6), TimeOfDay(12, 30, 33))) < 0); |
| assert(DateTime(Date(1999, 6, 8), TimeOfDay(12, 30, 33)).opCmp( |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))) > 0); |
| |
| auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 33, 30)); |
| const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 33, 30)); |
| immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 33, 30)); |
| assert(dt.opCmp(dt) == 0); |
| assert(dt.opCmp(cdt) == 0); |
| assert(dt.opCmp(idt) == 0); |
| assert(cdt.opCmp(dt) == 0); |
| assert(cdt.opCmp(cdt) == 0); |
| assert(cdt.opCmp(idt) == 0); |
| assert(idt.opCmp(dt) == 0); |
| assert(idt.opCmp(cdt) == 0); |
| assert(idt.opCmp(idt) == 0); |
| } |
| |
| |
| /++ |
| The date portion of $(LREF DateTime). |
| +/ |
| @property Date date() const @safe pure nothrow @nogc |
| { |
| return _date; |
| } |
| |
| @safe unittest |
| { |
| { |
| auto dt = DateTime.init; |
| assert(dt.date == Date.init); |
| } |
| |
| { |
| auto dt = DateTime(Date(1999, 7, 6)); |
| assert(dt.date == Date(1999, 7, 6)); |
| } |
| |
| const cdt = DateTime(1999, 7, 6); |
| immutable idt = DateTime(1999, 7, 6); |
| assert(cdt.date == Date(1999, 7, 6)); |
| assert(idt.date == Date(1999, 7, 6)); |
| } |
| |
| |
| /++ |
| The date portion of $(LREF DateTime). |
| |
| Params: |
| date = The Date to set this $(LREF DateTime)'s date portion to. |
| +/ |
| @property void date(in Date date) @safe pure nothrow @nogc |
| { |
| _date = date; |
| } |
| |
| @safe unittest |
| { |
| auto dt = DateTime.init; |
| dt.date = Date(1999, 7, 6); |
| assert(dt._date == Date(1999, 7, 6)); |
| assert(dt._tod == TimeOfDay.init); |
| |
| const cdt = DateTime(1999, 7, 6); |
| immutable idt = DateTime(1999, 7, 6); |
| static assert(!__traits(compiles, cdt.date = Date(2010, 1, 1))); |
| static assert(!__traits(compiles, idt.date = Date(2010, 1, 1))); |
| } |
| |
| |
| /++ |
| The time portion of $(LREF DateTime). |
| +/ |
| @property TimeOfDay timeOfDay() const @safe pure nothrow @nogc |
| { |
| return _tod; |
| } |
| |
| @safe unittest |
| { |
| { |
| auto dt = DateTime.init; |
| assert(dt.timeOfDay == TimeOfDay.init); |
| } |
| |
| { |
| auto dt = DateTime(Date.init, TimeOfDay(12, 30, 33)); |
| assert(dt.timeOfDay == TimeOfDay(12, 30, 33)); |
| } |
| |
| const cdt = DateTime(1999, 7, 6, 12, 30, 33); |
| immutable idt = DateTime(1999, 7, 6, 12, 30, 33); |
| assert(cdt.timeOfDay == TimeOfDay(12, 30, 33)); |
| assert(idt.timeOfDay == TimeOfDay(12, 30, 33)); |
| } |
| |
| |
| /++ |
| The time portion of $(LREF DateTime). |
| |
| Params: |
| tod = The $(REF TimeOfDay,std,datetime,date) to set this |
| $(LREF DateTime)'s time portion to. |
| +/ |
| @property void timeOfDay(in TimeOfDay tod) @safe pure nothrow @nogc |
| { |
| _tod = tod; |
| } |
| |
| @safe unittest |
| { |
| auto dt = DateTime.init; |
| dt.timeOfDay = TimeOfDay(12, 30, 33); |
| assert(dt._date == Date.init); |
| assert(dt._tod == TimeOfDay(12, 30, 33)); |
| |
| const cdt = DateTime(1999, 7, 6, 12, 30, 33); |
| immutable idt = DateTime(1999, 7, 6, 12, 30, 33); |
| static assert(!__traits(compiles, cdt.timeOfDay = TimeOfDay(12, 30, 33))); |
| static assert(!__traits(compiles, idt.timeOfDay = TimeOfDay(12, 30, 33))); |
| } |
| |
| |
| /++ |
| Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive |
| are B.C. |
| +/ |
| @property short year() const @safe pure nothrow @nogc |
| { |
| return _date.year; |
| } |
| |
| @safe unittest |
| { |
| assert(Date.init.year == 1); |
| assert(Date(1999, 7, 6).year == 1999); |
| assert(Date(-1999, 7, 6).year == -1999); |
| |
| const cdt = DateTime(1999, 7, 6, 12, 30, 33); |
| immutable idt = DateTime(1999, 7, 6, 12, 30, 33); |
| assert(idt.year == 1999); |
| assert(idt.year == 1999); |
| } |
| |
| |
| /++ |
| Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive |
| are B.C. |
| |
| Params: |
| year = The year to set this $(LREF DateTime)'s year to. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the new year is not |
| a leap year and if the resulting date would be on February 29th. |
| +/ |
| @property void year(int year) @safe pure |
| { |
| _date.year = year; |
| } |
| |
| /// |
| @safe unittest |
| { |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(9, 7, 5)).year == 1999); |
| assert(DateTime(Date(2010, 10, 4), TimeOfDay(0, 0, 30)).year == 2010); |
| assert(DateTime(Date(-7, 4, 5), TimeOfDay(7, 45, 2)).year == -7); |
| } |
| |
| @safe unittest |
| { |
| static void testDT(DateTime dt, int year, in DateTime expected, size_t line = __LINE__) |
| { |
| dt.year = year; |
| assert(dt == expected); |
| } |
| |
| testDT(DateTime(Date(1, 1, 1), TimeOfDay(12, 30, 33)), |
| 1999, |
| DateTime(Date(1999, 1, 1), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(1, 1, 1), TimeOfDay(12, 30, 33)), |
| 0, |
| DateTime(Date(0, 1, 1), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(1, 1, 1), TimeOfDay(12, 30, 33)), |
| -1999, |
| DateTime(Date(-1999, 1, 1), TimeOfDay(12, 30, 33))); |
| |
| const cdt = DateTime(1999, 7, 6, 12, 30, 33); |
| immutable idt = DateTime(1999, 7, 6, 12, 30, 33); |
| static assert(!__traits(compiles, cdt.year = 7)); |
| static assert(!__traits(compiles, idt.year = 7)); |
| } |
| |
| |
| /++ |
| Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if $(D isAD) is true. |
| +/ |
| @property short yearBC() const @safe pure |
| { |
| return _date.yearBC; |
| } |
| |
| /// |
| @safe unittest |
| { |
| assert(DateTime(Date(0, 1, 1), TimeOfDay(12, 30, 33)).yearBC == 1); |
| assert(DateTime(Date(-1, 1, 1), TimeOfDay(10, 7, 2)).yearBC == 2); |
| assert(DateTime(Date(-100, 1, 1), TimeOfDay(4, 59, 0)).yearBC == 101); |
| } |
| |
| @safe unittest |
| { |
| assertThrown!DateTimeException((in DateTime dt){dt.yearBC;}(DateTime(Date(1, 1, 1)))); |
| |
| auto dt = DateTime(1999, 7, 6, 12, 30, 33); |
| const cdt = DateTime(1999, 7, 6, 12, 30, 33); |
| immutable idt = DateTime(1999, 7, 6, 12, 30, 33); |
| dt.yearBC = 12; |
| assert(dt.yearBC == 12); |
| static assert(!__traits(compiles, cdt.yearBC = 12)); |
| static assert(!__traits(compiles, idt.yearBC = 12)); |
| } |
| |
| |
| /++ |
| Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C. |
| |
| Params: |
| year = The year B.C. to set this $(LREF DateTime)'s year to. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if a non-positive value |
| is given. |
| +/ |
| @property void yearBC(int year) @safe pure |
| { |
| _date.yearBC = year; |
| } |
| |
| /// |
| @safe unittest |
| { |
| auto dt = DateTime(Date(2010, 1, 1), TimeOfDay(7, 30, 0)); |
| dt.yearBC = 1; |
| assert(dt == DateTime(Date(0, 1, 1), TimeOfDay(7, 30, 0))); |
| |
| dt.yearBC = 10; |
| assert(dt == DateTime(Date(-9, 1, 1), TimeOfDay(7, 30, 0))); |
| } |
| |
| @safe unittest |
| { |
| assertThrown!DateTimeException((DateTime dt){dt.yearBC = -1;}(DateTime(Date(1, 1, 1)))); |
| |
| auto dt = DateTime(1999, 7, 6, 12, 30, 33); |
| const cdt = DateTime(1999, 7, 6, 12, 30, 33); |
| immutable idt = DateTime(1999, 7, 6, 12, 30, 33); |
| dt.yearBC = 12; |
| assert(dt.yearBC == 12); |
| static assert(!__traits(compiles, cdt.yearBC = 12)); |
| static assert(!__traits(compiles, idt.yearBC = 12)); |
| } |
| |
| |
| /++ |
| Month of a Gregorian Year. |
| +/ |
| @property Month month() const @safe pure nothrow @nogc |
| { |
| return _date.month; |
| } |
| |
| /// |
| @safe unittest |
| { |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(9, 7, 5)).month == 7); |
| assert(DateTime(Date(2010, 10, 4), TimeOfDay(0, 0, 30)).month == 10); |
| assert(DateTime(Date(-7, 4, 5), TimeOfDay(7, 45, 2)).month == 4); |
| } |
| |
| @safe unittest |
| { |
| assert(DateTime.init.month == 1); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)).month == 7); |
| assert(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)).month == 7); |
| |
| const cdt = DateTime(1999, 7, 6, 12, 30, 33); |
| immutable idt = DateTime(1999, 7, 6, 12, 30, 33); |
| assert(cdt.month == 7); |
| assert(idt.month == 7); |
| } |
| |
| |
| /++ |
| Month of a Gregorian Year. |
| |
| Params: |
| month = The month to set this $(LREF DateTime)'s month to. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the given month is |
| not a valid month. |
| +/ |
| @property void month(Month month) @safe pure |
| { |
| _date.month = month; |
| } |
| |
| @safe unittest |
| { |
| static void testDT(DateTime dt, Month month, in DateTime expected = DateTime.init, size_t line = __LINE__) |
| { |
| dt.month = month; |
| assert(expected != DateTime.init); |
| assert(dt == expected); |
| } |
| |
| assertThrown!DateTimeException(testDT(DateTime(Date(1, 1, 1), TimeOfDay(12, 30, 33)), cast(Month) 0)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(1, 1, 1), TimeOfDay(12, 30, 33)), cast(Month) 13)); |
| |
| testDT(DateTime(Date(1, 1, 1), TimeOfDay(12, 30, 33)), |
| cast(Month) 7, |
| DateTime(Date(1, 7, 1), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(-1, 1, 1), TimeOfDay(12, 30, 33)), |
| cast(Month) 7, |
| DateTime(Date(-1, 7, 1), TimeOfDay(12, 30, 33))); |
| |
| const cdt = DateTime(1999, 7, 6, 12, 30, 33); |
| immutable idt = DateTime(1999, 7, 6, 12, 30, 33); |
| static assert(!__traits(compiles, cdt.month = 12)); |
| static assert(!__traits(compiles, idt.month = 12)); |
| } |
| |
| |
| /++ |
| Day of a Gregorian Month. |
| +/ |
| @property ubyte day() const @safe pure nothrow @nogc |
| { |
| return _date.day; |
| } |
| |
| /// |
| @safe unittest |
| { |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(9, 7, 5)).day == 6); |
| assert(DateTime(Date(2010, 10, 4), TimeOfDay(0, 0, 30)).day == 4); |
| assert(DateTime(Date(-7, 4, 5), TimeOfDay(7, 45, 2)).day == 5); |
| } |
| |
| @safe unittest |
| { |
| import std.format : format; |
| import std.range : chain; |
| |
| static void test(DateTime dateTime, int expected) |
| { |
| assert(dateTime.day == expected, format("Value given: %s", dateTime)); |
| } |
| |
| foreach (year; chain(testYearsBC, testYearsAD)) |
| { |
| foreach (md; testMonthDays) |
| { |
| foreach (tod; testTODs) |
| test(DateTime(Date(year, md.month, md.day), tod), md.day); |
| } |
| } |
| |
| const cdt = DateTime(1999, 7, 6, 12, 30, 33); |
| immutable idt = DateTime(1999, 7, 6, 12, 30, 33); |
| assert(cdt.day == 6); |
| assert(idt.day == 6); |
| } |
| |
| |
| /++ |
| Day of a Gregorian Month. |
| |
| Params: |
| day = The day of the month to set this $(LREF DateTime)'s day to. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the given day is not |
| a valid day of the current month. |
| +/ |
| @property void day(int day) @safe pure |
| { |
| _date.day = day; |
| } |
| |
| @safe unittest |
| { |
| import std.exception : assertNotThrown; |
| |
| static void testDT(DateTime dt, int day) |
| { |
| dt.day = day; |
| } |
| |
| // Test A.D. |
| assertThrown!DateTimeException(testDT(DateTime(Date(1, 1, 1)), 0)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(1, 1, 1)), 32)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(1, 2, 1)), 29)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(4, 2, 1)), 30)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(1, 3, 1)), 32)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(1, 4, 1)), 31)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(1, 5, 1)), 32)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(1, 6, 1)), 31)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(1, 7, 1)), 32)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(1, 8, 1)), 32)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(1, 9, 1)), 31)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(1, 10, 1)), 32)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(1, 11, 1)), 31)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(1, 12, 1)), 32)); |
| |
| assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 1, 1)), 31)); |
| assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 2, 1)), 28)); |
| assertNotThrown!DateTimeException(testDT(DateTime(Date(4, 2, 1)), 29)); |
| assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 3, 1)), 31)); |
| assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 4, 1)), 30)); |
| assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 5, 1)), 31)); |
| assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 6, 1)), 30)); |
| assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 7, 1)), 31)); |
| assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 8, 1)), 31)); |
| assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 9, 1)), 30)); |
| assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 10, 1)), 31)); |
| assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 11, 1)), 30)); |
| assertNotThrown!DateTimeException(testDT(DateTime(Date(1, 12, 1)), 31)); |
| |
| { |
| auto dt = DateTime(Date(1, 1, 1), TimeOfDay(7, 12, 22)); |
| dt.day = 6; |
| assert(dt == DateTime(Date(1, 1, 6), TimeOfDay(7, 12, 22))); |
| } |
| |
| // Test B.C. |
| assertThrown!DateTimeException(testDT(DateTime(Date(-1, 1, 1)), 0)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(-1, 1, 1)), 32)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(-1, 2, 1)), 29)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(0, 2, 1)), 30)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(-1, 3, 1)), 32)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(-1, 4, 1)), 31)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(-1, 5, 1)), 32)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(-1, 6, 1)), 31)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(-1, 7, 1)), 32)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(-1, 8, 1)), 32)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(-1, 9, 1)), 31)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(-1, 10, 1)), 32)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(-1, 11, 1)), 31)); |
| assertThrown!DateTimeException(testDT(DateTime(Date(-1, 12, 1)), 32)); |
| |
| assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 1, 1)), 31)); |
| assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 2, 1)), 28)); |
| assertNotThrown!DateTimeException(testDT(DateTime(Date(0, 2, 1)), 29)); |
| assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 3, 1)), 31)); |
| assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 4, 1)), 30)); |
| assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 5, 1)), 31)); |
| assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 6, 1)), 30)); |
| assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 7, 1)), 31)); |
| assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 8, 1)), 31)); |
| assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 9, 1)), 30)); |
| assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 10, 1)), 31)); |
| assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 11, 1)), 30)); |
| assertNotThrown!DateTimeException(testDT(DateTime(Date(-1, 12, 1)), 31)); |
| |
| auto dt = DateTime(Date(-1, 1, 1), TimeOfDay(7, 12, 22)); |
| dt.day = 6; |
| assert(dt == DateTime(Date(-1, 1, 6), TimeOfDay(7, 12, 22))); |
| |
| const cdt = DateTime(1999, 7, 6, 12, 30, 33); |
| immutable idt = DateTime(1999, 7, 6, 12, 30, 33); |
| static assert(!__traits(compiles, cdt.day = 27)); |
| static assert(!__traits(compiles, idt.day = 27)); |
| } |
| |
| |
| /++ |
| Hours past midnight. |
| +/ |
| @property ubyte hour() const @safe pure nothrow @nogc |
| { |
| return _tod.hour; |
| } |
| |
| @safe unittest |
| { |
| assert(DateTime.init.hour == 0); |
| assert(DateTime(Date.init, TimeOfDay(12, 0, 0)).hour == 12); |
| |
| const cdt = DateTime(1999, 7, 6, 12, 30, 33); |
| immutable idt = DateTime(1999, 7, 6, 12, 30, 33); |
| assert(cdt.hour == 12); |
| assert(idt.hour == 12); |
| } |
| |
| |
| /++ |
| Hours past midnight. |
| |
| Params: |
| hour = The hour of the day to set this $(LREF DateTime)'s hour to. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the given hour would |
| result in an invalid $(LREF DateTime). |
| +/ |
| @property void hour(int hour) @safe pure |
| { |
| _tod.hour = hour; |
| } |
| |
| @safe unittest |
| { |
| assertThrown!DateTimeException((){DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0)).hour = 24;}()); |
| |
| auto dt = DateTime.init; |
| dt.hour = 12; |
| assert(dt == DateTime(1, 1, 1, 12, 0, 0)); |
| |
| const cdt = DateTime(1999, 7, 6, 12, 30, 33); |
| immutable idt = DateTime(1999, 7, 6, 12, 30, 33); |
| static assert(!__traits(compiles, cdt.hour = 27)); |
| static assert(!__traits(compiles, idt.hour = 27)); |
| } |
| |
| |
| /++ |
| Minutes past the hour. |
| +/ |
| @property ubyte minute() const @safe pure nothrow @nogc |
| { |
| return _tod.minute; |
| } |
| |
| @safe unittest |
| { |
| assert(DateTime.init.minute == 0); |
| assert(DateTime(1, 1, 1, 0, 30, 0).minute == 30); |
| |
| const cdt = DateTime(1999, 7, 6, 12, 30, 33); |
| immutable idt = DateTime(1999, 7, 6, 12, 30, 33); |
| assert(cdt.minute == 30); |
| assert(idt.minute == 30); |
| } |
| |
| |
| /++ |
| Minutes past the hour. |
| |
| Params: |
| minute = The minute to set this $(LREF DateTime)'s minute to. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the given minute |
| would result in an invalid $(LREF DateTime). |
| +/ |
| @property void minute(int minute) @safe pure |
| { |
| _tod.minute = minute; |
| } |
| |
| @safe unittest |
| { |
| assertThrown!DateTimeException((){DateTime.init.minute = 60;}()); |
| |
| auto dt = DateTime.init; |
| dt.minute = 30; |
| assert(dt == DateTime(1, 1, 1, 0, 30, 0)); |
| |
| const cdt = DateTime(1999, 7, 6, 12, 30, 33); |
| immutable idt = DateTime(1999, 7, 6, 12, 30, 33); |
| static assert(!__traits(compiles, cdt.minute = 27)); |
| static assert(!__traits(compiles, idt.minute = 27)); |
| } |
| |
| |
| /++ |
| Seconds past the minute. |
| +/ |
| @property ubyte second() const @safe pure nothrow @nogc |
| { |
| return _tod.second; |
| } |
| |
| @safe unittest |
| { |
| assert(DateTime.init.second == 0); |
| assert(DateTime(1, 1, 1, 0, 0, 33).second == 33); |
| |
| const cdt = DateTime(1999, 7, 6, 12, 30, 33); |
| immutable idt = DateTime(1999, 7, 6, 12, 30, 33); |
| assert(cdt.second == 33); |
| assert(idt.second == 33); |
| } |
| |
| |
| /++ |
| Seconds past the minute. |
| |
| Params: |
| second = The second to set this $(LREF DateTime)'s second to. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the given seconds |
| would result in an invalid $(LREF DateTime). |
| +/ |
| @property void second(int second) @safe pure |
| { |
| _tod.second = second; |
| } |
| |
| @safe unittest |
| { |
| assertThrown!DateTimeException((){DateTime.init.second = 60;}()); |
| |
| auto dt = DateTime.init; |
| dt.second = 33; |
| assert(dt == DateTime(1, 1, 1, 0, 0, 33)); |
| |
| const cdt = DateTime(1999, 7, 6, 12, 30, 33); |
| immutable idt = DateTime(1999, 7, 6, 12, 30, 33); |
| static assert(!__traits(compiles, cdt.second = 27)); |
| static assert(!__traits(compiles, idt.second = 27)); |
| } |
| |
| |
| /++ |
| Adds the given number of years or months to this $(LREF DateTime). A |
| negative number will subtract. |
| |
| Note that if day overflow is allowed, and the date with the adjusted |
| year/month overflows the number of days in the new month, then the month |
| will be incremented by one, and the day set to the number of days |
| overflowed. (e.g. if the day were 31 and the new month were June, then |
| the month would be incremented to July, and the new day would be 1). If |
| day overflow is not allowed, then the day will be set to the last valid |
| day in the month (e.g. June 31st would become June 30th). |
| |
| Params: |
| units = The type of units to add ("years" or "months"). |
| value = The number of months or years to add to this |
| $(LREF DateTime). |
| allowOverflow = Whether the days should be allowed to overflow, |
| causing the month to increment. |
| +/ |
| ref DateTime add(string units) |
| (long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe pure nothrow @nogc |
| if (units == "years" || units == "months") |
| { |
| _date.add!units(value, allowOverflow); |
| return this; |
| } |
| |
| /// |
| @safe unittest |
| { |
| auto dt1 = DateTime(2010, 1, 1, 12, 30, 33); |
| dt1.add!"months"(11); |
| assert(dt1 == DateTime(2010, 12, 1, 12, 30, 33)); |
| |
| auto dt2 = DateTime(2010, 1, 1, 12, 30, 33); |
| dt2.add!"months"(-11); |
| assert(dt2 == DateTime(2009, 2, 1, 12, 30, 33)); |
| |
| auto dt3 = DateTime(2000, 2, 29, 12, 30, 33); |
| dt3.add!"years"(1); |
| assert(dt3 == DateTime(2001, 3, 1, 12, 30, 33)); |
| |
| auto dt4 = DateTime(2000, 2, 29, 12, 30, 33); |
| dt4.add!"years"(1, AllowDayOverflow.no); |
| assert(dt4 == DateTime(2001, 2, 28, 12, 30, 33)); |
| } |
| |
| @safe unittest |
| { |
| auto dt = DateTime(2000, 1, 31); |
| dt.add!"years"(7).add!"months"(-4); |
| assert(dt == DateTime(2006, 10, 1)); |
| |
| const cdt = DateTime(1999, 7, 6, 12, 30, 33); |
| immutable idt = DateTime(1999, 7, 6, 12, 30, 33); |
| static assert(!__traits(compiles, cdt.add!"years"(4))); |
| static assert(!__traits(compiles, idt.add!"years"(4))); |
| static assert(!__traits(compiles, cdt.add!"months"(4))); |
| static assert(!__traits(compiles, idt.add!"months"(4))); |
| } |
| |
| |
| /++ |
| Adds the given number of years or months to this $(LREF DateTime). A |
| negative number will subtract. |
| |
| The difference between rolling and adding is that rolling does not |
| affect larger units. Rolling a $(LREF DateTime) 12 months |
| gets the exact same $(LREF DateTime). However, the days can still be |
| affected due to the differing number of days in each month. |
| |
| Because there are no units larger than years, there is no difference |
| between adding and rolling years. |
| |
| Params: |
| units = The type of units to add ("years" or "months"). |
| value = The number of months or years to add to this |
| $(LREF DateTime). |
| allowOverflow = Whether the days should be allowed to overflow, |
| causing the month to increment. |
| +/ |
| ref DateTime roll(string units) |
| (long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe pure nothrow @nogc |
| if (units == "years" || units == "months") |
| { |
| _date.roll!units(value, allowOverflow); |
| return this; |
| } |
| |
| /// |
| @safe unittest |
| { |
| auto dt1 = DateTime(2010, 1, 1, 12, 33, 33); |
| dt1.roll!"months"(1); |
| assert(dt1 == DateTime(2010, 2, 1, 12, 33, 33)); |
| |
| auto dt2 = DateTime(2010, 1, 1, 12, 33, 33); |
| dt2.roll!"months"(-1); |
| assert(dt2 == DateTime(2010, 12, 1, 12, 33, 33)); |
| |
| auto dt3 = DateTime(1999, 1, 29, 12, 33, 33); |
| dt3.roll!"months"(1); |
| assert(dt3 == DateTime(1999, 3, 1, 12, 33, 33)); |
| |
| auto dt4 = DateTime(1999, 1, 29, 12, 33, 33); |
| dt4.roll!"months"(1, AllowDayOverflow.no); |
| assert(dt4 == DateTime(1999, 2, 28, 12, 33, 33)); |
| |
| auto dt5 = DateTime(2000, 2, 29, 12, 30, 33); |
| dt5.roll!"years"(1); |
| assert(dt5 == DateTime(2001, 3, 1, 12, 30, 33)); |
| |
| auto dt6 = DateTime(2000, 2, 29, 12, 30, 33); |
| dt6.roll!"years"(1, AllowDayOverflow.no); |
| assert(dt6 == DateTime(2001, 2, 28, 12, 30, 33)); |
| } |
| |
| @safe unittest |
| { |
| auto dt = DateTime(2000, 1, 31); |
| dt.roll!"years"(7).roll!"months"(-4); |
| assert(dt == DateTime(2007, 10, 1)); |
| |
| const cdt = DateTime(1999, 7, 6, 12, 30, 33); |
| immutable idt = DateTime(1999, 7, 6, 12, 30, 33); |
| static assert(!__traits(compiles, cdt.roll!"years"(4))); |
| static assert(!__traits(compiles, idt.roll!"years"(4))); |
| static assert(!__traits(compiles, cdt.roll!"months"(4))); |
| static assert(!__traits(compiles, idt.roll!"months"(4))); |
| } |
| |
| |
| /++ |
| Adds the given number of units to this $(LREF DateTime). A negative |
| number will subtract. |
| |
| The difference between rolling and adding is that rolling does not |
| affect larger units. For instance, rolling a $(LREF DateTime) one |
| year's worth of days gets the exact same $(LREF DateTime). |
| |
| Accepted units are $(D "days"), $(D "minutes"), $(D "hours"), |
| $(D "minutes"), and $(D "seconds"). |
| |
| Params: |
| units = The units to add. |
| value = The number of $(D_PARAM units) to add to this |
| $(LREF DateTime). |
| +/ |
| ref DateTime roll(string units)(long value) @safe pure nothrow @nogc |
| if (units == "days") |
| { |
| _date.roll!"days"(value); |
| return this; |
| } |
| |
| /// |
| @safe unittest |
| { |
| auto dt1 = DateTime(2010, 1, 1, 11, 23, 12); |
| dt1.roll!"days"(1); |
| assert(dt1 == DateTime(2010, 1, 2, 11, 23, 12)); |
| dt1.roll!"days"(365); |
| assert(dt1 == DateTime(2010, 1, 26, 11, 23, 12)); |
| dt1.roll!"days"(-32); |
| assert(dt1 == DateTime(2010, 1, 25, 11, 23, 12)); |
| |
| auto dt2 = DateTime(2010, 7, 4, 12, 0, 0); |
| dt2.roll!"hours"(1); |
| assert(dt2 == DateTime(2010, 7, 4, 13, 0, 0)); |
| |
| auto dt3 = DateTime(2010, 1, 1, 0, 0, 0); |
| dt3.roll!"seconds"(-1); |
| assert(dt3 == DateTime(2010, 1, 1, 0, 0, 59)); |
| } |
| |
| @safe unittest |
| { |
| auto dt = DateTime(2000, 1, 31); |
| dt.roll!"days"(7).roll!"days"(-4); |
| assert(dt == DateTime(2000, 1, 3)); |
| |
| const cdt = DateTime(1999, 7, 6, 12, 30, 33); |
| immutable idt = DateTime(1999, 7, 6, 12, 30, 33); |
| static assert(!__traits(compiles, cdt.roll!"days"(4))); |
| static assert(!__traits(compiles, idt.roll!"days"(4))); |
| } |
| |
| |
| // Shares documentation with "days" version. |
| ref DateTime roll(string units)(long value) @safe pure nothrow @nogc |
| if (units == "hours" || |
| units == "minutes" || |
| units == "seconds") |
| { |
| _tod.roll!units(value); |
| return this; |
| } |
| |
| // Test roll!"hours"(). |
| @safe unittest |
| { |
| static void testDT(DateTime orig, int hours, in DateTime expected, size_t line = __LINE__) |
| { |
| orig.roll!"hours"(hours); |
| assert(orig == expected); |
| } |
| |
| // Test A.D. |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 0, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1, |
| DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 2, |
| DateTime(Date(1999, 7, 6), TimeOfDay(14, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 3, |
| DateTime(Date(1999, 7, 6), TimeOfDay(15, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 4, |
| DateTime(Date(1999, 7, 6), TimeOfDay(16, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 5, |
| DateTime(Date(1999, 7, 6), TimeOfDay(17, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 6, |
| DateTime(Date(1999, 7, 6), TimeOfDay(18, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 7, |
| DateTime(Date(1999, 7, 6), TimeOfDay(19, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 8, |
| DateTime(Date(1999, 7, 6), TimeOfDay(20, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 9, |
| DateTime(Date(1999, 7, 6), TimeOfDay(21, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 10, |
| DateTime(Date(1999, 7, 6), TimeOfDay(22, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 11, |
| DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 12, |
| DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 13, |
| DateTime(Date(1999, 7, 6), TimeOfDay(1, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 14, |
| DateTime(Date(1999, 7, 6), TimeOfDay(2, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 15, |
| DateTime(Date(1999, 7, 6), TimeOfDay(3, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 16, |
| DateTime(Date(1999, 7, 6), TimeOfDay(4, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 17, |
| DateTime(Date(1999, 7, 6), TimeOfDay(5, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 18, |
| DateTime(Date(1999, 7, 6), TimeOfDay(6, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 19, |
| DateTime(Date(1999, 7, 6), TimeOfDay(7, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 20, |
| DateTime(Date(1999, 7, 6), TimeOfDay(8, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 21, |
| DateTime(Date(1999, 7, 6), TimeOfDay(9, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 22, |
| DateTime(Date(1999, 7, 6), TimeOfDay(10, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 23, |
| DateTime(Date(1999, 7, 6), TimeOfDay(11, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 24, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 25, |
| DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33))); |
| |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -1, |
| DateTime(Date(1999, 7, 6), TimeOfDay(11, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -2, |
| DateTime(Date(1999, 7, 6), TimeOfDay(10, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -3, |
| DateTime(Date(1999, 7, 6), TimeOfDay(9, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -4, |
| DateTime(Date(1999, 7, 6), TimeOfDay(8, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -5, |
| DateTime(Date(1999, 7, 6), TimeOfDay(7, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -6, |
| DateTime(Date(1999, 7, 6), TimeOfDay(6, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -7, |
| DateTime(Date(1999, 7, 6), TimeOfDay(5, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -8, |
| DateTime(Date(1999, 7, 6), TimeOfDay(4, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -9, |
| DateTime(Date(1999, 7, 6), TimeOfDay(3, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -10, |
| DateTime(Date(1999, 7, 6), TimeOfDay(2, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -11, |
| DateTime(Date(1999, 7, 6), TimeOfDay(1, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -12, |
| DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -13, |
| DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -14, |
| DateTime(Date(1999, 7, 6), TimeOfDay(22, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -15, |
| DateTime(Date(1999, 7, 6), TimeOfDay(21, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -16, |
| DateTime(Date(1999, 7, 6), TimeOfDay(20, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -17, |
| DateTime(Date(1999, 7, 6), TimeOfDay(19, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -18, |
| DateTime(Date(1999, 7, 6), TimeOfDay(18, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -19, |
| DateTime(Date(1999, 7, 6), TimeOfDay(17, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -20, |
| DateTime(Date(1999, 7, 6), TimeOfDay(16, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -21, |
| DateTime(Date(1999, 7, 6), TimeOfDay(15, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -22, |
| DateTime(Date(1999, 7, 6), TimeOfDay(14, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -23, |
| DateTime(Date(1999, 7, 6), TimeOfDay(13, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -24, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -25, |
| DateTime(Date(1999, 7, 6), TimeOfDay(11, 30, 33))); |
| |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)), 1, |
| DateTime(Date(1999, 7, 6), TimeOfDay(1, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)), 0, |
| DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33)), -1, |
| DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33))); |
| |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33)), 1, |
| DateTime(Date(1999, 7, 6), TimeOfDay(0, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33)), 0, |
| DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(23, 30, 33)), -1, |
| DateTime(Date(1999, 7, 6), TimeOfDay(22, 30, 33))); |
| |
| testDT(DateTime(Date(1999, 7, 31), TimeOfDay(23, 30, 33)), 1, |
| DateTime(Date(1999, 7, 31), TimeOfDay(0, 30, 33))); |
| testDT(DateTime(Date(1999, 8, 1), TimeOfDay(0, 30, 33)), -1, |
| DateTime(Date(1999, 8, 1), TimeOfDay(23, 30, 33))); |
| |
| testDT(DateTime(Date(1999, 12, 31), TimeOfDay(23, 30, 33)), 1, |
| DateTime(Date(1999, 12, 31), TimeOfDay(0, 30, 33))); |
| testDT(DateTime(Date(2000, 1, 1), TimeOfDay(0, 30, 33)), -1, |
| DateTime(Date(2000, 1, 1), TimeOfDay(23, 30, 33))); |
| |
| testDT(DateTime(Date(1999, 2, 28), TimeOfDay(23, 30, 33)), 25, |
| DateTime(Date(1999, 2, 28), TimeOfDay(0, 30, 33))); |
| testDT(DateTime(Date(1999, 3, 2), TimeOfDay(0, 30, 33)), -25, |
| DateTime(Date(1999, 3, 2), TimeOfDay(23, 30, 33))); |
| |
| testDT(DateTime(Date(2000, 2, 28), TimeOfDay(23, 30, 33)), 25, |
| DateTime(Date(2000, 2, 28), TimeOfDay(0, 30, 33))); |
| testDT(DateTime(Date(2000, 3, 1), TimeOfDay(0, 30, 33)), -25, |
| DateTime(Date(2000, 3, 1), TimeOfDay(23, 30, 33))); |
| |
| // Test B.C. |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 0, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(13, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 2, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(14, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 3, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(15, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 4, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(16, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 5, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(17, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 6, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(18, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 7, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(19, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 8, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(20, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 9, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(21, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 10, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(22, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 11, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 12, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 13, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(1, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 14, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(2, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 15, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(3, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 16, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(4, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 17, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(5, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 18, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(6, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 19, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(7, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 20, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(8, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 21, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(9, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 22, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(10, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 23, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(11, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 24, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 25, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(13, 30, 33))); |
| |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -1, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(11, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -2, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(10, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -3, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(9, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -4, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(8, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -5, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(7, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -6, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(6, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -7, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(5, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -8, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(4, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -9, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(3, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -10, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(2, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -11, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(1, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -12, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -13, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -14, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(22, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -15, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(21, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -16, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(20, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -17, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(19, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -18, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(18, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -19, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(17, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -20, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(16, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -21, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(15, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -22, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(14, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -23, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(13, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -24, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -25, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(11, 30, 33))); |
| |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33)), 1, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(1, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33)), 0, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33)), -1, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33))); |
| |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33)), 1, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(0, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33)), 0, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(23, 30, 33)), -1, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(22, 30, 33))); |
| |
| testDT(DateTime(Date(-1999, 7, 31), TimeOfDay(23, 30, 33)), 1, |
| DateTime(Date(-1999, 7, 31), TimeOfDay(0, 30, 33))); |
| testDT(DateTime(Date(-1999, 8, 1), TimeOfDay(0, 30, 33)), -1, |
| DateTime(Date(-1999, 8, 1), TimeOfDay(23, 30, 33))); |
| |
| testDT(DateTime(Date(-2001, 12, 31), TimeOfDay(23, 30, 33)), 1, |
| DateTime(Date(-2001, 12, 31), TimeOfDay(0, 30, 33))); |
| testDT(DateTime(Date(-2000, 1, 1), TimeOfDay(0, 30, 33)), -1, |
| DateTime(Date(-2000, 1, 1), TimeOfDay(23, 30, 33))); |
| |
| testDT(DateTime(Date(-2001, 2, 28), TimeOfDay(23, 30, 33)), 25, |
| DateTime(Date(-2001, 2, 28), TimeOfDay(0, 30, 33))); |
| testDT(DateTime(Date(-2001, 3, 2), TimeOfDay(0, 30, 33)), -25, |
| DateTime(Date(-2001, 3, 2), TimeOfDay(23, 30, 33))); |
| |
| testDT(DateTime(Date(-2000, 2, 28), TimeOfDay(23, 30, 33)), 25, |
| DateTime(Date(-2000, 2, 28), TimeOfDay(0, 30, 33))); |
| testDT(DateTime(Date(-2000, 3, 1), TimeOfDay(0, 30, 33)), -25, |
| DateTime(Date(-2000, 3, 1), TimeOfDay(23, 30, 33))); |
| |
| // Test Both |
| testDT(DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33)), 17_546, |
| DateTime(Date(-1, 1, 1), TimeOfDay(13, 30, 33))); |
| testDT(DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33)), -17_546, |
| DateTime(Date(1, 1, 1), TimeOfDay(11, 30, 33))); |
| |
| auto dt = DateTime(2000, 1, 31, 9, 7, 6); |
| dt.roll!"hours"(27).roll!"hours"(-9); |
| assert(dt == DateTime(2000, 1, 31, 3, 7, 6)); |
| |
| const cdt = DateTime(1999, 7, 6, 12, 30, 33); |
| immutable idt = DateTime(1999, 7, 6, 12, 30, 33); |
| static assert(!__traits(compiles, cdt.roll!"hours"(4))); |
| static assert(!__traits(compiles, idt.roll!"hours"(4))); |
| } |
| |
| // Test roll!"minutes"(). |
| @safe unittest |
| { |
| static void testDT(DateTime orig, int minutes, in DateTime expected, size_t line = __LINE__) |
| { |
| orig.roll!"minutes"(minutes); |
| assert(orig == expected); |
| } |
| |
| // Test A.D. |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 0, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 2, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 32, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 3, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 33, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 4, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 34, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 5, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 35, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 10, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 40, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 15, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 45, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 29, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 59, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 30, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 45, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 15, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 60, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 75, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 45, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 90, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 100, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 10, 33))); |
| |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 689, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 59, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 690, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 691, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 1, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 960, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1439, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 29, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1440, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1441, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 2880, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -1, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 29, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -2, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 28, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -3, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 27, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -4, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 26, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -5, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 25, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -10, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 20, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -15, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 15, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -29, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 1, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -30, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -45, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 45, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -60, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -75, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 15, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -90, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -100, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 50, 33))); |
| |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -749, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 1, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -750, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -751, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 59, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -960, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -1439, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -1440, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -1441, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 29, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -2880, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)), 1, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 1, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)), 0, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 33)), -1, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 59, 33))); |
| |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(11, 59, 33)), 1, |
| DateTime(Date(1999, 7, 6), TimeOfDay(11, 0, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(11, 59, 33)), 0, |
| DateTime(Date(1999, 7, 6), TimeOfDay(11, 59, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(11, 59, 33)), -1, |
| DateTime(Date(1999, 7, 6), TimeOfDay(11, 58, 33))); |
| |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33)), 1, |
| DateTime(Date(1999, 7, 6), TimeOfDay(0, 1, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33)), 0, |
| DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 33)), -1, |
| DateTime(Date(1999, 7, 6), TimeOfDay(0, 59, 33))); |
| |
| testDT(DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 33)), 1, |
| DateTime(Date(1999, 7, 5), TimeOfDay(23, 0, 33))); |
| testDT(DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 33)), 0, |
| DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 33))); |
| testDT(DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 33)), -1, |
| DateTime(Date(1999, 7, 5), TimeOfDay(23, 58, 33))); |
| |
| testDT(DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 33)), 1, |
| DateTime(Date(1998, 12, 31), TimeOfDay(23, 0, 33))); |
| testDT(DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 33)), 0, |
| DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 33))); |
| testDT(DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 33)), -1, |
| DateTime(Date(1998, 12, 31), TimeOfDay(23, 58, 33))); |
| |
| // Test B.C. |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 0, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 31, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 2, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 32, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 3, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 33, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 4, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 34, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 5, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 35, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 10, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 40, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 15, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 45, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 29, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 59, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 30, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 45, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 15, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 60, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 75, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 45, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 90, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 100, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 10, 33))); |
| |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 689, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 59, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 690, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 691, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 1, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 960, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1439, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 29, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1440, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1441, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 31, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 2880, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))); |
| |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -1, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 29, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -2, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 28, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -3, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 27, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -4, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 26, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -5, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 25, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -10, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 20, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -15, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 15, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -29, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 1, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -30, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -45, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 45, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -60, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -75, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 15, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -90, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -100, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 50, 33))); |
| |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -749, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 1, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -750, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -751, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 59, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -960, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -1439, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 31, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -1440, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -1441, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 29, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -2880, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))); |
| |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)), 1, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 1, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)), 0, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 33)), -1, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 59, 33))); |
| |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(11, 59, 33)), 1, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(11, 0, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(11, 59, 33)), 0, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(11, 59, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(11, 59, 33)), -1, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(11, 58, 33))); |
| |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 33)), 1, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(0, 1, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 33)), 0, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 33)), -1, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(0, 59, 33))); |
| |
| testDT(DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 33)), 1, |
| DateTime(Date(-1999, 7, 5), TimeOfDay(23, 0, 33))); |
| testDT(DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 33)), 0, |
| DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 33))); |
| testDT(DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 33)), -1, |
| DateTime(Date(-1999, 7, 5), TimeOfDay(23, 58, 33))); |
| |
| testDT(DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 33)), 1, |
| DateTime(Date(-2000, 12, 31), TimeOfDay(23, 0, 33))); |
| testDT(DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 33)), 0, |
| DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 33))); |
| testDT(DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 33)), -1, |
| DateTime(Date(-2000, 12, 31), TimeOfDay(23, 58, 33))); |
| |
| // Test Both |
| testDT(DateTime(Date(1, 1, 1), TimeOfDay(0, 0, 0)), -1, |
| DateTime(Date(1, 1, 1), TimeOfDay(0, 59, 0))); |
| testDT(DateTime(Date(0, 12, 31), TimeOfDay(23, 59, 0)), 1, |
| DateTime(Date(0, 12, 31), TimeOfDay(23, 0, 0))); |
| |
| testDT(DateTime(Date(0, 1, 1), TimeOfDay(0, 0, 0)), -1, |
| DateTime(Date(0, 1, 1), TimeOfDay(0, 59, 0))); |
| testDT(DateTime(Date(-1, 12, 31), TimeOfDay(23, 59, 0)), 1, |
| DateTime(Date(-1, 12, 31), TimeOfDay(23, 0, 0))); |
| |
| testDT(DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33)), 1_052_760, |
| DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33))); |
| testDT(DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33)), -1_052_760, |
| DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33))); |
| |
| testDT(DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33)), 1_052_782, |
| DateTime(Date(-1, 1, 1), TimeOfDay(11, 52, 33))); |
| testDT(DateTime(Date(1, 1, 1), TimeOfDay(13, 52, 33)), -1_052_782, |
| DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33))); |
| |
| auto dt = DateTime(2000, 1, 31, 9, 7, 6); |
| dt.roll!"minutes"(92).roll!"minutes"(-292); |
| assert(dt == DateTime(2000, 1, 31, 9, 47, 6)); |
| |
| const cdt = DateTime(1999, 7, 6, 12, 30, 33); |
| immutable idt = DateTime(1999, 7, 6, 12, 30, 33); |
| static assert(!__traits(compiles, cdt.roll!"minutes"(4))); |
| static assert(!__traits(compiles, idt.roll!"minutes"(4))); |
| } |
| |
| // Test roll!"seconds"(). |
| @safe unittest |
| { |
| static void testDT(DateTime orig, int seconds, in DateTime expected, size_t line = __LINE__) |
| { |
| orig.roll!"seconds"(seconds); |
| assert(orig == expected); |
| } |
| |
| // Test A.D. |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 0, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 2, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 35))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 3, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 36))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 4, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 37))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 5, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 38))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 10, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 43))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 15, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 48))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 26, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 59))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 27, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 30, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 3))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 59, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 32))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 60, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 61, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34))); |
| |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1766, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 59))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1767, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 1768, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 1))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 2007, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 3599, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 32))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 3600, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 3601, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), 7200, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -1, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 32))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -2, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 31))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -3, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 30))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -4, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 29))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -5, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 28))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -10, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 23))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -15, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 18))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -33, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -34, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 59))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -35, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 58))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -59, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -60, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)), -61, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 32))); |
| |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)), 1, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 1))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)), 0, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 0)), -1, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 59))); |
| |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 0)), 1, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 1))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 0)), 0, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 0))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 0)), -1, |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 0, 59))); |
| |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0)), 1, |
| DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 1))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0)), 0, |
| DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0))); |
| testDT(DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 0)), -1, |
| DateTime(Date(1999, 7, 6), TimeOfDay(0, 0, 59))); |
| |
| testDT(DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 59)), 1, |
| DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 0))); |
| testDT(DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 59)), 0, |
| DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 59))); |
| testDT(DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 59)), -1, |
| DateTime(Date(1999, 7, 5), TimeOfDay(23, 59, 58))); |
| |
| testDT(DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 59)), 1, |
| DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 0))); |
| testDT(DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 59)), 0, |
| DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 59))); |
| testDT(DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 59)), -1, |
| DateTime(Date(1998, 12, 31), TimeOfDay(23, 59, 58))); |
| |
| // Test B.C. |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 0, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 34))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 2, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 35))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 3, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 36))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 4, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 37))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 5, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 38))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 10, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 43))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 15, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 48))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 26, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 59))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 27, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 30, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 3))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 59, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 32))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 60, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 61, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 34))); |
| |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1766, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 59))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1767, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 1768, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 1))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 2007, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 3599, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 32))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 3600, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 3601, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 34))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), 7200, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))); |
| |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -1, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 32))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -2, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 31))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -3, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 30))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -4, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 29))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -5, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 28))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -10, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 23))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -15, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 18))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -33, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -34, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 59))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -35, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 58))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -59, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 34))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -60, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33)), -61, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 32))); |
| |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)), 1, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 1))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)), 0, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 0)), -1, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 59))); |
| |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 0)), 1, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 1))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 0)), 0, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 0))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 0)), -1, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 0, 59))); |
| |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 0)), 1, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 1))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 0)), 0, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 0))); |
| testDT(DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 0)), -1, |
| DateTime(Date(-1999, 7, 6), TimeOfDay(0, 0, 59))); |
| |
| testDT(DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 59)), 1, |
| DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 0))); |
| testDT(DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 59)), 0, |
| DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 59))); |
| testDT(DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 59)), -1, |
| DateTime(Date(-1999, 7, 5), TimeOfDay(23, 59, 58))); |
| |
| testDT(DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 59)), 1, |
| DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 0))); |
| testDT(DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 59)), 0, |
| DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 59))); |
| testDT(DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 59)), -1, |
| DateTime(Date(-2000, 12, 31), TimeOfDay(23, 59, 58))); |
| |
| // Test Both |
| testDT(DateTime(Date(1, 1, 1), TimeOfDay(0, 0, 0)), -1, |
| DateTime(Date(1, 1, 1), TimeOfDay(0, 0, 59))); |
| testDT(DateTime(Date(0, 12, 31), TimeOfDay(23, 59, 59)), 1, |
| DateTime(Date(0, 12, 31), TimeOfDay(23, 59, 0))); |
| |
| testDT(DateTime(Date(0, 1, 1), TimeOfDay(0, 0, 0)), -1, |
| DateTime(Date(0, 1, 1), TimeOfDay(0, 0, 59))); |
| testDT(DateTime(Date(-1, 12, 31), TimeOfDay(23, 59, 59)), 1, |
| DateTime(Date(-1, 12, 31), TimeOfDay(23, 59, 0))); |
| |
| testDT(DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33)), 63_165_600L, |
| DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33))); |
| testDT(DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33)), -63_165_600L, |
| DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33))); |
| |
| testDT(DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 33)), 63_165_617L, |
| DateTime(Date(-1, 1, 1), TimeOfDay(11, 30, 50))); |
| testDT(DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 50)), -63_165_617L, |
| DateTime(Date(1, 1, 1), TimeOfDay(13, 30, 33))); |
| |
| auto dt = DateTime(2000, 1, 31, 9, 7, 6); |
| dt.roll!"seconds"(92).roll!"seconds"(-292); |
| assert(dt == DateTime(2000, 1, 31, 9, 7, 46)); |
| |
| const cdt = DateTime(1999, 7, 6, 12, 30, 33); |
| immutable idt = DateTime(1999, 7, 6, 12, 30, 33); |
| static assert(!__traits(compiles, cdt.roll!"seconds"(4))); |
| static assert(!__traits(compiles, idt.roll!"seconds"(4))); |
| } |
| |
| |
| /++ |
| Gives the result of adding or subtracting a $(REF Duration, core,time) |
| from this $(LREF DateTime). |
| |
| The legal types of arithmetic for $(LREF DateTime) using this operator |
| are |
| |
| $(BOOKTABLE, |
| $(TR $(TD DateTime) $(TD +) $(TD Duration) $(TD -->) $(TD DateTime)) |
| $(TR $(TD DateTime) $(TD -) $(TD Duration) $(TD -->) $(TD DateTime)) |
| ) |
| |
| Params: |
| duration = The $(REF Duration, core,time) to add to or subtract from |
| this $(LREF DateTime). |
| +/ |
| DateTime opBinary(string op)(Duration duration) const @safe pure nothrow @nogc |
| if (op == "+" || op == "-") |
| { |
| DateTime retval = this; |
| immutable seconds = duration.total!"seconds"; |
| mixin("return retval._addSeconds(" ~ op ~ "seconds);"); |
| } |
| |
| /// |
| @safe unittest |
| { |
| import core.time : hours, seconds; |
| |
| assert(DateTime(2015, 12, 31, 23, 59, 59) + seconds(1) == |
| DateTime(2016, 1, 1, 0, 0, 0)); |
| |
| assert(DateTime(2015, 12, 31, 23, 59, 59) + hours(1) == |
| DateTime(2016, 1, 1, 0, 59, 59)); |
| |
| assert(DateTime(2016, 1, 1, 0, 0, 0) - seconds(1) == |
| DateTime(2015, 12, 31, 23, 59, 59)); |
| |
| assert(DateTime(2016, 1, 1, 0, 59, 59) - hours(1) == |
| DateTime(2015, 12, 31, 23, 59, 59)); |
| } |
| |
| @safe unittest |
| { |
| auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| |
| assert(dt + dur!"weeks"(7) == DateTime(Date(1999, 8, 24), TimeOfDay(12, 30, 33))); |
| assert(dt + dur!"weeks"(-7) == DateTime(Date(1999, 5, 18), TimeOfDay(12, 30, 33))); |
| assert(dt + dur!"days"(7) == DateTime(Date(1999, 7, 13), TimeOfDay(12, 30, 33))); |
| assert(dt + dur!"days"(-7) == DateTime(Date(1999, 6, 29), TimeOfDay(12, 30, 33))); |
| |
| assert(dt + dur!"hours"(7) == DateTime(Date(1999, 7, 6), TimeOfDay(19, 30, 33))); |
| assert(dt + dur!"hours"(-7) == DateTime(Date(1999, 7, 6), TimeOfDay(5, 30, 33))); |
| assert(dt + dur!"minutes"(7) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 37, 33))); |
| assert(dt + dur!"minutes"(-7) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 23, 33))); |
| assert(dt + dur!"seconds"(7) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40))); |
| assert(dt + dur!"seconds"(-7) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26))); |
| assert(dt + dur!"msecs"(7_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40))); |
| assert(dt + dur!"msecs"(-7_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26))); |
| assert(dt + dur!"usecs"(7_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40))); |
| assert(dt + dur!"usecs"(-7_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26))); |
| assert(dt + dur!"hnsecs"(70_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40))); |
| assert(dt + dur!"hnsecs"(-70_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26))); |
| |
| assert(dt - dur!"weeks"(-7) == DateTime(Date(1999, 8, 24), TimeOfDay(12, 30, 33))); |
| assert(dt - dur!"weeks"(7) == DateTime(Date(1999, 5, 18), TimeOfDay(12, 30, 33))); |
| assert(dt - dur!"days"(-7) == DateTime(Date(1999, 7, 13), TimeOfDay(12, 30, 33))); |
| assert(dt - dur!"days"(7) == DateTime(Date(1999, 6, 29), TimeOfDay(12, 30, 33))); |
| |
| assert(dt - dur!"hours"(-7) == DateTime(Date(1999, 7, 6), TimeOfDay(19, 30, 33))); |
| assert(dt - dur!"hours"(7) == DateTime(Date(1999, 7, 6), TimeOfDay(5, 30, 33))); |
| assert(dt - dur!"minutes"(-7) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 37, 33))); |
| assert(dt - dur!"minutes"(7) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 23, 33))); |
| assert(dt - dur!"seconds"(-7) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40))); |
| assert(dt - dur!"seconds"(7) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26))); |
| assert(dt - dur!"msecs"(-7_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40))); |
| assert(dt - dur!"msecs"(7_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26))); |
| assert(dt - dur!"usecs"(-7_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40))); |
| assert(dt - dur!"usecs"(7_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26))); |
| assert(dt - dur!"hnsecs"(-70_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40))); |
| assert(dt - dur!"hnsecs"(70_000_000) == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26))); |
| |
| auto duration = dur!"seconds"(12); |
| const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| assert(cdt + duration == DateTime(1999, 7, 6, 12, 30, 45)); |
| assert(idt + duration == DateTime(1999, 7, 6, 12, 30, 45)); |
| assert(cdt - duration == DateTime(1999, 7, 6, 12, 30, 21)); |
| assert(idt - duration == DateTime(1999, 7, 6, 12, 30, 21)); |
| } |
| |
| |
| /++ |
| Gives the result of adding or subtracting a duration from this |
| $(LREF DateTime), as well as assigning the result to this |
| $(LREF DateTime). |
| |
| The legal types of arithmetic for $(LREF DateTime) using this operator |
| are |
| |
| $(BOOKTABLE, |
| $(TR $(TD DateTime) $(TD +) $(TD duration) $(TD -->) $(TD DateTime)) |
| $(TR $(TD DateTime) $(TD -) $(TD duration) $(TD -->) $(TD DateTime)) |
| ) |
| |
| Params: |
| duration = The duration to add to or subtract from this |
| $(LREF DateTime). |
| +/ |
| ref DateTime opOpAssign(string op)(Duration duration) @safe pure nothrow @nogc |
| if (op == "+" || op == "-") |
| { |
| import core.time : convert; |
| import std.format : format; |
| |
| DateTime retval = this; |
| immutable hnsecs = duration.total!"hnsecs"; |
| |
| mixin(format(`return _addSeconds(convert!("hnsecs", "seconds")(%shnsecs));`, op)); |
| } |
| |
| @safe unittest |
| { |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"weeks"(7) == |
| DateTime(Date(1999, 8, 24), TimeOfDay(12, 30, 33))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"weeks"(-7) == |
| DateTime(Date(1999, 5, 18), TimeOfDay(12, 30, 33))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"days"(7) == |
| DateTime(Date(1999, 7, 13), TimeOfDay(12, 30, 33))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"days"(-7) == |
| DateTime(Date(1999, 6, 29), TimeOfDay(12, 30, 33))); |
| |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"hours"(7) == |
| DateTime(Date(1999, 7, 6), TimeOfDay(19, 30, 33))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"hours"(-7) == |
| DateTime(Date(1999, 7, 6), TimeOfDay(5, 30, 33))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"minutes"(7) == |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 37, 33))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"minutes"(-7) == |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 23, 33))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"seconds"(7) == |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"seconds"(-7) == |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"msecs"(7_000) == |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"msecs"(-7_000) == |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"usecs"(7_000_000) == |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"usecs"(-7_000_000) == |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"hnsecs"(70_000_000) == |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) + dur!"hnsecs"(-70_000_000) == |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26))); |
| |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"weeks"(-7) == |
| DateTime(Date(1999, 8, 24), TimeOfDay(12, 30, 33))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"weeks"(7) == |
| DateTime(Date(1999, 5, 18), TimeOfDay(12, 30, 33))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"days"(-7) == |
| DateTime(Date(1999, 7, 13), TimeOfDay(12, 30, 33))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"days"(7) == |
| DateTime(Date(1999, 6, 29), TimeOfDay(12, 30, 33))); |
| |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"hours"(-7) == |
| DateTime(Date(1999, 7, 6), TimeOfDay(19, 30, 33))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"hours"(7) == |
| DateTime(Date(1999, 7, 6), TimeOfDay(5, 30, 33))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"minutes"(-7) == |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 37, 33))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"minutes"(7) == |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 23, 33))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"seconds"(-7) == |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"seconds"(7) == |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"msecs"(-7_000) == |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"msecs"(7_000) == |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"usecs"(-7_000_000) == |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"usecs"(7_000_000) == |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"hnsecs"(-70_000_000) == |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 40))); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - dur!"hnsecs"(70_000_000) == |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 26))); |
| |
| auto dt = DateTime(2000, 1, 31, 9, 7, 6); |
| (dt += dur!"seconds"(92)) -= dur!"days"(-500); |
| assert(dt == DateTime(2001, 6, 14, 9, 8, 38)); |
| |
| auto duration = dur!"seconds"(12); |
| const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| static assert(!__traits(compiles, cdt += duration)); |
| static assert(!__traits(compiles, idt += duration)); |
| static assert(!__traits(compiles, cdt -= duration)); |
| static assert(!__traits(compiles, idt -= duration)); |
| } |
| |
| |
| /++ |
| Gives the difference between two $(LREF DateTime)s. |
| |
| The legal types of arithmetic for $(LREF DateTime) using this operator are |
| |
| $(BOOKTABLE, |
| $(TR $(TD DateTime) $(TD -) $(TD DateTime) $(TD -->) $(TD duration)) |
| ) |
| +/ |
| Duration opBinary(string op)(in DateTime rhs) const @safe pure nothrow @nogc |
| if (op == "-") |
| { |
| immutable dateResult = _date - rhs.date; |
| immutable todResult = _tod - rhs._tod; |
| |
| return dur!"hnsecs"(dateResult.total!"hnsecs" + todResult.total!"hnsecs"); |
| } |
| |
| @safe unittest |
| { |
| auto dt = DateTime(1999, 7, 6, 12, 30, 33); |
| |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - DateTime(Date(1998, 7, 6), TimeOfDay(12, 30, 33)) == |
| dur!"seconds"(31_536_000)); |
| assert(DateTime(Date(1998, 7, 6), TimeOfDay(12, 30, 33)) - DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) == |
| dur!"seconds"(-31_536_000)); |
| |
| assert(DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33)) - DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) == |
| dur!"seconds"(26_78_400)); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - DateTime(Date(1999, 8, 6), TimeOfDay(12, 30, 33)) == |
| dur!"seconds"(-26_78_400)); |
| |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - DateTime(Date(1999, 7, 5), TimeOfDay(12, 30, 33)) == |
| dur!"seconds"(86_400)); |
| assert(DateTime(Date(1999, 7, 5), TimeOfDay(12, 30, 33)) - DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) == |
| dur!"seconds"(-86_400)); |
| |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - DateTime(Date(1999, 7, 6), TimeOfDay(11, 30, 33)) == |
| dur!"seconds"(3600)); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(11, 30, 33)) - DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) == |
| dur!"seconds"(-3600)); |
| |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)) - DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) == |
| dur!"seconds"(60)); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - DateTime(Date(1999, 7, 6), TimeOfDay(12, 31, 33)) == |
| dur!"seconds"(-60)); |
| |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)) - DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) == |
| dur!"seconds"(1)); |
| assert(DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)) - DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 34)) == |
| dur!"seconds"(-1)); |
| |
| assert(DateTime(1, 1, 1, 12, 30, 33) - DateTime(1, 1, 1, 0, 0, 0) == dur!"seconds"(45033)); |
| assert(DateTime(1, 1, 1, 0, 0, 0) - DateTime(1, 1, 1, 12, 30, 33) == dur!"seconds"(-45033)); |
| assert(DateTime(0, 12, 31, 12, 30, 33) - DateTime(1, 1, 1, 0, 0, 0) == dur!"seconds"(-41367)); |
| assert(DateTime(1, 1, 1, 0, 0, 0) - DateTime(0, 12, 31, 12, 30, 33) == dur!"seconds"(41367)); |
| |
| const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| assert(dt - dt == Duration.zero); |
| assert(cdt - dt == Duration.zero); |
| assert(idt - dt == Duration.zero); |
| |
| assert(dt - cdt == Duration.zero); |
| assert(cdt - cdt == Duration.zero); |
| assert(idt - cdt == Duration.zero); |
| |
| assert(dt - idt == Duration.zero); |
| assert(cdt - idt == Duration.zero); |
| assert(idt - idt == Duration.zero); |
| } |
| |
| |
| /++ |
| Returns the difference between the two $(LREF DateTime)s in months. |
| |
| To get the difference in years, subtract the year property |
| of two $(LREF DateTime)s. To get the difference in days or weeks, |
| subtract the $(LREF DateTime)s themselves and use the |
| $(REF Duration, core,time) that results. Because converting between |
| months and smaller units requires a specific date (which |
| $(REF Duration, core,time)s don't have), getting the difference in |
| months requires some math using both the year and month properties, so |
| this is a convenience function for getting the difference in months. |
| |
| Note that the number of days in the months or how far into the month |
| either date is is irrelevant. It is the difference in the month property |
| combined with the difference in years * 12. So, for instance, |
| December 31st and January 1st are one month apart just as December 1st |
| and January 31st are one month apart. |
| |
| Params: |
| rhs = The $(LREF DateTime) to subtract from this one. |
| +/ |
| int diffMonths(in DateTime rhs) const @safe pure nothrow @nogc |
| { |
| return _date.diffMonths(rhs._date); |
| } |
| |
| /// |
| @safe unittest |
| { |
| assert(DateTime(1999, 2, 1, 12, 2, 3).diffMonths( |
| DateTime(1999, 1, 31, 23, 59, 59)) == 1); |
| |
| assert(DateTime(1999, 1, 31, 0, 0, 0).diffMonths( |
| DateTime(1999, 2, 1, 12, 3, 42)) == -1); |
| |
| assert(DateTime(1999, 3, 1, 5, 30, 0).diffMonths( |
| DateTime(1999, 1, 1, 2, 4, 7)) == 2); |
| |
| assert(DateTime(1999, 1, 1, 7, 2, 4).diffMonths( |
| DateTime(1999, 3, 31, 0, 30, 58)) == -2); |
| } |
| |
| @safe unittest |
| { |
| auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| assert(dt.diffMonths(dt) == 0); |
| assert(cdt.diffMonths(dt) == 0); |
| assert(idt.diffMonths(dt) == 0); |
| |
| assert(dt.diffMonths(cdt) == 0); |
| assert(cdt.diffMonths(cdt) == 0); |
| assert(idt.diffMonths(cdt) == 0); |
| |
| assert(dt.diffMonths(idt) == 0); |
| assert(cdt.diffMonths(idt) == 0); |
| assert(idt.diffMonths(idt) == 0); |
| } |
| |
| |
| /++ |
| Whether this $(LREF DateTime) is in a leap year. |
| +/ |
| @property bool isLeapYear() const @safe pure nothrow @nogc |
| { |
| return _date.isLeapYear; |
| } |
| |
| @safe unittest |
| { |
| auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| assert(!dt.isLeapYear); |
| assert(!cdt.isLeapYear); |
| assert(!idt.isLeapYear); |
| } |
| |
| |
| /++ |
| Day of the week this $(LREF DateTime) is on. |
| +/ |
| @property DayOfWeek dayOfWeek() const @safe pure nothrow @nogc |
| { |
| return _date.dayOfWeek; |
| } |
| |
| @safe unittest |
| { |
| auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| assert(dt.dayOfWeek == DayOfWeek.tue); |
| assert(cdt.dayOfWeek == DayOfWeek.tue); |
| assert(idt.dayOfWeek == DayOfWeek.tue); |
| } |
| |
| |
| /++ |
| Day of the year this $(LREF DateTime) is on. |
| +/ |
| @property ushort dayOfYear() const @safe pure nothrow @nogc |
| { |
| return _date.dayOfYear; |
| } |
| |
| /// |
| @safe unittest |
| { |
| assert(DateTime(Date(1999, 1, 1), TimeOfDay(12, 22, 7)).dayOfYear == 1); |
| assert(DateTime(Date(1999, 12, 31), TimeOfDay(7, 2, 59)).dayOfYear == 365); |
| assert(DateTime(Date(2000, 12, 31), TimeOfDay(21, 20, 0)).dayOfYear == 366); |
| } |
| |
| @safe unittest |
| { |
| auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| assert(dt.dayOfYear == 187); |
| assert(cdt.dayOfYear == 187); |
| assert(idt.dayOfYear == 187); |
| } |
| |
| |
| /++ |
| Day of the year. |
| |
| Params: |
| day = The day of the year to set which day of the year this |
| $(LREF DateTime) is on. |
| +/ |
| @property void dayOfYear(int day) @safe pure |
| { |
| _date.dayOfYear = day; |
| } |
| |
| @safe unittest |
| { |
| auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| dt.dayOfYear = 12; |
| assert(dt.dayOfYear == 12); |
| static assert(!__traits(compiles, cdt.dayOfYear = 12)); |
| static assert(!__traits(compiles, idt.dayOfYear = 12)); |
| } |
| |
| |
| /++ |
| The Xth day of the Gregorian Calendar that this $(LREF DateTime) is on. |
| +/ |
| @property int dayOfGregorianCal() const @safe pure nothrow @nogc |
| { |
| return _date.dayOfGregorianCal; |
| } |
| |
| /// |
| @safe unittest |
| { |
| assert(DateTime(Date(1, 1, 1), TimeOfDay(0, 0, 0)).dayOfGregorianCal == 1); |
| assert(DateTime(Date(1, 12, 31), TimeOfDay(23, 59, 59)).dayOfGregorianCal == 365); |
| assert(DateTime(Date(2, 1, 1), TimeOfDay(2, 2, 2)).dayOfGregorianCal == 366); |
| |
| assert(DateTime(Date(0, 12, 31), TimeOfDay(7, 7, 7)).dayOfGregorianCal == 0); |
| assert(DateTime(Date(0, 1, 1), TimeOfDay(19, 30, 0)).dayOfGregorianCal == -365); |
| assert(DateTime(Date(-1, 12, 31), TimeOfDay(4, 7, 0)).dayOfGregorianCal == -366); |
| |
| assert(DateTime(Date(2000, 1, 1), TimeOfDay(9, 30, 20)).dayOfGregorianCal == 730_120); |
| assert(DateTime(Date(2010, 12, 31), TimeOfDay(15, 45, 50)).dayOfGregorianCal == 734_137); |
| } |
| |
| @safe unittest |
| { |
| const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| assert(cdt.dayOfGregorianCal == 729_941); |
| assert(idt.dayOfGregorianCal == 729_941); |
| } |
| |
| |
| /++ |
| The Xth day of the Gregorian Calendar that this $(LREF DateTime) is on. |
| Setting this property does not affect the time portion of |
| $(LREF DateTime). |
| |
| Params: |
| days = The day of the Gregorian Calendar to set this $(LREF DateTime) |
| to. |
| +/ |
| @property void dayOfGregorianCal(int days) @safe pure nothrow @nogc |
| { |
| _date.dayOfGregorianCal = days; |
| } |
| |
| /// |
| @safe unittest |
| { |
| auto dt = DateTime(Date.init, TimeOfDay(12, 0, 0)); |
| dt.dayOfGregorianCal = 1; |
| assert(dt == DateTime(Date(1, 1, 1), TimeOfDay(12, 0, 0))); |
| |
| dt.dayOfGregorianCal = 365; |
| assert(dt == DateTime(Date(1, 12, 31), TimeOfDay(12, 0, 0))); |
| |
| dt.dayOfGregorianCal = 366; |
| assert(dt == DateTime(Date(2, 1, 1), TimeOfDay(12, 0, 0))); |
| |
| dt.dayOfGregorianCal = 0; |
| assert(dt == DateTime(Date(0, 12, 31), TimeOfDay(12, 0, 0))); |
| |
| dt.dayOfGregorianCal = -365; |
| assert(dt == DateTime(Date(-0, 1, 1), TimeOfDay(12, 0, 0))); |
| |
| dt.dayOfGregorianCal = -366; |
| assert(dt == DateTime(Date(-1, 12, 31), TimeOfDay(12, 0, 0))); |
| |
| dt.dayOfGregorianCal = 730_120; |
| assert(dt == DateTime(Date(2000, 1, 1), TimeOfDay(12, 0, 0))); |
| |
| dt.dayOfGregorianCal = 734_137; |
| assert(dt == DateTime(Date(2010, 12, 31), TimeOfDay(12, 0, 0))); |
| } |
| |
| @safe unittest |
| { |
| const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| static assert(!__traits(compiles, cdt.dayOfGregorianCal = 7)); |
| static assert(!__traits(compiles, idt.dayOfGregorianCal = 7)); |
| } |
| |
| |
| /++ |
| The ISO 8601 week of the year that this $(LREF DateTime) is in. |
| |
| See_Also: |
| $(HTTP en.wikipedia.org/wiki/ISO_week_date, ISO Week Date) |
| +/ |
| @property ubyte isoWeek() const @safe pure nothrow |
| { |
| return _date.isoWeek; |
| } |
| |
| @safe unittest |
| { |
| auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| assert(dt.isoWeek == 27); |
| assert(cdt.isoWeek == 27); |
| assert(idt.isoWeek == 27); |
| } |
| |
| |
| /++ |
| $(LREF DateTime) for the last day in the month that this |
| $(LREF DateTime) is in. The time portion of endOfMonth is always |
| 23:59:59. |
| +/ |
| @property DateTime endOfMonth() const @safe pure nothrow |
| { |
| try |
| return DateTime(_date.endOfMonth, TimeOfDay(23, 59, 59)); |
| catch (Exception e) |
| assert(0, "DateTime constructor threw."); |
| } |
| |
| /// |
| @safe unittest |
| { |
| assert(DateTime(Date(1999, 1, 6), TimeOfDay(0, 0, 0)).endOfMonth == |
| DateTime(Date(1999, 1, 31), TimeOfDay(23, 59, 59))); |
| |
| assert(DateTime(Date(1999, 2, 7), TimeOfDay(19, 30, 0)).endOfMonth == |
| DateTime(Date(1999, 2, 28), TimeOfDay(23, 59, 59))); |
| |
| assert(DateTime(Date(2000, 2, 7), TimeOfDay(5, 12, 27)).endOfMonth == |
| DateTime(Date(2000, 2, 29), TimeOfDay(23, 59, 59))); |
| |
| assert(DateTime(Date(2000, 6, 4), TimeOfDay(12, 22, 9)).endOfMonth == |
| DateTime(Date(2000, 6, 30), TimeOfDay(23, 59, 59))); |
| } |
| |
| @safe unittest |
| { |
| // Test A.D. |
| assert(DateTime(1999, 1, 1, 0, 13, 26).endOfMonth == DateTime(1999, 1, 31, 23, 59, 59)); |
| assert(DateTime(1999, 2, 1, 1, 14, 27).endOfMonth == DateTime(1999, 2, 28, 23, 59, 59)); |
| assert(DateTime(2000, 2, 1, 2, 15, 28).endOfMonth == DateTime(2000, 2, 29, 23, 59, 59)); |
| assert(DateTime(1999, 3, 1, 3, 16, 29).endOfMonth == DateTime(1999, 3, 31, 23, 59, 59)); |
| assert(DateTime(1999, 4, 1, 4, 17, 30).endOfMonth == DateTime(1999, 4, 30, 23, 59, 59)); |
| assert(DateTime(1999, 5, 1, 5, 18, 31).endOfMonth == DateTime(1999, 5, 31, 23, 59, 59)); |
| assert(DateTime(1999, 6, 1, 6, 19, 32).endOfMonth == DateTime(1999, 6, 30, 23, 59, 59)); |
| assert(DateTime(1999, 7, 1, 7, 20, 33).endOfMonth == DateTime(1999, 7, 31, 23, 59, 59)); |
| assert(DateTime(1999, 8, 1, 8, 21, 34).endOfMonth == DateTime(1999, 8, 31, 23, 59, 59)); |
| assert(DateTime(1999, 9, 1, 9, 22, 35).endOfMonth == DateTime(1999, 9, 30, 23, 59, 59)); |
| assert(DateTime(1999, 10, 1, 10, 23, 36).endOfMonth == DateTime(1999, 10, 31, 23, 59, 59)); |
| assert(DateTime(1999, 11, 1, 11, 24, 37).endOfMonth == DateTime(1999, 11, 30, 23, 59, 59)); |
| assert(DateTime(1999, 12, 1, 12, 25, 38).endOfMonth == DateTime(1999, 12, 31, 23, 59, 59)); |
| |
| // Test B.C. |
| assert(DateTime(-1999, 1, 1, 0, 13, 26).endOfMonth == DateTime(-1999, 1, 31, 23, 59, 59)); |
| assert(DateTime(-1999, 2, 1, 1, 14, 27).endOfMonth == DateTime(-1999, 2, 28, 23, 59, 59)); |
| assert(DateTime(-2000, 2, 1, 2, 15, 28).endOfMonth == DateTime(-2000, 2, 29, 23, 59, 59)); |
| assert(DateTime(-1999, 3, 1, 3, 16, 29).endOfMonth == DateTime(-1999, 3, 31, 23, 59, 59)); |
| assert(DateTime(-1999, 4, 1, 4, 17, 30).endOfMonth == DateTime(-1999, 4, 30, 23, 59, 59)); |
| assert(DateTime(-1999, 5, 1, 5, 18, 31).endOfMonth == DateTime(-1999, 5, 31, 23, 59, 59)); |
| assert(DateTime(-1999, 6, 1, 6, 19, 32).endOfMonth == DateTime(-1999, 6, 30, 23, 59, 59)); |
| assert(DateTime(-1999, 7, 1, 7, 20, 33).endOfMonth == DateTime(-1999, 7, 31, 23, 59, 59)); |
| assert(DateTime(-1999, 8, 1, 8, 21, 34).endOfMonth == DateTime(-1999, 8, 31, 23, 59, 59)); |
| assert(DateTime(-1999, 9, 1, 9, 22, 35).endOfMonth == DateTime(-1999, 9, 30, 23, 59, 59)); |
| assert(DateTime(-1999, 10, 1, 10, 23, 36).endOfMonth == DateTime(-1999, 10, 31, 23, 59, 59)); |
| assert(DateTime(-1999, 11, 1, 11, 24, 37).endOfMonth == DateTime(-1999, 11, 30, 23, 59, 59)); |
| assert(DateTime(-1999, 12, 1, 12, 25, 38).endOfMonth == DateTime(-1999, 12, 31, 23, 59, 59)); |
| |
| const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| assert(cdt.endOfMonth == DateTime(1999, 7, 31, 23, 59, 59)); |
| assert(idt.endOfMonth == DateTime(1999, 7, 31, 23, 59, 59)); |
| } |
| |
| |
| /++ |
| The last day in the month that this $(LREF DateTime) is in. |
| +/ |
| @property ubyte daysInMonth() const @safe pure nothrow @nogc |
| { |
| return _date.daysInMonth; |
| } |
| |
| /// |
| @safe unittest |
| { |
| assert(DateTime(Date(1999, 1, 6), TimeOfDay(0, 0, 0)).daysInMonth == 31); |
| assert(DateTime(Date(1999, 2, 7), TimeOfDay(19, 30, 0)).daysInMonth == 28); |
| assert(DateTime(Date(2000, 2, 7), TimeOfDay(5, 12, 27)).daysInMonth == 29); |
| assert(DateTime(Date(2000, 6, 4), TimeOfDay(12, 22, 9)).daysInMonth == 30); |
| } |
| |
| @safe unittest |
| { |
| const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| assert(cdt.daysInMonth == 31); |
| assert(idt.daysInMonth == 31); |
| } |
| |
| |
| /++ |
| Whether the current year is a date in A.D. |
| +/ |
| @property bool isAD() const @safe pure nothrow @nogc |
| { |
| return _date.isAD; |
| } |
| |
| /// |
| @safe unittest |
| { |
| assert(DateTime(Date(1, 1, 1), TimeOfDay(12, 7, 0)).isAD); |
| assert(DateTime(Date(2010, 12, 31), TimeOfDay(0, 0, 0)).isAD); |
| assert(!DateTime(Date(0, 12, 31), TimeOfDay(23, 59, 59)).isAD); |
| assert(!DateTime(Date(-2010, 1, 1), TimeOfDay(2, 2, 2)).isAD); |
| } |
| |
| @safe unittest |
| { |
| const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| assert(cdt.isAD); |
| assert(idt.isAD); |
| } |
| |
| |
| /++ |
| The $(HTTP en.wikipedia.org/wiki/Julian_day, Julian day) for this |
| $(LREF DateTime) at the given time. For example, prior to noon, |
| 1996-03-31 would be the Julian day number 2_450_173, so this function |
| returns 2_450_173, while from noon onward, the julian day number would |
| be 2_450_174, so this function returns 2_450_174. |
| +/ |
| @property long julianDay() const @safe pure nothrow @nogc |
| { |
| if (_tod._hour < 12) |
| return _date.julianDay - 1; |
| else |
| return _date.julianDay; |
| } |
| |
| @safe unittest |
| { |
| assert(DateTime(Date(-4713, 11, 24), TimeOfDay(0, 0, 0)).julianDay == -1); |
| assert(DateTime(Date(-4713, 11, 24), TimeOfDay(12, 0, 0)).julianDay == 0); |
| |
| assert(DateTime(Date(0, 12, 31), TimeOfDay(0, 0, 0)).julianDay == 1_721_424); |
| assert(DateTime(Date(0, 12, 31), TimeOfDay(12, 0, 0)).julianDay == 1_721_425); |
| |
| assert(DateTime(Date(1, 1, 1), TimeOfDay(0, 0, 0)).julianDay == 1_721_425); |
| assert(DateTime(Date(1, 1, 1), TimeOfDay(12, 0, 0)).julianDay == 1_721_426); |
| |
| assert(DateTime(Date(1582, 10, 15), TimeOfDay(0, 0, 0)).julianDay == 2_299_160); |
| assert(DateTime(Date(1582, 10, 15), TimeOfDay(12, 0, 0)).julianDay == 2_299_161); |
| |
| assert(DateTime(Date(1858, 11, 17), TimeOfDay(0, 0, 0)).julianDay == 2_400_000); |
| assert(DateTime(Date(1858, 11, 17), TimeOfDay(12, 0, 0)).julianDay == 2_400_001); |
| |
| assert(DateTime(Date(1982, 1, 4), TimeOfDay(0, 0, 0)).julianDay == 2_444_973); |
| assert(DateTime(Date(1982, 1, 4), TimeOfDay(12, 0, 0)).julianDay == 2_444_974); |
| |
| assert(DateTime(Date(1996, 3, 31), TimeOfDay(0, 0, 0)).julianDay == 2_450_173); |
| assert(DateTime(Date(1996, 3, 31), TimeOfDay(12, 0, 0)).julianDay == 2_450_174); |
| |
| assert(DateTime(Date(2010, 8, 24), TimeOfDay(0, 0, 0)).julianDay == 2_455_432); |
| assert(DateTime(Date(2010, 8, 24), TimeOfDay(12, 0, 0)).julianDay == 2_455_433); |
| |
| const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| assert(cdt.julianDay == 2_451_366); |
| assert(idt.julianDay == 2_451_366); |
| } |
| |
| |
| /++ |
| The modified $(HTTP en.wikipedia.org/wiki/Julian_day, Julian day) for any |
| time on this date (since, the modified Julian day changes at midnight). |
| +/ |
| @property long modJulianDay() const @safe pure nothrow @nogc |
| { |
| return _date.modJulianDay; |
| } |
| |
| @safe unittest |
| { |
| assert(DateTime(Date(1858, 11, 17), TimeOfDay(0, 0, 0)).modJulianDay == 0); |
| assert(DateTime(Date(1858, 11, 17), TimeOfDay(12, 0, 0)).modJulianDay == 0); |
| |
| assert(DateTime(Date(2010, 8, 24), TimeOfDay(0, 0, 0)).modJulianDay == 55_432); |
| assert(DateTime(Date(2010, 8, 24), TimeOfDay(12, 0, 0)).modJulianDay == 55_432); |
| |
| const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| assert(cdt.modJulianDay == 51_365); |
| assert(idt.modJulianDay == 51_365); |
| } |
| |
| |
| /++ |
| Converts this $(LREF DateTime) to a string with the format YYYYMMDDTHHMMSS. |
| +/ |
| string toISOString() const @safe pure nothrow |
| { |
| import std.format : format; |
| try |
| { |
| return format!("%sT%02d%02d%02d")( |
| _date.toISOString(), |
| _tod._hour, |
| _tod._minute, |
| _tod._second |
| ); |
| } |
| catch (Exception e) |
| { |
| assert(0, "format() threw."); |
| } |
| } |
| |
| /// |
| @safe unittest |
| { |
| assert(DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)).toISOString() == |
| "20100704T070612"); |
| |
| assert(DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)).toISOString() == |
| "19981225T021500"); |
| |
| assert(DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)).toISOString() == |
| "00000105T230959"); |
| |
| assert(DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2)).toISOString() == |
| "-00040105T000002"); |
| } |
| |
| @safe unittest |
| { |
| // Test A.D. |
| assert(DateTime(Date(9, 12, 4), TimeOfDay(0, 0, 0)).toISOString() == "00091204T000000"); |
| assert(DateTime(Date(99, 12, 4), TimeOfDay(5, 6, 12)).toISOString() == "00991204T050612"); |
| assert(DateTime(Date(999, 12, 4), TimeOfDay(13, 44, 59)).toISOString() == "09991204T134459"); |
| assert(DateTime(Date(9999, 7, 4), TimeOfDay(23, 59, 59)).toISOString() == "99990704T235959"); |
| assert(DateTime(Date(10000, 10, 20), TimeOfDay(1, 1, 1)).toISOString() == "+100001020T010101"); |
| |
| // Test B.C. |
| assert(DateTime(Date(0, 12, 4), TimeOfDay(0, 12, 4)).toISOString() == "00001204T001204"); |
| assert(DateTime(Date(-9, 12, 4), TimeOfDay(0, 0, 0)).toISOString() == "-00091204T000000"); |
| assert(DateTime(Date(-99, 12, 4), TimeOfDay(5, 6, 12)).toISOString() == "-00991204T050612"); |
| assert(DateTime(Date(-999, 12, 4), TimeOfDay(13, 44, 59)).toISOString() == "-09991204T134459"); |
| assert(DateTime(Date(-9999, 7, 4), TimeOfDay(23, 59, 59)).toISOString() == "-99990704T235959"); |
| assert(DateTime(Date(-10000, 10, 20), TimeOfDay(1, 1, 1)).toISOString() == "-100001020T010101"); |
| |
| const cdt = DateTime(1999, 7, 6, 12, 30, 33); |
| immutable idt = DateTime(1999, 7, 6, 12, 30, 33); |
| assert(cdt.toISOString() == "19990706T123033"); |
| assert(idt.toISOString() == "19990706T123033"); |
| } |
| |
| |
| /++ |
| Converts this $(LREF DateTime) to a string with the format |
| YYYY-MM-DDTHH:MM:SS. |
| +/ |
| string toISOExtString() const @safe pure nothrow |
| { |
| import std.format : format; |
| try |
| { |
| return format!("%sT%02d:%02d:%02d")( |
| _date.toISOExtString(), |
| _tod._hour, |
| _tod._minute, |
| _tod._second |
| ); |
| } |
| catch (Exception e) |
| { |
| assert(0, "format() threw."); |
| } |
| } |
| |
| /// |
| @safe unittest |
| { |
| assert(DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)).toISOExtString() == |
| "2010-07-04T07:06:12"); |
| |
| assert(DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)).toISOExtString() == |
| "1998-12-25T02:15:00"); |
| |
| assert(DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)).toISOExtString() == |
| "0000-01-05T23:09:59"); |
| |
| assert(DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2)).toISOExtString() == |
| "-0004-01-05T00:00:02"); |
| } |
| |
| @safe unittest |
| { |
| // Test A.D. |
| assert(DateTime(Date(9, 12, 4), TimeOfDay(0, 0, 0)).toISOExtString() == "0009-12-04T00:00:00"); |
| assert(DateTime(Date(99, 12, 4), TimeOfDay(5, 6, 12)).toISOExtString() == "0099-12-04T05:06:12"); |
| assert(DateTime(Date(999, 12, 4), TimeOfDay(13, 44, 59)).toISOExtString() == "0999-12-04T13:44:59"); |
| assert(DateTime(Date(9999, 7, 4), TimeOfDay(23, 59, 59)).toISOExtString() == "9999-07-04T23:59:59"); |
| assert(DateTime(Date(10000, 10, 20), TimeOfDay(1, 1, 1)).toISOExtString() == "+10000-10-20T01:01:01"); |
| |
| // Test B.C. |
| assert(DateTime(Date(0, 12, 4), TimeOfDay(0, 12, 4)).toISOExtString() == "0000-12-04T00:12:04"); |
| assert(DateTime(Date(-9, 12, 4), TimeOfDay(0, 0, 0)).toISOExtString() == "-0009-12-04T00:00:00"); |
| assert(DateTime(Date(-99, 12, 4), TimeOfDay(5, 6, 12)).toISOExtString() == "-0099-12-04T05:06:12"); |
| assert(DateTime(Date(-999, 12, 4), TimeOfDay(13, 44, 59)).toISOExtString() == "-0999-12-04T13:44:59"); |
| assert(DateTime(Date(-9999, 7, 4), TimeOfDay(23, 59, 59)).toISOExtString() == "-9999-07-04T23:59:59"); |
| assert(DateTime(Date(-10000, 10, 20), TimeOfDay(1, 1, 1)).toISOExtString() == "-10000-10-20T01:01:01"); |
| |
| const cdt = DateTime(1999, 7, 6, 12, 30, 33); |
| immutable idt = DateTime(1999, 7, 6, 12, 30, 33); |
| assert(cdt.toISOExtString() == "1999-07-06T12:30:33"); |
| assert(idt.toISOExtString() == "1999-07-06T12:30:33"); |
| } |
| |
| /++ |
| Converts this $(LREF DateTime) to a string with the format |
| YYYY-Mon-DD HH:MM:SS. |
| +/ |
| string toSimpleString() const @safe pure nothrow |
| { |
| import std.format : format; |
| try |
| { |
| return format!("%s %02d:%02d:%02d")( |
| _date.toSimpleString(), |
| _tod._hour, |
| _tod._minute, |
| _tod._second |
| ); |
| } |
| catch (Exception e) |
| { |
| assert(0, "format() threw."); |
| } |
| } |
| |
| /// |
| @safe unittest |
| { |
| assert(DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12)).toSimpleString() == |
| "2010-Jul-04 07:06:12"); |
| |
| assert(DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0)).toSimpleString() == |
| "1998-Dec-25 02:15:00"); |
| |
| assert(DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59)).toSimpleString() == |
| "0000-Jan-05 23:09:59"); |
| |
| assert(DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2)).toSimpleString() == |
| "-0004-Jan-05 00:00:02"); |
| } |
| |
| @safe unittest |
| { |
| // Test A.D. |
| assert(DateTime(Date(9, 12, 4), TimeOfDay(0, 0, 0)).toSimpleString() == "0009-Dec-04 00:00:00"); |
| assert(DateTime(Date(99, 12, 4), TimeOfDay(5, 6, 12)).toSimpleString() == "0099-Dec-04 05:06:12"); |
| assert(DateTime(Date(999, 12, 4), TimeOfDay(13, 44, 59)).toSimpleString() == "0999-Dec-04 13:44:59"); |
| assert(DateTime(Date(9999, 7, 4), TimeOfDay(23, 59, 59)).toSimpleString() == "9999-Jul-04 23:59:59"); |
| assert(DateTime(Date(10000, 10, 20), TimeOfDay(1, 1, 1)).toSimpleString() == "+10000-Oct-20 01:01:01"); |
| |
| // Test B.C. |
| assert(DateTime(Date(0, 12, 4), TimeOfDay(0, 12, 4)).toSimpleString() == "0000-Dec-04 00:12:04"); |
| assert(DateTime(Date(-9, 12, 4), TimeOfDay(0, 0, 0)).toSimpleString() == "-0009-Dec-04 00:00:00"); |
| assert(DateTime(Date(-99, 12, 4), TimeOfDay(5, 6, 12)).toSimpleString() == "-0099-Dec-04 05:06:12"); |
| assert(DateTime(Date(-999, 12, 4), TimeOfDay(13, 44, 59)).toSimpleString() == "-0999-Dec-04 13:44:59"); |
| assert(DateTime(Date(-9999, 7, 4), TimeOfDay(23, 59, 59)).toSimpleString() == "-9999-Jul-04 23:59:59"); |
| assert(DateTime(Date(-10000, 10, 20), TimeOfDay(1, 1, 1)).toSimpleString() == "-10000-Oct-20 01:01:01"); |
| |
| const cdt = DateTime(1999, 7, 6, 12, 30, 33); |
| immutable idt = DateTime(1999, 7, 6, 12, 30, 33); |
| assert(cdt.toSimpleString() == "1999-Jul-06 12:30:33"); |
| assert(idt.toSimpleString() == "1999-Jul-06 12:30:33"); |
| } |
| |
| |
| /++ |
| Converts this $(LREF DateTime) to a string. |
| |
| This function exists to make it easy to convert a $(LREF DateTime) to a |
| string for code that does not care what the exact format is - just that |
| it presents the information in a clear manner. It also makes it easy to |
| simply convert a $(LREF DateTime) to a string when using functions such |
| as `to!string`, `format`, or `writeln` which use toString to convert |
| user-defined types. So, it is unlikely that much code will call |
| toString directly. |
| |
| The format of the string is purposefully unspecified, and code that |
| cares about the format of the string should use `toISOString`, |
| `toISOExtString`, `toSimpleString`, or some other custom formatting |
| function that explicitly generates the format that the code needs. The |
| reason is that the code is then clear about what format it's using, |
| making it less error-prone to maintain the code and interact with other |
| software that consumes the generated strings. It's for this same reason |
| that $(LREF DateTime) has no `fromString` function, whereas it does have |
| `fromISOString`, `fromISOExtString`, and `fromSimpleString`. |
| |
| The format returned by toString may or may not change in the future. |
| +/ |
| string toString() const @safe pure nothrow |
| { |
| return toSimpleString(); |
| } |
| |
| @safe unittest |
| { |
| auto dt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| const cdt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| immutable idt = DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33)); |
| assert(dt.toString()); |
| assert(cdt.toString()); |
| assert(idt.toString()); |
| } |
| |
| |
| |
| /++ |
| Creates a $(LREF DateTime) from a string with the format YYYYMMDDTHHMMSS. |
| Whitespace is stripped from the given string. |
| |
| Params: |
| isoString = A string formatted in the ISO format for dates and times. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the given string is |
| not in the ISO format or if the resulting $(LREF DateTime) would not |
| be valid. |
| +/ |
| static DateTime fromISOString(S)(in S isoString) @safe pure |
| if (isSomeString!S) |
| { |
| import std.algorithm.searching : countUntil; |
| import std.exception : enforce; |
| import std.format : format; |
| import std.string : strip; |
| |
| auto str = strip(isoString); |
| |
| enforce(str.length >= 15, new DateTimeException(format("Invalid ISO String: %s", isoString))); |
| auto t = str.countUntil('T'); |
| |
| enforce(t != -1, new DateTimeException(format("Invalid ISO String: %s", isoString))); |
| |
| immutable date = Date.fromISOString(str[0 .. t]); |
| immutable tod = TimeOfDay.fromISOString(str[t+1 .. $]); |
| |
| return DateTime(date, tod); |
| } |
| |
| /// |
| @safe unittest |
| { |
| assert(DateTime.fromISOString("20100704T070612") == |
| DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12))); |
| |
| assert(DateTime.fromISOString("19981225T021500") == |
| DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0))); |
| |
| assert(DateTime.fromISOString("00000105T230959") == |
| DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59))); |
| |
| assert(DateTime.fromISOString("-00040105T000002") == |
| DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2))); |
| |
| assert(DateTime.fromISOString(" 20100704T070612 ") == |
| DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12))); |
| } |
| |
| @safe unittest |
| { |
| assertThrown!DateTimeException(DateTime.fromISOString("")); |
| assertThrown!DateTimeException(DateTime.fromISOString("20100704000000")); |
| assertThrown!DateTimeException(DateTime.fromISOString("20100704 000000")); |
| assertThrown!DateTimeException(DateTime.fromISOString("20100704t000000")); |
| assertThrown!DateTimeException(DateTime.fromISOString("20100704T000000.")); |
| assertThrown!DateTimeException(DateTime.fromISOString("20100704T000000.0")); |
| |
| assertThrown!DateTimeException(DateTime.fromISOString("2010-07-0400:00:00")); |
| assertThrown!DateTimeException(DateTime.fromISOString("2010-07-04 00:00:00")); |
| assertThrown!DateTimeException(DateTime.fromISOString("2010-07-04t00:00:00")); |
| assertThrown!DateTimeException(DateTime.fromISOString("2010-07-04T00:00:00.")); |
| assertThrown!DateTimeException(DateTime.fromISOString("2010-07-04T00:00:00.0")); |
| |
| assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-0400:00:00")); |
| assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04 00:00:00")); |
| assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04t00:00:00")); |
| assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04T00:00:00")); |
| assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04 00:00:00.")); |
| assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04 00:00:00.0")); |
| |
| assertThrown!DateTimeException(DateTime.fromISOString("2010-12-22T172201")); |
| assertThrown!DateTimeException(DateTime.fromISOString("2010-Dec-22 17:22:01")); |
| |
| assert(DateTime.fromISOString("20101222T172201") == DateTime(Date(2010, 12, 22), TimeOfDay(17, 22, 01))); |
| assert(DateTime.fromISOString("19990706T123033") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| assert(DateTime.fromISOString("-19990706T123033") == DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))); |
| assert(DateTime.fromISOString("+019990706T123033") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| assert(DateTime.fromISOString("19990706T123033 ") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| assert(DateTime.fromISOString(" 19990706T123033") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| assert(DateTime.fromISOString(" 19990706T123033 ") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| } |
| |
| // bug# 17801 |
| @safe unittest |
| { |
| import std.conv : to; |
| import std.meta : AliasSeq; |
| foreach (C; AliasSeq!(char, wchar, dchar)) |
| { |
| foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) |
| assert(DateTime.fromISOString(to!S("20121221T141516")) == DateTime(2012, 12, 21, 14, 15, 16)); |
| } |
| } |
| |
| |
| /++ |
| Creates a $(LREF DateTime) from a string with the format |
| YYYY-MM-DDTHH:MM:SS. Whitespace is stripped from the given string. |
| |
| Params: |
| isoExtString = A string formatted in the ISO Extended format for dates |
| and times. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the given string is |
| not in the ISO Extended format or if the resulting $(LREF DateTime) |
| would not be valid. |
| +/ |
| static DateTime fromISOExtString(S)(in S isoExtString) @safe pure |
| if (isSomeString!(S)) |
| { |
| import std.algorithm.searching : countUntil; |
| import std.exception : enforce; |
| import std.format : format; |
| import std.string : strip; |
| |
| auto str = strip(isoExtString); |
| |
| enforce(str.length >= 15, new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString))); |
| auto t = str.countUntil('T'); |
| |
| enforce(t != -1, new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString))); |
| |
| immutable date = Date.fromISOExtString(str[0 .. t]); |
| immutable tod = TimeOfDay.fromISOExtString(str[t+1 .. $]); |
| |
| return DateTime(date, tod); |
| } |
| |
| /// |
| @safe unittest |
| { |
| assert(DateTime.fromISOExtString("2010-07-04T07:06:12") == |
| DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12))); |
| |
| assert(DateTime.fromISOExtString("1998-12-25T02:15:00") == |
| DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0))); |
| |
| assert(DateTime.fromISOExtString("0000-01-05T23:09:59") == |
| DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59))); |
| |
| assert(DateTime.fromISOExtString("-0004-01-05T00:00:02") == |
| DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2))); |
| |
| assert(DateTime.fromISOExtString(" 2010-07-04T07:06:12 ") == |
| DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12))); |
| } |
| |
| @safe unittest |
| { |
| assertThrown!DateTimeException(DateTime.fromISOExtString("")); |
| assertThrown!DateTimeException(DateTime.fromISOExtString("20100704000000")); |
| assertThrown!DateTimeException(DateTime.fromISOExtString("20100704 000000")); |
| assertThrown!DateTimeException(DateTime.fromISOExtString("20100704t000000")); |
| assertThrown!DateTimeException(DateTime.fromISOExtString("20100704T000000.")); |
| assertThrown!DateTimeException(DateTime.fromISOExtString("20100704T000000.0")); |
| |
| assertThrown!DateTimeException(DateTime.fromISOExtString("2010-07:0400:00:00")); |
| assertThrown!DateTimeException(DateTime.fromISOExtString("2010-07-04 00:00:00")); |
| assertThrown!DateTimeException(DateTime.fromISOExtString("2010-07-04 00:00:00")); |
| assertThrown!DateTimeException(DateTime.fromISOExtString("2010-07-04t00:00:00")); |
| assertThrown!DateTimeException(DateTime.fromISOExtString("2010-07-04T00:00:00.")); |
| assertThrown!DateTimeException(DateTime.fromISOExtString("2010-07-04T00:00:00.0")); |
| |
| assertThrown!DateTimeException(DateTime.fromISOExtString("2010-Jul-0400:00:00")); |
| assertThrown!DateTimeException(DateTime.fromISOExtString("2010-Jul-04t00:00:00")); |
| assertThrown!DateTimeException(DateTime.fromISOExtString("2010-Jul-04 00:00:00.")); |
| assertThrown!DateTimeException(DateTime.fromISOExtString("2010-Jul-04 00:00:00.0")); |
| |
| assertThrown!DateTimeException(DateTime.fromISOExtString("20101222T172201")); |
| assertThrown!DateTimeException(DateTime.fromISOExtString("2010-Dec-22 17:22:01")); |
| |
| assert(DateTime.fromISOExtString("2010-12-22T17:22:01") == DateTime(Date(2010, 12, 22), TimeOfDay(17, 22, 01))); |
| assert(DateTime.fromISOExtString("1999-07-06T12:30:33") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| assert(DateTime.fromISOExtString("-1999-07-06T12:30:33") == DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))); |
| assert(DateTime.fromISOExtString("+01999-07-06T12:30:33") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| assert(DateTime.fromISOExtString("1999-07-06T12:30:33 ") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| assert(DateTime.fromISOExtString(" 1999-07-06T12:30:33") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| assert(DateTime.fromISOExtString(" 1999-07-06T12:30:33 ") == DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| } |
| |
| // bug# 17801 |
| @safe unittest |
| { |
| import std.conv : to; |
| import std.meta : AliasSeq; |
| foreach (C; AliasSeq!(char, wchar, dchar)) |
| { |
| foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) |
| assert(DateTime.fromISOExtString(to!S("2012-12-21T14:15:16")) == DateTime(2012, 12, 21, 14, 15, 16)); |
| } |
| } |
| |
| |
| /++ |
| Creates a $(LREF DateTime) from a string with the format |
| YYYY-Mon-DD HH:MM:SS. Whitespace is stripped from the given string. |
| |
| Params: |
| simpleString = A string formatted in the way that toSimpleString |
| formats dates and times. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the given string is |
| not in the correct format or if the resulting $(LREF DateTime) |
| would not be valid. |
| +/ |
| static DateTime fromSimpleString(S)(in S simpleString) @safe pure |
| if (isSomeString!(S)) |
| { |
| import std.algorithm.searching : countUntil; |
| import std.exception : enforce; |
| import std.format : format; |
| import std.string : strip; |
| |
| auto str = strip(simpleString); |
| |
| enforce(str.length >= 15, new DateTimeException(format("Invalid string format: %s", simpleString))); |
| auto t = str.countUntil(' '); |
| |
| enforce(t != -1, new DateTimeException(format("Invalid string format: %s", simpleString))); |
| |
| immutable date = Date.fromSimpleString(str[0 .. t]); |
| immutable tod = TimeOfDay.fromISOExtString(str[t+1 .. $]); |
| |
| return DateTime(date, tod); |
| } |
| |
| /// |
| @safe unittest |
| { |
| assert(DateTime.fromSimpleString("2010-Jul-04 07:06:12") == |
| DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12))); |
| assert(DateTime.fromSimpleString("1998-Dec-25 02:15:00") == |
| DateTime(Date(1998, 12, 25), TimeOfDay(2, 15, 0))); |
| assert(DateTime.fromSimpleString("0000-Jan-05 23:09:59") == |
| DateTime(Date(0, 1, 5), TimeOfDay(23, 9, 59))); |
| assert(DateTime.fromSimpleString("-0004-Jan-05 00:00:02") == |
| DateTime(Date(-4, 1, 5), TimeOfDay(0, 0, 2))); |
| assert(DateTime.fromSimpleString(" 2010-Jul-04 07:06:12 ") == |
| DateTime(Date(2010, 7, 4), TimeOfDay(7, 6, 12))); |
| } |
| |
| @safe unittest |
| { |
| assertThrown!DateTimeException(DateTime.fromISOString("")); |
| assertThrown!DateTimeException(DateTime.fromISOString("20100704000000")); |
| assertThrown!DateTimeException(DateTime.fromISOString("20100704 000000")); |
| assertThrown!DateTimeException(DateTime.fromISOString("20100704t000000")); |
| assertThrown!DateTimeException(DateTime.fromISOString("20100704T000000.")); |
| assertThrown!DateTimeException(DateTime.fromISOString("20100704T000000.0")); |
| |
| assertThrown!DateTimeException(DateTime.fromISOString("2010-07-0400:00:00")); |
| assertThrown!DateTimeException(DateTime.fromISOString("2010-07-04 00:00:00")); |
| assertThrown!DateTimeException(DateTime.fromISOString("2010-07-04t00:00:00")); |
| assertThrown!DateTimeException(DateTime.fromISOString("2010-07-04T00:00:00.")); |
| assertThrown!DateTimeException(DateTime.fromISOString("2010-07-04T00:00:00.0")); |
| |
| assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-0400:00:00")); |
| assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04 00:00:00")); |
| assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04t00:00:00")); |
| assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04T00:00:00")); |
| assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04 00:00:00.")); |
| assertThrown!DateTimeException(DateTime.fromISOString("2010-Jul-04 00:00:00.0")); |
| |
| assertThrown!DateTimeException(DateTime.fromSimpleString("20101222T172201")); |
| assertThrown!DateTimeException(DateTime.fromSimpleString("2010-12-22T172201")); |
| |
| assert(DateTime.fromSimpleString("2010-Dec-22 17:22:01") == |
| DateTime(Date(2010, 12, 22), TimeOfDay(17, 22, 01))); |
| assert(DateTime.fromSimpleString("1999-Jul-06 12:30:33") == |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| assert(DateTime.fromSimpleString("-1999-Jul-06 12:30:33") == |
| DateTime(Date(-1999, 7, 6), TimeOfDay(12, 30, 33))); |
| assert(DateTime.fromSimpleString("+01999-Jul-06 12:30:33") == |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| assert(DateTime.fromSimpleString("1999-Jul-06 12:30:33 ") == |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| assert(DateTime.fromSimpleString(" 1999-Jul-06 12:30:33") == |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| assert(DateTime.fromSimpleString(" 1999-Jul-06 12:30:33 ") == |
| DateTime(Date(1999, 7, 6), TimeOfDay(12, 30, 33))); |
| } |
| |
| // bug# 17801 |
| @safe unittest |
| { |
| import std.conv : to; |
| import std.meta : AliasSeq; |
| foreach (C; AliasSeq!(char, wchar, dchar)) |
| { |
| foreach (S; AliasSeq!(C[], const(C)[], immutable(C)[])) |
| assert(DateTime.fromSimpleString(to!S("2012-Dec-21 14:15:16")) == DateTime(2012, 12, 21, 14, 15, 16)); |
| } |
| } |
| |
| |
| /++ |
| Returns the $(LREF DateTime) farthest in the past which is representable |
| by $(LREF DateTime). |
| +/ |
| @property static DateTime min() @safe pure nothrow @nogc |
| out(result) |
| { |
| assert(result._date == Date.min); |
| assert(result._tod == TimeOfDay.min); |
| } |
| body |
| { |
| auto dt = DateTime.init; |
| dt._date._year = short.min; |
| dt._date._month = Month.jan; |
| dt._date._day = 1; |
| |
| return dt; |
| } |
| |
| @safe unittest |
| { |
| assert(DateTime.min.year < 0); |
| assert(DateTime.min < DateTime.max); |
| } |
| |
| |
| /++ |
| Returns the $(LREF DateTime) farthest in the future which is |
| representable by $(LREF DateTime). |
| +/ |
| @property static DateTime max() @safe pure nothrow @nogc |
| out(result) |
| { |
| assert(result._date == Date.max); |
| assert(result._tod == TimeOfDay.max); |
| } |
| body |
| { |
| auto dt = DateTime.init; |
| dt._date._year = short.max; |
| dt._date._month = Month.dec; |
| dt._date._day = 31; |
| dt._tod._hour = TimeOfDay.maxHour; |
| dt._tod._minute = TimeOfDay.maxMinute; |
| dt._tod._second = TimeOfDay.maxSecond; |
| |
| return dt; |
| } |
| |
| @safe unittest |
| { |
| assert(DateTime.max.year > 0); |
| assert(DateTime.max > DateTime.min); |
| } |
| |
| |
| private: |
| |
| /+ |
| Add seconds to the time of day. Negative values will subtract. If the |
| number of seconds overflows (or underflows), then the seconds will wrap, |
| increasing (or decreasing) the number of minutes accordingly. The |
| same goes for any larger units. |
| |
| Params: |
| seconds = The number of seconds to add to this $(LREF DateTime). |
| +/ |
| ref DateTime _addSeconds(long seconds) return @safe pure nothrow @nogc |
| { |
| long hnsecs = convert!("seconds", "hnsecs")(seconds); |
| hnsecs += convert!("hours", "hnsecs")(_tod._hour); |
| hnsecs += convert!("minutes", "hnsecs")(_tod._minute); |
| hnsecs += convert!("seconds", "hnsecs")(_tod._second); |
| |
| auto days = splitUnitsFromHNSecs!"days"(hnsecs); |
| |
| if (hnsecs < 0) |
| { |
| hnsecs += convert!("days", "hnsecs")(1); |
| --days; |
| } |
| |
| _date._addDays(days); |
| |
| immutable newHours = splitUnitsFromHNSecs!"hours"(hnsecs); |
| immutable newMinutes = splitUnitsFromHNSecs!"minutes"(hnsecs); |
| immutable newSeconds = splitUnitsFromHNSecs!"seconds"(hnsecs); |
| |
| _tod._hour = cast(ubyte) newHours; |
| _tod._minute = cast(ubyte) newMinutes; |
| _tod._second = cast(ubyte) newSeconds; |
| |
| return this; |
| } |
| |
| @safe unittest |
| { |
| static void testDT(DateTime orig, int seconds, in DateTime expected, size_t line = __LINE__) |
| { |
| orig._addSeconds(seconds); |
| assert(orig == expected); |
| } |
| |
| // Test A.D. |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), 0, DateTime(1999, 7, 6, 12, 30, 33)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), 1, DateTime(1999, 7, 6, 12, 30, 34)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), 2, DateTime(1999, 7, 6, 12, 30, 35)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), 3, DateTime(1999, 7, 6, 12, 30, 36)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), 4, DateTime(1999, 7, 6, 12, 30, 37)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), 5, DateTime(1999, 7, 6, 12, 30, 38)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), 10, DateTime(1999, 7, 6, 12, 30, 43)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), 15, DateTime(1999, 7, 6, 12, 30, 48)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), 26, DateTime(1999, 7, 6, 12, 30, 59)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), 27, DateTime(1999, 7, 6, 12, 31, 0)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), 30, DateTime(1999, 7, 6, 12, 31, 3)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), 59, DateTime(1999, 7, 6, 12, 31, 32)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), 60, DateTime(1999, 7, 6, 12, 31, 33)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), 61, DateTime(1999, 7, 6, 12, 31, 34)); |
| |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), 1766, DateTime(1999, 7, 6, 12, 59, 59)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), 1767, DateTime(1999, 7, 6, 13, 0, 0)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), 1768, DateTime(1999, 7, 6, 13, 0, 1)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), 2007, DateTime(1999, 7, 6, 13, 4, 0)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), 3599, DateTime(1999, 7, 6, 13, 30, 32)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), 3600, DateTime(1999, 7, 6, 13, 30, 33)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), 3601, DateTime(1999, 7, 6, 13, 30, 34)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), 7200, DateTime(1999, 7, 6, 14, 30, 33)); |
| testDT(DateTime(1999, 7, 6, 23, 0, 0), 432_123, DateTime(1999, 7, 11, 23, 2, 3)); |
| |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), -1, DateTime(1999, 7, 6, 12, 30, 32)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), -2, DateTime(1999, 7, 6, 12, 30, 31)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), -3, DateTime(1999, 7, 6, 12, 30, 30)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), -4, DateTime(1999, 7, 6, 12, 30, 29)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), -5, DateTime(1999, 7, 6, 12, 30, 28)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), -10, DateTime(1999, 7, 6, 12, 30, 23)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), -15, DateTime(1999, 7, 6, 12, 30, 18)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), -33, DateTime(1999, 7, 6, 12, 30, 0)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), -34, DateTime(1999, 7, 6, 12, 29, 59)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), -35, DateTime(1999, 7, 6, 12, 29, 58)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), -59, DateTime(1999, 7, 6, 12, 29, 34)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), -60, DateTime(1999, 7, 6, 12, 29, 33)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), -61, DateTime(1999, 7, 6, 12, 29, 32)); |
| |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), -1833, DateTime(1999, 7, 6, 12, 0, 0)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), -1834, DateTime(1999, 7, 6, 11, 59, 59)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), -3600, DateTime(1999, 7, 6, 11, 30, 33)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), -3601, DateTime(1999, 7, 6, 11, 30, 32)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 33), -5134, DateTime(1999, 7, 6, 11, 4, 59)); |
| testDT(DateTime(1999, 7, 6, 23, 0, 0), -432_123, DateTime(1999, 7, 1, 22, 57, 57)); |
| |
| testDT(DateTime(1999, 7, 6, 12, 30, 0), 1, DateTime(1999, 7, 6, 12, 30, 1)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 0), 0, DateTime(1999, 7, 6, 12, 30, 0)); |
| testDT(DateTime(1999, 7, 6, 12, 30, 0), -1, DateTime(1999, 7, 6, 12, 29, 59)); |
| |
| testDT(DateTime(1999, 7, 6, 12, 0, 0), 1, DateTime(1999, 7, 6, 12, 0, 1)); |
| testDT(DateTime(1999, 7, 6, 12, 0, 0), 0, DateTime(1999, 7, 6, 12, 0, 0)); |
| testDT(DateTime(1999, 7, 6, 12, 0, 0), -1, DateTime(1999, 7, 6, 11, 59, 59)); |
| |
| testDT(DateTime(1999, 7, 6, 0, 0, 0), 1, DateTime(1999, 7, 6, 0, 0, 1)); |
| testDT(DateTime(1999, 7, 6, 0, 0, 0), 0, DateTime(1999, 7, 6, 0, 0, 0)); |
| testDT(DateTime(1999, 7, 6, 0, 0, 0), -1, DateTime(1999, 7, 5, 23, 59, 59)); |
| |
| testDT(DateTime(1999, 7, 5, 23, 59, 59), 1, DateTime(1999, 7, 6, 0, 0, 0)); |
| testDT(DateTime(1999, 7, 5, 23, 59, 59), 0, DateTime(1999, 7, 5, 23, 59, 59)); |
| testDT(DateTime(1999, 7, 5, 23, 59, 59), -1, DateTime(1999, 7, 5, 23, 59, 58)); |
| |
| testDT(DateTime(1998, 12, 31, 23, 59, 59), 1, DateTime(1999, 1, 1, 0, 0, 0)); |
| testDT(DateTime(1998, 12, 31, 23, 59, 59), 0, DateTime(1998, 12, 31, 23, 59, 59)); |
| testDT(DateTime(1998, 12, 31, 23, 59, 59), -1, DateTime(1998, 12, 31, 23, 59, 58)); |
| |
| testDT(DateTime(1998, 1, 1, 0, 0, 0), 1, DateTime(1998, 1, 1, 0, 0, 1)); |
| testDT(DateTime(1998, 1, 1, 0, 0, 0), 0, DateTime(1998, 1, 1, 0, 0, 0)); |
| testDT(DateTime(1998, 1, 1, 0, 0, 0), -1, DateTime(1997, 12, 31, 23, 59, 59)); |
| |
| // Test B.C. |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), 0, DateTime(-1999, 7, 6, 12, 30, 33)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), 1, DateTime(-1999, 7, 6, 12, 30, 34)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), 2, DateTime(-1999, 7, 6, 12, 30, 35)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), 3, DateTime(-1999, 7, 6, 12, 30, 36)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), 4, DateTime(-1999, 7, 6, 12, 30, 37)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), 5, DateTime(-1999, 7, 6, 12, 30, 38)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), 10, DateTime(-1999, 7, 6, 12, 30, 43)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), 15, DateTime(-1999, 7, 6, 12, 30, 48)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), 26, DateTime(-1999, 7, 6, 12, 30, 59)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), 27, DateTime(-1999, 7, 6, 12, 31, 0)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), 30, DateTime(-1999, 7, 6, 12, 31, 3)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), 59, DateTime(-1999, 7, 6, 12, 31, 32)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), 60, DateTime(-1999, 7, 6, 12, 31, 33)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), 61, DateTime(-1999, 7, 6, 12, 31, 34)); |
| |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), 1766, DateTime(-1999, 7, 6, 12, 59, 59)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), 1767, DateTime(-1999, 7, 6, 13, 0, 0)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), 1768, DateTime(-1999, 7, 6, 13, 0, 1)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), 2007, DateTime(-1999, 7, 6, 13, 4, 0)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), 3599, DateTime(-1999, 7, 6, 13, 30, 32)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), 3600, DateTime(-1999, 7, 6, 13, 30, 33)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), 3601, DateTime(-1999, 7, 6, 13, 30, 34)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), 7200, DateTime(-1999, 7, 6, 14, 30, 33)); |
| testDT(DateTime(-1999, 7, 6, 23, 0, 0), 432_123, DateTime(-1999, 7, 11, 23, 2, 3)); |
| |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), -1, DateTime(-1999, 7, 6, 12, 30, 32)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), -2, DateTime(-1999, 7, 6, 12, 30, 31)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), -3, DateTime(-1999, 7, 6, 12, 30, 30)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), -4, DateTime(-1999, 7, 6, 12, 30, 29)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), -5, DateTime(-1999, 7, 6, 12, 30, 28)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), -10, DateTime(-1999, 7, 6, 12, 30, 23)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), -15, DateTime(-1999, 7, 6, 12, 30, 18)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), -33, DateTime(-1999, 7, 6, 12, 30, 0)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), -34, DateTime(-1999, 7, 6, 12, 29, 59)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), -35, DateTime(-1999, 7, 6, 12, 29, 58)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), -59, DateTime(-1999, 7, 6, 12, 29, 34)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), -60, DateTime(-1999, 7, 6, 12, 29, 33)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), -61, DateTime(-1999, 7, 6, 12, 29, 32)); |
| |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), -1833, DateTime(-1999, 7, 6, 12, 0, 0)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), -1834, DateTime(-1999, 7, 6, 11, 59, 59)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), -3600, DateTime(-1999, 7, 6, 11, 30, 33)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), -3601, DateTime(-1999, 7, 6, 11, 30, 32)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), -5134, DateTime(-1999, 7, 6, 11, 4, 59)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 33), -7200, DateTime(-1999, 7, 6, 10, 30, 33)); |
| testDT(DateTime(-1999, 7, 6, 23, 0, 0), -432_123, DateTime(-1999, 7, 1, 22, 57, 57)); |
| |
| testDT(DateTime(-1999, 7, 6, 12, 30, 0), 1, DateTime(-1999, 7, 6, 12, 30, 1)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 0), 0, DateTime(-1999, 7, 6, 12, 30, 0)); |
| testDT(DateTime(-1999, 7, 6, 12, 30, 0), -1, DateTime(-1999, 7, 6, 12, 29, 59)); |
| |
| testDT(DateTime(-1999, 7, 6, 12, 0, 0), 1, DateTime(-1999, 7, 6, 12, 0, 1)); |
| testDT(DateTime(-1999, 7, 6, 12, 0, 0), 0, DateTime(-1999, 7, 6, 12, 0, 0)); |
| testDT(DateTime(-1999, 7, 6, 12, 0, 0), -1, DateTime(-1999, 7, 6, 11, 59, 59)); |
| |
| testDT(DateTime(-1999, 7, 6, 0, 0, 0), 1, DateTime(-1999, 7, 6, 0, 0, 1)); |
| testDT(DateTime(-1999, 7, 6, 0, 0, 0), 0, DateTime(-1999, 7, 6, 0, 0, 0)); |
| testDT(DateTime(-1999, 7, 6, 0, 0, 0), -1, DateTime(-1999, 7, 5, 23, 59, 59)); |
| |
| testDT(DateTime(-1999, 7, 5, 23, 59, 59), 1, DateTime(-1999, 7, 6, 0, 0, 0)); |
| testDT(DateTime(-1999, 7, 5, 23, 59, 59), 0, DateTime(-1999, 7, 5, 23, 59, 59)); |
| testDT(DateTime(-1999, 7, 5, 23, 59, 59), -1, DateTime(-1999, 7, 5, 23, 59, 58)); |
| |
| testDT(DateTime(-2000, 12, 31, 23, 59, 59), 1, DateTime(-1999, 1, 1, 0, 0, 0)); |
| testDT(DateTime(-2000, 12, 31, 23, 59, 59), 0, DateTime(-2000, 12, 31, 23, 59, 59)); |
| testDT(DateTime(-2000, 12, 31, 23, 59, 59), -1, DateTime(-2000, 12, 31, 23, 59, 58)); |
| |
| testDT(DateTime(-2000, 1, 1, 0, 0, 0), 1, DateTime(-2000, 1, 1, 0, 0, 1)); |
| testDT(DateTime(-2000, 1, 1, 0, 0, 0), 0, DateTime(-2000, 1, 1, 0, 0, 0)); |
| testDT(DateTime(-2000, 1, 1, 0, 0, 0), -1, DateTime(-2001, 12, 31, 23, 59, 59)); |
| |
| // Test Both |
| testDT(DateTime(1, 1, 1, 0, 0, 0), -1, DateTime(0, 12, 31, 23, 59, 59)); |
| testDT(DateTime(0, 12, 31, 23, 59, 59), 1, DateTime(1, 1, 1, 0, 0, 0)); |
| |
| testDT(DateTime(0, 1, 1, 0, 0, 0), -1, DateTime(-1, 12, 31, 23, 59, 59)); |
| testDT(DateTime(-1, 12, 31, 23, 59, 59), 1, DateTime(0, 1, 1, 0, 0, 0)); |
| |
| testDT(DateTime(-1, 1, 1, 11, 30, 33), 63_165_600L, DateTime(1, 1, 1, 13, 30, 33)); |
| testDT(DateTime(1, 1, 1, 13, 30, 33), -63_165_600L, DateTime(-1, 1, 1, 11, 30, 33)); |
| |
| testDT(DateTime(-1, 1, 1, 11, 30, 33), 63_165_617L, DateTime(1, 1, 1, 13, 30, 50)); |
| testDT(DateTime(1, 1, 1, 13, 30, 50), -63_165_617L, DateTime(-1, 1, 1, 11, 30, 33)); |
| |
| const cdt = DateTime(1999, 7, 6, 12, 30, 33); |
| immutable idt = DateTime(1999, 7, 6, 12, 30, 33); |
| static assert(!__traits(compiles, cdt._addSeconds(4))); |
| static assert(!__traits(compiles, idt._addSeconds(4))); |
| } |
| |
| |
| Date _date; |
| TimeOfDay _tod; |
| } |
| |
| |
| /++ |
| Represents a date in the |
| $(HTTP en.wikipedia.org/wiki/Proleptic_Gregorian_calendar, Proleptic |
| Gregorian Calendar) ranging from 32,768 B.C. to 32,767 A.D. Positive years |
| are A.D. Non-positive years are B.C. |
| |
| Year, month, and day are kept separately internally so that $(D Date) is |
| optimized for calendar-based operations. |
| |
| $(D Date) uses the Proleptic Gregorian Calendar, so it assumes the Gregorian |
| leap year calculations for its entire length. As per |
| $(HTTP en.wikipedia.org/wiki/ISO_8601, ISO 8601), it treats 1 B.C. as |
| year 0, i.e. 1 B.C. is 0, 2 B.C. is -1, etc. Use $(LREF yearBC) to use B.C. |
| as a positive integer with 1 B.C. being the year prior to 1 A.D. |
| |
| Year 0 is a leap year. |
| +/ |
| struct Date |
| { |
| public: |
| |
| /++ |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the resulting |
| $(LREF Date) would not be valid. |
| |
| Params: |
| year = Year of the Gregorian Calendar. Positive values are A.D. |
| Non-positive values are B.C. with year 0 being the year |
| prior to 1 A.D. |
| month = Month of the year (January is 1). |
| day = Day of the month. |
| +/ |
| this(int year, int month, int day) @safe pure |
| { |
| enforceValid!"months"(cast(Month) month); |
| enforceValid!"days"(year, cast(Month) month, day); |
| |
| _year = cast(short) year; |
| _month = cast(Month) month; |
| _day = cast(ubyte) day; |
| } |
| |
| @safe unittest |
| { |
| import std.exception : assertNotThrown; |
| assert(Date(1, 1, 1) == Date.init); |
| |
| static void testDate(in Date date, int year, int month, int day) |
| { |
| assert(date._year == year); |
| assert(date._month == month); |
| assert(date._day == day); |
| } |
| |
| testDate(Date(1999, 1 , 1), 1999, Month.jan, 1); |
| testDate(Date(1999, 7 , 1), 1999, Month.jul, 1); |
| testDate(Date(1999, 7 , 6), 1999, Month.jul, 6); |
| |
| // Test A.D. |
| assertThrown!DateTimeException(Date(1, 0, 1)); |
| assertThrown!DateTimeException(Date(1, 1, 0)); |
| assertThrown!DateTimeException(Date(1999, 13, 1)); |
| assertThrown!DateTimeException(Date(1999, 1, 32)); |
| assertThrown!DateTimeException(Date(1999, 2, 29)); |
| assertThrown!DateTimeException(Date(2000, 2, 30)); |
| assertThrown!DateTimeException(Date(1999, 3, 32)); |
| assertThrown!DateTimeException(Date(1999, 4, 31)); |
| assertThrown!DateTimeException(Date(1999, 5, 32)); |
| assertThrown!DateTimeException(Date(1999, 6, 31)); |
| assertThrown!DateTimeException(Date(1999, 7, 32)); |
| assertThrown!DateTimeException(Date(1999, 8, 32)); |
| assertThrown!DateTimeException(Date(1999, 9, 31)); |
| assertThrown!DateTimeException(Date(1999, 10, 32)); |
| assertThrown!DateTimeException(Date(1999, 11, 31)); |
| assertThrown!DateTimeException(Date(1999, 12, 32)); |
| |
| assertNotThrown!DateTimeException(Date(1999, 1, 31)); |
| assertNotThrown!DateTimeException(Date(1999, 2, 28)); |
| assertNotThrown!DateTimeException(Date(2000, 2, 29)); |
| assertNotThrown!DateTimeException(Date(1999, 3, 31)); |
| assertNotThrown!DateTimeException(Date(1999, 4, 30)); |
| assertNotThrown!DateTimeException(Date(1999, 5, 31)); |
| assertNotThrown!DateTimeException(Date(1999, 6, 30)); |
| assertNotThrown!DateTimeException(Date(1999, 7, 31)); |
| assertNotThrown!DateTimeException(Date(1999, 8, 31)); |
| assertNotThrown!DateTimeException(Date(1999, 9, 30)); |
| assertNotThrown!DateTimeException(Date(1999, 10, 31)); |
| assertNotThrown!DateTimeException(Date(1999, 11, 30)); |
| assertNotThrown!DateTimeException(Date(1999, 12, 31)); |
| |
| // Test B.C. |
| assertNotThrown!DateTimeException(Date(0, 1, 1)); |
| assertNotThrown!DateTimeException(Date(-1, 1, 1)); |
| assertNotThrown!DateTimeException(Date(-1, 12, 31)); |
| assertNotThrown!DateTimeException(Date(-1, 2, 28)); |
| assertNotThrown!DateTimeException(Date(-4, 2, 29)); |
| |
| assertThrown!DateTimeException(Date(-1, 2, 29)); |
| assertThrown!DateTimeException(Date(-2, 2, 29)); |
| assertThrown!DateTimeException(Date(-3, 2, 29)); |
| } |
| |
| |
| /++ |
| Params: |
| day = The Xth day of the Gregorian Calendar that the constructed |
| $(LREF Date) will be for. |
| +/ |
| this(int day) @safe pure nothrow @nogc |
| { |
| if (day > 0) |
| { |
| int years = (day / daysIn400Years) * 400 + 1; |
| day %= daysIn400Years; |
| |
| { |
| immutable tempYears = day / daysIn100Years; |
| |
| if (tempYears == 4) |
| { |
| years += 300; |
| day -= daysIn100Years * 3; |
| } |
| else |
| { |
| years += tempYears * 100; |
| day %= daysIn100Years; |
| } |
| } |
| |
| years += (day / daysIn4Years) * 4; |
| day %= daysIn4Years; |
| |
| { |
| immutable tempYears = day / daysInYear; |
| |
| if (tempYears == 4) |
| { |
| years += 3; |
| day -= daysInYear * 3; |
| } |
| else |
| { |
| years += tempYears; |
| day %= daysInYear; |
| } |
| } |
| |
| if (day == 0) |
| { |
| _year = cast(short)(years - 1); |
| _month = Month.dec; |
| _day = 31; |
| } |
| else |
| { |
| _year = cast(short) years; |
| |
| setDayOfYear(day); |
| } |
| } |
| else if (day <= 0 && -day < daysInLeapYear) |
| { |
| _year = 0; |
| |
| setDayOfYear(daysInLeapYear + day); |
| } |
| else |
| { |
| day += daysInLeapYear - 1; |
| int years = (day / daysIn400Years) * 400 - 1; |
| day %= daysIn400Years; |
| |
| { |
| immutable tempYears = day / daysIn100Years; |
| |
| if (tempYears == -4) |
| { |
| years -= 300; |
| day += daysIn100Years * 3; |
| } |
| else |
| { |
| years += tempYears * 100; |
| day %= daysIn100Years; |
| } |
| } |
| |
| years += (day / daysIn4Years) * 4; |
| day %= daysIn4Years; |
| |
| { |
| immutable tempYears = day / daysInYear; |
| |
| if (tempYears == -4) |
| { |
| years -= 3; |
| day += daysInYear * 3; |
| } |
| else |
| { |
| years += tempYears; |
| day %= daysInYear; |
| } |
| } |
| |
| if (day == 0) |
| { |
| _year = cast(short)(years + 1); |
| _month = Month.jan; |
| _day = 1; |
| } |
| else |
| { |
| _year = cast(short) years; |
| immutable newDoY = (yearIsLeapYear(_year) ? daysInLeapYear : daysInYear) + day + 1; |
| |
| setDayOfYear(newDoY); |
| } |
| } |
| } |
| |
| @safe unittest |
| { |
| import std.range : chain; |
| |
| // Test A.D. |
| foreach (gd; chain(testGregDaysBC, testGregDaysAD)) |
| assert(Date(gd.day) == gd.date); |
| } |
| |
| |
| /++ |
| Compares this $(LREF Date) with the given $(LREF Date). |
| |
| Returns: |
| $(BOOKTABLE, |
| $(TR $(TD this < rhs) $(TD < 0)) |
| $(TR $(TD this == rhs) $(TD 0)) |
| $(TR $(TD this > rhs) $(TD > 0)) |
| ) |
| +/ |
| int opCmp(in Date rhs) const @safe pure nothrow @nogc |
| { |
| if (_year < rhs._year) |
| return -1; |
| if (_year > rhs._year) |
| return 1; |
| |
| if (_month < rhs._month) |
| return -1; |
| if (_month > rhs._month) |
| return 1; |
| |
| if (_day < rhs._day) |
| return -1; |
| if (_day > rhs._day) |
| return 1; |
| |
| return 0; |
| } |
| |
| @safe unittest |
| { |
| // Test A.D. |
| assert(Date(1, 1, 1).opCmp(Date.init) == 0); |
| |
| assert(Date(1999, 1, 1).opCmp(Date(1999, 1, 1)) == 0); |
| assert(Date(1, 7, 1).opCmp(Date(1, 7, 1)) == 0); |
| assert(Date(1, 1, 6).opCmp(Date(1, 1, 6)) == 0); |
| |
| assert(Date(1999, 7, 1).opCmp(Date(1999, 7, 1)) == 0); |
| assert(Date(1999, 7, 6).opCmp(Date(1999, 7, 6)) == 0); |
| |
| assert(Date(1, 7, 6).opCmp(Date(1, 7, 6)) == 0); |
| |
| assert(Date(1999, 7, 6).opCmp(Date(2000, 7, 6)) < 0); |
| assert(Date(2000, 7, 6).opCmp(Date(1999, 7, 6)) > 0); |
| assert(Date(1999, 7, 6).opCmp(Date(1999, 8, 6)) < 0); |
| assert(Date(1999, 8, 6).opCmp(Date(1999, 7, 6)) > 0); |
| assert(Date(1999, 7, 6).opCmp(Date(1999, 7, 7)) < 0); |
| assert(Date(1999, 7, 7).opCmp(Date(1999, 7, 6)) > 0); |
| |
| assert(Date(1999, 8, 7).opCmp(Date(2000, 7, 6)) < 0); |
| assert(Date(2000, 8, 6).opCmp(Date(1999, 7, 7)) > 0); |
| assert(Date(1999, 7, 7).opCmp(Date(2000, 7, 6)) < 0); |
| assert(Date(2000, 7, 6).opCmp(Date(1999, 7, 7)) > 0); |
| assert(Date(1999, 7, 7).opCmp(Date(1999, 8, 6)) < 0); |
| assert(Date(1999, 8, 6).opCmp(Date(1999, 7, 7)) > 0); |
| |
| // Test B.C. |
| assert(Date(0, 1, 1).opCmp(Date(0, 1, 1)) == 0); |
| assert(Date(-1, 1, 1).opCmp(Date(-1, 1, 1)) == 0); |
| assert(Date(-1, 7, 1).opCmp(Date(-1, 7, 1)) == 0); |
| assert(Date(-1, 1, 6).opCmp(Date(-1, 1, 6)) == 0); |
| |
| assert(Date(-1999, 7, 1).opCmp(Date(-1999, 7, 1)) == 0); |
| assert(Date(-1999, 7, 6).opCmp(Date(-1999, 7, 6)) == 0); |
| |
| assert(Date(-1, 7, 6).opCmp(Date(-1, 7, 6)) == 0); |
| |
| assert(Date(-2000, 7, 6).opCmp(Date(-1999, 7, 6)) < 0); |
| assert(Date(-1999, 7, 6).opCmp(Date(-2000, 7, 6)) > 0); |
| assert(Date(-1999, 7, 6).opCmp(Date(-1999, 8, 6)) < 0); |
| assert(Date(-1999, 8, 6).opCmp(Date(-1999, 7, 6)) > 0); |
| assert(Date(-1999, 7, 6).opCmp(Date(-1999, 7, 7)) < 0); |
| assert(Date(-1999, 7, 7).opCmp(Date(-1999, 7, 6)) > 0); |
| |
| assert(Date(-2000, 8, 6).opCmp(Date(-1999, 7, 7)) < 0); |
| assert(Date(-1999, 8, 7).opCmp(Date(-2000, 7, 6)) > 0); |
| assert(Date(-2000, 7, 6).opCmp(Date(-1999, 7, 7)) < 0); |
| assert(Date(-1999, 7, 7).opCmp(Date(-2000, 7, 6)) > 0); |
| assert(Date(-1999, 7, 7).opCmp(Date(-1999, 8, 6)) < 0); |
| assert(Date(-1999, 8, 6).opCmp(Date(-1999, 7, 7)) > 0); |
| |
| // Test Both |
| assert(Date(-1999, 7, 6).opCmp(Date(1999, 7, 6)) < 0); |
| assert(Date(1999, 7, 6).opCmp(Date(-1999, 7, 6)) > 0); |
| |
| assert(Date(-1999, 8, 6).opCmp(Date(1999, 7, 6)) < 0); |
| assert(Date(1999, 7, 6).opCmp(Date(-1999, 8, 6)) > 0); |
| |
| assert(Date(-1999, 7, 7).opCmp(Date(1999, 7, 6)) < 0); |
| assert(Date(1999, 7, 6).opCmp(Date(-1999, 7, 7)) > 0); |
| |
| assert(Date(-1999, 8, 7).opCmp(Date(1999, 7, 6)) < 0); |
| assert(Date(1999, 7, 6).opCmp(Date(-1999, 8, 7)) > 0); |
| |
| assert(Date(-1999, 8, 6).opCmp(Date(1999, 6, 6)) < 0); |
| assert(Date(1999, 6, 8).opCmp(Date(-1999, 7, 6)) > 0); |
| |
| auto date = Date(1999, 7, 6); |
| const cdate = Date(1999, 7, 6); |
| immutable idate = Date(1999, 7, 6); |
| assert(date.opCmp(date) == 0); |
| assert(date.opCmp(cdate) == 0); |
| assert(date.opCmp(idate) == 0); |
| assert(cdate.opCmp(date) == 0); |
| assert(cdate.opCmp(cdate) == 0); |
| assert(cdate.opCmp(idate) == 0); |
| assert(idate.opCmp(date) == 0); |
| assert(idate.opCmp(cdate) == 0); |
| assert(idate.opCmp(idate) == 0); |
| } |
| |
| |
| /++ |
| Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive |
| are B.C. |
| +/ |
| @property short year() const @safe pure nothrow @nogc |
| { |
| return _year; |
| } |
| |
| /// |
| @safe unittest |
| { |
| assert(Date(1999, 7, 6).year == 1999); |
| assert(Date(2010, 10, 4).year == 2010); |
| assert(Date(-7, 4, 5).year == -7); |
| } |
| |
| @safe unittest |
| { |
| assert(Date.init.year == 1); |
| assert(Date(1999, 7, 6).year == 1999); |
| assert(Date(-1999, 7, 6).year == -1999); |
| |
| const cdate = Date(1999, 7, 6); |
| immutable idate = Date(1999, 7, 6); |
| assert(cdate.year == 1999); |
| assert(idate.year == 1999); |
| } |
| |
| /++ |
| Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive |
| are B.C. |
| |
| Params: |
| year = The year to set this Date's year to. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if the new year is not |
| a leap year and the resulting date would be on February 29th. |
| +/ |
| @property void year(int year) @safe pure |
| { |
| enforceValid!"days"(year, _month, _day); |
| _year = cast(short) year; |
| } |
| |
| /// |
| @safe unittest |
| { |
| assert(Date(1999, 7, 6).year == 1999); |
| assert(Date(2010, 10, 4).year == 2010); |
| assert(Date(-7, 4, 5).year == -7); |
| } |
| |
| @safe unittest |
| { |
| static void testDateInvalid(Date date, int year) |
| { |
| date.year = year; |
| } |
| |
| static void testDate(Date date, int year, in Date expected) |
| { |
| date.year = year; |
| assert(date == expected); |
| } |
| |
| assertThrown!DateTimeException(testDateInvalid(Date(4, 2, 29), 1)); |
| |
| testDate(Date(1, 1, 1), 1999, Date(1999, 1, 1)); |
| testDate(Date(1, 1, 1), 0, Date(0, 1, 1)); |
| testDate(Date(1, 1, 1), -1999, Date(-1999, 1, 1)); |
| |
| const cdate = Date(1999, 7, 6); |
| immutable idate = Date(1999, 7, 6); |
| static assert(!__traits(compiles, cdate.year = 1999)); |
| static assert(!__traits(compiles, idate.year = 1999)); |
| } |
| |
| |
| /++ |
| Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if $(D isAD) is true. |
| +/ |
| @property ushort yearBC() const @safe pure |
| { |
| import std.format : format; |
| |
| if (isAD) |
| throw new DateTimeException(format("Year %s is A.D.", _year)); |
| return cast(ushort)((_year * -1) + 1); |
| } |
| |
| /// |
| @safe unittest |
| { |
| assert(Date(0, 1, 1).yearBC == 1); |
| assert(Date(-1, 1, 1).yearBC == 2); |
| assert(Date(-100, 1, 1).yearBC == 101); |
| } |
| |
| @safe unittest |
| { |
| assertThrown!DateTimeException((in Date date){date.yearBC;}(Date(1, 1, 1))); |
| |
| auto date = Date(0, 7, 6); |
| const cdate = Date(0, 7, 6); |
| immutable idate = Date(0, 7, 6); |
| assert(date.yearBC == 1); |
| assert(cdate.yearBC == 1); |
| assert(idate.yearBC == 1); |
| } |
| |
| |
| /++ |
| Year B.C. of the Gregorian Calendar counting year 0 as 1 B.C. |
| |
| Params: |
| year = The year B.C. to set this $(LREF Date)'s year to. |
| |
| Throws: |
| $(REF DateTimeException,std,datetime,date) if a non-positive value |
| is given. |
| +/ |
| @property void yearBC(int year) @safe pure |
| { |
| if (year <= 0) |
| throw new DateTimeException("The given year is not a year B.C."); |
| _year = cast(short)((year - 1) * -1); |
| } |
| |
| /// |
| @safe unittest |
| { |
| auto date = Date(2010, 1, 1); |
| date.yearBC = 1; |
| assert(date == Date(0, 1, 1)); |
| |
| date.yearBC = 10; |
| assert(date == Date(-9, 1, 1)); |
| } |
| |
| @safe unittest |
| { |
| assertThrown!DateTimeException((Date date){date.yearBC = -1;}(Date(1, 1, 1))); |
| |
| auto date = Date(0, 7, 6); |
| const cdate = Date(0, 7, 6); |
| immutable idate = Date(0, 7, 6); |
| date.yearBC = 7; |
| assert(date.yearBC == 7); |
| static assert(!__traits(compiles, cdate.yearBC = 7)); |
| static assert(!__traits(compiles, idate.yearBC = 7)); |
| } |
| |
| |
| /++ |
| Month of a Gregorian Year. |
| +/ |
| @property Month month() const @safe pure nothrow @nogc |
| { |
| return _month; |
| } |
| |
| /// |
| @safe unittest |
| { |
| assert(Date(1999, 7, 6).month == 7); |
| assert(Date(2010, 10, 4).month == 10); |
| assert(Date(-7, 4, 5).month == 4); |
| } |
| |
| @safe unittest |
| { |
| assert(Date.init.month == 1);
|