A pesar de que existe la función nativa WEEK() que retorna el número de la semana del año, esta no satisfacía una necesidad que se me presentó, por lo que elaboré la función SEMANA() y su inversa.
Mi necesidad, era la de agrupar una consulta de todo un año, por el número de la semana. Aunque en la función WEEK() se puede especificar por ejemplo si la primer semana del año contiene el 1° de Enero, y cual será el primer día de la semana; ésta puede retornar el mismo valor para la primer semana de Enero como para la última semana de Diciembre, lo que me causaba un problema en el agrupado de mi consulta.
*-- Ejemplo de WEEK()
? WEEK(DATE(2004,1,2),1,1) && Primer semana de Enero de 2004
? WEEK(DATE(2004,12,29),1,1) && Ultima semana de Diciembre de 2004
La diferencia de la función WEEK() con la función SEMANA(), es que ésta última no retorna resultados repetidos para los meses de Enero y Diciembre.
*-- Ejemplo de SEMANA()
? SEMANA(DATE(2004,1,2),1) && Primer semana de Enero de 2004
? SEMANA(DATE(2004,12,29),1) && Ultima semana de Diciembre de 2004
A continuación, el código de las funciones SEMANA() e INVSEMANA(), ejemplos de uso y las diferencias entre WEEK() y SEMANA().
*-- Diferencias entre WEEK() y SEMANA()
ld = DATE(2004,12,15)
FOR ln = 1 TO 30
? ld, WEEK(ld,1,1), Semana(ld,1)
ld = ld + 1
ENDFOR
*-- Ejemplo de INVSEMANA()
FOR ln = 1 TO 7
ld = InvSemana(3,2005,ln,1)
? ld, CDOW(ld)
ENDFOR
*------------------------------------------------------------
* FUNCTION Semana(tdFecha, tnPriDiaSem)
*------------------------------------------------------------
* Retorna el número de semana de una Fecha
* USO: Semana(DATE(2004,06,03),2)
* PARAMETROS:
* tdFecha = Fecha
* tnPriDiaSem = Primer día de la semana (1=Domingo, ..., 7=Sábado)
* RETORNO: Numérico
*------------------------------------------------------------
FUNCTION Semana(tdFecha, tnPriDiaSem)
IF EMPTY(tdFecha)
RETURN 0
ENDIF
IF EMPTY(tnPriDiaSem)
tnPriDiaSem = 1
ENDIF
RETURN INT((tdFecha - DATE(YEAR(tdFecha),1,1) + ;
7 - DOW(tdFecha,tnPriDiaSem)) / 7) + 1
ENDFUNC
*------------------------------------------------------------
* FUNCTION InvSemana(tnSemana, tnAnio, tnNroDiaSem, tnPriDiaSem)
*------------------------------------------------------------
* Retorna una fecha a partir de un número de semana
* USO: InvSemana(23,2004,5,2)
* PARAMETROS:
* tnSemana = Número de semana
* tnAnio = Año de la semana
* tnNroDiaSem = Número del día de la semana (1=Domingo, ..., 7=Sábado)
* tnPriDiaSem = Primer día de la semana (1=Domingo, ..., 7=Sábado)
* RETORNO: Fecha
*------------------------------------------------------------
FUNCTION InvSemana(tnSemana, tnAnio, tnNroDiaSem, tnPriDiaSem)
IF EMPTY(tnAnio)
tnAnio = YEAR(DATE())
ENDIF
IF EMPTY(tnNroDiaSem)
tnNroDiaSem = 1
ENDIF
IF EMPTY(tnPriDiaSem)
tnPriDiaSem = 1
ENDIF
RETURN DATE(tnAnio,1,1) + (tnSemana * 7) - 7 + ;
tnNroDiaSem - DOW(DATE(tnAnio,1,1),tnPriDiaSem)
ENDFUNC
*------------------------------------------------------------
Hasta la próxima.
Luis María Guayán