L' RTC memorizza l'anno da 0 a 99.
Altri valori al di fuori di questo intervallo sono gestiti/creati artificiosamente dalle librerie usate.
Quindi per risolvere realmente bisogna capire esattamente come ragiona questa libreria, quali sono i suoi limiti e che obblighi impone per funzionare correttamente.
Nello specifico non conosco quella lib, ne le eventuali sottolib da essa usate come, se non sbaglio 'time'.
Per avere meno intermediari l'RTC l'ho sempre letto/scritto direttamente, e i registri hardware contengono i valori che ci si aspetta.
Posso mostrare come ho fatto io, ma credo non si adatti al tuo programma attuale.
Una struttura globale chiamata 'now' per contenere i valori letti o da scrivere sull'RTC:
struct {
byte hour = 0;
byte minute = 0;
byte second = 0;
byte w_day = 1;
byte m_day = 1;
byte month = 1;
byte year = 0;
} now;
Una funzione per leggere dall'RTC il secondo attuale (mi interessa sapere quando cambia il secondo per poi fare altre operazioni):
void readSecond(){
Wire.beginTransmission(0x68);
Wire.write(0); // punta al registro secondi
Wire.endTransmission();
Wire.requestFrom(0x68, 1); // legge un byte
now.second = BCDbin(Wire.read() & 0b01111111);}
Una per leggere ora e minuti:
void readHour(){
Wire.beginTransmission(0x68);
Wire.write(1); // punta al registro minuti
Wire.endTransmission();
Wire.requestFrom(0x68, 2); // legge due byte
now.minute = BCDbin(Wire.read() & 0b01111111);
now.hour = BCDbin(Wire.read() & 0b00111111);}
Una per leggere la data completa:
void readDate(){
Wire.beginTransmission(0x68);
Wire.write(3); // punta al registro 3
Wire.endTransmission();
Wire.requestFrom(0x68, 4); // legge 4 byte
now.w_day = Wire.read() & 0b00000111;
now.m_day = BCDbin(Wire.read() & 0b00111111);
now.month = BCDbin(Wire.read() & 0b00011111);
now.year = BCDbin(Wire.read());} // 0..99 = 2000..2099
E due per scrivere l'ora o la data:
void setHour(){
Wire.beginTransmission(0x68); // indirizzo RTC su bus i2c
Wire.write(0); // punta al registro 0
Wire.write(0); // azzera secondi RTC
Wire.write(binBCD(now.minute)); // imposta minuti RTC
Wire.write(binBCD(now.hour)); // imposta ore RTC
Wire.endTransmission();}
void setDate(){
Wire.beginTransmission(0x68);
Wire.write(3); // punta al registro 3
Wire.write(now.w_day); // 1..7 (1=LUN)
Wire.write(binBCD(now.m_day)); // 1..31
Wire.write(binBCD(now.month)); // 1..12 (1=GEN)
Wire.write(binBCD(now.year)); // 00..99 = 2000..2099
Wire.endTransmission();}
Il tutto con l'aiuto delle due funzioni di conversione BCD:
byte BCDbin(byte n){return ((n >> 4) * 10) + (n & 0x0F);}
byte binBCD(byte n){return ((n / 10) << 4) | (n % 10);}
Invece per capire cosa fa la libreria bisogna scoprire cosa fa la funzione 'tmYearToY2k' già nominata... che non so dove andare a trovare. In alternativa scriverei un anno usando la libreria, e poi andrei a leggere direttamente il registro per vedere cosa ci è stato scritto dentro (così per deduzione si dovrebbe capire cosa fa la 'tmYearToY2k', e quindi perché ci sono da fare quelle sottrazioni e se possono saltare fuori altre sorprese).