2012-03-05 10 views
6

Ho letto in due corde con un anno, il giorno giuliano (giorno dell'anno), ora, minuto e un'osservazione.Perché mktime() sta cambiando il giorno dell'anno della mia struttura tm?

ho tirare le variabili rilevanti utilizzando sscanf:

sscanf(tide_str1.c_str(), "%d %d %d %d %Lf", &y1, &j1, &h1, &m1, &obs1); 
sscanf(tide_str2.c_str(), "%d %d %d %d %Lf", &y2, &j2, &h2, &m2, &obs2); 

Per questo particolare insieme di dati, i valori sono 2011 083 23 22 1,1

poi creare e popolare una struttura tm, e corro mktime , con chiamate cout nel giorno intermedio e passa da 083 a 364.

int y1=2011, j1=83, h1=23, m1=22; 
struct tm time_struct = {0, 0, 0, 0, 0, 0, 0, 0, 0}, *time_ptr = &time_struct; 
time_t tv_min; 
time_struct.tm_year = y1 - 1900; 
time_struct.tm_yday = j1; 
cout << time_struct.tm_yday << endl; 
time_struct.tm_hour = h1; 
time_struct.tm_min = m1; 
time_struct.tm_isdst = -1; 
cout << time_struct.tm_yday << endl; 
tv_min = mktime(time_ptr); 
cout << time_struct.tm_yday << endl; 

Perché è così? È perché il tm_mday e il tm_mon sono impostati su 0? Inizialmente ho provato a non inizializzare tutto a zero, ma poi mktime ha restituito -1. Cosa dovrei fare in modo diverso se conosco solo il giorno dell'anno e non il mese e il giorno del mese?

+0

Il giorno dell'anno è a volte in modo non corretto * * indicato come un "Giorno Giuliano". In realtà, un numero [Julian Day] (http://en.wikipedia.org/wiki/Julian_day) è il numero di giorni dal 1 ° gennaio 4713 aC; è usato in astronomia. –

+0

Sì, ma è così ampiamente usato (erroneamente) all'interno di determinate professioni da essere, in pratica, corretto. Finché tutti all'interno di un campo usano lo stesso jargin ... la comunicazione avviene. – RuQu

risposta

13

mktime() sta facendo quello che dovrebbe fare.

Citando lo standard C:

La funzione mktime converte il tempo in panne, espressa come ora locale, nella struttura puntata da timeptr in un valore temporale calendario con la stessa codifica di quella dei valori restituiti da la funzione tempo. I valori originali di tm_wday e tm_yday componenti della struttura vengono ignorati ei valori originali degli altri componenti non sono limitati agli intervalli indicati in precedenza. In caso di successo, i valori della tm_wday e tm_yday componenti della struttura sono impostati in modo appropriato, e gli altri componenti sono impostati per rappresentare il tempo calendario specificato, ma con i loro valori forzati alle gamme sopra indicati; il valore finale di tm_mday non è impostato fino a quando tm_mon e tm_year sono determinati.

mktime() può calcolo i valori di tm_mday e tm_yday dagli altri membri; non è progettato per calcolare i valori degli altri membri da quei campi.

Ciò che è possibile fare, tuttavia, è inizializzare uno struct tm con valori fuori intervallo. Ad esempio, se si desidera che tm_yday sia 200 (il 200 ° giorno dell'anno), è possibile inizializzare uno struct tm che rappresenta il 200 ° giorno di gennaio. mktime() verrà quindi normalizzato alla data corretta, fornendo un valore time_t che è possibile quindi alimentare a gmtime() o localtime().

Ecco un semplice esempio:

#include <iostream> 
#include <ctime> 

int main() 
{ 
    struct tm t = { 0 }; 
    t.tm_sec = t.tm_min = t.tm_hour = 0; // midnight 
    t.tm_mon = 0;      // January 
    t.tm_year = 2012 - 1900; 
    t.tm_isdst = -1;      // unknown 

    t.tm_mday = 200;      // January 200th? 

    time_t when = mktime(&t); 
    const struct tm *norm = localtime(&when); // Normalized time 

    std::cout << "month=" << norm->tm_mon << ", day=" << norm->tm_mday << "\n"; 
    std::cout << "The 200th day of 2012 starts " << asctime(norm); 
} 

L'output è:

month=6, day=18 
The 200th day of 2012 starts Wed Jul 18 00:00:00 2012 
+0

Ho provato il tuo consiglio e inizializzato in questo modo: struct tm time_struct = {0, 0, 0, 200, 200, 0, 200, 0, 0} e il risultato quando l'ho richiamato era il giorno 77 quando doveva essere 83, che è più vicino del 364 di prima ma ancora spento. – RuQu

+1

Lo standard non garantisce l'ordine dei membri di 'struct tm', quindi inizializzarlo in quel modo non funzionerà necessariamente. È necessario inizializzare o assegnare tutti i membri per nome. Ma se sono dichiarati nel solito ordine, stai iniziando a 'tm_mday' e 'tm_mon' a 200. Non penso che tu voglia il 200o, o meglio il 201st, il mese dell'anno. (E non dimenticare che 'struct tm' numera i mesi da 0 a 11, non da 1 a 12.) –

+0

Per essere chiari, se voglio l'anno 83, dovrei impostare il mese a 0 e il mese a 83? – RuQu

Problemi correlati