Formato de fecha y hora en un script por lotes de Windows


192

En una secuencia de comandos por lotes de Windows (Windows XP) necesito formatear la fecha y hora actuales para su uso posterior en nombres de archivos, etc.

Es similar a la pregunta de desbordamiento de pila. Cómo agregar una fecha en archivos por lotes , pero también con tiempo.

Tengo esto hasta ahora:

echo %DATE%
echo %TIME%
set datetimef=%date:~-4%_%date:~3,2%_%date:~0,2%__%time:~0,2%_%time:~3,2%_%time:~6,2%
echo %datetimef%

lo que da:

28/07/2009
 8:35:31.01
2009_07_28__ 8_36_01

¿Hay alguna manera de permitir una hora de un solo dígito en% TIME%, para poder obtener lo siguiente?

2009_07_28__08_36_01



Puede reemplazar espacios vacíos en su datetimefvariable y poner 0 en su lugar. En su ejemplo:SET datetimef=%datetimef: =0%
SebaGra

Respuestas:


148

Terminé con este script:

set hour=%time:~0,2%
if "%hour:~0,1%" == " " set hour=0%hour:~1,1%
echo hour=%hour%
set min=%time:~3,2%
if "%min:~0,1%" == " " set min=0%min:~1,1%
echo min=%min%
set secs=%time:~6,2%
if "%secs:~0,1%" == " " set secs=0%secs:~1,1%
echo secs=%secs%

set year=%date:~-4%
echo year=%year%

:: En WIN2008R2, por ejemplo, necesitaba hacer su 'mes establecido =% fecha: ~ 3,2%' como a continuación :: de lo contrario, aparece 00 para el MES

set month=%date:~4,2%
if "%month:~0,1%" == " " set month=0%month:~1,1%
echo month=%month%
set day=%date:~0,2%
if "%day:~0,1%" == " " set day=0%day:~1,1%
echo day=%day%

set datetimef=%year%%month%%day%_%hour%%min%%secs%

echo datetimef=%datetimef%

11
Para su información, en Windows Server 2003 y en Windows 7, este script me dio "201200Mo_085806" (año y hora correctos).
sfuqua

50
Como nota para alguien que vendrá aquí desde Google (como yo): ¡Esto depende de la configuración regional, por lo que puede requerir ajustes para funcionar en Windows que no está en inglés!
PiotrK

Lo hice de esta manera: Time / T> Time.dat set / P ftime = <Time.dat set fDate =% date: ~ 6 %% date: ~ 3,2 %% date: ~ 0,2 %% ftime: ~ 0,2 %% ftime: ~ 3,2% echo% fDate% -> 201310170928
Ice

¿Qué hace% time: ~ 0,2% donde hay alguna documentación sobre: ​​~,% ​​estructura?
user1605665

66
Todo esto se puede hacer en solo 2 líneas usando el reemplazo de cadena ordinario: stackoverflow.com/a/23558738/1879699
Andreas

71
@ECHO OFF
: Sets the proper date and time stamp with 24Hr Time for log file naming
: convention

SET HOUR=%time:~0,2%
SET dtStamp9=%date:~-4%%date:~4,2%%date:~7,2%_0%time:~1,1%%time:~3,2%%time:~6,2% 
SET dtStamp24=%date:~-4%%date:~4,2%%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%

if "%HOUR:~0,1%" == " " (SET dtStamp=%dtStamp9%) else (SET dtStamp=%dtStamp24%)

ECHO %dtStamp%

PAUSE

2
En Windows Server 2003 y en Windows 7, esto me dio la cadena correcta. Mucho más elegante que lo que he construido en el pasado, ¡así que gracias!
sfuqua

3
Esto es lo que me da en Windows 7 con configuración regional rusa. La hora actual es 2013-05-03T02: 22: 51, pero el script imprime: "2013-5.-01_02_22_51"
codificador nocturno

77
El% date% dará diferentes cadenas con diferentes configuraciones regionales.
AechoLiu

2
me devuelve 20146.0._173502 (local checo)
Muflix

2
win7 64bit ultimate, hora incorrecta: 20140.01_131612, debe ser (2014.10.26_131612)
waza123

66

Así es como genero un nombre de archivo de registro (basado en http://ss64.com/nt/syntax-getdate.html ):

@ECHO OFF
:: Check WMIC is available
WMIC.EXE Alias /? >NUL 2>&1 || GOTO s_error

:: Use WMIC to retrieve date and time
FOR /F "skip=1 tokens=1-6" %%G IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table') DO (
   IF "%%~L"=="" goto s_done
      Set _yyyy=%%L
      Set _mm=00%%J
      Set _dd=00%%G
      Set _hour=00%%H
      SET _minute=00%%I
      SET _second=00%%K
)
:s_done

:: Pad digits with leading zeros
      Set _mm=%_mm:~-2%
      Set _dd=%_dd:~-2%
      Set _hour=%_hour:~-2%
      Set _minute=%_minute:~-2%
      Set _second=%_second:~-2%

Set logtimestamp=%_yyyy%-%_mm%-%_dd%_%_hour%_%_minute%_%_second%
goto make_dump

:s_error
echo WMIC is not available, using default log filename
Set logtimestamp=_

:make_dump
set FILENAME=database_dump_%logtimestamp%.sql
...

55
mejor respuesta en SO para preguntas sobre la generación de marca de tiempo independiente de la configuración regional en lote.
Mike Campbell

2
¡Increíble! Debería haber una manera de marcar esto como la solución
Rado

48

Por lo general, lo hago de esta manera cada vez que necesito una cadena de fecha / hora:

set dt=%DATE:~6,4%_%DATE:~3,2%_%DATE:~0,2%__%TIME:~0,2%_%TIME:~3,2%_%TIME:~6,2%
set dt=%dt: =0%

Esto es para el formato de fecha / hora alemán (dd.mm.aaaa hh: mm: ss). Básicamente concateno las subcadenas y finalmente reemplazo todos los espacios con ceros.

Breve explicación de cómo funcionan las subcadenas:

%VARIABLE:~num_chars_to_skip,num_chars_to_keep%

Entonces, para obtener solo el año de una fecha como "29.03.2018" use:

%DATE:~6,4%
       ^-----skip 6 characters
         ^---keep 4 characters 

77
con mucho, la solución más elegante cuando solo necesita una marca de tiempo limpia (sin espacios u otros caracteres)
jvdneste

1
No podría estar más de acuerdo con @jvdneste gracias por compartir mrt
this.user3272243

1
absolutamente genial - y funciona [la sintaxis requerida es muy confusa, pero ese no es el problema del póster]
JosephDoggie

38

Si PowerShell está instalado, puede obtener de manera fácil y confiable la Fecha / Hora en cualquier formato que desee, por ejemplo:

for /f %%a in ('powershell -Command "Get-Date -format yyyy_MM_dd__HH_mm_ss"') do set datetime=%%a
move "%oldfile%" "backup-%datetime%"

Por supuesto, hoy en día PowerShell siempre está instalado, pero en Windows XP probablemente solo quiera usar esta técnica si su script por lotes se está utilizando en un entorno conocido donde sabe que PS está disponible (o verifique su archivo por lotes si PowerShell está disponible) ...)

Puede preguntar razonablemente: ¿por qué usar un archivo por lotes? las cosas a la antigua usanza con archivos por lotes o (b) estás actualizando un script antiguo y no quieres portar todo a PS.


(a) en mi caso, y esto funciona perfectamente (bat es solo para mi entorno, pero tengo configuraciones mixtas en diferentes PC). ¡Gracias!
ccalboni

30

Encontré este problema hoy y lo resolví con:

SET LOGTIME=%TIME: =0%

Reemplaza los espacios con 0s y, básicamente, cero-pads por hora.

Después de una búsqueda rápida, no descubrí si requería extensiones de comando (aún funcionaba con SETLOCAL DISABLEEXTENSIONS).


OK, sustitución en variables. Ahora, ¿cómo sustituir un colon ( :)?
Tomasz Gandor

@TomaszGandor Esto funciona para mí: echo %TIME: =:%pero si no lo es, intenta escapar :con un me ^gusta echo %TIME: =^:%(que también funciona para mí).
opello

1
+1 por simplicidad. Los dos puntos no son válidos en los nombres de archivo. establecer theTime =% Time :: =% los elimina. ¿Puede sustituir 0 por espacio, eliminar los dos puntos y truncar a 6 caracteres (eliminando así la parte decimal) en una sola declaración? No es gran cosa si se necesitan dos o tres líneas. Tengo curiosidad.
riderBill

No que yo sepa. ¡Haz un seguimiento si encuentras uno!
opello

21

Como se ha observado, analizar la fecha y la hora solo es útil si conoce el formato que está utilizando el usuario actual (por ejemplo, MM / dd / aa o dd-MM-aaaa solo por nombrar dos). Esto podría determinarse, pero para cuando haga todo el énfasis y el análisis, aún terminará con alguna situación en la que se utiliza un formato inesperado, y serán necesarios más ajustes.

También puede usar algún programa externo que le devolverá una babosa de fecha en su formato preferido, pero que tiene las desventajas de necesitar distribuir el programa de utilidad con su script / lote.

También hay trucos por lotes que usan el reloj CMOS de una manera bastante cruda, pero eso está demasiado cerca de los cables pelados para la mayoría de las personas, y no siempre es el lugar preferido para recuperar la fecha / hora.

A continuación se muestra una solución que evita los problemas anteriores. Sí, presenta algunos otros problemas, pero para mis propósitos encontré que esta es la solución más fácil, más clara y más portátil para crear un sello de fecha en archivos .bat para sistemas Windows modernos. Este es solo un ejemplo, pero creo que verá cómo modificar para otros formatos de fecha y / o hora, etc.

reg copy "HKCU\Control Panel\International" "HKCU\Control Panel\International-Temp" /f
reg add "HKCU\Control Panel\International" /v sShortDate /d "yyMMdd" /f
@REM reg query "HKCU\Control Panel\International" /v sShortDate
set LogDate=%date%
reg copy "HKCU\Control Panel\International-Temp" "HKCU\Control Panel\International" /f

3
Justo lo que estaba buscando. Algo que funciona en cada configuración regional. ¡Gracias!
Lost_DM

+1 para los "sistemas Windows modernos" con los que nos enfrentamos :) Bromas aparte, esta es una forma muy ingeniosa y, como dijiste, portátil, de tratar el problema.
Zach Young

9
Esta es una solución terrible. Si falla, la configuración global cambia permanentemente. También introduce condiciones de carrera con otras aplicaciones.
MikeKulls

Puede usar la reg query "HKCU\Control Panel\International" /v sShortDateparte sin cambiar la configuración del registro (¡ejercicio que le queda al lector!).
tricasse

9

¿Lo siguiente puede no ser una respuesta directa sino una respuesta cercana?

set hour=%time:~0,2%
if "%hour:~0,1%" == " " set datetimef=%date:~-4%_%date:~3,2%_%date:~0,2%__0%time:~1,2%_%time:~3,2%_%time:~6,2%
else set datetimef=%date:~-4%_%date:~3,2%_%date:~0,2%__%time:~0,2%_%time:~3,2%_%time:~6,2%

Al menos puede ser inspirador.


9

Si no necesita exactamente este formato:

2009_07_28__08_36_01

Luego, podría usar las siguientes 3 líneas de código que usan% date% y% time%:

set mydate=%date:/=%
set mytime=%time::=%
set mytimestamp=%mydate: =_%_%mytime:.=_%

Nota: Los caracteres /y :se eliminan y el carácter .y el espacio se reemplazan con un guión bajo.

Ejemplo de salida (tomada el miércoles 8/5/15 a las 12:49 p.m. con 50 segundos y 93 milisegundos):

echo %mytimestamp%
Wed_08052015_124950_93

cuando la hora es inferior a 12, configure mydate =% date: / =% set mytime =% time :: =% set mytime =% mytime: = 0% set mytimestamp =% mydate: = _% _% mytime:. = _ %
ragche

8
REM Assumes UK style date format for date environment variable (DD/MM/YYYY).
REM Assumes times before 10:00:00 (10am) displayed padded with a space instead of a zero.
REM If first character of time is a space (less than 1) then set DATETIME to:
REM YYYY-MM-DD-0h-mm-ss
REM Otherwise, set DATETIME to:
REM YYYY-MM-DD-HH-mm-ss
REM Year, month, day format provides better filename sorting (otherwise, days grouped
REM together when sorted alphabetically).

IF "%time:~0,1%" LSS "1" (
   SET DATETIME=%date:~6,4%-%date:~3,2%-%date:~0,2%-0%time:~1,1%-%time:~3,2%-%time:~6,2%
) ELSE (
   SET DATETIME=%date:~6,4%-%date:~3,2%-%date:~0,2%-%time:~0,2%-%time:~3,2%-%time:~6,2%
)

ECHO %DATETIME%

6

El offset:lengthformato compatible con el SETcomando en Windows no le permitirá rellenarlo 0como parece estar interesado.

Sin embargo, puede codificar un script BATCH para verificar que la hora sea menor 10y
rellenar en consecuencia con una echocadena diferente .

Encontrará información sobre el SETcomando en este enlace .


También puede cambiar a otros métodos de programación para llegar aquí.

Es bastante simple en unix bash (disponible con Cygwin en Windows) simplemente decir,

date +%Y_%m_%d__%H_%M_%S

Y, siempre se rellena correctamente.


6

Lo hice de esta manera:

REM Generate FileName from date and time in format YYYYMMTTHHMM

Time /T > Time.dat
set /P ftime= < Time.dat

set FileName=LogFile%date:~6%%date:~3,2%%date:~0,2%%ftime:~0,2%%ftime:~3,2%.log

echo %FileName%

LogFile201310170928.log


Se ejecuta en el servidor en inglés (Nombre del sistema operativo: Microsoft (R) Windows (R) Server 2003 Standard x64 Edition, Versión del sistema operativo: 5.2.3790 Service Pack 2 Build 3790)
Ice

1
y también probado en el servidor alemán (Betriebssystemname: Microsoft® Windows Server® 2008 Enterprise, Betriebssystemversion: 6.0.6002 Service Pack 2 Build 6002)
Ice

1
Incluso este no está bien: (Betriebssystemname: Microsoft Windows Server 2012 Standard, Betriebssystemversion: 6.2.9200 Nicht zutreffend Build 9200)
Ice

4
::========================================================================  
::== CREATE UNIQUE DATETIME STRING IN FORMAT YYYYMMDD-HHMMSS   
::======= ================================================================  
FOR /f %%a IN ('WMIC OS GET LocalDateTime ^| FIND "."') DO SET DTS=%%a  
SET DATETIME=%DTS:~0,8%-%DTS:~8,6%  

La primera línea siempre sale en este formato con respecto a la zona horaria:
20150515150941.077000 + 120
Esto lo deja con solo formatear la salida para que se ajuste a sus deseos.


4

Este archivo bat (guardar como datetimestr.bat) produce la cadena de fecha y hora 3 veces: (1) cadena de fecha y hora larga con día de la semana y segundos, (2) cadena de fecha y hora corta sin ellas y (3) versión corta del código.

@echo off
REM "%date: =0%" replaces spaces with zeros
set d=%date: =0%
REM "set yyyy=%d:~-4%" pulls the last 4 characters
set yyyy=%d:~-4%
set mm=%d:~4,2%
set dd=%d:~7,2%
set dow=%d:~0,3%
set d=%yyyy%-%mm%-%dd%_%dow%

set t=%TIME: =0%
REM "%t::=%" removes semi-colons
REM Instead of above, you could use "%t::=-%" to 
REM replace semi-colons with hyphens (or any 
REM non-special character)
set t=%t::=%
set t=%t:.=%

set datetimestr=%d%_%t%
@echo  Long date time str = %datetimestr%

set d=%d:~0,10%
set t=%t:~0,4%
set datetimestr=%d%_%t%
@echo Short date time str = %datetimestr%


@REM Short version of the code above
set d=%date: =0%
set t=%TIME: =0%
set datetimestr=%d:~-4%-%d:~4,2%-%d:~7,2%_%d:~0,3%_%t:~0,2%%t:~3,2%%t:~6,2%%t:~9,2%
@echo Datetimestr = %datetimestr%

pause

Para dar el crédito adecuado, fusioné los conceptos de Peter Mortensen (18 de junio de 14 a las 21:02) y opello (25 de agosto de 11 a las 14:27).

Puede escribir esto mucho más corto, pero esta versión larga facilita la lectura y comprensión del código.


4

¡Soy realmente nuevo en los archivos por lotes y este es mi código! (No estoy seguro de por qué, pero no pude combinar fecha / t y hora / t juntas y no pude usar % date% y % time% directamente sin una variable ...)

@ECHO OFF
set ldt=%date% %time%
echo %ldt%>> logs.txt
EXIT

Se reutiliza de otros (la pregunta era obtener una fecha de hora formateada para usar como nombre de archivo).


4

Hay otra forma fácil de hacerlo:

set HH=%time:~0,2%
if %HH% LEQ 9 (
set HH=%time:~1,1%
)

3

Para generar una YYYY-MM-DD hh:mm:ssmarca de tiempo (24 horas) utilizo:

SET CURRENTTIME=%TIME%
IF "%CURRENTTIME:~0,1%"==" " (SET CURRENTTIME=0%CURRENTTIME:~1%)
FOR /F "tokens=2-4 delims=/ " %%A IN ('DATE /T') DO (SET TIMESTAMP=%%C-%%A-%%B %CURRENTTIME%)

¿Asume un entorno regional particular?
Peter Mortensen

1
De acuerdo con ss64.com/nt/syntax-variables.html, las variables %TIME%y %DATE%utilizan el mismo formato que los comandos TIMEy DATE, respectivamente. En mi sistema, las variables no coinciden con mi configuración regional.
M. Dudley

3

Este script por lotes hará exactamente lo que quiere el OP (probado en Windows XP SP3).

También utilicé ese ingenioso truco de registro descrito anteriormente por "jph", en el que, en mi humilde opinión, es la forma más sencilla de obtener un formato 100% coherente de la fecha "yyyy_MM_dd"en cualquier sistema Windows nuevo o antiguo. El cambio a un valor del Registro para hacer esto es instantáneo temporal y trivial; solo dura unos pocos milisegundos antes de que se revierta de inmediato.

Haga doble clic en este archivo por lotes para obtener una demostración instantánea. Aparecerá la ventana del símbolo del sistema y mostrará su marca de tiempo. . . . .

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: generates a custom formatted timestamp string using date and time.
:: run this batch file for an instant demo.
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

@ECHO OFF
SETLOCAL & MODE CON:COLS=80 LINES=15 & COLOR 0A

:: --- CHANGE THE COMPUTER DATE FORMAT TEMPORARILY TO MY PREFERENCE "yyyy_MM_dd",
REG COPY "HKCU\Control Panel\International" "HKCU\Control Panel\International-Temp" /f 2>nul >nul
REG ADD "HKCU\Control Panel\International" /v sShortDate /d "yyyy_MM_dd" /f 2>nul >nul

SET MYDATE=%date%

:: --- REVERT COMPUTER DATE BACK TO SYSTEM PREFERENCE
REG COPY "HKCU\Control Panel\International-Temp" "HKCU\Control Panel\International" /f 2>nul >nul
REG DELETE "HKCU\Control Panel\International-Temp" /f 2>nul >nul

:: --- SPLIT THE TIME [HH:MM:SS.SS] TO THREE SEPARATE VARIABLES [HH] [MM] [SS.SS]
FOR /F "tokens=1-3 delims=:" %%A IN ('echo %time%') DO (
SET HOUR=%%A
SET MINUTES=%%B
SET SECONDS=%%C
)

:: --- CHOOSE ONE OF THESE TWO OPTIONS :
:: --- FOR 4 DIGIT SECONDS        //REMOVES THE DOT FROM THE SECONDS VARIABLE [SS.SS]
:: SET SECONDS=%SECONDS:.=%
:: --- FOR 2 DIGIT SECONDS        //GETS THE FIRST TWO DIGITS FROM THE SECONDS VARIABLE [SS.SS]
SET SECONDS=%SECONDS:~0,2% 

:: --- FROM 12 AM TO 9 AM, THE HOUR VARIABLE WE EXTRACTED FROM %TIME% RETURNS A SINGLE DIGIT, 
:: --- WE PREFIX A ZERO CHARACTER TO THOSE CASES, SO THAT OUR WANTED TIMESTAMP
:: --- ALWAYS GENERATES DOUBLE-DIGIT HOURS (24-HOUR CLOCK TIME SYSTEM).
IF %HOUR%==0 (SET HOUR=00)
IF %HOUR%==1 (SET HOUR=01)
IF %HOUR%==2 (SET HOUR=02)
IF %HOUR%==3 (SET HOUR=03)
IF %HOUR%==4 (SET HOUR=04)
IF %HOUR%==5 (SET HOUR=05)
IF %HOUR%==6 (SET HOUR=06)
IF %HOUR%==7 (SET HOUR=07)
IF %HOUR%==8 (SET HOUR=08)
IF %HOUR%==9 (SET HOUR=09)

:: --- GENERATE OUR WANTED TIMESTAMP
SET TIMESTAMP=%MYDATE%__%HOUR%_%MINUTES%_%SECONDS%

:: --- VIEW THE RESULT IN THE CONSOLE SCREEN
ECHO.
ECHO    Generate a custom formatted timestamp string using date and time.
ECHO.
ECHO    Your timestamp is:    %TIMESTAMP%
ECHO.
ECHO.
ECHO    Job is done. Press any key to exit . . .
PAUSE > NUL

EXIT

Funciona en Windows 2019 también. Mantendré tu solución, me gusta :)
user225479

Pregunta, acabo de descubrir que después de la medianoche, el "0" final se cae en la salida. ¿Alguna idea de por qué? Mi salida con su script da: su marca de tiempo es: 2019_09_16__0_58_07 en lugar de ..00_58_07. Pero después de la 1 en punto funciona como se esperaba (y dará salida: ..01_01_56).
user225479

Agregué IF% HOUR% == 0 (SET HOUR = 00) a la declaración ELSE. Eso debería arreglarlo, espero :)
user225479

Gracias por los comentarios @ user225479. He arreglado el código. Todas las permutaciones posibles de la variable HORA convertida al formato de 24 HORAS ahora funcionarán correctamente. También he modificado el diseño para que sea más fácil de leer.
derty2

2
set hourstr = %time:~0,2%
if "%time:~0,1%"==" " (set hourstr=0%time:~1,1%)
set datetimestr=%date:~0,4%%date:~5,2%%date:~8,2%-%hourstr%%time:~3,2%%time:~6,2%

2

Cree un archivo llamado "search_files.bat" y coloque el contenido a continuación en el archivo. Luego haga doble clic en él. La variable temporal% THH% se implementó para manejar la AM de manera adecuada. Si hay un 0 en los primeros 2 dígitos del tiempo, Windows ignora el resto del nombre del archivo LOG.

CD .
SET THH=%time:~0,2%
SET THH=%THH: =0%
dir /s /b *.* > %date:~10,4%-%date:~4,2%-%date:~7,2%@%THH%.%time:~3,2%.%time:~6,2%.LOG

2

Me gusta la versión corta en la parte superior de @The lorax, pero para otras configuraciones de idioma puede ser ligeramente diferente.

Por ejemplo, en la configuración del idioma alemán (con formato de fecha natural: dd.mm.aaaa), la consulta del mes debe modificarse de 4,2 a 3,2:

@ECHO OFF
: Sets the proper date and time stamp with 24h time for log file naming convention i.e.

SET HOUR=%time:~0,2%
SET dtStamp9=%date:~-4%%date:~3,2%%date:~7,2%_0%time:~1,1%%time:~3,2%%time:~6,2% 
SET dtStamp24=%date:~-4%%date:~3,2%%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%

if "%HOUR:~0,1%" == " " (SET dtStamp=%dtStamp9%) else (SET dtStamp=%dtStamp24%)

ECHO %dtStamp%
: Outputs= 20160727_081040
: (format: YYYYMMDD_HHmmss; e.g.: the date-output of this post timestamp)

PAUSE

1

Estos son mis 2 centavos por a datetime string. En los MM DD YYYYsistemas, cambie la primera y la segunda %DATE:~entrada.

    REM ====================================================================================
    REM CREATE UNIQUE DATETIME STRING FOR ADDING TO FILENAME
    REM ====================================================================================
    REM Can handle dd DDxMMxYYYY and DDxMMxYYYY > CREATES YYYYMMDDHHMMSS (x= any character)
    REM ====================================================================================
    REM CHECK for SHORTDATE dd DDxMMxYYYY 
    IF "%DATE:~0,1%" GTR "3" (
        SET DATETIME=%DATE:~9,4%%DATE:~6,2%%DATE:~3,2%%TIME:~0,2%%TIME:~3,2%%TIME:~6,2%
    ) ELSE (
    REM ASSUMES SHORTDATE DDxMMxYYYY
        SET DATETIME=%DATE:~6,4%%DATE:~3,2%%DATE:~0,2%%TIME:~0,2%%TIME:~3,2%%TIME:~6,2%
        )
    REM CORRECT FOR HOURS BELOW 10
    IF %DATETIME:~8,2% LSS 10 SET DATETIME=%DATETIME:~0,8%0%DATETIME:~9,5%
    ECHO %DATETIME%

1

Intenté la respuesta aceptada y funciona bastante bien. Desafortunadamente, el formato de hora de EE. UU. Parece ser H: MM: SS.CS, y el 0 faltante en el frente estaba causando problemas de análisis antes de las 10 a.m. Para superar este obstáculo y también permitir el análisis de la mayoría de los formatos de hora mundial, se me ocurrió esta rutina simple que parece funcionar bastante bien.

:ParseTime
rem The format of %%TIME%% is H:MM:SS.CS or (HH:MM:SS,CS) for example 0:01:23.45 or 23:59:59,99
FOR /F "tokens=1,2,3,4 delims=:.," %%a IN ("%1") DO SET /A "%2=(%%a * 360000) + (%%b * 6000) + (%%c * 100) + %%d"
GOTO :EOF

Lo bueno de esta rutina es que pasa la cadena de tiempo como primer parámetro y el nombre de la variable de entorno que desea que contenga el tiempo (en centisegundos) como segundo parámetro. Por ejemplo:

CALL :ParseTime %START_TIME% START_CS
CALL :ParseTime %TIME% END_CS
SET /A DURATION=%END_CS% - %START_CS%

(* Chris *)


1

Tal vez algo como esto:

@call:DateTime

@for %%? in (
    "Year   :Y"
    "Month  :M"
    "Day    :D"
    "Hour   :H"
    "Minutes:I"
    "Seconds:S"
) do @for /f "tokens=1-2 delims=:" %%# in (%%?) do @for /f "delims=" %%_ in ('echo %%_DT_%%$_%%') do @echo %%# : _DT_%%$_ : %%_

:: OUTPUT
:: Year    : _DT_Y_ : 2014
:: Month   : _DT_M_ : 12
:: Day     : _DT_D_ : 17
:: Hour    : _DT_H_ : 09
:: Minutes : _DT_I_ : 04
:: Seconds : _DT_S_ : 35

@pause>nul

@goto:eof

:DateTime
    @verify errorlevel 2>nul & @wmics Alias /? >nul 2>&1
    @if not errorlevel 1 (
        @for /f "skip=1 tokens=1-6" %%a in ('wmic path win32_localtime get day^,hour^,minute^,month^,second^,year /format:table') do @if not "%%f"=="" ( set "_DT_D_=%%a" & set "_DT_H_=%%b" & set "_DT_I_=%%c" & set "_DT_M_=%%d" & set "_DT_S_=%%e" & set "_DT_Y_=%%f" )
    ) else (
        @set "_DT_T_=1234567890 "
    )
    @if errorlevel 1 (
        @for %%? in ("iDate" "sDate" "iTime" "sTime" "F" "Y" "M" "D" "H" "I" "S") do @set "_DT_%%~?_=%%~?"
        @for %%? in ("Date" "Time") do @for /f "skip=2 tokens=1,3" %%a in ('reg query "HKCU\Control Panel\International" /v ?%%~? 2^>nul') do @for /f %%x in ('echo:%%_DT_%%a_%%') do @if "%%x"=="%%a" set "_DT_%%a_=%%b"
        @for /f "tokens=1-3 delims=%_DT_T_%" %%a in ("%time%") do @set "_DT_T_=%%a%%b%%c"
    )
    @if errorlevel 1 (
        @if "%_DT_iDate_%"=="0" (set "_DT_F_=_DT_D_ _DT_Y_ _DT_M_") else if "%_DT_iDate_%"=="1" (set "_DT_F_=_DT_D_ _DT_M_ _DT_Y_") else if "%_DT_iDate_%"=="2" (set "_DT_F_=_DT_Y_ _DT_M_ _DT_D_")
        @for /f "tokens=1-4* delims=%_DT_sDate_%" %%a in ('date/t') do @for /f "tokens=1-3" %%x in ('echo:%%_DT_F_%%') do @set "%%x=%%a" & set "%%y=%%b" & set "%%z=%%c"
        @for /f "tokens=1-3 delims=%_DT_T_%" %%a in ("%time%") do @set "_DT_H_=%%a" & set "_DT_I_=%%b" & set "_DT_S_=%%c"
        @for %%? in ("iDate" "sDate" "iTime" "sTime" "F" "T") do @set "_DT_%%~?_="
    )
    @for %%i in ("Y"                ) do @for /f %%j in ('echo:"%%_DT_%%~i_%%"') do @set /a _DT_%%~i_+=  0 & @for /f %%k in ('echo:"%%_DT_%%~i_:~-4%%"') do @set "_DT_%%~i_=%%~k"
    @for %%i in ("M" "D" "H" "I" "S") do @for /f %%j in ('echo:"%%_DT_%%~i_%%"') do @set /a _DT_%%~i_+=100 & @for /f %%k in ('echo:"%%_DT_%%~i_:~-2%%"') do @set "_DT_%%~i_=%%~k"
@exit/b

1

En situaciones como esta, utilice un enfoque de programación simple y estándar: en lugar de gastar un gran esfuerzo en analizar una entidad desconocida, simplemente guarde la configuración actual, restablezca su estado conocido, extraiga la información y luego restaure el estado original. Use solo recursos estándar de Windows.

Específicamente, los formatos de fecha y hora se almacenan bajo la clave de registro HKCU \ Control Panel \ International \ en [valores de MS definición ":" sTimeFormat "y" sShortDate ". Reg es el editor de registro de consola incluido con todas las versiones de Windows. No se requieren privilegios elevados para modificar la clave HKCU

Prompt $N:$D $T$G

::Save current config to a temporary (unique name) subkey, Exit if copy fails
Set DateTime=
Set ran=%Random%
Reg copy "HKCU\Control Panel\International" "HKCU\Control Panel\International-Temp%ran%" /f
If ErrorLevel 1 GoTO :EOF

::Reset the date format to your desired output format (take effect immediately)
::Resetting the time format is useless as it only affect subsequent console windows
::Reg add "HKCU\Control Panel\International" /v sTimeFormat /d "HH_mm_ss"   /f
Reg add "HKCU\Control Panel\International" /v sShortDate  /d "yyyy_MM_dd" /f

::Concatenate the time and (reformatted) date strings, replace any embedded blanks with zeros
Set DateTime=%date%__%time:~0,2%_%time:~3,2%_%time:~6,2%
Set DateTime=%DateTime: =0%

::Restore the original config and delete the temp subkey, Exit if restore fails
Reg copy   "HKCU\Control Panel\International-Temp%ran%" "HKCU\Control Panel\International" /f
If ErrorLevel 1 GoTO :EOF
Reg delete "HKCU\Control Panel\International-Temp%ran%" /f

Simple, directo y debería funcionar para todas las regiones.

Por razones que no entiendo, restablecer el valor "sShortDate" tiene efecto inmediatamente en una ventana de consola, pero restablecer el valor muy similar "sTimeFormat" NO tiene efecto hasta que se abra una nueva ventana de consola. Sin embargo, lo único que se puede cambiar es el delimitador: las posiciones de los dígitos son fijas. Del mismo modo, se supone que la ficha de tiempo "HH" antepone los ceros iniciales, pero no lo hace. Afortunadamente, las soluciones son fáciles.


-1 "En lugar de agregar un cero a la izquierda, ¿por qué no interrumpe la configuración de la máquina, la cambia a su necesidad aleatoria y luego hace lo suyo?" Este enfoque está fuera de este mundo, requiere una cantidad considerable de esfuerzo y puede conducir a un número infinito de consecuencias no deseadas. Y ni siquiera quiero comenzar la discusión sobre la legibilidad y el comportamiento estándar esperado del código. prestigio.
vaitrafra

Restablecer el sTimeFormatformato de hora es inútil . No Como afecta el aviso de la consola posterior, aplíquelo usandofor /f "delims=" %%G in ('cmd /C echo SET "DateTime=%%date%%__%%time%%"') do %%G
JosefZ

1

Este script utiliza una interfaz WMI a la que se accede principalmente a través de la herramienta WMIC, que es una parte integral de Windows desde Windows XP Professional (la edición Home también es compatible, pero la herramienta no está instalada de manera predeterminada). El script también implementa una solución alternativa de la falta de la herramienta WMIC al crear y llamar a un vbscript WSH para acceder a una interfaz WMI y escribir en la salida de la consola la hora con el mismo formato que proporciona la herramienta WMIC.

@ECHO OFF
REM Returns: RETURN
REM Modify:  RETURN, StdOut
REM Required - mandatory: none
REM Required - optionaly: format strings delimited by a space to format an output delimited by predefined delimiter
REM    YYYY = 4-digit year
REM      MM = 2-digit month
REM      DD = 2-digit day
REM      hh = 2-digit hour
REM      mm = 2-digit minute
REM      ss = 2-digit second
REM      ms = 3-digit millisecond

CALL :getTime %*
ECHO %RETURN%
GOTO :EOF


REM SUBROUTINE
REM Returns: RETURN
REM Modify:  RETURN
REM Required - mandatory: none
REM Required - optionaly: format strings delimited by a space to format an output delimited by predefined delimiter
REM    YYYY = 4-digit year
REM      MM = 2-digit month
REM      DD = 2-digit day
REM      hh = 2-digit hour
REM      mm = 2-digit minute
REM      ss = 2-digit second
REM      ms = 3-digit millisecond
:getTime
  SETLOCAL EnableDelayedExpansion
    SET DELIM=-
    WHERE /Q wmic.exe
    IF NOT ERRORLEVEL 1 FOR /F "usebackq skip=1 tokens=*" %%x IN (`wmic.exe os get LocalDateTime`) DO (SET DT=%%x & GOTO getTime_Parse)
    SET _TMP=%TEMP:"=%
    ECHO Wscript.StdOut.WriteLine (GetObject("winmgmts:root\cimv2:Win32_OperatingSystem=@").LocalDateTime)>"%_TMP%\get_time_local-helper.vbs"
    FOR /F "usebackq tokens=*" %%x IN (`cscript //B //NoLogo "%_TMP%\get_time_local-helper.vbs"`) DO (SET DT=%%x & GOTO getTime_Parse)
    :getTime_Parse
      SET _RET=
      IF "%1" EQU "" (
        SET _RET=%DT:~0,4%%DELIM%%DT:~4,2%%DELIM%%DT:~6,2%%DELIM%%DT:~8,2%%DELIM%%DT:~10,2%%DELIM%%DT:~12,2%%DELIM%%DT:~15,3%
      ) ELSE (
        REM Not recognized format strings are ignored during parsing - no error is reported.
       :getTime_ParseLoop
         SET _VAL=
         IF "%1" EQU "YYYY" SET _VAL=%DT:~0,4%
         IF "%1" EQU "MM"   SET _VAL=%DT:~4,2%
         IF "%1" EQU "DD"   SET _VAL=%DT:~6,2%
         IF "%1" EQU "hh"   SET _VAL=%DT:~8,2%
         IF "%1" EQU "mm"   SET _VAL=%DT:~10,2%
         IF "%1" EQU "ss"   SET _VAL=%DT:~12,2%
         IF "%1" EQU "ms"   SET _VAL=%DT:~15,3%
         IF DEFINED _VAL (
           IF DEFINED _RET (
             SET _RET=!_RET!%DELIM%!_VAL!
           ) ELSE (
             SET _RET=!_VAL!
           )
         )
         SHIFT
         IF "%1" NEQ "" GOTO getTime_ParseLoop
      )
  ENDLOCAL & SET RETURN=%_RET%
GOTO :EOF

1

Un buen truco de una sola línea para evitar la expansión variable temprana es usar cmd /c echo ^%time^%

cmd /c echo ^%time^% & dir /s somelongcommand & cmd /c echo ^%time^%

0
:: =============================================================
:: Batch file to display Date and Time seprated by undescore.
:: =============================================================
:: Read the system date.
:: =============================================================
@SET MyDate=%DATE%
@SET MyDate=%MyDate:/=:%
@SET MyDate=%MyDate:-=:%
@SET MyDate=%MyDate: =:%
@SET MyDate=%MyDate:\=:%
@SET MyDate=%MyDate::=_%
:: =============================================================
:: Read the system time.
:: =============================================================
@SET MyTime=%TIME%
@SET MyTime=%MyTime: =0%
@SET MyTime=%MyTime:.=:%
@SET MyTime=%MyTime::=_%
:: =============================================================
:: Build the DateTime string.
:: =============================================================
@SET DateTime=%MyDate%_%MyTime%
:: =============================================================
:: Display the Date and Time as it is now.
:: =============================================================
@ECHO MyDate="%MyDate%" MyTime="%MyTime%" DateTime="%DateTime%"
:: =============================================================
:: Wait before close.
:: =============================================================
@PAUSE
:: =============================================================

0

Para una solución muy simple para la fecha numérica para usar en nombres de archivos, use el siguiente código:

set month=%date:~4,2%
set day=%date:~7,2%
set curTimestamp=%month%%day%%year%

rem then the you can add a prefix and a file extension easily like this
echo updates%curTimestamp%.txt

0

Divida los resultados del comando de fecha por una barra diagonal, luego puede mover cada uno de los tokens a las variables apropiadas.

FOR /F "tokens=1-3 delims=/" %%a IN ("%date:~4%") DO (
SET _Month=%%a
SET _Day=%%b
SET _Year=%%c
)
ECHO Month %_Month%
ECHO Day %_Day%
ECHO Year %_Year%
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.