2011-12-19 14 views
11

Ho visto molte visualizzazioni diverse, quindi ho pensato di chiedere qui.mktime e tm_isdst

Ho letto man mktime:

(A positive or zero value for tm_isdst causes mktime() to presume initially 
that summer time (for example, Daylight Saving Time) is or is not in 
effect for the specified time, respectively. A negative value for 
tm_isdst causes the mktime() function to attempt to divine whether summer 
time is in effect for the specified time. 

La mia domanda è, non dovrebbe tm_isdst essere tenuti come -1 per consentire al sistema di decidere se dst o no e in questo modo il codice diventa dst agnostica?

mi manca qualcosa?

risposta

5

Credo che il motivo originale sia che alcuni fusi orari non hanno l'ora legale. Dato che mktime non è asincrono sicuro e non rientra, l'implementazione consente di memorizzare il valore corrente dell'ora legale nel POSIX extern char tzname [2], indicizzato dalla luce diurna [0 o 1]. Questo significa tzname [0] = "[STD nome TZ]" e tzname = "[luce nome TZ, ad esempio EDT]"

vedere la vostra pagina man tzset() per maggiori informazioni su questo. Gli standard conformi a mktime() devono comportarsi come se chiamassero tzset() in ogni caso. Questo tipo di ovvia l'uso di tm_isdst, IMO.

Bottom line: la tua particolare implementazione e il/i timezone/i imporranno l'utilizzo di -1, 0 o 1 per tm_isdst. Non esiste un modo corretto predefinito per tutte le implementazioni.

7

È consigliabile evitare l'impostazione di tm_isdst su -1 se possibile. Il sistema non può sempre determinare lo stato dell'ora legale dalla data e dall'ora. È ambigua l'ora prima e dopo la fine dell'ora legale. Ad esempio, se si passa mktime() 1:30 AM 4 novembre 2012, non sono sufficienti informazioni per ottenere un valore time_t corretto da mktime(). Di solito ho visto mktime() assumere un tempo standard nel caso in cui sia ambiguo, ma non ho visto alcuna documentazione che garantisca questo comportamento su tutte le piattaforme. 1:30 del 4 novembre 2012 con tm_isdst == 1 sarà 1 ora prima, perché l'ora 1:00:00 alle 1:59:59 si ripete.

#include <stdio.h> 
#include <time.h> 

int main() 
{ 
    time_t daylight, standard; 
    struct tm timestr; 
    double diff; 

    timestr.tm_year = 2012 - 1900; 
    timestr.tm_mon = 11 - 1; 
    timestr.tm_mday = 4; 
    timestr.tm_hour = 1; 
    timestr.tm_min = 30; 
    timestr.tm_sec = 0; 

    /* first with standard time */ 
    timestr.tm_isdst = 0; 
    standard = mktime(&timestr); 

    /* now with daylight time */ 
    timestr.tm_isdst = 1; 
    daylight = mktime(&timestr); 

    diff = difftime(standard, daylight); 

    printf("Difference is %f hour(s)", diff/60.0/60.0); 

    return 0; 
} 

Questo produce:

Difference is 1.000000 hour(s) 

Entrambi sono 4 November, 2012 1:30, tuttavia entrambi sono due valori time_t distinti, 1 ora di distanza.

mktime() ha essenzialmente 2 uscite:

  • time_t
  • tempo riparato struct

Il tempo struct è sia un ingresso e un'uscita. Viene modificato da mktime() per restituire tutti i membri struct agli intervalli nominali. Ad esempio, se si incrementa il membro tm_hour += 500, ciò significa incrementare il tempo di 500 ore. Il membro tm_hour verrà modificato in un valore da 00 a 59 e tm_day, tm_mday e così via verranno regolati di conseguenza. tm_isdst è anche un input e output. I suoi valori sono i seguenti:

  • 1 (DST in effetti, cioè all'ora legale)
  • 0 (DST non attiva, ossiatempo standard)
  • -1 (Stato sconosciuto DST)

Così mktime() emette un 1 o 0 per tm_isdst, mai -1.

-1 è un possibile input, ma lo considererei come "Sconosciuto". Non pensarlo come "determinare automaticamente", perché in generale, mktime() non può sempre determinarlo automaticamente.

Lo stato DST esplicito (0 o 1) deve provenire da qualcosa di esterno al software, ad esempio memorizzarlo nel file o nel database o richiedere all'utente.

+2

Bene se non si conosce l'ora legale è necessario determinarlo (buona fortuna con quello), o impostarlo su '-1'. Non c'è altra opzione. Se si imposta su 0, non si ottiene affatto l'ora legale, il che è garantito errato, se si imposta su 1 si forza l'ora legale su cui è anche garantito l'errore. – rustyx

+0

@RustyX La codifica dura a -1, 0 o 1 sarà sempre errata. -1 è il meno cattivo, ma ancora cattivo. Lo stato esplicito (0 o 1) deve essere _input_ al software dall'utente o memorizzato nei dati (file o database). Fondamentalmente deve provenire da qualcosa di esterno all'applicazione. –

+0

v buona risposta. Grazie – drlolly