文件名中的批处理命令日期和时间

时间:2011-10-11 13:49:01

标签: windows batch-file command-line cmd

我在命令行上使用WinZip压缩文件。由于我们每天都会存档,因此我尝试为这些文件添加日期和时间,以便每次都自动生成一个新文件。

我使用以下命令生成文件名。将其粘贴到命令行,您应该看到一个带有日期和时间组件的文件名。

echo Archive_%date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.zip

输出

Archive_20111011_ 93609.zip

但是,我的问题是 AM vs PM 。 AM时间戳给我时间9(带有前导空格)与10自然占用两个空格。

我想我的问题将延续到前9天,前9个月等等。

如何解决此问题,以便包含前导零而不是前导空格,以便我得到Archive_20111011_093609.zip

15 个答案:

答案 0 :(得分:58)

另一种解决方案:

for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set datetime=%%I

它会给你(独立于区域设置!):

  20130802203023.304000+120
( YYYYMMDDhhmmss.<milliseconds><always 000>+/-<timedifference to UTC>  )

从这里开始,很容易:

set datetime=%datetime:~0,8%-%datetime:~8,6%
20130802-203023

对于Logan请求对文件的“日期时间修改”的相同输出格式:

for %%F in (test.txt) do set file=%%~fF
for /f "tokens=2 delims==" %%I in ('wmic datafile where name^="%file:\=\\%" get lastmodified /format:list') do set datetime=%%I
echo %datetime%

它有点复杂,因为它仅适用于完整路径,wmic期望反斜杠加倍并且=必须被转义(第一个。第二个受保护通过周围的引号)。

答案 1 :(得分:54)

提取小时,寻找前导空格,如果找到则替换为零;

set hr=%time:~0,2%
if "%hr:~0,1%" equ " " set hr=0%hr:~1,1%
echo Archive_%date:~-4,4%%date:~-10,2%%date:~-7,2%_%hr%%time:~3,2%%time:~6,2%.zip

答案 2 :(得分:19)

  

你应该搜索;您只需将所有空格替换为零set hr=%hr: =0% - jeb Oct 11 '11 at 14:16

所以我做了:

set hr=%time:~0,2%
set hr=%hr: =0%

然后在您格式化的任何字符串中使用%hr%,总是得到两位数的小时。

(杰布在最受欢迎的答案下的评论对我来说是最好的,也是最简单的。我在此重新发布,以使其对未来的用户更明显。)

答案 3 :(得分:15)

正如Vicky已经指出的那样,%DATE%%TIME%使用完全(无限制)自定义的短日期和时间格式返回当前日期和时间。

一个用户可以将其系统配置为返回Fri040811 08.03PM,而另一个用户可以选择08/04/2011 20:30。

对于BAT程序员来说,这是一场彻底的噩梦。

如果在退出BAT文件之前还原以前的格式,则将格式更改为固定格式可能会解决问题。但它可能会受到令人讨厌的竞争条件的影响,并且在取消的BAT文件中恢复也很复杂。

幸运的是,还有另一种选择。

您可以使用WMIC。 WMIC Path Win32_LocalTime Get Day,Hour,Minute,Month,Second,Year /Format:table以不变的方式返回日期和时间。使用FOR /F命令直接解析它非常方便。

所以,把这些碎片放在一起,试试这个作为起点...

SETLOCAL enabledelayedexpansion
FOR /F "skip=1 tokens=1-6" %%A IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table') DO (
  SET /A FD=%%F*1000000+%%D*100+%%A
  SET /A FT=10000+%%B*100+%%C
  SET FT=!FT:~-4!
  ECHO Archive_!FD!_!FT!.zip
 )

答案 4 :(得分:8)

在阅读完所有答案后,我找到了最佳解决方案:

set t=%date%_%time%
set d=%t:~10,4%%t:~7,2%%t:~4,2%_%t:~15,2%%t:~18,2%%t:~21,2%
echo hello>"Archive_%d%"

如果我得到20160915_ 150101(带有前导空格和时间)。

如果我得到20160915_2150101

答案 5 :(得分:4)

您可以在批处理中将前导零添加到变量(值最多99),如下所示: IF 1%Var% LSS 100 SET Var=0%Var%

因此,您需要将日期和时间组件解析为单独的变量,将它们全部处理,然后将它们连接在一起以创建文件名。

但是,解析日期和时间的基础方法取决于系统区域设置。如果您对代码不能移植到其他机器感到高兴,那可能没问题,但是如果您希望它在不同的国际环境中工作,那么您将需要一种不同的方法,例如通过读取注册表设置: / p>

HKEY_CURRENT_USER\Control Panel\International\iDate
HKEY_CURRENT_USER\Control Panel\International\iTime
HKEY_CURRENT_USER\Control Panel\International\iTLZero

(最后一个控制时间是否有前导零,但据我所知,不是日期)。

答案 6 :(得分:3)

@For /F "tokens=1,2,3,4 delims=/ " %%A in ('Date /t') do @(

Set DayW=%%A

Set Day=%%B

Set Month=%%C


Set Year=%%D


Set All=%%D%%B%%C
)
"C:\Windows\CWBZIP.EXE" "c:\transfer\ziptest%All%.zip" "C:\transfer\MB5L.txt"

如果在2012年2月4日运行,则需要MB5L.txt并将其压缩为ziptest20120204.zip

答案 7 :(得分:2)

从上面的答案中,我已经制作了一个即用型功能。

使用法国本地设置验证。

:::::::: PROGRAM ::::::::::

call:genname "my file 1.txt"
echo "%newname%"
call:genname "my file 2.doc"
echo "%newname%"

echo.&pause&goto:eof
:::::::: FUNCTIONS :::::::::

:genname
    set d1=%date:~-4,4%
    set d2=%date:~-10,2%
    set d3=%date:~-7,2%
    set t1=%time:~0,2%
    ::if "%t1:~0,1%" equ " " set t1=0%t1:~1,1%
    set t1=%t1: =0%
    set t2=%time:~3,2%
    set t3=%time:~6,2%
    set filename=%~1
    set newname=%d1%%d2%%d3%_%t1%%t2%%t3%-%filename%
goto:eof

答案 8 :(得分:1)

你的问题似乎已经解决了,但是......

我不确定您是否为您的问题采取了正确的解决方案 我想你试着每天压缩实际的项目代码。

使用ZIP和1980这是可能的,这是一个很好的解决方案,但今天您应该使用存储库系统,如subversion或git或...,但不是zip文件。

好吧,也许可能是我错了。

答案 9 :(得分:0)

我意识到这对OP来说是一个没有实际意义的问题,但我只是酝酿了这一点,而且我为自己在盒子外思考而感到自豪。

gawk下载适用于Windows的http://gnuwin32.sourceforge.net/packages/gawk.htm ....然后它是一个单行,没有那么笨重的DOS批处理语法,需要六个FOR循环来分割字符串(WTF?那真的真的很糟糕又疯了!...当然是恕我直言}

如果您已经了解C,C ++,Perl或Ruby,那么选择AWK(继承前两者,并对后两者做出重大贡献)就是一个众所周知的CAKE!

DOS批处理命令:

echo %DATE% %TIME% && echo %DATE% %TIME% | gawk -F"[ /:.]" "{printf(""""%s%02d%02d-%02d%02d%02d\n"""", $4, $3, $2, $5, $6, $7);}"

<强>打印

Tue 04/09/2012 10:40:38.25
20120904-104038

现在这还不是完整的故事...我只是懒得并在printf语句中硬编码我的其余日志文件名,因为它很简单......但是如果有人知道如何将%NOW%变量设置为AWK的输出(那是“通用”现在功能的内容)然后我全都听见了。


修改

快速搜索Stack Overflow,填写了最后一块拼图 Batch equivalent of Bash backticks

所以,这三行DOS批次:

echo %DATE% %TIME% | awk -F"[ /:.]" "{printf(""""%s%02d%02d-%02d%02d%02d\n"""", $4, $3, $2, $5, $6, $7);}" >%temp%\now.txt
set /p now=<%temp%\now.txt
echo %now%

农产品:

20120904-114434

所以现在我可以在我的SQL Server安装(2005+)脚本生成的日志文件的名称中包含一个日期时间:

sqlcmd -S .\SQLEXPRESS -d MyDb -e -i MyTSqlCommands.sql >MyTSqlCommands.sql.%now%.log

我又是一个快乐的露营者(除了生活在Unix上更容易SOOOOO)。

答案 10 :(得分:0)

文件名中的空格是合法的。如果您将路径和文件名放在引号中,它可能会飞。这是我在批处理文件中使用的内容:

svnadmin hotcopy "C:\SourcePath\Folder" "f:\DestPath\Folder%filename%"

%filename%中是否有空格并不重要。

答案 11 :(得分:0)

正如其他人已经指出的那样,%DATE%%TIME%(以及date /Ttime /T)的日期和时间格式取决于语言环境,因此提取当前的日期和时间始终是一场噩梦,由于几乎没有格式限制,因此不可能获得适用于所有可能格式的解决方案。


但是下面的代码存在另一个问题(让我们假设日期格式为MM/DD/YYYY,而12小时制时间格式为h:mm:ss ap,其中ap为{{ 1}}或AM):

PM

rem // Resolve AM/PM time: set "HOUR=%TIME:~,2%" if "%TIME:~-2%" == "PM" if %HOUR% lss 12 set /A "HOUR+=12" if "%TIME:~-2%" == "AM" if %HOUR% equ 12 set /A "HOUR-=12" rem // Left-zero-pad hour: set "HOUR=0%HOUR%" rem // Build and display date/time string: echo %DATE:~-4,4%%DATE:~0,2%%DATE:~3,2%_%HOUR:~-2%%TIME:~3,2%%TIME:~6,2% %DATE%的每个实例返回扩展时出现的日期或时间值,因此第一个%TIME%%DATE%表达式可能返回不同的值比以下值更有价值(您可以证明,在回显包含大量此类(最好是%TIME%这些表达式的长字符串时)。

您可以改进上述代码,以容纳%TIME%%DATE%的单个实例,如下所示:

%TIME%

但是,rem // Store current date and time once in the same line: set "CURRDATE=%DATE%" & set "CURRTIME=%TIME%" rem // Resolve AM/PM time: set "HOUR=%CURRTIME:~,2%" if "%CURRTIME:~-2%" == "PM" if %HOUR% lss 12 set /A "HOUR+=12" if "%CURRTIME:~-2%" == "AM" if %HOUR% equ 12 set /A "HOUR-=12" rem // Left-zero-pad hour: set "HOUR=0%HOUR%" rem // Build and display date/time string: echo %CURRDATE:~-4,4%%CURRDATE:~0,2%%CURRDATE:~3,2%_%HOUR:~-2%%CURRTIME:~3,2%%CURRTIME:~6,2% %DATE%中返回的值在午夜执行时可能反映不同的日期。

%TIME%%CURRDATE%中拥有同一天的唯一方法是:

%CURRTIME%

当然,所描述的问题的发生是不可能的,但是在某一时刻它会发生并导致奇怪的无法解释的故障。


对于用户answerStephan和用户{{3}在answer中基于rem // Store current date and time once in the same line: set "CURRDATE=%DATE%" & set "CURRTIME=%TIME%" rem // Resolve AM/PM time: set "HOUR=%CURRTIME:~,2%" if "%CURRTIME:~-2%" == "PM" if %HOUR% lss 12 set /A "HOUR+=12" if "%CURRTIME:~-2%" == "AM" if %HOUR% equ 12 set /A "HOUR-=12" rem // Fix date/time midnight discrepancy: if not "%CURRDATE%" == "%DATE%" if %CURRTIME:~0,2% equ 0 set "CURRDATE=%DATE%" rem // Left-zero-pad hour: set "HOUR=0%HOUR%" rem // Build and display date/time string: echo %CURRDATE:~-4,4%%CURRDATE:~0,2%%CURRDATE:~3,2%_%HOUR:~-2%%CURRTIME:~3,2%%CURRTIME:~6,2% 命令的方法中,上述问题不会发生},因此我强烈建议您选择其中之一。 wmic的唯一缺点是速度慢。

答案 12 :(得分:0)

我倾向于在current accepted answer from Stephan上使用它,因为这样可以在此之后使用命名参数配置时间戳:

for /f %%x in ('wmic path win32_utctime get /format:list ^| findstr "="') do set %%x

它将提供以下参数:

  • DayOfWeek
  • 小时
  • 毫秒
  • 分钟
  • 四分之一
  • 第二
  • WeekInMonth
  • 年份

然后您可以像这样配置格式:

SET DATE=%Year%%Month%%Day%

答案 13 :(得分:0)

因此,您想要生成格式为YYYYMMDD_hhmmss的日期。 由于%date%%time%格式取决于语言环境,因此您可能需要更强大的方法来获取格式化日期。

这里是一个选择:

@if (@X)==(@Y) @end /*
    @cscript //E:JScript //nologo "%~f0"
    @exit /b %errorlevel%
@end*/
var todayDate = new Date();
todayDate = "" + 
    todayDate.getFullYear() + 
    ("0" + (todayDate.getMonth() + 1)).slice(-2) +
    ("0" + todayDate.getDate()).slice(-2) + 
    "_" + 
    ("0" + todayDate.getHours()).slice(-2) +
    ("0" + todayDate.getMinutes()).slice(-2) +
    ("0" + todayDate.getSeconds()).slice(-2) ;
WScript.Echo(todayDate);

,如果将脚本另存为jsdate.bat,则可以将其分配为值:

for /f %%a in ('jsdate.bat') do @set "fdate=%%a"
echo %fdate%

或直接从命令提示符处

for /f %a in ('jsdate.bat') do @set "fdate=%a"

或者您可以使用powershell,这可能是需要较少代码的方式:

for /f %%# in ('powershell Get-Date -Format "yyyyMMdd_HHmmss"') do set "fdate=%%#"

答案 14 :(得分:0)

在此答案列表中添加其他选项。

您可以用 0 替换空白区域,例如 echo %time: =0%

但这仍然是依赖的,将代码移动到其他随机位置的好友 PC 上,您会得到有趣的输出。因此,您可以合并 powershell 的 Get-Date:

for /f "tokens=*" %%i in ('PowerShell -Command "Get-Date -format 'yyyymmdd_HHmmss'"') do echo %%i.zip"