.NET 6 / C# 10 introduced TimeOnly
and DateOnly
structs, to represent only a time and only a date respectively.
The good old DateTime
struct always had a Now
static property which would give you the current date and time.
I was expecting both TimeOnly
and DateOnly
structs to have similar static properties; like TimeOnly.Now
or DateOnly.Today
, but they apparently don't.
So, what should I do if I want a DateOnly
object representing the current date, or a TimeOnly
object representing the current time?
And I would also like to know WHY they decided not to include properties like that on these two new structs?
now() takes tzinfo as keyword argument but datetime. today() does not take any keyword arguments. datetime. now() return the current local date and time.
Internally, DateOnly stores its value as an integer , where 0 is the 1st of January 0001.
Returns a DateTime that is set to the date of this DateOnly instance and the time of specified input time. Represents a time of day, as would be read from a clock, within the range 00:00:00 to 23:59:59.9999999.
We may also add days, months or years to a DateOnly instance, resulting in a new instance with the adjusted date. The TimeOnly struct is used to represent a time that is independent of the date. For example, imagine creating an alarm clock app that lets the user create a reoccurring alarm.
Just as with DateOnly, we can convert from an existing DateTime into a TimeOnly using the FromDateTime static method. The above code will now write to console whether the current time falls between 10:30 (10:30am) and 17:00 (5pm).
But every now and again, those gremlins creep in when trying to use DateTime as either only a Date, or only a Time. In the case of using only a Date, this is extremely common when storing things such as birthdays, anniversary dates, or really any calendar date that doesn’t have a specific time associated with it.
You can use .FromDateTime()
method,
To get current date only:
var dateNow = DateOnly.FromDateTime(DateTime.Now);
To get current time only:
var timeNow = TimeOnly.FromDateTime(DateTime.Now);
For more details, you can go through Github issue. There are several good comments which explains, why .Now
property is not introduced to DateOnly
and TimeOnly
Why .Today
, .Now
and UtcNow
properties are not introduced to DateOnly
?
DateOnly
not relate to time zonesNext comment from @tarekgh, explained further complexity if they introduce these properties to the DateOnly
.
After reading github thread and couple of other documentations, I feel like introducing DateOnly
and TimeOnly
structs are just to decouple the DateTime
.
This decoupling of date and time will help us in future to perform individual calculations on Date
and Time
separately.
This will help us to design our model classes precisely and at granular level.
The way to create a TimeOnly
or DateOnly
object representing the current time or date would be to use the FromDateTime
static method along with DateTime.Now
. So like:
TimeOnly now = TimeOnly.FromDateTime(DateTime.Now);
DateOnly today = DateOnly.FromDateTime(DateTime.Now);
If this is something you repeatedly need in your project, in order to avoid duplication, you could create extension methods on DateTime
to convert a DateTime
instance into TimeOnly
or DateOnly
:
public static class DateTimeExtensions
{
public static TimeOnly ToTimeOnly(this DateTime dateTime)
{
return TimeOnly.FromDateTime(dateTime);
}
public static DateOnly ToDateOnly(this DateTime dateTime)
{
return DateOnly.FromDateTime(dateTime);
}
}
Usage:
TimeOnly now = DateTime.Now.ToTimeOnly();
DateOnly today = DateTime.Now.ToDateOnly();
Note that this would be not only useful for getting the current date or time as TimeOnly
or DateOnly
, but for converting any instance of DateTime
into TimeOnly
or DateOnly
.
Another approach would be to have two static classes like the following:
public static class TimeOnlyHelpers
{
public static TimeOnly Now => TimeOnly.FromDateTime(DateTime.Now);
}
public static class DateOnlyHelpers
{
public static DateOnly Today => DateOnly.FromDateTime(DateTime.Now);
}
Usage:
TimeOnly now = TimeOnlyHelpers.Now;
DateOnly today = DateOnlyHelpers.Today;
DateOnly
and TimeOnly
?The rationale behind why no Now
or Today
properties were added to these structs was discussed here in this GitHub issue.
In short, they didn't want to bring in timezones and everything into DateOnly
and TimeOnly
since that would add extra complexity, so they decided against this, and kept the new structs simple and explicit.
There is some discussion however about whether a property like that could be added to a Clock
class (still a proposal, you can follow it here) so that the usage would be along the lines of TimeOnly now = SystemClock.Local.Now
, or for DateOnly
like DateOnly today = SystemClock.Local.Today
or something like that. But that's still undecided.
To get the DateOnly object representing the current date, you can use:
var currentDate = DateOnly.FromDateTime(DateTime.Now);
Similarly, to get the TimeOnly object representing the current date, you can use:
var currentTime = TimeOnly.FromDateTime(DateTime.Now);
The reasoning behind not including the .Now property is discussed in detail here: https://github.com/dotnet/runtime/issues/53498
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With