ntp bug depuis mars ???

Bonjour,

j'utilise une routine de lecture NTP via une ESP8266 depuis plusieurs mois sans aucun problème

par contre, depuis le 1er mars, j'ai un souci de date, mon NTP me retourne le mauvais jour, comme si il manquait le 29 février car c'est la que ça a commencé, j'ai eu 2 28 février et le 1er mars a démarré le 2 !! c'est comme ça tous les jours avec un décalage de 1 ??

d’où peut donc venir ce décalage ? c'est bien ma routine de lecture NTP qui me retourne le mauvais jour, il est ensuite enregistré dans un DS1307 mais le problème n'est pas là

ça ne viens pas non plus de mon serveur NTP, j'en ai essayé plusieurs avec le même résultat

qui aurait rencontré cela ?

je pense que cela viens de ma fonction de décomposition timestamp récupérée sur internet :

void DecomposerTimestamp(uint32_t ts, uint8_t *a, uint8_t *m, uint8_t *j, uint8_t *js, uint8_t *hh, uint8_t *mm, uint8_t *ss)
{
  uint32_t li;

  uint16_t deb, fin;
  uint8_t mois;

  li = ts / 86400;

  *a = (li - ((li + 1401) / 1461)) / 365;//copieux mais correct

  li = li + 1 - ((*a)*365) - (((*a)+3)>>2);
  fin = 0;
  for (mois=1; mois<=12; mois++)
  {
    deb = fin;
    switch (mois)
    {
      case  2 :
        fin += 28 + (!((*a)&3));
        break;
      case  4 :
      case  6 :
      case  9 :
      case 11 :
        fin += 30;
        break;
      default :
        fin += 31;
        break;
    }
    if (fin >= li)
    {

      *m = mois;
      *j = li - deb;
      mois = 12;
    }
  }

  li  = ts % 86400;
  *hh = li / 3600;

  li  = li % 3600;
  *mm = li / 60;
  *ss = li % 60;

  *js = ((ts / 86400) + 5) % 7 + 1;

}

mais je ne vois pas trop ce qui bug…

ça sent le bug d’arrondi En calcul entier avec un mélange d’octets de int et de unsigned long quelque part....

Vérifiez que vous récupérez le bon time stamp quand même

Bonjour

Ce code m'est familier. J'ai retrouvé la source ici

Je vérifierai ce soir

C’est vrai que le code n’est pas super clean, mais bon ce n’était qu’un exemple d’expérimentation que j’avais posté, et non une bibliothèque en bonne et due forme.

Le code équivalent me semble beaucoup plus propre dans simpleRTC.h

Quoi qu’il en soit, je viens de vérifier et cette fonction est parfaitement opérationnelle sous arduino.

C’est une bête fonction en calcul pure, avec une entrée (ts = le nombre de secondes écoulées depuis le 1er janvier 2000), et n variables en sortie : a,m,j,js,hh,mm,ss

Là je viens de la tester pour TOUTES les valeurs de ts comprises entre 572832000 et 573609599, c’est-à-dire pour chaque seconde comprise entre le 25/02/2018 00:00:00 et le 05/03/2018 23:59:59

Et les variables calculées sont correctes.

Soit l’anomalie se trouve ailleurs, soit il s’agit d’une différence de compilation pour ESP8266 qui fait qu’un résultat de calcul n’est pas le même. Mais cela m’étonnerait car toutes les variables sont typées en uint.

Le programme de certification sur cette plage de dates :

void DecomposerTimestamp(uint32_t ts, uint8_t *a, uint8_t *m, uint8_t *j, uint8_t *js, uint8_t *hh, uint8_t *mm, uint8_t *ss)
{
  uint32_t li;

  uint16_t deb, fin;
  uint8_t mois;

  li = ts / 86400;

  *a = (li - ((li + 1401) / 1461)) / 365;//copieux mais correct

  li = li + 1 - ((*a)*365) - (((*a)+3)>>2);
  fin = 0;
  for (mois=1; mois<=12; mois++)
  {
    deb = fin;
    switch (mois)
    {
      case  2 :
        fin += 28 + (!((*a)&3));
        break;
      case  4 :
      case  6 :
      case  9 :
      case 11 :
        fin += 30;
        break;
      default :
        fin += 31;
        break;
    }
    if (fin >= li)
    {

      *m = mois;
      *j = li - deb;
      mois = 12;
    }
  }

  li  = ts % 86400;
  *hh = li / 3600;

  li  = li % 3600;
  *mm = li / 60;
  *ss = li % 60;

  *js = ((ts / 86400) + 5) % 7 + 1;
}

void avancer(uint8_t *a, uint8_t *m, uint8_t *j, uint8_t *js, uint8_t *hh, uint8_t *mm, uint8_t *ss)
{
  if (*ss < 59)
  {
    *ss = *ss + 1;
  }
  else
  {
    *ss = 0;
    if (*mm < 59)
    {
      *mm = *mm + 1;
    }
    else
    {
      *mm = 0;
      Serial.print('.');
      if (*hh < 23)
      {
        *hh = *hh + 1;
      }
      else
      {
        Serial.println();
        *hh = 0;
        *js = *js % 7 + 1;
        uint8_t jmax = (*m==4 || *m==6 || *m==9 || *m==11) ? 30 : (*m==2 ? (((*a)&3) ? 28 : 29) : 31);
        if (*j < jmax)
        {
          *j = *j + 1;
        }
        else
        {
          *j = 1;
          if (*m < 12)
          {
            *m = *m + 1;
          }
          else
          {
            *m = 1;
            *a = *a + 1;
          }
        }
      }
    }
  }
}

void afficher2chiffres(uint8_t nombre)
{
  if (nombre < 10) Serial.print('0');
  Serial.print(nombre);
}

void afficher(char *txt, uint8_t a, uint8_t m, uint8_t j, uint8_t js, uint8_t hh, uint8_t mm, uint8_t ss)
{
  Serial.print(txt);
  Serial.print('=');
  Serial.print(js);
  Serial.print(' ');
  afficher2chiffres(j);
  Serial.print('/');
  afficher2chiffres(m);
  Serial.print('/');
  afficher2chiffres(20);
  afficher2chiffres(a);
  Serial.print(' ');
  afficher2chiffres(hh);
  Serial.print(':');
  afficher2chiffres(mm);
  Serial.print(':');
  afficher2chiffres(ss);
  Serial.println();
}

bool certifierDecomposerTimestamp(uint32_t ts_min, uint32_t ts_max)
{
  bool erreur = false;
  uint8_t a0, m0, j0, js0, hh0, mm0, ss0;
  uint8_t a, m, j, js, hh, mm, ss;

  DecomposerTimestamp(ts_min, &a0, &m0, &j0, &js0, &hh0, &mm0, &ss0);
  afficher("ts_min", a0, m0, j0, js0, hh0, mm0, ss0);

  for (uint32_t ts = ts_min + 1; ts <= ts_max; ts++)
  {
    DecomposerTimestamp(ts, &a, &m, &j, &js, &hh, &mm, &ss);
    avancer(&a0, &m0, &j0, &js0, &hh0, &mm0, &ss0);
    if (a!=a0 || m!=m0 || j!=j0 || js!=js0 || hh!=hh0 || mm!=mm0 || ss!=ss0)
    {
      erreur = true;
      Serial.println("\nErreur : ");
      afficher("attendu", a0, m0, j0, js0, hh0, mm0, ss0);
      afficher("obtenu ", a, m, j, js, hh, mm, ss);
      ts = ts_max;
    }
    a0=a; m0=m; j0=j; js0=js; hh0=hh; mm0=mm; ss0=ss;
  }
  if(!erreur) afficher("\nts_max", a, m, j, js, hh, mm, ss);

  return !erreur;
}

void setup()
{
  Serial.begin(9600);
  uint32_t ts_min = 572832000UL;// 25/02/2018 00:00:00
  uint32_t ts_max = 573609599UL;// 05/03/2018 23:59:59

  Serial.println("Programme de certification de la fonction DecomposerTimestamp");
  if (certifierDecomposerTimestamp(ts_min, ts_max))
  {
    Serial.println("Certification OK");
  }
  else
  {
    Serial.println("Certification KO");
  }
}

void loop()
{
}