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


192

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

它类似于Stack Overflow问题,如何在批处理文件中添加日期,但也要添加时间。

到目前为止,我有:

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



您可以替换datetimef变量上的空白,然后改为0。在您的示例中:SET datetimef=%datetimef: =0%
SebaGra

Answers:


148

我结束了这个脚本:

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%

11
仅供参考,在Windows Server 2003和Windows 7上,此脚本给了我“ 201200Mo_085806”(正确的年份和时间)。
sfuqua'4

50
谨记要从Google来到这里的人(例如我):这取决于语言环境,因此可能需要进行调整才能在非英语的Windows上工作!
PiotrK

我这样做是这样的:时间/ T> Time.dat设置/ P ftime = <Time.dat设置fDate =%date:〜6 %% date:〜3.2 %% date:〜0.2 %% ftime: 〜0.2 %% ftime:〜3.2%echo%fDate%-> 201310170928
Ice

%time:〜0.2%在做什么?:〜,%结构上有哪些内容?
user1605665 2014年

6
使用普通的字符串替换,仅用两行就可以完成所有这些操作:stackoverflow.com/a/23558738/1879699
Andreas

71
@ECHO OFF
: Sets the proper date and time stamp with 24Hr Time for log file naming
: convention

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

2
在Windows Server 2003和Windows 7上,这给了我正确的字符串。比我过去的建筑优雅得多,谢谢!
sfuqua

3
这是在Windows 7中使用俄语语言环境给我的。当前时间是2013-05-03T02:22:51,但脚本打印:“ 2013-5.-01_02_22_51”
nightcoder 2013年

7
%date%将给出具有不同语言环境的不同字符串。
AechoLiu 2013年

2
向我返回20146.0._173502(捷克语言环境)
Muflix

2
win7 64位旗舰版,错误时间:20140.01_131612,必须为(2014.10.26_131612)
waza123 2014年

66

这是我生成日志文件名的方法(基于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
...

5
关于批量生成与语言环境无关的时间戳的问题,SO上的最佳答案。
Mike Campbell

2
太棒了!应该有一种方法可以将其标记为解决方案
Rado

48

每当需要日期/时间字符串时,我通常都采用这种方式:

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.yyyy hh:mm:ss)。基本上,我将子字符串连接起来,最后将所有空格替换为零。

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

%VARIABLE:~num_chars_to_skip,num_chars_to_keep%

因此,要从类似“ 29.03.2018”的日期中获取年份,请使用:

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

7
到目前为止,当您只需要干净的时间戳记(无空格或其他字符)时,这是最优雅的解决方案
jvdneste

1
非常同意@jvdneste,感谢您分享mrt
this.user3272243 '16

1
绝对很棒-并且有效[所需的语法非常混乱,但这几乎不是海报的问题]
JosephDoggie

38

如果安装了PowerShell,则可以轻松,可靠地获取所需的任何格式的日期/时间,例如:

for /f %%a in ('powershell -Command "Get-Date -format yyyy_MM_dd__HH_mm_ss"') do set datetime=%%a
move "%oldfile%" "backup-%datetime%"

当然,如今始终会安装PowerShell,但是在Windows XP上,如果您在已知PS可用的已知环境中使用批处理脚本,则可能只想使用此技术(或者如果PowerShell可用,则签入批处理文件) ...)

您可能会合理地问:如果可以使用PowerShell来获取日期/时间,为什么要完全使用批处理文件,但是我认为一些明显的原因是:(a)您对PowerShell并不十分熟悉,并且仍然喜欢执行大多数操作使用批处理文件的老式方法,或者(b)您正在更新旧脚本,并且不想将整个内容移植到PS。


(a)在我的情况下,这非常有效(bat仅适用于我的环境,但是我在不同的pc上混合了语言环境)。谢谢!
ccalboni

30

我今天遇到了这个问题,并通过以下方法解决了该问题:

SET LOGTIME=%TIME: =0%

它用0代替空格,基本上每小时补零。

经过一番快速搜索后,我没有发现它是否需要命令扩展(仍然可以与SETLOCAL DISABLEEXTENSIONS一起使用)。


好的,替换变量。现在-如何替换冒号(:)?
Tomasz Gandor

@TomaszGandor这对我有用:echo %TIME: =:%但是,如果不是这样,请尝试:使用^like进行转义echo %TIME: =^:%(这也对我有用 )。
opello

1
为简单起见,+ 1。冒号在文件名中无效。set theTime =%Time :: =%删除它们。您能否在单个语句中用0代替空格,删除冒号并截断为6个字符(从而删除小数部分)?如果只需要两三行,就没什么大不了的。我只是好奇。
riderBill

不,我知道。如果找到一个,请跟进!
opello

21

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

3
正是我想要的。适用于每种语言环境设置的内容。谢谢!
Lost_DM 2012年

+1是我们要处理的“现代Windows系统” :)开个玩笑,这是一种非常巧妙的方法,就像您所说的那样,可移植地处理该问题。
Zach Young

9
这是一个糟糕的解决方案。如果失败,则将永久更改全局设置。它还在其他应用程序中引入了竞争条件。
MikeKulls 2015年

您可以使用该reg query "HKCU\Control Panel\International" /v sShortDate部件而无需更改注册表设置(练习留给读者!)。
tricasse

9

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

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%

至少它可能鼓舞人心。


9

如果您不完全需要此格式:

2009_07_28__08_36_01

然后,您可以使用以下3行代码,这些代码使用%date%和%time%:

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

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

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

echo %mytimestamp%
Wed_08052015_124950_93

当小时小于12时,设置mydate =%date:/ =%设置mytime =%time :: =%设置mytime =%mytime:= 0%设置mytimestamp =%mydate:= _%_%mytime:。= _ %
ragche

8
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%

6

Windows中offset:lengthSET命令支持的格式不允许您填充0感兴趣的格式。

但是,您可以编写BATCH脚本来检查小时是否少于小时,10
相应地使用其他echo字符串填充。

您可以在此链接SET找到有关命令的一些信息


您也可以更改为其他编程方法以到达此处。

在unix bash(在Windows上与Cygwin一起提供)中,非常简单地说:

date +%Y_%m_%d__%H_%M_%S

而且,它始终正确填充。


6

我这样做是这样的:

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%

LogFile201310170928.log


它运行英语服务器上(OS名称:Microsoft(R)的Windows(R)Server 2003标准版x64版本,OS版本:5.2.3790 Service Pack 2的构建3790)

1
并在德语服务器上进行了测试(Betriebs系统名称:Microsoft®WindowsServer®2008 Enterprise,Betriebssystemversion:6.0.6002 Service Pack 2 Build 6002)

1
即使这样也可以:(Betriebssystemname:Microsoft Windows Server 2012 Standard,Betriebssystemversion:6.2.9200 Nicht zutreffend Build 9200)
Ice

4
::========================================================================  
::== 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
这使您只需要格式化输出即可使其符合您的意愿。


4

该bat文件(另存为datetimestr.bat)生成3次datetime字符串:(1)带有星期几和秒的长datetime字符串,(2)没有它们的短datetime字符串,以及(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(14年6月18日在21:02)和opello(11年8月25日在14:27)的概念。

您可以写的短得多,但是长的版本使阅读和理解代码变得容易。


4

我真的是批处理文件的新手,这是我的代码!!(我不确定为什么,但是我无法将日期/ t时间/ t结合在一起,并且不能在没有变量的情况下直接使用%date%%time% ...)

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

它可以从其他地方重用(问题是要获取格式化的日期用作文件名)。


4

还有另一种简单的方法:

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

3

要生成YYYY-MM-DD hh:mm:ss(24小时)时间戳,请使用:

SET CURRENTTIME=%TIME%
IF "%CURRENTTIME:~0,1%"==" " (SET CURRENTTIME=0%CURRENTTIME:~1%)
FOR /F "tokens=2-4 delims=/ " %%A IN ('DATE /T') DO (SET TIMESTAMP=%%C-%%A-%%B %CURRENTTIME%)

是否采用特定的区域设置?
Peter Mortensen 2014年

1
根据ss64.com/nt/syntax-variables.html%TIME%%DATE%变量分别使用与TIMEDATE命令相同的格式。在我的系统上,变量与我的区域设置不匹配。
M. Dudley 2014年

3

此批处理脚本将完全按照OP的要求进行操作(在Windows XP SP3上进行了测试)。

我还使用了以前由“ jph”描述的巧妙的注册表技巧,恕我直言,这是"yyyy_MM_dd"在任何新旧Windows系统上使日期100%保持一致格式的最简单方法。为此,将一个注册表值更改为瞬时的和琐碎的;它只持续几毫秒,然后立即恢复原状。

双击该批处理文件以获取即时演示,“命令提示符”窗口将弹出并显示您的时间戳。。。。。

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: 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)。
user225479 '19

我在IFSE语句中添加了IF%HOUR%== 0(SET HOUR = 00)。我希望可以解决这个问题:)
user225479 '19

感谢您的反馈@ user225479。我已经修复了代码。现在,将HOUR变量转换为24 HOUR格式的所有可能排列将正常工作。我还修改了布局,以便于阅读。
derty2

2
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%

2

创建一个名为“ search_files.bat”的文件,并将下面的内容放入文件中。然后双击它。放置了临时%THH%变量以适当地处理AM。如果时间的前两位数字为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

2

我喜欢@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

1

这是我的2美分datetime string。在MM DD YYYY系统上,切换第一%DATE:~项和第二项。

    REM ====================================================================================
    REM CREATE UNIQUE DATETIME STRING FOR ADDING TO FILENAME
    REM ====================================================================================
    REM Can handle dd DDxMMxYYYY and DDxMMxYYYY > CREATES YYYYMMDDHHMMSS (x= any character)
    REM ====================================================================================
    REM CHECK for SHORTDATE dd DDxMMxYYYY 
    IF "%DATE:~0,1%" GTR "3" (
        SET DATETIME=%DATE:~9,4%%DATE:~6,2%%DATE:~3,2%%TIME:~0,2%%TIME:~3,2%%TIME:~6,2%
    ) ELSE (
    REM ASSUMES SHORTDATE DDxMMxYYYY
        SET DATETIME=%DATE:~6,4%%DATE:~3,2%%DATE:~0,2%%TIME:~0,2%%TIME:~3,2%%TIME:~6,2%
        )
    REM CORRECT FOR HOURS BELOW 10
    IF %DATETIME:~8,2% LSS 10 SET DATETIME=%DATETIME:~0,8%0%DATETIME:~9,5%
    ECHO %DATETIME%

1

我尝试了接受的答案,效果很好。不幸的是,美国时间格式似乎是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%

(*克里斯*)


1

也许是这样的:

@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

1

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

具体来说,日期和时间格式存储在[MS定义]“值”:“ sTimeFormat”和“ sShortDate”的注册表项HKCU \ Control Panel \ International \下。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”时间令牌应该位于前导零之前,但并非如此。幸运的是,解决方法很容易。


-1“为什么不添加前导零,为什么不破坏计算机配置,将其更改为您的随机需求,然后做您的事情?” 这种方法是世界之外的,需要付出大量的努力,并且可能导致无数数量的不良后果。而且我什至不想开始讨论可读性和标准预期的代码行为。荣誉。
vaitrafra

重置sTimeFormat时间格式是没有用的。不。由于它会影响后续的控制台提示,请使用for /f "delims=" %%G in ('cmd /C echo SET "DateTime=%%date%%__%%time%%"') do %%G
JosefZ,

1

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

1

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

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

0
:: =============================================================
:: 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
:: =============================================================

0

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

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

0

用斜杠分隔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%
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.