¿Cómo guardo la fecha actual en formato AAAA-MM-DD en alguna variable en un archivo .bat de Windows?
Análogo de shell de Unix:
today=`date +%F`
echo $today
¿Cómo guardo la fecha actual en formato AAAA-MM-DD en alguna variable en un archivo .bat de Windows?
Análogo de shell de Unix:
today=`date +%F`
echo $today
Respuestas:
Puede obtener la fecha actual de forma independiente de la configuración regional utilizando
for /f "skip=1" %%x in ('wmic os get localdatetime') do if not defined MyDate set MyDate=%%x
Luego, puede extraer las partes individuales usando subcadenas:
set today=%MyDate:~0,4%-%MyDate:~4,2%-%MyDate:~6,2%
Otra forma, donde obtienes variables que contienen las partes individuales, sería:
for /f %%x in ('wmic path win32_localtime get /format:list ^| findstr "="') do set %%x
set today=%Year%-%Month%-%Day%
Mucho mejor que jugar con subcadenas, a expensas de contaminar el espacio de nombres de las variables.
Si necesita UTC en lugar de la hora local, el comando es más o menos el mismo:
for /f %%x in ('wmic path win32_utctime get /format:list ^| findstr "="') do set %%x
set today=%Year%-%Month%-%Day%
for /f
devuelve dos líneas, la última de las cuales está vacía. Puedes resolver eso usando set MyDate=
en el medio. Supongo que con eso se tropezó el usuario2023861.
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%
es una respuesta inválida: devuelve un dígito de mes y día. ¿Cómo se rellena la izquierda de 2 dígitos con mes cero y cadena del día hasta la fecha?
Si desea lograr esto usando comandos estándar de MS-DOS en un archivo por lotes, puede 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
Estoy seguro de que esto se puede mejorar aún más, pero esto da la fecha en 3 variables para Día (dd), Mes (mm) y Año (aaaa). Luego, puede usarlos más adelante en su secuencia de comandos por lotes según sea necesario.
SET todaysdate=%yyyy%%mm%%dd%
echo %dd%
echo %mm%
echo %yyyy%
echo %todaysdate%
Si bien entiendo que se ha aceptado una respuesta para esta pregunta, este método alternativo puede ser apreciado por muchos que buscan lograrlo sin usar la consola WMI, así que espero que agregue algo de valor a esta pregunta.
Úselo date /T
para buscar el formato en el símbolo del sistema.
Si el formato de fecha es Thu 17/03/2016
usa así:
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%
Dos formas más que no dependen de la configuración de la hora (ambas tomadas de Cómo obtener datos / hora independientemente de la localización ). ¡Y ambos también obtienen el día de la semana y ninguno de ellos requiere permisos de administrador !:
MAKECAB : funcionará en TODOS los sistemas Windows (rápido, pero crea un pequeño archivo temporal) (el 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 : no es un comando nativo para Windows XP y Windows Server 2003 , pero se puede descargar del sitio de Microsoft . Pero está integrado en todo, desde Windows Vista y versiones posteriores:
@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
Y tres formas más que utilizan otros lenguajes de script de Windows. Le darán más flexibilidad, por ejemplo, puede obtener la semana del año, la hora en milisegundos, etc.
Híbrido JScript / BATCH (debe guardarse como .bat
). JScript está disponible en todos los sistemas de Windows NT y superior, como parte de Windows Script Host ( aunque se puede desactivar a través del registro, es un 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());
VBScript / BATCH híbrido ( ¿Es posible incrustar y ejecutar VBScript dentro de un archivo por lotes sin usar un archivo temporal? ) En el mismo caso que jscript, pero la hibridación no es tan perfecta:
: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 : se puede instalar en todas las máquinas que tengan .NET; descargar de Microsoft ( v1 , v2 y v3 (solo para Windows 7 y superior)). Instalado por defecto en todo desde Windows 7 / Win2008 y superior:
C:\> powershell get-date -format "{dd-MMM-yyyy HH:mm}"
Jscript.net/batch autocompilado (nunca he visto una máquina con Windows sin .NET, así que creo que es 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 Esto no puede obtener el año y el día de la semana. Es comparativamente lento, también crea un archivo temporal y se basa en las marcas de tiempo que logman coloca en sus archivos de registro. Funcionará todo desde Windows XP y superior. Probablemente nadie lo use nunca, incluido yo, pero es una forma más ...
@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
Más información sobre la función Get-Date .
Me gustó mucho el método de Joey, pero pensé en ampliarlo un poco.
En este enfoque, puede ejecutar el código varias veces y no preocuparse por que el valor de fecha anterior "se quede" porque ya está definido.
Cada vez que ejecute este archivo por lotes, generará una representación combinada de fecha y hora compatible con 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%
En esta versión, deberá tener cuidado de no copiar / pegar el mismo código en varios lugares del archivo porque eso causaría etiquetas duplicadas. Puede tener una etiqueta separada para cada copia o simplemente poner este código en su propio archivo por lotes y llamarlo desde su archivo fuente cuando sea necesario.
Según la respuesta de @ProVi, simplemente cambie para adaptarse al formato que necesita
echo %DATE:~10,4%-%DATE:~7,2%-%DATE:~4,2% %TIME:~0,2%:%TIME:~3,2%:%TIME:~6,2%
volverá
yyyy-MM-dd hh:mm:ss
2015-09-15 18:36:11
EDITAR Según el comentario de @Jeb, quién tiene razón, el formato de hora anterior solo funcionará si su comando DATE / T regresa
ddd dd/mm/yyyy
Thu 17/09/2015
Sin embargo, es fácil de editar para que se adapte a su configuración regional, al usar la indexación de cada carácter en la cadena devuelta por la variable de entorno% DATE% relevante, puede extraer las partes de la cadena que necesita.
p.ej. El uso de% DATE ~ 10,4% expandiría la variable de entorno DATE y luego usaría solo los 4 caracteres que comienzan en el undécimo carácter (desplazamiento 10) del resultado expandido
Por ejemplo, si usa fechas con estilo de EE. UU., Se aplica lo siguiente
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
Revisa 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
Si tiene Python instalado, puede hacer
python -c "import datetime;print(datetime.date.today().strftime('%Y-%m-%d'))"
Puede adaptar fácilmente la cadena de formato a sus necesidades.
python -c "import datetime;print(datetime.date.today())"
, porque el __str__
método de la date
clase solo llama isoformat()
.
Es posible usar PowerShell y redirigir su salida a una variable de entorno mediante un bucle.
Desde la línea 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
En un archivo por lotes, puede 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
así que use MM superior para el mes y barra invertida para escapar de los caracteres literales.
Debido a que el formato de fecha y hora es información específica de la ubicación, recuperarlos de las variables% date% y% time% requerirá un esfuerzo adicional para analizar la cadena con la transformación de formato en consideración. Una buena idea es utilizar alguna API para recuperar la estructura de datos y analizarla como desee. WMIC es una buena opción. El siguiente ejemplo usa Win32_LocalTime . También puede utilizar Win32_CurrentTime o 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:
2018-04-25_10: 03: 11
Esta es una extensión de la respuesta de Joey para incluir el tiempo y rellenar las partes con ceros.
Por ejemplo, el resultado será 2019-06-01_17-25-36. También tenga en cuenta que esta es la 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%
Estoy usando lo siguiente:
set iso_date=%date:~6,4%-%date:~3,2%-%date:~0,2%
O en combinación con un nombre de archivo de registro 'MyLogFileName':
set log_file=%date:~6,4%-%date:~3,2%-%date:~0,2%-MyLogFileName
Si no le importa una inversión única de 10 a 30 minutos para obtener una solución confiable (que no depende de la configuración regional de Windows), siga leyendo.
Liberemos nuestras mentes. ¿Quiere simplificar los scripts para que se vean así? (Suponga que desea establecer la variable 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
Usted puede. Simplemente cree un FormatNow.exe con C # .NET y agréguelo a su PATH.
Notas:
Beneficios:
Código fuente de FormatNow.exe que creé con Visual Studio 2010 (prefiero compilarlo yo mismo para evitar el riesgo de descargar un programa desconocido, posiblemente malicioso). Simplemente copie y pegue los códigos a continuación, compile el programa una vez y luego tendrá un formateador de fecha confiable para todos los 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());
}
}
}
}
En general, cuando se trata de lógicas complicadas, podemos simplificarlo construyendo un programa muy pequeño y llamando al programa para que capture la salida de nuevo en una variable de script por lotes. No somos estudiantes y no estamos tomando exámenes que requieran que sigamos la regla de solo guiones por lotes para resolver problemas. En un entorno de trabajo real, se permite cualquier método (legal). ¿Por qué deberíamos ceñirnos a las pobres capacidades del script por lotes de Windows que necesita soluciones para muchas tareas simples? ¿Por qué deberíamos utilizar la herramienta incorrecta para el trabajo?