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 — лише час доби, без року, місяця, дня і, знову ж таки, без часового поясу.
Таблиця порівняння типів часу
| Тип | Дата | Час | Часовий пояс | Для чого використовується? |
|---|---|---|---|---|
|
✅ | ✅ | 🚫 | Підходить майже для всього (але не завжди зручно й безпечно) |
|
✅ | ✅ | ✅ | Коли потрібні і момент часу, і часовий пояс |
|
✅ | 🚫 | 🚫 | Дні народження, дати без часу |
|
🚫 | ✅ | 🚫 | Години роботи, розклади, інтервали протягом дня |
2. Робота з DateOnly
Оголошення і створення
Створити об’єкт DateOnly просто й швидко. Наприклад:
// Рік, місяць, день
DateOnly birthday = new DateOnly(1985, 4, 20);
Можна скористатися 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 не містять жодної інформації про часові пояси. Це просто дата або просто час — без зв’язку з часовим поясом. Якщо потрібно враховувати пояси, зберігайте цю інформацію окремо.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ