Description
Background and Motivation
Almost every project I've worked on, from small personal projects to large enterprise ones, ends up with various extension methods designed to make date and time manipulation more concise and less repetitive. Many of these are born out of inconsistencies and/or shortcomings of the current API surface on the five core date and time types: DateTime
, DateTimeOffset
, DateOnly
, TimeOnly
, and TimeSpan
. Specifically, DateOnly
and TimeOnly
do not feel like first class citizens next to DateTime
and DateTimeOffset
.
In an ecosystem where version after version, compiler and syntax changes have been consitently made to reduce the amount of syntax needed to create types (ie: collection expressions), I feel like these core system types have not been given the same amount of attention. Yet date and time manipulation is probably one of the most common operations and omni present in almost every single project a .NET developer will be involved in.
Proposed API
To avoid creating a large amount of issues that are all centered around the same background and motivation, I opted instead on creating a list of propose APIs with additional notes where appropriate. I have tried to group them as best as I can.
Missing APIs for consistency
1) DateTimeOffset.FromDateTime(DateTime dateTime) static method
DateOnly
andTimeOnly
both already exposeFromDateTime()
.- A
DateTime
can already be cast into aDateTimeOffset
.
2) DateTime.FromDateTimeOffset() static method
- There is already a constructor overload on
DateTimeOffset
which supports aDateTime
. - With proposal 1,
DateTimeOffset
would also expose the similarFromDateTime()
.
3) dateTime.ToDateTimeOffset(TimeSpan offset) instance method
- There is already a constructor overload on
DateTimeOffset
which supports aDateTime
andTimeSpan
. DateOnly
instances already expose the similarToDateTime
.
4) DateTimeOffset.Today and DateOnly.Today property
DateTimeOffset
already exposesNow
andUtcNow
likeDateTime
.DateTime
already exposesToday
.
5) TimeOnly.Now and TimeOnly.UtcNow property
DateTime
andDateTimeOffset
already exposeNow
andUtcNow
.
6) timeOnly.AddSeconds(double value), timeOnly.AddMilliseconds(double value), timeOnly.AddMicroseconds(double value), and timeOnly.AddTicks(long value) instance method
DateTime
andDateTimeOffset
instances both already exposeAddSeconds()
,AddMilliseconds()
,AddMicroseconds()
, andAddTicks()
.
7) DateOnly.FromDateTimeOffset(DateTimeOffset dateTimeOffset) and TimeOnly.FromDateTimeOffset(DateTimeOffset dateTimeOffset) static methods
DateOnly
andTimeOnly
both already exposeFromDateTime()
.
8) DateTime.FromDateOnly(DateOnly dateOnly) and DateTimeOffset.FromDateOnly(DateOnly dateOnly) static methods
DateOnly
andTimeOnly
both already exposeFromDateTime()
.
9) dateTime.ToDateOnly() instance method
DateOnly
instances already exposeToDateTime()
.
10) dateTimeOffset.ToDateOnly() instance method
DateOnly
instances already exposeToDateTime()
.- With proposal 9,
DateTime
instances would also exposeToDateOnly()
.
11) dateOnly.ToDateTimeOffset() and dateOnly.ToDateTimeOffset(TimeSpan offset) instance methods
DateOnly
instances already exposeToDateTime()
.- With proposal 9 and 10,
DateTime
instances would also exposeToDateOnly()
andDateTimeOffset
instances would also expose.ToDateOnly()
.
12) dateTime.ToTimeOnly() and dateTimeOffset.ToTimeOnly() instance methods
DateOnly
instances already exposeToDateTime()
.- With proposal 9, 10, and 11,
DateTime
instances would also exposeToDateOnly()
,DateTimeOffset
instances would also expose.ToDateOnly()
, andDateOnly
instances would also expose.ToDateTimeOffset()
.
13) Implicit cast from DateOnly instances to DateTimeOffset instances
DateTime
instances already implicitly cast toDateTimeOffset
.
Expanding Today API
14) DateTime.UtcToday, DateTimeOffset.UtcToday, DateOnly.UtcToday
DateTime
andDateTimeOffset
already expose the propertiesNow
andUtcNow
, this would be natural pairing to the already exposedToday
property.- With proposal 4, both
DateTimeOffset
andDateOnly
would also exposeToday
.
New Substract APIs
15) Substract instance method variants of Add to DateTime, DateTimeOffset, DateOnly, and TimeOnly
- Add the
SubstractYears(int value)
instance method toDateTime
,DateTimeOffset
, andDateOnly
. - Add the
SubstractMonths(int value)
instance method toDateTime
,DateTimeOffset
, andDateOnly
. - Add the
SubstractDays(double value)
instance method toDateTime
,DateTimeOffset
, andSubstractDays(int value)
instance methodDateOnly
. - Add the
SubstractHours(double value)
instance method toDateTime
,DateTimeOffset
, andTimeOnly
. - Add the
SubstractMinutes(double value)
instance method toDateTime
,DateTimeOffset
, andTimeOnly
. - Add the
SubstractSeconds(double value)
instance method toDateTime
,DateTimeOffset
, andTimeOnly
. - Add the
SubstractMilliseconds(double value)
instance method toDateTime
,DateTimeOffset
, andTimeOnly
. - Add the
SubstractMicroseconds(double value)
instance method toDateTime
,DateTimeOffset
, andTimeOnly
. - Add the
SubstractTicks(long value)
instance method toDateTime
,DateTimeOffset
, andTimeOnly
.
Expand TimeSpan API
#### 16) TimeSpan.FromYears(int value)
and TimeSpan.FromMonths(int value)
static methods
TimeSpan
already exposes all otherFrom
methods.
17) TimeSpan.Add
variants and TimeSpan.Substract
variants
- Adding the AddYears(), AddMonths(), AddDays(), AddHours(), AddMinutes(), AddSeconds(), AddMilliseconds(), AddMicroseconds(), AddTicks() instance methods would avoid needing to create an intermediate TimeSpan to manipulate an existing TimeSpan.
- Also in the same vein, adding the instance methods from proposal 15.