Страница 1 из 1

Увеличение даты на интервал

Добавлено: 23 авг 2006, 09:02
Bocman
Можно ли в InterBase7 увеличить дату на интервал в месяцах?

Добавлено: 23 авг 2006, 10:05
kdv
ребята, документацию надо читать, или сайт. date+30, к примеру.
на месяц - нет. что такое "месяц", абстрактно? нет такого понятия. Есть конкретный месяц в году с конкретным числом дней.
есть наборы udf (rfunc), где туча функций работы с датами.

Re: Увеличение даты на интервал

Добавлено: 23 авг 2006, 11:30
SAMZ
Bocman писал(а):Можно ли в InterBase7 увеличить дату на интервал в месяцах?
В библиотеке fbudf есть функции ADDDAY, ADDHOUR, ADDMONTH,
ADDWEEK, ADDYEAR. Причем ADDMONTH работает так, если после прибавления некоторого количества месяцев получется несуществующая дата (например, 30 февраля), то она приводится к последней дате месяца. ibudf не проверял.

Добавлено: 23 авг 2006, 11:37
SAMZ
kdv писал(а):ребята, документацию надо читать, или сайт. date+30, к примеру.
на месяц - нет. что такое "месяц", абстрактно? нет такого понятия. Есть конкретный месяц в году с конкретным числом дней.
есть наборы udf (rfunc), где туча функций работы с датами.
Есть такое понятие "месяц". Более того, в значительной части законодательных актов процессуальные сроки исчисляются именно в месяцах. При этом очень четко регламентируются правила исчисления сроков (имеется ввиду случай, когда механическое прибавление месяца дает инвалидную дату). Так, что все очень конкретно.

Добавлено: 23 авг 2006, 13:21
CyberMax
SAMZ писал(а):Есть такое понятие "месяц"
Дмитрий имел ввиду, что у числового представления даты нет месяца (и года тоже). Только количество дней, прошедших с начала определенной даты (например, 1 янвая 0001 года). Так что не путай :).

Добавлено: 23 авг 2006, 13:35
kdv
законодательных актов процессуальные сроки исчисляются именно в месяцах.
это "календарный" месяц, длительность в днях которого определяется началом отсчета. Так что может быть и 28, и 29, и 30, и 31 день. Так что абстрактного "месяца" не существует.

Если надо прибавить месяц, то делается это обычно так:
дата декодируется на год, месяц, день, затем к месяцу добавляется единица (если это не 12-ый месяц), и дата опять кодируется.

Добавлено: 23 авг 2006, 15:46
Bocman
Спасибо всем!!!

Добавлено: 25 авг 2006, 11:31
aaa3d
кусок UDF

Код: Выделить всё

ISC_QUAD * bg_addmonth(ISC_QUAD *d, int *m)
{
	static ISC_QUAD ret;
	struct tm tm1;
	isc_decode_date(d, &tm1);
			
	div_t q = div(*m, 12);      
	
	tm1.tm_mon += q.rem;
	tm1.tm_year += q.quot;
	
	isc_encode_date(&tm1, &ret);
	return &ret;
}

Добавлено: 25 авг 2006, 12:10
WildSery
Нет смысла писать собственную функцию, всё что нужно есть в rFunc

Добавлено: 25 авг 2006, 13:23
Bocman
Я использовал UDF на Delphi:

Код: Выделить всё

type
  PIBDateTime = ^TIBDateTime;
  TIBDateTime = record
    Days, // Date: Days since 17 November 1858
    MSec10: Integer; // Time: Millisecond * 10 since midnigth 
end;

const // константы трансляции даты:
  MSecsPerDay10 = MSecsPerDay * 10; // миллисекунд в сутках * 10
  IBDateDelta = 15018; // разница в днях между датами Delphi 2.0 и InterBase

function Inc(var IBDat: TIBDateTime; var interval: Integer): PIBDateTime; cdecl;
var
  DateTime: TDateTime;
  DelphiDays: Integer;
begin   //увеличение даты на интервал
   DateTime := IBDat.Days - IBDateDelta + IBDat.MSec10 / MSecsPerDay10;
   DateTime := incMonth(DateTime, interval);
   DelphiDays := Trunc(DateTime);
   IBDat.Days := DelphiDays + IBDateDelta;
   IBDat.MSec10 := Trunc((DateTime - DelphiDays) * MSecsPerDay10);
   Result := @IBDat;
end;