Batch Windows: date formatée en variable

105

Comment enregistrer la date actuelle au format AAAA-MM-JJ dans une variable d'un fichier .bat Windows?

Analogique du shell Unix:

today=`date +%F`
echo $today
Maksym Polshcha
la source
1
adarshr, la réponse à cette question utilise une manière assez horrible et sujette aux erreurs de la traiter. Je conseillerais de ne pas l'utiliser.
Joey
Ce lien est utile pour comprendre les réponses ci-dessous. ss64.com/nt/for_f.html
smwikipedia

Réponses:

151

Vous pouvez obtenir la date actuelle de manière indépendante des paramètres régionaux en utilisant

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

Ensuite, vous pouvez extraire les pièces individuelles à l'aide de sous-chaînes:

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

Une autre façon, où vous obtenez des variables contenant les parties individuelles, serait:

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

Beaucoup plus agréable que de jouer avec des sous-chaînes, au détriment de la pollution de votre espace de noms variable.

Si vous avez besoin de l'heure UTC au lieu de l'heure locale, la commande est plus ou moins la même:

for /f %%x in ('wmic path win32_utctime get /format:list ^| findstr "="') do set %%x
set today=%Year%-%Month%-%Day%
Joey
la source
1
@ user2023861 Il semble que même si j'ouvre une invite de commande, j'obtiens toujours la date / heure correcte au moment de l'invocation de la commande, pas quand j'ai ouvert l'invite de commande.
ADTC
5
Notez que si vous exécutez la ligne ci-dessus plusieurs fois, vous n'obtiendrez pas de nouvelle date pour chaque appel, car il vérifie que la variable n'est pas définie. Ceci est nécessaire car for /frenvoie deux lignes, la dernière étant vide. Vous pouvez résoudre cela en utilisant set MyDate=entre les deux. Je suppose que c'est ce sur quoi user2023861 est tombé.
Joey
1
@CharlesWood, au moins je recherche la robustesse de mes propres fichiers batch, bien que ces jours-ci j'utilise souvent PowerShell à la place.
Joey
1
Les variables qui seront définies: Year, Month, Day, Hour, Minute, Second, Quarter, WeekInMonth,DayOfWeek
utilisateur
2
for /f %%x in ('wmic path win32_localtime get /format:list ^| findstr "="') do set %%x set today=%Year%-%Month%-%Day% est une réponse invalide: elle renvoie un mois et un jour. Comment obtenir un remplissage à gauche de 2 chiffres avec zéro chaîne de mois et de jour à date?
Andrus
39

Si vous souhaitez y parvenir en utilisant les commandes MS-DOS standard dans un fichier de commandes, vous pouvez utiliser:

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

Je suis sûr que cela peut être amélioré, mais cela donne la date en 3 variables pour le jour (jj), le mois (mm) et l'année (aaaa). Vous pouvez ensuite les utiliser plus tard dans votre script batch, si nécessaire.

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

Bien que je sache qu'une réponse a été acceptée pour cette question, cette méthode alternative peut être appréciée par beaucoup qui cherchent à y parvenir sans utiliser la console WMI, j'espère donc qu'elle ajoute une certaine valeur à cette question.

Richhallstoke
la source
3
J'ai trouvé que j'avais besoin de changer légèrement cela sur une boîte Windows 7. Les jetons devaient être incrémentés de un: ... FOR / F "TOKENS = 2,3,4 eol = / DELIMS = /" ...
Joe Johnston
1
idem sur Win serveur 2012 sur Azure
Kirill Yunussov
34

Utilisation date /T pour trouver le format sur l'invite de commande.

Si le format de date est Thu 17/03/2016utilisé comme ceci:

set datestr=%date:~10,4%-%date:~7,2%-%date:~4,2%
echo %datestr%
Anup Rav
la source
1
C'est la réponse la plus proche de la question posée. Un simple one-liner était tout ce dont j'avais besoin, pas un programme.
DCookie
2
D'accord. Certaines des réponses ici ressemblent presque à "Installez MS SQL Server, connectez-vous à un client SQL et exécutez la commande SELECT CONVERT(VARCHAR(16), GETDATE(), 112)".
isapir
2
La date-heure au format ISO-8601 est%date:~10,4%%date:~7,2%%date:~4,2%T%time:~0,2%%time:~3,2%%time:~6,2%
isapir
3
La raison pour laquelle les autres réponses ressemblent à un programme est que cette réponse, bien que simple, échouera si vos paramètres régionaux Windows ne sont pas configurés de la manière attendue par ce code (c'est-à-dire que ce code ne fonctionnera pas sur tous les systèmes Windows)
Daniel Scott
20

Deux autres méthodes qui ne dépendent pas des paramètres d'heure (toutes deux tirées de Comment obtenir les données / l'heure indépendamment de la localisation ). Et les deux ont également le jour de la semaine et aucun d'entre eux ne nécessite des autorisations d'administrateur!:

  1. MAKECAB - fonctionnera sur TOUS les systèmes Windows (rapide, mais crée un petit fichier temporaire) (le 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 - ce n'est pas une commande native pour Windows XP et Windows Server 2003 , mais elle peut être téléchargée à partir du site Microsoft . Mais il est intégré à tout à partir de Windows Vista et supérieur:

    @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
    

    Et trois autres façons d'utiliser d'autres langages de script Windows. Ils vous donneront plus de flexibilité, par exemple, vous pouvez obtenir la semaine de l'année, le temps en millisecondes, etc.

  3. Hybride JScript / BATCH (doit être enregistré sous .bat). JScript est disponible sur tous les systèmes à partir de Windows NT et supérieur, en tant que partie de Windows Script Host ( bien qu'il puisse être désactivé via le registre, c'est un cas rare ):

    @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. Hybride VBScript / BATCH ( Est-il possible d'incorporer et d'exécuter VBScript dans un fichier batch sans utiliser de fichier temporaire? ) Même cas que jscript, mais l'hybridation n'est pas si parfaite:

    :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 - peut être installé sur chaque machine équipée de .NET - téléchargement depuis Microsoft ( v1 , v2 et v3 (uniquement pour Windows 7 et supérieur)). Installé par défaut sur tout sous Windows 7 / Win2008 et supérieur:

    C:\> powershell get-date -format "{dd-MMM-yyyy HH:mm}"
    
  6. Jscript.net/batch auto-compilé (je n'ai jamais vu de machine Windows sans .NET donc je pense que c'est un joli portable):

    @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. Bûcheron Cela ne peut pas obtenir l'année et le jour de la semaine. Il est relativement lent, crée également un fichier temporaire et est basé sur les horodatages que logman met sur ses fichiers journaux. Fonctionnera tout à partir de Windows XP et supérieur. Il ne sera probablement jamais utilisé par personne - y compris moi - mais c'est une autre façon ...

    @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
    

Plus d'informations sur la fonction Get-Date .


npocmaka
la source
8

J'ai beaucoup aimé la méthode de Joey, mais j'ai pensé que je la développerais un peu.

Dans cette approche, vous pouvez exécuter le code plusieurs fois sans vous soucier du fait que l'ancienne valeur de date "reste" car elle est déjà définie.

Chaque fois que vous exécutez ce fichier de commandes, il génère une représentation combinée de la date et de l'heure compatible 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%

Dans cette version, vous devrez faire attention à ne pas copier / coller le même code à plusieurs endroits dans le fichier car cela entraînerait des étiquettes en double. Vous pouvez soit avoir une étiquette distincte pour chaque copie, soit simplement mettre ce code dans son propre fichier de commandes et l'appeler à partir de votre fichier source si nécessaire.

Aardvarkk
la source
5

Utilisez simplement la %date%variable:

echo %date%
ProVi
la source
5
Cela renverra la date quel que soit le format de date courte actuellement configuré. C'est rarement ISO-8601.
Joey
@Joey D'accord - Je suis ici parce que ce n'est pas assez bon pour compter.
SteveCinq
5

Selon la réponse de @ProVi, modifiez simplement le format dont vous avez besoin

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

reviendra

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

EDIT Selon le commentaire @Jeb, qui est correct, le format d'heure ci-dessus ne fonctionnera que si votre commande DATE / T renvoie

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

Cependant, il est facile de le modifier en fonction de vos paramètres régionaux, en utilisant l'indexation de chaque caractère dans la chaîne renvoyée par la variable d'environnement% DATE% appropriée, vous pouvez extraire les parties de la chaîne dont vous avez besoin.

par exemple. L'utilisation de% DATE ~ 10,4% étendrait la variable d'environnement DATE, puis n'utiliserait que les 4 caractères commençant au 11e caractère (décalage 10) du résultat développé

Par exemple, si vous utilisez des dates de style américain, ce qui suit s'applique

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
marque
la source
Ce n'est une solution que pour certaines personnes, car cela ne fonctionne que dans certains endroits dans le monde, en fonction de vos paramètres de format de date / heure
jeb
3

J'ai défini une variable d'environnement sur la valeur au format numérique souhaité en faisant ceci:

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

Vérifier celui-ci..

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
Bhaskara Arani
la source
2

Si vous avez installé Python, vous pouvez faire

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

Vous pouvez facilement adapter la chaîne de format à vos besoins.

CodeKid
la source
2
En quoi le fait de dire «Utiliser python» est-il une réponse à la question?
Ross Presser
3
de la même manière que d'utiliser MAKECAB, ROBOCOPY, VBSCRIPT, POWERSHELL Logman et d'autres suggestions ici que vous pouvez appeler sur la ligne de commande?
CodeKid
Cela peut être simplifié python -c "import datetime;print(datetime.date.today())", car la __str__méthode de la dateclasse appelle simplement isoformat().
onewhaleid
2

Il est possible d'utiliser PowerShell et de rediriger sa sortie vers une variable d'environnement à l'aide d'une boucle.

Depuis la ligne de commande ( 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

Dans un fichier de commandes, vous pouvez vous échapper %acomme %%a:

for /f "tokens=*" %%a in ('powershell get-date -format "{yyyy-MM-dd+HH:mm}"') do set td=%%a
user103004
la source
1
Si le masque doit être comme ça FOR /F "tokens=*" %%a IN ('powershell get-date -format "{yyyy\-MM\-dd\THH\:mm\:ss}"') DO SET date=%%a , utilisez MM en haut pour le mois et une barre oblique inverse pour échapper les caractères littéraux.
Whome
1

En raison du format de la date et de l'heure et des informations spécifiques à l'emplacement, leur récupération à partir des variables% date% et% time% nécessitera un effort supplémentaire pour analyser la chaîne avec la transformation du format en considération. Une bonne idée est d'utiliser une API pour récupérer la structure de données et analyser comme vous le souhaitez. WMIC est un bon choix. L'exemple ci-dessous utilise Win32_LocalTime . Vous pouvez également utiliser Win32_CurrentTime ou 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  

Résultat:
2018-04-25_10: 03: 11

Ivellios
la source
1

C'est une extension de la réponse de Joey pour inclure l'heure et remplir les parties avec des 0.

Par exemple, le résultat sera 2019-06-01_17-25-36. Notez également qu'il s'agit de l'heure 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%
datchung
la source
0
echo %DATE:~10,4%%DATE:~7,2%%DATE:~4,2% 
Hillmee Bob
la source
pour une sortie comme celle-ci 20160711
Hillmee Bob
0

J'utilise ce qui suit:

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

Ou en combinaison avec un nom de fichier journal 'MyLogFileName':

set log_file=%date:~6,4%-%date:~3,2%-%date:~0,2%-MyLogFileName
Chris
la source
2
Mais où est votre réponse différente ou meilleure que les 16 autres? Et il y a déjà assez d'indices, que cette solution ne fonctionne que pour votre localisation
jeb
0

Si PowerShell est disponible, vous pouvez utiliser les codes ci-dessous:

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

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

Voici le résultat:

BuildDate=200518
BuildTime=115919
吴新茂
la source
-2

Si un investissement unique de 10 à 30 minutes ne vous dérange pas pour obtenir une solution fiable (qui ne dépend pas des paramètres régionaux de Windows), veuillez lire la suite.

Libérons nos esprits. Voulez-vous simplifier les scripts pour qu'ils ressemblent à ceci? (Supposons que vous souhaitiez définir la variable LOG_DATETIME)

FOR /F "tokens=* USEBACKQ" %%F IN (`FormatNow "yyyy-MM-dd"`) DO (
  Set LOG_DATETIME=%%F
)

echo I am going to write log to Testing_%LOG_DATETIME%.log

Vous pouvez. Créez simplement un FormatNow.exe avec C # .NET et ajoutez-le à votre PATH.

Remarques:

  1. Vous pouvez utiliser n'importe quelle édition de Visual Studio, telle que Visual Studio Express, pour générer le FormatNow.exe.
  2. Dans Visual Studio, choisissez le projet C # «Application console», pas le projet «Application Windows Forms».
  3. Bon sens: le FormatNow.exe construit aura besoin de .NET Framework pour fonctionner.
  4. Bon sens: après avoir ajouté FormatNow.exe à la variable PATH, vous devez redémarrer CMD pour prendre effet. Elle s'applique également à toute modification des variables d'environnement.

Avantages:

  1. Ce n'est pas lent (se termine en 0,2 seconde).
  2. De nombreux formats sont pris en charge https://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx par exemple FormatNow "ddd" pour obtenir uniquement le jour de la semaine, FormatNow "yyyy" pour obtenir uniquement l'année
  3. Cela ne dépend pas des paramètres régionaux de Windows, donc sa sortie est beaucoup plus fiable. D'un autre côté,% date% ne donne pas un format cohérent sur différents ordinateurs et n'est pas fiable.
  4. Vous n'avez pas besoin de créer autant de variables CMD et de polluer l'espace de noms des variables.
  5. Il faudrait 3 lignes dans le script batch pour appeler le programme et obtenir les résultats. Il devrait être suffisamment court.

Code source de FormatNow.exe que j'ai construit avec Visual Studio 2010 (je préfère le construire moi-même pour éviter le risque de télécharger un programme inconnu, éventuellement malveillant). Copiez et collez simplement les codes ci-dessous, créez le programme une fois, puis vous aurez un formateur de date fiable pour toutes les utilisations futures.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace FormatNow
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                if (args.Length < 1)
                {
                    throw new ArgumentException("Missing format");
                }
                string format = args[0];
                Console.Write(DateTime.Now.ToString(format, CultureInfo.InvariantCulture.DateTimeFormat));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

    }
}

En général, lorsque nous traitons des logiques compliquées, nous pouvons le simplifier en construisant un très petit programme et en appelant le programme pour capturer la sortie vers une variable de script batch à la place. Nous ne sommes pas des étudiants et nous ne passons pas d'examens nous obligeant à suivre la règle du script par lots uniquement pour résoudre les problèmes. Dans un environnement de travail réel, toute méthode (légale) est autorisée. Pourquoi devrions-nous encore nous en tenir aux faibles capacités du script batch Windows qui nécessite des solutions de contournement pour de nombreuses tâches simples? Pourquoi devrions-nous utiliser le mauvais outil pour le travail?

sken130
la source