Foros del Web » Programando para Internet » Javascript »

Solapamiento de fechas...

Estas en el tema de Solapamiento de fechas... en el foro de Javascript en Foros del Web. Estoy implementando un modulo php en el que antes de enviar el formulario tengo que hacer una validación de varias fechas organizadas por periodos y ...
  #1 (permalink)  
Antiguo 31/07/2007, 09:16
 
Fecha de Ingreso: noviembre-2006
Ubicación: Alicante
Mensajes: 107
Antigüedad: 18 años
Puntos: 0
Solapamiento de fechas...

Estoy implementando un modulo php en el que antes de enviar el formulario tengo que hacer una validación de varias fechas organizadas por periodos y en la que debo de controlar que no se solapen las fechas. Esto es:

Esto sería correcto.
P1 -> '05/05/2007' - '30/05/2007'
P2 -> '01/06/2007' - '30/06/2007'
P3 -> '01/04/2007' - '04/05/2007'

Esto sería incorrecto.
P1 -> '05/05/2007' - '30/05/2007'
P2 -> '01/06/2007' - '30/06/2007'
P3 -> '01/04/2007' - '05/05/2007' * Se solapa con el primer periodo.

Necesito una ayuda en forma de idea para poder arrancar.

Saludos y gracias.
  #2 (permalink)  
Antiguo 31/07/2007, 19:35
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 21 años, 1 mes
Puntos: 45
Re: Solapamiento de fechas...

Hola lagunafmr:

No es algo muy dificil. Se me ocurre por ejemplo transformar esas fechas que las tienes en String a objetos Date().

Luego podemos hallar de cada objeto Date() sus milisegundos desde 1970, con getTime(). Así lo que tendremos son intervalos de números enteros.

Luego sólo hay que mirar si esos intervalos de números enteros se pisan entre sí (mirando si un extremo de un intervalo está entre los extremos de otro intervalo existente).



Espero que lo hayas entendido para poderlo llevar a cabo.
Un saludo.
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
  #3 (permalink)  
Antiguo 01/08/2007, 08:38
 
Fecha de Ingreso: noviembre-2006
Ubicación: Alicante
Mensajes: 107
Antigüedad: 18 años
Puntos: 0
Re: Solapamiento de fechas...

derkenuke, gracias por tu respuesta.

Si que intenté hacer algo como lo que tu has propuesto, pero no me salía y opte por ir comparando las fechas entre ellas.

Dejo el código por si a alguien le interesa:

Código PHP:
// fecha es un array rellenado antes con todas las fechas de los periodos.
for (var 0<= fecha.length 1c+=2){
// m es utilizada para comparar el último periodo con el primero.
var 2;

    if (
>= fecha.length)
        
0;

    if (
compararFechas(fecha[c], fecha[m]))
        if (
compararFechas(fecha[c+1], fecha[m]))
            
flag2 'false';
        else{
            
alert(' Se han encontrado fechas solapadas... ');
            
flag2 'true';
            break;
        }
    else
        if (
compararFechas(fecha[c], fecha[m]))
            if (
compararFechas(fecha[m+1], fecha[c]))
                
flag2 'false';
            else{
                
alert(' Se han encontrado fechas solapadas... ');
                
flag2 'true';
                break;
            }
}

function 
compararFechas(p_f1p_f2){
...

Saludos.
  #4 (permalink)  
Antiguo 01/08/2007, 11:28
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 21 años, 1 mes
Puntos: 45
Re: Solapamiento de fechas...

O algo como esto:

Código PHP:
function e(q,br) {
document.body.appendChilddocument.createTextNode(q) );
if(!
brdocument.body.appendChilddocument.createElement("BR") );
}
function 
id(x) { return document.getElementById(x); }


// intervalos
var = new Array();
P[0] = {inicio: new Date('05/05/2007'), fin: new Date('05/30/2007') };        // se solapa con 2
P[1] = {inicio: new Date('06/01/2007'), fin: new Date('06/30/2007') };        // no se solapa con 3, contiene a 3 entero
P[2] = {inicio: new Date('04/01/2007'), fin: new Date('05/05/2007') };        // se solapa con 0
P[3] = {inicio: new Date('06/15/2007'), fin: new Date('06/20/2007') };        // se solapa con 1

// devuelve el mismo esquema de objeto de fechas pero acotada entre numeros (milisegundos)
function getIntervaloMSintervalo ) {
    
dev = new Object();
    for( var 
i in intervalo )
        
dev[i] = intervalo[i].getTime();
    return 
dev;
}

Number.prototype.estaEntre = function(a,b) {
    return ( (
Math.min(a,b)<=this) && (this<=Math.max(a,b)) );
}


for(var 
i=0PMS = new Array(); i<P.lengthi++)    // hallamos cada P en milisegundos (ms)
    
PMS[i] = getIntervaloMSP[i] );

for(var 
i=0i<PMS.lengthi++)  {            //cada PMS lo comprobamos con los demás
    
for(var j=0j<PMS.lengthj++) {
        if( 
i==) continue;        //estamos comparando uno consigo mismo
        
else {
            if( 
PMS[i].inicio.estaEntrePMS[j].inicioPMS[j].fin ) ^ PMS[i].fin.estaEntrePMS[j].inicioPMS[j].fin ) ) {
                
e(' Se han encontrado fechas solapadas: '+i+' con '+j+'. ');
            }
            else if( 
PMS[i].inicio.estaEntrePMS[j].inicioPMS[j].fin ) && PMS[i].fin.estaEntrePMS[j].inicioPMS[j].fin ) ) {
                
e(' La primera está contenida en la segunda: '+i+' en '+j+'. ');
            }
            else {
                
e(' No están solapadas : '+i+' con '+j+'. ');
            }
        }
    }
}

e("fin"); 
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
  #5 (permalink)  
Antiguo 02/08/2007, 01:41
 
Fecha de Ingreso: noviembre-2006
Ubicación: Alicante
Mensajes: 107
Antigüedad: 18 años
Puntos: 0
Re: Solapamiento de fechas...

Hola!!!

Gracias por el código, pero el problema es que todavía no sé programar a ese nivel.

Estudiaré tu respuesta y veré si lo consigo entender.

Saludos.
  #6 (permalink)  
Antiguo 02/08/2007, 07:38
Avatar de derkenuke
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: self.location.href
Mensajes: 2.665
Antigüedad: 21 años, 1 mes
Puntos: 45
Re: Solapamiento de fechas...

Te lo he comentado para que lo entiendas un poquito mejor, seguro que leyéndolo bien te haces con ello:

Código PHP:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<
html>
<
head>
<
titlePágina nueva </title>
<
meta name="Author" content="derkeNuke">
<
style type="text/css">
</
style>
</
head>

<
body>

<
script type="text/javascript">
/* La función e(q,br) escribe algo en el documento aunque ya tengamos el documento cargado, se basa en el DOM, y es así de dinámico 
    q - el texto que vamos a escribir (etiquetas HTML no se interpretarán)
    br - boolean opcional: false > No se escribe salto; true o indefinido > Se escribe salto de línea
*/
function e(q,br) {
document.body.appendChilddocument.createTextNode(q) );
if(!
brdocument.body.appendChilddocument.createElement("BR") );
}
/* id(x), un acortamiento de document.getElementById(x) */
function id(x) { return document.getElementById(x); }


/* DEFINICIÓN DE LOS INTERVALOS BASE (método de escritura de objetos JSON)
Conseguiremos un Array de objetos. Cada elemento del array (P[x]) será un objeto con dos propiedades: 'inicio' y 'fin'.
De esta manera P[0].inicio (ó P[0]["inicio"]) nos retornará el objeto Date que tiene la fecha del inicio del intervalo P[0].

A su vez Date también es un objeto con sus métodos y propiedades, de manera que, como en cualquier fecha podemos hacer getFullYear(), con P[0].fin también podremos utilizar ese método: P[0].fin.getFullYear() (=2007)

Recordar que para iniciar un objeto date con un String de formato inglés mm/dd/aaaa
*/
var = new Array();
P[0] = {inicio: new Date('05/05/2007'), fin: new Date('05/30/2007') };        // se solapa con 2
P[1] = {inicio: new Date('06/01/2007'), fin: new Date('06/30/2007') };        // no se solapa con 3, contiene a 3 entero
P[2] = {inicio: new Date('04/01/2007'), fin: new Date('05/05/2007') };        // se solapa con 0
P[3] = {inicio: new Date('06/15/2007'), fin: new Date('06/20/2007') };        // se solapa con 1

/* FUNCIÓN PARA AHORRARNOS OPERACIONES
Ejecuta getTime() y devuelve el mismo esquema de objeto de antes (un objeto con propiedades 'inicio' y 'fin') pero estas propiedades ya no serán objetos Date, sino números (milisegundos obtenidos desde getTime() > ms desde 1970).
Esto es para no hacer getTime() mil veces dentro de los bucles de abajo, pero bueno, podríamos haberlo puesto a lo bestia luego.
*/
function getIntervaloMSintervalo ) {
    
dev = new Object();
    for( var 
i in intervalo )
        
dev[i] = intervalo[i].getTime();
    return 
dev;
}

/* FUNCIÓN MÉTODO DE CUALQUIER NÚMERO QUE NOS DEVUELVE TRUE EN CASO DE QUE UN NÚMERO ESTÉ CONTENIDO EN EL INTERVALO (a,b) Ó (b,a). a Y b CONTENIDOS EN ESE INTERVALO.
    4.estaEntre(1,6) >> true
    6.estaEntre(5,6) >> true
    8.estaEntre(1,4) >> false
*/
Number.prototype.estaEntre = function(a,b) {
    return ( (
Math.min(a,b)<=this) && (this<=Math.max(a,b)) );
}

/* TRANSFORMAMOS CADA INTERVALO QUE TENGAMOS A MILISEGUNDOS CON LA FUNCIÓN getIntervaloMS()
Un bucle for para recorrer todos los elementos de P, y a cada elemento de P le aplicamos getIntervaloMS(), guardando el resultado en otro array que llamaremos PMS y que será tan largo como P.
*/
for(var i=0PMS = new Array(); i<P.lengthi++)    // hallamos cada P en milisegundos (ms)
    
PMS[i] = getIntervaloMSP[i] );

/* RECORREMOS PMS PARA VER SI HAY INTERVALOS QUE SE PISAN */
for(var i=0i<PMS.lengthi++)  {           
    
//cada PMS lo comprobamos con los demás, es decir, hacemos otra vez un bucle con todos los PMS
    
for(var j=0j<PMS.lengthj++) {
        
// Compararemos PMS[i] con los 4 PMS[j]
        
if( i==) continue;        //estamos comparando uno consigo mismo
        
else {
            
// inicioSePisa será true si el valor de inicio de PMS[i] está entre los valores de inicio y fin de PMS[j] (si no false)
            
var inicioSePisa PMS[i].inicio.estaEntrePMS[j].inicioPMS[j].fin );
            
// finSePisa será true si el valor de fin de PMS[i] está entre los valores de inicio y fin de PMS[j] (si no false)
            
var finSePisa PMS[i].fin.estaEntrePMS[j].inicioPMS[j].fin );
            
// Si se pisa inicio ó se pisa fin, pero no los dos a la vez, está solapado
            
if( inicioSePisa finSePisa )        
                
e(' Se han encontrado fechas solapadas: '+i+' con '+j+'. ');
            
// Si se pisa inicio y a la vez se pisa fin, es que una contiene a la otra
            
else if( inicioSePisa && finSePisa )
                
e(' La primera está contenida en la segunda: '+i+' en '+j+'. ');
            
// En otro caso, no estarán solapadas
            
else
                
e(' No están solapadas : '+i+' con '+j+'. ');
        }
    }
}

//fin
e("fin");  


</script>
</body>
</html> 

Si no has entendido algún punto te lo explicaré con gusto.


Un saludo.
__________________
- Haz preguntas inteligentes, y obtendrás más y mejores respuestas.
- Antes de postearlo Inténtalo y Búscalo.
- Escribe correctamente tus mensajes.
  #7 (permalink)  
Antiguo 02/08/2007, 08:14
 
Fecha de Ingreso: noviembre-2006
Ubicación: Alicante
Mensajes: 107
Antigüedad: 18 años
Puntos: 0
Re: Solapamiento de fechas...

Gracias!!!

Me imprimo este también para verlo con mas calma.

Ya te cuento.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 01:13.