DateOnly și TimeOnly în C# (.NET)

DateOnly ține doar o zi din calendar, TimeOnly doar o oră din zi: potrivite pentru zile de naștere, scadențe și program de lucru.

Sintaxă C#
var zi = new DateOnly(2026, 10, 25);   var ora = new TimeOnly(9, 30);   zi.ToDateTime(ora)

Ce face DateOnly și TimeOnly

DateOnly reprezintă o zi fără oră și fără fus orar, așa că nu apar erori de tipul „ziua de naștere s-a mutat cu o zi” la conversia între fusuri. Are AddDays, AddMonths, AddYears, DayOfWeek și DayNumber (numărul de zile de la 1 ianuarie anul 1), util pentru diferențe în zile.

TimeOnly reprezintă o oră din zi, între 00:00 și 23:59:59.9999999. Adunarea trece peste miezul nopții circular (22:00 + 4 ore = 02:00), iar IsBetween(inceput, sfarsit) verifică un interval, inclusiv unul care trece de miezul nopții.

Conversiile: DateOnly.FromDateTime(dt), TimeOnly.FromDateTime(dt) și zi.ToDateTime(ora). Entity Framework Core și System.Text.Json știu să salveze ambele tipuri.

Exemple

Exemplul 1: Vârsta și zilele până la o scadență

var nastere = new DateOnly(1995, 3, 14);
var azi = new DateOnly(2026, 10, 25);

int varsta = azi.Year - nastere.Year;
if (azi < nastere.AddYears(varsta))
    varsta--;
Console.WriteLine($"Vârsta: {varsta} ani");

var scadenta = new DateOnly(2026, 12, 25);
Console.WriteLine($"Zile până la scadență: {scadenta.DayNumber - azi.DayNumber}");
Console.WriteLine(scadenta.ToString("yyyy-MM-dd"));
Console.WriteLine(scadenta.DayOfWeek);

Rezultat

Vârsta: 31 ani
Zile până la scadență: 61
2026-12-25
Friday

Exemplul 2: Program de lucru cu TimeOnly

IsBetween include ora de început și exclude ora de sfârșit.

var deschidere = new TimeOnly(9, 0);
var inchidere = new TimeOnly(18, 0);

foreach (var ora in new[] { new TimeOnly(8, 59), new TimeOnly(9, 0), new TimeOnly(18, 0) })
    Console.WriteLine($"{ora:HH:mm} deschis: {ora.IsBetween(deschidere, inchidere)}");

Console.WriteLine(inchidere - deschidere);
Console.WriteLine(new TimeOnly(22, 0).AddHours(4).ToString("HH:mm"));

var zi = new DateOnly(2026, 10, 25);
Console.WriteLine(zi.ToDateTime(deschidere).ToString("yyyy-MM-dd HH:mm"));

Rezultat

08:59 deschis: False
09:00 deschis: True
18:00 deschis: False
09:00:00
02:00
2026-10-25 09:00

Greșeli frecvente

  • Folosirea lui DateTime pentru zile de naștere: ora 00:00 convertită între fusuri orare poate muta data cu o zi.
  • DateOnly și TimeOnly nu există în .NET Framework, doar din .NET 6.
  • Scăderea a două DateOnly cu - nu se compilează. Folosește DayNumber.

Comenzi înrudite

  • DateTime: Reprezintă o dată cu oră: creare, adunare de zile și luni, diferențe, formatare și citire din text cu ParseExact.
  • TimeSpan: Reprezintă o durată (ore, minute, secunde): creare, adunare, proprietăți Total* și formatare ca text.
  • Formatarea numerelor și string.Format: Specificatori de format (N2, F1, D5, X) și aliniere în string.Format, ToString și șiruri interpolate, cu cultura ro-RO.