在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
这个脚本使用一个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
在这种情况下,使用简单、标准的编程方法:
与其花费大量精力解析未知实体,不如简单地保存当前配置,将其重置为已知状态,提取信息,然后恢复原始状态。只使用标准的Windows资源。
具体来说,日期和时间格式存储在注册表项下
HKCU\Control Panel\International\ [MS定义]"values": " timeformat "及"sShortDate"。
Reg是包含在所有Windows版本中的控制台注册表编辑器。
修改HKCU密钥不需要提升权限
Prompt $N:$D $T$G
::Save current config to a temporary (unique name) subkey, Exit if copy fails
Set DateTime=
Set ran=%Random%
Reg copy "HKCU\Control Panel\International" "HKCU\Control Panel\International-Temp%ran%" /f
If ErrorLevel 1 GoTO :EOF
::Reset the date format to your desired output format (take effect immediately)
::Resetting the time format is useless as it only affect subsequent console windows
::Reg add "HKCU\Control Panel\International" /v sTimeFormat /d "HH_mm_ss" /f
Reg add "HKCU\Control Panel\International" /v sShortDate /d "yyyy_MM_dd" /f
::Concatenate the time and (reformatted) date strings, replace any embedded blanks with zeros
Set DateTime=%date%__%time:~0,2%_%time:~3,2%_%time:~6,2%
Set DateTime=%DateTime: =0%
::Restore the original config and delete the temp subkey, Exit if restore fails
Reg copy "HKCU\Control Panel\International-Temp%ran%" "HKCU\Control Panel\International" /f
If ErrorLevel 1 GoTO :EOF
Reg delete "HKCU\Control Panel\International-Temp%ran%" /f
简单,直接,应该适用于所有地区。
出于我不理解的原因,重置“sShortDate”值立即生效
一个控制台窗口,但重置非常相似的“sTimeFormat”值不会生效
直到打开一个新的控制台窗口。但是,唯一可以更改的是分隔符-
数字的位置是固定的。同样,“HH”时间标记应该在前导零之前,但它没有。
幸运的是,变通方法很简单。
下面是如何生成一个日志文件名(基于http://ss64.com/nt/syntax-getdate.html):)
@ECHO OFF
:: Check WMIC is available
WMIC.EXE Alias /? >NUL 2>&1 || GOTO s_error
:: Use WMIC to retrieve date and time
FOR /F "skip=1 tokens=1-6" %%G IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table') DO (
IF "%%~L"=="" goto s_done
Set _yyyy=%%L
Set _mm=00%%J
Set _dd=00%%G
Set _hour=00%%H
SET _minute=00%%I
SET _second=00%%K
)
:s_done
:: Pad digits with leading zeros
Set _mm=%_mm:~-2%
Set _dd=%_dd:~-2%
Set _hour=%_hour:~-2%
Set _minute=%_minute:~-2%
Set _second=%_second:~-2%
Set logtimestamp=%_yyyy%-%_mm%-%_dd%_%_hour%_%_minute%_%_second%
goto make_dump
:s_error
echo WMIC is not available, using default log filename
Set logtimestamp=_
:make_dump
set FILENAME=database_dump_%logtimestamp%.sql
...