È peggio di così, ci sono anche i "leap seconds", e ogni timestamp ha un'idea diversa di come trattarli. E poi c'è il fatto che la terra man mano rallenta, per cui il "tempo ufficiale" (=orologi atomici+tempo fissato per un anno terrestre) si discosta ogni anno di un qualcosina rispetto al "tempo terrestre". Te l'ho detto, è un pasticcio.
Comunque, l'idea dei mesi se non sbaglio viene dai cicli lunari, per cui volendoli legare a qualcosa si potrebbero fare 13 mesi da 28 giorni e attaccarci un giorno in più l'ultimo mese (due nei bisestili) - vagamente più regolare e più semplice gestire il "caso speciale".
Sono particolarmente sensibile alla questione perché sono rimasto scottato una volta. In uno dei primi programmi fatti per soldi (era una roba di reportistica da dati CSV, fine 2006) da qualche parte il codice doveva sapere quanti giorni c'erano in ogni mese; quindi, all'inizio di una funzione c'era questa roba:
codice:
//Nomi dei mesi
char months[12][4]={"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
//Numero di giorni/mese
unsigned int dpm[12]={31,29,31,30,31,30,31,31,30,31,30,31};
Ora, questa è la versione corretta (tra l'altro, a sette anni di distanza vedo che months poteva essere tranquillamente un const char * [12], ma vabbé), ma nella versione originale mi ero perso per strada giugno, forse perché, prima dell'inizio dell'università, era essenzialmente una zona di non-tempo.
Ho scovato l'errore completamente per caso poco prima che il programma, ormai in versione definitiva, andasse in produzione: mi serviva riciclare quel codice in un altro programma, e mi sono accorto che sfalsava tutti i mesi dopo giugno. Nel programma originale questo dava, tra le altre cose, risultati leggermente sballati per tutte le medie mensili di emissioni per i mesi in questione, ma sballate in modo sufficientemente sottile da non accorgersene a colpo.
La storia insegna tre cose:
- usare librerie già fatte per queste cose in genere è una buona idea;
- chiedere sempre una copertura il più ampio possibile sui dati di test;
- se i mesi mi stanno antipatici c'è un motivo.