Підрозділ 12.4
Структура TimeSpan
12.4. Структура TimeSpan Якщо DateTime відповідає на питання « коли? » конкретна точка в часі , то TimeSpan відповідає на питання « скільки? » тривалість інтервалу . Наприклад: скільки тривала госпіталізація? Ч
12.4. Структура TimeSpan
Якщо DateTime відповідає на питання «коли?» (конкретна точка в часі), то TimeSpan відповідає на питання «скільки?» (тривалість інтервалу). Наприклад: скільки тривала госпіталізація? Через скільки годин призначити повторний прийом? Яка різниця між часом надходження пацієнта і виконанням аналізу?
TimeSpan — це структура (value type) з простору імен System, що внутрішньо зберігає одне long-значення — кількість тіків (тих самих 100-наносекундних тіків, що й DateTime). Тому TimeSpan може представляти тривалість від мінусових тисячоліть до позитивних — або, точніше, від TimeSpan.MinValue (близько -10 мільйонів днів) до TimeSpan.MaxValue (близько +10 мільйонів днів).

TimeSpan vs DateTime vs TimeOnly
Ці три типи часто плутають. Принципова різниця:
| Тип | Що представляє | Діапазон | Може бути від'ємним? |
|---|---|---|---|
DateTime |
Момент в часі | 01.01.0001 – 31.12.9999 | Ні |
TimeOnly |
Час на годиннику | 00:00:00 – 23:59:59 | Ні |
TimeSpan |
Тривалість | ±10 млн днів | Так |
TimeSpan є результатом різниці двох DateTime: dt1 - dt2 = TimeSpan. Але він може також виражати довільну тривалість: «через 72 години», «за 21 день», «відняти 30 хвилин».
Створення TimeSpan
Є кілька способів створити TimeSpan:
// 1. Конструктори
var ts1 = new TimeSpan(2, 30, 0); // 2 год 30 хв 0 сек = 02:30:00
var ts2 = new TimeSpan(7, 0, 0, 0); // 7 днів
var ts3 = new TimeSpan(0, 36, 0, 0); // 36 годин (= 1 день 12 год)
var ts4 = new TimeSpan(1, 14, 30, 20, 500); // 1 дн 14 год 30 хв 20 сек 500 мс
// 2. Статичні методи From*
TimeSpan week = TimeSpan.FromDays(7); // 7 днів (7.5 = 7 днів 12 год)
TimeSpan day = TimeSpan.FromHours(24); // 1 день
TimeSpan hour = TimeSpan.FromMinutes(60); // 1 година
TimeSpan minute = TimeSpan.FromSeconds(60); // 1 хвилина
TimeSpan zero = TimeSpan.Zero; // 00:00:00
// 3. З тіків
TimeSpan fromTicks = new TimeSpan(36_000_000_000L); // 1 година = 10^7 тіків/сек * 3600
// 4. Різниця двох DateTime (найчастіший спосіб)
DateTime admission = new DateTime(2026, 6, 1, 9, 0, 0);
DateTime discharge = new DateTime(2026, 6, 8, 14, 30, 0);
TimeSpan stay = discharge - admission; // 7 днів 5 год 30 хвВластивості TimeSpan: компоненти та Total*
Клас TimeSpan має два набори властивостей, які легко переплутати:
Компонентні властивості — цілочисельна частина відповідного компонента:
TimeSpan ts = new TimeSpan(1, 14, 30, 20); // 1 день 14 год 30 хв 20 сек
Console.WriteLine(ts.Days); // 1 — тільки дні
Console.WriteLine(ts.Hours); // 14 — тільки години (0-23)
Console.WriteLine(ts.Minutes); // 30 — тільки хвилини (0-59)
Console.WriteLine(ts.Seconds); // 20 — тільки секунди (0-59)
Console.WriteLine(ts.Milliseconds); // 0Total-властивості — загальна тривалість, виражена у відповідній одиниці як double:
Console.WriteLine(ts.TotalDays); // 1.604... — усі дні включно із годинами
Console.WriteLine(ts.TotalHours); // 38.50... — усього годин (1*24 + 14 = 38)
Console.WriteLine(ts.TotalMinutes); // 2310.333 — усього хвилин
Console.WriteLine(ts.TotalSeconds); // 138620.0 — усього секундПравило: для відображення («госпіталізація тривала 7 днів і 5 годин») — використовуйте компонентні властивості Days + Hours; для порівняння або арифметики («чи пройшло більше 72 годин?») — TotalHours:
if (stay.TotalHours > 72)
Console.WriteLine("Пацієнт перебуває понад 3 дні");Арифметика TimeSpan
TimeSpan підтримує такі операції:
TimeSpan t1 = TimeSpan.FromDays(3);
TimeSpan t2 = TimeSpan.FromHours(12);
TimeSpan sum = t1 + t2; // 3 дні 12 годин
TimeSpan diff = t1 - t2; // 2 дні 12 годин
TimeSpan neg = -t1; // -3 дні (від'ємний)
TimeSpan abs = t1.Duration(); // завжди невід'ємний (як Math.Abs)
// DateTime + TimeSpan → DateTime
DateTime admission = new DateTime(2026, 6, 1, 9, 0, 0);
DateTime scheduledD = admission + TimeSpan.FromDays(21); // плановий повторний огляд
DateTime reminderT = scheduledD - TimeSpan.FromHours(24); // нагадування за добу
// DateTime - DateTime → TimeSpan
TimeSpan elapsed = DateTime.Now - admission; // скільки часу пройшлоВід'ємний TimeSpan виникає, коли перша дата пізніша за другу: dt1 - dt2 де dt1 < dt2. Для отримання абсолютного значення — метод Duration() або статичний TimeSpan.FromTicks(Math.Abs(ts.Ticks)).
Властивість Duration
ts.Duration() завжди повертає невід'ємний TimeSpan — аналог Math.Abs() для тривалості:
DateTime d1 = new DateTime(2026, 6, 1);
DateTime d2 = new DateTime(2026, 6, 10);
TimeSpan diff1 = d2 - d1; // +9 днів
TimeSpan diff2 = d1 - d2; // -9 днів
Console.WriteLine(diff2.Duration()); // 9.00:00:00 (без знаку)Це зручно, коли порядок дат невідомий заздалегідь — наприклад, при обчисленні відстані між двома датами в медичній статистиці без знання, яка з них раніша.
Форматування TimeSpan
TimeSpan можна форматувати через ToString() або $"...":
TimeSpan stay = new TimeSpan(7, 5, 30, 0);
Console.WriteLine(stay); // 7.05:30:00 — формат за замовчуванням
Console.WriteLine(stay.ToString(@"d\d\ hh\:mm")); // 7d 05:30
Console.WriteLine($"{(int)stay.TotalDays} днів {stay.Hours} годин"); // 7 днів 5 годинФормат за замовчуванням d.hh:mm:ss — 7.05:30:00 — де перша цифра є кількістю днів. Для виводу в людиночитному вигляді зазвичай будують рядок вручну через компонентні властивості.
Медична картка: тривалість госпіталізації — runnable приклад
Планування лікування та цикли — runnable приклад
Розрахунок дат повторних прийомів і перевірка відповідності розкладу: