On-line: Andrey, гостей 0. Всего: 1 [подробнее..]
АвторСообщение
Администратор




Пост N: 3486
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 20.09.16 16:50. Заголовок: Високосный год


В качестве разминки, предложите алгоритм:
Есть даты: d1 и d2
Как определить, попадает ли високосный день 29.02 в промежуток между d1 и d2 ?

Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 11 [только новые]


постоянный участник


Пост 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


Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 6027
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 20.09.16 17:43. Заголовок: Или можно заюзать Em..


Или можно заюзать Empty(Ctod ("29/02/2018")) // .T.

От не существующей даты вернет .T.
То есть тоже цикл но с d1 по d2


Спасибо: 0 
ПрофильЦитата Ответить



Пост 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


Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост 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


Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост 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



Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 3488
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 20.09.16 22:12. Заголовок: Заданы a и b (d1 и d..


Заданы a и b (d1 и d2), а c - нет.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост 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





Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост 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



Оп-па! Попался..

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост 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( ).



Таки косяк.



Спасибо: 0 
ПрофильЦитата Ответить



Пост 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



Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 3489
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 21.09.16 10:15. Заголовок: Вот эта функция дает..



 цитата:
Вот эта функция дает такой же результат, что и DatesLeap от Pasha
Без циклов и короче.



Так задача стояла найти не 29.2.2016, а любой високосный день в заданном периоде.
Впрочем, задача уже решена. Есть не один рабочий вариант. Все спасибо.

Спасибо: 0 
ПрофильЦитата Ответить
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 700
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет