Description
Edited By @tarekgh
This proposal has been approved before #94545 (comment). There was some feedback from @tannergooding and @IDisposable.
@tannergooding said: the concern I raised is that there are scenarios this can cause problems since days * TimeSpan.HoursPerDay
could overflow. For example, if days > 89,478,485
then this will overflow to a negative int
.
HoursPerDay
happens to be the only case where it is "sensible" for it to be int
, since both MaxDays
(10,675,199
) and MaxHours
(256,204,778
) are within int.MaxValue
. That is also why the signatures are FromDays(int days, int hours, long minutes, long milliseconds, long microseconds)
. So other values, like MinutesPerDay
(1440
), MinutesPerHour
(60
), or even the existing MillisecondsPerTick
(10,000
) are all expected to be used in contexts where long
is the target type.
When considering TimeSpan, which is where these constants are defined, hours and days are int, all other units are long.
Background and motivation
In the TimeSpan
class there are a few public const
values that are generally applicable that are usefully exposed.
There are also a bunch more that are internal const
but would be generally useful for other code and are not more implementation driven than the already exposed const values.
These values should be exposed publicly on the TimeSpan class.
Note: NOT suggesting we expose the truly internal const
values that are related to MinTicks
and MaxTicks
. They could be included but are just not as naturally useful elsewhere.
API Proposal
namespace System.Collections.Generic;
public class TimeSpan: // elided details
{
// more elision
public const long MicrosecondsPerMillisecond = TicksPerMillisecond / TicksPerMicrosecond; // 1,000
public const long MicrosecondsPerSecond = TicksPerSecond / TicksPerMicrosecond; // 1,000,000
public const long MicrosecondsPerMinute = TicksPerMinute / TicksPerMicrosecond; // 60,000,000
public const long MicrosecondsPerHour = TicksPerHour / TicksPerMicrosecond; // 3,600,000,000
public const long MicrosecondsPerDay = TicksPerDay / TicksPerMicrosecond; // 86,400,000,000
public const long MillisecondsPerSecond = TicksPerSecond / TicksPerMillisecond; // 1,000
public const long MillisecondsPerMinute = TicksPerMinute / TicksPerMillisecond; // 60,000
public const long MillisecondsPerHour = TicksPerHour / TicksPerMillisecond; // 3,600,000
public const long MillisecondsPerDay = TicksPerDay / TicksPerMillisecond; // 86,400,000
public const long SecondsPerMinute = TicksPerMinute / TicksPerSecond; // 60
public const long SecondsPerHour = TicksPerHour / TicksPerSecond; // 3,600
public const long SecondsPerDay = TicksPerDay / TicksPerSecond; // 86,400
public const long MinutesPerHour = TicksPerHour / TicksPerMinute; // 60
public const long MinutesPerDay = TicksPerDay / TicksPerMinute; // 1,440
public const long HoursPerDay = TicksPerDay / TicksPerHour; // 24
}
API Usage
if (TimeSpan.MinutesPerHour * numHours) > TimeSpan.MinutesPerDay * 7)
Console.WriteLine("That's really weeks");
Alternative Designs
N/A
Risks
Since these are compile-time constant values, there would be no runtime cost in either memory or execution overhead. Additionally they would centralize basic real-world facts to one logical location (TimeSpan).