Как правильно измерить время выполнения команд в Windows CMD
При работе в командной строке Windows (cmd) может возникнуть задача измерить, сколько времени заняло выполнение определённой команды или набора команд. Например, попытка просто вывести текущее время до и после timeout не даёт ожидаемого результата:
echo %DATE% %TIME% & timeout 5 & echo %DATE% %TIME%
Почему обе даты и времени одинаковы? Дело в том, что переменные окружения в CMD, такие как %TIME% и %DATE%, расширяются сразу при разборе команды, а не в момент её выполнения. Поэтому обе команды echo получают одинаковое значение времени, взятое до паузы.
Проблема с расширением переменных
CMD парсит всю строку команды целиком перед её выполнением. Если вы используете такие переменные, как %TIME%, их значение фиксируется в момент разбора команды, а не в момент вывода. Это значит, что:
echo %DATE% %TIME% & timeout 5 & echo %DATE% %TIME%
по факту превращается в
echo 11/18/2025 16:42:51.15 & timeout 5 & echo 11/18/2025 16:42:51.15
и оба вывода случаются с одинаковым временем.
Вариант 1: Отложенное расширение переменных в CMD
Windows CMD поддерживает механизм отложенного (delayed) расширения переменных, который позволяет «промедлить» взятие значения переменной до момента выполнения команды. Для этого:
- Включите отложенное расширение через ключ
/V:ONпри запуске CMD; - Обращайтесь к переменным не через
%VAR%, а через!VAR!.
Пример команды:
cmd /V:ON /C "echo !DATE! !TIME! & timeout 5 & echo !DATE! !TIME!"
Вывод будет примерно такой:
Wed 11/19/2025 0:03:00.45
Waiting for 5 seconds, press a key to continue ...
Wed 11/19/2025 0:03:05.19
Аналогично, в батч файле можно использовать:
setlocal enabledelayedexpansion
echo !DATE! !TIME!
timeout 5
echo !DATE! !TIME!
endlocal
Отложенное расширение прекрасно подходит, если вы хотите просто «поймать» текущее время до и после какого-либо действия внутри скрипта.
Вариант 2: Использование команды net time для получения точного времени с сервера
Также можно получить текущее сетевое время с контроллера домена с помощью команды net time. Это актуально, если вам важно время, синхронизированное с доменом или сервером.
Пример команды:
net time \\%userdomain% & timeout 5 & net time \\%userdomain%
Или:
net time %logonserver% & timeout 5 & net time %logonserver%
Пример вывода:
Current time at \\PCNAME is 11/18/2025 8:34:30 PM
The command completed successfully.
Waiting for 5 seconds, press a key to continue ...
Current time at \\PCNAME is 11/18/2025 8:34:35 PM
The command completed successfully.
У этого способа есть свои нюансы:
- Он зависит от доступности доменного контроллера;
- Значение зависит от сетевой синхронизации;
- Полезен для корпоративных сетей.
Вариант 3: Использование call для повторного расширения переменных
Если не хочется заморачиваться с отложенным расширением, можно использовать команду call, которая вызывает дополнительный проход интерпретатора и позволяет расширить переменные во время выполнения:
echo %DATE% %TIME% & timeout 1 & call echo ^%DATE^% ^%TIME^%
В скрипте (.bat):
echo %DATE% %TIME% & timeout 1 & call echo %%DATE%% %%TIME%%
Обратите внимание на экранирование процентов с помощью символов ^ и удвоения % в батч файлах.
Вариант 4: Измерение длительности выполнения команды в секундах
Чтобы не только выводить время, но и посчитать, сколько секунд заняла команда, можно воспользоваться арифметикой и выделением подстрок из строки времени.
Пример скрипта, который считает разницу времени между двумя моментами:
setlocal enabledelayedexpansion
set "START=!TIME!"
timeout 5 > nul
set "END=!TIME!"
set /A DURATION=(1!END:~0,2!-1!START:~0,2!)*3600 + (!END:~3,2!-!START:~3,2!)*60 + (!END:~6,2!-!START:~6,2!)
rem Если выполнение прошло через полночь, поправим отрицательное значение
if !DURATION! LSS 0 set /A DURATION+=86400
echo Команда выполнялась !DURATION! секунд
endlocal
Здесь:
- Используется отложенное расширение переменных;
- Извлекаются часы, минуты и секунды из строки времени
HH:mm:ss.ssс помощью подстрок~; - Выполняется арифметика для подсчёта общего времени в секундах;
- Обрабатывается случай перехода через полночь.
Вариант 5: Настройка подсказки (prompt) и вывод времени вручную
Можно настроить командную строку так, чтобы она всегда показывала время вместе с вашим приглашением. Например, установить такой prompt:
set prompt=$T$H$H$H$H$H$H$S%computername%\%username%$S$M$P$+$G
Где:
$T— текущее время;$H— символ Backspace, используется для контролируемого показа долей секунд;%computername%,%username%— имя компьютера и пользователя;- Другие символы форматируют внешний вид.
Выполняя команды с предваряющим echo %time%, вы сможете видеть время начала и окончания команд в логах терминала. Такой способ особенно удобен для интерактивной работы и отладки. Для анализа длительности потребуется вручную вычислять разницу между времени запуска и окончания.
Рекомендации и выводы
- Для простого и быстрого получения актуального времени во время выполнения команды используйте отложенное расширение переменных (
cmd /V:ONи!TIME!). - Если нужно получить время с сервера, например, доменного контроллера — используйте
net time. - Команда
callс экранированием подходит для разовых случаев без включения delayed expansion в скриптах. - Для измерения длительности выполнения можно вычислять разницу между стартовым и конечным временем, используя арифметику и substring-обработку.
- Настройка prompt удобна для просмотра времени запуска команд в интерактивном режиме, но требует дополнительных действий для вычисления длительности.
- Если вы планируете более серьезное скриптование, рекомендую обратить внимание на PowerShell, который предоставляет полноценные и удобные средства для работы с датой, временем и измерением длительности.
Таким образом, выбор решения зависит от ваших задач и контекста:
- Для простой отметки времени — delayed expansion;
- Для сетевого времени —
net time; - Для точного измерения длительности — вычисление разницы времён;
- Для автоматического отображения времени в командной строке — настройка prompt.



