Автор | Сообщение |
|
| Администратор
|
Пост N: 3486
Зарегистрирован: 23.05.05
|
|
Отправлено: 20.09.16 16:50. Заголовок: Високосный год
В качестве разминки, предложите алгоритм: Есть даты: d1 и d2 Как определить, попадает ли високосный день 29.02 в промежуток между d1 и d2 ?
|
|
|
Новых ответов нет
[см. все]
|
|
|
| постоянный участник
|
Пост N: 1275
Зарегистрирован: 27.01.07
|
|
Отправлено: 20.09.16 16:59. Заголовок: FOR i := Year(d1) ..
Может так? FOR i := Year(d1) to Year(d2) ? Empty( CDoW( "29.02." + AllTrim( Str( i, 4, 0 ) ) ) ) NEXT
|
|
|
|
| |
Пост N: 6027
Зарегистрирован: 17.05.05
|
|
Отправлено: 20.09.16 17:43. Заголовок: Или можно заюзать Em..
Или можно заюзать Empty(Ctod ("29/02/2018")) // .T. От не существующей даты вернет .T. То есть тоже цикл но с d1 по d2
|
|
|
|
| |
Пост N: 28
Зарегистрирован: 02.08.10
|
|
Отправлено: 20.09.16 20:44. Заголовок: определить високосны..
определить високосный год Function IsLeapYear(nYEAR) RETURN IIF((nYEAR % 4 = 0 .AND. nYEAR % 100 <> 0) .OR. nYear % 400 = 0 ,.T.,.F.) определить количество дней в месяце Function DaysInMonth( nMonth, lLeapYear ) Local nRes DO CASE CASE nMonth = 2 nRes = IIF(lLeapYear,29,28) CASE nMonth = 4 .OR. nMonth = 6 .OR. nMonth = 9 .OR. nMonth = 11 nRes = 30 OTHERWISE nRes = 31 ENDCASE Return nRes
|
|
|
|
| Администратор
|
Пост N: 3487
Зарегистрирован: 23.05.05
|
|
Отправлено: 20.09.16 21:11. Заголовок: В одну строку, увы, ..
В одну строку, увы, не получается, да и без цикла не обойтись В конце концов, вышел такой вариант: Function DatesLeap(d1, d2) Local lleap := .f., nY1, nY2, nY if ! Empty(d1) .and. ! Empty(d2) .and. d1 <= d2 if Month(d2) == 2 .and. Day(d2) == 29 lLeap := .t. else nY1 := Year(d1) if Month(d1) >= 3 nY1 ++ endif nY2 := Year(d2) if Month(d2) <= 2 nY2 -- endif for nY := nY1 to nY2 if ( ( nY % 4 ) == 0 .and. ( nY % 100 ) != 0 ) .or. ( nY % 400 == 0 ) lLeap := .t. exit endif next endif endif Return lLeap
|
|
|
|
| |
Пост N: 6029
Зарегистрирован: 17.05.05
|
|
Отправлено: 20.09.16 21:26. Заголовок: Pasha пишет: В одну..
Pasha пишет: цитата: | В одну строку, увы, не получается, да и без цикла не обойтись |
| а так , или я задачу не понял ? set date to german a:=ctod("20.02.2016") b:=ctod("20.02.2017") c:=ctod("29.02.2016") ? test(a,b,c) Func Test(d1,d2,vd) return vd>=d1 .and. vd<=d2
|
|
|
|
| Администратор
|
Пост N: 3488
Зарегистрирован: 23.05.05
|
|
Отправлено: 20.09.16 22:12. Заголовок: Заданы a и b (d1 и d..
Заданы a и b (d1 и d2), а c - нет.
|
|
|
|
| постоянный участник
|
Пост N: 1300
Зарегистрирован: 09.10.06
|
|
Отправлено: 20.09.16 22:38. Заголовок: Моя версия local..
Моя версия цитата: | #include "assert.ch" local d1, d2, dim set date format to "dd.mm.yyyy" d1 := ctod("20.02.2023") d2 := ctod("20.02.2016") dim := DatesLeap( d1, d2 ) ASSERT( ! Empty( dim ), "dates not found" ) Aeval( dim, {|e|Qout( e )} ) return proc DatesLeap( d1, d2 ) local a := min( d1, d2 ) local b := max( d1, d2 ) local dim := {} for i := year( a ) to year( b ) c := ctod( "29.02." + str( i, 4 ) ) if /* ! Empty( c ) .and. */ Between( c, a, b ) AAdd( dim, c ) endif next return dim |
|
|
|
|
|
| постоянный участник
|
Пост N: 1301
Зарегистрирован: 09.10.06
|
|
Отправлено: 20.09.16 22:41. Заголовок: Between - это из fox..
Between - это из foxpro (hbfoxpro), удобная вещь цитата: | #pragma BEGINDUMP #include "hbapi.h" #include "hbapiitm.h" HB_FUNC( BETWEEN ) { HB_BOOL fResult = HB_FALSE; if( hb_pcount() == 3 ) { PHB_ITEM pItem = hb_param( 1, HB_IT_ANY ); int iResult1, iResult2; if( hb_itemCompare( pItem, hb_param( 12, HB_IT_ANY ), HB_FALSE, &iResult1 ) && hb_itemCompare( pItem, hb_param( 23, HB_IT_ANY ), HB_FALSE, &iResult2 ) ) fResult = iResult1 >= 0 && iResult2 <= 0; } hb_retl( fResult ); } #pragma ENDDUMP |
| Оп-па! Попался..
|
|
|
|
| постоянный участник
|
Пост N: 1302
Зарегистрирован: 09.10.06
|
|
Отправлено: 20.09.16 23:30. Заголовок: Определяет, лежит ли..
цитата: | Определяет, лежит ли значение некоторого выражения в диапазоне между значениями двух других выражений, имеющих тот же тип данных. Синтаксис: BETWEEN(eTestValue, eLowValue, eHighValue) Параметры: eTestValue Задает выражение, значение которого проверяет функция BETWEEN( ). Если значение выражения eTestValue больше или равно значению выражения eLowerValue и меньше или равно значению выражения eHighValue, функция BETWEEN( ) возвращает значение "истина" (.T.). В противном случае BETWEEN( ) возвращает "ложь" (.F.). BETWEEN( ) возвращает значение NULL, если значением eLowValue или eHighValue является NULL. eLowValue Задает нижнюю границу диапазона, проверяемого функцией BETWEEN( ). eHighValue Задает верхнюю границу диапазона, проверяемого функцией BETWEEN( ). |
| Таки косяк.
|
|
|
|
| |
Пост N: 1
Зарегистрирован: 21.09.16
|
|
Отправлено: 21.09.16 10:05. Заголовок: Еще один велосипед, ..
Еще один велосипед, конечно, здорово. Dima, таки, прав! Вот эта функция дает такой же результат, что и DatesLeap от Pasha Без циклов и короче. Function DatesLeap1( d1, d2 ) local lLeap := .F. local dat := stod( '20160229' ) if ! Empty( d1 ) .and. ! Empty( d2 ) .and. d1 <= d2 if d1 <= dat .and. dat <= d2 lLeap := .T. endif endif return lLeap Проверено на d1 := stod( '20160220' ) d2 := stod( '20160320' ) ? DatesLeap( d1, d2 ) ? DatesLeap1( d1, d2 ) wait d1 := stod( '20150220' ) d2 := stod( '20160229' ) ? DatesLeap( d1, d2 ) ? DatesLeap1( d1, d2 ) wait d1 := stod( '20160229' ) d2 := stod( '20160320' ) ? DatesLeap( d1, d2 ) ? DatesLeap1( d1, d2 ) wait d1 := stod( '20160329' ) d2 := stod( '20160520' ) ? DatesLeap( d1, d2 ) ? DatesLeap1( d1, d2 ) wait
|
|
|
|
| Администратор
|
Пост N: 3489
Зарегистрирован: 23.05.05
|
|
Отправлено: 21.09.16 10:15. Заголовок: Вот эта функция дает..
цитата: | Вот эта функция дает такой же результат, что и DatesLeap от Pasha Без циклов и короче. |
| Так задача стояла найти не 29.2.2016, а любой високосный день в заданном периоде. Впрочем, задача уже решена. Есть не один рабочий вариант. Все спасибо.
|
|
|
|