Quando si sta tentando di eseguire l'aritmetica del calendario utilizzando time_t
, è naturalmente necessario preoccuparsi del tipo e della rappresentazione di time_t
, che è ovviamente definito dall'implementazione. È quasi sempre un tipo integrale e firmato. Su Unix e sui moderni sistemi MacOS sono secondi dal 1970, e per compatibilità penso che potrebbe essere usato in questo modo anche su Windows. Tende ad essere 32 bit. Mettendo tutto insieme, in genere può rappresentare date tra il 13 dicembre 1901 e il 18 gennaio, 2038.
E infatti quando ho cambiato la linea tm_year
nel codice per
referenceDateComponent.tm_year = 60;
il codice ha funzionato e stampato 1.721.200,226 mila , che è circa 19921 giorni o 54,5 anni, che è esattamente la differenza tra il 31 dicembre 1960 e oggi.
Ma se si imposta tm_year
in modo negativo, si chiederebbe una data prima del 1900, e non funzionerà con la definizione tipica di time_t
di cui abbiamo discusso.
(È vero che ci sono altre possibilità per time_t
. Potrebbe essere in virgola mobile.Potrebbe essere unsigned invece di firmato.Potrebbe essere un tipo a 64-bit, il che significa che avrebbe una gamma di quasi 600.000.000.000 anni, che è incidentalmente più di un 32-bit tm_year
può contenere.)
Quindi anche se ci sono molti oppositori qui che ti dicono di non farlo, e anche se ci sono certamente molte difficoltà oscure che hanno a che fare con fusi orari e secondi e calendari bisestili altro rispetto a Gregorian, di solito è meglio usare time_t
per fare calcoli matematici di base per le date nel 20 ° secolo e in questo secolo fino al 2038, quando il famigerato "Y2.038K problem" sta per colpire. (Sarà, temo, un po 'peggiore del non così infame Y2K problem, ma questa è un'altra storia.)
Come ho già detto, il tuo codice ha funzionato per me per date precedenti al 1970. Ecco cosa consiglierei di usare per semplici calcoli time_t
data basati (e con avvertimenti come già detto):
time_t makedate(int year, int month, int day)
{
struct tm tm = {0};
tm.tm_hour = 12;
tm.tm_min = tm.tm_sec = 0;
tm.tm_year = year - 1900;
tm.tm_mon = month - 1;
tm.tm_mday = day;
tm.tm_isdst = -1;
return mktime(&tm);
}
int main()
{
long int d = difftime(makedate(2015, 7, 17), makedate(2015, 6, 1));
printf("%ld sec = %ld days = %.2f years\n", d, d/86400, d/86400./365.25);
d = difftime(makedate(2015, 7, 17), makedate(2014, 7, 17));
printf("%ld sec = %ld days = %.2f years\n", d, d/86400, d/86400./365.25);
d = difftime(makedate(1975, 7, 17), makedate(1965, 7, 17));
printf("%ld sec = %ld days = %.2f years\n", d, d/86400, d/86400./365.25);
d = difftime(makedate(1950, 1, 11), makedate(1925, 1, 1));
printf("%ld sec = %ld days = %.2f years\n", d, d/86400, d/86400./365.25);
d = difftime(makedate(2030, 12, 31), makedate(2025, 12, 31));
printf("%ld sec = %ld days = %.2f years\n", d, d/86400, d/86400./365.25);
}
Proprio come il tuo codice, questo sfrutta la sorprendentemente potente funzione di mktime
, e può fare tutto ciò che può fare. Gestisce gli anni bisestili, nessun problema. Non gestisce i secondi bisestili o le modifiche del calendario.
E se, come dici tu, ti interessano le date prima del 1900, temo che tu non abbia fortuna. time_t
semplicemente non può rappresentare quelle date sulla maggior parte dei sistemi, quindi dovrai perseguire qualche altra soluzione.
Puoi migliorare il tuo titolo? Non descrive la tua domanda in alcun modo utile. –
Qual è il caso d'uso effettivo per una data precedente al 1900 sul computer? È il compleanno di una persona molto anziana, o peggio di quella ... Transizione gregoriana/giuliana avvenuta nel XX secolo in Russia. Quindi ** modifica la tua domanda ** per dare contesto e motivazione e ulteriori spiegazioni –
[Questo non è affatto semplice] (https://www.youtube.com/watch?v=-5wpm-gesOY). – nwp