JavaRush /Курси /C# SELF /Корисні типи: DateOnly і TimeOnly

Корисні типи: DateOnly і TimeOnly

C# SELF
Рівень 15 , Лекція 1
Відкрита

1. Вступ

Раніше у C# не існувало окремого типу лише для дати або лише для часу. Тож навіть якщо потрібно було зберігати тільки дату — наприклад, день народження, — доводилося використовувати DateTime і додавати «час за замовчуванням». Старий спосіб зберігання лише дати через DateTime:


DateTime birthday = new DateTime(1985, 4, 20); // 20 квітня 1985 року, 00:00:00

Такий підхід незручний. Ви хочете просто дату, а отримуєте ще й час — навіть якщо він нульовий. Це може заплутувати: наприклад, під час порівняння дат програма враховуватиме і час, і ви дістанете неочікувані результати.

Так само й навпаки: якщо ви працюєте лише з часом (наприклад, графік роботи з 08:00 до 17:00), усе одно доводилося «вигадувати» якусь дату, хоча вона зовсім не важлива.

Тепер у .NET є спеціальні типи DateOnly і TimeOnly, які усувають цю плутанину.

Нові корисні типи DateOnly і TimeOnly

  • DateOnly — лише календарна дата, без часу доби й без інформації про часовий пояс.
  • TimeOnly — лише час доби, без року, місяця, дня і, знову ж таки, без часового поясу.

Таблиця порівняння типів часу

Тип Дата Час Часовий пояс Для чого використовується?
DateTime
🚫 Підходить майже для всього (але не завжди зручно й безпечно)
DateTimeOffset
Коли потрібні і момент часу, і часовий пояс
DateOnly
🚫 🚫 Дні народження, дати без часу
TimeOnly
🚫 🚫 Години роботи, розклади, інтервали протягом дня

2. Робота з DateOnly

Оголошення і створення

Створити об’єкт DateOnly просто й швидко. Наприклад:

// Рік, місяць, день
DateOnly birthday = new DateOnly(1985, 4, 20);
Створення дати народження за допомогою DateOnly

Можна скористатися DateOnly.FromDateTime, якщо у вас уже є об’єкт DateTime:

DateTime now = DateTime.Now;
DateOnly today = DateOnly.FromDateTime(now);
// тепер today містить лише дату, час відкинуто

Основні властивості і методи

  • Year, Month, Day — звично, як у DateTime.
  • .ToString() — форматує дату; можна задати власний формат.
Console.WriteLine($"Дата народження: {birthday.Year} рік, {birthday.Month} місяць, {birthday.Day} число.");

Console.WriteLine(today.ToString("dd.MM.yyyy")); // Наприклад, 30.07.2024

Арифметика дат

Можна легко додавати дні/місяці/роки:

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

Спробуйте у своєму основному застосунку замінити поля типу DateTime, які зберігають лише дату, на DateOnly — так ви зробите крок до сучасного .NET!

Порівняння дат

Працює порівняння через <, >, ==:

if (birthday < today)
    Console.WriteLine("День народження вже був цього року або давно :)");

Помилок із зайвими мілісекундами й хвилинами вже не буде.

Отримання сьогоднішнього дня

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

3. Робота з TimeOnly

Тепер розглянемо час без дати — адже з розкладами обідів стикався кожен.

Створення TimeOnly

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

Можна отримати лише години, хвилини, секунди:

Console.WriteLine($"Робочий день: з {startWork.Hour}:{startWork.Minute:D2} до {endWork.Hour}:{endWork.Minute:D2}");

Отримати час із DateTime

DateTime now = DateTime.Now;
TimeOnly currentTime = TimeOnly.FromDateTime(now);
Console.WriteLine($"Зараз {currentTime}");

Арифметика часу

TimeOnly breakStart = startWork.AddHours(4); // перерва через 4 години, тобто о 13:00
TimeOnly breakEnd = breakStart.AddMinutes(30); // 30 хвилин обіду

Порівняння і перевірки

if (currentTime >= startWork && currentTime <= endWork)
    Console.WriteLine("Час працювати :)");
else
    Console.WriteLine("Можна відпочивати.");

4. Взаємодія з іншими типами

Перетворення між DateOnly, TimeOnly і DateTime

Іноді потрібно знову отримати DateTime (наприклад, для зберігання у старій базі даних або для сумісності):


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

І навпаки:

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

Важливі особливості і типові помилки

  • Якщо ви спробуєте розібрати лише дату або лише час за допомогою старих методів на кшталт DateTime.Parse(), найімовірніше, отримаєте помилку або не те, чого очікуєте. Для таких випадків є спеціальні методи: скористайтеся DateOnly.Parse() і TimeOnly.Parse() — вони знають, як працювати з «обрізаними» значеннями.
  • Важливо розуміти: DateOnly і TimeOnly не містять жодної інформації про часові пояси. Це просто дата або просто час — без зв’язку з часовим поясом. Якщо потрібно враховувати пояси, зберігайте цю інформацію окремо.
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ