Дата и время пакетной команды в имени файла - PullRequest
63 голосов
/ 11 октября 2011

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

Я использую следующее для создания имени файла.Скопируйте и вставьте его в командную строку, и вы увидите имя файла с компонентом Date and Time.

echo Archive_%date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.zip

Вывод

Archive_20111011_ 93609.zip

Однако моя проблема AM против вечера .Отметка времени AM дает мне время 9 (с начальным пробелом) против 10, естественно занимающего два пробела.

Полагаю, моя проблема будет распространяться и на первые девять дней, первые 9 месяцев и т. Д.

Как это исправить, чтобы вместо начальных пробелов были добавлены начальные нули,Я получаю Archive_20111011_093609.zip?

Ответы [ 12 ]

58 голосов
/ 02 августа 2013

Другое решение:

for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set datetime=%%I

Это даст вам (независимо от региональных настроек!):

  20130802203023.304000+120
( YYYYMMDDhhmmss.<milliseconds><always 000>+/-<timedifference to UTC>  )

Отсюда легко:

set datetime=%datetime:~0,8%-%datetime:~8,6%
20130802-203023

Для запроса Логана на тот же формат вывода для «даты-времени, измененной» файла:

for %%F in (test.txt) do set file=%%~fF
for /f "tokens=2 delims==" %%I in ('wmic datafile where name^="%file:\=\\%" get lastmodified /format:list') do set datetime=%%I
echo %datetime%

Это немного сложнее, поскольку он работает только с полными путями, wmic ожидаетобратная косая черта должна быть удвоена, и = должен быть экранирован (первый. Второй защищен окружающими кавычками).

54 голосов
/ 11 октября 2011

Извлеките час, ищите начальный пробел, если нашли, замените на ноль;

set hr=%time:~0,2%
if "%hr:~0,1%" equ " " set hr=0%hr:~1,1%
echo Archive_%date:~-4,4%%date:~-10,2%%date:~-7,2%_%hr%%time:~3,2%%time:~6,2%.zip
19 голосов
/ 02 августа 2013

Вы должны искать;Вы можете просто заменить все пробелы на ноль set hr=%hr: =0% - jeb 11 октября 11 в 14: 16

Итак, я сделал:

set hr=%time:~0,2%
set hr=%hr: =0%

Затем используйте %hr% внутри любой строки, которую вы форматируете, чтобы всегда получать двузначный час.

(комментарий Джеба под самым популярным ответом работал лучше всего для меня и являетсясамое простое. Я опубликую это здесь, чтобы сделать его более очевидным для будущих пользователей.)

15 голосов
/ 11 октября 2011

Как уже указывал Вики, %DATE% и %TIME% возвращают текущую дату и время, используя форматы короткой даты и времени, которые полностью (бесконечно) настраиваются.

Один пользователь может настроить свою систему навозвращение Fri040811 08.03PM, в то время как другой пользователь может выбрать 08/04/2011 20: 30.

Это полный кошмар для программиста на BAT.

Смена формата на фирменный формат может решить проблемупри условии, что вы восстановите предыдущий формат перед выходом из файла BAT.Но это может быть связано с неприятными условиями гонки и усложнить восстановление в отмененных файлах BAT.

К счастью, есть альтернатива.

Вместо этого вы можете использовать WMIC.WMIC Path Win32_LocalTime Get Day,Hour,Minute,Month,Second,Year /Format:table возвращает дату и время неизменным образом.Очень удобно анализировать его напрямую с помощью команды FOR /F.

Итак, собрав части воедино, попробуйте в качестве отправной точки ...

SETLOCAL enabledelayedexpansion
FOR /F "skip=1 tokens=1-6" %%A IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table') DO (
  SET /A FD=%%F*1000000+%%D*100+%%A
  SET /A FT=10000+%%B*100+%%C
  SET FT=!FT:~-4!
  ECHO Archive_!FD!_!FT!.zip
 )
8 голосов
/ 23 сентября 2016

Я нашел лучшее решение для меня, прочитав все ваши ответы:

set t=%date%_%time%
set d=%t:~10,4%%t:~7,2%%t:~4,2%_%t:~15,2%%t:~18,2%%t:~21,2%
echo hello>"Archive_%d%"

Если я получу 20160915_ 150101 (с пробелом и временем).

Если PM, я получаю 20160915_2150101.

4 голосов
/ 11 октября 2011

Вы можете добавить начальные нули к переменной (значение до 99), например, в пакете: IF 1%Var% LSS 100 SET Var=0%Var%

Таким образом, вам нужно будет разбить компоненты даты и времени на отдельные переменные, обработать ихвсе так, а затем объедините их вместе, чтобы создать имя файла.

Однако используемый вами метод анализа даты и времени зависит от настроек языкового стандарта системы.Если вы рады, что ваш код не переносится на другие машины, это, вероятно, хорошо, но если вы ожидаете, что он будет работать в других международных контекстах, тогда вам понадобится другой подход, например, путем считывания настроек реестра:

HKEY_CURRENT_USER\Control Panel\International\iDate
HKEY_CURRENT_USER\Control Panel\International\iTime
HKEY_CURRENT_USER\Control Panel\International\iTLZero

(Последний контролирует, есть ли ведущий ноль по времени, но не по датам, насколько я знаю).

3 голосов
/ 04 февраля 2012
@For /F "tokens=1,2,3,4 delims=/ " %%A in ('Date /t') do @(

Set DayW=%%A

Set Day=%%B

Set Month=%%C


Set Year=%%D


Set All=%%D%%B%%C
)
"C:\Windows\CWBZIP.EXE" "c:\transfer\ziptest%All%.zip" "C:\transfer\MB5L.txt"

Это берет MB5L.txt и сжимает его в ziptest20120204.zip, если запустить 4 февраля 2012

2 голосов
/ 12 февраля 2015

Из приведенного выше ответа я сделал готовую функцию.

Подтверждено с французскими локальными настройками.

:::::::: PROGRAM ::::::::::

call:genname "my file 1.txt"
echo "%newname%"
call:genname "my file 2.doc"
echo "%newname%"

echo.&pause&goto:eof
:::::::: FUNCTIONS :::::::::

:genname
    set d1=%date:~-4,4%
    set d2=%date:~-10,2%
    set d3=%date:~-7,2%
    set t1=%time:~0,2%
    ::if "%t1:~0,1%" equ " " set t1=0%t1:~1,1%
    set t1=%t1: =0%
    set t2=%time:~3,2%
    set t3=%time:~6,2%
    set filename=%~1
    set newname=%d1%%d2%%d3%_%t1%%t2%%t3%-%filename%
goto:eof
1 голос
/ 11 октября 2011

Ваш вопрос вроде бы решен, но ...

Я не уверен, что вы примете правильное решение для вашей проблемы.
Я полагаю, вы пытаетесь каждый день сжимать фактический код проекта.

Возможно, с ZIP и 1980 это было хорошим решением, но сегодня вы должны использовать систему репозитория, такую ​​как subversion или git или ..., но не zip-файл.

Хорошо, может быть, я ошибаюсь.

0 голосов
/ 16 июля 2019

Как уже отмечали другие, форматы даты и времени %DATE% и %TIME% (а также date /T и time /T) зависят от локали, поэтому извлечение текущей даты и времени всегдакошмар, и невозможно получить решение, которое работает со всеми возможными форматами, поскольку нет практически никаких ограничений формата.


Но есть другая проблема с кодом, подобным следующему (допустим, чтоформат даты, например MM/DD/YYYY и 12-часовой формат времени, например h:mm:ss ap, где ap имеет значение AM или PM):

rem // Resolve AM/PM time:
set "HOUR=%TIME:~,2%"
if "%TIME:~-2%" == "PM" if %HOUR% lss 12 set /A "HOUR+=12"
if "%TIME:~-2%" == "AM" if %HOUR% equ 12 set /A "HOUR-=12"
rem // Left-zero-pad hour:
set "HOUR=0%HOUR%"
rem // Build and display date/time string:
echo %DATE:~-4,4%%DATE:~0,2%%DATE:~3,2%_%HOUR:~-2%%TIME:~3,2%%TIME:~6,2%

Каждый экземпляр %DATE% и %TIME%возвращает значение даты или времени, присутствующее во время его расширения, поэтому первое выражение %DATE% или %TIME% может возвращать значение, отличное от следующих (вы можете доказать это при отображении длинной строки, содержащей огромное количество таких, предпочтительно %TIME%, выражения).

Вы могли бы улучшить вышеупомянутый код для хранения одного экземпляра %DATE% и %TIME% следующим образом:

rem // Store current date and time once in the same line:
set "CURRDATE=%DATE%" & set "CURRTIME=%TIME%"
rem // Resolve AM/PM time:
set "HOUR=%CURRTIME:~,2%"
if "%CURRTIME:~-2%" == "PM" if %HOUR% lss 12 set /A "HOUR+=12"
if "%CURRTIME:~-2%" == "AM" if %HOUR% equ 12 set /A "HOUR-=12"
rem // Left-zero-pad hour:
set "HOUR=0%HOUR%"
rem // Build and display date/time string:
echo %CURRDATE:~-4,4%%CURRDATE:~0,2%%CURRDATE:~3,2%_%HOUR:~-2%%CURRTIME:~3,2%%CURRTIME:~6,2%

Но, тем не менее, возвращаемые значения в %DATE% и %TIME% могут отражать разные дни при выполнении в полдень.

Единственный способ иметь один и тот же день в %CURRDATE% и %CURRTIME% - это:

rem // Store current date and time once in the same line:
set "CURRDATE=%DATE%" & set "CURRTIME=%TIME%"
rem // Resolve AM/PM time:
set "HOUR=%CURRTIME:~,2%"
if "%CURRTIME:~-2%" == "PM" if %HOUR% lss 12 set /A "HOUR+=12"
if "%CURRTIME:~-2%" == "AM" if %HOUR% equ 12 set /A "HOUR-=12"
rem // Fix date/time midnight discrepancy:
if not "%CURRDATE%" == "%DATE%" if %CURRTIME:~0,2% equ 0 set "CURRDATE=%DATE%"
rem // Left-zero-pad hour:
set "HOUR=0%HOUR%"
rem // Build and display date/time string:
echo %CURRDATE:~-4,4%%CURRDATE:~0,2%%CURRDATE:~3,2%_%HOUR:~-2%%CURRTIME:~3,2%%CURRTIME:~6,2%

Конечно, возникновение описанной проблемы весьма маловероятно, но в какой-то момент это произойдет и приведет к странным необъяснимым сбоям.


Описанная проблема не может возникнуть при подходахна основе команды wmic, как описано в ответе пользователем Stephan и в ответе пользователем PA. , поэтому яНастоятельно рекомендую пойти на один из них.Единственный недостаток wmic в том, что он намного медленнее.

...