¿El reloj en tiempo real Epson RX8900 cuenta el año “00” como un año bisiesto?

1

Las hojas de datos dicen ambiguamente ...

  

Un año bisiesto se establece cuando el valor del año es un múltiplo de cuatro (como 04, 08, 12, 88, 92 o 96).

¿Escerounmúltiplodecuatro?Estoesmásde una pregunta filosófica que una especificación. La serie que se muestra comienza en 4 y finaliza con 96, lo que sugiere que la buena gente de Seiko no cree que cero sea un múltiplo de cuatro.

Resulta ser un hecho crítico si está tratando de medir los intervalos de tiempo. Si elige incorrectamente, cualquier fecha posterior al 1 de marzo, 00 puede estar desactualizada por un día.

    
pregunta bigjosh

1 respuesta

5

A pesar de la serie engañosa en la hoja de datos, el RX8900 considera que el año "00" es un año bisiesto.

Probé esto empíricamente estableciendo la fecha en 28 de febrero de 00 y dejándola rodar para ver cómo era el día siguiente ...

Tambiénverifiquéel28defebrerode01comocontrol...

Siestáconsiderandoestapregunta,estecódigopodríaserledeutilidad...

//ThistableofdayspermonthcamefromtheRX8900datasheetpage9staticuint8_tdaysInMonth(uint8_tm,uint8_ty){switch(m){case1:case3:case5:case7:case8:case10:case12://Interestingly,wewillneverhit12.Seewhy?return31;case4:case6:case9:case11:return30;case2:if(y%4==0){//"A leap year is set whenever the year value is a multiple of four (such as 04, 08, 12, 88, 92, or 96)."
                                                // Empirical testing also shows that 00 is a leap year to the RX8900
                                                // https://electronics.stackexchange.com/questions/385952/does-the-epson-rx8900-real-time-clock-count-the-year-00-as-a-leap-year

                        return 29 ;             // "February in leap year 01, 02, 03 ... 28, 29, 01

                    } else {

                        return 28;              // February in normal year 01, 02, 03 ... 28, 01, 02
                    }

    }

    __builtin_unreachable();

}

static const uint32_t rx8900_days_per_century = ( 100UL * 365 ) + 25;       // 25 leap years in every RX8900 century

// Convert the y/m/d values from the RX8900 to a count of the number of days since 00/1/1
// rx8900_date_to_days( 0 , 1, 1 ) = 0
// rx8900_date_to_days( 0 , 1, 31) = 30
// rx8900_date_to_days( 0 , 2, 1 ) = 31
// rx8900_date_to_days( 1 , 1, 1 ) = 366 (00 is a leap year!)

static uint32_t rx8900_date_to_days( uint8_t c , uint8_t y , uint8_t m, uint8_t d ) {

    uint32_t dayCount=0;

    // Count days in centuries past

    dayCount += rx8900_days_per_century * c;

    // Count days in years past this century

    for( uint8_t y_scan = 0; y_scan < y ; y_scan++ ) {

        if ( y_scan % 4 == 0 ) {
            // leap year every 4 years on RX8900
            dayCount += 366UL;      // 366 days per year past in leap years

        } else {

            dayCount += 365UL;      // 365 days per year past in normal years
        }

    }


    // Now accumulate the days in months past so far this year

    for( uint8_t m_scan = 1; m_scan < m ; m_scan++ ) {      // Don't count current month

        dayCount += daysInMonth( m_scan , y );       // Year is needed to count leap day in feb in leap years.


    }

    // Now include the passed days so far this month

    dayCount += (uint32_t) d-1;     // 1st day of a month is 1, so if it is the 1st of the month then no days has elapsed this month yet.

    return dayCount;

}
    
respondido por el bigjosh

Lea otras preguntas en las etiquetas