Batch Windows: data formattata in variabile


105

Come faccio a salvare la data corrente nel formato AAAA-MM-GG in una variabile in un file .bat di Windows?

Analogo della shell Unix:

today=`date +%F`
echo $today

1
possibile duplicato di data e ora in formato script batch
adarshr


1
Adarshr, la risposta a questa domanda utilizza un modo piuttosto orribile e soggetto a errori per affrontarla. Consiglierei di non usarlo.
Joey

Questo collegamento è utile per comprendere le risposte di seguito. ss64.com/nt/for_f.html
smwikipedia

Risposte:


151

È possibile ottenere la data corrente in modo indipendente dalle impostazioni locali utilizzando

for /f "skip=1" %%x in ('wmic os get localdatetime') do if not defined MyDate set MyDate=%%x

Quindi puoi estrarre le singole parti usando le sottostringhe:

set today=%MyDate:~0,4%-%MyDate:~4,2%-%MyDate:~6,2%

Un altro modo, in cui si ottengono variabili che contengono le singole parti, sarebbe:

for /f %%x in ('wmic path win32_localtime get /format:list ^| findstr "="') do set %%x
set today=%Year%-%Month%-%Day%

Molto più carino che armeggiare con le sottostringhe, a scapito dell'inquinamento dello spazio dei nomi delle variabili.

Se hai bisogno dell'UTC invece dell'ora locale, il comando è più o meno lo stesso:

for /f %%x in ('wmic path win32_utctime get /format:list ^| findstr "="') do set %%x
set today=%Year%-%Month%-%Day%

1
@ user2023861 Sembra che anche se apro un prompt dei comandi, ottengo sempre la data / ora corretta al momento dell'invocazione del comando, non quando ho aperto il prompt dei comandi.
ADTC

5
Nota che se esegui la riga sopra più volte non otterrai una nuova data per ogni chiamata, poiché controlla che la variabile non sia definita. Ciò è necessario perché for /frestituisce due righe, l'ultima delle quali vuota. Puoi risolverlo usando set MyDate=in mezzo. Immagino che questo sia ciò che user2023861 inciampò.
Joey

1
@CharlesWood, almeno mi sforzo per la robustezza nei miei file batch, anche se in questi giorni utilizzo spesso PowerShell.
Joey

1
Le variabili che verranno impostate: Year, Month, Day, Hour, Minute, Second, Quarter, WeekInMonth,DayOfWeek
utente

2
for /f %%x in ('wmic path win32_localtime get /format:list ^| findstr "="') do set %%x set today=%Year%-%Month%-%Day% è una risposta non valida: restituisce una cifra per mese e giorno. Come ottenere 2 cifre a sinistra riempite con zero mese e stringa da giorno a data?
Andrus

39

Se desideri ottenere ciò utilizzando i comandi MS-DOS standard in un file batch, puoi utilizzare:

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

Sono sicuro che questo può essere ulteriormente migliorato, ma questo dà la data in 3 variabili per giorno (gg), mese (mm) e anno (aaaa). È quindi possibile utilizzarli in un secondo momento nello script batch come richiesto.

SET todaysdate=%yyyy%%mm%%dd%
echo %dd%
echo %mm%
echo %yyyy%
echo %todaysdate%

Anche se capisco che una risposta è stata accettata per questa domanda, questo metodo alternativo potrebbe essere apprezzato da molti che cercano di ottenere questo risultato senza utilizzare la console WMI, quindi spero che aggiunga un certo valore a questa domanda.


3
Ho scoperto che avevo bisogno di cambiarlo leggermente su una scatola di Windows 7. I token dovevano essere incrementati di uno: ... FOR / F "TOKENS = 2,3,4 eol = / DELIMS = /" ...
Joe Johnston

1
lo stesso su Win server 2012 su Azure
Kirill Yunussov

34

Utilizzare date /Tper trovare il formato sul prompt dei comandi.

Se il formato della data è Thu 17/03/2016utilizzato in questo modo:

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

1
Questa è la risposta più vicina alla domanda posta. Una semplice battuta era tutto ciò di cui avevo bisogno, non un programma.
DCookie

2
Concordato. Alcune delle risposte qui sembrano quasi "Installa MS SQL Server, connettiti con un client SQL ed esegui il comando SELECT CONVERT(VARCHAR(16), GETDATE(), 112)".
isapir

2
La data e l'ora nel formato ISO-8601 è%date:~10,4%%date:~7,2%%date:~4,2%T%time:~0,2%%time:~3,2%%time:~6,2%
isapir

3
Il motivo per cui le altre risposte sembrano un programma è che questa risposta, sebbene semplice, fallirà se le impostazioni internazionali di Windows non sono configurate nel modo previsto da questo codice (cioè questo codice non funzionerà su tutti i sistemi Windows)
Daniel Scott

20

Altri due modi che non dipendono dalle impostazioni dell'ora (entrambi presi da Come ottenere dati / ora indipendentemente dalla localizzazione ). Ed entrambi ottengono anche il giorno della settimana e nessuno di loro richiede le autorizzazioni di amministratore !:

  1. MAKECAB - funzionerà su OGNI sistema Windows (veloce, ma crea un piccolo file temporaneo) (lo 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 : non è un comando nativo per Windows XP e Windows Server 2003 , ma può essere scaricato dal sito Microsoft . Ma è integrato in tutto da Windows Vista e versioni successive:

    @echo off
    setlocal
    for /f "skip=8 tokens=2,3,4,5,6,7,8 delims=: " %%D in ('robocopy /l * \ \ /ns /nc /ndl /nfl /np /njh /XF * /XD *') do (
        set "dow=%%D"
        set "month=%%E"
        set "day=%%F"
        set "HH=%%G"
        set "MM=%%H"
        set "SS=%%I"
        set "year=%%J"
    )
    
    echo Day of the week: %dow%
    echo Day of the month : %day%
    echo Month : %month%
    echo hour : %HH%
    echo minutes : %MM%
    echo seconds : %SS%
    echo year : %year%
    endlocal
    

    E altri tre modi in cui utilizza altri linguaggi di script di Windows. Ti daranno maggiore flessibilità, ad es. Puoi ottenere la settimana dell'anno, il tempo in millisecondi e così via.

  3. JScript / BATCH ibrido (deve essere salvato come .bat). JScript è disponibile su tutti i sistemi da Windows NT e versioni successive, come parte di Windows Script Host ( anche se può essere disabilitato tramite il registro è 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 ibrido ( è possibile incorporare ed eseguire VBScript all'interno di un file batch senza utilizzare un file temporaneo? ) Stesso caso di jscript, ma l'ibridazione non è così perfetta:

    :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 : può essere installato su ogni macchina con .NET, scaricabile da Microsoft ( v1 , v2 e v3 (solo per Windows 7 e versioni successive)). Installato di default su tutto da Windows 7 / Win2008 e versioni successive:

    C:\> powershell get-date -format "{dd-MMM-yyyy HH:mm}"
    
  6. Jscript.net/batch autocompilato (non ho mai visto una macchina Windows senza .NET quindi penso che questo sia abbastanza portatile):

    @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"));
    
  7. Logman Questo non può ottenere l'anno e il giorno della settimana. È relativamente lento, crea anche un file temporaneo e si basa sui timestamp che logman inserisce nei suoi file di registro.Funzionerà tutto da Windows XP e versioni successive. Probabilmente non verrà mai usato da nessuno, me compreso, ma è un altro modo ...

    @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
    

Ulteriori informazioni sulla funzione Get-Date .



8

Mi è piaciuto molto il metodo di Joey, ma ho pensato di approfondirlo un po '.

In questo approccio, è possibile eseguire il codice più volte e non preoccuparsi che il vecchio valore della data "rimanga" perché è già definito.

Ogni volta che si esegue questo file batch, verrà emessa una rappresentazione combinata di data e ora compatibile 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%

In questa versione, dovrai fare attenzione a non copiare / incollare lo stesso codice in più punti del file perché ciò causerebbe etichette duplicate. Puoi avere un'etichetta separata per ogni copia o semplicemente inserire questo codice nel proprio file batch e chiamarlo dal tuo file sorgente ove necessario.


5

Usa la %date%variabile:

echo %date%

5
Ciò restituirà la data in qualunque sia il formato di data breve attualmente configurato. Questo è raramente ISO-8601.
Joey

@Joey d'accordo - Sono qui perché non è abbastanza buono su cui fare affidamento.
SteveCinq

5

Come da risposta di @ProVi, cambia semplicemente per adattarlo alla formattazione richiesta

echo %DATE:~10,4%-%DATE:~7,2%-%DATE:~4,2% %TIME:~0,2%:%TIME:~3,2%:%TIME:~6,2%

sarà di ritorno

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

MODIFICA Come per il commento @Jeb, chi è corretto, il formato dell'ora sopra funzionerà solo se il comando DATE / T ritorna

ddd dd/mm/yyyy
Thu 17/09/2015

È facile modificarlo per adattarlo alle proprie impostazioni locali, tuttavia, utilizzando l'indicizzazione di ogni carattere nella stringa restituita dalla relativa variabile d'ambiente% DATE% è possibile estrarre le parti della stringa necessarie.

per esempio. L'uso di% DATE ~ 10,4% espande la variabile d'ambiente DATE e quindi utilizza solo i 4 caratteri che iniziano con l'undicesimo carattere (offset 10) del risultato espanso

Ad esempio, se si utilizzano date in stile USA, si applica quanto segue

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

È solo una soluzione per alcune persone, poiché funziona solo in alcune località del mondo, a seconda delle impostazioni del formato di data / ora
jeb

3

Ho impostato una variabile di ambiente sul valore nel formato numerico desiderato in questo modo:

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

2

Controlla questo ..

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

2

Se hai installato Python, puoi farlo

python -c "import datetime;print(datetime.date.today().strftime('%Y-%m-%d'))"

Puoi adattare facilmente la stringa di formato alle tue esigenze.


2
In che modo dire "Usa python" è una risposta alla domanda?
Ross Presser

3
nello stesso modo in cui usi MAKECAB, ROBOCOPY, VBSCRIPT, POWERSHELL Logman e altri suggerimenti qui che puoi chiamare dalla riga di comando?
CodeKid

Questo può essere semplificato python -c "import datetime;print(datetime.date.today())", perché il __str__metodo della dateclasse chiama solo isoformat().
onewhaleid

2

È possibile utilizzare PowerShell e reindirizzarne l'output a una variabile di ambiente utilizzando un ciclo.

Dalla riga di 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

In un file batch potresti uscire %acome %%a:

for /f "tokens=*" %%a in ('powershell get-date -format "{yyyy-MM-dd+HH:mm}"') do set td=%%a

1
La maschera dovrebbe essere così, FOR /F "tokens=*" %%a IN ('powershell get-date -format "{yyyy\-MM\-dd\THH\:mm\:ss}"') DO SET date=%%a quindi usa MM superiore per mese e barra rovesciata per sfuggire ai caratteri letterali.
Whome

1

A causa del formato di data e ora è informazioni specifiche sulla posizione, il loro recupero dalle variabili% date% e% time% richiederà uno sforzo extra per analizzare la stringa con la trasformazione del formato in considerazione. Una buona idea è utilizzare alcune API per recuperare la struttura dei dati e analizzarla come desideri. WMIC è una buona scelta. L'esempio seguente usa Win32_LocalTime . Puoi anche usare 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  

Risultato:
2018-04-25_10: 03: 11


1

Questa è un'estensione della risposta di Joey per includere il tempo e riempire le parti con 0.

Ad esempio, il risultato sarà 2019-06-01_17-25-36. Nota anche che questa è l'ora 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%


0

Sto usando quanto segue:

set iso_date=%date:~6,4%-%date:~3,2%-%date:~0,2%

O in combinazione con un nome di file di registro "MyLogFileName":

set log_file=%date:~6,4%-%date:~3,2%-%date:~0,2%-MyLogFileName

2
Ma dov'è la tua risposta diversa o migliore rispetto alle altre 16? E ci sono già abbastanza indizi, che questa soluzione funziona solo per la tua localizzazione
jeb

0

Se è disponibile PowerShell, puoi utilizzare i codici seguenti:

# get date
$BuildDate=(get-date -format "yyMMdd")
echo BuildDate=$BuildDate

# get time
$BuildTime=(get-date -format "hhmmss")
echo BuildTime=$BuildTime

Ecco il risultato:

BuildDate=200518
BuildTime=115919

-2

Se non ti dispiace un investimento una tantum di 10-30 minuti per ottenere una soluzione affidabile (che non dipende dalle impostazioni della regione di Windows), continua a leggere.

Liberiamo le nostre menti. Vuoi semplificare gli script per assomigliare a questo? (Supponi di voler impostare la variabile 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

Puoi. Crea semplicemente un FormatNow.exe con C # .NET e aggiungilo al tuo PATH.

Appunti:

  1. È possibile utilizzare qualsiasi edizione di Visual Studio, ad esempio Visual Studio Express, per creare FormatNow.exe.
  2. In Visual Studio, scegli il progetto C # "Applicazione console", non il progetto "Applicazione Windows Form".
  3. Buon senso: il formato FormatNow.exe costruito richiederà .NET Framework per essere eseguito.
  4. Buon senso: dopo aver aggiunto FormatNow.exe alla variabile PATH, è necessario riavviare CMD per avere effetto. Si applica anche a qualsiasi modifica nelle variabili di ambiente.

Benefici:

  1. Non è lento (termina entro 0,2 secondi).
  2. Sono supportati molti formati https://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx ad es. FormatNow "ddd" per ottenere solo il giorno della settimana, FormatNow "yyyy" per ottenere solo l'anno
  3. Non dipende dalle impostazioni della regione di Windows, quindi il suo output è molto più affidabile. D'altra parte,% date% non fornisce un formato coerente su computer diversi e non è affidabile.
  4. Non è necessario creare così tante variabili CMD e inquinare lo spazio dei nomi delle variabili.
  5. Richiederebbero 3 righe nello script batch per richiamare il programma e ottenere i risultati. Dovrebbe essere abbastanza breve.

Codice sorgente di FormatNow.exe che ho creato con Visual Studio 2010 (preferisco crearlo da solo per evitare il rischio di scaricare un programma sconosciuto, possibilmente dannoso). Basta copiare e incollare i codici di seguito, creare il programma una volta e quindi disporre di un formattatore di data affidabile per tutti gli usi futuri.

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());
            }
        }

    }
}

In generale, quando si ha a che fare con logiche complicate, è possibile renderlo più semplice costruendo un programma molto piccolo e chiamando il programma per catturare l'output in una variabile di script batch. Non siamo studenti e non stiamo sostenendo esami che ci richiedono di seguire la regola dello script batch per risolvere i problemi. Nell'ambiente di lavoro reale, è consentito qualsiasi metodo (legale). Perché dovremmo ancora attenerci alle scarse capacità dello script batch di Windows che necessita di soluzioni alternative per molte semplici attività? Perché dovremmo usare lo strumento sbagliato per il lavoro?

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.