diff --git a/src/libraries/System.Private.CoreLib/src/System/DateTime.cs b/src/libraries/System.Private.CoreLib/src/System/DateTime.cs index b3cc06c3725fa..a7ce233507b02 100644 --- a/src/libraries/System.Private.CoreLib/src/System/DateTime.cs +++ b/src/libraries/System.Private.CoreLib/src/System/DateTime.cs @@ -61,7 +61,9 @@ public readonly partial struct DateTime ISubtractionOperators { // Number of 100ns ticks per time unit - private const long TicksPerMillisecond = 10000; + private const long NanosecondsPerTick = 100; + private const long TicksPerMicrosecond = 10; + private const long TicksPerMillisecond = TicksPerMicrosecond * 1000; private const long TicksPerSecond = TicksPerMillisecond * 1000; private const long TicksPerMinute = TicksPerSecond * 60; private const long TicksPerHour = TicksPerMinute * 60; @@ -189,15 +191,81 @@ public DateTime(int year, int month, int day) _dateData = DateToTicks(year, month, day); } + public DateTime(int year, int month, int day, DateTimeKind kind) + : this(year, month, day, 0, 0, 0, kind) + { + } + // Constructs a DateTime from a given year, month, and day for // the specified calendar. The // time-of-day of the resulting DateTime is always midnight. - // public DateTime(int year, int month, int day, Calendar calendar) : this(year, month, day, 0, 0, 0, calendar) { } + /// + /// Initializes a new instance of the structure to the specified year, month, day, hour, minute, second, + /// millisecond, and Coordinated Universal Time (UTC) or local time for the specified calendar. + /// + /// The year (1 through the number of years in ). + /// The month (1 through the number of months in ). + /// The day (1 through the number of days in ). + /// The hours (0 through 23). + /// The minutes (0 through 59). + /// The seconds (0 through 59). + /// The milliseconds (0 through 999). + /// The calendar that is used to interpret , , and . + /// + /// One of the enumeration values that indicates whether , , , + /// , , , and + /// specify a local time, Coordinated Universal Time (UTC), or neither. + /// + /// is + /// + /// + /// is not in the range supported by . + /// + /// -or- + /// + /// is less than 1 or greater than the number of months in . + /// + /// -or- + /// + /// is less than 1 or greater than the number of days in . + /// + /// -or- + /// + /// is less than 0 or greater than 23. + /// + /// -or- + /// + /// is less than 0 or greater than 59. + /// + /// -or- + /// + /// is less than 0 or greater than 59. + /// + /// -or- + /// + /// is less than 0 or greater than 999. + /// + /// + /// is not one of the values. + /// + /// + /// The allowable values for , , and parameters + /// depend on the parameter. An exception is thrown if the specified date and time cannot + /// be expressed using . + /// + /// 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, Calendar calendar!!, DateTimeKind kind) + : this(year, month, day, hour, minute, second, millisecond, 0, calendar, kind) + { + } + // Constructs a DateTime from a given year, month, day, hour, // minute, and second. // @@ -251,77 +319,360 @@ public DateTime(int year, int month, int day, int hour, int minute, int second, // Constructs a DateTime from a given year, month, day, hour, // minute, and second. - // public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond) + : this(year, month, day, hour, minute, second, millisecond, 0) + { + } + + public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, DateTimeKind kind) + : this(year, month, day, hour, minute, second, millisecond, 0, kind) + { + } + + /// + /// Initializes a new instance of the structure to the specified year, month, day, hour, minute, second, + /// millisecond, and Coordinated Universal Time (UTC) or local time for the specified calendar. + /// + /// The year (1 through the number of years in ). + /// The month (1 through the number of months in ). + /// The day (1 through the number of days in ). + /// The hours (0 through 23). + /// The minutes (0 through 59). + /// The seconds (0 through 59). + /// The milliseconds (0 through 999). + /// The calendar that is used to interpret , , and . + /// + /// is + /// + /// + /// is not in the range supported by . + /// + /// -or- + /// + /// is less than 1 or greater than the number of months in . + /// + /// -or- + /// + /// is less than 1 or greater than the number of days in . + /// + /// -or- + /// + /// is less than 0 or greater than 23. + /// + /// -or- + /// + /// is less than 0 or greater than 59. + /// + /// -or- + /// + /// is less than 0 or greater than 59. + /// + /// -or- + /// + /// is less than 0 or greater than 999. + /// + /// + /// The allowable values for , , and parameters + /// depend on the parameter. An exception is thrown if the specified date and time cannot + /// be expressed using . + /// + /// 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, Calendar calendar!!) + : this(year, month, day, hour, minute, second, millisecond, 0, calendar) + { + } + + /// + /// Initializes a new instance of the structure to the specified year, month, day, hour, minute, second, + /// millisecond, and Coordinated Universal Time (UTC) or local time for the specified calendar. + /// + /// The year (1 through 9999). + /// The month (1 through 12). + /// The day (1 through the number of days in ). + /// The hours (0 through 23). + /// The minutes (0 through 59). + /// The seconds (0 through 59). + /// The milliseconds (0 through 999). + /// The milliseconds (0 through 900). + /// + /// is less than 1 or greater than 9999. + /// + /// -or- + /// + /// is less than 1 or greater than 12. + /// + /// -or- + /// + /// is less than 1 or greater than the number of days in . + /// + /// -or- + /// + /// is less than 0 or greater than 23. + /// + /// -or- + /// + /// is less than 0 or greater than 59. + /// + /// -or- + /// + /// is less than 0 or greater than 59. + /// + /// -or- + /// + /// is less than 0 or greater than 999. + /// -or- + /// + /// is less than 0 or greater than 900. + /// + /// + /// This constructor interprets , and as a year, month and day + /// in the Gregorian calendar. To instantiate a value by using the year, month and day in another calendar, call + /// the constructor. + /// + /// The property is initialized to . + /// + /// 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, int microsecond) { if ((uint)millisecond >= MillisPerSecond) ThrowMillisecondOutOfRange(); if (second != 60 || !s_systemSupportsLeapSeconds) { - ulong ticks = DateToTicks(year, month, day) + TimeToTicks(hour, minute, second); - ticks += (uint)millisecond * (uint)TicksPerMillisecond; - Debug.Assert(ticks <= MaxTicks, "Input parameters validated already"); - _dateData = ticks; + _dateData = DateToTicks(year, month, day) + TimeToTicks(hour, minute, second, millisecond, microsecond); } 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); + this = new DateTime(year, month, day, hour, minute, 59, millisecond, microsecond); ValidateLeapSecond(); } } - public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, DateTimeKind kind) + /// + /// Initializes a new instance of the structure to the specified year, month, day, hour, minute, second, + /// millisecond, and Coordinated Universal Time (UTC) or local time for the specified calendar. + /// + /// The year (1 through 9999). + /// The month (1 through 12). + /// The day (1 through the number of days in ). + /// The hours (0 through 23). + /// The minutes (0 through 59). + /// The seconds (0 through 59). + /// The milliseconds (0 through 999). + /// The milliseconds (0 through 900). + /// + /// One of the enumeration values that indicates whether , , , + /// , , , and + /// specify a local time, Coordinated Universal Time (UTC), or neither. + /// + /// is less than 1 or greater than 9999. + /// + /// -or- + /// + /// is less than 1 or greater than 12. + /// + /// -or- + /// + /// is less than 1 or greater than the number of days in . + /// + /// -or- + /// + /// is less than 0 or greater than 23. + /// + /// -or- + /// + /// is less than 0 or greater than 59. + /// + /// -or- + /// + /// is less than 0 or greater than 59. + /// + /// -or- + /// + /// is less than 0 or greater than 999. + /// -or- + /// + /// is less than 0 or greater than 900. + /// + /// + /// is not one of the values. + /// + /// + /// This constructor interprets , and as a year, month and day + /// in the Gregorian calendar. To instantiate a value by using the year, month and day in another calendar, call + /// the constructor. + /// + /// 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, int microsecond, DateTimeKind kind) { if ((uint)millisecond >= MillisPerSecond) ThrowMillisecondOutOfRange(); if ((uint)kind > (uint)DateTimeKind.Local) ThrowInvalidKind(); if (second != 60 || !s_systemSupportsLeapSeconds) { - ulong ticks = DateToTicks(year, month, day) + TimeToTicks(hour, minute, second); - ticks += (uint)millisecond * (uint)TicksPerMillisecond; - Debug.Assert(ticks <= MaxTicks, "Input parameters validated already"); - _dateData = ticks | ((ulong)kind << KindShift); + _dateData = DateToTicks(year, month, day) + TimeToTicks(hour, minute, second, millisecond, microsecond); } 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, kind); + this = new DateTime(year, month, day, hour, minute, 59, millisecond, microsecond, kind); ValidateLeapSecond(); } } - // Constructs a DateTime from a given year, month, day, hour, - // minute, and second for the specified calendar. - // - public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, Calendar calendar!!) + /// + /// Initializes a new instance of the structure to the specified year, month, day, hour, minute, second, + /// millisecond, and Coordinated Universal Time (UTC) or local time for the specified calendar. + /// + /// The year (1 through the number of years in ). + /// The month (1 through the number of months in ). + /// The day (1 through the number of days in ). + /// The hours (0 through 23). + /// The minutes (0 through 59). + /// The seconds (0 through 59). + /// The milliseconds (0 through 999). + /// The milliseconds (0 through 900). + /// The calendar that is used to interpret , , and . + /// + /// is + /// + /// + /// is not in the range supported by . + /// + /// -or- + /// + /// is less than 1 or greater than the number of months in . + /// + /// -or- + /// + /// is less than 1 or greater than the number of days in . + /// + /// -or- + /// + /// is less than 0 or greater than 23. + /// + /// -or- + /// + /// is less than 0 or greater than 59. + /// + /// -or- + /// + /// is less than 0 or greater than 59. + /// + /// -or- + /// + /// is less than 0 or greater than 999. + /// -or- + /// + /// is less than 0 or greater than 900. + /// + /// + /// The allowable values for , , and parameters + /// depend on the parameter. An exception is thrown if the specified date and time cannot + /// be expressed using . + /// + /// 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, int microsecond, Calendar calendar!!) { if (second != 60 || !s_systemSupportsLeapSeconds) { - _dateData = calendar.ToDateTime(year, month, day, hour, minute, second, millisecond).UTicks; + var dateTime = calendar.ToDateTime(year, month, day, hour, minute, second, millisecond); + dateTime = dateTime.AddMicroseconds(microsecond); + _dateData = dateTime.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); + this = new DateTime(year, month, day, hour, minute, 59, millisecond, microsecond, calendar); ValidateLeapSecond(); } } - public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, Calendar calendar!!, DateTimeKind kind) + /// + /// Initializes a new instance of the structure to the specified year, month, day, hour, minute, second, + /// millisecond, and Coordinated Universal Time (UTC) or local time for the specified calendar. + /// + /// The year (1 through the number of years in ). + /// The month (1 through the number of months in ). + /// The day (1 through the number of days in ). + /// The hours (0 through 23). + /// The minutes (0 through 59). + /// The seconds (0 through 59). + /// The milliseconds (0 through 999). + /// The milliseconds (0 through 900). + /// The calendar that is used to interpret , , and . + /// + /// One of the enumeration values that indicates whether , , , + /// , , , and + /// specify a local time, Coordinated Universal Time (UTC), or neither. + /// + /// is + /// + /// + /// is not in the range supported by . + /// + /// -or- + /// + /// is less than 1 or greater than the number of months in . + /// + /// -or- + /// + /// is less than 1 or greater than the number of days in . + /// + /// -or- + /// + /// is less than 0 or greater than 23. + /// + /// -or- + /// + /// is less than 0 or greater than 59. + /// + /// -or- + /// + /// is less than 0 or greater than 59. + /// + /// -or- + /// + /// is less than 0 or greater than 999. + /// -or- + /// + /// is less than 0 or greater than 900. + /// + /// + /// is not one of the values. + /// + /// + /// The allowable values for , , and parameters + /// depend on the parameter. An exception is thrown if the specified date and time cannot + /// be expressed using . + /// + /// 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, int microsecond, Calendar calendar!!, DateTimeKind 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; + var dateTime = calendar.ToDateTime(year, month, day, hour, minute, second, millisecond); + dateTime = dateTime.AddMicroseconds(microsecond); + ulong ticks = dateTime.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); + this = new DateTime(year, month, day, hour, minute, 59, millisecond, microsecond, calendar, kind); ValidateLeapSecond(); } } @@ -422,6 +773,43 @@ public DateTime AddMilliseconds(double value) return Add(value, 1); } + /// + /// Returns a new that adds the specified number of microseconds to the value of this instance. + /// + /// + /// A number of whole and fractional microseconds. + /// The parameter can be negative or positive. + /// Note that this value is rounded to the nearest integer. + /// + /// + /// An object whose value is the sum of the date and time represented + /// by this instance and the number of microseconds represented by . + /// + /// + /// This method does not change the value of this . Instead, it returns a new + /// whose value is the result of this operation. + /// + /// 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. + /// + /// The value parameter is rounded to the nearest integer. + /// + /// + /// The resulting is less than or greater than . + /// + public DateTime AddMicroseconds(double value) + { + int ticks = (int)(value * TicksPerMicrosecond); + if (ticks is < 0 or > 900) + { + ThrowOutOfRange(); + } + + return AddTicks(ticks); + + static void ThrowOutOfRange() => throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_AddValue); + } + // Returns the DateTime resulting from adding a fractional number of // minutes to this DateTime. The result is computed by rounding the // fractional number of minutes given by value to the nearest @@ -625,6 +1013,19 @@ internal static ulong TimeToTicks(int hour, int minute, int second, int millisec return ticks; } + internal static ulong TimeToTicks(int hour, int minute, int second, int millisecond, int microsecond) + { + ulong ticks = TimeToTicks(hour, minute, second, millisecond); + + if ((uint)microsecond >= 999) ThrowMillisecondOutOfRange(); + + ticks += (uint)microsecond * (uint)TicksPerMicrosecond; + + Debug.Assert(ticks <= MaxTicks, "Input parameters validated already"); + + return ticks; + } + // Returns the number of days in the month given by the year and // month arguments. // @@ -1018,6 +1419,16 @@ public DateTimeKind Kind // public int Millisecond => (int)((UTicks / TicksPerMillisecond) % 1000); + /// + /// The microseconds component, expressed as a value between 0 and 999. + /// + public int Microsecond => (int)(UTicks / TicksPerMicrosecond); + + /// + /// The nanoseconds component, expressed as a value between 0 and 900. + /// + public int Nanosecond => (int)(UTicks * NanosecondsPerTick); + // Returns the minute part of this DateTime. The returned value is // an integer between 0 and 59. // diff --git a/src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.cs b/src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.cs index 61c57ed07c9a1..a13da501b141d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.cs +++ b/src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.cs @@ -188,6 +188,165 @@ public DateTimeOffset(int year, int month, int day, int hour, int minute, int se } } + /// + /// Initializes a new instance of the structure using the + /// specified , , , , , + /// , , and . + /// + /// The year (1 through 9999). + /// The month (1 through 12). + /// The day (1 through the number of days in ). + /// The hours (0 through 23). + /// The minutes (0 through 59). + /// The seconds (0 through 59). + /// The milliseconds (0 through 999). + /// The microseconds (0 through 999). + /// The time's offset from Coordinated Universal Time (UTC). + /// + /// does not represent whole minutes. + /// + /// + /// This constructor interprets , and as a year, month and day + /// in the Gregorian calendar. To instantiate a value by using the year, month and day in another calendar, call + /// the constructor. + /// + /// + /// is less than 1 or greater than 9999. + /// + /// -or- + /// + /// is less than 1 or greater than 12. + /// + /// -or- + /// + /// is less than 1 or greater than the number of days in . + /// + /// -or- + /// + /// is less than 0 or greater than 23. + /// + /// -or- + /// + /// is less than 0 or greater than 59. + /// + /// -or- + /// + /// is less than 0 or greater than 59. + /// + /// -or- + /// + /// is less than 0 or greater than 999. + /// -or- + /// + /// 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) + { + _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); + } + } + + /// + /// Initializes a new instance of the structure using the + /// specified , , , , , + /// , , and . + /// + /// The year (1 through 9999). + /// The month (1 through 12). + /// The day (1 through the number of days in ). + /// The hours (0 through 23). + /// The minutes (0 through 59). + /// The seconds (0 through 59). + /// The milliseconds (0 through 999). + /// The microseconds (0 through 999). + /// The calendar that is used to interpret , , and . + /// The time's offset from Coordinated Universal Time (UTC). + /// + /// This constructor interprets , and as a year, month and day + /// in the Gregorian calendar. To instantiate a value by using the year, month and day in another calendar, call + /// the constructor. + /// + /// + /// does not represent whole minutes. + /// + /// + /// is not in the range supported by . + /// + /// -or- + /// + /// is less than 1 or greater than the number of months in . + /// + /// -or- + /// + /// is less than 1 or greater than the number of days in . + /// + /// -or- + /// + /// is less than 0 or greater than 23. + /// + /// -or- + /// + /// is less than 0 or greater than 59. + /// + /// -or- + /// + /// is less than 0 or greater than 59. + /// + /// -or- + /// + /// is less than 0 or greater than 999. + /// + /// -or- + /// + /// is less than 0 or greater than 900. + /// + /// -or- + /// + /// is less than -14 hours or greater than 14 hours. + /// + /// -or- + /// + /// The , , and parameters + /// cannot be represented as a date and time value. + /// + /// -or- + /// + /// The property is earlier than or later than . + /// + 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); @@ -256,6 +415,26 @@ public DateTimeOffset ToOffset(TimeSpan offset) => // public int Millisecond => ClockDateTime.Millisecond; + /// + /// Gets the microsecond component of the time represented by the current object. + /// + /// + /// If you rely on properties such as or 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. + /// + public int Microsecond => ClockDateTime.Microsecond; + + /// + /// Gets the nanosecond component of the time represented by the current object. + /// + /// + /// If you rely on properties such as or 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. + /// + public int Nanosecond => ClockDateTime.Nanosecond; + // Returns the minute part of this DateTimeOffset. The returned value is // an integer between 0 and 59. // @@ -324,6 +503,33 @@ public DateTimeOffset AddHours(double hours) => public DateTimeOffset AddMilliseconds(double milliseconds) => new DateTimeOffset(ClockDateTime.AddMilliseconds(milliseconds), Offset); + /// + /// Returns a new object that adds a specified number of microseconds to the value of this instance. + /// + /// A number of whole and fractional microseconds. The number can be negative or positive. + /// + /// An object whose value is the sum of the date and time represented by the current object and the number + /// of whole microseconds represented by . + /// + /// + /// 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, is rounded to the nearest microsecond; all values of .5 or greater are rounded up. + /// + /// Because a object does not represent the date and time in a specific time zone, + /// the method does not consider a particular time zone's adjustment rules + /// when it performs date and time arithmetic. + /// + /// + /// The resulting value is less than + /// + /// -or- + /// + /// The resulting value is greater than + /// + 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 diff --git a/src/libraries/System.Private.CoreLib/src/System/TimeOnly.cs b/src/libraries/System.Private.CoreLib/src/System/TimeOnly.cs index 9169cdcae0bb7..251005ad2c724 100644 --- a/src/libraries/System.Private.CoreLib/src/System/TimeOnly.cs +++ b/src/libraries/System.Private.CoreLib/src/System/TimeOnly.cs @@ -65,7 +65,17 @@ public TimeOnly(int hour, int minute, int second) : this(DateTime.TimeToTicks(ho /// The minutes (0 through 59). /// The seconds (0 through 59). /// The millisecond (0 through 999). - 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)) { } + + /// + /// Initializes a new instance of the structure to the specified hour, minute, second, and millisecond. + /// + /// The hours (0 through 23). + /// The minutes (0 through 59). + /// The seconds (0 through 59). + /// The millisecond (0 through 999). + /// The microsecond (0 through 999). + public TimeOnly(int hour, int minute, int second, int millisecond, int microsecond) : this(DateTime.TimeToTicks(hour, minute, second, millisecond, microsecond)) { } /// /// Initializes a new instance of the TimeOnly structure using a specified number of ticks. @@ -104,6 +114,16 @@ public TimeOnly(long ticks) /// public int Millisecond => new TimeSpan(_ticks).Milliseconds; + /// + /// Gets the microsecond component of the time represented by this instance. + /// + public int Microsecond => new TimeSpan(_ticks).Microseconds; + + /// + /// Gets the nanosecond component of the time represented by this instance. + /// + public int Nanosecond => new TimeSpan(_ticks).Nanoseconds; + /// /// Gets the number of ticks that represent the time of this instance. /// diff --git a/src/libraries/System.Private.CoreLib/src/System/TimeSpan.cs b/src/libraries/System.Private.CoreLib/src/System/TimeSpan.cs index 346f7c36670bd..f21a12341175f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/TimeSpan.cs +++ b/src/libraries/System.Private.CoreLib/src/System/TimeSpan.cs @@ -45,7 +45,11 @@ public readonly struct TimeSpan IUnaryNegationOperators, IUnaryPlusOperators { - public const long TicksPerMillisecond = 10000; + public const long NanosecondsPerTick = 100; + + public const long TicksPerMicrosecond = 10; + + public const long TicksPerMillisecond = TicksPerMicrosecond * 1000; public const long TicksPerSecond = TicksPerMillisecond * 1000; // 10,000,000 @@ -87,12 +91,33 @@ public TimeSpan(int days, int hours, int minutes, int seconds) { } - public TimeSpan(int days, int hours, int minutes, int seconds, int milliseconds) + public TimeSpan(int days, int hours, int minutes, int seconds, int milliseconds) : + this(days, hours, minutes, seconds, milliseconds, 0) {} + + /// + /// Initializes a new instance of the structure to a specified number of + /// days, hours, minutes, seconds, and milliseconds. + /// + /// Number of days. + /// Number of hours. + /// Number of minutes. + /// Number of seconds. + /// Number of milliseconds. + /// Number of microseconds. + /// + /// The specified , , , + /// and are converted to ticks, and that value initializes this instance. + /// + /// + /// The parameters specify a value less than or greater than + /// + public TimeSpan(int days, int hours, int minutes, int seconds, int milliseconds, int microseconds) { long totalMilliSeconds = ((long)days * 3600 * 24 + (long)hours * 3600 + (long)minutes * 60 + seconds) * 1000 + milliseconds; if (totalMilliSeconds > MaxMilliSeconds || totalMilliSeconds < MinMilliSeconds) ThrowHelper.ThrowArgumentOutOfRange_TimeSpanTooLong(); _ticks = (long)totalMilliSeconds * TicksPerMillisecond; + _ticks += microseconds * TicksPerMicrosecond; } public long Ticks => _ticks; @@ -103,6 +128,24 @@ public TimeSpan(int days, int hours, int minutes, int seconds, int milliseconds) public int Milliseconds => (int)((_ticks / TicksPerMillisecond) % 1000); + /// + /// Gets the microseconds component of the time interval represented by the current structure. + /// + /// + /// The property represents whole microseconds, whereas the + /// property represents whole and fractional microseconds. + /// + public int Microseconds => (int)(_ticks / TicksPerMicrosecond); + + /// + /// Gets the nanoseconds component of the time interval represented by the current structure. + /// + /// + /// The property represents whole nanoseconds, whereas the + /// property represents whole and fractional nanoseconds. + /// + public int Nanoseconds => (int)(_ticks * NanosecondsPerTick); + public int Minutes => (int)((_ticks / TicksPerMinute) % 60); public int Seconds => (int)((_ticks / TicksPerSecond) % 60); @@ -126,6 +169,30 @@ public double TotalMilliseconds } } + /// + /// Gets the value of the current structure expressed in whole and fractional microseconds. + /// + /// + /// This property converts the value of this instance from ticks to microseconds. + /// This number might include whole and fractional microseconds. + /// + /// The property represents whole and fractional microseconds, + /// whereas the property represents whole microseconds. + /// + public double TotalMicroseconds => (double)_ticks / TicksPerMicrosecond; + + /// + /// Gets the value of the current structure expressed in whole and fractional nanoseconds. + /// + /// + /// This property converts the value of this instance from ticks to nanoseconds. + /// This number might include whole and fractional nanoseconds. + /// + /// The property represents whole and fractional nanoseconds, + /// whereas the property represents whole nanoseconds. + /// + public double TotalNanoseconds => (double)_ticks * NanosecondsPerTick; + public double TotalMinutes => (double)_ticks / TicksPerMinute; public double TotalSeconds => (double)_ticks / TicksPerSecond; @@ -234,6 +301,11 @@ public static TimeSpan FromMilliseconds(double value) return Interval(value, TicksPerMillisecond); } + public static TimeSpan FromMicroseconds(double value) + { + return Interval(value, TicksPerMicrosecond); + } + public static TimeSpan FromMinutes(double value) { return Interval(value, TicksPerMinute);