2
votes

L'heure est mal réglée après minuit

J'utilise ce qui suit pour définir la date / l'heure sur quelque chose de plus lisible:

set day=%date:~4,2%
set mth=%date:~7,2%
set yr=%date:~10,4%
set hur=%time:~0,2%
set min=%time:~3,2%
set bdate=[%day%-%mth%-%yr%]-[%hur%-%min%]

cela fonctionne bien et produit quelque chose comme: [02-06-2020] - [22-59]

Cependant, après minuit, le format de l'heure passe de HH: MM: SS: MS à H: MM: SS: MS et perturbe le format et lorsqu'il inclut le : dans le temps, puisque les caractères sont décalés de un, lorsque je créer le fichier journal avec lequel il est incorrect.

Y a-t-il un moyen de le forcer à toujours être un format?


5 commentaires

demandez-vous comment fournir un 0 non significatif pour les heures à un chiffre?


j'en ai besoin pour avoir un zéro non significatif seulement s'il n'y a qu'un seul chiffre pour l'heure, IE: 1-9 am, 10a-12: 59a fonctionne bien, car j'utilise l'heure dans le nom du fichier journal, le fichier est nommé bizarre et devient "fichier" au lieu d'un fichier .txt


Je ne connais pas le fichier batch, mais une astuce que vous pouvez utiliser à partir d'autres programmes / programmation est de convertir l'heure en une chaîne et de la concaténer avec un zéro non significatif lorsque l'heure est inférieure à 10: 00: 00: 00


Vous pouvez également appliquer ce que vous voulez à partir de cela afin de le convertir en 24 heures. https://stackoverflow.com/a/60094011/12343998


vous devriez vraiment utiliser une méthode indépendante de la localisation et des paramètres utilisateur pour obtenir une chaîne de date / heure fiable.


4 Réponses :


0
votes
set "day=%date:~4,2%"
set "mth=%date:~7,2%"
set "yr=%date:~10,4%"
set "_time=0%time%"
set "hur=%_time:~-11,2%"
set "min=%_time:~-8,2%"
set bdate=[%day%-%mth%-%yr%]-[%hur%-%min%]
You can pad time with a 0 and then do the substitution from the right side using negative numbers as the start position of the string. 1:00 would become 01-00 to match the pattern of HH-MM.

0 commentaires

2
votes

L'utilisation des variables d'environnement dynamiques DATE et TIME avec des substitutions de chaînes comme expliqué très détaillé par ma réponse à la question Que signifie% date: ~ -4,4 %% date: ~ -10,2 %% date: ~ -7, 2% _% temps: ~ 0,2 %% temps: ~ 3,2% en moyenne? est très rapide, mais présente l'inconvénient que le format de la chaîne de date et d'heure dépend de la région (pays) configurée pour le compte utilisé lors de l'exécution du fichier de commandes.

La date peut être sans ou avec un jour de semaine abrégé au début et sans ou avec une virgule ajoutée après le jour de la semaine abrégé. La chaîne de date peut être au format année / mois / jour ou mois / jour / année ou jour / mois / année avec / ou . ou - ou  comme séparateur. Voir aussi l'article Wikipédia sur le format de date par pays .

L'heure peut être au format 12 ou 24 heures. L'heure peut être sans ou avec un 0 significatif si elle est inférieure à 10.

Il n'a pas été affiché ce qui est sorti lors de l'exécution de l' echo %DATE% %TIME% avant dix heures du matin et à trois heures de l'après-midi pour connaître le format de date / heure locale.

Il semble qu'il est possible d'utiliser le code suivant avec : comme séparateur dans la chaîne de temps:

C:\Windows\System32\cmd.exe /c C:\Windows\System32\robocopy.exe "C:\|" . /NJH

Si le deuxième caractère de la chaîne de temps est un deux-points, la condition est vraie et la première expression est utilisée avec 0 ajouté à gauche à l'heure à un seul chiffre, sinon le bloc ELSE est utilisé avec l'heure à deux chiffres.

Une autre solution avec le séparateur dans la chaîne de temps étant soit un deux-points, un point ou un espace serait:

set "bdate="
for /F "tokens=1-5 delims=/: " %%I in ('%SystemRoot%\System32\robocopy.exe "%SystemDrive%\|" . /NJH') do if not defined bdate set "bdate=[%%K-%%J-%%I]-[%%L-%%M]"

L'heure restante pour : ou . ou  est affecté à la variable d'environnement Hour avec un zéro non significatif. La minute juste pour : ou . ou  est affecté à la variable Minute . La chaîne date / heure est construite en ne prenant que les deux derniers chiffres de Hour pour que l'heure soit finalement toujours avec deux chiffres dans la chaîne date / heure affectés à la variable d'environnement bdate .


Il serait préférable d'obtenir la date et l'heure actuelles (pays) indépendantes et de les reformater au format souhaité en utilisant des substitutions de chaînes.

Une chaîne de date / heure indépendante de la région peut être obtenue à l' aide de l'outil de ligne de commande Windows Management Instrumentation WMIC .

La ligne de commande

2020/02/08 12:45:14 ERROR 123 (0x0000007B) Accessing Source Directory C:\|\
The filename, directory name, or volume label syntax is incorrect.

sorties UTF-16 Little Endian encodées par exemple:

robocopy "C:\|" . /NJH

Il y a deux lignes vides, puis la ligne avec la date / heure locale actuelle au format aaaaMMjjHHmmss.microseconde ± décalage UTC en minutes et deux autres lignes vides.

Les données peuvent être utilisées avec un code de lot comme celui-ci:

@echo off
for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "DateTime=%%I"
set "bdate=[%DateTime:~6,2%-%DateTime:~4,2%-%DateTime:~0,4%]-[%DateTime:~8,2%-%DateTime:~10,2%]"

Il n'est intéressant ici que la chaîne date / heure entre le signe égal et la virgule décimale qui est la raison de l'utilisation for /F options for /F tokens=2 delims==. pour obtenir seulement 20200208124514 affecté à la variable de boucle I dont la valeur est affectée à côté de la variable d'environnement DateTime .

La variable d'environnement DateTime est reformatée à l'aide de substitutions de chaînes pour obtenir la chaîne de date / heure au format [dd-MM-yyyy]-[HH-mm] ce qui entraîne la définition de la variable d'environnement bdate avec [08-02-2020]-[12-45] .

Il serait bien sûr possible d'utiliser bdate partout au lieu de DateTime pour n'utiliser qu'une seule variable d'environnement au lieu de deux variables.

L'avantage d'utiliser WMIC pour obtenir la date / heure locale est son indépendance sur les paramètres régionaux de Windows et qu'il fonctionne même sous Windows XP. L'inconvénient est que l'exécution de la commande prend un temps assez long (une à deux secondes) par rapport à l'utilisation des variables d'environnement DATE et TIME auxquelles on accède en quelques microsecondes.

La commande FOR a des problèmes pour analyser correctement la sortie Unicode encodée en UTF-16 LE. Il interprète la séquence d'octets 0D 00 0A 00 (retour chariot + saut de ligne) de la sortie WMIC erronée comme 0D 0D 0A , c'est-à-dire comme deux retours chariot et un saut de ligne. Cela entraîne l'interprétation des deux dernières lignes vides à la fin de la sortie WMIC comme deux lignes avec un seul retour chariot sous forme de chaîne.

C'est très souvent un problème parce que le résultat de l' set "EnvironmentVariable=%%I" est avec %%I développant juste pour retourner chariot la suppression de la variable d'environnement déjà définie auparavant avec la valeur correcte.

Il existe plusieurs solutions pour contourner cette erreur d'analyse Unicode de la commande FOR . Il est possible d'ajouter & goto Label pour quitter la boucle avec un saut à :Label sous la boucle FOR une fois que la valeur est assignée à la variable d'environnement pour éviter de rencontrer ce problème du tout.

Une autre solution consiste à utiliser if not defined DateTime set "DateTime=%%I" avec le set "DateTime=" dessus de la ligne de commande FOR pour s'assurer que la commande SET n'est exécutée qu'une seule fois.

Une autre solution est celle utilisée dans ce code. Le nom de la propriété et sa valeur sont affichés sur la même ligne en raison de l'utilisation de l'option WMIC /VALUE . La commande FOR exécute la commande SET en raison de tokens=2 uniquement lorsqu'elle peut diviser la ligne actuelle en au moins deux sous-chaînes (tokens) en utilisant le signe égal et le point comme délimiteurs en raison des delims==. . Mais les mauvaises lignes vides analysées de la sortie WMIC sont pour FOR juste une ligne contenant seulement un retour chariot et n'ont donc pas de deuxième jeton. Pour cette raison, les lignes vides mal analysées sont également ignorées ici par la commande FOR .

Consultez Comment corriger un mauvais comportement d'écrasement de variable lors de l'analyse de la sortie? et cmd écrit en quelque sorte du texte chinois comme sortie pour plus de détails sur le problème d'analyse de FOR sur la sortie encodée UTF-16 LE.


Une autre solution pour obtenir la date et l'heure du jour indépendantes de la région consiste à utiliser ROBOCOPY qui est disponible depuis Windows Vista et Windows Server 2003 dans le répertoire système de Windows, mais n'est pas disponible par défaut sur Windows XP. robocopy.exe de Windows Server 2003 peut être copié dans %SystemRoot%\System32 de Windows XP pour utiliser cet exécutable également sous Windows XP, mais il n'est pas disponible par défaut sous Windows XP.

ROBOCOPY est exécuté avec une chaîne de répertoire source non valide "C:\|" et une chaîne de répertoire de destination valide . (peut également être quelque chose d'autre valide) et l'argument /NJH pour supprimer la sortie des informations d'en-tête.


LocalDateTime=20200208124514.468000+060


Cette exécution produit le message d'erreur:

wmic OS GET LocalDateTime /VALUE

Le format de la date / heure actuelle au début de la deuxième ligne après la ligne vide est indépendant de la région.

Cette sortie peut être traitée avec:

FOR démarre dans ce cas un autre processus de commande en arrière-plan avec %ComSpec% /c et la ligne de commande entre les deux ' ajoutés comme arguments supplémentaires, ce qui entraîne l'installation de Windows dans C:\Windows lors de l'exécution de:

if "%TIME:~1,1%" == ":" (
    set "bdate=[%DATE:~-10,2%-%DATE:~-7,2%-%DATE:~-4%]-[0%TIME:~0,1%-%TIME:~2,2%]"
) else (
    set "bdate=[%DATE:~-10,2%-%DATE:~-7,2%-%DATE:~-4%]-[%TIME:~0,2%-%TIME:~3,2%]"
)

Les cinq premières chaînes séparées par une barre oblique, deux points ou un espace de la première ligne non vide de la sortie du message d'erreur pour gérer STDOUT du processus de commande d'arrière-plan capturé par FOR sont affectées à:

  • I ... un an
  • J ... mois
  • K ... jour
  • L ... heure
  • M ... minute

Les cinq chaînes de données sont concaténées à la chaîne date / heure au format souhaité.

Mais FOR exécutera à nouveau la commande SET pour la deuxième ligne de message d'erreur. Pour cette raison, la variable d'environnement bdate est explicitement indéfinie avant d'exécuter FOR . La variable d'environnement bdate est définie en premier avec la chaîne date / heure et n'est plus modifiée lors du traitement FOR de la deuxième ligne non vide en raison de la condition IF supplémentaire pour éviter d'écraser la chaîne date / heure d'intérêt par une chaîne indésirable.

L'avantage de la solution ROBOCOPY par rapport à la solution WMIC est son temps d'exécution beaucoup plus rapide.


Pour comprendre les commandes utilisées et leur fonctionnement, ouvrez une fenêtre d' invite de commande , exécutez les commandes suivantes et lisez attentivement toutes les pages d'aide affichées pour chaque commande.

  • echo /?
  • for /?
  • if /?
  • robocopy /?
  • set /?
  • wmic /?
  • wmic os /?
  • wmic os get /?
  • wmic os get localdatetime /?

PS: Il existe de nombreuses autres solutions pour obtenir la date / heure actuelle dans un format spécifique indépendant du pays configuré pour le compte utilisé. Toutes ces solutions alternatives peuvent être trouvées dans les réponses sur:

Comment obtenir la date / heure actuelle sur la ligne de commande Windows dans un format approprié pour une utilisation dans un nom de fichier / dossier?


0 commentaires

0
votes
  • Si l'utilisation de wmic.exe est une option, je voudrais suggérer ce code pour ajuster votre disposition de variable et de sortie ...
  • [08-02-2020]-[01-00]
    

    • Les sorties:

    Obs .: Pensez à accepter la réponse @mofi


0 commentaires

2
votes

Le problème est que vous utilisez les valeurs des variables %DATE% et %TIME% , qui contiennent des chaînes qui ne sont pas cohérentes entre les paramètres régionaux, les PC ou les utilisateurs.

Le meilleur conseil est de récupérer les informations en utilisant une méthode alternative, par exemple:

    ↓  ↓  ↓  ↓  ↓    delims
2020/02/08 01:25:04
↑    ↑  ↑  ↑  ↑
 1    2  3  4  5     tokens
 %G  %H %I %J %K

La méthode implique la génération d'un message d'erreur à partir de l'utilitaire . Nous faisons cela en lui demandant de copier à partir d'un répertoire cible nommé : à la racine du lecteur actuel, \ . Une erreur est renvoyée car Windows n'autorise pas les noms de répertoire contenant le caractère : Ce message d'erreur, quels que soient les paramètres régionaux, le PC ou l'utilisateur, génère toujours une ligne commençant par les chaînes de date et d'heure dans un format connu, yyyy/MM/dd hh:mm:ss .

Exemples:

2020/02/08 01:25:04 FEHLER 123 (0x0000007B) Zugriff auf Zielverzeichnis C:\:\
Die Syntax für den Dateinamen, Verzeichnisnamen oder die Datenträgerbezeichnungist falsch.

2020/02/08 01:25:04 ERREUR 123 (0x0000007B) Copie du fichier C:\:\
La syntaxe du nom de fichier, de répertoire ou de volume est incorrecte.

2020/02/08 01:25:04 ОШИБКА 123 (0x0000007B) Доступ к исходной папке C:\:\
‘Ё*в*ЄбЁзҐбЄ*п ®иЁЎЄ* ў Ё¬Ґ*Ё д*©«*, Ё¬Ґ*Ё Ї*ЇЄЁ Ё«Ё ¬ҐвЄҐ ⮬*.

2020/02/08 01:25:04 ERROR 123 (0x0000007B) Accessing Source Directory C:\:\
The filename, directory name, or volume label syntax is incorrect.

Nous exécutons notre commande Robocopy dans une afin de pouvoir capturer les chaînes requises en fonction de leur position de ligne, de leur format et de leurs caractères de séparation connus. Nous devons également tenir compte du fait que la sortie se compose de plusieurs lignes. Pour sélectionner la ligne, j'ai utilisé l'utilitaire de intégré et choisi de ne faire correspondre que les lignes contenant la chaîne  123 car elle ne peut pas apparaître ailleurs dans la sortie. Ensuite, je divise la ligne en utilisant les caractères de séparation connus comme délimiteurs et je choisis le nombre de composants de jeton séparés par un séparateur à renvoyer. Je choisis une barre oblique, / , qui délimite les composants de date individuels , un deux-points. : , qui délimite les composants de temps individuels , et un espace,  , qui sépare la date et l'heure du reste de la ligne et de l'autre . Pour votre cas utilisateur, vous ne vouliez que cinq composants de jeton:

@For /F "Tokens=1-5Delims=/: " %%G In (
    '""%__AppDir__%Robocopy.exe" \: . /NJH /L|"%__AppDir__%find.exe" " 123""'
)Do @Set "bdate=[%%I-%%H-%%G]-[%%J-%%K]"

La dernière chose que je fais est de mettre chacun des composants ensemble dans l'ordre et le format requis, en l'enregistrant en tant que valeur de chaîne dans une variable nommée bdate . Vous devriez pouvoir utiliser cette valeur ailleurs dans le script, comme %bdate% ou !bdate! si l'expansion retardée est activée .

Pour obtenir plus d'informations sur l'utilisation d'une , ouvrez une fenêtre d'invite de commande et entrez for /? .


1 commentaires

Cela fonctionne parfaitement, merci beaucoup et merci d'avoir expliqué comment / pourquoi, j'apprends un peu en faisant des fichiers batch pour le travail et jusqu'à présent, je viens de tâtonner jusqu'à présent.