Рубріки: Теория

Работа с датой и временем в C#: только самое важное

Андрій Денисенко

Для представления даты и времени в C# используется класс DateTime. Из этой статьи вы узнаете как форматировать DateTime с помощью C# и как преобразовывать строки в объекты DateTime. Мы также опишем логику работу с форматами дат в разных регионах (культурах), а также с пользовательскими форматами времени (c# format datetime).

Содержание:

1. Форматирование даты и времени в C#
1.1 Стандартные форматы
1.2 Пользовательские форматы
1.3 Даты
1.4 Время
2. Преобразование строк в объекты DateTime
3. Заключение

Форматирование даты и времени в C#

Для форматирования даты и времени в C# используются стандартные и пользовательские описатели формата. Стандартные описатели позволяют применять готовые форматы, а пользовательские дают возможность форматировать дату и время так, как это нужно для конкретной цели.

Стандартные форматы

Стандартные описатели дают задать формат даты/времени одной буквой. По умолчанию для форматирования применяется культура, установленная в разделе панели управления «Язык и региональные стандарты». Ниже в таблице приведены примеры применения стандартного форматирования.

Описатель формата Описание Пример
“d” Краткая дата. 30.09.2021
“D” Полная дата. 30 сентября 2021 г.
“f” Полная дата и время (с кратким временем). 30 сентября 2021 г. 9:34
“F” Полная дата и время (с полным временем). 30 сентября 2021 г. 9:34:22
“g” Общая дата (с кратким временем). 30.09.2021 9:34
“G” Общая дата (с полным временем). 30.09.2021 9:34:22
“M”, “m” Дни месяца. 30 сентября

 

30 сентября

“O”, “o” Обратное преобразование даты и времени. 2021-09-30T09:34:22.8066025+03:00

 

2021-09-30T09:34:22.8066025+03:00

“R”, “r” Шаблон RFC1123. Thu, 30 Sep 2021 09:34:22 GMT

 

Thu, 30 Sep 2021 09:34:22 GMT

“s” Сортируемый шаблон времени и даты. 2021-09-30T09:34:22
“t” Краткое время. 9:34
“T” Полное время. 9:34:22
“u” Универсальный сортируемый шаблон времени и даты. 2021-09-30 09:34:22Z
“U” Универсальное полное время. 30 сентября 2021 г. 6:34:22
“Y”, “y” Месяц года. Сентябрь 2021

 

Сентябрь 2021

Другой символ Неизвестный описатель. Выбрасывает исключительную ситуацию FormatException.

Эти описатели применяются в методе ToString() объекта DateTime. Приведенный ниже код позволяет получить результаты форматирования, показанные в таблице.

using System;

namespace DateTimeFormatting
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime dt = DateTime.Now;
            Console.WriteLine(dt.ToString("d"));
            Console.WriteLine(dt.ToString("D"));
            Console.WriteLine(dt.ToString("f"));
            Console.WriteLine(dt.ToString("F"));
            Console.WriteLine(dt.ToString("g"));
            Console.WriteLine(dt.ToString("G"));
            Console.WriteLine(dt.ToString("M"));
            Console.WriteLine(dt.ToString("m"));
            Console.WriteLine(dt.ToString("O"));
            Console.WriteLine(dt.ToString("o"));
            Console.WriteLine(dt.ToString("R"));
            Console.WriteLine(dt.ToString("r"));
            Console.WriteLine(dt.ToString("s"));
            Console.WriteLine(dt.ToString("t"));
            Console.WriteLine(dt.ToString("T"));
            Console.WriteLine(dt.ToString("u"));
            Console.WriteLine(dt.ToString("U"));
            Console.WriteLine(dt.ToString("Y"));
            Console.WriteLine(dt.ToString("y"));
        }
    }
}

В результате получим следующий вывод, если в панели управления выбраны настройки для русского языка.

Стандартные описатели являются псевдонимами для строк пользовательского формата. В зависимости от выбранной культуры строки пользовательского формата могут меняться, но псевдоним остается тем же. Например, без учета региональных параметров используется шаблон даты «мм/дд/гггг», а в таблице выше применен шаблон «дд.мм.гггг».

При преобразовании даты в строку можно указать культуру (регион), с учетом которой требуется ее отформатировать:

namespace DateTimeFormatting
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime dt = DateTime.Now;
            CultureInfo culture = new CultureInfo("en-us");
            Console.WriteLine(dt.ToString("d", culture));
            Console.WriteLine(dt.ToString("D", culture));
            Console.WriteLine(dt.ToString("f", culture));
            Console.WriteLine(dt.ToString("F", culture));
            Console.WriteLine(dt.ToString("g", culture));
            Console.WriteLine(dt.ToString("G", culture));
            Console.WriteLine(dt.ToString("M", culture));
            Console.WriteLine(dt.ToString("m", culture));
            Console.WriteLine(dt.ToString("O", culture));
            Console.WriteLine(dt.ToString("o", culture));
            Console.WriteLine(dt.ToString("R", culture));
            Console.WriteLine(dt.ToString("r", culture));
            Console.WriteLine(dt.ToString("s", culture));
            Console.WriteLine(dt.ToString("t", culture));
            Console.WriteLine(dt.ToString("T", culture));
            Console.WriteLine(dt.ToString("u", culture));
            Console.WriteLine(dt.ToString("U", culture));
            Console.WriteLine(dt.ToString("Y", culture));
            Console.WriteLine(dt.ToString("y", culture));
        }
    }
}

В этом коде применена культура «en-us», и вывод будет таким:

Пользовательские форматы

Пользовательские описатели даты и времени дают больше свободы в форматировании. Ниже в таблице приведен полный список этих описателей.

Описатель формата Описание
“d” День месяца, от 1 до 31.
“dd” День месяца с ведущим нулем, от 01 до 31.
“ddd” День недели (сокращенное название).
“dddd” День недели (полное название).
“f” – “fffffff” От десятых до десятимиллионных долей секунды.
“F” – “FFFFFFF” От десятых до десятимиллионных долей секунды при значении, отличном от нуля.
“g”, “gg” Период или эра.
“h” Час в 12-часовом формате от 1 до 12.
“hh” Час в 12-часовом формате от 01 до 12.
“H” Час в 24-часовом формате от 0 до 23.
“HH” Час в 24-часовом формате от 00 до 23.
“K” Часовой пояс.
“m” Минуты, от 0 до 59.
“mm” Минуты с ведущим нулем, от 00 до 59.
“M” Месяц, от 1 до 12.
“MM” Месяц с ведущим нулем, от 01 до 12.
“MMM” Месяц (сокращенное название).
“MMMM” Месяц (полное название).
“s” Секунды, от 0 до 59.
“ss” Секунды с ведущим нулем, от 00 до 59.
“t” Первый символ указателя AM/PM (до полудня/после полудня).
“tt” Указатель AM/PM (до полудня/после полудня).
“y” Год, от 0 до 99.
“yy” Год с ведущим нулем, от 00 до 99.
“yyy” Год (минимум три цифры).
“yyyy” Год (четыре цифры).
“yyyyy” Год (пять цифр).
“z” Сдвиг в часах от времени в формате UTC (универсального времени), без ведущих нулей.
“zz” Сдвиг в часах от времени в формате UTC (универсального времени) с ведущими нулями для значений из одной цифры.
“zzz” Сдвиг в часах и минутах от времени в формате UTC (универсального времени).
“:” Разделитель для времени.
“/” Разделитель для даты.
string Буквенный разделитель строк.
% Задает следующий символ в качестве настраиваемого описателя формата.
\ Escape-символ.
Любой другой знак Символ копируется в строку даты без изменений.

Дальше рассмотрим на примерах как применяется пользовательское форматирование.

Дата

В следующем примере кода мы выводим дату в кратком формате двумя способами. В первом выводе мы используем стандартный описатель и указываем культуру. Во втором мы конкретно определяем как будет выводиться каждый элемент даты.

using System;
using System.Globalization;

namespace DateTimeFormatting
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime dt = new DateTime(2021, 9, 30, 10, 14, 42);
            CultureInfo culture = new CultureInfo("ru-ru");
            Console.WriteLine(dt.ToString("d", culture));
            Console.WriteLine(dt.ToString("dd.MM.yyyy"));
        }
    }
}

Результаты вывода будут одинаковы:

Для вывода даты в полном формате используется описатель “D”. Чтобы получить тот же результат с применением пользовательского форматирования, укажем дату в формате “dd MMMM yyyy г.”.

Как видно из таблицы пользовательских описателей, любые символы, не являющиеся описателями, передаются в итоговую строку без изменений, поэтому в конце строки формата добавляем ” г.”.

Заменим в примере кода строки вывода на следующие:

Console.WriteLine(dt.ToString("D", culture));
Console.WriteLine(dt.ToString("dd MMMM yyyy г."));

Получим:

Время

Время можно выводить в 12-часовом и в 24-часовом формате. При этом, часы, минуты и секунды могут быть представлены как с ведущим нулем, так и без него.

В следующем примере кода показано как это можно сделать.

using System;
using System.Globalization;

namespace DateTimeFormatting
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime dtam = new DateTime(2021, 9, 30, 08, 15, 00);
            
            Console.WriteLine("До полудня");
            Console.WriteLine("12-часовой формат: " + dtam.ToString("hh:mm:ss tt", CultureInfo.InvariantCulture));
            Console.WriteLine("24-часовой формат: " + dtam.ToString("HH:mm:ss"));
            
            Console.WriteLine();
            
            DateTime dtpm = new DateTime(2021, 9, 30, 17, 15, 00);
            
            Console.WriteLine("После полудня");         
            Console.WriteLine("12-часовой формат: " + dtpm.ToString("hh:mm:ss tt", CultureInfo.InvariantCulture));
            Console.WriteLine("24-часовой формат: " + dtpm.ToString("HH:mm:ss"));
        }
    }
}

Сначала объявляем DateTime со временем до полудня и выводим в обоих форматах, затем таким же образом форматируем DateTime после полудня.

Обратите внимание: чтобы вывести время в 12-часовом формате с описателем «tt», мы указываем инвариантную культуру, потому что в ней используется этот описатель. В культуре для русского языка такой описатель не используется. Для наглядности добавим в приведенный выше код пару строк:

…
Console.WriteLine("До полудня");
Console.WriteLine("12-часовой(ru-RU): " + dtam.ToString("hh:mm:ss tt", CultureInfo.CreateSpecificCulture("ru-RU")));
…
Console.WriteLine("После полудня");         
            Console.WriteLine("12-часовой(ru-RU): " + dtpm.ToString("hh:mm:ss tt", CultureInfo.CreateSpecificCulture("ru-RU")));
…

Теперь формат DateTime будет выглядеть так:

Преобразование строк в объекты DateTime

Строку с датой и временем можно преобразовать в объект DateTime с помощью методов Parse(), ParseExact(), TryParse() и TryParseExact(). Для этого строка должна быть отформатирована в соответствии с указанными параметрами.

Рассмотрим применение метода Parse():

using System;
using System.Globalization;

namespace DateTimeFormatting
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime dtDate;
            string strDate = "01.11.2021 00:00:00";
            
            string strSuccess = "'{0}' -> {1}";
            string strFailure = "Ошибка: '{0}'.";

            try {
              dtDate = DateTime.Parse(strDate, new CultureInfo("ru-RU", false));
              Console.WriteLine(strSuccess, strDate, dtDate);
            }
            catch (FormatException) {
              Console.WriteLine(strFailure, strDate);
            }
            
            strDate = "01.11.2021 00.00.00";

            try {
              dtDate = DateTime.Parse(strDate);
              Console.WriteLine(strSuccess, strDate, dtDate);
            }
            catch (FormatException) {
              Console.WriteLine(strFailure, strDate);
            }
            
            strDate = "10.30.2021 23:59:59";

            try {
              dtDate = DateTime.Parse(strDate, new CultureInfo("ru-RU", false));
              Console.WriteLine(strSuccess, strDate, dtDate);
            }
            catch (FormatException) {
              Console.WriteLine(strFailure, strDate);
            }
            
            try {
              dtDate = DateTime.Parse(strDate, new CultureInfo("en-US", false));
              Console.WriteLine(strSuccess, strDate, dtDate);
            }
            catch (FormatException) {
              Console.WriteLine(strFailure, strDate);
            }
        }
    }
}

В результате получим следующие результаты преобразования строки в объект DateTime:

Сначала мы объявляем строку с датой и временем “01.11.2021 00:00:00”. Она успешно преобразуется при использовании культуры “ru-RU”.

Строка “01.11.2021 00.00.00”, где часы, минуты и секунды разделены точками, вызывает исключительную ситуацию, потому что эти символы недопустимы как разделители элементов времени.

Далее мы анализируем дату “10.30.2021 23:59:59”, где месяц указан в первой позиции, а день — во второй. Эта строка вызовет исключительную ситуацию для культуры “ru-RU”, но будет успешно преобразована в дату для культуры “en-US”, где принята именно такая последовательность.

Метод ParseExact() позволяет преобразовывать строки в дату и время с применением стандартных форматов DateTime, а также пользовательских форматов DateTime.

using System;
using System.Globalization;

namespace DateTimeFormatting
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime dtDate;
            string strDate;
            string format;
            CultureInfo provider = new CultureInfo("ru-RU", false);
            
            string strSuccess = "'{0}' -> {1}";
            string strFailure = "Ошибка: '{0}'.";
            
    // Стандартный формат DateTime
            format = "d";
            
            strDate = "01.11.2021";
            
            try {
              dtDate = DateTime.ParseExact(strDate, format, provider);
              Console.WriteLine(strSuccess, strDate, dtDate);
            }
            catch (FormatException) {
              Console.WriteLine(strFailure, strDate);
            }
            
            strDate = "1.11.2021";

            try {
              dtDate = DateTime.ParseExact(strDate, format, provider);
              Console.WriteLine(strSuccess, strDate, dtDate);
            }
            catch (FormatException) {
              Console.WriteLine(strFailure, strDate);
            }

            // Пользовательский формат DateTime
            format = "d.MM.yyyy";
            try {
              dtDate = DateTime.ParseExact(strDate, format, provider);
              Console.WriteLine(strSuccess, strDate, dtDate);
            }
            catch (FormatException) {
              Console.WriteLine(strFailure, strDate);
            }
        }
    }
}

Вывод:

Вначале используем дату: “01.11.2021” и получаем успешное преобразование для культуры “ru-RU”.

Затем убираем из строкового представления даты ведущий ноль и получаем исключительную ситуацию, потому что указан недопустимый формат DateTime, который не соответствует описателю “d”.

Если же мы изменим строку форматирования даты и времени, указав, что ведущие нули не нужны, то дата “1.11.2021” будет преобразована в объект DateTime успешно.

Методы Parse() и ParseExact() выбрасывают исключительную ситуацию, если переданная строка не является допустимым представлением даты и времени. Поэтому рекомендуется вместо них использовать методы TryParse() и TryParseExact(). Последние возвращают булевское значение, которое истинно при успешном преобразовании и ложно, если формат не соответствует заданным параметрам. Результат преобразования возвращается в последнем аргументе.

using System;
using System.Globalization;

namespace DateTimeFormatting
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime dtDate;
            string strDate;
            CultureInfo provider = CultureInfo.CreateSpecificCulture("ru-RU");
            DateTimeStyles styles = DateTimeStyles.None;
            
            string strSuccess = "'{0}' -> {1}";
            string strFailure = "Ошибка: '{0}'.";
            
            strDate = "30.10.2021";
            
            if(DateTime.TryParse(strDate, provider, styles, out dtDate)) {
              Console.WriteLine(strSuccess, strDate, dtDate);
            }
            else {
              Console.WriteLine(strFailure, strDate);
            }
            
            strDate = "10.30.2021";

            if(DateTime.TryParse(strDate, provider, styles, out dtDate)) {
              Console.WriteLine(strSuccess, strDate, dtDate);
            }
            else {
              Console.WriteLine(strFailure, strDate);
            }
        }
    }
}

Для культуры “ru-RU” первый формат будет допустимым, а второй — нет:

Метод TryParse может возвращать False, если текущие DateSeparator и TimeSeparator в региональных параметрах совпадают.

Заключение

В этой статье мы ознакомились с основами работы с форматами DateTime, рассмотрели стандартные и пользовательские описатели и способы преобразования строк в дату и время с применением форматов DateTime.

Методы, о которых мы узнали, имеют и другие перегрузки, кроме использованных в наших примерах кода.

Обратите внимание, что на форматирование влияет текущий объект DateTimeFormatInfo, который по умолчанию определяется в региональных параметрах в Панели управления.

Подробнее о форматировании DateTime можно узнать на сайте документации Microsoft .NET.

Останні статті

Обучение Power BI – какие онлайн курсы аналитики выбрать

Сегодня мы поговорим о том, как выбрать лучшие курсы Power BI в Украине, особенно для…

13.01.2024

Work.ua назвал самые конкурентные вакансии в IТ за 2023 год

В 2023 году во всех крупнейших регионах конкуренция за вакансию выросла на 5–12%. Не исключением…

08.12.2023

Украинская IT-рекрутерка создала бесплатный трекер поиска работы

Unicorn Hunter/Talent Manager Лина Калиш создала бесплатный трекер поиска работы в Notion, систематизирующий все этапы…

07.12.2023

Mate academy отправит работников в 10-дневный оплачиваемый отпуск

Edtech-стартап Mate academy принял решение отправить своих работников в десятидневный отпуск – с 25 декабря…

07.12.2023

Переписки, фото, история браузера: киевский программист зарабатывал на шпионаже

Служба безопасности Украины задержала в Киеве 46-летнего программиста, который за деньги устанавливал шпионские программы и…

07.12.2023

Как вырасти до сеньйора? Девелопер создал популярную подборку на Github

IT-специалист Джордан Катлер создал и выложил на Github подборку разнообразных ресурсов, которые помогут достичь уровня…

07.12.2023