如何将 YYYY-MM-DD 格式的当前日期保存到 Windows .bat 文件中的某个变量中?
Unix shell 类似物:
today=`date +%F`
echo $today
如何将 YYYY-MM-DD 格式的当前日期保存到 Windows .bat 文件中的某个变量中?
Unix shell 类似物:
today=`date +%F`
echo $today
您可以使用与语言环境无关的方式获取当前日期
for /f "skip=1" %%x in ('wmic os get localdatetime') do if not defined MyDate set MyDate=%%x
然后您可以使用子字符串提取各个部分:
set today=%MyDate:~0,4%-%MyDate:~4,2%-%MyDate:~6,2%
另一种方法是,您可以获得包含各个部分的变量:
for /f %%x in ('wmic path win32_localtime get /format:list ^| findstr "="') do set %%x
set today=%Year%-%Month%-%Day%
比摆弄子字符串要好得多,但会污染变量命名空间。
如果您需要 UTC 而不是本地时间,该命令或多或少是相同的:
for /f %%x in ('wmic path win32_utctime get /format:list ^| findstr "="') do set %%x
set today=%Year%-%Month%-%Day%
用于date /T
在命令提示符下查找格式。
如果日期格式是Thu 17/03/2016
这样使用的:
set datestr=%date:~10,4%-%date:~7,2%-%date:~4,2%
echo %datestr%
如果您希望在批处理文件中使用标准 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
我确信这可以进一步改进,但这会将日期分为 3 个变量,分别代表日 (dd)、月 (mm) 和年 (yyyy)。然后,您可以稍后根据需要在批处理脚本中使用它们。
SET todaysdate=%yyyy%%mm%%dd%
echo %dd%
echo %mm%
echo %yyyy%
echo %todaysdate%
虽然我知道这个问题的答案已被接受,但许多希望在不使用 WMI 控制台的情况下实现这一目标的人可能会喜欢这种替代方法,所以我希望它为这个问题增加一些价值。
另外两种不依赖于时间设置的方法(均取自How get data/time Independent from localization)。两者也都获得了星期几,而且都不需要管理员权限!:
MAKECAB - 适用于每个 Windows 系统(速度快,但会创建一个小的临时文件)(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
ROBOCOPY - 它不是Windows XP和Windows Server 2003的本机命令,但可以从 Microsoft 站点下载。但它内置于 Windows 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
还有另外三种使用其他 Windows 脚本语言的方法。它们会给你更多的灵活性,例如你可以得到一年中的一周,毫秒的时间等等。
JScript/BATCH混合(需要另存为.bat
)。JScript 在Windows NT及更高版本的每个系统上都可用,作为Windows Script Host的一部分(虽然可以通过注册表禁用,但这种情况很少见):
@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());
VBScript/BATCH混合(是否可以在不使用临时文件的情况下在批处理文件中嵌入和执行 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), ", ", "-")
PowerShell - 可以安装在每台具有 .NET 的机器上 - 从 Microsoft 下载(v1、v2和v3(仅适用于 Windows 7 及更高版本))。默认安装在 Windows 7/Win2008 及更高版本的所有设备上:
C:\> powershell get-date -format "{dd-MMM-yyyy HH:mm}"
自编译 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"));
Logman这不能得到星期几。它相对较慢,还创建一个临时文件,并且基于 logman 在其日志文件上放置的时间戳。适用于 Windows 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
根据@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% 环境变量返回的字符串中每个字符的索引,您可以提取所需的字符串部分。
例如。使用 %DATE~10,4% 将扩展 DATE 环境变量,然后仅使用从扩展结果的第 11 个(偏移量 10)字符开始的 4 个字符
例如,如果使用美式日期,则以下适用
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
我真的很喜欢 Joey 的方法,但我想我会进一步扩展它。
在这种方法中,您可以多次运行代码,而不必担心旧的日期值“保留”,因为它已经定义了。
每次运行此批处理文件时,它将输出与 ISO 8601 兼容的组合日期和时间表示。
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%
在此版本中,您必须小心不要将相同的代码复制/粘贴到文件中的多个位置,因为这会导致标签重复。您可以为每个副本设置一个单独的标签,或者只是将此代码放入其自己的批处理文件中,并在必要时从源文件中调用它。
只需使用%date%
变量:
echo %date%
我通过执行以下操作将环境变量设置为所需数字格式的值:
FOR /F "tokens=1,2,3,4 delims=/ " %a IN ('echo %date%') DO set DateRun=%d-%b-%c
检查这个..
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
这是乔伊答案的扩展,包括时间并用 0 填充部分。
例如,结果将是 2019-06-01_17-25-36。另请注意,这是 UTC 时间。
for /f %%x in ('wmic path win32_utctime get /format:list ^| findstr "="') do set %%x
set Month=0%Month%
set Month=%Month:~-2%
set Day=0%Day%
set Day=%Day:~-2%
set Hour=0%Hour%
set Hour=%Hour:~-2%
set Minute=0%Minute%
set Minute=%Minute:~-2%
set Second=0%Second%
set Second=%Second:~-2%
set TimeStamp=%Year%-%Month%-%Day%_%Hour%-%Minute%-%Second%
可以使用 PowerShell 并通过循环将其输出重定向到环境变量。
从命令行 ( 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
在批处理文件中,您可能会转义%a
为%%a
:
for /f "tokens=*" %%a in ('powershell get-date -format "{yyyy-MM-dd+HH:mm}"') do set td=%%a
如果你安装了 Python,你可以这样做
python -c "import datetime;print(datetime.date.today().strftime('%Y-%m-%d'))"
您可以根据需要轻松调整格式字符串。
由于日期和时间格式是特定于位置的信息,因此从 %date% 和 %time% 变量中检索它们需要额外的努力来解析带有格式转换的字符串。一个好主意是使用一些 API 来检索数据结构并根据需要进行解析。WMIC 是一个不错的选择。下面的示例使用Win32_LocalTime。您还可以使用Win32_CurrentTime或Win32_UTCTime。
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
for /f %%x in ('wmic path Win32_LocalTime get /format:list ^| findstr "="') do set %%x
set yyyy=0000%Year%
set mmmm=0000%Month%
set dd=00%Day%
set hh=00%Hour%
set mm=00%Minute%
set ss=00%Second%
set ts=!yyyy:~-4!-!mmmm:~-2!-!dd:~-2!_!hh:~-2!:!mm:~-2!:!ss:~-2!
echo %ts%
ENDLOCAL
结果:
2018-04-25_10:03:11
我正在使用以下内容:
set iso_date=%date:~6,4%-%date:~3,2%-%date:~0,2%
或与日志文件名称“MyLogFileName”结合使用:
set log_file=%date:~6,4%-%date:~3,2%-%date:~0,2%-MyLogFileName
echo %DATE:~10,4%%DATE:~7,2%%DATE:~4,2%
如果 powershell 可用,您可以使用以下代码:
# get date
$BuildDate=(get-date -format "yyMMdd")
echo BuildDate=$BuildDate
# get time
$BuildTime=(get-date -format "hhmmss")
echo BuildTime=$BuildTime
结果如下:
BuildDate=200518
BuildTime=115919
如果您不介意一次性投入 10 到 30 分钟来获得可靠的解决方案(不依赖于 Windows 的区域设置),请继续阅读。
让我们解放思想。您想简化脚本使其看起来像这样吗?(假设您要设置 LOG_DATETIME 变量)
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 构建一个 FormatNow.exe 并将其添加到您的 PATH 中。
笔记:
好处:
我使用 Visual Studio 2010 构建的 FormatNow.exe 的源代码(我更喜欢自己构建它以避免下载未知的可能是恶意程序的风险)。只需复制并粘贴下面的代码,构建一次程序,然后您就拥有了一个可靠的日期格式化程序以供将来使用。
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());
}
}
}
}
一般来说,在处理复杂的逻辑时,我们可以通过构建一个非常小的程序并调用该程序将输出捕获回一个批处理脚本变量来简化它。我们不是学生,我们不会参加要求我们遵循仅批处理脚本规则来解决问题的考试。在实际工作环境中,允许任何(合法)方法。为什么我们仍然要坚持许多简单任务需要变通方法的 Windows 批处理脚本的低劣功能?为什么我们应该使用错误的工具来完成这项工作?