Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Rodrigo B.A

Recorrência com datas

Recommended Posts

Pessoal,

 

 

estou com dificuldades para chegar numa solução, não estou conseguindo chegar numa lógica de recorrência de datas.

Quando o cara cadastra um evento ele seta a data e a recorrência dela que pode ser por exemplo diário, semanal ou quinzenal...

 

Eu tinha pensando em fazer um loop e ir colocando por exemplo se for semanal fazer um loop e ir colocando 5 dias em cada loop, mas não acho que seja a solução mais correta.

provavel que deve ter algo em sql ou no proprio php que não estou conseguindo encontrar.

 

obrigado

Compartilhar este post


Link para o post
Compartilhar em outros sites

o cara vai cadastrar um evento, por exemplo dia 15/10/2011, ele vai escolher a recorrência, se ele escolher por exemplo semanal, o evento tem que aparecer a cada quinze dias no calendário, se for semestral, de seis em seis meses aparece o evento no calendário...

obs: estou usando fullcalendar jquery

 

obrigado

Compartilhar este post


Link para o post
Compartilhar em outros sites

o cara vai cadastrar um evento, por exemplo dia 15/10/2011, ele vai escolher a recorrência, se ele escolher por exemplo semanal, o evento tem que aparecer a cada quinze dias no calendário, se for semestral, de seis em seis meses aparece o evento no calendário...

obs: estou usando fullcalendar jquery

 

obrigado

 

é amigo estou com o mesmo problema e o pior que o que eu to fazendo tem que ser igualzinho a recorrência do Outlook, coisa essa que to quebrando a cabeça e nao sei nem por onde começar...

 

a recorrência diária é tranquila...

a semanal com escolha dos dias da semana e com intervalo de quantas semanas que ta me matando...

 

Alguém poderia dar uma luz pelo menos? alguma Class que ajude no gerenciamento desse range de datas?

 

Obrigado desde de já!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom, vou dar a minha solução, que pensei agora vendo seu problema.

Ficou meio extenso o post, mas tá bem detalhado.

 

Primeiramente, definir os níveis de repetição que quero:

 

 

0 = não repetir
1 = diario
2 = semanal
3 = quinzenal
4 = mensal

 

Neste exemplo, mostrarei do diário para frente.

 

Segunda coisa, será montar uma tabela-calendário.

Esta técnica é muito recomendada para banco de dados MySQL, e você verá que sua vida nunca mais será a mesma depois dela :D.

 

Vamos colocar 3 informações nesta tabela:

  • A data propriamente dita;
  • Dia da semana (indexando por 0, como no PHP);
  • Semana do ano.
CREATE TABLE calendario (
	`data` date not null,
	dia_semana int not null,
	semana_ano int not null,
	primary key(`data`)
) ENGINE=MyISAM;

Para popular esta tabela, vamos criar uma tabela auxiliar, com um unico campo auto-incrementável, para fazermos um insert em massa posteriormente.

CREATE TABLE numero (
	id int not null auto_increment, 
	primary key(id)
) ENGINE=MyISAM;

INSERT INTO NUMERO VALUES(NULL);
INSERT INTO NUMERO SELECT NULL FROM NUMERO; // executando 12 vezes = 4096 registros

Agora, populamos nossa tabela-calendario:

INSERT INTO calendario 
SELECT
	DATE_ADD('2013-01-01', INTERVAL id-1 DAY),
	DAYOFWEEK(DATE_ADD('2013-01-01', INTERVAL id-1 DAY))-1,
	WEEKOFYEAR(DATE_ADD('2013-01-01', INTERVAL id-1 DAY))
FROM numero;

Pronto, agora temos um calendário lindão para trabalhar no banco de dados.

Voltando para o seu problema, pensei em duas tabelas simples para começar.

Uma indicando a tarefa, e outra indicando em quais dias da semana aquela tarefa vai se repetir.

Cheguei nos seguintes exemplos:

 


CREATE TABLE tarefa (
	codtarefa int not null auto_increment,
	codusuario int not null,
	codtiporepeticao int not null,
	dtainicio date not null,
	primary key(codtarefa)
) ENGINE=innodb;

CREATE TABLE tarefa_dia (
	codtarefadia int not null auto_increment,
	codtarefa int not null,
	dia_semana int not null,
	primary key(codtarefadia),
	foreign  key(codtarefa) references tarefa(codtarefa)
		on update cascade on delete cascade
) ENGINE=innodb;

Também, o dia da semana é indexado por zero, como no PHP.

Agora, nossa vida ficou mega fácil :D

 

Primeiro exemplo

Diário, se repetindo de segunda a sexta

INSERT INTO tarefa VALUES (null,1,1,'2013-06-28');

-- pega o id
SET @id = SELECT LAST_INSERT_ID();

-- insere os dias da semana
INSERT INTO tarefa_dia VALUES (NULL, @id, 1),(NULL, @id, 2),(NULL, @id, 3),(NULL, @id, 4),(NULL, @id, 5);

SELECT c.`data`, c.dia_semana
FROM calendario c, tarefa t, tarefa_dia d
WHERE t.codtarefa = d.codtarefa
  AND t.codtarefa = @id
  AND c.`data` >= t.dtainicio
  AND c.dia_semana = d.dia_semana
ORDER BY c.`data`
LIMIT 30;

 

Segundo exemplo

semanal, repetindo nas quartas e quintas

INSERT INTO tarefa VALUES (null,1,2,'2013-06-28');

-- pega o id
SET @id = SELECT LAST_INSERT_ID();

-- insere os dias da semana desejados
INSERT INTO tarefa_dia VALUES (NULL,@id,3),(NULL,@id,4);

-- selecionando os dias
SELECT `data`,c.dia_semana
FROM calendario c, tarefa t, tarefa_dia d
WHERE c.`data` >= t.dtainicio
  AND c.dia_semana = d.dia_semana
  AND t.codtarefa = d.codtarefa
  AND t.codtarefa = @id
ORDER BY c.`data`
LIMIT 10;

Terceiro exemplo

quinzenal, repetindo nas segundas e sextas

INSERT INTO tarefa VALUES (null,1,3,'2013-06-28');

-- pega o id inserido
SET @id = SELECT LAST_INSERT_ID();

-- insere os dias da semana desejados
INSERT INTO tarefa_dia VALUES (NULL,@id,1),(NULL,@id,5);

-- pega as datas quinzenais
SELECT `data`,c.dia_semana
FROM calendario c, tarefa t, tarefa_dia d
WHERE c.`data` >= t.dtainicio
  AND c.dia_semana = d.dia_semana
  AND t.codtarefa = d.codtarefa
  AND t.codtarefa = @id
  AND (c.semana_ano - WEEKOFYEAR(t.dtainicio)) % 2 = 0
ORDER BY c.`data`
LIMIT 10;

Quarto exemplo

mensal, repetindo todo dia 28

INSERT INTO tarefa VALUES (null,1,4,'2013-06-28');

-- pega o id
SET @id := SELECT LAST_INSERT_ID();

-- variavel para poder pegar os meses mais facil
SET @mes := 0;

-- consulta as datas
SELECT c.`data`, @mes := @mes + 1
FROM calendario c, tarefa t
WHERE c.`data` >= t.dtainicio
  AND t.codtarefa = @id
  AND c.`data` = DATE_ADD(t.dtainicio, INTERVAL @mes MONTH)
  ORDER BY c.`data`
LIMIT 10;

@braços e fique com Deus!

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.