CodeGym /Courses /C# SELF /Handy Types: DateOnly and TimeOnly

Handy Types: DateOnly and TimeOnly

C# SELF
Level 15, Lesson 1
Available

1. Introduction

Back in the day, C# didn't have a separate type for just a date or just a time. So even if you only needed to store a date—like a birthday—you had to use DateTime and tack on a "default time". The old way to store just a date using DateTime:


DateTime birthday = new DateTime(1985, 4, 20); // April 20, 1985, 00:00:00

But that's not convenient. You just want a date, but you end up with a time too—even if it's zero. That can be confusing: for example, when comparing dates, your program might take the time into account and you'll get weird results.

Same story the other way around: if you're only working with time (like a work schedule from 08:00 to 17:00), you still had to "make up" a date, even though it doesn't matter at all.

Now .NET has special types DateOnly and TimeOnly that get rid of all that confusion.

New Handy Types DateOnly and TimeOnly

  • DateOnly — just a calendar date, no time of day and no timezone info.
  • TimeOnly — just the time of day, no year, month, day, and again, no timezone.

Time Types Comparison Table

Type Date Time Timezone What is it used for?
DateTime
✅ ✅ 🚫 Pretty much everything (but not always convenient or safe)
DateTimeOffset
✅ ✅ ✅ When you need both a moment in time and a timezone
DateOnly
✅ 🚫 🚫 Birthdays, dates without time
TimeOnly
🚫 ✅ 🚫 Business hours, schedules, intervals during the day

2. Working with DateOnly

Declaration and Creation

Creating a DateOnly object is as easy as picking up a new habit: quick and simple! For example:

// Year, month, day
DateOnly birthday = new DateOnly(1985, 4, 20);
Creating a birthday date using DateOnly

You can use DateOnly.FromDateTime if you already have a DateTime object:

DateTime now = DateTime.Now;
DateOnly today = DateOnly.FromDateTime(now);
// now today only has the date, time is dropped

Main Properties and Methods

  • Year, Month, Day — just like in DateTime.
  • .ToString() — formats the date, you can set your own format.
Console.WriteLine($"Birthday: {birthday.Year} year, {birthday.Month} month, {birthday.Day} day.");

Console.WriteLine(today.ToString("dd.MM.yyyy")); // For example, 07/30/2024

Date Math

You can easily add days/months/years:

DateOnly tomorrow = today.AddDays(1);
DateOnly nextMonth = today.AddMonths(1);

Try swapping out your DateTime fields that only store a date for DateOnly in your main app—you'll be one step closer to modern .NET!

Date Comparison

You can compare using <, >, ==:

if (birthday < today)
    Console.WriteLine("Birthday already happened this year or a long time ago :)");

No more bugs with extra milliseconds or minutes.

Getting Today's Date

DateOnly currentDate = DateOnly.FromDateTime(DateTime.Now);

3. Working with TimeOnly

Now let's deal with time without a date—because what programmer hasn't had to deal with lunch schedules?

Creating TimeOnly

TimeOnly startWork = new TimeOnly(9, 0);    // 09:00
TimeOnly endWork = new TimeOnly(17, 30);    // 17:30

You can get just the hours, minutes, seconds:

Console.WriteLine($"Workday: from {startWork.Hour}:{startWork.Minute:D2} to {endWork.Hour}:{endWork.Minute:D2}");

Get Time from DateTime

DateTime now = DateTime.Now;
TimeOnly currentTime = TimeOnly.FromDateTime(now);
Console.WriteLine($"Right now it's {currentTime}");

Time Math

TimeOnly breakStart = startWork.AddHours(4); // break in 4 hours, so at 13:00
TimeOnly breakEnd = breakStart.AddMinutes(30); // 30 minute lunch

Comparisons and Checks

if (currentTime >= startWork && currentTime <= endWork)
    Console.WriteLine("Time to work :)");
else
    Console.WriteLine("You can chill.");

4. Interacting with Other Types

Converting between DateOnly, TimeOnly, and DateTime

Sometimes you need to get a DateTime again (like for storing in an old database or for compatibility):


DateOnly datePart = new DateOnly(2024, 7, 30);
TimeOnly timePart = new TimeOnly(14, 15);
DateTime datetime = datePart.ToDateTime(timePart); // 2024-07-30 14:15:00

And the other way around:

DateTime dt = DateTime.Now;
DateOnly justDate = DateOnly.FromDateTime(dt);
TimeOnly justTime = TimeOnly.FromDateTime(dt);

Important Features and Common Mistakes

  • If you try to parse just a date or just a time using the old methods like DateTime.Parse(), you'll probably get an error or not what you expected. For those cases, there are special methods: use DateOnly.Parse() and TimeOnly.Parse()—they know how to handle "trimmed" values.
  • Important to get: DateOnly and TimeOnly have zero clue about timezones. It's just a date or just a time—no connection to a timezone. If you need to care about zones, store that info separately.
2
Task
C# SELF, level 15, lesson 1
Locked
Working with `DateOnly`
Working with `DateOnly`
2
Task
C# SELF, level 15, lesson 1
Locked
Working with `TimeOnly`
Working with `TimeOnly`
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION