Código horario verano/invierno

Gracias por contestar,

la idea de agrupar toda la fecha para generar un número con el que comparar así fechas, para saber si una fecha está antes o después, es muy buena idea. Lo que no sé es como hacerlo, ya que las variables que obtengo del RTC (month, day, hour,..) me vienen en tipo byte por lo que supongo que tendré que convertirlo en long -> 2011032703 (momento clave de cambio de hora en formato [AAAAMMDDHH]) es decir necesito guardar más de 2 mil millones (supongo que el año podría dejarlo sólo en dos cifras pero como el integer no sirve ya que estamos...)

¿Alguién sabe como hacerlo?

Un saludo

Se me había olvidado que no todos los meses tienen 31 días, pero en horario de verano todos los años son iguales (siento no reducir el código)

// Al incrementar la hora en verano, hay que ajustar el día de mes y mes una hora antes que
// el RTC según el mes tenga 30 o 31 días
  if (hour>=24){
    hour=0;
    if(dayOfMonth>=32&&month==3){
      dayOfMonth=1;
      month=month++;
    }
    if(dayOfMonth>=32&&month==5){
      dayOfMonth=1;
      month=month++;
    }
    if(dayOfMonth>=32&&month==7){
      dayOfMonth=1;
      month=month++;
    }
    if(dayOfMonth>=32&&month==8){
      dayOfMonth=1;
      month=month++;
    }
    if(dayOfMonth>=32&&month==10){
      dayOfMonth=1;
      month=month++;
    }

    if(dayOfMonth>=31&&month==4){
      dayOfMonth=1;
      month=month++;
    }
    if(dayOfMonth>=31&&month==6){
      dayOfMonth=1;
      month=month++;
    }
    if(dayOfMonth>=31&&month==9){
      dayOfMonth=1;
      month=month++;
    }
  }

Creo que he simplificado bastante el código, como bien me habéis recomendado. A la espera de hacer otra versión mejorada, haciendo un numero uniendo las variables para compararlas, como comentáis, dejo aquí la última versión (se agradece cualquier comentario:

void calculo_horario (void){
  
  //Todo abril y todo noviembre (más adelante se le resta para los días de
  //octubre que no son horario de verano
  if (month>=4&&month<=10){
    hour++;
  }
  //Para los días de marzo desde el último domingo del mes
  if (month==3&&dayOfWeek==1&&dayOfMonth>=25){
    if(hour>=2){   
    hour++;
    }
  }
  if (month==3&&dayOfWeek==2&&dayOfMonth>=26){
    hour++;
  }
  if (month==3&&dayOfWeek==3&&dayOfMonth>=27){
    hour++;
  }
  if (month==3&&dayOfWeek==4&&dayOfMonth>=28){
    hour++;
  }
  if (month==3&&dayOfWeek==5&&dayOfMonth>=29){
    hour++;
  }
  if (month==3&&dayOfWeek==6&&dayOfMonth>=30){
    hour++;
  }  
  if (month==3&&dayOfWeek==7&&dayOfMonth==31){
    hour++;
  }
  
 
//Para los días de octubre que no son de horario de verano (se le resta la hora
//anteriormente sumada)
  if (month==10&&dayOfWeek==1&&dayOfMonth>=25){
      if(hour>=3){
        hour=hour-1;
      }
  }
  if (month==10&&dayOfWeek==2&&dayOfMonth>=26){
    if (hour==0){
      hour=22;
    }
    else
    {
      if (hour==1){
      hour=23;
      }
      else
      {
        hour=hour-2;
      }
    }
  }
  if (month==10&&dayOfWeek==3&&dayOfMonth>=27){
    if (hour==0){
      hour=22;
    }
    else
    {
      if (hour==1){
      hour=23;
      }
      else
      {
        hour=hour-2;
      }
    }
  }
  if (month==10&&dayOfWeek==4&&dayOfMonth>=28){
    if (hour==0){
      hour=22;
    }
    else
    {
      if (hour==1){
      hour=23;
      }
      else
      {
        hour=hour-2;
      }
    }
  }
  if (month==10&&dayOfWeek==5&&dayOfMonth>=29){
    if (hour==0){
      hour=22;
    }
    else
    {
      if (hour==1){
      hour=23;
      }
      else
      {
        hour=hour-2;
      }
    }
  }

  if (month==10&&dayOfWeek==6&&dayOfMonth>=30){
    if (hour==0){
      hour=22;
    }
    else
    {
      if (hour==1){
      hour=23;
      }
      else
      {
        hour=hour-2;
      }
    }
  }  
  if (month==10&&dayOfWeek==7&&dayOfMonth==31){
    if (hour==0){
      hour=22;
    }
    else
    {
      if (hour==1){
      hour=23;
      }
      else
      {
        hour=hour-2;
      }
    }
  }
  
// Al incrementar la hora en verano, hay que ajustar el día de mes y mes una hora antes que
// el RTC según el mes tenga 30 o 31 días
  if (hour>=24){
    hour=0;
    if(dayOfMonth>=32&&month==3){
      dayOfMonth=1;
      month++;
    }
    if(dayOfMonth>=32&&month==5){
      dayOfMonth=1;
      month++;
    }
    if(dayOfMonth>=32&&month==7){
      dayOfMonth=1;
      month++;
    }
    if(dayOfMonth>=32&&month==8){
      dayOfMonth=1;
      month++;
    }
    if(dayOfMonth>=32&&month==10){
      dayOfMonth=1;
      month++;
    }

    if(dayOfMonth>=31&&month==4){
      dayOfMonth=1;
      month++;
    }
    if(dayOfMonth>=31&&month==6){
      dayOfMonth=1;
      month++;
    }
    if(dayOfMonth>=31&&month==9){
      dayOfMonth=1;
      month++;
    }
  }
}

Hay varias formas de hacer lo de la fecha, una facil es si tienes anyo,mes y dia en variables numericas:
unsigned long mifecha=anyo10000+mes100+dia;

Para dia=11,mes=10 y anyo=2011=> mifecha=20110000+1000+11 (si quieres puedes usar el anyo solo 2 cifras o esperas que aguante mas del 2100?? je,je,je)

De todas formas, esta pregunta es de no haberse parado a pensar un poquito… ehhh!!!

Yo cogeria papel y boli, y me lo pensaria bien como hacerlo. Luego programar son 5 minutillos…

:wink:

Gracias Igor R,

lo que comentas esta bien pero lo que no sé es pasar de variable byte a long, ya que byte es como me devuelve la función del RTC y byte no se suficiente para alamacenar el número.

Un saludo

A ver…

Un byte contiene un numero de 0 a 255.
Si ves el datasheet de tu RTC => http://datasheets.maxim-ic.com/en/ds/DS3231.pdf
Pag 11 => puedes ver los “range” de tus datos.
cual es el problema?? Te va a devolver algo como (fecha de hoy)
Anyo=11, Mes=02, Dia=14

No hay ningun problema en sumar variables de tipo byte y almacenarlas en un unsigned long (ya que la suma va a ser mas pequenya que el maximo numero que puede albergar unsigned long).

Ahora que hemos cambiado de hora, he encontrado una forma bastante sencilla, empleand la "congruencia de Zeller". En este artículo lo explican: http://latecladeescape.com/recetas-algoritmicas/ya-estamos-otra-vez-con-el-dichoso-cambio-de-hora.html

He mirado el codigo y no lo entiendo, como sabe el cambio?

Salu2

En el enlace que puse viene explicado, y también en la wikipedia, pero esa explicación no la entiendo

Lo que calculamos es el último domingo de Marzo y el último domingo de Octubre (las 2 de la madrugada del sábado al domingo ya es el domingo) y si la fecha actual es posterior al último domingo de Marzo, y anterior al último domingo de octubre, entonces es horario de verano (lo almaceno poniendo la variable horariodeverano a true). Se podría afinar más haciendo el cambio a las 2 de la madrugada, pero a mí me vale si lo hace a las 12 de la noche y me simplifica el código.

La hora, la tengo en UTC y si es horario de verano, cuando voy a escribirla muestro la hora +2, pero si no es horario de verano, muestro la hora +1.

  if  (horariodeverano==true)
  {
    Serial.print(now.hour()+2, DEC);
  }
  else
  {
    Serial.print(now.hour()+1, DEC);
  }

Aquí la función calculacambiohora, que llama a la de Zeller:

void calculacambiohora () {
  DateTime now = RTC.now();
  int anno=now.year();
  //el último domingo de Marzo
  int dhv = 31 - Zeller(anno, 3, 31);
  //el último domingo de Octubre
  int dhi=31 - Zeller(anno,10,31);
  horariodeverano=false;
  if ((( now.month()>3 ) && ( now.month()<10 )) || ( ( now.month()==3 ) && (  now.day()>=dhv)) || ( ( now.month()==10 ) && (  now.day()<dhi)))
  {
    horariodeverano=true;
  }
}


int Zeller(int anno, int mes, int dia)
{
  if (mes <= 2)
  {
    mes = mes + 10;
    anno = anno - 1;
  }
  else
  {
    mes = mes - 2;
  }
  int a = anno % 100;
  int b = anno / 100;
  int resultado =
    (
  700 +
    ((26 * mes - 2) / 10) +
    dia +
    a +
    a / 4 +
    b / 4 -
    2 * b
    ) % 7;
  return resultado;
}

Lo probé el otro día, y por la mañana el arduino-reloj mostraba la hora con el cambio correcto
Saludos