Арифметика даты в сценариях cmd
Мне нужно написать сценарий для изменения имени файла из aDate.txt-bDate.тхт, где:
- aDate-текущая системная дата в yyyymmdd и
- bDate-текущая системная дата - 1 в yyyymmdd.
в настоящее время у меня есть:
set yy=%date:~6,2%
set mm=%date:~3,2%
set dd=%date:~0,2%
if "%date:~6,1%"==" " set yy=0%yy:~1,1%
if "%date:~3,1%"==" " set mm=0%mm:~1,1%
if "%date:~0,1%"==" " set dd=0%dd:~1,1%
SET sys_date=20%yy%%mm%%dd%
ECHO %sys_date%
REM still have to do this bit properly
SET sys_date_yesterday=%sys_date%a
move %sys_date%.txt %sys_date_yesterday%.txt
но я понятия не имею, как сделать дату -1 вещь (кроме долго запыхавшейся) вычесть 1 из дня, и если это = 0, то вычесть один из месяц и день = последний день нового месяца и так далее в течение многих лет.
какие идеи?
5 ответов
Это также работает:
http://www.robvanderwoude.com/datetiment.php#Yesterday
Он очень полный в том, что он проверяет реестр для локальных настроек формата даты и использует их при создании вчерашней даты.
вы должны сделать это трудный путь. Я предлагаю использовать этой решение SteveGTR. Я копирую текст ниже, потому что, по крайней мере, я не всегда вижу решение на этом сайте.
вот пакетный файл, который я разработал, чтобы вычесть любое количество дней из текущей даты. Он принимает параметр командной строки количества дней. Значение по умолчанию-1 день (вчера):
@echo off
set yyyy=
set $tok=1-3
for /f "tokens=1 delims=.:/-, " %%u in ('date /t') do set $d1=%%u
if "%$d1:~0,1%" GTR "9" set $tok=2-4
for /f "tokens=%$tok% delims=.:/-, " %%u in ('date /t') do (
for /f "skip=1 tokens=2-4 delims=/-,()." %%x in ('echo.^|date') do (
set %%x=%%u
set %%y=%%v
set %%z=%%w
set $d1=
set $tok=))
if "%yyyy%"=="" set yyyy=%yy%
if /I %yyyy% LSS 100 set /A yyyy=2000 + 1%yyyy% - 100
set CurDate=%mm%/%dd%/%yyyy%
set dayCnt=%1
if "%dayCnt%"=="" set dayCnt=1
REM Substract your days here
set /A dd=1%dd% - 100 - %dayCnt%
set /A mm=1%mm% - 100
:CHKDAY
if /I %dd% GTR 0 goto DONE
set /A mm=%mm% - 1
if /I %mm% GTR 0 goto ADJUSTDAY
set /A mm=12
set /A yyyy=%yyyy% - 1
:ADJUSTDAY
if %mm%==1 goto SET31
if %mm%==2 goto LEAPCHK
if %mm%==3 goto SET31
if %mm%==4 goto SET30
if %mm%==5 goto SET31
if %mm%==6 goto SET30
if %mm%==7 goto SET31
if %mm%==8 goto SET31
if %mm%==9 goto SET30
if %mm%==10 goto SET31
if %mm%==11 goto SET30
REM ** Month 12 falls through
:SET31
set /A dd=31 + %dd%
goto CHKDAY
:SET30
set /A dd=30 + %dd%
goto CHKDAY
:LEAPCHK
set /A tt=%yyyy% %% 4
if not %tt%==0 goto SET28
set /A tt=%yyyy% %% 100
if not %tt%==0 goto SET29
set /A tt=%yyyy% %% 400
if %tt%==0 goto SET29
:SET28
set /A dd=28 + %dd%
goto CHKDAY
:SET29
set /A dd=29 + %dd%
goto CHKDAY
:DONE
if /I %mm% LSS 10 set mm=0%mm%
if /I %dd% LSS 10 set dd=0%dd%
echo Date %dayCnt% day(s) before %CurDate% is %mm%/%dd%/%yyyy%
Удачи, Стив!--4-->
легко добавлять или вычитать дни с даты с помощью пакетного скрипта Windows
вот решение, которое я придумал для вычисления даты (сложения или вычитания) с помощью пакетного скрипта. Установите переменные соответственно для ваших потребностей, а затем настройте логику как необходимость для ваших потребностей. Это очень хорошо работает для моих нужд, и все это содержится в одном и том же пакетном скрипте без слишком большой логики.
добавить: вы также можете использовать этот скрипт для добавления ряда дней до текущей даты, удалив минус (-
)
символ из приведенного ниже пакетного сценария в :DynamicVBSScriptBuild
рутина, так где вы видите это,-%MinusDay%,
вы просто удалите символ "минус", чтобы получить ,%MinusDay%,
на каждой из этих строк и сейчас MinusDay=
значение переменной будет равно количеству дней, которые вы хотите добавить.
Важное Замечание: похоже, что пять 9-х (99999
) - это ограничение на пакетный скрипт при вычитании с помощью MinusDays=
значение. Также кажется, что шесть 9-х (999999
) - это ограничение на пакетный скрипт при добавлении с помощью MinusDays=
значение.
Скрипт
@ECHO ON
::// Minus days is the number of days to subtract from the CURRENT DAY i.e. 2 for minus 2 days or 99999 for minus 99999 days from when it's run
SET MinusDay=2
:: This calls the temp vbs script routine that will be used to set YYYY-MM-DD values for the subtracted days date you specify
CALL :DynamicVBSScriptBuild
FOR /F "TOKENS=*" %%A IN ('cscript//nologo "%YYYYTmpVBS%"') DO SET YYYY=%%A
FOR /F "TOKENS=*" %%A IN ('cscript//nologo "%MMTmpVBS%"') DO SET MM=%%A
FOR /F "TOKENS=*" %%A IN ('cscript//nologo "%DDTmpVBS%"') DO SET DD=%%A
::// Set your web server log file path in the below variable
SET WebServerLogPath=C:\WebServer\Logs
::// Set web server log file name where YYYY MM DD variables are set to the values after the day numbers setup above are subtracted
SET YYYY=%YYYY%
SET MM=%MM%
SET DD=%DD%
ECHO %YYYY%%MM%%DD%
PAUSE
GOTO EOF
:DynamicVBSScriptBuild
SET YYYYTmpVBS=%temp%\~tmp_yyyy.vbs
SET MMTmpVBS=%temp%\~tmp_mm.vbs
SET DDTmpVBS=%temp%\~tmp_dd.vbs
IF EXIST "%YYYYTmpVBS%" DEL /Q /F "%YYYYTmpVBS%"
IF EXIST "%MMTmpVBS%" DEL /Q /F "%MMTmpVBS%"
IF EXIST "%DDTmpVBS%" DEL /Q /F "%DDTmpVBS%"
ECHO dt = DateAdd("d",-%MinusDay%,date) >> "%YYYYTmpVBS%"
ECHO yyyy = Year(dt) >> "%YYYYTmpVBS%"
ECHO WScript.Echo yyyy >> "%YYYYTmpVBS%"
ECHO dt = DateAdd("d",-%MinusDay%,date) >> "%MMTmpVBS%"
ECHO mm = Right("0" ^& Month(dt),2) >> "%MMTmpVBS%"
ECHO WScript.Echo mm >> "%MMTmpVBS%"
ECHO dt = DateAdd("d",-%MinusDay%,date) >> "%DDTmpVBS%"
ECHO dd = Right("0" ^& Day(dt),2) >> "%DDTmpVBS%"
ECHO WScript.Echo dd >> "%DDTmpVBS%"
GOTO EOF
Дополнительные Ресурсы
мне нужно было что-то, что вычитало бы дни из текущей даты при проверке високосных лет и т. д. и это сработало великолепно.
Я просто вызываю его из этих скриптов с необходимым параметром (количество дней для вычитания), а затем он вызывает вызывающий скрипт с подстановками и передает параметр обратно в исходный скрипт для измененной (вычитаемой) даты.
вот примеры:
скрипт, нуждающийся в переменной расчета даты set:
IF "%1"=="" goto modifydate
:modifydate
SET subtractdays=5
SET ModDateScript=\servershare\path\Called_Scripts\ModDate.cmd
CALL "%ModDateScript%" %subtractdays% "%~fnx0"
скрипт, который вычислит и передаст обратно параметр %moddate% исходному вызывающему скрипту, который будет установлен в качестве переменной для соответствующей обработки. Вы просто поместите это в конец скрипта, который вы вызываете, чтобы изменить / вычесть дни из текущей даты (ModDate.УМК.)
SET moddate=%mm%/%dd%/%yyyy%
Call %2 %moddate%
GOTO EOF
я смог протестировать и определить, что эти строки из исходного сценария размещены:
set yyyy=
set $tok=1-3
for /f "tokens=1 delims=.:/-, " %%u in ('date /t') do set $d1=%%u
if "%$d1:~0,1%" GTR "9" set $tok=2-4
for /f "tokens=%$tok% delims=.:/-, " %%u in ('date /t') do (
for /f "skip=1 tokens=2-4 delims=/-,()." %%x in ('echo.^|date') do (
set %%x=%%u
set %%y=%%v
set %%z=%%w
set $d1=
set $tok=))
if "%yyyy%"=="" set yyyy=%yy%
if /I %yyyy% LSS 100 set /A yyyy=2000 + 1%yyyy% - 100
можно заменить только эту одну строку и работает так же хорошо:
FOR /F "tokens=2-4 delims=/ " %%A IN ("%date%") DO SET "mm=%%A" DO (& SET "dd=%%B") DO (& SET "yyyy=%%C")
пожалуйста, объясните, что эти строки (те, которые я изменил только на одну строку с и утверждениями) делают в любом случае, потому что я не могу быстро определить разницу. Я вычитал до 19-го века, и это показалось мне точным. Я подумал, что, возможно, это поможет справиться с вычислениями, где модифицированный год будет меньше 2000, но я не видел этого, если я что-то не пропустил.
в противном случае этот сценарий можно смело назвать и передайте %mm%/%dd% / %yyyy% в качестве параметра для нескольких скриптов, которые нуждаются в собственных вычислениях. Отличное и очень эффективное пакетное решение. Я могу передать аргумент как %1, %2, %3 и т. д. и все же используйте setlocal в этом скрипте для текущей даты - просто сделайте переменную чем-то вроде moddate=%1 и т. д.
наконец, я призываю любого эксперта пакетного сценария оптимизировать этот сценарий еще больше и опубликовать результаты для пакетных людей для тестирования.
спасибо, P
попробуйте использовать этот код другими словами. Вы можете использовать в качестве подпрограммы скрипта или использовать это с функциями вызова и параметров, чтобы вернуться к исходному пакетному файлу:
:: Pass 1st parameter as number of days (whole numbers) to subtract from current day in date
:: This script is able to subtract days to any date of the current date
:: This script will check for leap years, etc. as well
@echo on
::for /f "tokens=2-4 delims=/ " %%A in ("%date%") do set "mm=%%A" do & set "dd=%%B" do & set "yyyy=%%C"
set "mm=%date:~4,2%" & set "dd=%date:~7,2%" & set "yyyy=%date:~10,4%"
set CurDate=%mm%/%dd%/%yyyy%
set dayCnt=%1
if "%dayCnt%"=="" set dayCnt=1
:: Substract your days here
set /A dd=1%dd% - 100 - %dayCnt%
set /A mm=1%mm% - 100
:CHKDAY
if /I %dd% GTR 0 goto DONE
set /A mm=%mm% - 1
if /I %mm% GTR 0 goto ADJUSTDAY
set /A mm=12
set /A yyyy=%yyyy% - 1
:ADJUSTDAY
if %mm%==1 goto SET31
if %mm%==2 goto LEAPCHK
if %mm%==3 goto SET31
if %mm%==4 goto SET30
if %mm%==5 goto SET31
if %mm%==6 goto SET30
if %mm%==7 goto SET31
if %mm%==8 goto SET31
if %mm%==9 goto SET30
if %mm%==10 goto SET31
if %mm%==11 goto SET30
:: ** Month 12 falls through
:SET31
set /A dd=31 + %dd%
goto CHKDAY
:SET30
set /A dd=30 + %dd%
goto CHKDAY
:LEAPCHK
set /A tt=%yyyy% %% 4
if not %tt%==0 goto SET28
set /A tt=%yyyy% %% 100
if not %tt%==0 goto SET29
set /A tt=%yyyy% %% 400
if %tt%==0 goto SET29
:SET28
set /A dd=28 + %dd%
goto CHKDAY
:SET29
set /A dd=29 + %dd%
goto CHKDAY
:DONE
if /I %mm% LSS 10 set mm=0%mm%
if /I %dd% LSS 10 set dd=0%dd%
echo Date %dayCnt% day(s) before %CurDate% is %mm%/%dd%/%yyyy%
SET DirDate=%mm%/%dd%/%yyyy%
:: The %2 parameter is passed from the calling script as the full path and name of the file to call back
:: %2 equals %~fnx0
:: The dirdate variable is passed as parameter %1 back to the calling script
Call %2 %dirdate%
GOTO EOF
Я собираюсь искать vb или что-то более эффективное, я все еще могу включать или вызывать из пакета для динамического вычисления дат.