¿Quieres registrarte?

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

Por: NeoCesar
1 de Septiembre del 2009
508 de clabLevel
Otros artículos de NeoCesar
4,433 visitas

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

Enviar a twitter Enviar a facebook


También te interesa


Etiquetas javascript matematicas

Comentarios | Enviar un comentario
La verdad te felicito por la investigación y haber mejorado el algoritmo anterior. Una buena labor que le suma valor a tus tips. +1 NeoCesar.
Por: Freddie
La verdad te felicito por la investigación y haber mejorado el algoritmo anterior. Una buena labor que le suma valor a tus tips. +1 NeoCesar.
Por: Freddie
Este algoritmo es en javascript WSH (archivos js). Se q no es lo mismo pero tal vez puedas pasarlo al lenguaje q estas usando
---------------------------------------


function Num_Week()
{
fecha = new Date();
f2 = new Date(fecha.getFullYear(),fecha.getMonth(),fecha.getDate(),0,0);
f1 = new Date(fecha.getFullYear(),0,1,0,0);
day = f1.getDay();
if(day == 0)
day = 7;
if(day <5)
{
FW = parseInt(((Math.round(((f2-f1)/1000/60/60/24))+(day-1))/7) + 1);
if(FW == 53 || FW == 0)
FW = 1;
}
else
{
FW = parseInt(((Math.round(((f2-f1)/1000/60/60/24))+(day-1))/7));
if(FW == 0)
FW = 52;
if(FW == 53)
FW = 1;
}
return(FW);
}

WScript.echo(Num_Week());
Por: Macamba-blog
Perdon porque el script q puse no era correcto y no toma bien la regla:

"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


--------------------------------------

WScript.echo(FW());

function FW()
{
fecha = new Date();
month = fecha.getMonth();
date = fecha.getDate();

f1 = new Date(fecha.getFullYear(),0,1,0,0);
dayf1 = f1.getDay();
if(dayf1 == 0)
dayf1 = 7;

f2 = new Date(fecha.getFullYear(),month,date,0,0);
dayf2 = f2.getDay();
if(dayf2 == 0)
dayf2 = 7;

if(month == 0 && date == 1 && dayf2 > 4 || month == 0 && date == 2 && dayf2 > 5 || month == 0 && date == 3 && dayf2 == 7)
{
f1 = new Date(fecha.getFullYear()-1,0,1,0,0);
f2 = new Date(fecha.getFullYear()-1,11,31,0,0);
dayf1 = f1.getDay();
if(dayf1 == 0)
day = 7;
}
if(month == 11 && date == 31 && dayf2 < 4 || month == 11 && date == 30 && dayf2 < 3 || month == 11 && date == 29 && dayf2 == 1)
return 1;

if(dayf1 <5)
FW = parseInt(((Math.round(((f2-f1)/1000/60/60/24))+(dayf1-1))/7) + 1);
else
FW = parseInt(((Math.round(((f2-f1)/1000/60/60/24))+(dayf1-1))/7));
return FW;
}

--------------------------------------

Guardar el contenido con el bloc de notas y despues cambiar la extension de *.txt a *.js
Por: Macamba-blog
Deja un comentario
IMPORTANTE

Recuerda ser respetuoso, no insultes a otras personas, ni uses palabrotas, hay una persona al otro lado de la pantalla.

Habla bien, NO ESCRIBAS EN MAYUSCULA TODO, no escribas como en un SMS, evita cosas como "ke", "x q" y demás abreviaciones.

Aquí funcionan las etiquetas de los foros, puedes usar [b] para negrita, [img] para las imágenes, [url] para los enlaces, etc.

Si tienes preguntas técnicas, envíalas mejor al foro.