1. Форматування дат
Якщо ви вважаєте, що виведення 2025-06-19T17:30:00 виглядає доволі стильно, спробуйте показати такий формат своїй бабусі або бухгалтеру. Ймовірно, вони попросять щось простіше: 19.06.2025 17:30. А ось англомовні колеги очікують 06/19/2025 5:30 PM. DevOps‑інженери й машини взагалі полюбляють 2025-06-19T17:30:00Z. Тобто один DateTime у памʼяті програми може бути представлений десятками форматів на екрані.
Зворотне завдання теж класика: користувач вводить дату в поле введення ("19.06.2025"), а ми маємо розпізнати її в об’єкт C# і не заплутатися, де день, а де місяць. Автоматизація, інтеграції, звіти — усюди потрібна правильна інтерпретація текстових дат.
Базове форматування
C# дозволяє перетворювати об’єкт дати й часу (DateTime, DateOnly, TimeOnly, DateTimeOffset) у рядок за допомогою методу .ToString():
DateTime now = DateTime.Now;
Console.WriteLine(now.ToString()); // Виведення: 19.06.2025 17:30:25
Якщо викликати .ToString() без параметрів — використовується формат, характерний для поточної культури системи (наприклад, німецька версія Windows покаже один формат, американська — інший).
Стандартні форматні рядки
Можна явно вказати формат виведення, використовуючи так звані стандартні форматні рядки для дати й часу:
| Формат | Опис | Приклад виведення |
|---|---|---|
|
Коротка дата | 19.06.2025 |
|
Повна дата | 19 червня 2025 р. |
|
Повна дата + короткий час | 19 червня 2025 р. 17:30 |
|
Повна дата + повний час | 19 червня 2025 р. 17:30:25 |
|
Коротка дата й час | 19.06.2025 17:30 |
|
Коротка дата + повний час | 19.06.2025 17:30:25 |
|
Короткий час | 17:30 |
|
Повний час | 17:30:25 |
|
Місяць і день | 19 червня |
|
Рік і місяць | Червень 2025 р. |
|
ISO 8601 («round-trip») | 2025-06-19T17:30:25.0000000 |
Console.WriteLine(now.ToString("d")); // 19.06.2025
Console.WriteLine(now.ToString("F")); // 19 червня 2025 р. 17:30:25
Console.WriteLine(now.ToString("O")); // 2025-06-19T17:30:25.0000000
Кастомні (користувацькі) шаблони
Якщо потрібні специфічніші формати, можна використовувати власні шаблони:
| Символ | Значення |
|---|---|
| yyyy | Рік, 4 цифри |
| yy | Рік, 2 цифри |
| MM | Місяць, 2 цифри |
| MMMM | Назва місяця |
| dd | День, 2 цифри |
| d | День, 1–2 цифри |
| HH | Година (24‑годинний формат) |
| mm | Хвилини |
| ss | Секунди |
| tt | AM/PM |
Console.WriteLine(now.ToString("yyyy-MM-dd HH:mm")); // 2025-06-19 17:30
Console.WriteLine(now.ToString("dd.MM.yyyy")); // 19.06.2025
Console.WriteLine(now.ToString("dddd, MMMM d")); // середа, червня 19
Культурні відмінності у форматуванні
Якщо хочете отримати результат у стилі іншої країни чи мови, використовуйте перевантаження ToString(string, IFormatProvider):
var enUS = new System.Globalization.CultureInfo("en-US");
Console.WriteLine(now.ToString("D", enUS)); // June 19, 2025
- Якщо чітко задати шаблон виду "MM/dd/yyyy", то незалежно від культури ви все одно отримаєте "06/19/2025".
- Але якщо використовуєте лише "d" або "D" — формат залежить від культури!
Важливі моменти під час роботи з форматуванням
Під час роботи з форматуванням дат важливо розуміти різницю між стандартними й користувацькими форматами. Стандартні формати (як-от "d", "F", "G") автоматично адаптуються до культури системи, що зручно для UI, але може створювати проблеми під час обміну даними між системами. Користувацькі формати дають повний контроль над виведенням, але вимагають детальнішого налаштування.
Особливу увагу варто приділити формату "O" (або "o") — це так званий «round-trip» формат, який гарантує, що дата, перетворена в рядок і назад, залишиться точно такою самою. Цей формат особливо важливий під час серіалізації даних або їх передавання через мережу.
2. Парсинг дат і часу: як із рядка отримати об’єкт
Найпростіший парсинг: DateTime.Parse
DateTime.Parse — метод, який намагається розпізнати рядок із датою з урахуванням культури системи.
string input = "19.06.2025";
DateTime parsed = DateTime.Parse(input);
Console.WriteLine(parsed); // 19.06.2025 00:00:00
Якщо рядок некоректний, метод згенерує виняток (ніхто не застрахований!).
Задавання культури
string input = "06/19/2025";
var enUS = new System.Globalization.CultureInfo("en-US");
DateTime dt = DateTime.Parse(input, enUS);
Console.WriteLine(dt); // 19.06.2025 00:00:00
Безпечний парсинг: TryParse
string input = "неправильна дата";
bool ok = DateTime.TryParse(input, out DateTime safeDate);
if (!ok)
Console.WriteLine("Помилка: не вдалося розпізнати дату!");
Точне задавання формату: ParseExact і TryParseExact
var culture = System.Globalization.CultureInfo.InvariantCulture;
string dateStr = "2025-06-19";
DateTime d = DateTime.ParseExact(dateStr, "yyyy-MM-dd", culture);
Console.WriteLine(d); // 19.06.2025 00:00:00
bool parsedOk = DateTime.TryParseExact(
"19.06.2025",
"dd.MM.yyyy",
System.Globalization.CultureInfo.InvariantCulture,
System.Globalization.DateTimeStyles.None,
out DateTime myDate);
Таблиця популярних форматів
| Рядок | Формат | Підсумковий об’єкт |
|---|---|---|
| "2025-06-19" | "yyyy-MM-dd" | 19 червня 2025 |
| "19.06.2025" | "dd.MM.yyyy" | 19 червня 2025 |
| "06/19/2025" | "MM/dd/yyyy" | 19 червня 2025 |
| "2025-06-19T14:15:16" | "s" | 19 червня 2025 14:15:16 |
Робота з DateTimeStyles
Під час парсингу можна додатково керувати поведінкою через параметр DateTimeStyles. Цей enum дає змогу налаштувати, як парсер має інтерпретувати вхідні дані. Наприклад, DateTimeStyles.AssumeUniversal змушує парсер вважати час UTC, якщо зміщення не вказано явно. DateTimeStyles.AllowWhiteSpaces дозволяє ігнорувати зайві пробіли в рядку. Ці налаштування особливо корисні під час роботи з даними із зовнішніх джерел, де формат може бути непередбачуваним.
3. Форматування та парсинг DateOnly, TimeOnly
Нові типи DateOnly і TimeOnly тепер часто використовують для зберігання дат/часу без зайвих деталей.
Форматування
DateOnly birthday = new DateOnly(2000, 6, 19);
Console.WriteLine(birthday.ToString("dd MMMM yyyy")); // 19 червня 2000
Парсинг
var d = DateOnly.ParseExact("19.06.2000", "dd.MM.yyyy");
Console.WriteLine(d.Day); // 19
Точно так само працюють і методи для TimeOnly (лише шаблони описують години/хвилини/секунди):
TimeOnly t = TimeOnly.ParseExact("23:59", "HH:mm");
Console.WriteLine(t.Hour); // 23
Переваги DateOnly і TimeOnly
Використання DateOnly і TimeOnly замість DateTime дає кілька важливих переваг. По‑перше, це семантична ясність — якщо вам потрібна лише дата без часу (наприклад, дата народження), DateOnly чітко показує цей намір. По‑друге, це допомагає уникнути проблем із часовими поясами, які можуть виникати під час роботи з DateTime. По‑третє, ці типи займають менше місця в памʼяті та базах даних.
Форматування та парсинг із урахуванням часових поясів
Якщо зберігаєте час з інформацією про зміщення — використовуйте DateTimeOffset. Це особливо важливо для міжнародних, розподілених систем. Усі методи форматування й парсингу аналогічні, тільки тепер можна також керувати зміщенням:
DateTimeOffset meeting = new DateTimeOffset(2025, 6, 19, 17, 30, 0, TimeSpan.FromHours(3));
Console.WriteLine(meeting.ToString("o")); // 2025-06-19T17:30:00.0000000+03:00
string input = "2025-06-19T17:30:00+03:00";
var parsedOffset = DateTimeOffset.Parse(input);
Console.WriteLine(parsedOffset.Offset); // 03:00:00
4. Практичні зауваження та типові помилки
Одна з пасток — плутати «день» і «місяць» під час парсингу міжнародних форматів. Наприклад, рядок "01/02/2025" у США — це 2 січня, а в більшості європейських країн — 1 лютого (сюрприз!).
Часто забувають і про вплив культури: якщо застосунок працює на сервері в Німеччині, а користувачі — з різних країн, формат дати з бази може інтерпретуватися інакше на кожному сервері.
Часта помилка — використання .ToString() без зазначення культури/формату для журналів (логів) і файлів обміну: результат може змінитися після міграції на іншу ОС або якщо застосунок працюватиме від імені різних користувачів Windows.
Рекомендації щодо роботи з датами
- Для внутрішнього зберігання й обміну даними завжди використовуйте інваріантну культуру (CultureInfo.InvariantCulture) або явно зазначені формати.
- Для UI застосовуйте культуру користувача або дайте змогу вибрати бажаний формат.
- Під час роботи з API та базами даних віддавайте перевагу формату ISO 8601, який є міжнародним стандартом.
- Завжди перевіряйте вхідні дані: існування дати, діапазон і коректність значень.
Робота з різними джерелами даних
Під час інтеграції із зовнішніми системами часто доводиться працювати з датами в різних форматах. Деякі системи можуть передавати дати у форматі Unix timestamp (кількість секунд від 1 січня 1970 року), інші — у вигляді рядків у національних форматах. Важливо заздалегідь домовитися про формат обміну даними й завжди перевіряти коректність парсингу.
Також варто памʼятати, що деякі формати можуть бути неоднозначними. Наприклад, "12/13/2025" однозначно інтерпретується як 13 грудня 2025 року, але "12/11/2025" може бути як 12 листопада, так і 11 грудня залежно від культури. У таких випадках краще використовувати однозначніші формати або явно вказувати культуру парсингу.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ