FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour Funcion para determinar semana del año?
Posts: 3358
Joined: Fri Oct 07, 2005 08:20 PM
Funcion para determinar semana del año?
Posted: Fri Feb 20, 2026 03:39 AM

Amigos del foro:

Busco una función que dando una fecha me devuelva el número de semana pero la semana debe ser de sábado a viernes.

Ejemplo: la primera semana en enero 2026 es del 03/01/2026 (sábado) al 09/01/2026 (viernes, cualquier fecha entre las dos fechas anteriores debe devolver 1 (uno)

Alguien tiene algo parecido?

Saludos

SOI, s.a. de c.v.
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Funcion para determinar semana del año?
Posted: Fri Feb 20, 2026 05:04 AM

Estimado Armando,

Programado por Google Antigravity usando el repo de Harbour como carpeta de trabajo:

week_utils.prg

/*
 * week_utils.prg
 * Funciones de utilidad para cálculo de semanas de Sábado a Viernes.
 */

FUNCTION WeekSatToFri( dDate )
    LOCAL nYear := Year( dDate )
    LOCAL dFirstSat := FirstSatOfYear( nYear )
    LOCAL nWeek

// Si la fecha es anterior al primer sábado del año, pertenece al año anterior
IF dDate < dFirstSat
    nYear--
    dFirstSat := FirstSatOfYear( nYear )
ENDIF

// Cálculo: (Diferencia de días / 7) + 1
nWeek := Int( ( dDate - dFirstSat ) / 7 ) + 1

RETURN nWeek

FUNCTION FirstSatOfYear( nYear )
    LOCAL dDate := hb_SToD( AllTrim( Str( nYear ) ) + "0101" )
    LOCAL nDow  := DoW( dDate ) // 1=Dom, 2=Lun, ..., 7=Sab

// Harbour DoW(): 1=Domingo, ..., 7=Sábado
// Si es Sábado (7), ya estamos. Si no, sumamos los días necesarios.
// Días a sumar:
// Dom(1) -> +6
// Lun(2) -> +5
// Mar(3) -> +4
// Mie(4) -> +3
// Jue(5) -> +2
// Vie(6) -> +1
// Sab(7) -> +0

IF nDow < 7
    dDate += ( 7 - nDow )
ENDIF

RETURN dDate

test_week.prg

/*
 * test_week.prg
 * Script de prueba regionalmente independiente para validar la función WeekSatToFri.
 */

PROCEDURE Main()
    LOCAL aTests := { ;
        { "20260103", 1, "Primer sábado 2026 (Inicio sem 1)" }, ;
        { "20260109", 1, "Viernes después del primer sábado (Fin sem 1)" }, ;
        { "20260110", 2, "Siguiente sábado (Inicio sem 2)" }, ;
        { "20260101", 52, "Primeros días de 2026 (Pertenecen a 2025)" }, ;
        { "20260102", 52, "Día antes del primer sábado 2026" }, ;
        { "20251231", 52, "Fin de año 2025" } ;
        }
    LOCAL oTest
    LOCAL nResult
    LOCAL nErrors := 0

? "Iniciando pruebas de WeekSatToFri (Formato YYYYMMDD)..."
? "------------------------------------------------------"

FOR EACH oTest IN aTests
    nResult := WeekSatToFri( hb_SToD( oTest[1] ) )
    ?? "Fecha: " + oTest[1] + " -> Semana: " + AllTrim(Str(nResult))
    IF nResult == oTest[2]
        ?? " [OK]"
    ELSE
        ?? " [ERROR! Esperado: " + AllTrim(Str(oTest[2])) + "]"
        nErrors++
    ENDIF
    ? "Nota: " + oTest[3]
NEXT

? "------------------------------------------------------"
IF nErrors == 0
    ? "Todas las pruebas pasaron correctamente."
ELSE
    ? "Se encontraron " + AllTrim(Str(nErrors)) + " errores."
ENDIF

RETURN

Iniciando pruebas de WeekSatToFri (Formato YYYYMMDD)...

Fecha: 20260103 -> Semana: 1 [OK]
Nota: Primer sábado 2026 (Inicio sem 1) Fecha: 20260109 -> Semana: 1 [OK]
Nota: Viernes después del primer sábado (Fin sem 1) Fecha: 20260110 -> Semana: 2 [OK]
Nota: Siguiente sábado (Inicio sem 2) Fecha: 20260101 -> Semana: 52 [OK]
Nota: Primeros días de 2026 (Pertenecen a 2025) Fecha: 20260102 -> Semana: 52 [OK]
Nota: Día antes del primer sábado 2026 Fecha: 20251231 -> Semana: 52 [OK]

Nota: Fin de año 2025

Todas las pruebas pasaron correctamente.

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Funcion para determinar semana del año?
Posted: Fri Feb 20, 2026 05:19 AM

He creado un script adicional llamado deep_test.prg que comprueba todos los días desde 2020 hasta 2030, verificando matemáticamente que la semana solo cambia de número cuando es Sábado y que nunca avanza más de 1 semana a la vez. No ha arrojado ningún error.

La lógica es matemáticamente perfecta para "Sábado a Viernes". Ten en cuenta un solo detalle importante: cuando la semana devuelta es la 52 (o 53 en algunos años como 2022) en los primeros días de enero (ej: 2026-01-01), ese número de semana pertenece en realidad al año fiscal anterior. Si vas a agrupar en base de datos, te recomiendo asegurarte de que agrupes también por ese año anterior (ej. 2025 Semana 52), y no solo consultes el número de semana ignorando el año.

deep_test.prg

// deep_test.prg
PROCEDURE Main()
    LOCAL dStart := hb_SToD( "20200101" )
    LOCAL dEnd := hb_SToD( "20301231" )
    LOCAL dDate := dStart
    LOCAL nPrevWeek := 0
    LOCAL nWeek
    LOCAL nYear, nPrevYear := 0
    LOCAL nDow

? "Iniciando Deep Test..."
DO WHILE dDate <= dEnd
nDow := DoW( dDate )
nWeek := WeekSatToFri( dDate )

IF nPrevWeek > 0
// Solo debe cambiar en sabado, o no cambiar.
IF nPrevWeek != nWeek
// Si cambiamos de semana, deberia ser sabado (7) y el numero deberia ser nPrevWeek + 1, o 1 si es nuevo año de ciclo.
IF nDow != 7
? "ERROR: Cambio de semana en un dia que no es sabado! Fecha: " + DToC(dDate) + " - Sem: " + Str(nWeek) + ", Prev: " + Str(nPrevWeek)
ENDIF
            
IF nWeek != 1 .AND. nWeek != nPrevWeek + 1
? "ERROR: Salto invalido de semana! Fecha: " + DToC(dDate) + " - Sem: " + Str(nWeek) + ", Prev: " + Str(nPrevWeek)
ENDIF
ENDIF
ENDIF

nPrevWeek := nWeek
dDate++
ENDDO

? "Deep Test Finalizado."
RETURN
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 3358
Joined: Fri Oct 07, 2005 08:20 PM
Re: Funcion para determinar semana del año?
Posted: Sat Feb 21, 2026 04:16 AM

Maestro Antonio:

Muchas gracias, le voy a hincar el diente.

Saludos

SOI, s.a. de c.v.
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero

Continue the discussion