.NET
programming
time representation
DateTime
C#

How do I represent a time only value in .NET?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Many business domains need clock time values such as opening hours, cutoff times, and recurring reminders without attaching a specific calendar date. In .NET, choosing the correct type for this concept is important for validation, serialization, and database mapping. The best practice in modern projects is using TimeOnly for time-of-day semantics.

Use TimeOnly in Modern .NET

TimeOnly was introduced in .NET 6 to represent only a time within one day. It avoids hidden date components and makes intent clearer than DateTime when date is irrelevant.

csharp
1using System;
2using System.Globalization;
3
4TimeOnly opening = new TimeOnly(9, 30);
5TimeOnly closing = TimeOnly.ParseExact("18:15", "HH:mm", CultureInfo.InvariantCulture);
6
7Console.WriteLine(opening.ToString("HH:mm"));
8Console.WriteLine(closing.ToString("hh:mm tt", CultureInfo.InvariantCulture));

This type is ideal for schedules and recurring local-time settings.

Fallback for Older Framework Targets

If your target framework does not support TimeOnly, use TimeSpan constrained to a single day.

csharp
1using System;
2
3static void ValidateClockTime(TimeSpan value)
4{
5    if (value < TimeSpan.Zero || value >= TimeSpan.FromDays(1))
6    {
7        throw new ArgumentOutOfRangeException(nameof(value), "Time must be within one day");
8    }
9}
10
11TimeSpan start = TimeSpan.FromHours(8.5);
12TimeSpan end = TimeSpan.FromHours(17);
13
14ValidateClockTime(start);
15ValidateClockTime(end);
16
17Console.WriteLine(start);
18Console.WriteLine(end);

Avoid DateTime for pure time values unless you are forced by API constraints.

Serialization Strategy for APIs

For APIs, define a fixed wire format. A common choice is HH:mm:ss for clarity and interoperability.

csharp
1using System;
2using System.Text.Json;
3using System.Text.Json.Serialization;
4
5public record BusinessHours([property: JsonConverter(typeof(TimeOnlyJsonConverter))] TimeOnly OpensAt);
6
7public class TimeOnlyJsonConverter : JsonConverter<TimeOnly>
8{
9    private const string Format = "HH:mm:ss";
10
11    public override TimeOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
12    {
13        var text = reader.GetString() ?? throw new JsonException("Missing time value");
14        return TimeOnly.ParseExact(text, Format);
15    }
16
17    public override void Write(Utf8JsonWriter writer, TimeOnly value, JsonSerializerOptions options)
18    {
19        writer.WriteStringValue(value.ToString(Format));
20    }
21}
22
23var payload = JsonSerializer.Serialize(new BusinessHours(new TimeOnly(9, 0)));
24Console.WriteLine(payload);

Explicit converters avoid format drift across services.

Database Mapping and Persistence

Map time-only fields to SQL time columns where possible. This keeps storage semantics aligned with domain meaning.

With EF Core, verify generated mappings and precision in migrations. If you store seconds or fractional seconds, test round-trip behavior.

Practical checklist:

  • application type is TimeOnly or constrained TimeSpan
  • database type is time
  • serialization format is documented
  • round-trip tests include edge values such as midnight

Keep conversion only at boundaries, not spread across core logic.

Time-Only Versus Timestamp Semantics

A time-only value is not a unique instant on a global timeline. It needs context when execution depends on timezone.

For recurring jobs, store:

  • local clock time, for example 09:00
  • timezone identifier, for example America/Toronto
  • daylight-saving transition policy

Without timezone metadata, jobs can shift unexpectedly during seasonal transitions.

Validation and Domain Rules

Common validation rules include:

  • start time before end time for same-day windows
  • minute granularity requirements
  • forbidden closed intervals
csharp
1using System;
2
3static bool IsValidWindow(TimeOnly start, TimeOnly end)
4{
5    return start < end;
6}
7
8Console.WriteLine(IsValidWindow(new TimeOnly(9, 0), new TimeOnly(17, 0))); // True
9Console.WriteLine(IsValidWindow(new TimeOnly(18, 0), new TimeOnly(9, 0))); // False

Put these rules in domain services to keep behavior consistent across UI and API layers.

Common Pitfalls

A common pitfall is storing time-only data in DateTime and accidentally comparing date components. Another is assuming time-only fields contain timezone meaning. Teams often leave API format undefined, causing parsing issues across clients. Fallback TimeSpan values are sometimes accepted without range validation, leading to invalid times. Database precision mismatches can also truncate seconds unexpectedly if not tested.

Summary

  • Use TimeOnly in .NET 6 and later for time-of-day values.
  • Use constrained TimeSpan on older targets when needed.
  • Standardize API serialization format, such as HH:mm:ss.
  • Map to database time type and test round-trip precision.
  • Store timezone context separately when schedule execution depends on region.
  • Keep validation rules centralized to enforce consistent behavior.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.