Урок 10.4 — DateTime и TimeSpan
Время — важнейший ресурс. Научимся работать с датами, временем и интервалами в C#.
Даты и время окружают нас в каждой программе: дата регистрации пользователя, время отправки сообщения, deadline задачи, возраст, статистика за период. C# предоставляет мощные структуры DateTime и TimeSpan для работы с датами и временем. Научимся пользоваться ими профессионально.
DateTime — структура для даты и времени
DateTime — это структура (value type), представляющая один момент во времени: дату + время. Она содержит год, месяц, день, час, минуту, секунду и миллисекунды.
Создание DateTime:
// Текущая дата и время
DateTime now = DateTime.Now; // локальное время
DateTime utcNow = DateTime.UtcNow; // UTC (глобальное)
DateTime today = DateTime.Today; // сегодняшняя дата, время 00:00
// Конкретная дата и время
DateTime birthDay = new DateTime(2000, 5, 15); // 15 мая 2000, 00:00
DateTime exactTime = new DateTime(2026, 3, 14, 15, 30, 0); // 14 марта 2026, 15:30:00
// Из строки (парсинг)
DateTime parsed = DateTime.Parse("2026-01-15");
Console.WriteLine(now);
Console.WriteLine(utcNow);
Свойства DateTime:
DateTime dt = new DateTime(2026, 6, 23, 14, 45, 30);
Console.WriteLine(dt.Year); // 2026
Console.WriteLine(dt.Month); // 6
Console.WriteLine(dt.Day); // 23
Console.WriteLine(dt.Hour); // 14
Console.WriteLine(dt.Minute); // 45
Console.WriteLine(dt.Second); // 30
Console.WriteLine(dt.DayOfWeek); // Tuesday (день недели — Enum)
Console.WriteLine(dt.DayOfYear); // 174 (день года)
// День недели по-русски:
string[] ruDays = { "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота", "Воскресенье" };
Console.WriteLine(ruDays[(int)dt.DayOfWeek - 1]); // Вторник
Форматирование дат в строку
Метод ToString() с форматной строкой позволяет вывести дату в любом виде:
DateTime dt = new DateTime(2026, 6, 23, 14, 45, 30);
Console.WriteLine(dt.ToString("dd.MM.yyyy")); // 23.06.2026
Console.WriteLine(dt.ToString("yyyy-MM-dd")); // 2026-06-23
Console.WriteLine(dt.ToString("dd.MM.yyyy HH:mm")); // 23.06.2026 14:45
Console.WriteLine(dt.ToString("dd MMMM yyyy")); // 23 июня 2026
Console.WriteLine(dt.ToString("D")); // 23 июня 2026 г. (полная дата)
Console.WriteLine(dt.ToString("t")); // 14:45 (короткое время)
Console.WriteLine(dt.ToString("T")); // 14:45:30 (полное время)
Console.WriteLine(dt.ToString("F")); // 23 июня 2026 г. 14:45:30
Console.WriteLine(dt.ToString("dddd")); // вторник
// Интерполяция с форматированием:
Console.WriteLine($"Сегодня: {dt:dd.MM.yyyy}");
💡 Основные коды форматирования: dd — день (01-31), MM — месяц (01-12), yyyy — год (2026), HH — часы (00-23), mm — минуты, ss — секунды. Регистр важен: MM — месяц, mm — минуты.
Парсинг строки в дату
Часто дата приходит от пользователя или из файла в виде строки. Её нужно преобразовать в DateTime:
// Простой парсинг (формат определяется культурой)
DateTime dt1 = DateTime.Parse("23.06.2026");
DateTime dt2 = DateTime.Parse("2026-06-23");
// ParseExact — строгий формат:
DateTime dt3 = DateTime.ParseExact("23-06-2026", "dd-MM-yyyy", null);
// Безопасный парсинг — TryParseExact (рекомендуется для пользовательского ввода):
string input = "23.06.2026";
if (DateTime.TryParseExact(input, "dd.MM.yyyy", null, System.Globalization.DateTimeStyles.None, out DateTime result))
{
Console.WriteLine($"Дата: {result:yyyy-MM-dd}");
}
else
{
Console.WriteLine("Ошибка! Неверный формат даты.");
}
// Парсинг с учётом культуры:
var culture = new System.Globalization.CultureInfo("ru-RU");
DateTime dt4 = DateTime.Parse("23 июня 2026", culture);
⚠️ Всегда используй TryParseExact для пользовательского ввода. Parse и ParseExact выбрасывают исключение, если строка не соответствует формату. Никогда не доверяй вводу пользователя!
Арифметика дат — AddDays, AddMonths, AddYears
DateTime — неизменяемая структура. Методы Add создают новый объект DateTime, а не меняют существующий:
DateTime today = DateTime.Today; // 23.06.2026
// Добавление дней, месяцев, лет:
DateTime tomorrow = today.AddDays(1); // 24.06.2026
DateTime nextWeek = today.AddDays(7); // 30.06.2026
DateTime nextMonth = today.AddMonths(1); // 23.07.2026
DateTime nextYear = today.AddYears(1); // 23.06.2027
// Вычитание (отрицательное значение):
DateTime yesterday = today.AddDays(-1); // 22.06.2026
// Другие интервалы:
DateTime inTwoHours = DateTime.Now.AddHours(2);
DateTime in30Min = DateTime.Now.AddMinutes(30);
DateTime in5Sec = DateTime.Now.AddSeconds(5);
// Сравнение дат:
DateTime deadline = new DateTime(2026, 7, 1);
if (today < deadline)
Console.WriteLine("Дедлайн ещё не наступил");
else if (today == deadline)
Console.WriteLine("Сегодня дедлайн!");
else
Console.WriteLine("Дедлайн просрочен!");
TimeSpan — интервалы времени
TimeSpan представляет промежуток времени, а не конкретную дату. Это разница между двумя DateTime. Его можно создать, складывать, вычитать и использовать для измерения длительности.
// Создание TimeSpan
TimeSpan oneHour = new TimeSpan(1, 0, 0); // 1 час
TimeSpan oneHour30 = new TimeSpan(1, 30, 0); // 1 час 30 минут
TimeSpan twoDays = new TimeSpan(2, 0, 0, 0); // 2 дня
// Статические методы
TimeSpan fromDays = TimeSpan.FromDays(3.5); // 3 дня 12 часов
TimeSpan fromHours = TimeSpan.FromHours(48); // 48 часов = 2 дня
TimeSpan fromMinutes = TimeSpan.FromMinutes(90); // 90 минут = 1:30
// Свойства
Console.WriteLine(fromDays.Days); // 3
Console.WriteLine(fromDays.Hours); // 12
Console.WriteLine(fromDays.TotalHours); // 84 (общее количество часов)
Разница между датами — самый частый use case:
DateTime start = new DateTime(2026, 1, 1);
DateTime end = new DateTime(2026, 12, 31);
TimeSpan difference = end - start; // или end.Subtract(start)
Console.WriteLine(difference.Days); // 364 (дней между датами)
Console.WriteLine(difference.TotalDays); // 364.0
Console.WriteLine(difference.TotalHours); // 8736
Console.WriteLine(difference.TotalMinutes); // 524160
// Сколько осталось до Нового года:
DateTime newYear = new DateTime(2027, 1, 1);
TimeSpan until = newYear - DateTime.Now;
Console.WriteLine($"До Нового года: {until.Days} дней, {until.Hours} часов");
Сводный пример — возраст и дни рождения
using System;
class Program
{
static void Main()
{
Console.Write("Введите дату рождения (дд.мм.гггг): ");
string input = Console.ReadLine();
if (DateTime.TryParseExact(input, "dd.MM.yyyy", null,
System.Globalization.DateTimeStyles.None, out DateTime birthDate))
{
DateTime today = DateTime.Today;
int age = today.Year - birthDate.Year;
// Проверяем, был ли уже день рождения в этом году
if (today < birthDate.AddYears(age))
age--;
// Сколько дней до следующего дня рождения
DateTime nextBirthday = birthDate.AddYears(age + 1);
TimeSpan daysUntil = nextBirthday - today;
Console.WriteLine($"\nВаш возраст: {age} лет");
Console.WriteLine($"До следующего дня рождения: {daysUntil.Days} дней");
// День недели рождения
Console.WriteLine($"Вы родились в день: {birthDate:dddd}");
// Сколько всего прожито дней
TimeSpan totalDays = today - birthDate;
Console.WriteLine($"Прожито дней: {totalDays.Days}");
}
else
{
Console.WriteLine("Неверный формат даты! Используйте дд.мм.гггг");
}
}
}
Что важно запомнить
date2 - date1. Свойства: Days, Hours, TotalDays, TotalHours.Тест: 10.4: DateTime и TimeSpan
3 вопроса