Стандартная библиотека: Дата и время
Стандартная библиотека поддерживает обработку дат и времени с использованием двух подходов:
Календарный подход, подходящий для обработки дат и времени в целом;
Подход реального времени, который лучше подходит для приложений реального времени, требующих повышенной точности, например, благодаря доступу к абсолютным часам и обработке интервалов времени. Следует отметить, что этот подход поддерживает только время, но не даты.
Эти два подхода представлены в следующих разделах.
Обработка даты и времени
Пакет Ada.Calendar
поддерживает обработку дат и времени. Рассмотрим
простой пример:
В этом примере отображаются текущая дата и время, которые извлекаются
при вызове функции Clock
. Мы вызываем функцию Image
из пакета
Ada.Calendar.Formatting
, чтобы получить
строку (String
) для текущей даты и времени. Вместо этого мы могли бы
получить каждую компоненту с помощью функции Split
. Например:
Здесь мы получаем каждый элемент и отображаем его отдельно.
Задержка с использованием даты
Вы можете приостановить приложение, чтобы оно перезапустилось в
определенную дату и время. Мы видели нечто подобное в главе о задачах.
Вы делаете это с помощью оператора delay until
. Например:
В этом примере мы указываем дату и время, инициализируя Next
с помощью
вызова Time_Of
, функции, принимающей различные компоненты даты (год,
месяц и т. д.) и возвращающей элемент типа Time
. Поскольку указанная
дата находится в прошлом, задержка delay until
не даст
заметного эффекта. Если мы укажем дату в будущем, программа будет ждать
наступления этой конкретной даты и времени.
Здесь мы переводим время в местный часовой пояс. Если мы не указываем
часовой пояс, по умолчанию используется всемирное координированное
время (Coordinated Universal Time сокращенно UTC). Получив смещение времени
к UTC с помощью вызова UTC_Time_Offset
из пакета
Ada.Calendar.Time_Zones
, мы можем инициализировать TZ
и
использовать его при вызове Time_Of
. Это все, что нам нужно сделать,
чтобы информация, предоставляемая Time_Of
, относилась к местному
часовому поясу.
Мы могли бы добиться аналогичного результата, инициализировав Next
с
помощью значения типа String
. Мы можем сделать это использовав вызов Value
из
пакета Ada.Calendar.Formatting
. Вот модифицированный код:
В этом примере мы снова используем TZ
в вызове Value
, чтобы
привести время ввода в соответствие с текущим часовым поясом.
В приведенных выше примерах мы приостанавливались до определенной даты и времени. Как мы видели в главе о задачах, мы могли бы вместо этого указать задержку относительно текущего времени. Например, мы можем задержать на 5 секунд, используя текущее время:
Здесь мы указываем продолжительность 5 секунд в D
, добавляем ее к
текущему времени из Now
и сохраняем сумму в Next
. Затем мы
используем его в операторе delay until
.
Режим реального времени
В дополнение к Ada.Calendar
стандартная библиотека также поддерживает
операции со временем для приложений реального времени. Они включены в пакет
Ada.Real_Time
. Этот пакет также включает тип Time
. Однако в
пакете Ada.Real_Time
тип Time
используется для
представления абсолютных часов и обработки промежутков времени. Это
контрастирует с Ada.Calendar
, который использует тип Time
для
представления даты и времени.
В предыдущем разделе мы использовали тип Time
из Ada.Calendar
и
оператор delay until
, чтобы отложить приложение на 5 секунд. Вместо
этого мы могли бы использовать пакет Ada.Real_Time
. Давайте изменим этот
пример:
Основное отличие состоит в том, что D
теперь является переменной типа
Time_Span
, определенной в пакете Ada.Real_Time
. Мы вызываем
функцию Seconds
для инициализации D
, но мы могли бы получить
более тончное значение, вызвав вместо этого Nanoseconds
. Кроме того,
нам нужно сначала преобразовать D
в тип Duration
с помощью
функции To_Duration
, прежде чем мы сможем его напечатать.
Анализ производительности
Одним из интересных приложений, использующих пакет Ada.Real_Time
,
является анализ производительности. Мы уже использовали этот пакет в предыдущем
разделе при обсуждении задач. Давайте рассмотрим пример анализа производительности:
В этом примере определяется фиктивное приложение
Computational_Intensive_App
, реализованное с использованием простого
оператора задержки delay
. Мы инициализируем Start_Time
и
Stop_Time
по текущим на тот момент часам и вычисляем прошедшее время.
Запустив эту программу, мы видим, что время составляет примерно 5 секунд, что
соответствует реботе оператора задержки delay
.
Аналогичное приложение - это анализ затраченного процессорного
времени. Мы можем реализовать это с помощью пакета Execution_Time
.
Давайте изменим предыдущий пример, чтобы измерить процессорное время:
В этом примере Start_Time
и Stop_Time
имеют тип CPU_Time
вместо Time
. Однако мы по-прежнему вызываем функцию Clock
для
инициализации обеих переменных и вычисления прошедшего времени так же, как и
раньше. Запустив эту программу, мы видим, что время процессора значительно
ниже, чем те 5 секунд, которые мы видели раньше. Это связано с тем, что
оператор задержки delay
не требует много времени процессора.
Результаты будут другими, если мы изменим реализацию
Computational_Intensive_App
для использования математических функций
в длинном цикле. Например:
Теперь, когда наша фиктивная Computational_Intensive_App
включает
математические операции, требующие значительного времени ЦПУ, измеренное
затраченное время и время ЦПУ намного ближе друг к другу, чем раньше.