Функция Now() в Delphi широко используется для получения текущего времени с высокой точностью. Однако, в официальной документации Embarcadero указано, что точность Now() составляет только 1 секунду. В данной статье мы рассмотрим реальные ограничения точности Now() на различных платформах и попробуем понять, насколько точным является это утверждение.
Платформа Windows
На платформе Windows функция Now() основана на системной функции GetLocalTime(). Давайте рассмотрим подробнее, как работает эта функция и какие ограничения могут быть на её точность.
GetLocalTime()
Функция GetLocalTime() возвращает текущее время в локальном часовом поясе. Она использует системный таймер, который обычно имеет разрешение в 15-55 миллисекунд. Однако, с помощью функции timeBeginPeriod(), можно повысить разрешение таймера до 1 миллисекунды.
Тестирование точности Now() на Windows
Для проверки точности Now() на Windows, можно воспользоваться следующим примером кода на Object Pascal:
program Project4;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
System.DateUtils,
Winapi.Windows;
var
I: Integer;
T1: Int64;
T2: Int64;
TD: Double;
D1: TDateTime;
D2: TDateTime;
DiffMs: Int64;
Frequency: Int64;
function Delay: Integer;
var
I: Integer;
begin
Result := 0;
for I := 0 to 1000000 do
Inc(Result);
end;
begin
FormatSettings.DecimalSeparator := '.';
FormatSettings.ThousandSeparator := ',';
try
QueryPerformanceFrequency(Frequency);
D1 := Now();
QueryPerformanceCounter(T1);
Delay;
D2 := Now();
QueryPerformanceCounter(T2);
TD := (T2 - T1) * 1000 / Frequency;
DiffMs := MilliSecondsBetween(D2, D1);
Writeln(Format('Now() delta = %d ms', [DiffMs]));
Writeln(Format('QueryPerformance delta = %f ms', [TD]));
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
Этот код измеряет разницу в миллисекундах между двумя вызовами Now() и сравнивает её с результатом измерения с помощью QueryPerformanceCounter. Как видно из результатов, Now() может достигать точности около 15 миллисекунд.
Платформа macOS/iOS
На платформе macOS/iOS функция Now() основана на системной функции mach_absolute_time(). Эта функция предоставляет высокую точность, которая может достигать 1 миллисекунды. Однако, стоит отметить, что использование mach_absolute_time() может вызвать проблемы с приватностью и политиками Apple.
Платформа Android/Linux
На платформе Android/Linux функция Now() основана на системной функции clock_gettime(CLOCK_MONOTONIC, @res). Эта функция также предоставляет высокую точность, которая может достигать 1 миллисекунды.
Платформа другие
На других платформах функция Now() также может достигать высокой точности, которая может достигать 1 миллисекунды. Однако, стоит отметить, что точность может варьироваться в зависимости от конкретной платформы и её системного таймера.
Заключение
Из приведённых выше примеров можно сделать вывод, что функция Now() в Delphi может достигать точности около 15 миллисекунд на различных платформах. Однако, стоит отметить, что официальная документация Embarcadero указывает, что точность Now() составляет только 1 секунду. Это может быть связано с тем, что Now() основана на системном таймере, который может быть блокирован различными нагрузками и вызывать проблемы с точностью.
Если вам нужна высокая точность, рекомендуется использовать другие функции, такие как QueryPerformanceCounter() или TStopwatch, которые предоставляют высокую точность и не зависят от системного таймера.
Context — это окружение или обстоятельства, в которых происходит действие или событие, влияющие на его понимание и интерпретацию.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.