Simplificar rutina de fechas

130 views
Skip to first unread message

jmr...@gmail.com

unread,
Jun 10, 2026, 8:35:10 AM (3 days ago) Jun 10
to Comunidad de Visual Foxpro en Español
¿A alguien se le ocurre algo para simplificar esta rutina? Me parece que me enrollo un poco

*Quiero calcular el numero de dias que una propiedad la usa el propietario en un periodo dado
*La propiedad puede que se haya escriturado en el mismo año
*Esa propiedad puede haberse alquilado en ese año.
*Por tanto tengo cinco fechas
*1. m.fecini -> Periodo de inicio del calculo
*2. m.fecfin -> Periodo de final del calculo
*3. m.fecnot  -> Fecha escritura
*4. m.fecalt  -> Fecha de comienzo alquiler
*5. m.fecbaj  -> Fecha de finalizacion de alquiler
clear
set talk off
lhazdec = .t.
lexplo = .f.
numdiasano = 365
ndiaexpl = 0
m.fecini = CTOD('01/01/2025')
m.fecfin = CTOD('31/12/2025')
m.fecnot = CTOD('01/07/2025')
m.fecalt = CTOD('01/08/2025')
m.fecbaj = CTOD('01/09/2025')
@10,10 say 'Notaria'
@10,20 get m.fecnot
@12,10 say 'Alta   '
@12,20 get m.fecalt
@14,10 say 'Baja   '
@14,20 get m.fecbaj
read
IF !EMPTY(m.fecnot)
*calculo del periodo de la declaracion (segun fecha escritura y explotacion)
IF m.fecnot < m.fecini
*escriturado antes del ejercicio
ELSE
IF m.fecnot <= m.fecfin
*se escrituro en el ejercicio
m.fecini = m.fecnot
ELSE
*se escrituro despues del ejercicio
*no hace declaracion
lhazdec = .F.
ENDIF
ENDIF
IF lhazdec
diasesc = m.fecfin - m.fecini + 1
numdia = diasesc
ENDIF
IF m.fecbaj >= m.fecini .AND. diasesc <> 0      &&Si no tiene alquiler esto no se ejecuta
*tiene fecha de alta o baja en alquiler en el ejercicio
lexplo = .T.
IF m.fecalt < m.fecini
*empezo la alquiler antes del ejercicio
IF m.fecbaj >= m.fecfin
*termina la alquiler despues del ejercicio
numdia = 0
ELSE
*termina la alquiler en el ejercicio
*declara desde fin de alquiler
numdia = numdia - (m.fecbaj - m.fecini)
ENDIF
ELSE
*la alquiler no empezo antes del ejercicio
IF YEAR(m.fecalt) <= YEAR(m.fecini) .AND. YEAR(m.fecbaj) >= YEAR(m.fecfin)
*tiene alquiler en el ejercicio
IF m.fecbaj > m.fecfin
*termina la alquiler despues del ejercicio
*declara hasta inicio alquiler
numdia = numdia - (m.fecfin - m.fecalt)
ELSE
*entra y sale de alquiler durante el ejercicio
ndiaexpl = m.fecbaj - m.fecalt + 1
ndiasano = m.fecfin - m.fecini + 1
numdia = ndiasano - ndiaexpl
ENDIF
ELSE
*no tiene alquiler en el ejercicio
*hace la declaracion completa
lexplo = .F.
ENDIF
ENDIF
ENDIF    &&Bucle de control de alquiler */
ENDIF
@16,10 say 'Numero dias'
@16,20 say numdia
read

Oscar Bonet

unread,
Jun 10, 2026, 9:50:33 AM (3 days ago) Jun 10
to Comunidad de Visual Foxpro en Español
veo un problema es con la fecha de inicio, veo varias y pienso y sugiero debe ser una sola, debería considerar definir una fecha de inicio del contrato para que está misma sea la utilizada al finalizar el mismo contrato de alquiler y de ahí se calcula los días.

Mario Dal Degan

unread,
Jun 10, 2026, 4:24:07 PM (3 days ago) Jun 10
to Comunidad de Visual Foxpro en Español
Le pregunté a Copilot. Espero te sirva (Revisa bien su respuesta)

Sí, se puede simplificar bastante si lo pensás como intersección de intervalos en lugar de ir ramificando con tantos IF. En realidad tenés dos intervalos principales:

  1. Intervalo de propiedad → desde la fecha de escritura (m.fecnot) hasta el fin del período (m.fecfin), limitado por el inicio del período (m.fecini).

  2. Intervalo de alquiler → desde m.fecalt hasta m.fecbaj.

El número de días que usa el propietario es simplemente:

donde DuraciónPeriodo es la cantidad de días entre fecini y fecfin (ajustado por escritura), y la intersección es el tramo en que el alquiler cae dentro del período.

Ventajas de este enfoque

  • Eliminás la mayoría de los IF anidados.

  • Pensás todo como intervalos que se solapan o no.

  • Es más fácil de mantener y extender (por ejemplo, si después querés contemplar varios períodos de alquiler).

En tu ejemplo (escritura en julio, alquiler agosto-septiembre), el cálculo se reduce a:

  • Periodo válido: 1/7/2025 a 31/12/2025 → 184 días

  • Alquiler: 1/8/2025 a 1/9/2025 → 32 días

  • Uso propietario = 184 - 32 = 152 días

* Ajustar inicio según escritura
dIni = MAX(m.fecini, m.fecnot)
dFin = m.fecfin

IF dIni > dFin
    numdia = 0
ELSE
    * Duración total del período válido
    numdia = dFin - dIni + 1

    * Calcular intersección con alquiler
    IF !EMPTY(m.fecalt) AND !EMPTY(m.fecbaj)
        dAlqIni = MAX(dIni, m.fecalt)
        dAlqFin = MIN(dFin, m.fecbaj)

        IF dAlqIni <= dAlqFin
            numdia = numdia - (dAlqFin - dAlqIni + 1)
        ENDIF
    ENDIF
ENDIF

Zarlu

unread,
Jun 10, 2026, 8:11:25 PM (3 days ago) Jun 10
to Comunidad de Visual Foxpro en Español
Buenas tardes jmromeo!

SET DATE FRENCH
SET CENTURY on

clear
set talk off
lhazdec = .t.
lexplo = .f.
numdiasano = 365
ndiaexpl = 0
m.fecini = CTOD('01/01/2025')
m.fecfin = CTOD('31/12/2025')
m.fecnot = CTOD('01/07/2025')
m.fecalt = CTOD('01/08/2025')
m.fecbaj = CTOD('01/09/2025')
@10,10 say 'Notaria'
@10,20 get m.fecnot
@12,10 say 'Alta   '
@12,20 get m.fecalt
@14,10 say 'Baja   '
@14,20 get m.fecbaj
read

*falta algun dato
IF EMPTY(m.fecnot) OR EMPTY(m.fecalt) OR EMPTY(m.fecbaj) OR ;
m.fecbaj<m.fecalt
@16,10 say 'Fechas no válidas'
Return
EndIF

*se escrituró en el ejercicio
IF BETWEEN(m.fecnot,m.fecini,m.fecfin)
m.fecini = m.fecnot
ENDIF


*se escrituro despues del ejercicio
*no hace declaracion
IF m.fecnot>m.fecfin
lhazdec = .F.
EndIf

*dias del ejercicio
IF lhazdec
numdia = m.fecfin - m.fecini + 1
ENDIF

*alta en el ejercio
m.altaEjer=IIF(BETWEEN(m.fecalt,m.fecini,m.fecfin),.t.,.f.)

*baja en el ejercicio
m.bajaEjer=IIF(BETWEEN(m.fecbaj,m.fecini,m.fecfin),.t.,.f.)

*alta/baja en el ejercicio
IF m.altaEjer AND m.bajaEjer
*entra y sale de alquiler durante el ejercicio
ndiaexpl = m.fecbaj - m.fecalt + 1
ndiasano = m.fecfin - m.fecini + 1
numdia = ndiasano - ndiaexpl
EndIf

*alta en el ejercicio-baja fuera del ejercico
IF m.altaEjer AND !m.bajaEjer
*termina la alquiler despues del ejercicio
*declara hasta inicio alquiler
numdia = numdia - (m.fecfin - m.fecalt)
ENDIF

*alta/baja fuera del ejercicio
IF !m.altaEjer AND !m.bajaEjer
numdia = 0
EndIF

*alta fuera del ejercicio-baja en el ejercico
IF !m.altaEjer AND m.bajaEjer
numdia = numdia - (m.fecbaj - m.fecini)
EndIf

@16,10 say 'Numero dias: ' + Transform(numdia)

Faltaría validar la variable  "explo"

Suerte
zarlu
Chetumal, Quintana Roo, México

arturo....@gmail.com

unread,
Jun 10, 2026, 11:19:19 PM (3 days ago) Jun 10
to Comunidad de Visual Foxpro en Español
* Periodo declaración
dIni = m.fecini
dFin = m.fecfin

* Si hay escritura
IF !EMPTY(m.fecnot)
    IF m.fecnot > dFin
        numdia = 0
        RETURN
    ENDIF

    IF m.fecnot > dIni
        dIni = m.fecnot
    ENDIF
ENDIF

* Días propiedad dentro del periodo

numdia = dFin - dIni + 1

* Restar días alquilados que crucen con ese periodo
IF !EMPTY(m.fecalt) AND !EMPTY(m.fecbaj)
    dAltIni = MAX(m.fecalt, dIni)
    dAltFin = MIN(m.fecbaj, dFin)

    IF dAltIni <= dAltFin
        numdia = numdia - (dAltFin - dAltIni + 1)
    ENDIF
ENDIF

IF numdia < 0
    numdia = 0
ENDIF

jmr...@gmail.com

unread,
Jun 11, 2026, 6:42:09 AM (2 days ago) Jun 11
to Comunidad de Visual Foxpro en Español
¡¡¡Muchisimas gracias a todos!!!!

Ramón Rodríguez Martínez

unread,
Jun 11, 2026, 12:21:34 PM (2 days ago) Jun 11
to publice...@googlegroups.com
*==================================================
* CALCULO DE DIAS DE USO PROPIETARIO EN PERIODO
* Considera: escritura, alquiler (alta/baja), periodo fiscal
*==================================================
CLEAR
SET TALK OFF
SET DATE FRENCH
SET CENTURY ON

*--------------------------------------------------
* INICIALIZACION DE VARIABLES
*--------------------------------------------------
m.fecini = CTOD('01/01/2025')   && Inicio periodo fiscal
m.fecfin = CTOD('31/12/2025')   && Fin periodo fiscal
m.fecnot = CTOD('01/07/2025')   && Fecha escritura (notaria)
m.fecalt = CTOD('01/08/2025')   && Fecha alta alquiler
m.fecbaj = CTOD('01/09/2025')   && Fecha baja alquiler

*--------------------------------------------------
* PANTALLA DE CAPTURA
*--------------------------------------------------
@ 05,10 SAY 'CALCULO DE DIAS DE USO PROPIETARIO'
@ 05,10 TO 05,45

@ 08,10 SAY 'Periodo fiscal:'
@ 08,25 SAY m.fecini
@ 08,35 SAY 'a'
@ 08,38 SAY m.fecfin

@ 10,10 SAY 'Fecha escritura (Notaria):' GET m.fecnot
@ 12,10 SAY 'Fecha alta alquiler      :' GET m.fecalt
@ 14,10 SAY 'Fecha baja alquiler      :' GET m.fecbaj

READ

*--------------------------------------------------
* VALIDACIONES BASICAS
*--------------------------------------------------
IF EMPTY(m.fecnot)
    @ 18,10 SAY 'ERROR: Debe indicar fecha de escritura' COLOR R+/W
    WAIT WINDOW
    RETURN
ENDIF

IF !EMPTY(m.fecalt) AND EMPTY(m.fecbaj)
    @ 18,10 SAY 'ERROR: Si hay alta alquiler, debe haber baja' COLOR R+/W
    WAIT WINDOW
    RETURN
ENDIF

IF !EMPTY(m.fecalt) AND !EMPTY(m.fecbaj) AND m.fecbaj < m.fecalt
    @ 18,10 SAY 'ERROR: Fecha baja no puede ser anterior a alta' COLOR R+/W
    WAIT WINDOW
    RETURN
ENDIF

*--------------------------------------------------
* CALCULO DE PERIODO EFECTIVO DE PROPIEDAD
*--------------------------------------------------
* La propiedad solo se declara desde la escritura

IF m.fecnot > m.fecfin
    * Escriturado despues del ejercicio -> no declara
    nDiasPropiedad = 0
    cMensaje = 'Escriturado despues del ejercicio. No declara.'
ELSE
    * Fecha inicio efectiva: la mas tardia entre inicio ejercicio y escritura
    dIniEfectivo = MAX(m.fecini, m.fecnot)
    * Fecha fin efectiva: fin del ejercicio
    dFinEfectivo = m.fecfin
   
    nDiasPropiedad = dFinEfectivo - dIniEfectivo + 1
ENDIF

*--------------------------------------------------
* CALCULO DE DIAS EN ALQUILER (dentro del periodo efectivo)
*--------------------------------------------------
nDiasAlquiler = 0

IF nDiasPropiedad > 0 AND !EMPTY(m.fecalt) AND !EMPTY(m.fecbaj)
    * Verificar si hay solapamiento entre periodo propiedad y alquiler
   
    * Inicio del alquiler que cae dentro del periodo efectivo
    dIniAlqEfectivo = MAX(dIniEfectivo, m.fecalt)
    * Fin del alquiler que cae dentro del periodo efectivo  
    dFinAlqEfectivo = MIN(dFinEfectivo, m.fecbaj)
   
    * Solo si hay solapamiento real
    IF dFinAlqEfectivo >= dIniAlqEfectivo
        nDiasAlquiler = dFinAlqEfectivo - dIniAlqEfectivo + 1
    ENDIF
ENDIF

*--------------------------------------------------
* RESULTADO FINAL
*--------------------------------------------------
nDiasPropietario = nDiasPropiedad - nDiasAlquiler

*--------------------------------------------------
* MOSTRAR RESULTADOS
*--------------------------------------------------
@ 16,10 SAY REPLICATE('=', 50)

IF nDiasPropiedad = 0
    @ 18,10 SAY cMensaje
ELSE
    @ 18,10 SAY 'Periodo efectivo propiedad:'
    @ 18,40 SAY dIniEfectivo
    @ 18,52 SAY 'a'
    @ 18,55 SAY dFinEfectivo
   
    @ 20,10 SAY 'Dias totales del periodo   :'
    @ 20,40 SAY nDiasPropiedad PICTURE '999'
   
    IF nDiasAlquiler > 0
        @ 22,10 SAY 'Dias en alquiler           :'
        @ 22,40 SAY nDiasAlquiler PICTURE '999'
        @ 22,50 SAY '(del ' + DTOC(dIniAlqEfectivo) + ' al ' + DTOC(dFinAlqEfectivo) + ')'
    ELSE
        @ 22,10 SAY 'Dias en alquiler           : Ninguno'
    ENDIF
   
    @ 24,10 SAY '----------------------------------------'
    @ 26,10 SAY 'DIAS USO PROPIETARIO       :'
    @ 26,40 SAY nDiasPropietario PICTURE '999' COLOR G+/W
ENDIF

@ 28,10 SAY REPLICATE('=', 50)

*--------------------------------------------------
* ESPERAR ANTES DE SALIR
*--------------------------------------------------
WAIT WINDOW 'Presione cualquier tecla para salir...'

RETURN

No se si sea eso lo que quieres

--
Blog de la Comunidad Visual FoxPro en Español http://comunidadvfp.blogspot.com
---
Has recibido este mensaje porque estás suscrito al grupo "Comunidad de Visual Foxpro en Español" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a publicesvfoxp...@googlegroups.com.
Para ver este debate, visita https://groups.google.com/d/msgid/publicesvfoxpro/ce78f24f-2513-46ae-9632-defab77ec2aen%40googlegroups.com.


--
Ramón Rodríguez Martínez
Licenciado en Ciencias de la computación
SOPORTE TOTAL EN COMPUTACIÓN
Reply all
Reply to author
Forward
0 new messages