Hola @anon91236016 te respondo paso a paso.
La diferencia T1-T0 funciona perfectamente, cambié tu código con T1 a 1 dia, 1 mes 6 meses y luego con horas y dias y siempre dió la respuesta correcta.
Tu error al ver valores negativos debe tener que ver con el tipo de variable elegida.
Ahora miro y te lo indico.
Yo elegí 1 mes y mira la respuesta que da
18/12/2020 9:30:0
18/1/2021 9:30:0
1/2/1970 0:0:0
1 meses,0 dias,0 horas, 0 minutos
30 dias en los meses,
-22336 minutos en los 2 meses, 0 minutos en los dias,0 minutos en las horas, 0 minutos
Vamos bien hasta los minutos, porque claro, son muchos minutos en 1 mes y el tipo de variable que has usado queda rebasado.
Los enteros sin signo toleras 2^16 bits => de 0 a 65535 números
si eso no alcanza entonces usar unsigned long 2^32 calculadora y te da algo como 4mil millones de números.
En donde empiezan los problemas es en los minutos
Esto debería funcionar mejor
Acá mi programa con 1 mes, 1 dia, 1 hora, 1 min y 1 segundo mas
#include <TimeLib.h>
time_t T0, T1 ; // Contenedores de fechas
void setup() {
Serial.begin(115200);
T0 = SetFecha(2020, 12, 18, 9, 30, 0); //18/12/2020 09:30:00
printFecha(T0) ;
T1 = SetFecha(2021, 01, 19, 10, 31, 1); //18/12/2020 09:30:00
//SetFecha(2021, 03, 01, 07, 0, 0); // 1/03/2021 7:00:00
printFecha(T1) ;
printFecha(T1 - T0);
Serial.println("--------------------------------------------------");
time_t H = T1 - T0 ;
int meses = month(H) - 1;
Serial.print( String(meses ) + " meses,");
int dias = day(H) - 1;
int horas = hour(H);
int minutos = minute(H);
Serial.println(String(dias) + " dias," + String(horas) + " horas, " + String(minutos) + " minutos");
Serial.println("*************************************************");
if (meses == 1)
Serial.println( "30 dias en 1 mes, ");
else
Serial.println( String(meses * 30 ) + " dias en los " + String(meses) +" meses, ");
unsigned long minxmes = (month(H) - 1) * 86400;
if (meses == 1)
Serial.print(String(minxmes) + " minutos en 1 mes, "); //86400 minutos
else
Serial.print(String(minxmes) + " minutos en los " + String(meses)+" meses, "); //86400 minutos
unsigned long minxdia = (day(H) - 1) * 1440;
Serial.println(String(minxdia) + " minutos en los dias," + String((hour(H) * 60)) + " minutos en las horas, " + String(minute(H)) + " minutos");
Serial.println("---------------------------------------------------");
unsigned long verifico = meses * 86400 + dias * 1440 + horas + minutos;
Serial.println( String(verifico));// no coincide
}
void loop() {
}//fin lood
void printFecha(time_t t)
{
Serial.print(day(t)) ; Serial.print(+ "/") ; Serial.print(month(t)); Serial.print(+ "/") ;
Serial.print(year(t)); Serial.print( " ") ;
Serial.print(hour(t)); Serial.print(+ ":") ; Serial.print(minute(t)); Serial.print(":") ;
Serial.println(second(t));
delay(1000);
}//fin printfecha
time_t SetFecha(int y, int m, int d, int h, int mi, int s )
{ tmElements_t Fecha ;
Fecha.Second = s;
Fecha.Minute = mi;
Fecha.Hour = h;
Fecha.Day = d ;
Fecha.Month = m ;
Fecha.Year = y - 1970 ;
return makeTime(Fecha);
}//fin setfecha
El inconveniente estaba acá, al final
unsigned long verifico = meses * 86400 + dias * 1440 + horas + minutos;
Serial.println( String(verifico));// no coincide
al usar un tipo de variable que simplemente contiene como corresponde la cuenta, no hay problema de overflow o rebasamiento porque multiplicar algo por 86400 saca a los enteros de su máximo posible representable que es 65535
1x86400 > 65535 y eso da overflow que se representa con un valor negativo.
Al usar long o unsigned long se supera el problema
Podria tambien haberse resuelto asi
Serial.println( String((long) (((month(H) - 1) * 86400 ) + ((day(H) - 1) * 1440) + (hour(H) * 60) + minute(H))));// no coincide