PDA

Ver la Versión Completa : Como Saber si una fecha está entre otras dos fechas


davidmedina29
11-02-2016, 00:24:12
Hola Buenas tardes
Estoy haciendo un sistema con una base de datos llamada CA_PERIODOSINGRESOS
en mi tabla tengo 4 campos:
1.Ejercicio
2.Periodo
3.Inicio
4.Fin

En ejercicio tengo un combobox el cual jala el año 2014,2015 y 2016 de otra tabla.
y tengo dos dateedit cxDateEdit1(es la fecha inicial) y cxDateEdit2(es la fecha final)

en mi sistema se pone un rango de fechas de 10 dias por ejemplo del 01/01/2016 al 01/10/2016
quiero hacer una validacion para no insetar una fecha que ya exista en ese rango de 10 dias
si alguien me ayuda se lo agradeceria mucho.!!

BDWONG
11-02-2016, 01:42:39
Hola compañero puedes probar con la función DaysBetween que nos regresa la cantidad de dias entre dos fechas
te dejo un ejemplo:

uses
SysUtils,dateutils;

var
fechaInicial,fechaFinal:TDateTime;
diasEntreFechas:Integer;
begin

TryStrToDate('01/01/2016',fechaInicial);
TryStrToDate('10/01/2016',fechaFinal);
diasEntreFechas:=DaysBetween(fechaInicial,fechaFinal);

if diasEntreFechas<=10 then
Writeln('Esta en el rango de 10 dias, son: ',diasEntreFechas,' dias ')
else
Writeln('No esta en el rango de 10 dias, son: ',diasEntreFechas,' dias ');

readln;
end.


Si no es lo que buscas comentalo para poder ayudarte.
Saludos....

davidmedina29
11-02-2016, 01:50:09
Hola muchas gracias por responder mas bien quiero un mensaje que al momento de querer insertar las dos fechas y exista la fecha dentro del rango me diga que ya existe, no presisamente es la fecha 01/01/2016 al 01/10/2016, el usuario puede capturar cualquier fecha lo que quiero es que el sistema me lanse un menaje cuando el usuaria quiera insertar una fecha que ya este en la base datos.

Saludos!!

AgustinOrtu
11-02-2016, 05:19:21
Bienvenido

Lo que comento el compañero BDWONG es correcto, ya que es una de las posibles soluciones

Hay varias formas de solucionar tu problema: Bloquear la insercion cuando la fecha ya existe

Podes validar en el nivel de la base de datos: con triggers o definiendo una clave
Podes validar a nivel de DataSet (si es que usas DataSets para insertar), mediante los eventos, por ejemplo BeforePost
Podes lanzar una consulta (Query) entre esas fechas: si devuelve algo significa que "esta ocupado", si no, esta disponible
Podes recorrer un DataSet y usar la funcion DaysBetween
...

Cual es la mas apropiada solamente podes decirlo vos ya que no sabemos como funciona tu aplicacion; no sabemos si programas a nivel de base de datos (stored procedures, triggers, etc), a nivel de servidor de aplicaciones, si trabajas con dataset o combinas query + comands; no sabemos que base de datos estas usando; no sabemos si se ejecutan operaciones en concurrente; y un largo etc

No es un regaño, simplemente que es imposible responder con precision cuando la pregunta no es precisa. A veces nos dan la respuesta no de la manera en que esperamos, pero un ejemplo o caso similar y esta en nosotros el entenderlo, asimilarlo y aplicarlo

El titulo y consulta de tu pregunta es "Como Saber si una fecha está entre otras dos fechas" y eso se puede hacer con DaysBetween, con CompareDate, con InRange, y seguro muchas mas formas que desconozco

ecfisa
11-02-2016, 06:46:08
Hola davidmedina29.

No está del todo claro si la consulta es como verificar si una fecha está entre otras dos (como dice el título de tu primer mensaje), o verificar si una fecha ya existe en la base de datos (como dice el texto de tu segundo mensaje).

En el primer caso, el tipo TDate se puede comparar por <, >, =, <=, >=, sea directamente sobre los valores o haciendote una función si la reutilización lo amerita:

function IsDateBetweenDates(const CurrentDate, FromDate, ToDate: TDate): Boolean;
begin
Result := (CurrentDate >= FromDate) and (CurrentDate <= ToDate);
end;


En el segundo caso, como te ha comentado Agustín, deberías dar toda la información sobre el gestor de BD y componentes con que estas trabajando para poder darte una respuesta concreta. (ver un poco del código que usas tampoco nos vendría mal).

Saludos :)

davidmedina29
11-02-2016, 16:20:12
Buen dia una disculpa si no me explique bien, uso delphi 7 y sql server, mi idea es que al momento de dar click en guardar me lanze un mensaje de error si es que el rango de las dos fechas que pongo ya existe en la BD, aqui les dejo el codigo del boton guardar.


with msqry1 do // en esta parte esta la idea de lo que quiero hacer pero no estabien.
begin
close;
SQL.Clear;
sql.Add(('Select*From CA_PERIODOSINGRESOS Between :Inicio and :Fin'));
msqry1.ParamByName('Inicio').AsDate:=cxDateEdit1.Date;
msqry1.ParamByName('Fin').AsDate:=cxDateEdit2.Date;
Open;
end;
if not msqry1.IsEmpty then
MessageDlg('La fecha ya existe', mtError, [mbOK], 0)
else
if cxDateEdit2.Text='' then
begin
MessageDlg('Falta Fecha Final', mtError, [mbOK], 0);
end
else
if cxDateEdit1.Text='' then
begin
MessageDlg('Falta Fecha Inivial', mtError, [mbOK], 0);
end
else
if cxComboBox1.Text='' then
begin
MessageDlg('Falta Ejercicio', mtError, [mbOK], 0);
end
else
if cxTextEdit1.Text='' then
begin
MessageDlg('Falta Periodo', mtError, [mbOK], 0)
end
else
if (cxDateEdit1.Date) > (cxDateEdit2.Date) then
begin
MessageDlg('La fecha inicial no puede ser mayor a la final', mtError, [mbOK], 0)
end
else
begin
DM.msqry1.Append;
DM.msqry1.FieldByName('Ejercicio').AsString := cxComboBox1.Text;
DM.msqry1.FieldByName('Periodo').AsString := cxTextEdit1.Text;
DM.msqry1.FieldByName('Inicio').AsDateTime := cxDateEdit1.Date;
DM.msqry1.FieldByName('Fin').AsDateTime := cxDateEdit2.Date;
DM.msqry1.Post;
DM.msqry1.SQL.Add('order by Periodo');
MessageDlg('Dato Guardado', mtInformation, [mbOK], 0);
fCatPeriodosInNvo.Close;
cxTextEdit1.Clear;
cxDateEdit1.Clear;
cxDateEdit2.Clear;
end;
end;


Alguna sugerencia? se los agradeceria mucho.
Saludos!! :):)

ecfisa
11-02-2016, 16:32:13
Hola David.

Intenta de este modo:

...
DM.msqry1.Close;
DM.msqry1.SQL.Clear;
DM.msqry1.SQL.Add('SELECT * FROM CA_PERIODOSINGRESOS');
DM.msqry1.SQL.Add('WHERE CAMPO_FECHA BETWEEN :INICIO AND :FIN'); // (*)
DM.msqry1.ParamByName('INICIO').AsDate := cxDateEdit1.Date;
DM.msqry1.ParamByName('FIN').AsDate := cxDateEdit2.Date;
DM.msqry1.Open;
if not DM.msqry1.IsEmpty then
raise Exception.Create('La fecha ya existe');
...

(*) Donde CAMPO_FECHA sería el nombre de la columna a controlar.

Saludos :)

AgustinOrtu
11-02-2016, 16:34:16
Bien pero cual es el problema? Da error en algun punto? El query no devuelve los resultados esperados?

Has depurado tu programa?

davidmedina29
11-02-2016, 17:07:02
Gracias por sus respuestas, no estaba tan perdido ecfisa pero el detalle que no tengo esa columna de campo_fecha debe de tener solo fecha inicial y fecha final entonces ahi esta el detalle amigo mi base de datos cuenta con 4 campos: Ejercicio, Periodo, Inicio y Fin no le puedo meter otro campo. que podria hacer ahi :confused::confused:

Saludos y gracias de nuevo por responder!!

davidmedina29
16-02-2016, 23:12:18
Buenas tardes, esto parece algo sencillo pero no puedo dar con la solución

tengo una tabla los cuales en dos campos llevan fechas se llaman Inicio y Fin.
En la tabla se registran periodos de rangos de fecha por ejemplo:

Inicio :01/01/2016, Fin:12/01/2016

lo que quiero es que si ya existe ese rango de fechas y quiero insertar una fecha que ya exista dentro de ese rango por ejemplo:

Inicio :03/01/2016, Fin:14/01/2016

al momento de guardar me mande un mensaje de error de fechas

uso
cxDateEdit1 (fechaInicial)
cxDateEdit2 (FechaFinal)
msqry1 conectado a un dataset
cxButton1 (btnGuardar)

alguna sugerencia se los agradeceria mucho

TiammatMX
16-02-2016, 23:18:05
...alguna sugerencia se los agradeceria mucho

Como no dices qué motor de base de datos usas, generalizo.

Una fecha está expresada INTERNAMENTE a Delphi (y ObjectPASCAL en general, si no me equivoco) como un número decimal, donde la parte entera indica la fecha (en cantidad de días transcurridos a partir del 1 de enero de 1900) y la parte decimal es la hora del día con precisión de milisegundos...

Como dirían los gringos, "it's up to you, do the maths"... ;)

AgustinOrtu
17-02-2016, 04:22:30
Ya habias hecho la misma pregunta aca (http://www.clubdelphi.com/foros/showthread.php?t=89811)

No hace falta crear un nuevo hilo, de hecho tenes varias respuestas en el original

Saludos

Casimiro Notevi
17-02-2016, 09:24:35
Ya habias hecho la misma pregunta aca (http://www.clubdelphi.com/foros/showthread.php?t=89811)
No hace falta crear un nuevo hilo, de hecho tenes varias respuestas en el original
Saludos
^\||/^\||/^\||/ He unido los hilos.

davidmedina29
18-02-2016, 16:14:03
Hola David.

Intenta de este modo:

...
DM.msqry1.Close;
DM.msqry1.SQL.Clear;
DM.msqry1.SQL.Add('SELECT * FROM CA_PERIODOSINGRESOS');
DM.msqry1.SQL.Add('WHERE CAMPO_FECHA BETWEEN :INICIO AND :FIN'); // (*)
DM.msqry1.ParamByName('INICIO').AsDate := cxDateEdit1.Date;
DM.msqry1.ParamByName('FIN').AsDate := cxDateEdit2.Date;
DM.msqry1.Open;
if not DM.msqry1.IsEmpty then
raise Exception.Create('La fecha ya existe');
...

(*) Donde CAMPO_FECHA sería el nombre de la columna a controlar.

Saludos :)

gracias por responder ecfisa pero hay un detalle, el problema es que solo tengo como campos date (Inicio) y (Fin) no tengo otro campo como el que pones CAMPO_FECHA que se puede hacer?

gracias!!

Casimiro Notevi
18-02-2016, 16:29:58
El problema es que no está claro qué tienes y qué quieres.

davidmedina29
18-02-2016, 16:55:48
hola casimiro lo explico otra vez.

tengo una base de datos en sql server con los sig campos: Ejercicio, Periodo, Inicio, Fin.

en Ejercicio tengo un cxCombobox con los sig items: 2014,2015,2016
en Periodo tengo un cxTextEdit que se incrementa en 1, los periodos son: 1, 2, 3 .. etc
en Inicio y Fin tengo dos cxDateEdit en el cual pongo un rango de fechas por ejemplo : Inicio: 20/01/2015, Fin:25/01/2015.

con la BD tengo
msquery en un DM
dataset ligado al msquery en el DM
Msconection ligada a la bd

entonces suponiendo que ya esta dada de alta esa fecha del 20/01/2015 al 25/01/2015, lo que quiero es que si vuelven a ingresar una fecha que este dentro de ese rango por ejemplo 22/01/2015 al 30/01/2015, me marque un error y no deje guardar.
les comparto mi boton guardar.


procedure TfCatPeriodosInNvo.cxButton1Click(Sender: TObject);
begin
if cxDateEdit2.Text='' then
MessageDlg('Falta Fecha Final', mtError, [mbOK], 0)
else
if cxDateEdit1.Text='' then
MessageDlg('Falta Fecha Inivial', mtError, [mbOK], 0)
else
if cxComboBox1.Text='' then
MessageDlg('Falta Ejercicio', mtError, [mbOK], 0)
else
if cxTextEdit1.Text='' then
MessageDlg('Falta Periodo', mtError, [mbOK], 0)
else
if (cxDateEdit1.Date) > (cxDateEdit2.Date) then
MessageDlg('La fecha inicial no puede ser mayor a la final', mtError, [mbOK], 0)
else
if yearof(cxDateEdit1.Date)<>cxComboBox1.EditValue then
MessageDlg('La fecha no coincide con el ejercicio', mtError, [mbOk], 0)
//raise Exception.Create('La fecha no coincide con el ejercicio');
else
if yearof(cxDateEdit2.Date)<>cxComboBox1.EditValue then
MessageDlg('La fecha no coincide con el ejercicio', mtError, [mbOk], 0)
else
begin
if DM.msqry1.State=dsInsert then
begin
DM.msqry1.FieldByName('Ejercicio').AsString := cxComboBox1.Text;
DM.msqry1.FieldByName('Periodo').AsString := cxTextEdit1.Text;
DM.msqry1.FieldByName('Inicio').AsString := cxDateEdit1.Text;
DM.msqry1.FieldByName('Fin').AsString := cxDateEdit2.Text;
DM.msqry1.Post;
MessageDlg('Dato Guardado', mtInformation, [mbOK], 0);
fCatPeriodosInNvo.Close;
end
else
begin
if dm.msqry1.State=dsEdit then
DM.msqry1.FieldByName('Inicio').AsDateTime:=cxDateEdit1.Date;
DM.msqry1.FieldByName('Inicio').AsDateTime:= cxDateEdit2.Date;
DM.msqry1.Post;
MessageDlg('Ingreso Guardado', mtInformation, [mbOK], 0);
fCatPeriodosInNvo.Close;
end
end
end;



si me ayudan se los agradecere mucho!!

Casimiro Notevi
18-02-2016, 17:38:21
Entonces, tienes una tabla con los campos: ... inicio, fin, ...
1. El usuario escribe 2 fechas (inicio y fin)
Quieres saber si no hay ningún registro que tengan esas 2 fechas, la de inicio y las de fin
select count(*) from tabla where inicio=fechaINIusuarioi and fin=fechaFINusuario
Si devuelve mayor de cero es que hay algún registro con esas fechas.

2. El usuario escribe 1 fecha.
Quieres saber que no esté comprendida entre "inicio" y "fin" en ningún registro.
select count(*) from tabla where fechausuario >= inicio and fechausuario <= fin
Si devuelve mayor de cero es que esa fecha está comprendida entre las fechas inicio y fin de algún registro.

O acaso quieres una 3 opción:
3. El usuario escribe 2 fechas.
Quieres saber que fechaINIusuario >= inicio de cualquier registro Y fechaFINusuario<=fin de cualquier registro

Y si es otra cosa lo que quieres hacer, tendrás que explicarlo de otra forma.