我在命令行上使用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
?
答案 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 /T
和time /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%
当然,所描述的问题的发生是不可能的,但是在某一时刻它会发生并导致奇怪的无法解释的故障。
对于用户answer在Stephan和用户{{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
它将提供以下参数:
然后您可以像这样配置格式:
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"