Description
Background and motivation
.NET now has many different DateTime types: DateTime
, DateTimeOffset
, DateOnly
, etc. Each of these were added for good reasons.
DateTime
: The original but fails to account for time zone offsetsDateTimeOffset
: Accounts for only a numerical DateTimeOffset (not named IANA zones)DateOnly
: Simplified dates without worrying about time and timezone offsets complicating calculationsTimeOnly
: Simplified again with only time-related components.
But there is one obvious gap. For UI programming IANA time zone or Windows ID time zones are required for user selection. It's not 1:1 to convert this to/from a numerical time zone offset which means DateTimeOffset
can't be used in some cases as well. Then 3rd party libraries come into play to fill this gap.
Now we have way too many Date/Time types to manage and no way to do it in a generic way. So my proposal is something like the INumber
interface to bring all of this together.
The use cases are not only for backend code. But also for UI controls. For example UI frameworks can start writing generic Date/TimePickers and allow the app to define the type they need to work with. An IDate
interface is perfect for this to support all known date/time types (since a DatePicker control only cares about the date-related components).
API Proposal
I'll flesh this out when I have more time.
public interface IDate
{
int Day;
int Month;
int Year;
}
public interface IDateTime
{
int Day;
int Month;
int Year;
int Hour;
int Minute;
int Second;
}
public interface ITime
{
int Hour;
int Minute;
int Second;
}
API Usage
TBD
Alternative Designs
It needs to be discussed:
- Whether to call these interfaces
IDateOnly
andITimeOnly
instead and model them almost entirely based onDateOnly
andTimeOnly
. ThenIDateTime
will simply be a union of the two interfaces. - The specific members to include in
ITimeOnly
are debatable. Should this be only high-level hours/minutes/seconds (all that usually needed for general-purpose or UI code) or should it include all members down to ticks. The answer is likely all members down to ticks. However, some 3rd party libraries may not support all these members. Therefore, there could be multiple levels to these interfaces like what was done for INumber. BasicallyIBasicTimeOnly
with only hours/minutes/seconds and then anITimeOnly
that derives from that and includes everything.
Risks
This seems low risk to me as it is only abstracting common, shared properties already used in all the types.