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
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
Risposte:
È 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%
for /f
restituisce due righe, l'ultima delle quali vuota. Puoi risolverlo usando set MyDate=
in mezzo. Immagino che questo sia ciò che user2023861 inciampò.
Year
, Month
, Day
, Hour
, Minute
, Second
, Quarter
, WeekInMonth
,DayOfWeek
for /f %%x in ('wmic path win32_localtime get /format:list ^| findstr "="') do set %%x set today=%Year%-%Month%-%Day%
è 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?
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.
Utilizzare date /T
per trovare il formato sul prompt dei comandi.
Se il formato della data è Thu 17/03/2016
utilizzato in questo modo:
set datestr=%date:~10,4%-%date:~7,2%-%date:~4,2%
echo %datestr%
SELECT CONVERT(VARCHAR(16), GETDATE(), 112)
".
%date:~10,4%%date:~7,2%%date:~4,2%T%time:~0,2%%time:~3,2%%time:~6,2%
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 !:
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
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.
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());
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), ", ", "-")
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}"
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"));
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 .
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.
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
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
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.
python -c "import datetime;print(datetime.date.today())"
, perché il __str__
metodo della date
classe chiama solo isoformat()
.
È 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 %a
come %%a
:
for /f "tokens=*" %%a in ('powershell get-date -format "{yyyy-MM-dd+HH:mm}"') do set td=%%a
FOR /F "tokens=*" %%a IN ('powershell get-date -format "{yyyy\-MM\-dd\THH\:mm\:ss}"') DO SET date=%%a
quindi usa MM superiore per mese e barra rovesciata per sfuggire ai caratteri letterali.
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
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%
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
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:
Benefici:
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?