Skip to content
Merged
615 changes: 583 additions & 32 deletions src/libraries/System.Private.CoreLib/src/System/DateTime.cs

Large diffs are not rendered by default.

206 changes: 206 additions & 0 deletions src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,165 @@ public DateTimeOffset(int year, int month, int day, int hour, int minute, int se
}
}

/// <summary>
/// Initializes a new instance of the <see cref="DateTimeOffset"/> structure using the
/// specified <paramref name="year"/>, <paramref name="month"/>, <paramref name="day"/>, <paramref name="hour"/>, <paramref name="minute"/>,
/// <paramref name="second"/>, <paramref name="millisecond"/>, <paramref name="microsecond"/> and <paramref name="offset"/>.
/// </summary>
/// <param name="year">The year (1 through 9999).</param>
/// <param name="month">The month (1 through 12).</param>
/// <param name="day">The day (1 through the number of days in <paramref name="month"/>).</param>
/// <param name="hour">The hours (0 through 23).</param>
/// <param name="minute">The minutes (0 through 59).</param>
/// <param name="second">The seconds (0 through 59).</param>
/// <param name="millisecond">The milliseconds (0 through 999).</param>
/// <param name="microsecond">The microseconds (0 through 999).</param>
/// <param name="offset">The time's offset from Coordinated Universal Time (UTC).</param>
/// <exception cref="ArgumentException">
/// <paramref name="offset"/> does not represent whole minutes.
/// </exception>
/// <remarks>
/// This constructor interprets <paramref name="year"/>, <paramref name="month"/> and <paramref name="day"/> as a year, month and day
/// in the Gregorian calendar. To instantiate a <see cref="DateTimeOffset"/> value by using the year, month and day in another calendar, call
/// the <see cref="DateTimeOffset(int, int, int, int, int, int, int, int, Calendar, TimeSpan)"/> constructor.
/// </remarks>
/// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="year"/> is less than 1 or greater than 9999.
///
/// -or-
///
/// <paramref name="month"/> is less than 1 or greater than 12.
///
/// -or-
///
/// <paramref name="day"/> is less than 1 or greater than the number of days in <paramref name="month"/>.
///
/// -or-
///
/// <paramref name="hour"/> is less than 0 or greater than 23.
///
/// -or-
///
/// <paramref name="minute"/> is less than 0 or greater than 59.
///
/// -or-
///
/// <paramref name="second"/> is less than 0 or greater than 59.
///
/// -or-
///
/// <paramref name="millisecond"/> is less than 0 or greater than 999.
/// -or-
///
/// <paramref name="microsecond"/> is less than 0 or greater than 900.
/// </exception>
public DateTimeOffset(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond, TimeSpan offset)
{
_offsetMinutes = ValidateOffset(offset);

int originalSecond = second;
if (second == 60 && DateTime.s_systemSupportsLeapSeconds)
{
// Reset the leap second to 59 for now and then we'll validate it after getting the final UTC time.
second = 59;
}

_dateTime = ValidateDate(new DateTime(year, month, day, hour, minute, second, millisecond, microsecond), offset);

if (originalSecond == 60 &&
!DateTime.IsValidTimeWithLeapSeconds(_dateTime.Year, _dateTime.Month, _dateTime.Day, _dateTime.Hour, _dateTime.Minute, DateTimeKind.Utc))
{
throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadHourMinuteSecond);
}
}

/// <summary>
/// Initializes a new instance of the <see cref="DateTimeOffset"/> structure using the
/// specified <paramref name="year"/>, <paramref name="month"/>, <paramref name="day"/>, <paramref name="hour"/>, <paramref name="minute"/>,
/// <paramref name="second"/>, <paramref name="millisecond"/>, <paramref name="microsecond"/> and <paramref name="offset"/>.
/// </summary>
/// <param name="year">The year (1 through 9999).</param>
/// <param name="month">The month (1 through 12).</param>
/// <param name="day">The day (1 through the number of days in <paramref name="month"/>).</param>
/// <param name="hour">The hours (0 through 23).</param>
/// <param name="minute">The minutes (0 through 59).</param>
/// <param name="second">The seconds (0 through 59).</param>
/// <param name="millisecond">The milliseconds (0 through 999).</param>
/// <param name="microsecond">The microseconds (0 through 999).</param>
/// <param name="calendar">The calendar that is used to interpret <paramref name="year"/>, <paramref name="month"/>, and <paramref name="day"/>.</param>
/// <param name="offset">The time's offset from Coordinated Universal Time (UTC).</param>
/// <remarks>
/// This constructor interprets <paramref name="year"/>, <paramref name="month"/> and <paramref name="day"/> as a year, month and day
/// in the Gregorian calendar. To instantiate a <see cref="DateTimeOffset"/> value by using the year, month and day in another calendar, call
/// the <see cref="DateTimeOffset(int, int, int, int, int, int, int, int, Calendar, TimeSpan)"/> constructor.
/// </remarks>
/// <exception cref="ArgumentException">
/// <paramref name="offset"/> does not represent whole minutes.
/// </exception>
/// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="year"/> is not in the range supported by <paramref name="calendar"/>.
///
/// -or-
///
/// <paramref name="month"/> is less than 1 or greater than the number of months in <paramref name="calendar"/>.
///
/// -or-
///
/// <paramref name="day"/> is less than 1 or greater than the number of days in <paramref name="month"/>.
///
/// -or-
///
/// <paramref name="hour"/> is less than 0 or greater than 23.
///
/// -or-
///
/// <paramref name="minute"/> is less than 0 or greater than 59.
///
/// -or-
///
/// <paramref name="second"/> is less than 0 or greater than 59.
///
/// -or-
///
/// <paramref name="millisecond"/> is less than 0 or greater than 999.
///
/// -or-
///
/// <paramref name="microsecond"/> is less than 0 or greater than 900.
///
/// -or-
///
/// <paramref name="offset"/> is less than -14 hours or greater than 14 hours.
///
/// -or-
///
/// The <paramref name="year"/>, <paramref name="month"/>, and <paramref name="day"/> parameters
/// cannot be represented as a date and time value.
///
/// -or-
///
/// The <see cref="UtcDateTime"/> property is earlier than <see cref="MinValue"/> or later than <see cref="MaxValue"/>.
/// </exception>
public DateTimeOffset(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond, Calendar calendar, TimeSpan offset)
{
_offsetMinutes = ValidateOffset(offset);

int originalSecond = second;
if (second == 60 && DateTime.s_systemSupportsLeapSeconds)
{
// Reset the leap second to 59 for now and then we'll validate it after getting the final UTC time.
second = 59;
}

_dateTime = ValidateDate(new DateTime(year, month, day, hour, minute, second, millisecond, microsecond, calendar), offset);

if (originalSecond == 60 &&
!DateTime.IsValidTimeWithLeapSeconds(_dateTime.Year, _dateTime.Month, _dateTime.Day, _dateTime.Hour, _dateTime.Minute, DateTimeKind.Utc))
{
throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadHourMinuteSecond);
}
}

// Returns a DateTimeOffset representing the current date and time. The
// resolution of the returned value depends on the system timer.
public static DateTimeOffset Now => ToLocalTime(DateTime.UtcNow, true);
Expand Down Expand Up @@ -256,6 +415,26 @@ public DateTimeOffset ToOffset(TimeSpan offset) =>
//
public int Millisecond => ClockDateTime.Millisecond;

/// <summary>
/// Gets the microsecond component of the time represented by the current <see cref="DateTimeOffset"/> object.
/// </summary>
/// <remarks>
/// If you rely on properties such as <see cref="Now"/> or <see cref="UtcNow"/> to accurately track the number of elapsed microseconds,
/// the precision of the time's microseconds component depends on the resolution of the system clock.
/// On Windows NT 3.5 and later, and Windows Vista operating systems, the clock's resolution is approximately 10000-15000 microseconds.
/// </remarks>
public int Microsecond => ClockDateTime.Microsecond;

/// <summary>
/// Gets the nanosecond component of the time represented by the current <see cref="DateTimeOffset"/> object.
/// </summary>
/// <remarks>
/// If you rely on properties such as <see cref="Now"/> or <see cref="UtcNow"/> to accurately track the number of elapsed nanosecond,
/// the precision of the time's nanosecond component depends on the resolution of the system clock.
/// On Windows NT 3.5 and later, and Windows Vista operating systems, the clock's resolution is approximately 10000000-15000000 nanoseconds.
/// </remarks>
public int Nanosecond => ClockDateTime.Nanosecond;

// Returns the minute part of this DateTimeOffset. The returned value is
// an integer between 0 and 59.
//
Expand Down Expand Up @@ -324,6 +503,33 @@ public DateTimeOffset AddHours(double hours) =>
public DateTimeOffset AddMilliseconds(double milliseconds) =>
new DateTimeOffset(ClockDateTime.AddMilliseconds(milliseconds), Offset);

/// <summary>
/// Returns a new <see cref="DateTimeOffset"/> object that adds a specified number of microseconds to the value of this instance.
/// </summary>
/// <param name="microseconds">A number of whole and fractional microseconds. The number can be negative or positive.</param>
/// <returns>
/// An object whose value is the sum of the date and time represented by the current <see cref="DateTimeOffset"/> object and the number
/// of whole microseconds represented by <paramref name="microseconds"/>.
/// </returns>
/// <remarks>
/// The fractional part of value is the fractional part of a microsecond.
/// For example, 4.5 is equivalent to 4 microseconds and 50 ticks, where one microseconds = 10 ticks.
/// However, <paramref name="microseconds"/> is rounded to the nearest microsecond; all values of .5 or greater are rounded up.
///
/// Because a <see cref="DateTimeOffset"/> object does not represent the date and time in a specific time zone,
/// the <see cref="AddMicroseconds"/> method does not consider a particular time zone's adjustment rules
/// when it performs date and time arithmetic.
/// </remarks>
/// <exception cref="ArgumentOutOfRangeException">
/// The resulting <see cref="DateTimeOffset"/> value is less than <see cref="MinValue"/>
///
/// -or-
///
/// The resulting <see cref="DateTimeOffset"/> value is greater than <see cref="MaxValue"/>
/// </exception>
public DateTimeOffset AddMicroseconds(double microseconds) =>
new DateTimeOffset(ClockDateTime.AddMicroseconds(microseconds), Offset);

// Returns the DateTimeOffset resulting from adding a fractional number of
// minutes to this DateTimeOffset. The result is computed by rounding the
// fractional number of minutes given by value to the nearest
Expand Down
22 changes: 21 additions & 1 deletion src/libraries/System.Private.CoreLib/src/System/TimeOnly.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,17 @@ public TimeOnly(int hour, int minute, int second) : this(DateTime.TimeToTicks(ho
/// <param name="minute">The minutes (0 through 59).</param>
/// <param name="second">The seconds (0 through 59).</param>
/// <param name="millisecond">The millisecond (0 through 999).</param>
public TimeOnly(int hour, int minute, int second, int millisecond) : this(DateTime.TimeToTicks(hour, minute, second, millisecond)) {}
public TimeOnly(int hour, int minute, int second, int millisecond) : this(DateTime.TimeToTicks(hour, minute, second, millisecond)) { }

/// <summary>
/// Initializes a new instance of the <see cref="TimeOnly"/> structure to the specified hour, minute, second, and millisecond.
/// </summary>
/// <param name="hour">The hours (0 through 23).</param>
/// <param name="minute">The minutes (0 through 59).</param>
/// <param name="second">The seconds (0 through 59).</param>
/// <param name="millisecond">The millisecond (0 through 999).</param>
/// <param name="microsecond">The microsecond (0 through 999).</param>
public TimeOnly(int hour, int minute, int second, int millisecond, int microsecond) : this(DateTime.TimeToTicks(hour, minute, second, millisecond, microsecond)) { }

/// <summary>
/// Initializes a new instance of the TimeOnly structure using a specified number of ticks.
Expand Down Expand Up @@ -104,6 +114,16 @@ public TimeOnly(long ticks)
/// </summary>
public int Millisecond => new TimeSpan(_ticks).Milliseconds;

/// <summary>
/// Gets the microsecond component of the time represented by this instance.
/// </summary>
public int Microsecond => new TimeSpan(_ticks).Microseconds;

/// <summary>
/// Gets the nanosecond component of the time represented by this instance.
/// </summary>
public int Nanosecond => new TimeSpan(_ticks).Nanoseconds;

/// <summary>
/// Gets the number of ticks that represent the time of this instance.
/// </summary>
Expand Down
Loading