sábado, 4 de mayo de 2019

Calcular el día de la Semana

En esta breve entrada veremos dos formas para determinar el día de la semana...
la primera forma es un Sketch de diseño propio, que requiere un dato de referencia para calcular el día de la semana durante el año-
Este primer Sketch es poco útil como tal, si bien contiene conversiones de valores numéricos a String y viceversa  que nos podrán valer como referencia en caso de requerir este tipo de Casting.

// Compilado con Arduino 1.8.1, 1/03/2019
byte Mes[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // Array de tipo byte, con los dias totales de cada mes del año
char tSemana[7] = {'L', 'M', 'X', 'J', 'V', 'S', 'D'}; // Array de tipo char, para visualizar el dia de la semana
char dSemana;// Variable tipo char, almacena el char correspondiente del array anterior
byte dia = 1;// Variable tipo byte, indicamos el dia del mes que deseamos conocer su equivalente en dia de semana
byte mes = 6;// Variable de tipo byte, indicamos el mes para el dia que deseamos conocer el dia de la semana
void setup() {
  Serial.begin(9600);
  diaSemana();// llamada a la funcion que calcula el dia de la semana
  Serial.println(dSemana);// Imprimimos el dia de la semana resultante
}

void loop() {}

void diaSemana() {
  byte puntero = 1; //Esta variable señala la pocicion de tSemana, debe coincidir con el primer dia del año a consultar.
                    //0=Lunes, 1=Martes, 2=Miercoles... el primer dia del año 2019 fue Martes, por tanto puntero debe valer 1
                    //El primer dia del año 2020 será Miércoles y puntero debera actualizarse a 3 ...
  byte d = 1;// variable para el dia de punto de partida para el calculo del dia de la semana (deberia ser una constante) 
  byte m = 1;//variable para el mes de partida para el calculo del dia de la semana (deberia ser una constante) 
  String stfecha = String(dia) + "_" + String(mes); // se realizan dos castings de byte a string y se concatenan los dos en una nueva String
  String stF = String(d) + "_" + String(m);// al igual que el anterior, las dos Strings resultantes podran ser comparadas en el While
  while (!stF.equals(stfecha)) {// Mientras la fecha de partida no coincida con la fecha introducida el bucle se repite
    Serial.print("stF: "); Serial.print(stF); Serial.print(" stfecha: "); Serial.println(stfecha); // imprime lo comparado en cada iteración
    if (puntero > 5) {// si puntero vale mas de 5, o sea 6, es que ha llegado al final del array tSemana 
      puntero = 0;// entonces puntero se situa nuevamente al principio del array
    } else {
      puntero++; // de lo contrario, la variable puntero va tomando un nuevo valor del array tSemana en cada iteración
    }
    d++; // se suma uno a cada iteracion
    if (d > Mes[m - 1]) {//si el valor de la variable supera el valor del Array Mes...
      d = 1;// dia se establece en 1
      m++; // y mes se incrementa
    }
    stF = String(d) + "_" + String(m);// se actualiza el valor de la String stF para ser comparada nuevamente en la siguiente iteracion
  }
  dSemana = tSemana[puntero];// la variable dSemana toma el valor del Array tSemana con la posicion que le indica puntero.
}

El resultado para el 1 de Junio de 2019 es S (Sábado):




Si bien conocemos la "Congruencia de Zeller"  de la que se puede establecer un algoritmo que  nos permita realizar dicho calculo de manera mas sencilla y práctica para nuestros proyectos, el siguiente Sketch así lo demuestra:

// Algorito basado en la Congruencia de Zeller, Compilado con Arduino 1.8.1, 1/03/2019
// by @quark https://forum.processing.org/two/discussion/3350/getting-the-day-of-the-week-without-calendar
char tSemana[7] = {'D', 'L', 'M', 'X', 'J', 'V', 'S'}; // Array de tipo char, para visualizar el dia de la semana
void setup(){ 
  Serial.begin(9600);
  Serial.println(tSemana[dow(1,7,2019)]);// Llama a la funcion al tiempo que imprime el resultado
}

void loop() {
}

int dow(int d, int m, int y) { 
  if (m < 3) {
    m += 12;
    y--;
  }
  return ((d + int((m+1)*2.6) +  y + int(y/4) + 6*int(y/100) + int(y/400) + 6) % 7);
}

Atención, este algoritmo ordena los días de la semana en plan Americano, de manera que el primer día de la semana es Domingo!!! y así debe establecerse en el Array tSemana.






No hay comentarios:

Publicar un comentario

Gracias por tu comentario, en breve lo revisaremos.