Lote de Windows: fecha formateada en variable

¿Cómo guardo la fecha actual en formato YYYY-MM-DD en alguna variable en un archivo .bat de Windows?

Análogo de shell de Unix:

today=`date +%F` echo $today 

Puede obtener la fecha actual de una manera 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 variable.

Si necesita UTC en lugar de 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% 

Si desea lograr esto utilizando los comandos estándar de MS-DOS en un archivo por lotes, entonces 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 más adelante, pero esto le da a la fecha 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 una respuesta ha sido aceptada para esta pregunta, este método alternativo puede ser apreciado por muchos que buscan lograr esto sin usar la consola WMI, por lo que espero que agregue algo de valor a esta pregunta.

Use date / T para encontrar el formato en el símbolo del sistema.

Si el formato de fecha es “Jue 03/03/2016”, use esto:

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

Dos formas más que no dependen de la configuración de tiempo (ambas tomadas de Cómo obtener datos / tiempo independientes de la localización ). ¡Y ambos también tienen el día de la semana y ninguno de ellos requiere permisos de administrador !:

  1. MAKECAB : funcionará en CADA sistema de 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 
  2. ROBOCOPY : no es un comando nativo para Windows XP y Windows Server 2003 , pero se puede descargar desde el sitio de Microsoft . Pero está incorporado en todo, desde Windows Vista y más arriba:

     @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 usan otros lenguajes de script de Windows. Le darán más flexibilidad, por ejemplo, puede obtener la semana del año, el tiempo en milisegundos, etc.

  3. JScript / BATCH hybrid (necesita ser guardado como .bat ). JScript está disponible en todos los sistemas desde Windows NT y superior, como parte de Windows Script Host ( aunque se puede deshabilitar 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()); 
  4. VBScript / BATCH hybrid ( ¿Es posible incrustar y ejecutar VBScript dentro de un archivo por lotes sin usar un archivo temporal? ) 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), ", ", "-") 
  5. PowerShell : se puede instalar en todas las máquinas que tengan .NET: descargar desde 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}" 
  6. Self-compiled jscript.net/batch (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_comstacktion 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 comstacktion :::: :::::::::::::::::::::::::::::::::::: :skip_comstacktion "%~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 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 nunca sea usado por nadie, incluyéndome a mí, 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 .


Solo usa la variable %date% :

 echo %date% 

Realmente me gustó el método de Joey, pero pensé que lo ampliaría un poco.

En este enfoque, puede ejecutar el código varias veces y no preocuparse por el antiguo valor de la fecha “quedarse” porque ya está definido.

Cada vez que ejecute este archivo por lotes, obtendrá 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, ya que eso provocaría tags duplicadas. Puede tener una etiqueta por separado para cada copia, o simplemente poner este código en su propio archivo por lotes y llamarlo desde su archivo de origen cuando sea necesario.

Establecí una variable de entorno al valor en el formato numérico deseado al hacer esto:

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

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% 

regresará

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

EDITAR Según el comentario de @Jeb, quien está en lo correcto, el formato 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 adaptarlo a su configuración regional; al usar la indexación de cada carácter en la cadena devuelta por la variable de entorno% DATE% correspondiente, puede extraer las partes de la cadena que necesita.

p.ej. Usar% DATE ~ 10,4% expandiría la variable de entorno DATE, y luego usaría solo los 4 caracteres que comienzan en el 11 ° (desplazamiento 10) del carácter del resultado expandido.

Por ejemplo, si se usan fechas con estilo estadounidense, 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.

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

Debido al formato de fecha y hora, es información específica de la ubicación, recuperarlas de las variables% date% y% time% requerirá un esfuerzo adicional para analizar la cadena con transformación de formato en consideración. Una buena idea es usar alguna API para recuperar la estructura de datos y analizar como lo desee. WMIC es una buena opción. A continuación, use Win32_LocalTime . También puede usar 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

Es posible utilizar PowerShell y redirigir su salida a una variable de entorno mediante el uso de 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 

Si no le importa una inversión de 10 a 30 minutos para obtener una solución confiable (que no depende de la configuración regional de Windows), continúe leyendo.

Liberemos nuestras mentes ¿Desea simplificar los scripts para que luzcan así? (Supongamos que quiere 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 RUTA.

Notas:

  1. Puede usar cualquier edición de Visual Studio, como Visual Studio Express, para crear FormatNow.exe.
  2. En Visual Studio, elija el proyecto C # de “Aplicación de consola”, no el proyecto “Aplicación Windows Forms”.
  3. Sentido común: el formato FormatNow.exe necesitará .NET Framework para ejecutarse.
  4. Sentido común: después de agregar FormatNow.exe a la variable PATH, necesita reiniciar CMD para que tenga efecto. También se aplica a cualquier cambio en las variables de entorno.

Beneficios:

  1. No es lento (termina en 0.2 segundos).
  2. Se admiten muchos formatos https://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx, por ejemplo, FormatNow “ddd” para obtener solo el día de la semana, FormatNow “yyyy” para obtener solo el año
  3. No depende de la configuración regional de Windows, por lo que su resultado es mucho más confiable. Por otro lado,% date% no da un formato consistente en diferentes computadoras, y no es confiable.
  4. No es necesario crear tantas variables CMD y contaminar el espacio de nombre variable.
  5. Se requerirían 3 líneas en el script por lotes para invocar el progtwig y obtener los resultados. Debe ser razonablemente lo suficientemente corto.

Código fuente de FormatNow.exe que creé con Visual Studio 2010 (prefiero comstackrlo para evitar el riesgo de descargar un progtwig desconocido, posiblemente malicioso). Simplemente copie y pegue los códigos a continuación, cree el progtwig una vez y luego tenga un formateador de datos 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 creando un progtwig muy pequeño y llamando al progtwig para que capture nuevamente la salida en una secuencia de comandos de proceso por lotes. No somos estudiantes y no estamos tomando exámenes que nos exigen que sigamos la regla solo de script por lotes para resolver problemas. En un entorno de trabajo real, se permite cualquier método (legal). ¿Por qué todavía debemos apegarnos a las pobres capacidades del script por lotes de Windows que necesita soluciones para muchas tareas simples? ¿Por qué deberíamos usar la herramienta incorrecta para el trabajo?