Урок №3. Дата и время в Qt5

  Дмитрий Бушуев  | 

  |

  Обновл. 16 Сен 2021  | 

 48412

 ǀ   14 

Qt5 имеет классы QDate, QTime и QDateTime для работы с датой и временем:

   QDate — это класс для работы с датой в григорианском календаре. У него есть методы для определения, сравнения и манипулирования датами.

   QTime — это класс для работы со временем. Он имеет методы для сравнения, определения и манипулирования временем.

   QDateTime — это класс, который объединяет QDate и QTime в одно целое.

На этом уроке мы рассмотрим почти всё, что связано с датой и временем в Qt5.

Дата и время

Объекты даты и времени могут быть инициализированы двумя основными способами: инициализация в конструкторе или создание пустых объектов и их последующее заполнение данными.

Результат выполнения программы:


В следующем примере мы выведем текущую дату и время на экран:

Результат выполнения программы:

Сравнение дат


Операторы сравнения могут использоваться для сравнения дат. Мы можем сравнивать их позиции в календаре:

Результат выполнения программы:

Операторы сравнения также можно использовать и с объектами классов QTime и QDateTime.

Определение високосного года

Високосный год — это год с одним дополнительным днем (29 февраля). Причиной, по которой добавляется этот день в календарь, является различие между астрономическим и календарным годом. Календарный год состоит из 365 дней. Астрономический год — это время, за которое Земля делает оборот вокруг Солнца (365.25 дня). Данная разница в 6 часов приводит к тому, что за 4 года мы получаем еще 1 дополнительные сутки. А для того, чтобы наш календарь всегда оставался актуальным, мы раз в четыре года прибавляем к февралю один дополнительный день, поэтому в григорианском календаре в високосный год февраль содержит 29 дней вместо обычных 28, а сам год состоит из 366 дней вместо обычных 365.

Статический метод QDate::isLeapYear() помогает определить, является ли год високосным. В следующей программе у нас есть список лет (с 2010 по 2016 год), среди которых мы вычисляем високосные:

Результат выполнения программы:

Стоит обратить внимание на то, что при инициализации списка лет, мы используем возможности стандарта языка C++11:

Скорее всего, вам потребуется дополнительно включить данную возможность в проекте. Для этого в проектный файл .pro добавьте следующее:

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


Qt5 имеет несколько встроенных форматов дат. Метод toString() класса QDate принимает формат даты в качестве параметра. По умолчанию Qt5 устанавливает формат даты как Qt::TextDate.

В следующем примере мы рассмотрим 8 предопределенных форматов отображения текущей даты:

Результат выполнения программы:


Дата может быть представлена и в других форматах. В Qt5 мы также можем создавать собственные форматы дат. Другая версия метода toString() принимает строку, в которой мы можем использовать различные спецификаторы. Например, спецификатор d обозначает отображение дня как числа без ведущего нуля. Спецификатор dd обозначает отображение дня как числа с ведущим нулем.

В следующей таблице перечислены доступные выражения, которые мы можем использовать для определения пользовательских форматов дат:

Выражение Вывод
d День в виде числа без ведущего нуля (от 1 до 31)
dd День в виде числа с ведущим нулем (от 01 до 31)
ddd Сокращенное название дня недели (например, от «Пн» до «Вс»). Используется метод QDate::shortDayName().
dddd Полное название дня недели (например, от «Понедельник» до «Воскресенье»). Используется метод QDate::longDayName().
M Месяц в виде числа без ведущего нуля (от 1 до 12)
MM Месяц в виде числа с ведущим нулем (от 01 до 12)
MMM Сокращенное название месяца (например, от «Янв» до «Дек»). Используется метод QDate::shortMonthName().
MMMM Полное название месяца (от «Январь» до «Декабрь»). Используется метод QDate::longMonthName().
yy Год в виде двузначного числа (от 00 до 99)
yyyy Год в виде четырехзначного числа. Если год отрицательный, то дополнительно добавляется знак минуса.

Рассмотрим 4 варианта пользовательских форматов времени:

Результат выполнения программы:

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

Qt5 содержит несколько предопределенных форматов для отображения времени. Стандартные спецификаторы формата времени идентичны тем, которые используются в форматах даты. В Qt5 формат времени по умолчанию отображается с помощью Qt::TextDate.

В качестве примера давайте рассмотрим 8 предопределенных форматов отображения текущего времени:

Результат выполнения программы:


С помощью спецификаторов мы можем создавать пользовательские форматы времени. В таблице ниже приведен список спецификаторов, доступных для использования:

Выражение Вывод
h Час без ведущего нуля (от 0 до 23 или от 1 до 12, если включен режим AM/PM )
hh Час с ведущим нулем (от 00 до 23 или от 01 до 12, если включен режим AM/PM)
H Час без ведущего нуля (от 0 до 23, даже если включен режим AM/PM)
HH Час с ведущим нулем (от 00 до 23, даже если включен режим AM/PM)
m Минуты без ведущего нуля (от 0 до 59)
mm Минуты с ведущим нулем (от 00 до 59)
s Секунды без ведущего нуля (от 0 до 59)
ss Секунды с ведущим нулем (от 00 до 59)
z Миллисекунды без ведущего нуля (от 0 до 999)
zzz Миллисекунды с ведущим нулем (от 000 до 999)
AP или A Используется отображение AM/PM. AP будет заменен на «AM» или «PM»
ap или a Используется отображение am/pm. ap будет заменен на «am» или «pm»
t Временная зона (например, «CEST» = «Центральноевропейское летнее время»)

Создадим 4 пользовательских формата времени:

Результат выполнения программы:

Работа с днями недели


Метод dayOfWeek() возвращает число, которое представляет день недели, где 1 — это понедельник, а 7 — воскресенье. В следующей программе мы отобразим текущий день недели в формате короткого и полного названия:

Результат выполнения программы:


Мы можем вычислить количество дней в конкретном месяце с помощью метода daysInMonth(), а количество дней в году с помощью метода daysInYear(). В следующем примере мы создадим пять объектов даты и вычислим количество дней в этих месяцах и в конкретном году:

Результат выполнения программы:

Проверка корректности даты

Для проверки корректности (валидности) даты используется метод isValid():

Результат выполнения программы:

Мы можем легко посчитать, сколько дней осталось до какой-нибудь конкретной даты с помощью метода daysTo() или какая дата наступит по истечении определенного количества дней с помощью метода addDays(). Допустим, мы хотим узнать, какая дата будет через 55 дней после 11 мая 2019 года, а также сколько дней осталось до Рождества:

Результат выполнения программы:

Класс QDateTime

Объект класса QDateTime содержит календарную дату и время. Он является комбинацией классов QDate и QTime и имеет много схожих методов, а его использование идентично использованию этих двух классов. В следующем примере мы выведем на экран текущую дату и время:

Результат выполнения программы:

Юлианская дата

Юлианская дата — это астрономический способ измерения времени, который начинает свой отсчет с начала Юлианского периода. Не следует её путать с Юлианским календарем. Юлианский период начался в 4713 году до нашей эры (детально об этом здесь). Помимо астрономии, Юлианские даты также часто используются военными и в вычислениях, проводимых на мейнфреймах.

В следующей программе мы вычислим Григорианскую и Юлианскую дату для текущего дня:

Результат выполнения программы:

Следующий пример показывает, сколько дней прошло с момента двух исторических событий:

Результат выполнения программы:

UTC-время

У нас есть 24 часовых пояса. В каждом часовом поясе существует свое местное время, которое может изменяться при переходе на летнее время.

Существует потребность в едином глобальном времени. Единое глобальное время поможет избежать путаницы с часовыми поясами и переходом на летнее время. В качестве основного стандарта времени был выбран стандарт UTC (Всемирное координированное время). UTC используется в авиации, в прогнозах погоды, в управлении воздушным движением и т.д. В отличие от местного времени, UTC не меняется со сменой сезонов.

В следующем примере мы вычислим текущую дату и время, а затем выведем её в форматах UTC и локального времени:

Результат выполнения программы:

Unix-время

Эпоха — это момент времени, выбранный в качестве начала определенной эры. Например, в западных христианских странах эпоха времени начинается с нулевого дня, когда родился Иисус. Другой пример — французский республиканский календарь, который использовался в течение двенадцати лет. Эта эпоха была началом Республиканской эры, которая была провозглашена 22 сентября 1792 года, в день провозглашения Первой Республики и упразднения монархии.

У компьютеров также есть свои эпохи. Одной из самых популярных является эпоха Unix. Эпоха Unix — это время 00:00:00 в формате UTC 1 января 1970 года (или 1970-01-01T00:00:00Z ISO 8601). Дата и время в компьютере определяются в соответствии с количеством секунд, прошедших с определенной эпохи для этого компьютера или платформы.

Unix-время — это количество секунд, прошедших с эпохи Unix. В следующем примере мы будем использовать две функции Qt5, чтобы получить Unix-время и преобразовать его в читабельную версию и обратно:

Результат выполнения программы:

На этом всё! До следующего урока!

Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (78 оценок, среднее: 4,79 из 5)
Загрузка...

Комментариев: 14

  1. ruser:

    Интересная статья, но все примеры даны на чтение даты-времени. А если я хочу скорректировать и записать свою дату в Windows, как быть?

  2. Дмитрий:

    У меня нормально работает только если не менять кодировку.
    Если ставить out.setCodec("CP866"), то выводит в консоль иероглифы

    1. Антон:

      Ох, как я Вас прекрасно понимаю. Сам намучился с этими кодировками. В итоге плюнул и делаю как раньше:

      Соответственно вот это становится ненужным

      а весь вывод кидаю в std::cout

  3. Rock:

    Есть вопрос ,в пользовательском формате времени при вводе без QLocale а только через QTime.toString добавление AP A a в конце не меняет формат отображения

    обязательно ли использовать QLocale для этого?

    1. Фото аватара Дмитрий Бушуев:

      Проверьте настройки локали вашей системы:
      Windows 10 -> вбить в панели поиска "Панель управления" -> "Региональные стандарты" -> кнопка "Дополнительные параметры…" ->вкладка "Время" -> проверить настройки "Обозначение времени до полудня (AM)" и "Обозначение времени после полудня (PM)" -> если там пусто, то из выпадающих списков выбрать соответствующие параметры. Как всё сделаете, проверьте вашу программу без явного указания локали через QLocale…

  4. kimoror:

    У меня просит писать именно Qt::endl. Как сделать так, чтобы можно было писать endl без пространства имён Qt

    1. Фото аватара Дмитрий Бушуев:

      Странно…
      Только что проверил на Windows 10 + Qt 5.14.2 — всё нормально. Попробуйте пересоздать проект.

      P.S.: В каком конкретно примере появляется данная ошибка? Какая версия Qt и ОС? Если есть возможность — загрузите куда-нить скриншот с полным описание ошибки.

    2. Мгер:

      Qt::endl это начинается с версии Qt 5.15

      Я сделал что то типо:

      И в коде везде использую Qt::endl
      И так же с другими манипуляторами (hex, flush)

      1. wasserati:

        Добавить перед первым использованием строку:

  5. Мгер:

    мне кажется есть ещё одна очень важная функция, которую не расмотрели: QClass::fromString(QSrring format), где QClass может быть как время, датой или общее

    1. Фото аватара Дмитрий Бушуев:

      Не совсем понял, о какой функции идет речь? Можно ссылку на документацию?

      1. Мгер:

        QClass -> QDateTime. Видимо читали и писал комментарии уже сонным

        https://doc.qt.io/QT-5/qdatetime.html#fromString

  6. Sergey:

    Классная статья )

Добавить комментарий для Мгер Отменить ответ

Ваш E-mail не будет опубликован. Обязательные поля помечены *