当从服务器2016中的计划任务运行时,%date%在batch file中产生不同的结果

batch file正在运行robocopy并创build一个日志文件robocopyServer_%date%.txt

batch file手动运行时,结果是robocopyServer_yyyy-mm-dd.txt

当batch file从计划任务运行时,结果是robocopyServer_Tue(或者一周中的哪一天),并且没有文件扩展名。

此batch file在Server 2012R2(手动或计划任务)下完美运行。

%日期%或date /t并不总是可靠的,因为它取决于地区和用户设置。 以下是如何获得普遍有效的日期:

 for /f %%# in ('wmic os get localdatetime^|findstr .') do if "%%#" neq "" set date=%%# set date=%date:~,4%-%date:~4,2%-%date:~6,2% echo %date% 

这将以yyyy-mm-dd格式回显当前日期。

环境变量DATETIME的字符串格式取决于所使用帐户的Windows Region和Language设置。

独立的日期/时间字符串可以使用Windows Management Instrumentation命令行工具WMIC获取

使用命令行

 wmic OS GET LocalDateTime /VALUE 

输出例如UTF-16 Little Endian编码:

 LocalDateTime=20170621095402.953000+120 

有两个空行,然后是格式为YYYYMMDDHHmmSS.microsecond的当前区域设置日期/时间的行,以分钟为单位的UTC偏移量和另外两个空行。

这些数据可以像这样使用批处理代码:

 @echo off for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "FileNameDate=%%I" set "FileNameDate=%FileNameDate:~0,4%-%FileNameDate:~4,2%-%FileNameDate:~6,2%" echo %FileNameDate% 

对文件和文件夹名称感兴趣的只是等号和小数点之间的日期/时间字符串,这是使用for /F选项tokens=2 delims==. 得到只是20170621095402分配给循环变量I的值其环境变量FileNameDate旁边分配的值。

环境变量FileNameDate使用字符串替换重新格式化,以得到格式YYYY-MM-DD日期字符串,该格式输出用于2017-06-21验证。

使用WMIC获取本地日期/时间的优势在Windows区域和语言设置上是独立的。 缺点是命令执行需要花费相当长的时间(1到2秒),而使用几微秒内访问的DATETIME环境变量。

命令FOR有解析Unicode输出正确的问题。 它在WMIC输出结束时解释字节序列0D 00 0A 00 0D 00 0A 00,因为两条空行为0D 0D 0A,即两个回车符和一个换行符。 这导致将WMIC输出结尾处的最后两个空行解释为单个行,并将单个回车作为字符串返回。

这通常是一个问题,因为set "EnvironmentVariable=%%I"%%I扩展到只是回车删除已经定义的环境变量之前正确的值。

有多种解决方案来解决这个FOR命令的Unicode解析错误。 一旦将值分配给环境变量以避免遇到这个问题,就可以追加& goto Label来退出循环,跳转到:Label FOR循环下的:Label

另一个解决方案是在这个代码中使用的。 由于使用WMIC选项/VALUE ,属性的名称和它的值在同一行输出。 命令FOR运行命令SET,因为只有当由于分号delims==.使用等号和点作为分隔符将当前行分割成至少2个子字符串(标记)时,才能使用tokens=2 delims==. 但是WMIC输出的错误解析结束是FOR一行只包含一个回车,因此没有第二个标记。 由于这个原因,错误的解析空行在这里也被忽略了。

请参阅解析输出时如何更正变量覆盖不当行为? 而cmd是以某种方式写中文文本作为输出 ,详细解析UTF-16 LE编码输出的FOR的解析问题。

为了理解使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。

  • echo /?
  • for /?
  • set /?
  • wmic /?
  • wmic os /?
  • wmic os get /?
  • wmic os get localdatetime /?