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 не имеют ни малейшего представления о временных зонах. Это просто дата или просто время — без связи с часовым поясом. Если нужно учитывать зоны, храните эту информацию отдельно.
2
Задача
C# SELF, 15 уровень, 1 лекция
Недоступна
Работа с DateOnly
Работа с DateOnly
2
Задача
C# SELF, 15 уровень, 1 лекция
Недоступна
Работа с TimeOnly
Работа с TimeOnly
Комментарии (1)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Александр Уровень 18
12 ноября 2025
вот это реально годные типы данных. почему сразу не допетрили что они нужны..