Comunidad de diseño web y desarrollo en internet online

Calcular el número de semana actual del año con Javascript

Estaba leyendo mi anterior tip de Cómo obtener el número de semana del año con Javascript. Revisando los comentarios encontré que había un gravísimo error en cuanto a no seguir los estándares para medición de tiempo, esta vez vuelvo a postear el tip corrigiendo este error garrafal.

Obtener el número de semana del año de una fecha actual con Javascript (ISO compatible)


Tal como acote en el tip original no existe (aún) una función nativa de Javascript que nos calcule el número de la semana del año de una fecha dada, ya que esta función no existe no nos queda de otra que implementarla a mano, esta vez siguiendo el estándar para medición de tiempo ISO8601 que más o menos dicen algo como:

La primera semana del año, la número 01, es la que contiene el primer jueves de enero. Las semanas de un año van de la 01 a la 52, salvo que el año termine en jueves, o bien en jueves o viernes si es bisiesto, en cuyo caso se añade una semana más: la 53.
Extraido de Wikipedia


Las explicaciones del proceso volitivo pueden verlas en el tip original, haciendo claro la salvedad que la primera semana del año no es la que contiene al 01 e enero necesariamente si no la que contiene al primer jueves del año.

La mejor solución que encontré corresponde a un algoritmo que me hicieron llegar como respuesta al tip original y que adapte para Javascript.

Dicho todo esto pasemos a ver la solución que humildemente os propongo:

Código :

function semanaISO($fecha){
   
   if($fecha.match(/\//)){
      $fecha   =   $fecha.replace(/\//g,"-",$fecha); //Permite que se puedan ingresar formatos de fecha ustilizando el "/" o "-" como separador
   };
   
   $fecha   =   $fecha.split("-"); //Dividimos el string de fecha en trozos (dia,mes,año)
   $dia   =   eval($fecha[0]);
   $mes   =   eval($fecha[1]);
   $ano   =   eval($fecha[2]);
   
   if ($mes==1 || $mes==2){
      //Cálculos si el mes es Enero o Febrero
      $a   =   $ano-1;
      $b   =   Math.floor($a/4)-Math.floor($a/100)+Math.floor($a/400);
      $c   =   Math.floor(($a-1)/4)-Math.floor(($a-1)/100)+Math.floor(($a-1)/400);
      $s   =   $b-$c;
      $e   =   0;
      $f   =   $dia-1+(31*($mes-1));
   } else {
      //Calculos para los meses entre marzo y Diciembre
      $a   =   $ano;
      $b   =   Math.floor($a/4)-Math.floor($a/100)+Math.floor($a/400);
      $c   =   Math.floor(($a-1)/4)-Math.floor(($a-1)/100)+Math.floor(($a-1)/400);
      $s   =   $b-$c;
      $e   =   $s+1;
      $f   =   $dia+Math.floor(((153*($mes-3))+2)/5)+58+$s;
   };

   //Adicionalmente sumándole 1 a la variable $f se obtiene numero ordinal del dia de la fecha ingresada con referencia al año actual.

   //Estos cálculos se aplican a cualquier mes
   $g   =   ($a+$b)%7;
   $d   =   ($f+$g-$e)%7; //Adicionalmente esta variable nos indica el dia de la semana 0=Lunes, ... , 6=Domingo.
   $n   =   $f+3-$d;
   
   if ($n<0){
      //Si la variable n es menor a 0 se trata de una semana perteneciente al año anterior
      $semana   =   53-Math.floor(($g-$s)/5);
      $ano      =   $ano-1; 
   } else if ($n>(364+$s)) {
      //Si n es mayor a 364 + $s entonces la fecha corresponde a la primera semana del año siguiente.
      $semana   = 1;
      $ano   =   $ano+1;
   } else {
      //En cualquier otro caso es una semana del año actual.
      $semana   =   Math.floor($n/7)+1;
   };
   
   return $semana+"-"+$ano; //La función retorna una cadena de texto indicando la semana y el año correspondiente a la fecha ingresada   
};

Cabe resaltar que este algoritmo solo funciona para semanas del calendario gregoriano y para otro tipo de calendarios (Juliano, Egipcio, Maya, etc.).

El algoritmo original en el que se basa este script fue desarrollado por Claus Tøndering en el 2002.

Espero les sea de utilidad

¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.

Publica tu comentario

El autor de este artículo ha cerrado los comentarios. Si tienes preguntas o comentarios, puedes hacerlos en el foro

Entra al foro y participa en la discusión

o puedes...

¿Estás registrado en Cristalab y quieres
publicar tu URL y avatar?

¿No estás registrado aún pero quieres hacerlo antes de publicar tu comentario?

Registrate