Como salvo a data atual no formato AAAA-MM-DD em alguma variável em um arquivo .bat do Windows?
Análogo de shell Unix:
today=`date +%F`
echo $today
Como salvo a data atual no formato AAAA-MM-DD em alguma variável em um arquivo .bat do Windows?
Análogo de shell Unix:
today=`date +%F`
echo $today
Respostas:
Você pode obter a data atual de forma independente da localidade usando
for /f "skip=1" %%x in ('wmic os get localdatetime') do if not defined MyDate set MyDate=%%x
Em seguida, você pode extrair as partes individuais usando substrings:
set today=%MyDate:~0,4%-%MyDate:~4,2%-%MyDate:~6,2%
Outra maneira, onde você obtém variáveis que contêm as partes individuais, seria:
for /f %%x in ('wmic path win32_localtime get /format:list ^| findstr "="') do set %%x
set today=%Year%-%Month%-%Day%
Muito melhor do que mexer com substrings, ao custo de poluir o namespace de sua variável.
Se você precisa do UTC em vez da hora local, o comando é mais ou menos o mesmo:
for /f %%x in ('wmic path win32_utctime get /format:list ^| findstr "="') do set %%x
set today=%Year%-%Month%-%Day%
for /f
retorna duas linhas, a última das quais vazia. Você pode resolver isso usando o set MyDate=
meio. Acho que foi nisso que user2023861 tropeçou.
Year
, Month
, Day
, Hour
, Minute
, Second
, Quarter
, WeekInMonth
,DayOfWeek
for /f %%x in ('wmic path win32_localtime get /format:list ^| findstr "="') do set %%x set today=%Year%-%Month%-%Day%
é uma resposta inválida: retorna um dígito mês e dia. Como obter 2 dígitos preenchidos à esquerda com zero mês e string de dia até a data?
Se você deseja fazer isso usando comandos padrão do MS-DOS em um arquivo em lote, você pode usar:
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
Tenho certeza que isso pode ser melhorado ainda mais, mas isso fornece a data em 3 variáveis para Dia (dd), Mês (mm) e Ano (aaaa). Você pode usá-los posteriormente em seu script de lote, conforme necessário.
SET todaysdate=%yyyy%%mm%%dd%
echo %dd%
echo %mm%
echo %yyyy%
echo %todaysdate%
Embora eu entenda que uma resposta foi aceita para esta pergunta, este método alternativo pode ser apreciado por muitos que procuram conseguir isso sem usar o console WMI, então espero que agregue algum valor a esta pergunta.
Use date /T
para localizar o formato no prompt de comando.
Se o formato da data for Thu 17/03/2016
usado assim:
set datestr=%date:~10,4%-%date:~7,2%-%date:~4,2%
echo %datestr%
SELECT CONVERT(VARCHAR(16), GETDATE(), 112)
".
%date:~10,4%%date:~7,2%%date:~4,2%T%time:~0,2%%time:~3,2%%time:~6,2%
Mais duas maneiras que não dependem das configurações de tempo (ambas tiradas de Como obter dados / hora independente da localização ). E ambos também obtêm o dia da semana e nenhum deles requer permissões de administrador !:
MAKECAB - funcionará em TODOS os sistemas Windows (rápido, mas cria um pequeno arquivo temporário) (o script 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 - não é um comando nativo para Windows XP e Windows Server 2003 , mas pode ser baixado do site da Microsoft . Mas está integrado em tudo, desde o Windows Vista e superior:
@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
E mais três maneiras que usam outras linguagens de script do Windows. Eles lhe darão mais flexibilidade, por exemplo, você pode obter a semana do ano, o tempo em milissegundos e assim por diante.
Híbrido JScript / BATCH (precisa ser salvo como .bat
). JScript está disponível em todos os sistemas do Windows NT e superior, como parte do Windows Script Host ( embora possa ser desativado por meio do registro, é um caso raro ):
@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());
Híbrido VBScript / BATCH ( é possível incorporar e executar VBScript em um arquivo em lote sem usar um arquivo temporário? ) Mesmo caso que jscript, mas a hibridização não é tão perfeita:
: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 - pode ser instalado em todas as máquinas que possuem .NET - baixe da Microsoft ( v1 , v2 e v3 (apenas para Windows 7 e superior)). Instalado por padrão em tudo do Windows 7 / Win2008 e superior:
C:\> powershell get-date -format "{dd-MMM-yyyy HH:mm}"
Jscript.net/batch autocompilado (nunca vi uma máquina Windows sem .NET, então acho que é bastante portátil):
@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 Não é possível obter o ano e o dia da semana. É comparativamente lento, também cria um arquivo temporário e é baseado nos registros de data e hora que o logman coloca em seus arquivos de log. Funcionará em tudo a partir do Windows XP e superior. Provavelmente nunca será usado por ninguém - incluindo eu - mas é mais uma forma ...
@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
Mais informações sobre a função Get-Date .
Eu realmente gostei do método de Joey, mas pensei em expandi-lo um pouco.
Nessa abordagem, você pode executar o código várias vezes e não se preocupar com o valor de data antigo "persistente" porque já está definido.
Cada vez que você executar este arquivo em lote, ele produzirá uma representação combinada de data e hora compatível com 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%
Nesta versão, você terá que ter cuidado para não copiar / colar o mesmo código em vários lugares no arquivo, pois isso causaria rótulos duplicados. Você pode ter um rótulo separado para cada cópia ou apenas colocar esse código em seu próprio arquivo em lote e chamá-lo de seu arquivo de origem sempre que necessário.
Basta usar a %date%
variável:
echo %date%
De acordo com a resposta de @ProVi, basta mudar para se adequar à formatação que você precisa
echo %DATE:~10,4%-%DATE:~7,2%-%DATE:~4,2% %TIME:~0,2%:%TIME:~3,2%:%TIME:~6,2%
retornará
yyyy-MM-dd hh:mm:ss
2015-09-15 18:36:11
EDITAR De acordo com o comentário de @Jeb, quem está correto o formato de hora acima só funcionará se o seu comando DATE / T retornar
ddd dd/mm/yyyy
Thu 17/09/2015
É fácil editar para se adequar à sua localidade, no entanto, usando a indexação de cada caractere na string retornada pela variável de ambiente% DATE% relevante, você pode extrair as partes da string de que precisa.
por exemplo. Usar% DATE ~ 10,4% expandiria a variável de ambiente DATE e, em seguida, usaria apenas os 4 caracteres que começam no 11º (deslocamento 10) caractere do resultado expandido
Por exemplo, se usar datas no estilo dos EUA, o seguinte se aplica
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
Verifique este ..
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
Se você tiver o Python instalado, você pode fazer
python -c "import datetime;print(datetime.date.today().strftime('%Y-%m-%d'))"
Você pode adaptar facilmente a string de formato às suas necessidades.
python -c "import datetime;print(datetime.date.today())"
, porque o __str__
método da date
classe apenas chama isoformat()
.
É possível usar o PowerShell e redirecionar sua saída para uma variável de ambiente usando um loop.
Na linha de comando ( 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
Em um arquivo em lote, você pode escapar %a
como %%a
:
for /f "tokens=*" %%a in ('powershell get-date -format "{yyyy-MM-dd+HH:mm}"') do set td=%%a
FOR /F "tokens=*" %%a IN ('powershell get-date -format "{yyyy\-MM\-dd\THH\:mm\:ss}"') DO SET date=%%a
então use MM superior para mês e barra invertida para escapar de caracteres literais.
Devido ao formato de data e hora ser uma informação específica do local, recuperá-los das variáveis% date% e% time% exigirá um esforço extra para analisar a string com a transformação do formato em consideração. Uma boa ideia é usar alguma API para recuperar a estrutura de dados e analisá-la como desejar. WMIC é uma boa escolha. O exemplo abaixo usa Win32_LocalTime . Você também pode usar Win32_CurrentTime ou 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
Resultado:
25-04-2018_10: 03: 11
Esta é uma extensão da resposta de Joey para incluir a hora e preencher as partes com zeros.
Por exemplo, o resultado será 2019-06-01_17-25-36. Observe também que esta é a hora 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%
Estou usando o seguinte:
set iso_date=%date:~6,4%-%date:~3,2%-%date:~0,2%
Ou em combinação com um nome de arquivo de log 'MyLogFileName':
set log_file=%date:~6,4%-%date:~3,2%-%date:~0,2%-MyLogFileName
Se você não se importa em um investimento único de 10 a 30 minutos para obter uma solução confiável (que não depende das configurações regionais do Windows), continue lendo.
Vamos libertar nossas mentes. Você deseja simplificar os scripts para ficarem assim? (Suponha que você deseja definir a variável 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
Você pode. Basta construir um FormatNow.exe com C # .NET e adicioná-lo ao seu PATH.
Notas:
Benefícios:
Código-fonte do FormatNow.exe que construí com o Visual Studio 2010 (prefiro construí-lo sozinho para evitar o risco de baixar um programa desconhecido e possivelmente malicioso). Apenas copie e cole os códigos abaixo, crie o programa uma vez e você terá um formatador de data confiável para todos os usos futuros.
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());
}
}
}
}
Em geral, ao lidar com lógicas complicadas, podemos torná-lo mais simples construindo um programa muito pequeno e chamando o programa para capturar a saída de volta para uma variável de script em lote. Não somos alunos e não estamos fazendo exames que nos obriguem a seguir a regra somente script em lote para resolver problemas. No ambiente de trabalho real, qualquer método (legal) é permitido. Por que ainda devemos nos ater aos recursos pobres do script em lote do Windows, que precisa de soluções alternativas para muitas tarefas simples? Por que devemos usar a ferramenta errada para o trabalho?