1. Основні завдання під час роботи з датою та часом
Робота з датами й часом часто викликає легке, а іноді й зовсім не легке, відчуття паніки навіть у досвідчених розробників. Треба порівнювати дати, обчислювати інтервали, додавати або віднімати дні, місяці, роки, рахувати вік, визначати день тижня — і ще багато всього.
Усе це — типові завдання для трекерів завдань і календарів, обліку абонементів чи підписок, фінансових розрахунків, статистичних звітів і, звісно, для задач на співбесідах (наприклад, «порахувати кількість робочих днів між двома датами»).
У C# і .NET для цього є вбудовані класи й методи. А головне — більшість обчислень виконується через обʼєктно-орієнтований, максимально безпечний і зрозумілий API.
2. Структура TimeSpan — вимірюємо інтервали часу
Усе починається зі структури TimeSpan. Це «шматочок» часу: наприклад, 5 днів, 3 години, 7 хвилин і 21 секунда.
Як створити TimeSpan?
Можна «відняти» дві дати або створити його явно:
// Різниця між двома датами завжди TimeSpan!
DateTime start = new DateTime(2025, 5, 1, 7, 0, 0);
DateTime end = new DateTime(2025, 5, 2, 11, 30, 0);
TimeSpan duration = end - start; // Повна магія!
Console.WriteLine(duration); // 1.04:30:00 (1 день, 4 години, 30 хвилин)
Можна створити TimeSpan явно через параметри конструктора:
TimeSpan span = new TimeSpan(2, 14, 18, 0); // 2 дні, 14 годин, 18 хвилин, 0 секунд
Console.WriteLine(span); // 2.14:18:00
Альтернативний спосіб — статичні методи, які зазвичай читабельніші:
TimeSpan fiveMinutes = TimeSpan.FromMinutes(5);
TimeSpan twoHours = TimeSpan.FromHours(2);
TimeSpan oneWeek = TimeSpan.FromDays(7);
Які властивості є у TimeSpan?
| Властивість | Опис |
|---|---|
|
Ціла кількість днів |
|
Годинна частина |
|
Хвилинна частина |
|
Секундна частина |
|
Час у днях (із дробовою частиною) |
|
Час у годинах (із дробовою частиною) |
|
Час у хвилинах (із дробовою частиною) |
|
Час у секундах (із дробовою частиною) |
Console.WriteLine($"Днів: {duration.Days}, усього годин: {duration.TotalHours}");
Як додати/відняти TimeSpan з дати?
DateTime now = DateTime.Now;
DateTime future = now.Add(duration); // Додали duration до now
DateTime past = now.Subtract(TimeSpan.FromDays(10)); // Мінус 10 днів
Console.WriteLine(future);
Console.WriteLine(past);
3. Калькулятор дат: обчислюємо різницю між датами
Навичка, яка стане в пригоді майже завжди. Наприклад, хтось хоче знати, скільки залишилося до відпустки, а хтось — коли закінчується безкоштовний період.
DateTime today = DateTime.Today;
DateTime vacation = new DateTime(2025, 8, 1);
TimeSpan untilVacation = vacation - today;
Console.WriteLine($"До відпустки залишилося {untilVacation.Days} днів!");
Зверніть увагу: якщо у відніманні беруть участь лише «дати» без часу (через DateTime.Date або DateTime.Today), то результат завжди ціле число днів. А якщо хоча б одна дата містить час, різниця — дробова.
int days = (vacation - today).TotalDays; // Помилка компіляції! TotalDays — double
Якщо потрібне ціле число — використовуйте .Days або перетворіть значення на цілий тип: (int)TotalDays.
4. Додавання і віднімання часу: методи AddDays, AddMonths, AddHours, ...
C# не вимагає ручного підрахунку днів у кожному місяці, високосних років і подібних дрібниць. Просто скористайтеся:
DateTime orderDate = new DateTime(2024, 4, 20);
DateTime deliveryDate = orderDate.AddDays(14); // Через 2 тижні
Console.WriteLine($"Товар буде доставлено {deliveryDate.ToShortDateString()}");
| Метод | Що додає (або віднімає при відʼємному числі) |
|---|---|
|
Дні (підтримка дробів, наприклад 1,5 дня) |
|
Місяці (автоматично враховує довжину місяця) |
|
Роки (з урахуванням високосних років) |
|
Години |
|
Хвилини |
|
Секунди |
DateTime birthday = new DateTime(2000, 2, 29);
DateTime nextYear = birthday.AddYears(1); // 2001-02-28 (а не 29-го, адже 2001 рік невисокосний)
Console.WriteLine(nextYear.ToShortDateString()); // 28.02.2001
Памʼятайте: усі методи повертають новий екземпляр дати, початкова дата не змінюється!
var dt = DateTime.Now;
dt.AddDays(5); // Це НЕ змінить dt!
dt = dt.AddDays(5); // Тепер зміниться
5. Допоміжні методи для обчислень
Визначення дня тижня
У більшості випадків можна використовувати властивість .DayOfWeek:
DateTime examDate = new DateTime(2025, 6, 19);
DayOfWeek day = examDate.DayOfWeek;
Console.WriteLine(day); // Wednesday
Можна перетворити на ціле число:
int number = (int)day; // Sunday == 0, Monday == 1, і так далі
Перевірка «сьогодні», «вчора», «завтра»
Найпростіші порівняння:
DateTime date = new DateTime(2025, 6, 18);
if (date.Date == DateTime.Today)
Console.WriteLine("Сьогодні!");
else if (date.Date == DateTime.Today.AddDays(-1))
Console.WriteLine("Вчора!");
else if (date.Date == DateTime.Today.AddDays(1))
Console.WriteLine("Завтра!");
Обчислення віку
Одна з найчастіших задач — коректно обчислити вік людини. Просте віднімання років не завжди працює правильно:
public static int CalculateAge(DateTime birthDate, DateTime currentDate)
{
int age = currentDate.Year - birthDate.Year;
// Якщо день народження ще не настав у цьому році
if (currentDate.Month < birthDate.Month ||
(currentDate.Month == birthDate.Month && currentDate.Day < birthDate.Day))
{
age--;
}
return age;
}
// Використання
DateTime birth = new DateTime(1990, 8, 15);
DateTime today = DateTime.Today;
int age = CalculateAge(birth, today);
Console.WriteLine($"Вік: {age} років");
Робота з робочими днями
Часто потрібно підрахувати кількість робочих днів між датами, виключаючи вихідні:
public static int CountWorkingDays(DateTime startDate, DateTime endDate)
{
int workingDays = 0;
DateTime current = startDate;
while (current <= endDate)
{
if (current.DayOfWeek != DayOfWeek.Saturday &&
current.DayOfWeek != DayOfWeek.Sunday)
{
workingDays++;
}
current = current.AddDays(1);
}
return workingDays;
}
6. Як повʼязані основні класи
graph TD A(DateTime) --віднімання--> B(TimeSpan) A2(DateTime) --AddDays, AddMonths--> A A --ToLocalTime/ToUniversalTime--> C(DateTimeOffset) D(DateOnly) --ToDateTime--> A E(TimeOnly) --ToTimeSpan--> B A --DayOfWeek, Day, Month, Year--> F(Числові властивості) B(TimeSpan) --TotalDays, TotalHours, ...-->G(Властивості тривалості)
7. Швидкий «довідник»: що робити, якщо…
| Завдання | Що використовувати | Приклад |
|---|---|---|
| Дізнатися різницю між датами | |
|
| Додати 2 тижні до дати | |
|
| Обчислити вік | Формула з і перевіркою місяця/дня |
Див. розділ вище |
| Отримати/встановити лише дату | |
|
| Отримати/встановити лише час | |
|
| Порівняти дати | Оператори , , , |
|
| Перевести до іншого часового поясу | |
|
| Дізнатися номер тижня у році | |
див. документацію |
| Дізнатися день тижня | |
|
| Порахувати робочі дні | Цикл із перевіркою |
Див. розділ вище |
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ