bat. Помогите с решением... Вычисление даты - 6 дней, если попадает на предыдущий месяц

AsterixM
Дата: 06.02.2018 09:48:09
Всем привет.
Столкнулся с такой проблемой, что не могу понять, как вычислить дату... Использовал скрипт указанный ниже

rem @Echo Off
setlocal
1>nul chcp 1251
setlocal enabledelayedexpansion

set log_file=C:\1.log
set dd=%date:~0,2%
set mm=%date:~3,2%
set yyyy=%date:~6,4%

if %dd:~0,1%==0 set dd=%dd:~1%
if %mm:~0,1%==0 set mm=%mm:~1%



set /a feb=yyyy%%4
if %feb%==0 (set feb=29) else (set feb=28)

set /a tok=mm-1
if %tok%==0 set tok=12
for /f "tokens=%tok%" %%i in ("31 %feb% 31 30 31 30 31 31 30 31 30 31") do (
rem минус 1 день  set /a dd-=1
   set /a dd-=1
    if !dd!==0 (
        set dd=%%i
        set mm=%tok%
        if !mm!==12 set /a yyyy-=1
    )
)

set dd=0%dd%
set mm=0%mm%

set FinishDate=%dd:~-2%-%mm:~-2%-%yyyy%
echo FinishDateLog=%FinishDate%>>%log_file%

rem [b]------------- FinishDate показывает правильно -------------------[/b]

 rem  set dd1=%dd:~-2%
 rem set mm1=%mm:~-2%
set dd1=%date:~0,2%
set mm1=%date:~3,2%
set yyyy1=%date:~6,4%
 
  if %dd1:~0,1%==0 set dd1=%dd1:~1%
  if %mm1:~0,1%==0 set mm1=%mm1:~1%

 set /a feb1=yyyy1%%4
 if %feb1%==0 (set feb1=29) else (set feb1=28)

set /a tok1=mm1-1
if %tok1%==0 set tok1=12
for /f "tokens=%tok1%" %%k in ("31 %feb1% 31 30 31 30 31 31 30 31 30 31") do (
rem минус 6 день  set /a dd-=6
   set /a [b]dd1-=6[/b]
	echo i=%k%>>%log_file%   
    if !dd1!==0 (
        set dd1=%%k
        set mm1=%tok1%
        if !mm1!==12 set /a yyyy1-=1
    )
)

 
 set dd1=0%dd1%
 set mm1=0%mm1%

set StartDate=%dd1:~-2%-%mm1:~-2%-%yyyy1%
echo StartDateLog=%StartDate%>>%log_file%
rem ------ [b]если например пытаемся от 05 числа минус 6 дней, здесь уже показывает неправильно[/b]
exp98
Дата: 06.02.2018 11:33:45
AsterixM, другой год? 30 февраля? 31 июня?
В батнике муторно писать логику.
Если запутался, нарисуй на бумаге схему всех вариантов, без "оптимизаций".

В помощь
SHIFT
предопределённые переменные среды на каждый yyyy, mm, dd
внешний ехе/питон/пхп/vscript/jscript (в винде) с потоковым входм / выходом (либо читающее/пишущее в переменные среды), т.к. в ЯП легко пишется с библиотечными ф-циями.
Akina
Дата: 06.02.2018 12:06:50
Вычисление даты - 6 дней, если попадает на предыдущий месяц

1) Получить текущий день D
2) Получить текущий месяц M и год Y
3) Получить предыдущий месяц: если M=1, то M=12, Y=Y-1, иначе M=M-1
4) Добавить к дню D количество дней в предыдущем месяце N
5) Вычесть 6
6) Сравнить результат с N
7а) Если больше - отнять, и добавить текущий месяц и год
7б) Иначе - добавить предыдущий месяц и год
AsterixM
Дата: 06.02.2018 12:52:50
exp98
AsterixM, другой год? 30 февраля? 31 июня?
В батнике муторно писать логику.
Если запутался, нарисуй на бумаге схему всех вариантов, без "оптимизаций".


Согласен...муторно, да и времени особо искать выхода нет.

Почему я пришел к этому варианту...
В планировщике Windows, настроена задача, которая вызывает exe c входными параметрами(exe уже есть),
prog.exe ..... /Param1=StartDate /Param2=FinishDate, где
FinishDate - это текущая дата минус 1 день (вчерашний день)
StartDate - это FinishDate минус 6 день

Понимаю, что в самом проекта exe , можно использовать библиотеку для работы с датами (проще, но не нужно)
Нужно просто передавать эти даты и всё...
Я не нашел другого варианта, как использовать bat, а в батнике вызывать start .....\prog.exe /Param1=StartDate /Param2=FinishDate,
соответственно подготовив сначала для этого переменные FinishDate, StartDate

Есть ли другие альтернативы, чтобы можно было бы обойтись без bat, но при этом передавать вычисляемые даты в планировщике?
exp98
Дата: 06.02.2018 13:10:45
AsterixM,
за другие возможности не скажу, мне это редко надо, а у себя точно так же вешаю на задание 3-тьестепенную информационную мелочёвку. файл.cmd вызывает другой файл.cmd и/или файл.vbs и т.п. И что мешает прикрутить вызов нормального скрипта? разве что пароли ...
Например в одном случае шлю еmail из файл.vbs
Для VScript'а/CScript вообще только виндовс и нужен.
В командной строке CScript //nologo "wscheck.vbs" -t=1 <bbb >tt

Или вот выдрал пример своей логики, только для примера и то не для любых веков/1000-й
и только для месяцев
/// Вычисляет диапазон месяцев между 2-мя датами (1 ... ) в предположении, что from <= to
int TDateReport::MonthsBetweenDates( TDateTime fromD, TDateTime toD)
{
    try
    {   unsigned short y0,m0,d0, y1,m1,d1;
        fromD.DecodeDate(&y0,&m0,&d0);  toD.DecodeDate(&y1,&m1,&d1);
        int dm;

        //dm= (y0 == y1 ? (int)m1 - (int)m0 + 1 :
        //            (12 - (int)m0 +1) + 12*((int)y1 - (int)y0 -1) + m1); // март-март = 1 месяц

        dm= (12 - (int)m0 +1) + 12*((int)y1 - (int)y0 -1) + m1; // март-март = 1 месяц
        return dm;
    }
}//end_sub

для дней в принципе аналогично, c тем усложнением, что вместо 12 будет переменное число 28/29/30/31
AsterixM
Дата: 06.02.2018 13:13:37
Нашел интересную ссылку....
кстати, вариант использования VBS в bat https://stackoverflow.com/questions/355425/date-arithmetic-in-cmd-scripting
AsterixM
Дата: 06.02.2018 13:17:15
exp98
AsterixM,
за другие возможности не скажу, мне это редко надо, а у себя точно так же вешаю на задание 3-тьестепенную информационную мелочёвку. файл.cmd вызывает другой файл.cmd и/или файл.vbs и т.п. И что мешает прикрутить вызов нормального скрипта? разве что пароли ...

Спасибо... Действительно вариант, единственно я так понимаю, скрипты должны рядом с bat валятся, хотя это не проблема
Akina
Дата: 06.02.2018 13:25:50
AsterixM
Я не нашел другого варианта, как использовать bat
Перепиши ВЕСЬ БАТНИК на VBS.
Планировщику пофиг, кого запускать и кому параметры передавать. А на VBS прибавлять-отнимать дни от даты - элементарно...
AsterixM
Дата: 06.02.2018 13:33:39
Akina
AsterixM
Я не нашел другого варианта, как использовать bat
Перепиши ВЕСЬ БАТНИК на VBS.
Планировщику пофиг, кого запускать и кому параметры передавать. А на VBS прибавлять-отнимать дни от даты - элементарно...

Было уже такое, минус в том, что он в потоке создает ещё wbscript.exe, и было замечено, что он не высвобождает себя, поэтому пришлось отказаться от этой идеи. Примечание: в vbs скрипте создавал объект COM и работал с ним...но отказался от этого подхода.

А в найденом примере он также использует vbs, но только для вычисления даты и всё, без использования COM.... Мне этого наверное достаточно будет
Akina
Дата: 06.02.2018 13:41:07
AsterixM, у тебя заявленная задача - запустить EXE с параметрами... какие там СОМ и зависший wbscript?