在 Windows 批处理脚本中格式化日期和时间

Posted

技术标签:

【中文标题】在 Windows 批处理脚本中格式化日期和时间【英文标题】:Format date and time in a Windows batch script 【发布时间】:2010-11-14 14:47:15 【问题描述】:

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

它类似于 Stack Overflow 问题 How to append a date in batch files,但也有时间。

到目前为止我有这个:

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

【问题讨论】:

How to get current datetime on Windows command line, in a suitable format for using in a filename?的可能重复 Split %date% in a batch file regardless of Regional Settings 您可以替换 datetimef 变量上的空格,并用 0 代替。在您的示例中:SET datetimef=%datetimef: =0% 【参考方案1】:
for /f "tokens=1-4 delims=/ " %%I in ("%DATE%") do set curdate=%%K_%%J_%%I
for /f "tokens=1-4 delims=:," %%I in ("%TIME: =0%") do set curtime=%%I_%%J_%%K
echo %curdate%__%curtime%

如果您的系统使用另一个符号,请替换 delims 符号(用于切片到 %%I,%%J...) 如果您的系统使用另一个 D/M/Y 订单,也请编辑 curdate

【讨论】:

正如在基于%DATE%/%TIME% 的许多其他答案中所讨论的 - 这是不可靠的,因为它取决于语言环境。不仅分隔符可以不同。甚至日期组件的顺序也因地区而异。有更好的解决方案。 谢谢,说明已修改,+DMY 订单【参考方案2】:

所以%DATE% 的问题在于它取决于语言环境。因此,以前的大多数答案对我都不起作用。如果您对确切的格式不挑剔,只是想要一个时间戳来区分文件,您可以这样做:

set _date=%DATE%-%TIME%
set _date=%_date:/=-%
set _date=%_date: =-%
set _date=%_date::=-%
set _date=%_date:.=-%
echo %_date%

这应该适用于大多数语言环境。如果它没有添加另一行 set _date=%_date:<offending_char>=-% 以删除违规字符。即:与文件名不兼容的字符或文件名中不想要的字符。

请注意,这不符合问题规定的确切标准。

【讨论】:

【参考方案3】:

每当我需要日期/时间字符串时,我通常都会这样做:

set dt=%DATE:~6,4%_%DATE:~3,2%_%DATE:~0,2%__%TIME:~0,2%_%TIME:~3,2%_%TIME:~6,2%
set dt=%dt: =0%

这是德语日期/时间格式 (dd.mm.yyyyhh:mm:ss)。基本上我将子字符串连接起来,最后用零替换所有空格。

生成的字符串格式为:yyyy_mm_dd__hh_mm_ss


子字符串如何工作的简短说明:

%VARIABLE:~num_chars_to_skip,num_chars_to_keep%

所以要从像“29.03.2018”这样的日期获取年份:

%DATE:~6,4%
       ^-----skip 6 characters
         ^---keep 4 characters 

【讨论】:

当您只需要一个干净的时间戳(没有空格或其他字符)时,这是迄今为止最优雅的解决方案 最佳答案,因为它解释了如何打印变量而不是强制一些对很多人来说可能不同的子字符串。我总是先运行 echo %date%_%time% 来查看单独为我打印的变量,然后决定我想保留哪些子字符串。 如何获得 UTC 时区,例如在结果字符串的末尾添加+01 @AndreasL。在命令行上获取时区信息涉及其他工具。例如,您可以使用systeminfo,如下所示:for /F "tokens=2 delims=^(: " %i in ('systeminfo^|find "Zeit"') do set "tz=%i"(假设您使用的是德语 Windows)。请注意,如果您想在批处理文件中使用他,您需要将%s 加倍。【参考方案4】:
@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

【讨论】:

在 Windows Server 2003 和 Windows 7 上,这给了我正确的字符串。比我过去构建的要优雅得多,谢谢! 这是在俄罗斯语言环境的 Windows 7 中给我的。当前时间是 2013-05-03T02:22:51,但脚本打印:“2013-5.-01_02_22_51” %date% 将给出具有不同语言环境的不同字符串。 返回 20146.0._173502 给我(捷克语语言环境) win7 64bit Ultimate,错误时间:20140.01_131612,必须是(2014.10.26_131612)【参考方案5】:

希望这会有所帮助:

set MM=%date:~4,2%
set DD=%date:~7,2%
set YYYY=%date:~10,4%

echo %DD%_%MM%_%YYYY%

这将打印05_06_2021

【讨论】:

这显示了什么,现有的十几个答案还没有?此外,正如已经讨论过的,这是不可靠的特定于语言环境的解决方案。在我的(捷克)系统上,这会打印出02_6._【参考方案6】:
    设置 xtime=%time% 如果 "%xtime:~0,1%" == " " 设置 xtime=0%xtime:~1,7% 设置isodate=%date:~-4%%date:~3,2%%date:~0,2%_%xtime:~0,2%%xtime:~3,2%%time:~ 6.2%

【讨论】:

如果您将答案添加到其他 40 个,它应该显示不同的解决方案,或者至少是更好的解释。但是没有任何解释的等效答案并不是很有用。【参考方案7】:

此批处理脚本将完全按照 O.P. 的要求执行(在 Windows XP SP3 上测试)。

我还使用了“jph”之前描述的聪明的注册表技巧,恕我直言,这是在任何新旧 Windows 系统上将日期格式 100% 一致地设置为 "yyyy_MM_dd" 的最简单方法。为此更改一个注册表值是瞬时的且微不足道的;它只持续几毫秒,然后立即恢复。

双击此批处理文件进行即时演示,命令提示符窗口将弹出并显示您的时间戳。 . . . .

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: generates a custom formatted timestamp string using date and time.
:: run this batch file for an instant demo.
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

@ECHO OFF
SETLOCAL & MODE CON:COLS=80 LINES=15 & COLOR 0A

:: --- CHANGE THE COMPUTER DATE FORMAT TEMPORARILY TO MY PREFERENCE "yyyy_MM_dd",
REG COPY "HKCU\Control Panel\International" "HKCU\Control Panel\International-Temp" /f 2>nul >nul
REG ADD "HKCU\Control Panel\International" /v sShortDate /d "yyyy_MM_dd" /f 2>nul >nul

SET MYDATE=%date%

:: --- REVERT COMPUTER DATE BACK TO SYSTEM PREFERENCE
REG COPY "HKCU\Control Panel\International-Temp" "HKCU\Control Panel\International" /f 2>nul >nul
REG DELETE "HKCU\Control Panel\International-Temp" /f 2>nul >nul

:: --- SPLIT THE TIME [HH:MM:SS.SS] TO THREE SEPARATE VARIABLES [HH] [MM] [SS.SS]
FOR /F "tokens=1-3 delims=:" %%A IN ('echo %time%') DO (
SET HOUR=%%A
SET MINUTES=%%B
SET SECONDS=%%C
)

:: --- CHOOSE ONE OF THESE TWO OPTIONS :
:: --- FOR 4 DIGIT SECONDS        //REMOVES THE DOT FROM THE SECONDS VARIABLE [SS.SS]
:: SET SECONDS=%SECONDS:.=%
:: --- FOR 2 DIGIT SECONDS        //GETS THE FIRST TWO DIGITS FROM THE SECONDS VARIABLE [SS.SS]
SET SECONDS=%SECONDS:~0,2% 

:: --- FROM 12 AM TO 9 AM, THE HOUR VARIABLE WE EXTRACTED FROM %TIME% RETURNS A SINGLE DIGIT, 
:: --- WE PREFIX A ZERO CHARACTER TO THOSE CASES, SO THAT OUR WANTED TIMESTAMP
:: --- ALWAYS GENERATES DOUBLE-DIGIT HOURS (24-HOUR CLOCK TIME SYSTEM).
IF %HOUR%==0 (SET HOUR=00)
IF %HOUR%==1 (SET HOUR=01)
IF %HOUR%==2 (SET HOUR=02)
IF %HOUR%==3 (SET HOUR=03)
IF %HOUR%==4 (SET HOUR=04)
IF %HOUR%==5 (SET HOUR=05)
IF %HOUR%==6 (SET HOUR=06)
IF %HOUR%==7 (SET HOUR=07)
IF %HOUR%==8 (SET HOUR=08)
IF %HOUR%==9 (SET HOUR=09)

:: --- GENERATE OUR WANTED TIMESTAMP
SET TIMESTAMP=%MYDATE%__%HOUR%_%MINUTES%_%SECONDS%

:: --- VIEW THE RESULT IN THE CONSOLE SCREEN
ECHO.
ECHO    Generate a custom formatted timestamp string using date and time.
ECHO.
ECHO    Your timestamp is:    %TIMESTAMP%
ECHO.
ECHO.
ECHO    Job is done. Press any key to exit . . .
PAUSE > NUL

EXIT

【讨论】:

也适用于 Windows 2019。我会保留你的解决方案,我喜欢它:) 问题,我刚刚发现在午夜之后,输出中的尾随“0”会被删除。知道为什么吗?我的脚本输出给出:您的时间戳是:2019_09_16__0_58_07 而不是 ..00_58_07。但是在 1 点钟之后它会按预期工作(它会给出输出:..01_01_56)。 我在 ELSE 语句中添加了 IF %HOUR%==0 (SET HOUR=00)。这应该可以解决它,我希望 :) 感谢@user225479 的反馈。我已经修复了代码。转换为 24 HOUR 格式的 HOUR 变量的所有可能排列现在都可以正常工作。我还修改了布局,使其更易于阅读。【参考方案8】:

你可以使用这些...

Parameters:
%date:~4,2% -- month
%date:~7,2% -- days
%date:~10,4% -- years

%time:~1,1% -- hours
%time:~3,2% -- minutes
%time:~6,2% -- seconds
%time:~9,2% -- mili-seconds

%date:~4,2%%date:~7,2%%date:~10,4% : MMDDYYYY
%date:~7,2%%date:~4,2%%date:~10,4% : DDMMYYYY
%date:~10,4%%date:~4,2%%date:~7,2% : YYYYMMDD

【讨论】:

此答案仅在 Windows 中设置了特定日期格式时才有效。因此,它不适用于全球大多数 Windows 系统。【参考方案9】:

避免早期变量扩展的一个很好的单行技巧是使用cmd /c echo ^%time^%

cmd /c echo ^%time^% & dir /s somelongcommand & cmd /c echo ^%time^%

【讨论】:

【参考方案10】:

还有另一种简单的方法:

set HH=%time:~0,2%
if %HH% LEQ 9 (
set HH=%time:~1,1%
)

【讨论】:

【参考方案11】:

我对批处理文件真的很陌生,这是我的代码! (我不知道为什么,但我无法将 date /ttime /t 组合在一起,我也无法使用 %date%%time% 直接不带变量...)

@ECHO OFF
set ldt=%date% %time%
echo %ldt%>> logs.txt
EXIT

它是从其他人那里重用的(问题是获取格式化的时间日期以用作文件名)。

【讨论】:

【参考方案12】:

此脚本使用主要通过 WMIC 工具访问的 WMI 接口,该工具是自 Windows XP Professional 以来 Windows 不可或缺的一部分(也支持家庭版,但默认情况下不安装该工具)。该脚本还通过创建和调用 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

【讨论】:

【参考方案13】:

当时间值为 7-9 时,使用 % 会遇到十六进制运算错误。为避免这种情况,请使用 DelayedExpansion 并使用 !min:~1!

获取时间值

如果您有 PowerShell,另一种方法是调用它:

for /F "usebackq delims=Z" %%i IN (`powershell Get-Date -format u`) do (set server-time=%%i)

【讨论】:

【参考方案14】:

我喜欢@The lorax 之上的简短版本, 但对于其他语言设置,可能会略有不同。

例如,在德语设置中(使用自然日期格式:dd.mm.yyyy),月份查询必须从 4,2 更改为 3,2:

@ECHO OFF
: Sets the proper date and time stamp with 24h time for log file naming convention i.e.

SET HOUR=%time:~0,2%
SET dtStamp9=%date:~-4%%date:~3,2%%date:~7,2%_0%time:~1,1%%time:~3,2%%time:~6,2% 
SET dtStamp24=%date:~-4%%date:~3,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%
: Outputs= 20160727_081040
: (format: YYYYMMDD_HHmmss; e.g.: the date-output of this post timestamp)

PAUSE

【讨论】:

【参考方案15】:

在这种情况下,请使用简单、标准的编程方法: 无需花费大量精力来解析未知实体,只需保存当前配置,将其重置为已知状态,提取信息,然后恢复原始状态。仅使用标准 Windows 资源。

具体来说,日期和时间格式存储在注册表项下 [MS 定义]“值”中的 HKCU\Control Panel\International\:“sTimeFormat”和“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”值 NOT 生效 直到打开一个新的控制台窗口。但是,唯一可以改变的是分隔符 - 数字位置是固定的。同样,“HH”时间标记应该预先添加前导零,但事实并非如此。 幸运的是,解决方法很简单。

【讨论】:

-1 "与其添加前导零,不如中断机器配置,将其更改为您的随机需要,然后执行您的操作?"这种方法超出了这个世界,需要大量的努力,并且可能导致无限数量的不良后果。而且我什至不想开始讨论可读性和标准预期代码行为。荣誉。 重置sTimeFormat时间格式没用。没有。由于它会影响后续的控制台提示,请使用 for /f "delims=" %%G in ('cmd /C echo SET "DateTime=%%date%%__%%time%%"') do %%G 应用它【参考方案16】:

我最终得到了这个脚本:

set hour=%time:~0,2%
if "%hour:~0,1%" == " " set hour=0%hour:~1,1%
echo hour=%hour%
set min=%time:~3,2%
if "%min:~0,1%" == " " set min=0%min:~1,1%
echo min=%min%
set secs=%time:~6,2%
if "%secs:~0,1%" == " " set secs=0%secs:~1,1%
echo secs=%secs%

set year=%date:~-4%
echo year=%year%

:: 在 WIN2008R2 例如我需要让你的 'set month=%date:~3,2%' 如下所示::否则 MONTH 会出现 00

set month=%date:~4,2%
if "%month:~0,1%" == " " set month=0%month:~1,1%
echo month=%month%
set day=%date:~0,2%
if "%day:~0,1%" == " " set day=0%day:~1,1%
echo day=%day%

set datetimef=%year%%month%%day%_%hour%%min%%secs%

echo datetimef=%datetimef%

【讨论】:

仅供参考,在 Windows Server 2003 和 Windows 7 上,这个脚本给了我“201200Mo_085806”(正确的年份和时间)。 对于那些从谷歌来到这里的人(比如我)请注意:这取决于语言环境,因此可能需要调整才能在非英语 Windows 上工作! 我是这样做的:Time /T > Time.dat set /P ftime= 201310170928 %time:~0,2% 做了什么 :~,% 结构的一些文档在哪里? 所有这些都可以使用普通的字符串替换在 2 行中完成:***.com/a/23558738/1879699【参考方案17】:

此 bat 文件(另存为 datetimestr.bat)生成 3 次日期时间字符串:(1) 带有星期几和秒的长日期时间字符串, (2) 没有它们的短日期时间字符串和 (3) 短版代码。

@echo off
REM "%date: =0%" replaces spaces with zeros
set d=%date: =0%
REM "set yyyy=%d:~-4%" pulls the last 4 characters
set yyyy=%d:~-4%
set mm=%d:~4,2%
set dd=%d:~7,2%
set dow=%d:~0,3%
set d=%yyyy%-%mm%-%dd%_%dow%

set t=%TIME: =0%
REM "%t::=%" removes semi-colons
REM Instead of above, you could use "%t::=-%" to 
REM replace semi-colons with hyphens (or any 
REM non-special character)
set t=%t::=%
set t=%t:.=%

set datetimestr=%d%_%t%
@echo  Long date time str = %datetimestr%

set d=%d:~0,10%
set t=%t:~0,4%
set datetimestr=%d%_%t%
@echo Short date time str = %datetimestr%


@REM Short version of the code above
set d=%date: =0%
set t=%TIME: =0%
set datetimestr=%d:~-4%-%d:~4,2%-%d:~7,2%_%d:~0,3%_%t:~0,2%%t:~3,2%%t:~6,2%%t:~9,2%
@echo Datetimestr = %datetimestr%

pause

为了给予适当的评价,我合并了 Peter Mortensen(2014 年 6 月 18 日 21:02)和 opello(2011 年 8 月 25 日 14:27)的概念。

您可以写得更短,但这个长版本使阅读和理解代码变得容易。

【讨论】:

【参考方案18】:

使用 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

【讨论】:

【参考方案19】:

用斜杠分割date命令的结果,然后你可以将每个标记移动到适当的变量中。

FOR /F "tokens=1-3 delims=/" %%a IN ("%date:~4%") DO (
SET _Month=%%a
SET _Day=%%b
SET _Year=%%c
)
ECHO Month %_Month%
ECHO Day %_Day%
ECHO Year %_Year%

【讨论】:

【参考方案20】:

如果您并不完全需要这种格式:

2009_07_28__08_36_01

然后您可以使用以下 3 行代码,其中使用了 %date% 和 %time%:

set mydate=%date:/=%
set mytime=%time::=%
set mytimestamp=%mydate: =_%_%mytime:.=_%

注意:字符 /: 被删除,字符 . 和空格被替换为下划线。

示例输出(2015 年 8 月 5 日星期三下午 12:49 拍摄,时间为 50 秒和 93 毫秒):

echo %mytimestamp%
Wed_08052015_124950_93

【讨论】:

小时小于12时,设置mydate=%date:/=% set mytime=%time::=% set mytime=%mytime: =0% set mytimestamp=%mydate: =_ %_%mytime:.=_%【参考方案21】:

对于在文件名中使用数字日期的非常简单的解决方案,请使用以下代码:

set month=%date:~4,2%
set day=%date:~7,2%
set curTimestamp=%month%%day%%year%

rem then the you can add a prefix and a file extension easily like this
echo updates%curTimestamp%.txt

【讨论】:

【参考方案22】:
::========================================================================  
::== CREATE UNIQUE DATETIME STRING IN FORMAT YYYYMMDD-HHMMSS   
::======= ================================================================  
FOR /f %%a IN ('WMIC OS GET LocalDateTime ^| FIND "."') DO SET DTS=%%a  
SET DATETIME=%DTS:~0,8%-%DTS:~8,6%  

无论时区如何,第一行始终以这种格式输出: 20150515150941.077000+120 这使您只需格式化输出以符合您的意愿。

【讨论】:

【参考方案23】:
:: =============================================================
:: Batch file to display Date and Time seprated by undescore.
:: =============================================================
:: Read the system date.
:: =============================================================
@SET MyDate=%DATE%
@SET MyDate=%MyDate:/=:%
@SET MyDate=%MyDate:-=:%
@SET MyDate=%MyDate: =:%
@SET MyDate=%MyDate:\=:%
@SET MyDate=%MyDate::=_%
:: =============================================================
:: Read the system time.
:: =============================================================
@SET MyTime=%TIME%
@SET MyTime=%MyTime: =0%
@SET MyTime=%MyTime:.=:%
@SET MyTime=%MyTime::=_%
:: =============================================================
:: Build the DateTime string.
:: =============================================================
@SET DateTime=%MyDate%_%MyTime%
:: =============================================================
:: Display the Date and Time as it is now.
:: =============================================================
@ECHO MyDate="%MyDate%" MyTime="%MyTime%" DateTime="%DateTime%"
:: =============================================================
:: Wait before close.
:: =============================================================
@PAUSE
:: =============================================================

【讨论】:

【参考方案24】:

可能是这样的:

@call:DateTime

@for %%? in (
    "Year   :Y"
    "Month  :M"
    "Day    :D"
    "Hour   :H"
    "Minutes:I"
    "Seconds:S"
) do @for /f "tokens=1-2 delims=:" %%# in (%%?) do @for /f "delims=" %%_ in ('echo %%_DT_%%$_%%') do @echo %%# : _DT_%%$_ : %%_

:: OUTPUT
:: Year    : _DT_Y_ : 2014
:: Month   : _DT_M_ : 12
:: Day     : _DT_D_ : 17
:: Hour    : _DT_H_ : 09
:: Minutes : _DT_I_ : 04
:: Seconds : _DT_S_ : 35

@pause>nul

@goto:eof

:DateTime
    @verify errorlevel 2>nul & @wmics Alias /? >nul 2>&1
    @if not errorlevel 1 (
        @for /f "skip=1 tokens=1-6" %%a in ('wmic path win32_localtime get day^,hour^,minute^,month^,second^,year /format:table') do @if not "%%f"=="" ( set "_DT_D_=%%a" & set "_DT_H_=%%b" & set "_DT_I_=%%c" & set "_DT_M_=%%d" & set "_DT_S_=%%e" & set "_DT_Y_=%%f" )
    ) else (
        @set "_DT_T_=1234567890 "
    )
    @if errorlevel 1 (
        @for %%? in ("iDate" "sDate" "iTime" "sTime" "F" "Y" "M" "D" "H" "I" "S") do @set "_DT_%%~?_=%%~?"
        @for %%? in ("Date" "Time") do @for /f "skip=2 tokens=1,3" %%a in ('reg query "HKCU\Control Panel\International" /v ?%%~? 2^>nul') do @for /f %%x in ('echo:%%_DT_%%a_%%') do @if "%%x"=="%%a" set "_DT_%%a_=%%b"
        @for /f "tokens=1-3 delims=%_DT_T_%" %%a in ("%time%") do @set "_DT_T_=%%a%%b%%c"
    )
    @if errorlevel 1 (
        @if "%_DT_iDate_%"=="0" (set "_DT_F_=_DT_D_ _DT_Y_ _DT_M_") else if "%_DT_iDate_%"=="1" (set "_DT_F_=_DT_D_ _DT_M_ _DT_Y_") else if "%_DT_iDate_%"=="2" (set "_DT_F_=_DT_Y_ _DT_M_ _DT_D_")
        @for /f "tokens=1-4* delims=%_DT_sDate_%" %%a in ('date/t') do @for /f "tokens=1-3" %%x in ('echo:%%_DT_F_%%') do @set "%%x=%%a" & set "%%y=%%b" & set "%%z=%%c"
        @for /f "tokens=1-3 delims=%_DT_T_%" %%a in ("%time%") do @set "_DT_H_=%%a" & set "_DT_I_=%%b" & set "_DT_S_=%%c"
        @for %%? in ("iDate" "sDate" "iTime" "sTime" "F" "T") do @set "_DT_%%~?_="
    )
    @for %%i in ("Y"                ) do @for /f %%j in ('echo:"%%_DT_%%~i_%%"') do @set /a _DT_%%~i_+=  0 & @for /f %%k in ('echo:"%%_DT_%%~i_:~-4%%"') do @set "_DT_%%~i_=%%~k"
    @for %%i in ("M" "D" "H" "I" "S") do @for /f %%j in ('echo:"%%_DT_%%~i_%%"') do @set /a _DT_%%~i_+=100 & @for /f %%k in ('echo:"%%_DT_%%~i_:~-2%%"') do @set "_DT_%%~i_=%%~k"
@exit/b

【讨论】:

【参考方案25】:

我是这样做的:

REM Generate FileName from date and time in format YYYYMMTTHHMM

Time /T > Time.dat
set /P ftime= < Time.dat

set FileName=LogFile%date:~6%%date:~3,2%%date:~0,2%%ftime:~0,2%%ftime:~3,2%.log

echo %FileName%

日志文件201310170928.log

【讨论】:

它在英文服务器上运行(操作系统名称:Microsoft(R) Windows(R) Server 2003 Standard x64 Edition,操作系统版本:5.2.3790 Service Pack 2 Build 3790) 并且还在德国服务器上进行了测试(Betriebssystemname:Microsoft® Windows Server® 2008 Enterprise,Betriebssystemversion:6.0.6002 Service Pack 2 Build 6002) 即使这个也可以:(Betriebssystemname:Microsoft Windows Server 2012 Standard,Betriebssystemversion:6.2.9200 Nicht zutreffend Build 9200)【参考方案26】:

如前所述,仅当您知道当前用户使用的格式(例如,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

【讨论】:

这是一个糟糕的解决方案。如果失败,则永久更改全局设置。它还引入了与其他应用程序的竞争条件。 您可以在不更改注册表设置的情况下使用reg query "HKCU\Control Panel\International" /v sShortDatepart(练习留给读者!)。【参考方案27】:

以下可能不是直接答案,而是接近答案?

set hour=%time:~0,2%
if "%hour:~0,1%" == " " set datetimef=%date:~-4%_%date:~3,2%_%date:~0,2%__0%time:~1,2%_%time:~3,2%_%time:~6,2%
else set datetimef=%date:~-4%_%date:~3,2%_%date:~0,2%__%time:~0,2%_%time:~3,2%_%time:~6,2%

至少它可能是鼓舞人心的。

【讨论】:

使用%date%/%time% 的答案在很大程度上取决于区域设置。这个期望的格式是什么?【参考方案28】:

创建一个名为“search_files.bat”的文件并将下面的内容放入文件中。然后双击它。临时 %THH% 变量已到位以适当处理 AM。如果时间的前 2 位有 0,Windows 将忽略 LOG 文件的其余文件名。

CD .
SET THH=%time:~0,2%
SET THH=%THH: =0%
dir /s /b *.* > %date:~10,4%-%date:~4,2%-%date:~7,2%@%THH%.%time:~3,2%.%time:~6,2%.LOG

【讨论】:

【参考方案29】:

我尝试了接受的答案,效果很好。不幸的是,美国时间格式似乎是 H:MM:SS.CS,前面缺少的 0 导致上午 10 点之前出现解析问题。为了克服这个障碍并允许解析大多数世界时间格式,我想出了这个看起来运行良好的简单例程。

:ParseTime
rem The format of %%TIME%% is H:MM:SS.CS or (HH:MM:SS,CS) for example 0:01:23.45 or 23:59:59,99
FOR /F "tokens=1,2,3,4 delims=:.," %%a IN ("%1") DO SET /A "%2=(%%a * 360000) + (%%b * 6000) + (%%c * 100) + %%d"
GOTO :EOF

这个例程的好处是您将时间字符串作为第一个参数传递,并将您想要包含时间(以厘秒为单位)的环境变量的名称作为第二个参数传递。例如:

CALL :ParseTime %START_TIME% START_CS
CALL :ParseTime %TIME% END_CS
SET /A DURATION=%END_CS% - %START_CS%

(*克里斯*)

【讨论】:

【参考方案30】:
set hourstr = %time:~0,2%
if "%time:~0,1%"==" " (set hourstr=0%time:~1,1%)
set datetimestr=%date:~0,4%%date:~5,2%%date:~8,2%-%hourstr%%time:~3,2%%time:~6,2%

【讨论】:

以上是关于在 Windows 批处理脚本中格式化日期和时间的主要内容,如果未能解决你的问题,请参考以下文章

Windows批处理:如何读取文件中的日期和时间并将其与当前日期和时间进行比较

Windows批处理中获取日期和时间

更改 csv 文件中的日期时间格式 - 批处理脚本/Powershell [关闭]

Windows批处理 - 给自己写个库(2. 获取格式化的日期和时间)

日期和时间

datecal和clear命令