Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - [решено] Посчитать количество дней между двумя датами

Ответить
Настройки темы
CMD/BAT - [решено] Посчитать количество дней между двумя датами

Новый участник


Сообщения: 26
Благодарности: 0

Профиль | Отправить PM | Цитировать


Изменения
Автор: wlad1164
Дата: 24-05-2018
Имеется 2 переменных
Код: Выделить весь код
Set /a Date1=180312
Set /a Date2=180523
Date2 всегда больше Date1
Формат всегда ГГММДД
Нужно посчитать кол-во дней между ними ( = 72 )

Запнулся на такой задаче, предположение как решить:
посчитать разность лет,месяцев,дней
затем перемножить и сложить и играться с этими данными добавив условия
но думаю есть решение проще... Буду благодарен за подсказку если таковое есть.

Все это нужно сделать именно в bat

Отправлено: 16:55, 24-05-2018

 

Ветеран


Сообщения: 27449
Благодарности: 8086

Профиль | Отправить PM | Цитировать


Цитата wlad1164:
Все это нужно сделать именно в bat »
Причина?

Отправлено: 17:08, 24-05-2018 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

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


Аватара для Elven

Ветеран


Сообщения: 992
Благодарности: 268

Профиль | Сайт | Отправить PM | Цитировать


wlad1164, мсье знает толк в извращениях. Тут час убить только на то чтобы прописать условия для всех месяцев, учесть високосный год, имхо, если так уж нужно получать эти данные в bat - проще выполнять вычисления, например, в powershell, в нужном формате возвращать результат и разбив его извращаться дальше.

Отправлено: 17:43, 24-05-2018 | #3


Ветеран


Сообщения: 27449
Благодарности: 8086

Профиль | Отправить PM | Цитировать


Elven, ну, коллеги тут делать-то делали подобное, при большом желании напишут. А так — да, хотелось бы понять причины требования «только пакетный файл».

Отправлено: 18:09, 24-05-2018 | #4


Ветеран


Contributor


Сообщения: 2708
Благодарности: 1684

Профиль | Отправить 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
Благодарности: 0

Профиль | Отправить 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


Ветеран


Contributor


Сообщения: 2708
Благодарности: 1684

Профиль | Отправить 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
Замечание: Если год начинается с 0, то надо его определять не как численный
Set /a Date1=080312
а как строковый
Set "Date1=080312"

Вариант использования функции
Код: Выделить весь код
..................................
Set "Date1=18 03 12"
Set "Date2=18 05 23"

Call :Days %Date1% "ND1"
Call :Days %Date2% "ND2"
..................................
В принципе, не сложно переделать и под четырёхзначный год, например, дни отсчитывать начиная с 1900 года, но задача Вами так не ставилась
Верю: это же можно сделать элегантнее, но я пока не знаю как

-------
Даже самая сложная проблема обязательно имеет простое, лёгкое для понимания, неправильное решение. Каждое решение плодит новые проблемы.


Последний раз редактировалось megaloman, 25-05-2018 в 10:20.

Это сообщение посчитали полезным следующие участники:

Отправлено: 09:34, 25-05-2018 | #7


Забанен


Сообщения: 793
Благодарности: 260

Профиль | Цитировать


Есть такая штука, 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
Благодарности: 0

Профиль | Отправить PM | Цитировать


greg zakharov, наконец тор снова добрался до батника, предложенный Вами вариант работает, но не всегда, к примеру

2>nul set /a "d1=180312, d2=180508"

Уже не сработает

Отправлено: 11:28, 08-06-2018 | #9


Забанен


Сообщения: 793
Благодарности: 260

Профиль | Цитировать


wlad1164, ошибка возникает из-за того, что командная строка считает числа начинающиеся с нуля в восьмеричной системе счисления, отсюда 08, например, будет недопустимым значением для данной СЧ. Чтобы избежать подобной ошибки нужно значения вроде того же 08 приводить к тому, что в понимании командного интерпретатора будет десятичным числом. Иначе говоря:
Код: Выделить весь код
set /a "n=10%var%%%100"
Исправленный вариант с 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



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - [решено] Посчитать количество дней между двумя датами

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Подбор - [решено] Как правильно посчитать количество лицензий для покупки? 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




 
Переход