Explain DateOnly and TimeOnly in C#

Wait, it is Over! Yes

In this article, we are going to explore DateOnly and TimeOnly in C#. During development, there is often a need to exclusively handle either date or time for storage or presentation on the front end. Previously, achieving this involved using the DateTime struct along with specific properties and methods. However, with the introduction of .NET 6.0, new DateOnly and TimeOnly structs have been added, allowing us to use them directly as needed.

Before the advent of .NET 6, these structs were also accessible in the .NET Framework. However, their utilization required the manual addition of the NuGet package Portable.System.DateTimeOnly to the project for accessibility. Further details can be found in the NuGet description. (https://www.nuget.org/packages/Portable.System.DateTimeOnly)

These both structs types exist out of the box only in .Net 6+ Framework.

DateOnly Struct

The DateOnly structure is designed to represent a particular date devoid of any time information. As it lacks a time component, it signifies a date spanning from the beginning of the day to its conclusion. This structure proves particularly useful for the storage of precise dates, such as birthdates, anniversaries, or dates associated with business events. Here is an example of how to use the DateOnly struct:

var dateOnly = new DateOnly(2023, 12, 25);  

// new DateOnly(int year, int month, int day)
Console.WriteLine(dateOnly);

/* This example produces the following output:
 * 12/25/2023

*/

AddDays, AddMonths, and AddYears Methods with DateOnly

Just like with DateTime, the Add<component> methods have been brought across to the DateOnly struct.

var addDays = dateOnly.AddDays(1); // 12/26/2023
var addMonths = dateOnly.AddMonths(1); // 01/25/2024
var addYears = dateOnly.AddYears(1); // 12/25/2024

TimeOnly Struct in C#

When we are only interested solely in the time element, the newly introduced TimeOnly struct becomes invaluable. Before the inception of the TimeOnly type, developers commonly utilized either the DateTime type or the TimeSpan type to signify a particular time.

var timeOnly = TimeOnly.FromDateTime(DateTime.Now);
Console.WriteLine($"It is { timeOnly } right now");

/* This example produces output similar to the following:
* It is 3:01 PM right now
*/

Creating a new TimeOnly instance is very simple.

Var elevenAM = new TimeOnly(11, 0);
// new TimeOnly (int hour, int minute)

Console.WriteLine($"Time: { elevenAM } ");

// Output
// Time: 11:00 AM

The hour component of TimeOnly is according to a 24-hour clock, so if we want 11 PM, we would use the value 23 for the hour parameter.

AddHours and AddMinutes Methods with TimeOnly

We already know how the AddDays(), AddMonths(), and AddYears() methods work with DateOnly. Similarly, with TimeOnly, we have AddHours() and AddMinutes().

var addHours = elevenAM.AddHours(1);
var addMinutes = elevenAM.AddMinutes(5);

For more detail regarding operations on DateOnly and TimeOnly, see.

Conclusion

This article has provided insights into the recently introduced DateOnly and TimeOnly types in .NET 6. These additions afford us improved alternatives for handling dates and times in the .NET framework, granting greater flexibility in our decision-making processes.