Как получить дату в пакетном файле в предсказуемом формате?

17

В командном файле мне нужно извлечь месяц, день, год из команды даты. Поэтому я использовал следующее, которое по существу анализирует команду Date для извлечения ее подстрок в переменную:

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

Это все замечательно, но если я разверну этот пакетный файл на машине с другими региональными / страновыми настройками, он потерпит неудачу, потому что месяц, день и год находятся в разных местах.

Как извлечь месяц, день и год независимо от формата даты?

AngryHacker
источник
1
Вы абсолютно ограничены Batch? Такая вещь намного проще в VBScript / WSH и / или PowerShell ...
Adrien
@Adrien, да, ограничено пакетной обработкой - это часть шага после сборки VS2008.
AngryHacker
замена% date% на% date: ~ 6,4% -% date: ~ 3,2% -% date: ~ 0,2% сработало
MagTun

Ответы:

14

Источник: http://ss64.com/nt/syntax-getdate.html

Метод 2 (один cmd)

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

введите описание изображения здесь


Метод 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)
Tex Hex
источник
1
Ага, очень аккуратный способ определения даты в локали. У ss64 есть отличное сообщество пользователей cmd.exe.
Николи
Я включил оба сценария из вашей ссылки на источник. Надеюсь, что все в порядке для вас
Никсда
@nixda Нет проблем, что бы пользователь ни помог.
Tex Hex
Если вам нужно сохранить секунды в «Методе 2» выше, добавьте их Set _second=00%%Kпри извлечении из wmicи добавьте начальные нули, как и остальные.
Тим Паренти
12

Windows XP и выше

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%

Выход

введите описание изображения здесь

and31415
источник
+1 за самый лаконичный ответ. Я также предложил бы закончить ECHO %year%-%month%-%day%форматом, совместимым с ISO и файловой системой (не говоря уже о автоматической сортировке по году-месяцу-дню). :-).
Зефан Шредер
3

Я знаю, что это не совсем то, что вы просили, но я использую порт Windows dateприложения Linux из команды внутри командного файла, а затем присваиваю результат переменной.

Мне еще предстоит найти способ надежного получения даты, используя только пакетные команды.

Hydaral
источник
2

Используйте этот пакетный файл для формата ГГГГ-ММ-ДД. Он использует инструмент управления окнами, который должен присутствовать во всех последних версиях Windows, чтобы получить строку даты и времени, которая не зависит от региональных настроек.

Сохраните в командный файл по пути (например) c: \ windows \ rdate.bat, затем получите доступ к CALL RDATE.BAT, чтобы установить переменную (и). Кроме того, скопируйте код в ваш пакетный файл.

Этот формат даты подходит для имен файлов и ведения журнала. Сортирует правильно. Переменная logtime добавляет переменную дата + время в виде ГГГГ-ММ-ДД-ЧЧММСС, пригодную для использования при регистрации активности пакетного файла со второй точностью.

Настройте форматы даты (и времени) по своему усмотрению. REM экран эхо в производстве. Два числа в каждом выделенном тексте - это начальный индекс начальных символов, начинающийся с нуля, и количество копируемых символов, например,% datetime: ~ 0,4% занимает подстроку из 4 символов, начиная с позиции 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
Почти так же, как и ответ от 31415 . Оба сценария используютwmic os get localdatetime
nixda
1

Хотя вы правы в том, что VS 2008 выводит пакетный файл, вы можете запустить практически любую программу, включая скрипты Powershell и другие программы.

Редактировать:

Вот несколько похожих вопросов:

/programming/1051845/visual-studio-2008-professional-build-process /programming/3049369/embed-application-compilation-time-stamp

Первоначально, я собирался перевести это на SO. , ,

surfasb
источник
0

Вы пытались использовать NET TIME \\%ComputerName%вместо DATE? Я думаю, что NET TIMEпредполагается предоставлять данные в согласованном формате независимо от локали.

Кирк
источник
Нет, это не так.
AngryHacker
Интересно, я только что попробовал, переключаясь между форматами AU и US, и net timeвсегда выводил в формате m / d / yyyy. @AngryHacker, с какими настройками он у тебя не работал?
Hydaral
1
Я переключил французский (бельгийский), и это дало мне 2011-07-27. США дают 27/27/2011
AngryHacker
0

Благодаря посту Шекхара это работает по мере необходимости и ноль заполнения времени.

@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%

Выходные данные: LogFile-20151113-0901.txt

Trifused
источник
-1

Это может быть несколько не по теме, но вот файл .bat, который я написал для своих собственных запланированных резервных копий, а также вызов из действий после сборки в visual studio. Я надеюсь, что некоторые найдут это полезным.

Сохраните следующее в .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
JC
источник
1
tl; dr, вы можете добавить объяснение того, что делает скрипт. потому что это не сразу как решение. Это также может быть более полезным, если вы можете удалить ненужные биты кода
Shekhar
1
Вся партия сценарий опирается на %date%и %time%переменных, которые локали знают, и не может действительно быть разобран предсказуемым образом , как просили ОП.
and31415