Modern C# Development: Get Started With TimeOnly

Lou Creemers - May 24 - - Dev Community

Hi lovely readers,

We probably all know the pain of using DateTime while just needing a date without time, or a time without a day. Well, .NET came with a solution that still isn’t that widely used. In this blog post, we’re going to focus on the data type TimeOnly.

Does your application heavily rely on time and not date? Do you hate time zones and do you rather not deal with them? Do you want to learn how to make your time variables even better, and easier to serialize? Continue reading and I’ll show you how.

Why TimeOnly

TimeOnly is great in situations where you’re heavily focused on Time. Here are some scenarios where TimeOnly proves to be a great alternative to DateTime:

  1. Simplicity and Readability:

    When your application deals primarily with event times that don’t necessarily need dates, TimeOnly provides a better option.

  2. Database Operations:

    Working with databases that store time information without date becomes seamless with TimeOnly.

  3. Comparisons:

    TimeOnly is a great pick if your logic involves comparing two TimeOnly objects and how much time is in between them. It has methods built in to compare time.

  4. Consistency in Codebase:

    For codebases that heavily rely on time, using TimeOnly throughout helps with consistency.

  5. Avoiding Time Zone Complexity:

    Because TimeOnly doesn’t focus on dates, you don’t have time zone complexities at all. This makes working with TimeOnly way easier.

How to use TimeOnly

Now that we've explored why TimeOnly is a great choice in multiple scenarios, let's dive into how to use TimeOnly in your C# projects.

Initialize TimeOnly

Creating a TimeOnly instance is straightforward. You can set a specific time using the constructor like this:

TimeOnly specificTime = new TimeOnly(11,30); //hour, minute
TimeOnly specificTime2 = new TimeOnly(11,30,45); //hour, minute, second
TimeOnly specificTime3 = new TimeOnly(11,30,45,100); //hour, minute, second, millisecond
TimeOnly specificTime4 = new TimeOnly(11,30,45,100, 4); //hour, minute, second, millisecond, microsecond
Enter fullscreen mode Exit fullscreen mode

If you want to initialize a TimeOnly variable with the time right now, you can use the ‘FromDateTime’ method:

TimeOnly timeNow = TimeOnly.FromDateTime(DateTime.Now);
Enter fullscreen mode Exit fullscreen mode

You can write it to the console like every other variable:

Console.WriteLine(specificTime); //11:30
Console.WriteLine(timeNow); //Whatever time it is right now in hh:mm
Enter fullscreen mode Exit fullscreen mode

Whether you get to see a 24-hour clock or 12-hour clock depends on the settings of your machine.

Formatting the TimeOnly value

Of course, you can format this TimeOnly variable differently based on whatever country/culture you want to focus on. You can use the System.Globalization package for this.

From the 24-hour system to the USA AM/PM system:

using System.Globalization;

TimeOnly specificTime = new TimeOnly(11,30); //hour, minute
CultureInfo ci = CultureInfo.GetCultureInfo("en-US");

Console.WriteLine(specificTime.ToString(ci));

Enter fullscreen mode Exit fullscreen mode

From USA AM/PM system to the European 24-hour system:

using System.Globalization;

TimeOnly specificTime = new TimeOnly(11,30); //hour, minute
CultureInfo ci = CultureInfo.GetCultureInfo("en-GB");

Console.WriteLine(specificTime.ToString(ci));

Enter fullscreen mode Exit fullscreen mode

Logic with TimeOnly

TimeOnly supports time operations like adding or subtracting hours or minutes. Here's how you can do it.

Adding and Subtracting Time:

TimeOnly timeNow = TimeOnly.FromDateTime(DateTime.Now);
TimeOnly timeNowPlusAnHour = timeNow.AddHours(1);
TimeOnly timeNowMinusAnHour = timeNow.AddHours(-1);
TimeOnly timeNowPlusAMinute = timeNow.AddMinutes(1);
TimeOnly timeNowMinusAMinute = timeNow.AddMinutes(-1);
Enter fullscreen mode Exit fullscreen mode

Serialization

Serialization is often crucial when dealing with dates in applications. TimeOnly simplifies this process. For instance, when working with JSON:

using System.Text.Json;

TimeOnly specificTime = new TimeOnly(11,30); //hour, minute

string json = JsonSerializer.Serialize(specificTime);
TimeOnly deserializedTime = JsonSerializer.Deserialize<TimeOnly>(json);

Console.WriteLine(deserializedTime); // 11:30
Enter fullscreen mode Exit fullscreen mode

Conditions

You can use if-else conditions, switch cases, or switch expressions with TimeOnly


TimeOnly specificTime = new TimeOnly(11,30); //hour, minute
TimeOnly timeLater = new TimeOnly(11,35); //hour, minute

if(specificTime > timeLater)
{
    Console.WriteLine("specificTime is later than timeLater");
}
else
{
    Console.WriteLine("specificTime is not later than timeLater");
}

Enter fullscreen mode Exit fullscreen mode

Compare two TimeOnly objects

You can compare two TimeOnly objects and store that value in another variable. This variable will become a TimeSpan data type

TimeOnly specificTime = new TimeOnly(11,30); //hour, minute
TimeOnly timeLater = new TimeOnly(11,35); //hour, minute

TimeSpan difference = timeLater-specificTime;

Console.WriteLine(difference); // 00:05:00
Enter fullscreen mode Exit fullscreen mode

It will also work with more precise TimeOnly objects where you have to compare microseconds

TimeOnly specificTime = new TimeOnly(11,30,00,00,00); //hour, minute, second, millisecond, microsecond
TimeOnly timeLater = new TimeOnly(11,30,00,00,02); //hour, minute, second, millisecond, microsecond

TimeSpan difference = timeLater-specificTime;

Console.WriteLine(difference); // 00:00:00.0000020
Enter fullscreen mode Exit fullscreen mode

That’s a wrap!

So in conclusion, TimeOnly offers simplicity, readability, and consistency when working with times in C# applications. By focusing solely on time and ignoring dates, it streamlines operations like database storage, user interfaces, and comparisons. Whether you're developing scheduling software, logging systems, or any other application reliant on time, TimeOnly can enhance your workflow and codebase.

I hope that this blog post was helpful and made you understand this datatype built into C#. If you have any questions or comments, feel free to reach out on @lovelacecoding on almost every social media platform or leave a comment down below.

See ya!

. . . . . . .