Windows CMD批处理脚本中的文件名时间戳被截断

47

我有一个批处理脚本会生成一个文件,我想确保每次执行脚本时不会覆盖现有的文件,所以我尝试在文件名上加上时间戳。

目前我的做法是:

set  stamp=%DATE:/=-%_%TIME::=-%

但是如果时间在凌晨1点至9点之间,它会返回类似于:

13-06-2012_ instead of a full 13-06-2012_12-39-37.28

我该如何解决这个问题?

我使用的是Windows 7,在命令行窗口中执行echo %date% %time%命令的输出为(我的“短日期”时钟格式设置为显示3个字母的月份):

03-Sep-12 9:06:21.54
基本上,我想要一个解决方案,无论时钟格式设置为什么,都可以解决问题。

编辑: 由于没有人喜欢阅读标题之后的内容,所以我将明确指出这个问题是关于截断问题的。 我已经找到了一个解决方案。

我已经使用以下时间戳一段时间了,效果很好。

set timestamp=%DATE:/=-%_%TIME::=-%
set timestamp=%timestamp: =%

它生成了一个类似于时间戳的东西: 18-03-2013_13-37-43.26, 通过替换%TIME%%DATE%中的/:,然后去除空格。实际上是空格导致我的原始问题。


@feeela,那并没有解决或解释截断问题。请参见我的已接受答案 - bryc
9个回答

77

这段代码的前四行将使用 WMIC 在 XP Pro 及以上版本中为您提供可靠的 YY DD MM YYYY HH Min Sec 变量。

@echo off
for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "DD=%dt:~6,2%"
set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%"

set "datestamp=%YYYY%%MM%%DD%" & set "timestamp=%HH%%Min%%Sec%"
set "fullstamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%"
echo datestamp: "%datestamp%"
echo timestamp: "%timestamp%"
echo fullstamp: "%fullstamp%"
pause

输出示例:

datestamp: "20200828"
timestamp: "085513"
fullstamp: "2020-08-28_08-55-13"
Press any key to continue . . .

伟大而最可靠的解决方案。谢谢。 - Eric Ouellet
这真的帮了我很多,谢谢。 :) - LastTigerEyes
似乎%dt%date%time后面的数字取决于系统的时间格式设置。例如:如果我使用日期/时间格式为YYYY-MM-DD,那么date:~0,4%将是年份,但如果我使用格式为DD/MM/YYYY,那么date:~0,4%将是其他内容。 - undefined

13

请查看Stack Overflow问题如何在Windows命令行中获取当前日期时间,并以适合用于文件名的格式呈现?

创建一个名为date.bat的文件:

@echo off
For /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set mydate=%%c-%%a-%%b)
For /f "tokens=1-3 delims=/:/ " %%a in ('time /t') do (set mytime=%%a-%%b-%%c)
set mytime=%mytime: =% 
echo %mydate%_%mytime%

运行 date.bat

C:\>date.bat
2012-06-14_12-47-PM

更新:

你也可以只用一行代码完成这个操作:

for /f "tokens=2-8 delims=.:/ " %%a in ("%date% %time%") do set DateNtime=%%c-%%a-%%b_%%d-%%e-%%f.%%g

注:此代码与IT技术有关,是用于生成文件名的代码。

1
抱歉,似乎返回了无效的日期,我得到了“-06-2012_01”。 - bryc
2
为什么不在一行上完成所有操作呢?for /f "tokens=2-8 delims=.:/ " %%a in ("%date% %time%") do set DateNtime=%%c-%%a-%%b_%%d-%%e-%%f.%%g 这个例子使用了24小时制而不是12小时制+AM/PM,并包括毫秒。如果你不想要毫秒,就不要使用 %%g - James K
嗨,詹姆斯,我把你的答案放到我的答案里了。 - Nicholas DiPiazza
1
此答案假定计算机设置为美国日期格式,并且在未经修改的其他系统上无法正常工作。 - silver

7
这是一个我写的批处理脚本,用于返回时间戳。可以提供一个可选的第一个参数作为字段分隔符。如:
c:\sys\tmp>timestamp.bat 20160404_144741 c:\sys\tmp>timestamp.bat - 2016-04-04_14-45-25 c:\sys\tmp>timestamp.bat : 2016:04:04_14:45:29
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
:: put your desired field delimiter here.
:: for example, setting DELIMITER to a hyphen will separate fields like so:
:: yyyy-MM-dd_hh-mm-ss
::
:: setting DELIMITER to nothing will output like so:
:: yyyyMMdd_hhmmss
::
SET DELIMITER=%1

SET DATESTRING=%date:~-4,4%%DELIMITER%%date:~-7,2%%DELIMITER%%date:~-10,2%
SET TIMESTRING=%TIME%
::TRIM OFF the LAST 3 characters of TIMESTRING, which is the decimal point and hundredths of a second
set TIMESTRING=%TIMESTRING:~0,-3%

:: Replace colons from TIMESTRING with DELIMITER
SET TIMESTRING=%TIMESTRING::=!DELIMITER!%

:: if there is a preceeding space substitute with a zero
echo %DATESTRING%_%TIMESTRING: =0%

3
for /f "tokens=2-8 delims=.:/ " %%a in ("%date% %time: =0%") do set DateNtime=%%c-%%a-%%b_%%d-%%e-%%f.%%g
echo %DateNtime%

或者,从命令行中执行:
for /f "tokens=2-8 delims=.:/ " %a in ("%date% %time: =0%") do echo %c-%a-%b_%d-%e-%f.%g 

编辑: 根据Bryce的非标准时间/日期规范。(03-Sep-12 9:06:21.54

@echo off
setlocal enabledelayedexpansion
for /f "tokens=1-7 delims=.:/- " %%a in ("%date% %time%") do (
  if "%%b"=="Jan" set MM=01
  if "%%b"=="Feb" set MM=02
  if "%%b"=="Mar" set MM=03
  if "%%b"=="Apr" set MM=04
  if "%%b"=="May" set MM=05
  if "%%b"=="Jun" set MM=06
  if "%%b"=="Jul" set MM=07
  if "%%b"=="Aug" set MM=08
  if "%%b"=="Sep" set MM=09
  if "%%b"=="Oct" set MM=10
  if "%%b"=="Nov" set MM=11
  if "%%b"=="Dec" set MM=12
  set HH=0%%d
  set HH=!HH:~-2!
  echo 20%%c-!MM!-%%a_!HH!-%%e-%%f.%%g
)
endlocal

2

1
我的上面的脚本使用 set mytime=%mytime: =% 来消除那个空格。 - Nicholas DiPiazza
1
你可以将冒号和空格都设置为分隔符 "delims=: ",它会忽略空格。 - James K

1

2018-02-08_14.32.06.34.log格式的Windows批处理日志文件名:

setlocal
set d=%DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%
set t=%time::=.% 
set t=%t: =%
set logfile="%d%_%t%.log"

ping localhost -n 11>%1/%logfile%
endlocal

0

批处理/CMD文件,例如DateAndTime.cmd不在CMD控制台中

代码:

SETLOCAL EnableDelayedExpansion
(set d=%date:~8,2%-%date:~3,2%-%date:~0,2%) & (set t=%time::=.%) & (set t=!t: =0!) & (set STAMP=!d!__!t!)

创建输出:
echo %stamp%

输出:

2020-02-25__08.43.38.90

同时也可以在CMD控制台和BATCH/CMD文件中使用

set d=%date:~6,4%-%date:~3,2%-%date:~0,2%
set t=%time::=.%
set t=%t: =0%
set stamp=%d%__%t%

"Create output" 和 "Output" 与上述相同


0
过去,我曾经使用在互联网上找到的.cmd脚本。我讨厌本地化通常会干扰日期格式的方式。如果您在文件名(或其他任何地方,如果我可以这么说)中有日期,我认为您希望它们以ISO 8601格式显示:

2015-02-19T14:54:51Z

或者是按照Y M D H M顺序排列的其他格式,例如

2015-02-19 14:54

因为它可以解决MDY / DMY的歧义,并且作为文本可排序。

我不知道我从哪里得到那个.cmd脚本,但它可能是http://ss64.com/nt/syntax-getdate.html,在我的YYYY-MM-DD Windows 8.1和M/D/YYYY原始安装的Windows 7上都可以完美运行。两者都提供相同的格式:

2015-02-09 04:43


0

它需要完整的时间格式为DD-MM-YYYY_HH-MM-SS.TT,其中TT是ticks。异常信息已经说明了一切。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接