--
-- cego advanced date functions
--

drop if exists procedure second;
drop if exists procedure minute;
drop if exists procedure hour;
drop if exists procedure day;
drop if exists procedure month;
drop if exists procedure year;

drop if exists procedure plusHour;
drop if exists procedure plusDay;
drop if exists procedure plusMonth;
drop if exists procedure plusYear;

drop if exists procedure minusHour;
drop if exists procedure minusDay;
drop if exists procedure minusMonth;
drop if exists procedure minusYear;

@
create procedure second(ts in datetime) return int
begin
	var i int;
	:i = str2int(date2str(:ts, '%S'));
	return :i;
end;
@

@
create procedure minute(ts in datetime) return int
begin
	var i int;
	:i = str2int(date2str(:ts, '%M'));
	return :i;
end;
@

@
create procedure hour(ts in datetime) return int
begin
	var i int;
	:i = str2int(date2str(:ts, '%H'));
	return :i;
end;
@

@
create procedure day(ts in datetime) return int
begin
	var i int;
	:i = str2int(date2str(:ts, '%d'));
	return :i;
end;
@

@
create procedure month(ts in datetime) return int
begin
	var i int;
	:i = str2int(date2str(:ts, '%m'));
	return :i;
end;
@

@
create procedure year(ts in datetime) return int
begin
	var i int;
	:i = str2int(date2str(:ts, '%Y'));
	return :i;
end;
@

@
create procedure plusHour(ts in datetime, h in int) return datetime
begin
	return long2date(date2long(:ts) + :h * 3600);
end;
@

@
create procedure plusDay(ts in datetime, d in int) return datetime
begin
	return long2date(date2long(:ts) + :d * 3600 * 24);
end;
@

@
create procedure plusMonth(ts in datetime, m in int) return datetime
begin
	var td int;
	var tm int;
	var ty int;
	
	var ds string(100);

	:td = day(:ts);
	:ty = year(:ts) + div(:m, 12);
	:tm = mod ( month(:ts) + mod(:m, 12), 12);
	if :tm = 0
	then
	   :tm = 12;
	end;

	-- we concatenate the appropriate string
	:ds = right(0 | :td, 2) | '.' | right(0 | :tm, 2) | '.' | :ty | ' ' | date2str(:ts, '%H:%M:%S');

	return dateformat('%d.%m.%Y %H:%M:%S', :ds);
end;
@


@
create procedure plusYear(ts in datetime, y in int) return datetime
begin

	var td int;
	var tm int;
	var ty int;
	
	var ds string(100);

	:td = day(:ts);
	:ty = year(:ts) + :y;
	:tm = month(:ts);

	-- we concatenate the appropriate string
	:ds = right(0 | :td, 2) | '.' | right(0 | :tm, 2) | '.' | :ty | ' ' | date2str(:ts, '%H:%M:%S');

	return dateformat('%d.%m.%Y %H:%M:%S', :ds);
end;
@


@
create procedure minusHour(ts in datetime, h in int) return datetime
begin
	return long2date(date2long(:ts) - :h * 3600);
end;
@

@
create procedure minusDay(ts in datetime, d in int) return datetime
begin
	return long2date(date2long(:ts) - :d * 3600 * 24);
end;
@

@
create procedure minusMonth(ts in datetime, m in int) return datetime
begin
	var td int;
	var tm int;
	var ty int;
	
	var ds string(100);

	:td = day(:ts);
	:ty = year(:ts) - div(:m, 12);
	if  mod(:m, 12) > month(:ts)
	then
		:ty = :ty -1;
		:tm = 12 - ( mod(:m, 12) - month(:ts));
	else
		:tm = month(:ts) - mod(:m, 12);
	end;

	:ds = right(0 | :td, 2) | '.' | right(0 | :tm, 2) | '.' | :ty | ' ' | date2str(:ts, '%H:%M:%S');

	return dateformat('%d.%m.%Y %H:%M:%S', :ds);
end;
@


@
create procedure minusYear(ts in datetime, y in int) return datetime
begin

	var td int;
	var tm int;
	var ty int;
	
	var ds string(100);

	:td = day(:ts);
	:ty = year(:ts) - :y;
	:tm = month(:ts);

	-- we concatenate the appropriate string
	:ds = right(0 | :td, 2) | '.' | right(0 | :tm, 2) | '.' | :ty | ' ' | date2str(:ts, '%H:%M:%S');
		
	return dateformat('%d.%m.%Y %H:%M:%S', :ds);
end;
@
