在Windows (Windows XP)批处理脚本中,我需要格式化当前日期和时间,以便以后在文件名等中使用。

这类似于堆栈溢出问题如何在批处理文件中添加日期,但也包含时间。

到目前为止,我有这个:

echo %DATE%
echo %TIME%
set datetimef=%date:~-4%_%date:~3,2%_%date:~0,2%__%time:~0,2%_%time:~3,2%_%time:~6,2%
echo %datetimef%

这使:

28/07/2009
 8:35:31.01
2009_07_28__ 8_36_01

是否有一种方法可以允许%TIME%中的个位数小时,以便我可以得到以下结果?

2009_07_28__08_36_01

当前回答

使用REG保存/修改/恢复对您的bat文件最有用的值。这是windows 7,对于其他版本,你可能需要一个不同的键名。

reg save    "HKEY_CURRENT_USER\Control Panel\International" _tmp.reg /y
reg add     "HKEY_CURRENT_USER\Control Panel\International" /v sShortDate  /d "yyyy-MM-dd" /f
set file=%DATE%-%TIME: =0%
reg restore "HKEY_CURRENT_USER\Control Panel\International" _tmp.reg
set file=%file::=-%
set file=%file:.=-%
set file

其他回答

这个脚本使用一个WMI接口,主要通过WMIC工具访问,这是Windows的一个组成部分,因为Windows XP专业版(家庭版也支持,但默认情况下不安装该工具)。该脚本还通过创建和调用WSH vbscript来访问WMI接口,并以与WMIC工具提供的相同格式写入控制台输出时间,从而实现了缺少WMIC工具的解决方案。

@ECHO OFF
REM Returns: RETURN
REM Modify:  RETURN, StdOut
REM Required - mandatory: none
REM Required - optionaly: format strings delimited by a space to format an output delimited by predefined delimiter
REM    YYYY = 4-digit year
REM      MM = 2-digit month
REM      DD = 2-digit day
REM      hh = 2-digit hour
REM      mm = 2-digit minute
REM      ss = 2-digit second
REM      ms = 3-digit millisecond

CALL :getTime %*
ECHO %RETURN%
GOTO :EOF


REM SUBROUTINE
REM Returns: RETURN
REM Modify:  RETURN
REM Required - mandatory: none
REM Required - optionaly: format strings delimited by a space to format an output delimited by predefined delimiter
REM    YYYY = 4-digit year
REM      MM = 2-digit month
REM      DD = 2-digit day
REM      hh = 2-digit hour
REM      mm = 2-digit minute
REM      ss = 2-digit second
REM      ms = 3-digit millisecond
:getTime
  SETLOCAL EnableDelayedExpansion
    SET DELIM=-
    WHERE /Q wmic.exe
    IF NOT ERRORLEVEL 1 FOR /F "usebackq skip=1 tokens=*" %%x IN (`wmic.exe os get LocalDateTime`) DO (SET DT=%%x & GOTO getTime_Parse)
    SET _TMP=%TEMP:"=%
    ECHO Wscript.StdOut.WriteLine (GetObject("winmgmts:root\cimv2:Win32_OperatingSystem=@").LocalDateTime)>"%_TMP%\get_time_local-helper.vbs"
    FOR /F "usebackq tokens=*" %%x IN (`cscript //B //NoLogo "%_TMP%\get_time_local-helper.vbs"`) DO (SET DT=%%x & GOTO getTime_Parse)
    :getTime_Parse
      SET _RET=
      IF "%1" EQU "" (
        SET _RET=%DT:~0,4%%DELIM%%DT:~4,2%%DELIM%%DT:~6,2%%DELIM%%DT:~8,2%%DELIM%%DT:~10,2%%DELIM%%DT:~12,2%%DELIM%%DT:~15,3%
      ) ELSE (
        REM Not recognized format strings are ignored during parsing - no error is reported.
       :getTime_ParseLoop
         SET _VAL=
         IF "%1" EQU "YYYY" SET _VAL=%DT:~0,4%
         IF "%1" EQU "MM"   SET _VAL=%DT:~4,2%
         IF "%1" EQU "DD"   SET _VAL=%DT:~6,2%
         IF "%1" EQU "hh"   SET _VAL=%DT:~8,2%
         IF "%1" EQU "mm"   SET _VAL=%DT:~10,2%
         IF "%1" EQU "ss"   SET _VAL=%DT:~12,2%
         IF "%1" EQU "ms"   SET _VAL=%DT:~15,3%
         IF DEFINED _VAL (
           IF DEFINED _RET (
             SET _RET=!_RET!%DELIM%!_VAL!
           ) ELSE (
             SET _RET=!_VAL!
           )
         )
         SHIFT
         IF "%1" NEQ "" GOTO getTime_ParseLoop
      )
  ENDLOCAL & SET RETURN=%_RET%
GOTO :EOF
REM Assumes UK style date format for date environment variable (DD/MM/YYYY).
REM Assumes times before 10:00:00 (10am) displayed padded with a space instead of a zero.
REM If first character of time is a space (less than 1) then set DATETIME to:
REM YYYY-MM-DD-0h-mm-ss
REM Otherwise, set DATETIME to:
REM YYYY-MM-DD-HH-mm-ss
REM Year, month, day format provides better filename sorting (otherwise, days grouped
REM together when sorted alphabetically).

IF "%time:~0,1%" LSS "1" (
   SET DATETIME=%date:~6,4%-%date:~3,2%-%date:~0,2%-0%time:~1,1%-%time:~3,2%-%time:~6,2%
) ELSE (
   SET DATETIME=%date:~6,4%-%date:~3,2%-%date:~0,2%-%time:~0,2%-%time:~3,2%-%time:~6,2%
)

ECHO %DATETIME%

使用%,当时间值为7-9时,您将遇到十六进制操作错误。为了避免这种情况,请使用delayeexpand并使用!min:~1!

如果你有PowerShell,另一个方法是调用它:

for /F "usebackq delims=Z" %%i IN (`powershell Get-Date -format u`) do (set server-time=%%i)
@ECHO OFF
: Sets the proper date and time stamp with 24Hr Time for log file naming
: convention ('YYYYMMDD_HHMMSS')

: Scrapes the characters out of their expected permissions in the date/time
: environment variables.

: Expects a date format of '____MM_DD_YYYY'
: Expects a time format of 'HH:MM:SS' or ' H:MM:SS'

SET HOUR=%time:~0,2%
SET dtStamp9=%date:~-4%%date:~4,2%%date:~7,2%_0%time:~1,1%%time:~3,2%%time:~6,2% 
SET dtStamp24=%date:~-4%%date:~4,2%%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%

if "%HOUR:~0,1%" == " " (SET dtStamp=%dtStamp9%) else (SET dtStamp=%dtStamp24%)

ECHO %dtStamp%

PAUSE

如前所述,只有在您知道当前用户使用的格式(例如,MM/dd/yy或dd-MM-yyyy,仅举两个例子)时,解析日期和时间才有用。这是可以确定的,但是当您完成所有的强调和解析时,您仍然会遇到使用了意想不到的格式的情况,需要进行更多的调整。

您还可以使用一些外部程序,它们将以您喜欢的格式返回日期段,但这样做的缺点是需要将实用程序与脚本/批处理一起分发。

也有批处理技巧使用CMOS时钟在一个相当原始的方式,但这是太接近裸线对大多数人来说,也不总是首选的地方来检索日期/时间。

下面是避免上述问题的解决方案。是的,它引入了一些其他问题,但就我的目的而言,我发现这是在现代Windows系统的.bat文件中创建日期戳的最简单、最清晰、最可移植的解决方案。这只是一个示例,但我认为您将看到如何修改其他日期和/或时间格式等。

reg copy "HKCU\Control Panel\International" "HKCU\Control Panel\International-Temp" /f
reg add "HKCU\Control Panel\International" /v sShortDate /d "yyMMdd" /f
@REM reg query "HKCU\Control Panel\International" /v sShortDate
set LogDate=%date%
reg copy "HKCU\Control Panel\International-Temp" "HKCU\Control Panel\International" /f