CodeGym /Kursy /C# SELF /Przydatne typy: DateOnly i TimeOnly

Przydatne typy: DateOnly i TimeOnly

C# SELF
Poziom 15, Lekcja 1
Dostępny

1. Wprowadzenie

Kiedyś w C# nie było osobnego typu tylko na datę albo tylko na czas. Więc nawet jeśli chciałeś przechować samą datę — na przykład urodziny — musiałeś używać DateTime i dodawać "domyślną godzinę". Stary sposób przechowywania samej daty przez DateTime:


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

Ale to jest niewygodne. Chcesz tylko datę, a dostajesz jeszcze czas — nawet jeśli zerowy. To może wprowadzać zamieszanie: na przykład przy porównywaniu dat program może brać pod uwagę też czas i dostaniesz nieoczekiwane wyniki.

To samo w drugą stronę: jeśli pracujesz tylko z czasem (np. grafik pracy od 08:00 do 17:00), i tak musiałeś "wymyślić" jakąś datę, chociaż w ogóle nie była potrzebna.

Teraz w .NET są specjalne typy DateOnly i TimeOnly, które rozwiązują ten bałagan.

Nowe przydatne typy DateOnly i TimeOnly

  • DateOnly — tylko data kalendarzowa, bez godziny i bez informacji o strefie czasowej.
  • TimeOnly — tylko godzina w ciągu dnia, bez roku, miesiąca, dnia i oczywiście bez strefy czasowej.

Tabela porównawcza typów czasu

Typ Data Czas Strefa czasowa Do czego używać?
DateTime
✅ ✅ 🚫 Prawie do wszystkiego (ale nie zawsze wygodne i bezpieczne)
DateTimeOffset
✅ ✅ ✅ Kiedy potrzebny jest moment w czasie i strefa czasowa
DateOnly
✅ 🚫 🚫 Urodziny, daty bez czasu
TimeOnly
🚫 ✅ 🚫 Godziny pracy, grafiki, przedziały w ciągu dnia

2. Praca z DateOnly

Deklaracja i tworzenie

Stworzyć obiekt DateOnly — jak zacząć nowy nawyk: prosto i szybko! Na przykład:

// Rok, miesiąc, dzień
DateOnly birthday = new DateOnly(1985, 4, 20);
Tworzenie daty urodzin przy użyciu DateOnly

Możesz użyć DateOnly.FromDateTime, jeśli już masz obiekt DateTime:

DateTime now = DateTime.Now;
DateOnly today = DateOnly.FromDateTime(now);
// teraz today zawiera tylko datę, czas jest odrzucony

Podstawowe właściwości i metody

  • Year, Month, Day — tak samo jak w DateTime.
  • .ToString() — formatuje datę, możesz podać własny format.
Console.WriteLine($"Data urodzenia: {birthday.Year} rok, {birthday.Month} miesiąc, {birthday.Day} dzień.");

Console.WriteLine(today.ToString("dd.MM.yyyy")); // Na przykład, 30.07.2024

Arytmetyka dat

Możesz łatwo dodawać dni/miesiące/lata:

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

Spróbuj w swoim głównym projekcie zamienić pola typu DateTime, które przechowują tylko datę, na DateOnly — będziesz o krok bliżej do nowoczesnego .NET!

Porównywanie dat

Działa porównywanie przez <, >, ==:

if (birthday < today)
    Console.WriteLine("Urodziny już były w tym roku albo dawno :)");

Nie będzie już błędów przez zbędne milisekundy i minuty.

Pobieranie dzisiejszej daty

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

3. Praca z TimeOnly

Teraz zajmiemy się czasem bez daty — bo który programista nie miał do czynienia z grafikami lunchów?

Tworzenie TimeOnly

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

Możemy pobrać tylko godziny, minuty, sekundy:

Console.WriteLine($"Dzień pracy: od {startWork.Hour}:{startWork.Minute:D2} do {endWork.Hour}:{endWork.Minute:D2}");

Pobierz czas z DateTime

DateTime now = DateTime.Now;
TimeOnly currentTime = TimeOnly.FromDateTime(now);
Console.WriteLine($"Teraz {currentTime}");

Arytmetyka czasu

TimeOnly breakStart = startWork.AddHours(4); // przerwa po 4 godzinach, czyli o 13:00
TimeOnly breakEnd = breakStart.AddMinutes(30); // 30 minut lunchu

Porównania i sprawdzenia

if (currentTime >= startWork && currentTime <= endWork)
    Console.WriteLine("Czas pracować :)");
else
    Console.WriteLine("Można odpocząć.");

4. Współpraca z innymi typami

Konwersja między DateOnly, TimeOnly i DateTime

Czasem trzeba znowu dostać DateTime (np. do przechowywania w starej bazie albo dla kompatybilności):


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

I odwrotnie:

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

Ważne cechy i typowe błędy

  • Jeśli spróbujesz sparsować tylko datę albo tylko czas przez stare metody jak DateTime.Parse(), najprawdopodobniej dostaniesz błąd albo nie to, czego oczekiwałeś. Do takich przypadków są specjalne metody: używaj DateOnly.Parse() i TimeOnly.Parse() — one wiedzą, jak radzić sobie z "uciętymi" wartościami.
  • Ważne: DateOnly i TimeOnly nie mają żadnego pojęcia o strefach czasowych. To po prostu data albo po prostu czas — bez powiązania ze strefą. Jeśli musisz brać pod uwagę strefy, przechowuj tę informację osobno.
2
Zadanie
C# SELF, poziom 15, lekcja 1
Niedostępne
Praca z `DateOnly`
Praca z `DateOnly`
2
Zadanie
C# SELF, poziom 15, lekcja 1
Niedostępne
Praca z `TimeOnly`
Praca z `TimeOnly`
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION