Windows批处理:将日期格式化为变量

Mak*_*cha 99 windows batch-file

如何将当前日期以YYYY-MM-DD格式保存到Windows .bat文件中的某个变量中?

Unix shell模拟:

today=`date +%F`
echo $today
Run Code Online (Sandbox Code Playgroud)

Joe*_*oey 144

您可以使用与区域设置无关的方式获取当前日期

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

然后,您可以使用子字符串提取单个部分:

set today=%MyDate:~0,4%-%MyDate:~4,2%-%MyDate:~6,2%
Run Code Online (Sandbox Code Playgroud)

另一种方法,即获得包含各个部分的变量,将是:

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

比摆弄子串更好,代价是污染你的变量命名空间.

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

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

  • 请注意,如果多次运行上面的行,则不会为每次调用获取新日期,因为它会检查未定义的变量.这是必需的,因为`for/f`返回两行,后者是空行.您可以通过在它们之间使用`set MyDate =`来解决这个问题.我猜这就是user2023861偶然发现的事情. (5认同)
  • `for /f %%x in ('wmic path win32_localtime get /format:list ^| findstr "="') do set %%x set today=%Year%-%Month%-%Day%` 是无效答案:它返回**一位数**月份和日期。如何用零月份和日期字符串填充2位左数? (3认同)
  • 你好,它有效,谢谢。一个小问题。如何获得两位数的月份? (2认同)

ric*_*oke 36

如果您希望在批处理文件中使用标准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
Run Code Online (Sandbox Code Playgroud)

我确信这可以进一步改进,但这会将日期分为3个变量,分别为Day(dd),Month(mm)和Year(yyyy).然后,您可以根据需要在批处理脚本中使用它们.

SET todaysdate=%yyyy%%mm%%dd%
echo %dd%
echo %mm%
echo %yyyy%
echo %todaysdate%
Run Code Online (Sandbox Code Playgroud)

虽然我理解这个问题已经接受了答案,但是许多人希望在不使用WMI控制台的情况下实现这一目标,所以我希望它能为这个问题增加一些价值.

  • 我发现我需要在Windows 7机箱上略微改变它.令牌需要增加1:... FOR/F"TOKENS = 2,3,4 eol =/DELIMS = /"... (3认同)

小智 29

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

如果日期格式为"Thu 03/03/2016",请使用如下:

set datestr=%date:~10,4%-%date:~7,2%-%date:~4,2%
echo %datestr%
Run Code Online (Sandbox Code Playgroud)

  • 其他响应看起来像程序的原因是,这个答案虽然简单,但如果您的 Windows 区域设置未按照此代码期望的方式配置,则会失败(即此代码不适用于*每个* Windows 系统) (7认同)
  • 这是对所问问题的最接近的答案。我只需要一个简单的单行程序,而不是一个程序。 (3认同)
  • 同意 这里的一些答案几乎就像“安装MS SQL Server,连接SQL Client,并执行命令SELECT CONVERT(VARCHAR(16),GETDATE(),112)”。 (2认同)
  • ISO-8601格式的日期时间是'%date:~10,4 %% date:~7,2 %% date:~4,2%T%time:~0,2 %% time:~3, 2 %%时间:〜6,2%` (2认同)

npo*_*aka 19

另外两种不依赖于时间设置的方法(均来自如何获取数据/时间与本地化无关).而且两者都得到了一周的日子,而且没有一个需要管理员权限!:

  1. 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
    
    Run Code Online (Sandbox Code Playgroud)
  2. ROBOCOPY - 它不是Windows XPWindows 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
    
    Run Code Online (Sandbox Code Playgroud)

    还有三种使用其他Windows脚本语言的方法.它们将为您提供更多灵活性,例如您可以获得一年中的一周,时间以毫秒为单位等等.

  3. JScript/BATCH混合(需要保存为.bat).作为Windows脚本宿主的一部分,JScript在Windows NT及更高版本的每个系统上都可用(虽然可以通过注册表禁用它是一种罕见的情况):

    @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());
    
    Run Code Online (Sandbox Code Playgroud)
  4. 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), ", ", "-")
    
    Run Code Online (Sandbox Code Playgroud)
  5. PowerShell - 可以安装在每台具有.NET的计算机上 - 从Microsoft下载(v1,v2v3(仅适用于Windows 7及更高版本)).默认安装在Windows 7/Win2008及更高版本的所有内容上:

    C:\> powershell get-date -format "{dd-MMM-yyyy HH:mm}"
    
    Run Code Online (Sandbox Code Playgroud)
  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"));
    
    Run Code Online (Sandbox Code Playgroud)
  7. 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
    
    Run Code Online (Sandbox Code Playgroud)

有关Get-Date功能的更多信息.



aar*_*rkk 7

我真的很喜欢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%
Run Code Online (Sandbox Code Playgroud)

在此版本中,您必须小心不要将相同的代码复制/粘贴到文件中的多个位置,因为这会导致重复的标签.您可以为每个副本设置单独的标签,或者只是将此代码放入其自己的批处理文件中,并在必要时从源文件中调用它.


Mar*_*ark 7

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

echo %DATE:~10,4%-%DATE:~7,2%-%DATE:~4,2% %TIME:~0,2%:%TIME:~3,2%:%TIME:~6,2%
Run Code Online (Sandbox Code Playgroud)

将返回

yyyy-MM-dd hh:mm:ss
2015-09-15 18:36:11
Run Code Online (Sandbox Code Playgroud)

编辑 根据@Jeb 评论,谁是正确的,上述时间格式仅在您的 DATE /T 命令返回时才有效

ddd dd/mm/yyyy
Thu 17/09/2015
Run Code Online (Sandbox Code Playgroud)

很容易编辑以适应您的语言环境,但是,通过使用相关 %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
Run Code Online (Sandbox Code Playgroud)


小智 6

可以使用 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
Run Code Online (Sandbox Code Playgroud)

在批处理文件中,您可能会转义%a%%a

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

  • 掩码应该像这样 `FOR /F "tokens=*" %%a IN ('powershell get-date -format "{yyyy\-MM\-dd\THH\:mm\:ss}"') DO SET date =%%a` 因此请使用大写 MM 表示月份并使用反斜杠来转义文字字符。 (2认同)

小智 5

只需使用%date%变量:

echo %date%
Run Code Online (Sandbox Code Playgroud)

  • 这将以当前配置的短日期格式返回日期.这很少是ISO-8601. (4认同)
  • @Joey 同意 - 我来这里是因为这还不够好,值得依赖。 (2认同)

dat*_*ung 5

这是 Joey 答案的扩展,包括时间并用 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%
Run Code Online (Sandbox Code Playgroud)