Formatta la data e l'ora in uno script batch di Windows


193

In uno script batch di Windows (Windows XP) ho bisogno di formattare la data e l'ora correnti per un uso successivo nei nomi dei file, ecc.

È simile alla domanda Stack Overflow Come aggiungere una data nei file batch , ma anche con l'ora.

Ho questo finora:

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%

che dà:

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

Esiste un modo per consentire un'ora a una cifra in% TIME%, in modo da poter ottenere quanto segue?

2009_07_28__08_36_01



Puoi sostituire spazi vuoti sulla tua datetimefvariabile e inserire invece 0. Nel tuo esempio:SET datetimef=%datetimef: =0%
SebaGra,

Risposte:


148

Ho finito con questo 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%

:: Su WIN2008R2 ad es. Dovevo rendere il tuo 'set month =% date: ~ 3,2%' come sotto :: altrimenti 00 appare per MONTH

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
Cordiali saluti, su Windows Server 2003 e su Windows 7, questo script mi ​​ha dato "201200Mo_085806" (anno e ora corretti).
sfuqua,

50
Come nota per qualcuno che verrà qui da Google (come me): questo dipende dalle impostazioni locali, quindi potrebbe richiedere modifiche per funzionare su Windows non inglese!
PiotrK,

l'ho fatto in questo modo: 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% fData% -> 201310170928
Ghiaccio,

Cosa fa% time: ~ 0,2% dove si trova una documentazione sulla struttura: ~,%?
user1605665

6
Tutto ciò può essere fatto in sole 2 righe usando la normale sostituzione di stringhe: 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
Su Windows Server 2003 e su Windows 7, questo mi ha dato la stringa corretta. Molto più elegante di quello che ho costruito in passato, quindi grazie!
sfuqua,

3
Ecco cosa mi dà in Windows 7 con impostazioni locali russe. L'ora corrente è 03/05/2013 T02: 22: 51, ma la sceneggiatura stampa: "2013-5.-01_02_22_51"
nightcoder

7
% Date% fornirà una stringa diversa con impostazioni internazionali diverse.
AechoLiu,

2
restituisce 20146.0._173502 a me (locale ceco)
Muflix,

2
win7 64 bit ultimo, orario errato: 20140.01_131612, deve essere (2014.10.26_131612)
waza123,

67

Ecco come generare un nome file di registro (basato su 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
...

5
migliore risposta su SO per domande sulla generazione di timestamp indipendente dalla locale in batch.
Mike Campbell,

2
Eccezionale! Dovrebbe esserci un modo per contrassegnare questa come soluzione
Rado,

49

Di solito lo faccio in questo modo ogni volta che ho bisogno di una stringa di data / ora:

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

Questo è per il formato data / ora tedesco (gg.mm.aaaa hh: mm: ss). Fondamentalmente concateno le sottostringhe e infine sostituisco tutti gli spazi con zeri.

Breve spiegazione di come funzionano le sottostringhe:

%VARIABLE:~num_chars_to_skip,num_chars_to_keep%

Quindi, per ottenere solo l'anno da una data come "29.03.2018" utilizzare:

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

7
di gran lunga la soluzione più elegante quando hai solo bisogno di un timestamp pulito (senza spazi o altri caratteri)
jvdneste,

1
Non potrei essere più d'accordo con @jvdneste grazie per aver condiviso mrt
this.user3272243

1
assolutamente fantastico - e funziona [la sintassi richiesta è molto confusa, ma non è certo il problema del poster]
JosephDoggie

38

Se PowerShell è installato, è possibile ottenere facilmente e in modo affidabile la data / ora in qualsiasi formato desiderato, ad esempio:

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

Ovviamente al giorno d'oggi PowerShell è sempre installato, ma su Windows XP probabilmente vorrai utilizzare questa tecnica solo se lo script batch viene utilizzato in un ambiente noto in cui sai che PS è disponibile (o controlla nel tuo file batch se PowerShell è disponibile ...)

Puoi ragionevolmente chiederti: perché usare un file batch se puoi usare PowerShell per ottenere la data / ora, ma penso che alcuni ovvi motivi siano: (a) non hai familiarità con PowerShell e preferisci comunque fare la maggior parte cose alla vecchia maniera con file batch o (b) stai aggiornando un vecchio script e non vuoi trasferire tutto su PS.


(a) nel mio caso, e questo funziona perfettamente (il pipistrello è solo per il mio ambiente, ma ho mescolato i locali su PC diversi). Grazie!
ccalboni,

30

Oggi ho riscontrato questo problema e l'ho risolto con:

SET LOGTIME=%TIME: =0%

Sostituisce gli spazi con 0 e sostanzialmente zero-pad l'ora.

Dopo alcune ricerche rapide non ho scoperto se richiedesse estensioni di comando (funzionava ancora con SETLOCAL DISABLEEXTENSIONS).


OK, sostituzione in variabili. Ora - come sostituire i due punti ( :)?
Tomasz Gandor,

@TomaszGandor Questo funziona per me: echo %TIME: =:%ma se non lo è, forse prova a scappare :con un ^like echo %TIME: =^:%(che funziona anche per me).
Opello,

1
+1 per semplicità. I due punti non sono validi nei nomi di file. set theTime =% Time :: =% li elimina. Puoi sostituire 0 per spazio, eliminare i due punti e troncare a 6 caratteri (eliminando così la parte decimale) in una singola istruzione? Non è un grosso problema se ci vogliono due o tre righe. Sono solo curioso.
riderBill

Non che io sappia. Per favore segui se ne trovi uno!
opello,

21

Come è stato notato, l'analisi della data e dell'ora è utile solo se si conosce il formato utilizzato dall'utente corrente (ad esempio, MM / gg / aa o gg-MM-aaaa solo per citarne due). Questo potrebbe essere determinato, ma quando fai tutto lo stress e l'analisi, ti ritroverai ancora in una situazione in cui viene utilizzato un formato imprevisto e saranno necessarie ulteriori modifiche.

È inoltre possibile utilizzare alcuni programmi esterni che restituiranno una lumaca della data nel formato preferito, ma che presenta gli svantaggi della necessità di distribuire il programma di utilità con lo script / batch.

Ci sono anche trucchi batch che utilizzano l'orologio CMOS in un modo piuttosto grezzo, ma è troppo vicino ai fili scoperti per la maggior parte delle persone, e non sempre è il luogo preferito per recuperare la data / ora.

Di seguito è una soluzione che evita i problemi di cui sopra. Sì, introduce alcuni altri problemi, ma per i miei scopi ho scoperto che questa è la soluzione più semplice, chiara e portatile per creare un datestamp in file .bat per i moderni sistemi Windows. Questo è solo un esempio, ma penso che vedrai come modificare altri formati di data e / o ora, ecc.

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
Proprio quello che stavo cercando. Qualcosa che funziona su ogni impostazione locale. Grazie!
Lost_DM,

+1 per i "moderni sistemi Windows" di cui ci occuperemo :) Scherzi a parte, questo è un modo molto ingegnoso, e come hai detto, portatile, di affrontare il problema.
Zach Young,

9
Questa è una soluzione terribile. Se fallisce, un'impostazione globale viene modificata in modo permanente. Inoltre introduce le condizioni di gara con altre applicazioni.
MikeKulls,

È possibile utilizzare la reg query "HKCU\Control Panel\International" /v sShortDateparte senza modificare le impostazioni del registro (esercizio lasciato al lettore!).
tricasse

9

Quanto segue potrebbe non essere una risposta diretta, ma una risposta stretta?

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%

Almeno potrebbe essere d'ispirazione.


9

Se non hai esattamente bisogno di questo formato:

2009_07_28__08_36_01

Quindi è possibile utilizzare le seguenti 3 righe di codice che utilizzano% date% e% time%:

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

Nota: i caratteri /e :vengono rimossi e il carattere .e lo spazio vengono sostituiti da un carattere di sottolineatura.

Esempio di output (preso mercoledì 8/5/15 alle 12:49 PM con 50 secondi e 93 millisecondi):

echo %mytimestamp%
Wed_08052015_124950_93

quando l'ora è inferiore a 12, imposta mydate =% date: / =% imposta mytime =% time :: =% imposta mytime =% mytime: = 0% imposta 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

La offset:lengthformattazione supportata con il SETcomando in Windows non ti permetterà di riempire 0come sembri essere interessato.

Tuttavia, è possibile codificare uno script BATCH per verificare che l'ora sia minore di 10e
pad di conseguenza con una echostringa diversa .

Troverai alcune informazioni sul SETcomando su questo link .


Puoi anche passare ad altri metodi di programmazione per arrivare qui.

È abbastanza semplice in unix bash (disponibile con Cygwin su Windows) dire,

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

E, sempre pad correttamente.


6

L'ho fatto in questo modo:

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


Funziona su server inglese (Nome SO: Microsoft (R) Windows (R) Server 2003 Standard x64 Edition, Versione SO: 5.2.3790 Service Pack 2 Build 3790)
Ice,

1
e testato anche su server tedesco (nome del sistema Betriebs: Microsoft® Windows Server® 2008 Enterprise, versione del sistema Betriebs: 6.0.6002 Service Pack 2 Build 6002)
Ice,

1
Anche questo è ok: (Nome del sistema Betriebs: Microsoft Windows Server 2012 Standard, Versione del sistema Betriebs: 6.2.9200 Nicht zutreffend Build 9200)
Ghiaccio,

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 prima riga emette sempre in questo formato riguardo al fuso orario:
20150515150941.077000 + 120
Questo ti lascia solo con la formattazione dell'output per soddisfare i tuoi desideri.


4

Questo file bat (salva come datetimestr.bat) produce la stringa datetime 3 volte: (1) stringa datetime lunga con giorno della settimana e secondi, (2) stringa datetime breve senza di essi e (3) versione breve del codice.

@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

Per dare il giusto credito, ho unito i concetti di Peter Mortensen (18 giugno 14 alle 21:02) e Opello (25 agosto 11 alle 14:27).

Puoi scrivere molto più breve, ma questa versione lunga semplifica la lettura e la comprensione del codice.


4

Sono davvero nuovo ai file batch e questo è il mio codice !! (Non sono sicuro del perché, ma non sono riuscito a combinare data / t e ora / t insieme e non ho potuto usare % date% e % time% direttamente senza una variabile ...)

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

È un po 'riutilizzato dagli altri (la domanda era ottenere un calendario formattato da usare come nome file).


4

C'è un altro modo semplice per farlo:

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

3

Per generare un YYYY-MM-DD hh:mm:sstimestamp (24 ore) che uso:

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%)

Presuppone una particolare impostazione regionale?
Peter Mortensen,

1
Secondo ss64.com/nt/syntax-variables.html le variabili %TIME%e %DATE%usano rispettivamente lo stesso formato dei comandi TIMEe DATE. Sul mio sistema le variabili non corrispondono alle mie impostazioni internazionali.
M. Dudley,

3

Questo script batch farà esattamente ciò che l'OP vuole (testato su Windows XP SP3).

Ho anche usato quell'ingegnoso trucco del registro descritto da "jph" in precedenza in cui IMHO è il modo più semplice per ottenere una formattazione coerente al 100% della data "yyyy_MM_dd"su qualsiasi sistema Windows nuovo o vecchio. La modifica a un valore del Registro di sistema per eseguire questa operazione è temporanea e banale istantanea; dura solo pochi millisecondi prima di tornare immediatamente indietro.

Fare doppio clic su questo file batch per una demo istantanea, verrà visualizzata la finestra del prompt dei comandi e verrà visualizzato il timestamp. . . . .

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: 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

Funziona anche su Windows 2019. Terrò la tua soluzione in giro, mi piace :)
user225479

Domanda, ho appena scoperto che dopo mezzanotte, lo "0" finale viene eliminato nell'output. Qualche idea sul perché? Il mio output con il tuo script dà: Il tuo timestamp è: 2019_09_16__0_58_07 Invece di ..00_58_07. Ma dopo l'una funziona come previsto (e darà un output: ..01_01_56).
user225479,

Ho aggiunto IF% HOUR% == 0 (SET HOUR = 00) all'istruzione ELSE. Ciò dovrebbe risolverlo, spero :)
user225479

Grazie per il feedback @ user225479. Ho corretto il codice. Tutte le possibili permutazioni della variabile HOUR convertite nel formato 24 HOUR ora funzioneranno correttamente. Ho anche modificato il layout in modo che sia più facile da leggere.
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

Crea un file chiamato "search_files.bat" e posiziona il contenuto qui sotto nel file. Quindi fare doppio clic su di esso. La variabile temporanea% THH% è stata creata per gestire la AM in modo appropriato. Se è presente uno 0 nelle prime 2 cifre del tempo, Windows ignora il resto del nome del file 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

Mi piace la versione breve in cima a @The lorax, ma per altre impostazioni della lingua potrebbe essere leggermente diversa.

Ad esempio, nelle impostazioni della lingua tedesca (con formato data naturale: gg.mm.aaaa) la query del mese deve essere modificata da 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

Questi sono i miei 2 centesimi per a datetime string. Sui MM DD YYYYsistemi commutare la prima e la seconda voce %DATE:~.

    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

Ho provato la risposta accettata e funziona abbastanza bene. Sfortunatamente il formato ora degli Stati Uniti sembra essere H: MM: SS.CS e lo 0 mancante sul fronte stava causando problemi di analisi prima delle 10 del mattino. Per superare questo ostacolo e consentire anche l'analisi della maggior parte dei formati dell'ora mondiale, ho ideato questa semplice routine che sembra funzionare abbastanza bene.

: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

La cosa bella di questa routine è che passi la stringa temporale come primo parametro e il nome della variabile d'ambiente che vuoi contenere il tempo (in centisecondi) come secondo parametro. Per esempio:

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

(*Chris*)


1

Forse qualcosa del genere:

@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

In situazioni come questa usa un approccio di programmazione semplice e standard: invece di dedicare un enorme sforzo all'analisi di un'entità sconosciuta, è sufficiente salvare la configurazione corrente, reimpostarla su uno stato noto, estrarre le informazioni e quindi ripristinare lo stato originale. Utilizzare solo risorse di Windows standard.

In particolare, i formati di data e ora sono memorizzati nella chiave di registro HKCU \ Control Panel \ International \ in [valori MS] "valori": "sTimeFormat" e "sShortDate". Reg è l'editor del registro della console incluso in tutte le versioni di Windows. Non sono richiesti privilegi elevati per modificare la chiave 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

Semplice, diretto e dovrebbe funzionare per tutte le regioni.

Per motivi che non capisco, il ripristino del valore "sShortDate" ha effetto immediato in una finestra della console, ma il ripristino del valore "sTimeFormat" molto simile NON ha effetto fino all'apertura di una nuova finestra della console. Tuttavia, l'unica cosa che può essere modificata è il delimitatore: le posizioni delle cifre sono fisse. Allo stesso modo, il token temporale "HH" dovrebbe anteporre gli zeri iniziali, ma non è così. Fortunatamente, le soluzioni alternative sono facili.


-1 "Invece di aggiungere uno zero iniziale, perché non interrompere la configurazione della macchina, cambiarla in base alle proprie necessità casuali e quindi fare le proprie cose?" Questo approccio è fuori dal mondo, richiede un notevole sforzo e può portare a un numero infinito di conseguenze indesiderate. E non voglio nemmeno iniziare la discussione sulla leggibilità e sul comportamento del codice previsto standard. complimenti.
Vaitrafra,

Il ripristino del sTimeFormatformato dell'ora è inutile . No. Poiché influisce sul successivo prompt della console, applicalo utilizzandofor /f "delims=" %%G in ('cmd /C echo SET "DateTime=%%date%%__%%time%%"') do %%G
JosefZ il

1

Questo script utilizza un'interfaccia WMI accessibile principalmente tramite lo strumento WMIC, che è parte integrante di Windows poiché Windows XP Professional (anche l'edizione Home è supportata, ma lo strumento non è installato per impostazione predefinita). Lo script implementa anche una soluzione alternativa dello strumento WMIC mancante creando e chiamando un vbscript WSH per accedere a un'interfaccia WMI e scrivere sull'output della console l'ora con lo stesso formato fornito dallo strumento 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

È necessario utilizzare un bel trucco a linea singola per evitare l'espansione variabile precoce 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

Per una soluzione molto semplice per la data numerica da utilizzare nei nomi di file, utilizzare il codice seguente:

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

Dividi i risultati del comando data per barra, quindi puoi spostare ciascuno dei token nelle variabili appropriate.

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%
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.