diff --git a/src/libraries/System.Private.CoreLib/src/System/DateTime.cs b/src/libraries/System.Private.CoreLib/src/System/DateTime.cs index 778992bc160c5a..9adeb52e4fa481 100644 --- a/src/libraries/System.Private.CoreLib/src/System/DateTime.cs +++ b/src/libraries/System.Private.CoreLib/src/System/DateTime.cs @@ -261,8 +261,21 @@ public DateTime(int year, int month, int day, Calendar calendar) /// you can use the corresponding constructor. /// public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, Calendar calendar!!, DateTimeKind kind) - : this(year, month, day, hour, minute, second, millisecond, 0, calendar, kind) { + if ((uint)millisecond >= MillisPerSecond) ThrowMillisecondOutOfRange(); + if ((uint)kind > (uint)DateTimeKind.Local) ThrowInvalidKind(); + + if (second != 60 || !s_systemSupportsLeapSeconds) + { + ulong ticks = calendar.ToDateTime(year, month, day, hour, minute, second, millisecond).UTicks; + _dateData = ticks | ((ulong)kind << KindShift); + } + else + { + // if we have a leap second, then we adjust it to 59 so that DateTime will consider it the last in the specified minute. + this = new DateTime(year, month, day, hour, minute, 59, millisecond, calendar, kind); + ValidateLeapSecond(); + } } // Constructs a DateTime from a given year, month, day, hour, @@ -364,10 +377,8 @@ public DateTime(int year, int month, int day, int hour, int minute, int second, /// For applications in which portability of date and time data or a limited degree of time zone awareness is important, /// you can use the corresponding constructor. /// - public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond) - { + public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond) => _dateData = Init(year, month, day, hour, minute, second, millisecond); - } /// /// Initializes a new instance of the structure to the specified year, month, day, hour, minute, second, @@ -422,10 +433,8 @@ public DateTime(int year, int month, int day, int hour, int minute, int second, /// For applications in which portability of date and time data or a limited degree of time zone awareness is important, /// you can use the corresponding constructor. /// - public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, DateTimeKind kind) - { + public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, DateTimeKind kind) => _dateData = Init(year, month, day, hour, minute, second, millisecond, kind); - } /// /// Initializes a new instance of the structure to the specified year, month, day, hour, minute, second, @@ -478,8 +487,17 @@ public DateTime(int year, int month, int day, int hour, int minute, int second, /// you can use the corresponding constructor. /// public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, Calendar calendar!!) - : this(year, month, day, hour, minute, second, millisecond, 0, calendar) { + if (second != 60 || !s_systemSupportsLeapSeconds) + { + _dateData = calendar.ToDateTime(year, month, day, hour, minute, second, millisecond).UTicks; + } + else + { + // if we have a leap second, then we adjust it to 59 so that DateTime will consider it the last in the specified minute. + this = new DateTime(year, month, day, hour, minute, 59, millisecond, calendar); + ValidateLeapSecond(); + } } /// @@ -665,13 +683,8 @@ public DateTime(int year, int month, int day, int hour, int minute, int second, /// you can use the corresponding constructor. /// public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond, Calendar calendar!!) - : this(year, month, day, hour, minute, second, millisecond, microsecond, calendar, DateTimeKind.Unspecified) + : this(year, month, day, hour, minute, second, millisecond, microsecond, calendar, DateTimeKind.Unspecified) { - if (microsecond is < 0 or >= MicrosecondsPerMillisecond) - { - ThrowMicrosecondOutOfRange(); - } - _dateData = new DateTime(_dateData).AddMicroseconds(microsecond)._dateData; } /// @@ -737,24 +750,13 @@ public DateTime(int year, int month, int day, int hour, int minute, int second, /// you can use the corresponding constructor. /// public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond, Calendar calendar!!, DateTimeKind kind) + : this(year, month, day, hour, minute, second, millisecond, calendar, kind) { - if (second != 60 || !s_systemSupportsLeapSeconds) - { - if (microsecond is < 0 or >= MicrosecondsPerMillisecond) - { - ThrowMicrosecondOutOfRange(); - } - - var dateTime = calendar.ToDateTime(year, month, day, hour, minute, second, millisecond); - dateTime = dateTime.AddMicroseconds(microsecond); - _dateData = dateTime.UTicks | ((ulong)kind << KindShift); - } - else + if (microsecond is < 0 or >= MicrosecondsPerMillisecond) { - // if we have a leap second, then we adjust it to 59 so that DateTime will consider it the last in the specified minute. - this = new DateTime(year, month, day, hour, minute, 59, millisecond, microsecond, calendar); - ValidateLeapSecond(); + ThrowMicrosecondOutOfRange(); } + _dateData = new DateTime(_dateData).AddMicroseconds(microsecond)._dateData; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.cs b/src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.cs index c53aa17621051e..a3f6843d8ec21f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.cs +++ b/src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.cs @@ -241,11 +241,11 @@ public DateTimeOffset(int year, int month, int day, int hour, int minute, int se /// is less than 0 or greater than 900. /// public DateTimeOffset(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond, TimeSpan offset) - : this(year, month, day, hour, minute, second, millisecond, offset) + : this(year, month, day, hour, minute, second, millisecond, offset) { if ((uint)microsecond >= DateTime.MicrosecondsPerMillisecond) { - throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadHourMinuteSecond); + throw new ArgumentOutOfRangeException(nameof(microsecond), SR.ArgumentOutOfRange_BadHourMinuteSecond); } _dateTime = _dateTime.AddMicroseconds(microsecond); } @@ -322,7 +322,7 @@ public DateTimeOffset(int year, int month, int day, int hour, int minute, int se { if ((uint)microsecond >= DateTime.MicrosecondsPerMillisecond) { - throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadHourMinuteSecond); + throw new ArgumentOutOfRangeException(nameof(microsecond), SR.ArgumentOutOfRange_BadHourMinuteSecond); } _dateTime = _dateTime.AddMicroseconds(microsecond); } diff --git a/src/libraries/System.Runtime/tests/System/DateTimeOffsetTests.cs b/src/libraries/System.Runtime/tests/System/DateTimeOffsetTests.cs index ae0c345936f058..c5b3a0a719be43 100644 --- a/src/libraries/System.Runtime/tests/System/DateTimeOffsetTests.cs +++ b/src/libraries/System.Runtime/tests/System/DateTimeOffsetTests.cs @@ -14,7 +14,7 @@ public static class DateTimeOffsetTests [Fact] public static void MaxValue() { - VerifyDateTimeOffset(DateTimeOffset.MaxValue, 9999, 12, 31, 23, 59, 59, 999, 999, TimeSpan.Zero); + VerifyDateTimeOffset(DateTimeOffset.MaxValue, 9999, 12, 31, 23, 59, 59, 999, 999, TimeSpan.Zero, 900); } [Fact] @@ -36,7 +36,7 @@ public static void Ctor_DateTime() var dateTimeOffset = new DateTimeOffset(new DateTime(2012, 6, 11, 0, 0, 0, 0, DateTimeKind.Utc)); VerifyDateTimeOffset(dateTimeOffset, 2012, 6, 11, 0, 0, 0, 0, 0, TimeSpan.Zero); - dateTimeOffset = new DateTimeOffset(new DateTime(1986, 8, 15, 10, 20, 5, 4, DateTimeKind.Local)); + dateTimeOffset = new DateTimeOffset(new DateTime(1986, 8, 15, 10, 20, 5, 4, 3, DateTimeKind.Local)); VerifyDateTimeOffset(dateTimeOffset, 1986, 8, 15, 10, 20, 5, 4, 3, null); DateTimeOffset today = new DateTimeOffset(DateTime.Today); @@ -81,7 +81,7 @@ public static void Ctor_DateTime_TimeSpan() VerifyDateTimeOffset(dateTimeOffset, 1, 1, 1, 0, 0, 0, 0, 0, TimeSpan.FromHours(-14)); dateTimeOffset = new DateTimeOffset(DateTime.MaxValue, TimeSpan.FromHours(14)); - VerifyDateTimeOffset(dateTimeOffset, 9999, 12, 31, 23, 59, 59, 999, 999, TimeSpan.FromHours(14)); + VerifyDateTimeOffset(dateTimeOffset, 9999, 12, 31, 23, 59, 59, 999, 999, TimeSpan.FromHours(14), 900); dateTimeOffset = new DateTimeOffset(new DateTime(2012, 12, 31, 13, 50, 10), TimeSpan.Zero); VerifyDateTimeOffset(dateTimeOffset, 2012, 12, 31, 13, 50, 10, 0, 0, TimeSpan.Zero); @@ -1138,7 +1138,7 @@ public static void Parse_InvalidDateTimeStyle_ThrowsArgumentException(DateTimeSt Assert.Equal(default(DateTimeOffset), dateTimeOffset); } - private static void VerifyDateTimeOffset(DateTimeOffset dateTimeOffset, int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond, TimeSpan? offset) + private static void VerifyDateTimeOffset(DateTimeOffset dateTimeOffset, int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond, TimeSpan? offset, int nanosecond = 0) { Assert.Equal(year, dateTimeOffset.Year); Assert.Equal(month, dateTimeOffset.Month); @@ -1148,7 +1148,7 @@ private static void VerifyDateTimeOffset(DateTimeOffset dateTimeOffset, int year Assert.Equal(second, dateTimeOffset.Second); Assert.Equal(millisecond, dateTimeOffset.Millisecond); Assert.Equal(microsecond, dateTimeOffset.Microsecond); - Assert.Equal(0, dateTimeOffset.Nanosecond); + Assert.Equal(nanosecond, dateTimeOffset.Nanosecond); if (offset.HasValue) {