powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Функция определения месяца (с макс. кол. дней) из диапозона дат
5 сообщений из 5, страница 1 из 1
Функция определения месяца (с макс. кол. дней) из диапозона дат
    #39761932
faustgreen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как лучше всего реализровать функцию, которая принимает на вход две даты и возвращает месяц и год периода для того месяца, который содержит наибольшее количество дней в промежутке указанных дат? Например,
Код: sql
1.
f(Date1, date2) = f(02.12.2018, 05.01.2019) = 12, 2019 (так как в указаном диапазоне декабрь месяц 2018 года содержит наибольшее количество дней). 



Ограничения функции:
Код: sql
1.
2.
   1). Период охватывает не более двух месяцев.
   2). Один из двух месяцев периода точно больше другого.



Первое, что приходит на ум - цикл со счетчиками, но может быть есть более красивое решение ?
...
Рейтинг: 0 / 0
Функция определения месяца (с макс. кол. дней) из диапозона дат
    #39761934
faustgreen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
опечатка, должно быть:
Код: sql
1.
f(Date1, date2) = f(02.12.2018, 05.01.2019) = 12, 2018 (так как в указаном диапазоне декабрь месяц 2018 года содержит наибольшее количество дней). 
...
Рейтинг: 0 / 0
Функция определения месяца (с макс. кол. дней) из диапозона дат
    #39761970
faustgreen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня получилось, что то типо этого:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
PROCEDURE longestPeriod
PARAMETERS tdStartDate, tdEndDate

	roResult = CREATEOBJECT("Empty")
	ADDPROPERTY(roResult, 'IsSuccess', .F.)
	ADDPROPERTY(roResult, 'Year', 0)
	ADDPROPERTY(roResult, 'Month', 0)

	DO CASE
		CASE VARTYPE(tdStartDate) != "D" OR VARTYPE(tdEndDate) != "D"
			MESSAGEBOX('Îøèáêà ôóíêöèè longestPeriod: Âõîäíûå ïàðàìåòðû äîëæíû èìåòü òèï "Date"!')
		CASE tdStartDate > tdEndDate
			MESSAGEBOX('Îøèáêà ôóíêöèè longestPeriod: Äàòà íà÷àëà ïåðèîäà íå äîëæíà ïðåâûøàòü äàòó êîíöà ïåðèîäà!')
		OTHERWISE
			STORE tdStartDate TO ldNextBeginDate, ldNextEndDate
			STORE 0 TO lnDayInLongestPeriod

			roResult.isSuccess = .T.
			roResult.MONTH = MONTH(tdStartDate)
			roResult.YEAR  = YEAR(tdStartDate)

			DO WHILE ldNextEndDate < tdEndDate
				IF ldNextEndDate != tdStartDate
					ldNextBeginDate = ldNextEndDate + 1
				ENDIF

				ldNextLastDayOfMonth = GOMONTH(ldNextBeginDate,1)-DAY(GOMONTH(ldNextBeginDate,1))
				ldNextEndDate = IIF(ldNextLastDayOfMonth < tdEndDate, ldNextLastDayOfMonth, tdEndDate)

				lnNextPeriodDayCount = ldNextEndDate - ldNextBeginDate + 1

				IF lnNextPeriodDayCount > lnDayInLongestPeriod
					lnDayInLongestPeriod   = lnNextPeriodDayCount
					roResult.MONTH = MONTH(ldNextEndDate)
					roResult.YEAR  = YEAR(ldNextEndDate)
				ENDIF
			ENDDO
	ENDCASE

	RETURN roResult
ENDPROC



Может кому пригодится.
...
Рейтинг: 0 / 0
Функция определения месяца (с макс. кол. дней) из диапозона дат
    #39762000
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Правильно ли я понял постановку задачи

1. Есть диапазон дат: от 02.12.2018 до 05.01.2019
2. Внутри этого диапазона

- на первый месяц диапазона (декабрь 2018) приходится (31.12.2018-02.12.2018) + 1 = 30 дней
- на второй месяц диапазона (январь 2019) приходится (05.01.2019-01.01.2019) + 1 = 5 дней

Поскольку 30 больше 5, то надо вернуть "декабрь 2018"

В случае равенства не очень понятно, что вернуть. Но, предположим, первую дату

-------------

Если даты диапазона всегда в разных и соседних месяцах, то можно просто подсчитать количество дней диапазона и сравнить с номером дня второго диапазона

Т.е. в данном случае, разница (05.01.2019 - 02.12.2018) + 1 = 35 дней
Номер дня завершающей даны = 5 дней

35/2 >= 5

Значит, в первой "половине" дней больше и надо вернуть месяц и год первой даты

В виде кода это так

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
PROCEDURE longestPeriod
PARAMETERS tdStartDate, tdEndDate

if (tdEndDate - tdStartDate + 1)/2 >= day(tdEndDate)
    * Взять реквизиты начальной даты tdStartDate
else
    * Взять реквизиты конечной даты tdEndDate
endif
...
Рейтинг: 0 / 0
Функция определения месяца (с макс. кол. дней) из диапозона дат
    #39762047
faustgreen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМ, да все правильно поняли. Суть задачи в целом в следующем:
1). Пользователь при формировании отчета выбирает диапозон дат " с _ по _"
2). Далее описанная функция вытягивает из диапозона год и месяц (для того месяца, в котором больше всего дней)
3). Полученные данные вставляются в отчет: "Отчет такой то за [месяц] [год]"

Отчет месячный, но часто бывает сдвинутый по времени, т.е. отличается от календарного. Например, не 01.01.2019-31.01.2019, а 05.01.2019-01.02.2019 или 01.01.2019-29.01.2019.
Можно конечно было допольнительно запрашивать год и месяц у пользователя, но они ж ленивые )
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Функция определения месяца (с макс. кол. дней) из диапозона дат
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]