|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - [решено] Посчитать количество дней между двумя датами |
|
CMD/BAT - [решено] Посчитать количество дней между двумя датами
|
Новый участник Сообщения: 26 |
Имеется 2 переменных
Date2 всегда больше Date1 Формат всегда ГГММДД Нужно посчитать кол-во дней между ними ( = 72 ) Запнулся на такой задаче, предположение как решить: посчитать разность лет,месяцев,дней затем перемножить и сложить и играться с этими данными добавив условия но думаю есть решение проще... Буду благодарен за подсказку если таковое есть. Все это нужно сделать именно в bat |
|
Отправлено: 16:55, 24-05-2018 |
Ветеран Сообщения: 27449
|
Профиль | Отправить PM | Цитировать Цитата wlad1164:
|
|
Отправлено: 17:08, 24-05-2018 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Ветеран Сообщения: 992
|
Профиль | Сайт | Отправить PM | Цитировать wlad1164, мсье знает толк в извращениях. Тут час убить только на то чтобы прописать условия для всех месяцев, учесть високосный год, имхо, если так уж нужно получать эти данные в bat - проще выполнять вычисления, например, в powershell, в нужном формате возвращать результат и разбив его извращаться дальше.
|
Отправлено: 17:43, 24-05-2018 | #3 |
Ветеран Сообщения: 27449
|
Профиль | Отправить PM | Цитировать Elven, ну, коллеги тут делать-то делали подобное, при большом желании напишут. А так — да, хотелось бы понять причины требования «только пакетный файл».
|
Отправлено: 18:09, 24-05-2018 | #4 |
Ветеран Сообщения: 2732
|
Профиль | Отправить PM | Цитировать bat+js
@set @E=1; /* @Echo Off cls Set /A Date1=180312 Set /A Date2=180523 Set /A Vek=20 FOR /F "usebackq delims=" %%d IN (`Cscript //NoLogo /E:jscript "%~dpnx0" %Vek%%Date2% %Vek%%Date1%`) DO Set /A Days=%%d Echo %Date2%-%Date1%=%Days% Pause GoTo :Eof */ var oArg = WScript.Arguments; if (oArg.Count()<2) WScript.Quit(1); var msek1=Date.UTC(oArg(0).substr(0,4),oArg(0).substr(4,2)-1,oArg(0).substr(6,2)); var msek2=Date.UTC(oArg(1).substr(0,4),oArg(1).substr(4,2)-1,oArg(1).substr(6,2)); WScript.Echo((msek1-msek2)/86400000); WScript.Quit(0); |
|
------- Отправлено: 20:01, 24-05-2018 | #5 |
Новый участник Сообщения: 26
|
Профиль | Отправить PM | Цитировать Iska, ну главный вопрос был в том а нет ли какой-либо функции для этого, насколько понял нет...
megaloman, спасибо что не поленились затратить время, но хотелось бы без JS.... Попыхтев пару часов получилось что то вроде этого: Коряво, но вроде работает
echo off Chcp 1251 cls :: Установка дат Set /a Date1=180312 Set /a Date2=180523 echo %time% :: Разбивка первой даты Set /a God1= %Date1:~0,2%+2000 Set /a Mes1= %Date1:~2,2% Set /a Day1= %Date1:~4,2% :: Разбивка второй даты Set /a God2= %Date2:~0,2%+2000 Set /a Mes2= %Date2:~2,2% Set /a Day2= %Date2:~4,2% :: Считаем кол-во дней в за годы первой даты Set /a GodVis1=%God1%/4 Set /a GodNeVis1=%God1%/4-1 Set /a VisGod1=%God1%%%4 If "%VisGod1%"=="0" (Set /a KolNeVisGod1=%God1%-%GodNeVis1%) If "%VisGod1%"=="1" (Set /a KolNeVisGod1=%God1%-%GodNeVis1%) If "%VisGod1%"=="2" (Set /a KolNeVisGod1=%God1%-%GodVis1%) If "%VisGod1%"=="3" (Set /a KolNeVisGod1=%God1%-%GodVis1%) Set /a KolVisGod1=%God1%-%KolNeVisGod1% Set /a DaysGod1=%KolVisGod1%*366+%KolNeVisGod1%*365 :: Считаем кол-во дней за годы второй даты Set /a GodVis2=%God2%/4 Set /a GodNeVis2=%God2%/4-1 Set /a VisGod2=%God2%%%4 If "%VisGod2%"=="0" (Set /a KolNeVisGod2=%God2%-%GodNeVis2%) If "%VisGod2%"=="1" (Set /a KolNeVisGod2=%God2%-%GodNeVis2%) If "%VisGod2%"=="2" (Set /a KolNeVisGod2=%God2%-%GodVis2%) If "%VisGod2%"=="3" (Set /a KolNeVisGod2=%God2%-%GodVis2%) Set /a KolVisGod2=%God2%-%KolNeVisGod2% Set /a DaysGod2=%KolVisGod2%*366+%KolNeVisGod2%*365 :: Разность жней меду годами Set /a RaznostGod=%DaysGod2%-%DaysGod1% :: Считаем кол-во дней за месяца первой даты :: Февраль первой даты If "%VisGod1%"=="0" (Set /a FebDate1=29) else (Set /a FebDate1=28) :: Дни If "%Mes1%"=="1" (Set /a DayMes1=%Day1%) If "%Mes1%"=="2" (Set /a DayMes1=31+%Day1%) If "%Mes1%"=="3" (Set /a DayMes1=31+%FebDate1%+%Day1%) If "%Mes1%"=="4" (Set /a DayMes1=31*2+%FebDate1%+%Day1%) If "%Mes1%"=="5" (Set /a DayMes1=31*2+%FebDate1%+30+%Day1%) If "%Mes1%"=="6" (Set /a DayMes1=31*3+%FebDate1%+30+%Day1%) If "%Mes1%"=="7" (Set /a DayMes1=31*3+%FebDate1%+30*2+%Day1%) If "%Mes1%"=="8" (Set /a DayMes1=31*4+%FebDate1%+30*2+%Day1%) If "%Mes1%"=="9" (Set /a DayMes1=31*5+%FebDate1%+30*2+%Day1%) If "%Mes1%"=="10" (Set /a DayMes1=31*5+%FebDate1%+30*3+%Day1%) If "%Mes1%"=="11" (Set /a DayMes1=31*6+%FebDate1%+30*3+%Day1%) If "%Mes1%"=="12" (Set /a DayMes1=31*6+%FebDate1%+30*4+%Day1%) :: Считаем кол-во дней за месяца второй даты :: Февраль второй даты If "%VisGod2%"=="0" (Set /a FebDate2=29) else (Set /a FebDate2=28) :: Дни If "%Mes2%"=="1" (Set /a DayMes2=%Day2%) If "%Mes2%"=="2" (Set /a DayMes2=31+%Day2%) If "%Mes2%"=="3" (Set /a DayMes2=31+%FebDate2%+%Day2%) If "%Mes2%"=="4" (Set /a DayMes2=31*2+%FebDate2%+%Day2%) If "%Mes2%"=="5" (Set /a DayMes2=31*2+%FebDate2%+30+%Day2%) If "%Mes2%"=="6" (Set /a DayMes2=31*3+%FebDate2%+30+%Day2%) If "%Mes2%"=="7" (Set /a DayMes2=31*3+%FebDate2%+30*2+%Day2%) If "%Mes2%"=="8" (Set /a DayMes2=31*4+%FebDate2%+30*2+%Day2%) If "%Mes2%"=="9" (Set /a DayMes2=31*5+%FebDate2%+30*2+%Day2%) If "%Mes2%"=="10" (Set /a DayMes2=31*5+%FebDate2%+30*3+%Day2%) If "%Mes2%"=="11" (Set /a DayMes2=31*6+%FebDate2%+30*3+%Day2%) If "%Mes2%"=="12" (Set /a DayMes2=31*6+%FebDate2%+30*4+%Day2%) :: Разность жней меду днями года Set /a RaznostDayMes=%DayMes2%-%DayMes1% :: Разность между Set /a Day=%RaznostGod%+%RaznostDayMes% echo %Date2%-%Date1%=%Day% дн. echo %time% pause Високосный год вроде бы тоже работает... по крайней мере мне так показалось))) Код корявый, можно и упростить, но сначала надо убедиться что работает правильно.... UPD Немного улучшенный вариант
echo off Chcp 1251 cls call :СчитатьРазностьДат Day 20180312 20180523 echo Разность %Day% дн. pause :СчитатьРазностьДат :: Получение дат Set /a Date1=%~2 & Set /a Date2=%~3 :: Разбивка даты Set /a God1= %Date1:~0,4% & Set /a God2= %Date2:~0,4% Set /a Mes1= %Date1:~4,2% & Set /a Mes2= %Date2:~4,2% Set /a Day1= %Date1:~6,2% & Set /a Day2= %Date2:~6,2% :: Определяем вискокосные ли даты Set /a VisGod1=%God1%%%4 & Set /a VisGod2=%God2%%%4 :: Считаем дни call :СчитатьДниПрошедшихЛет DaysGod1 %VisGod1% %God1% call :СчитатьДниПрошедшихЛет DaysGod2 %VisGod2% %God2% call :СчитатьДниГода DayMes1 %VisGod1% %Mes1% %Day1% call :СчитатьДниГода DayMes2 %VisGod2% %Mes2% %Day2% Set /a %~1=(%DaysGod2%-%DaysGod1%)+(%DayMes2%-%DayMes1%) exit /b :СчитатьДниГода If "%~2"=="0" (Set /a FebDay=29) else (Set /a FebDay=28) If "%~3"=="1" (Set /a %~1=%~4) If "%~3"=="2" (Set /a %~1=31+%~4) If "%~3"=="3" (Set /a %~1=31+%FebDay%+%~4) If "%~3"=="4" (Set /a %~1=31*2+%FebDay%+%~4) If "%~3"=="5" (Set /a %~1=31*2+%FebDay%+30+%~4) If "%~3"=="6" (Set /a %~1=31*3+%FebDay%+30+%~4) If "%~3"=="7" (Set /a %~1=31*3+%FebDay%+30*2+%~4) If "%~3"=="8" (Set /a %~1=31*4+%FebDay%+30*2+%~4) If "%~3"=="9" (Set /a %~1=31*5+%FebDay%+30*2+%~4) If "%~3"=="10" (Set /a %~1=31*5+%FebDay%+30*3+%~4) If "%~3"=="11" (Set /a %~1=31*6+%FebDay%+30*3+%~4) If "%~3"=="12" (Set /a %~1=31*6+%FebDay%+30*4+%~4) exit /b :СчитатьДниПрошедшихЛет Set /a GodVis=%~3/4 Set /a GodNeVis=%~3/4-1 If "%~2"=="0" (Set /a NeVis=%~3-%GodNeVis%) If "%~2"=="1" (Set /a NeVis=%~3-%GodNeVis%) If "%~2"=="2" (Set /a NeVis=%~3-%GodVis%) If "%~2"=="3" (Set /a NeVis=%~3-%GodVis%) Set /a VisGod=%~3-%NeVis% Set /a %~1=%VisGod%*366+%NeVis%*365 exit /b |
Последний раз редактировалось wlad1164, 24-05-2018 в 23:21. Отправлено: 22:31, 24-05-2018 | #6 |
Ветеран Сообщения: 2732
|
Профиль | Отправить PM | Цитировать wlad1164, Меня количество Ваших если ужасает.
Вот мой вариант. Нормальные ленивые герои всегда идут в обход
Идея как и в JS: сделал функцию, которая вычислит порядковый номер заданного дня в дате начиная от 1 января 2000 (точнее -00) года . Затем разность посчитать - нет труда.
@Echo Off cls Set "Date1=180312" Set "Date2=180523" Call :Days %Date1:~0,2% %Date1:~2,2% %Date1:~4,2% "ND1" Call :Days %Date2:~0,2% %Date2:~2,2% %Date2:~4,2% "ND2" Set /A ND=%ND2%-%ND1% Echo %Date2%-%Date1%=%ND2%-%ND1%=%ND% Pause GoTo :Eof :Days SetLocal Set /A N01=0, N02=31, N03=59, N04=90, N05=120, N06=151, N07=181, N08=212, N09=243, N10=273, N11=304, N12=334 Set /A V01=0, V02=31, V03=60, V04=91, V05=121, V06=152, V07=182, V08=213, V09=244, V10=274, V11=305, V12=335 Set /A NN=%1-%1/4*4 Set /A Dy=%1/4*1461+%NN%*365 If %NN%==0 (Call Set MM=%%V%2%%) Else (Set /A Dy+=1 &Call Set MM=%%N%2%%) EndLocal &Set /A %~4=%Dy%+%MM%+%3 GoTo :Eof Set /a Date1=080312 а как строковый Set "Date1=080312" Вариант использования функции В принципе, не сложно переделать и под четырёхзначный год, например, дни отсчитывать начиная с 1900 года, но задача Вами так не ставилась |
------- Последний раз редактировалось megaloman, 25-05-2018 в 10:20. Отправлено: 09:34, 25-05-2018 | #7 |
Забанен Сообщения: 793
|
Есть такая штука, julian day называется, значительно облегчает расчет разницы между датами.
@echo off setlocal 2>nul set /a "d1=180312, d2=180523" % rem : даты, между которыми будет считаться разница call:expandDate %d1% d1 call:expandDate %d2% d2 set /a "delta=d2-d1" echo %delta% endlocal exit /b :expandDate set "d=%~1" call:toJulianDay %d:~4,2% %d:~2,2% 20%d:~0,2% set "%~2=%jdn%" exit /b :toJulianDay set /a "jdn=(1461*(%3+4800+(%2-14)/12))/4+(367*(%2-2-12*((%2-14)/12)))/12-(3*((%3+4900+(%2-14)/12)/100))/4+%1-32075" exit /b |
Отправлено: 14:13, 26-05-2018 | #8 |
Новый участник Сообщения: 26
|
Профиль | Отправить PM | Цитировать greg zakharov, наконец тор снова добрался до батника, предложенный Вами вариант работает, но не всегда, к примеру
2>nul set /a "d1=180312, d2=180508" Уже не сработает |
Отправлено: 11:28, 08-06-2018 | #9 |
Забанен Сообщения: 793
|
wlad1164, ошибка возникает из-за того, что командная строка считает числа начинающиеся с нуля в восьмеричной системе счисления, отсюда 08, например, будет недопустимым значением для данной СЧ. Чтобы избежать подобной ошибки нужно значения вроде того же 08 приводить к тому, что в понимании командного интерпретатора будет десятичным числом. Иначе говоря:
Исправленный вариант с julianday будет выглядеть так: @echo off setlocal 2>nul set /a "d1=180312, d2=180508" % rem : даты, между которыми будет считаться разница call:expandDate %d1% d1 call:expandDate %d2% d2 set /a "delta=d2-d1" echo %delta% endlocal exit /b :expandDate set "d=%~1" set /a "a=10%d:~4,2%%%100, b=10%d:~2,2%%%100" call:toJulianDay %a% %b% 20%d:~0,2% set "%~2=%jdn%" exit /b :toJulianDay set /a "jdn=(1461*(%3+4800+(%2-14)/12))/4+(367*(%2-2-12*((%2-14)/12)))/12-(3*((%3+4900+(%2-14)/12)/100))/4+%1-32075" exit /b |
Отправлено: 12:15, 08-06-2018 | #10 |
![]() |
Участник сейчас на форуме |
![]() |
Участник вне форума |
![]() |
Автор темы |
![]() |
Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
Подбор - [решено] Как правильно посчитать количество лицензий для покупки? | James Marsh | Лицензирование продуктов Microsoft | 10 | 12-11-2017 03:23 | |
CMD/BAT - [решено] Запуск .bat определенное количество раз и определенное количество дней | 55kadi | Скриптовые языки администрирования Windows | 24 | 25-10-2016 07:06 | |
Прочее - Как посчитать количество вхождений при тайлинг в секунду | SyCraft | Общий по Linux | 1 | 11-02-2011 12:24 | |
Посчитать количество файлов в папке | Lodoss | AutoIt | 10 | 21-08-2009 04:12 | |
C/C++ - посчитать количество символов без пробела | ShadowMas | Программирование и базы данных | 5 | 07-05-2009 10:51 |
|