【问题标题】:Print time in a batch file (milliseconds)批处理文件中的打印时间(毫秒)
【发布时间】:2009-03-03 08:16:57
【问题描述】:

如何在 Windows 批处理文件中打印时间(以毫秒为单位)?

我想测量批处理文件中各行之间经过的时间,但 Windows 的“时间 /T”不打印毫秒。

【问题讨论】:

标签: windows batch-file time


【解决方案1】:

%time% 应该可以工作,前提是两次通话之间有足够的时间:

@echo OFF

@echo %time%
ping -n 1 -w 1 127.0.0.1 1>nul
@echo %time%

在我的系统上,我得到以下输出:

6:46:13.50
6:46:13.60

【讨论】:

  • 在我的机器上,即使我在通话之间睡觉,它也会显示相同的时间。
  • 您可以发布您尝试分析的批处理文件的代码吗?
  • 我对此表示怀疑 :) 问题是什么?在这里分享它会帮助遇到同样事情的其他人吗?
  • 我有同样的问题,整个执行过程中时间总是一样的,即使脚本运行了几个小时,它总是显示脚本启动的时间。
  • @MaxiWheat - 请参阅 *.com/questions/12524909/… 这可能会解释您的问题
【解决方案2】:

如果你正在做类似的事情

for /l %%i in (1,1,500) do @echo %time%

if foo (
    echo %time%
    do_something
    echo %time%
)

然后您可以简单地将setlocal enabledelayedexpansion 放在批处理文件的开头并使用!time! 而不是%time%,它会在执行时评估,而不是在解析行时(包括括号中的完整块)。

【讨论】:

    【解决方案3】:

    下面的批处理“程序”应该做你想做的事。请注意,它以厘秒而不是毫秒为单位输出数据。所用命令的精度仅为厘秒。

    这是一个示例输出:

    STARTTIME: 13:42:52,25
    ENDTIME: 13:42:56,51
    STARTTIME: 4937225 centiseconds
    ENDTIME: 4937651 centiseconds
    DURATION: 426 in centiseconds
    00:00:04,26
    

    这是批处理脚本:

    @echo off
    setlocal
    
    rem The format of %TIME% is HH:MM:SS,CS for example 23:59:59,99
    set STARTTIME=%TIME%
    
    rem here begins the command you want to measure
    dir /s > nul
    rem here ends the command you want to measure
    
    set ENDTIME=%TIME%
    
    rem output as time
    echo STARTTIME: %STARTTIME%
    echo ENDTIME: %ENDTIME%
    
    rem convert STARTTIME and ENDTIME to centiseconds
    set /A STARTTIME=(1%STARTTIME:~0,2%-100)*360000 + (1%STARTTIME:~3,2%-100)*6000 + (1%STARTTIME:~6,2%-100)*100 + (1%STARTTIME:~9,2%-100)
    set /A ENDTIME=(1%ENDTIME:~0,2%-100)*360000 + (1%ENDTIME:~3,2%-100)*6000 + (1%ENDTIME:~6,2%-100)*100 + (1%ENDTIME:~9,2%-100)
    
    rem calculating the duratyion is easy
    set /A DURATION=%ENDTIME%-%STARTTIME%
    
    rem we might have measured the time inbetween days
    if %ENDTIME% LSS %STARTTIME% set set /A DURATION=%STARTTIME%-%ENDTIME%
    
    rem now break the centiseconds down to hors, minutes, seconds and the remaining centiseconds
    set /A DURATIONH=%DURATION% / 360000
    set /A DURATIONM=(%DURATION% - %DURATIONH%*360000) / 6000
    set /A DURATIONS=(%DURATION% - %DURATIONH%*360000 - %DURATIONM%*6000) / 100
    set /A DURATIONHS=(%DURATION% - %DURATIONH%*360000 - %DURATIONM%*6000 - %DURATIONS%*100)
    
    rem some formatting
    if %DURATIONH% LSS 10 set DURATIONH=0%DURATIONH%
    if %DURATIONM% LSS 10 set DURATIONM=0%DURATIONM%
    if %DURATIONS% LSS 10 set DURATIONS=0%DURATIONS%
    if %DURATIONHS% LSS 10 set DURATIONHS=0%DURATIONHS%
    
    rem outputing
    echo STARTTIME: %STARTTIME% centiseconds
    echo ENDTIME: %ENDTIME% centiseconds
    echo DURATION: %DURATION% in centiseconds
    echo %DURATIONH%:%DURATIONM%:%DURATIONS%,%DURATIONHS%
    
    endlocal
    goto :EOF
    

    【讨论】:

    • %TIME% 在午夜后采用 H:MM:SS,CS 格式,因此无法转换为厘秒。早上 6 点 46 分看到 Patrick Cuff 的帖子,好像不止我一个人。
    • (1%STARTTIME:~6,2%-100)*100 应该是 (1%STARTTIME:~6,2%-100)*1000 等等。
    • (1%STARTTIME:~9,2%-100) 应该是 (1%STARTTIME:~9,2%-100) * 10 等等。
    • @jaroslaw-pawlak,如果您的 %TIME% 格式是 H:MM:SS.CS(小时 set STARTTIME=%TIME: =0% 和set ENDTIME=%TIME: =0%
    【解决方案4】:

    在 CMD 中计时任务很简单

    echo %TIME% && your_command && cmd /v:on /c echo !TIME!
    

    【讨论】:

    • 是的,但问题是,启动一个新进程会花费时间并导致错误的值 (try echo %TIME% & cmd /v:on /c echo !TIME!`在我的系统上 20 毫秒)更好地创建测量之外的过程:(cmd /v:on /c "echo !time! & echo !time!" 给出零延迟[技术上必须有延迟,但它低于显示精度])或在上述情况下:cmd /v:on /c "echo !time! & your_command & echo !time!"
    • (注:一个&就足够了。意思是“然后做”。&&意思是“如果成功,做”)
    【解决方案5】:

    也许this tool (archived version) 能帮上忙?它不会返回时间,但它是衡量命令所用时间的好工具。

    【讨论】:

    • 谢谢,+1 有帮助。但仍然很有趣,为什么没有简单的批量打印时间......
    • 我喜欢这个建议。不幸的是,没有工具的名称,当链接断开时(例如现在),我看不到您在说什么。
    • 认为可能是timethis.exe(在撰写本文时,它似乎可以通过this link获得。
    • 链接已损坏,但它在 Internet 存档中:timethis_setup.exe
    【解决方案6】:

    %TIME% 在午夜后采用 H:MM:SS,CS 格式,因此转换为厘秒 > 不起作用。早上 6 点 46 分看到 Patrick Cuff 的帖子,好像不止我一个人。

    但是有了这几行,你应该很容易解决这个问题:

    if " "=="%StartZeit:~0,1%" set StartZeit=0%StartZeit:~-10%
    if " "=="%EndZeit:~0,1%" set EndZeit=0%EndZeit:~-10%
    

    感谢您的精彩灵感!我喜欢在我的 mplayer、ffmpeg、sox 脚本中使用它来为旧的 PocketPlayers 拉皮条我的媒体文件,只是为了好玩。

    【讨论】:

      【解决方案7】:

      你必须小心你想做的事情,因为它不仅仅是为了获得时间。

      批次有内部变量来表示日期和时间:%DATE% %TIME%。 但它们依赖于 Windows 语言环境。

      %Date%

      • dd.MM.yyyy
      • dd.MM.yy
      • d.M.yy
      • 日/月/年
      • yyyy-MM-dd

      %TIME%

      • H:mm:ss,msec
      • HH:mm:ss,msec

      现在,您的脚本可以运行多长时间以及何时运行?例如,如果它超过一天并且确实过了午夜,它肯定会出错,因为午夜之间的 2 个时间戳之间的差异是负值!您需要日期来找出正确的日期之间的距离,但是如果日期格式不是常数,您如何做到这一点?如果您继续将它们用于数学目的,带有 %DATE%%TIME% 的事情可能会变得越来越糟。

      原因是 %DATE%%TIME% 的存在只是为了在输出中向用户显示日期和时间,而不是用于计算。因此,如果您想在某些时间值之间做出正确的距离或根据日期和时间生成一些唯一值,那么您必须使用不同于 %DATE%%TIME%。

      我正在使用 wmic windows 内置实用程序来请求这些东西(将其放在脚本文件中):

      for /F "usebackq tokens=1,2 delims==" %%i in (`wmic os get LocalDateTime /VALUE`) do if "%%i" == "LocalDateTime" echo.%%j
      

      或在 cmd.exe 控制台中输入:

      for /F "usebackq tokens=1,2 delims==" %i in (`wmic os get LocalDateTime /VALUE`) do @if "%i" == "LocalDateTime" echo.%j
      

      这样做的缺点是在频繁调用的情况下性能较慢。在我的机器上大约是每秒 12 次调用。

      如果你想继续使用它,你可以写这样的东西(get_datetime.bat):

      @echo off
      
      rem Description:
      rem   Independent to Windows locale date/time request.
      
      rem Drop last error level
      cd .
      
      rem drop return value
      set "RETURN_VALUE="
      
      for /F "usebackq tokens=1,2 delims==" %%i in (`wmic os get LocalDateTime /VALUE 2^>NUL`) do if "%%i" == "LocalDateTime" set "RETURN_VALUE=%%j"
      
      if not "%RETURN_VALUE%" == "" (
        set "RETURN_VALUE=%RETURN_VALUE:~0,18%"
        exit /b 0
      )
      
      exit /b 1
      

      现在,您可以在脚本中的某处解析 %RETURN_VALUE%

      call get_datetime.bat
      set "FILE_SUFFIX=%RETURN_VALUE:.=_%"
      set "FILE_SUFFIX=%FILE_SUFFIX:~8,2%_%FILE_SUFFIX:~10,2%_%FILE_SUFFIX:~12,6%"
      echo.%FILE_SUFFIX%
      

      【讨论】: