Como obter a data em um arquivo em lotes em um formato previsível?


17

Em um arquivo em lotes, eu preciso extrair um mês, dia, ano do comando date. Então, usei o seguinte, que analisa essencialmente o comando Date para extrair suas sub-strings em uma variável:

set Day=%Date:~3,2%
set Mth=%Date:~0,2%
set Yr=%Date:~6,4%

Tudo isso é ótimo, mas se eu implantar esse arquivo em lotes em uma máquina com configurações regionais / de países diferentes, ele falhará porque mês, dia e ano estão em locais diferentes.

Como extrair mês, dia e ano, independentemente do formato da data?


1
Você está absolutamente restrito ao lote? Tal coisa é muito mais simples em VBScript / WSH e / ou PowerShell ...
Adrien

@ Adrien, Sim limitado ao lote - faz parte da etapa de pós-compilação do VS2008.
23911 AngryHacker

substituindo% date% por data%: ~ 6,4% -% date: ~ 3,2% -% date: ~ 0,2% trabalhavam
MagTun

Respostas:


14

Fonte: http://ss64.com/nt/syntax-getdate.html

Método 2 (cmd único)

GetDate.cmd

@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
)
:s_done

:: Pad digits with leading zeros
      Set _mm=%_mm:~-2%
      Set _dd=%_dd:~-2%
      Set _hour=%_hour:~-2%
      Set _minute=%_minute:~-2%

:: Display the date/time in ISO 8601 format:
Set _isodate=%_yyyy%-%_mm%-%_dd% %_hour%:%_minute%
Echo %_isodate%
pause

insira a descrição da imagem aqui


Método 1 (cmd + vb)

GetDate.cmd

@Echo off
For /f %%G in ('cscript /nologo getdate.vbs') do set _dtm=%%G
Set _yyyy=%_dtm:~0,4%
Set _mm=%_dtm:~4,2%
Set _dd=%_dtm:~6,2%
Set _hh=%_dtm:~8,2%
Set _nn=%_dtm:~10,2%
Echo %_yyyy%-%_mm%-%_dd%T%_hh%:%_nn%

getdate.vbs

Dim dt
dt=now
'output format: yyyymmddHHnn
wscript.echo ((year(dt)*100 + month(dt))*100 + day(dt))*10000 + hour(dt)*100 + minute(dt)

1
Ah ha, maneira muito elegante de encontrar a data da encomenda do local. O ss64 possui uma comunidade bacana de usuários do cmd.exe.
Nicholi

Eu incluí os dois scripts do seu link de origem. Espero que o seu ok para você
nixda

@ nixda Sem problemas, o que quer que o usuário ajude.
Tex Hex

Se você precisar reter os segundos no "Método 2" acima, adicione Set _second=00%%Kao extrair wmice preencher com zeros à esquerda como os outros.
precisa

12

Windows XP e posterior

getDate.cmd

@echo off
for /f "tokens=2 delims==" %%G in ('wmic os get localdatetime /value') do set datetime=%%G

set year=%datetime:~0,4%
set month=%datetime:~4,2%
set day=%datetime:~6,2%

echo %year%/%month%/%day%

Resultado

insira a descrição da imagem aqui


+1 para a resposta mais concisa. Eu também sugeriria terminar com o ECHO %year%-%month%-%day%formato compatível com ISO e sistema de arquivos (para não mencionar automaticamente as classificações por ano-mês-dia). :-).
Zephan Schroeder 9/04/19

3

Sei que não é exatamente o que você solicitou, mas uso a porta Windows do dateaplicativo Linux a partir de um comando dentro do arquivo em lotes e atribuo o resultado a uma variável.

Ainda estou para encontrar uma maneira de obter a data de forma confiável usando apenas comandos em lote.


2

Use este arquivo em lotes no formato AAAA-MM-DD. Ele usa a ferramenta de instrumentação de janelas que deve estar presente em todas as versões recentes do Windows para obter uma sequência de data e hora independente das configurações regionais.

Salve em um arquivo em lotes no caminho (por exemplo) c: \ windows \ rdate.bat e acesse com um CALL RDATE.BAT para definir a (s) variável (s). Como alternativa, copie o código no seu arquivo em lotes.

Esse formato de data é adequado para nomes de arquivos e log. Classifica corretamente. A variável logtime adiciona uma variável de data e hora como AAAA-MM-DD-HHMMSS, adequada para uso no registro de atividades de arquivos em lotes com segunda precisão.

Ajuste os formatos de data (e hora) conforme desejar. REM a tela ecoa em produção. Os dois números em cada seleção de texto são o índice de caracteres iniciais baseado em zero e o número de caracteres a serem copiados, por exemplo,% datetime: ~ 0,4% utiliza uma substring de 4 caracteres começando na posição 0.

echo off
rem First, get the locality-invariant datetime
for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set datetime=%%I
rem echo %datetime%

rem Build the reverse date string YYYY-MM-DD
set rdate=%datetime:~0,4%-%datetime:~4,2%-%datetime:~6,2%
echo rdate=%rdate%

rem Built a datetime string YYYY-MM-DD-hhmmss
set logtime=%rdate%-%datetime:~8,6% 
echo logtime=%logtime%

1
Quase o mesmo que a resposta de and31415 . Ambos os scripts usamwmic os get localdatetime
nixda


0

Você já tentou usar em NET TIME \\%ComputerName%vez de DATE? Eu acho que isso NET TIMEdeve fornecer os dados em um formato consistente, independentemente da localidade.


Não, não faz.
23911 AngryHacker

Interessante, eu apenas tentei, alternando entre os formatos AU e EUA, e net timesempre produzo no formato m / d / aaaa. @AngryHacker, com quais configurações ele não funcionou para você?
Hydaral 28/07

1
Troquei de francês (belga) e isso me deu 2011-07-27. Os EUA entregam
27/07/2011

0

Graças ao post de Shekhar, isso funciona conforme o necessário e o preenchimento zero do tempo.

@Echo Off

for /f "tokens=1-5 delims=:" %%d in ("%time%") do set var=%date:~10,4%%date:~4,2%%date:~7,2%-%%d%%e

set datetimestr=%var: =0%

set logfile=LogFile-%datetimestr%.txt

echo %logfile%

Saída: LogFile-20151113-0901.txt


-1

Isso pode ser um pouco fora do tópico, mas aqui está um arquivo .bat que eu escrevi para meus próprios backups agendados e também chamo de ações pós-construção no visual studio. Espero que alguns achem útil.

Salve o seguinte em um arquivo .bat

--------------------------------------------------
**:: The following is Copyright © 2012 ShopNetNuke Corp.  All rights reserved.
::  and released under the GNU General Public License (GPLv3)**

:: The following section retrieves the current date and time and formats it into the '%var%' variable
:: This format always ensures that the Date and Time are fixed length to avoid the situation of
:: having a value of '12/ 1/2012 rather than '12/01/2012'
echo off
for /f "tokens=1-5 delims=:" %%d in ("%time%") do set var=%date:~10,4%-%date:~4,2%-%date:~7,2%-%%d-%%e
set var=%var: =0%
echo Beginning my valuable Backup Set:  Backup--%var%

:: If you wanted to request the user input a filename prefix, 
:: then we would use something similar to this
:: set /p nameprefix= Enter the file name prefix?
:: Get the Current Date and Time
::for /f "tokens=1-5 delims=:" %%d in ("%time%") do set var=%date:~10,4%-%date:~4,2%-%date:~7,2%-%%d-%%e
:: set var=%var: =0%
:: echo Beginning my valuable Backup Set:  Backup--%var%_%nameprefix%

Pause

echo Starting SQL Server Database Backup Job...
:: The following line initiates the Backup job within SqlServer Agent.
:: Change 'MyBackupNameInSqlAgent' to the name of the job you want executed
:: Change the directory paths to those relevant to your current system installation directories
:: SqlAgent will not return a value if the backup action succeed, 
:: however, in the event an error is encountered, it will be echoed onto the screen
"C:\Program Files\Microsoft SQL Server\100\Tools\Binn\sqlcmd.exe" -S SQLSERVERNAME\INSTANCENAME -Q "execute msdb.dbo.sp_start_job @job_name = 'MyBackupNameInSqlAgent'"
:: An error will be returned if the Backup job is not found or has already been triggered by another process

echo Starting My Valuable Source Code Directory Backup...

echo ...backing up files and folders in "C:\Source\MyPreciousProjectDirectory\"...
:: The following line will execute the 7zip command to create a .7z file of the directory named in 'MyPreciousProjectDirectory'
:: and tells it to put the archive in the 'MyPreciousBackupDirectory'.  The compression level will be defined by the 7zip default settings
:: The -p flag tells 7zip to password protect the archive, in this case, I've used the Date/Time portion of the filename as the password
:: remove the '-p%var%' section to remove password protection from the archive
"C:\Program Files\7-Zip\7z.exe" a -t7z C:\MyPreciousBackupDirectory\%var%\MyPreciousProject--%var%.7z -p%var% -mhe C:\Source\MyPreciousProjectDirectory\* 

echo Source Code Directory Backups complete.

echo Archiving Database Backups now...
:: The following line will execute the 7zip command to archive the Database backup.
:: The '*' could be replaced by the actual backup name.
:: The '*' indicates all files of type '.bak'
:: The -p flag tells 7zip to password protect the archive, in this case, again, I've used the Date/Time portion of the filename as the password
:: remove the '-p%var%' section to remove password protection from the archive
"C:\Program Files\7-Zip\7z.exe" a -t7z  C:\MyPreciousBackupDirectory\%var%\MyPreciousProject-Database-%var%.7z -p%var% -mhe "C:\Program Files\Microsoft SQL Server\MSSQL10.SQLDEV08\MSSQL\Backup\*.bak"

echo Database Backup Archival process complete.

:: If you wanted to place both the previous backups into one single combination archive,
:: you could do something like the following
"C:\Program Files\7-Zip\7z.exe" a -t7z C:\MyPreciousBackupDirectoryForSourceAndDatabase\%var%\MyPreciousProjectBackupSourceAndDatabase--%var%.7z -p%var% -mhe C:\Source\MyPreciousProjectDirectory\* 


echo Now attempting to copy archives to Network Server...
:: The following line will use xcopy to copy the arechives to the server backup directory and place them in a directory named by the DateTime variable %var%
xcopy /S /I /J /Y C:\MyPreciousBackupDirectory\%var% \\MyPreciousBackupServerName\SourceCode\MyPreciousServerBackupDirectory\%var%
:: Or if the combination above was used then copy that...
xcopy /S /I /J /Y C:\MyPreciousBackupDirectoryForSourceAndDatabase\%var% \\MyPreciousBackupServerName\SourceCode\MyPreciousServerBackupDirectory\%var%


echo 7z Archive files transferred to MyPreciousBackupServerName successfully
echo  ||
echo \||/
echo  \/
echo ---------------------------------------------------
echo ----- BACKUP SET "%var%" COMPLETE ------
echo ---------------------------------------------------
pause

1
tl; dr, você pode adicionar uma explicação sobre o que o script faz. porque não sai como solução imediatamente. Ele também pode ser mais útil, se você pode remover os bits não pertinentes do código
Shekhar

1
O script lote inteiro depende dos %date%e %time%variáveis, que são locale-aware, e realmente não pode ser analisado de uma forma previsível como o OP perguntou.
and31415
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.