DateTime.Now equivalent for TimeOnly and DateOnly?
Asked Answered
C

3

83

.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?

Chug answered 1/11, 2021 at 14:23 Comment(2)
See github.com/dotnet/runtime/issues/53498 – Cyaneous
Now in which timezone? Even the date isn't the same at any given moment -actually half the Earth is on a different date. That's why the new API requires you to be explicit – Verda
C
37

The solution:

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;

Why isn't there a simple property on 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 atomic.

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.

Chug answered 1/11, 2021 at 14:40 Comment(0)
N
96

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?

  • From @tarekgh comment, dotnet community is trying to keep DateOnly not relate to time zones

Next 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.

Nibelungenlied answered 1/11, 2021 at 14:28 Comment(2)
Legacy issues πŸ™ˆ ... from a programmers perspective it feels so wrong: var date = DateOnly.FromDateTime(DateTime.Now); – Tello
In case of DateOnly I disagree. DateOnly do not relate to time zones by design. The only exception is initialization to today's value. And no matter what you invent you'll get dependency on timezone because today in Australia may be different from today in London. And in 99% cases today is used for local time zone so DateOnly.Today would be beneficial for most users. DateOnly is like inventing int after many years of using decimal only. And by analogy we have int.default forbidden to avoid dependency on System so everybody is using (int)default(decimal). – Aeniah
C
37

The solution:

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;

Why isn't there a simple property on 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 atomic.

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.

Chug answered 1/11, 2021 at 14:40 Comment(0)
L
10

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

Lipsey answered 1/11, 2021 at 14:31 Comment(0)

© 2022 - 2024 β€” McMap. All rights reserved.