Стандартная библиотека: Дата и время
Стандартная библиотека поддерживает обработку дат и времени с использованием двух подходов:
Календарный подход, подходящий для обработки дат и времени в целом;
Подход реального времени, который лучше подходит для приложений реального времени, требующих повышенной точности, например, благодаря доступу к абсолютным часам и обработке интервалов времени. Следует отметить, что этот подход поддерживает только время, но не даты.
Эти два подхода представлены в следующих разделах.
Обработка даты и времени
Пакет 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 включает
математические операции, требующие значительного времени ЦПУ, измеренное
затраченное время и время ЦПУ намного ближе друг к другу, чем раньше.