Windows批处理:格式化date到variables

如何将YYYY-MM-DD格式的当前date保存到Windows .bat文件中的某个variables中? Unix shell模拟:

today=`date +%F` echo $today 

谢谢

您可以使用与区域无关的方式获取当前date

 for /f "skip=1" %%x in ('wmic os get localdatetime') do if not defined MyDate set MyDate=%%x 

然后你可以使用子string提取各个部分:

 set today=%MyDate:~0,4%-%MyDate:~4,2%-%MyDate:~6,2% 

另一种方式,你得到包含单个部分的variables,将是:

 for /f %%x in ('wmic path win32_localtime get /format:list ^| findstr "="') do set %%x set today=%Year%-%Month%-%Day% 

比摆弄子串好得多,代价是污染variables名称空间。

如果您需要UTC而不是本地时间,则该命令或多或less是相同的:

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

如果你想在一个batch file中使用标准的MS-DOS命令来实现这一点,那么你可以使用:

 FOR /F "TOKENS=1 eol=/ DELIMS=/ " %%A IN ('DATE/T') DO SET dd=%%A FOR /F "TOKENS=1,2 eol=/ DELIMS=/ " %%A IN ('DATE/T') DO SET mm=%%B FOR /F "TOKENS=1,2,3 eol=/ DELIMS=/ " %%A IN ('DATE/T') DO SET yyyy=%%C 

我相信这可以进一步改善,但这个date为日(dd),月(mm)和年(yyyy)3个variables。 您可以稍后在批处理脚本中根据需要使用它们。

 SET todaysdate=%yyyy%%mm%%dd% echo %dd% echo %mm% echo %yyyy% echo %todaysdate% 

虽然我明白这个问题的答案已经被接受了,但是这个替代方法可能会被许多人看到,而不使用WMI控制台来实现这一点,所以我希望它为这个问题增加了一些价值。

使用date / T在命令提示符下查找格式。

如果date格式是“Thu 03/03/2016”,请使用如下所示:

 set datestr=%date:~10,4%-%date:~7,2%-%date:~4,2% echo %datestr% 

还有两种方法不依赖于时间设置(两者都取自:如何从本地化获取数据/时间独立性 )。而且两者都获得一周中的哪一天,而且它们都不需要pipe理员权限!

1. MAKECAB – 将在每个窗口系统上工作(快速,但创build一个小临时文件)(foxidrive脚本):

 @echo off pushd "%temp%" makecab /D RptFileName=~.rpt /D InfFileName=~.inf /f nul >nul for /f "tokens=3-7" %%a in ('find /i "makecab"^<~.rpt') do ( set "current-date=%%e-%%b-%%c" set "current-time=%%d" set "weekday=%%a" ) del ~.* popd echo %weekday% %current-date% %current-time% pause 

2. ROBOCOPY – 它不是windows xp和win 2003的原生命令,但可以从微软站点下载 。但是内置于Vista和以上的所有软件:

  @echo off setlocal for /f "skip=8 tokens=2,3,4,5,6,7,8 delims=: " %%D in ('robocopy /l * \ \ /ns /nc /ndl /nfl /np /njh /XF * /XD *') do ( set "dow=%%D" set "month=%%E" set "day=%%F" set "HH=%%G" set "MM=%%H" set "SS=%%I" set "year=%%J" ) echo Day of the week: %dow% echo Day of the month : %day% echo Month : %month% echo hour : %HH% echo minutes : %MM% echo seconds : %SS% echo year : %year% endlocal 

还有三种使用其他窗口脚本语言的方法。他们会给你更多的灵活性,例如你可以得到一年的一周,毫秒的时间等等。

3. JSCRIPT / BATCH混合(需要保存为.bat ).Jscript可以在每个NT或更高版本的系统上使用,作为Windows脚本主机的一部分( 虽然可以通过registry禁用,但这种情况很less见 ):

 @if (@X)==(@Y) @end /* ---Harmless hybrid line that begins a JScript comment @echo off cscript //E:JScript //nologo "%~f0" exit /b 0 *------------------------------------------------------------------------------*/ function GetCurrentDate() { // Today date time which will used to set as default date. 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); return todayDate; } WScript.Echo(GetCurrentDate()); 

4. VBSCRIPT / BATCH混合( 可以在batch file中embedded和执行VBScript而不使用临时文件? )与jscript相同,但是混合并不完美:

 :sub echo(str) :end sub echo off '>nul 2>&1|| copy /Y %windir%\System32\doskey.exe %windir%\System32\'.exe >nul '& echo current date: '& cscript /nologo /E:vbscript "%~f0" '& exit /b '0 = vbGeneralDate - Default. Returns date: mm/dd/yy and time if specified: hh:mm:ss PM/AM. '1 = vbLongDate - Returns date: weekday, monthname, year '2 = vbShortDate - Returns date: mm/dd/yy '3 = vbLongTime - Returns time: hh:mm:ss PM/AM '4 = vbShortTime - Return time: hh:mm WScript.echo Replace(FormatDateTime(Date,1),", ","-") 

5. POWERSHELL – 可以安装在每台有.net的机器上 – 从微软下载( v1 , v2 , v3) (只适用于win7及以上版本)。默认情况下安装在Win7 / Win2008及以上的版本:

 C:\>powershell get-date -format "{dd-MMM-yyyy HH:mm}" 

6. 自编译的jscript.net/batch (从来没有见过没有.net的Windows机器,所以我认为这是一个非常便携的):

 @if (@X)==(@Y) @end /****** silent line that start jscript comment ****** @echo off :::::::::::::::::::::::::::::::::::: ::: compile the script :::: :::::::::::::::::::::::::::::::::::: setlocal if exist "%~n0.exe" goto :skip_compilation set "frm=%SystemRoot%\Microsoft.NET\Framework\" :: searching the latest installed .net framework for /f "tokens=* delims=" %%v in ('dir /b /s /a:d /o:-n "%SystemRoot%\Microsoft.NET\Framework\v*"') do ( if exist "%%v\jsc.exe" ( rem :: the javascript.net compiler set "jsc=%%~dpsnfxv\jsc.exe" goto :break_loop ) ) echo jsc.exe not found && exit /b 0 :break_loop call %jsc% /nologo /out:"%~n0.exe" "%~dpsfnx0" :::::::::::::::::::::::::::::::::::: ::: end of compilation :::: :::::::::::::::::::::::::::::::::::: :skip_compilation "%~n0.exe" exit /b 0 ****** end of jscript comment ******/ import System; import System.IO; var dt=DateTime.Now; Console.WriteLine(dt.ToString("yyyy-MM-dd hh:mm:ss")); 

7. Logman这不能得到星期几和星期。它比较慢,也创build一个临时文件,并且基于logman放在它的日志文件上的时间戳。将工作从XP和以上的一切。可能是永远不会被任何人使用 – 包括我 – 但是还有一种方法…

 @echo off setlocal del /q /f %temp%\timestampfile_* Logman.exe stop ts-CPU 1>nul 2>&1 Logman.exe delete ts-CPU 1>nul 2>&1 Logman.exe create counter ts-CPU -sc 2 -v mmddhhmm -max 250 -c "\Processor(_Total)\%% Processor Time" -o %temp%\timestampfile_ >nul Logman.exe start ts-CPU 1>nul 2>&1 Logman.exe stop ts-CPU >nul 2>&1 Logman.exe delete ts-CPU >nul 2>&1 for /f "tokens=2 delims=_." %%t in ('dir /b %temp%\timestampfile_*^&del /q/f %temp%\timestampfile_*') do set timestamp=%%t echo %timestamp% echo MM: %timestamp:~0,2% echo dd: %timestamp:~2,2% echo hh: %timestamp:~4,2% echo mm: %timestamp:~6,2% endlocal exit /b 0 

有关get-date函数的更多信息 。


只需使用%date%variables:

 echo %date% 

我真的很喜欢乔伊的方法,但我想我会扩展一下。

在这种方法中,您可以多次运行代码,而不必担心旧date值“滞留”,因为它已经被定义。

每次运行此batch file时,都会输出ISO 8601兼容的组合date和时间表示。

 FOR /F "skip=1" %%D IN ('WMIC OS GET LocalDateTime') DO (SET LIDATE=%%D & GOTO :GOT_LIDATE) :GOT_LIDATE SET DATETIME=%LIDATE:~0,4%-%LIDATE:~4,2%-%LIDATE:~6,2%T%LIDATE:~8,2%:%LIDATE:~10,2%:%LIDATE:~12,2% ECHO %DATETIME% 

在这个版本中,你必须小心不要将相同的代码复制/粘贴到文件中的多个位置,因为这会导致重复的标签。 您可以为每个副本分别添加一个标签,也可以将这些代码放入自己的batch file中,并在需要时从源文件中调用。

我通过这样设置一个环境variables到数值格式的值:

FOR / F“令牌= 1,2,3,4 delims = /”%a IN('echo%date%')DO set DateRun =%d-%b-%c

根据@ProVi的回答,只需更改以适应您所需的格式

 echo %DATE:~10,4%-%DATE:~7,2%-%DATE:~4,2% %TIME:~0,2%:%TIME:~3,2%:%TIME:~6,2% 

将返回

 yyyy-MM-dd hh:mm:ss 2015-09-15 18:36:11 

编辑根据@Jeb评论,谁是正确的上述时间格式将只适用于如果您的DATE / T命令返回

 ddd dd/mm/yyyy Thu 17/09/2015 

然而,通过使用相关%DATE%环境variables返回的string中的每个字符的索引,可以很容易地编辑以适应您的语言环境,从而可以提取所需的string部分。

例如。 使用%DATE〜10,4%将展开DATE环境variables,然后仅使用从展开结果的第11个(偏移量为10)字符开始的4个字符

例如,如果使用美式date,则适用以下内容

 ddd mm/dd/yyyy Thu 09/17/2015 echo %DATE:~10,4%-%DATE:~4,2%-%DATE:~7,2% %TIME:~0,2%:%TIME:~3,2%:%TIME:~6,2% 2015-09-17 18:36:11 

检查这一个..

 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 "MS=%dt:~15,3%" set "datestamp=%YYYY%%MM%%DD%" & set "timestamp=%HH%%Min%%Sec%" & set "fullstamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%-%MS%" echo datestamp: "%datestamp%" echo timestamp: "%timestamp%" echo fullstamp: "%fullstamp%" pause 

如果你安装了python,你可以这样做

 python -c "import datetime;print(datetime.date.today().strftime('%Y-%m-%d'))" 

您可以轻松地调整格式string以满足您的需求。

 echo %DATE:~10,4%%DATE:~7,2%%DATE:~4,2% 

有可能使用powershell并通过使用循环将其输出redirect到环境variables。

从命令行( cmd ):

 for /f "tokens=*" %a in ('powershell get-date -format "{yyyy-mm-dd+HH:mm}"') do set td=%a echo %td% 2016-25-02+17:25 

在batch file中,您可能会将%a转义为%%a

 for /f "tokens=*" %%a in ('powershell get-date -format "{yyyy-mm-dd+HH:mm}"') do set td=%%a 

如果您不介意10到30分钟的一次性投资以获得可靠的解决scheme(不依赖于Windows的区域设置),请继续阅读。

让我们释放我们的思想。 你想简化脚本看起来像这样吗? (假设你想设置LOG_DATETIMEvariables)

 FOR /F "tokens=* USEBACKQ" %%F IN (`FormatNow "yyyy-MM-dd"`) DO ( Set LOG_DATETIME=%%F ) echo I am going to write log to Testing_%LOG_DATETIME%.log 

您可以。 只需使用C#.NET构buildFormatNow.exe,并将其添加到PATH中。

笔记:

  1. 您可以使用任何Visual Studio版本(如Visual Studio Express)来构buildFormatNow.exe。
  2. 在Visual Studio中,select“控制台应用程序”C#项目,而不是“Windows窗体应用程序”项目。
  3. 常识:构build的FormatNow.exe将需要运行.NET Framework。
  4. 常识:将FormatNow.exe添加到PATHvariables后,需要重新启动CMD才能生效。 它也适用于环境variables的任何变化。

优点:

  1. 这并不慢(在0.2秒内完成)。
  2. 支持多种格式https://msdn.microsoft.com/zh-cn/library/8kb3ddd4(v=vs.110).aspx例如FormatNow“ddd”仅获取星期几,FormatNow“yyyy”仅获取那一年
  3. 它不依赖于Windows的区域设置,所以它的输出更可靠。 另一方面,%date%不会在不同的计算机上提供一致的格式,并且不可靠。
  4. 您不需要创build如此多的CMDvariables并污染variables名称空间。
  5. 在批处理脚本中需要3行来调用程序并获得结果。 这应该是相当短的。

我使用Visual Studio 2010构build的FormatNow.exe的源代码(我更喜欢自己构build,以避免下载未知的,可能是恶意的程序的风险)。 只需复制和粘贴下面的代码,一次构build程序,然后您有一个可靠的date格式化程序为所有未来的使用。

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Globalization; namespace FormatNow { class Program { static void Main(string[] args) { try { if (args.Length < 1) { throw new ArgumentException("Missing format"); } string format = args[0]; Console.Write(DateTime.Now.ToString(format, CultureInfo.InvariantCulture.DateTimeFormat)); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } } } 

一般来说,在处理复杂的逻辑时,我们可以通过构build一个非常小的程序并调用程序来将输出捕获回批处理脚本variables来简化它。 我们不是学生,我们没有参加考试,要求我们遵循批处理脚本规则来解决问题。 在真实的工作环境中,任何(合法的)方法都是允许的。 为什么我们仍然坚持需要解决许多简单任务的Windows批处理脚本的糟糕function? 为什么我们应该使用错误的工具来完成这项工作?