2013-05-07 14 views
9
package check; 

import java.util.Calendar; 

public class Test { 
    public static void main(String[] args) { 
     // length of a day 
     long DAY_MILLIS = 1000 * 60 * 60 * 24; 

     Calendar cal = Calendar.getInstance(); 

     cal.set(1900, 0, 1, 0, 0, 0); 
     System.out.println(cal.getTime()); 

     cal.setTimeInMillis(cal.getTimeInMillis() + DAY_MILLIS); 
     System.out.println(cal.getTime()); 
    } 
} 

Ed è risultato è:30 minuti errore in Java calcolo della data in 1900 solo

Mon Jan 01 00:00:00 KST 1900 
Mon Jan 01 23:30:00 KST 1900 // Where is 30 minutes here? 

maggior parte divertente e indizio importante è che questo problema si verifica quando l'anno è solo 1.900.

+1

possibilmente correlate al [questa domanda] (http://stackoverflow.com/q/6841333/732016)? – wchargin

+0

Definitivamente correlati. Lo stesso problema di base ... il tempo è complicato. –

+0

Ho provato questo e ottengo 'Tue Gen 02 00:00:00 EST 1900'.Qualcosa che ha a che fare con i fusi orari? –

risposta

3

Questo a causa delle variazioni storiche di spostamento GMT. Guarda un esempio qui http://www.timeanddate.com/worldclock/timezone.html?n=101&syear=1900. Queste modifiche sono diverse per diversi fusi orari. Per esempio nel mio fuso orario (EET) il risultato del test è diverso:

Mon Jan 01 00:00:00 EET 1900 
Mon Jan 01 23:39:52 EET 1900 

perché (secondo Java) gli orologi sono stati trasformati in avanti 0:20:08 ore il 1 gen 1900 a EET. TimeZone ha metodi per determinare compensare per una data particolare, TimeZone.getOffset (lunga data) API

Questo metodo restituisce un valore storicamente corretta compensazione se un sottostante sottoclasse implementazione TimeZone supporta calendario storico ora legale e GMT Offset modifiche.

Si noti che se si imposta Calendario su GMT e si stampa il risultato in GMT non si verificherà alcun errore.

SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
    df.setTimeZone(TimeZone.getTimeZone("GMT")); 
    Calendar cal = Calendar.getInstance(); 
    cal.setTimeZone(TimeZone.getTimeZone("GMT")); 
    cal.set(1900, 0, 1, 0, 0, 0); 
    System.out.println(df.format(cal.getTime())); 
    cal.setTimeInMillis(cal.getTimeInMillis() + 1000 * 60 * 60 * 24); 
    System.out.println(df.format(cal.getTime())); 

uscita

1900-01-01 00:00:00 
1900-01-02 00:00:00 
3

Tali irregolarità nelle date di elaborazione sono comuni. Vedi per es. Jon Skeet's most famous answer. Sto cercando il database attuale di questi difetti; aggiornerà la risposta quando trovata.

Questa risposta è abbastanza incompleta, ma potrebbe essere sufficiente per farti scollare; Lo lascerò ma ti incoraggio ad accettarne uno più completo se pubblicato.

+0

Wow epic fun Skeet risposta. –

0
public static void main(String[] args) { 
     // length of a day 
     long DAY_MILLIS = 1000 * 60 * 60 * 24; 

     Calendar cal = Calendar.getInstance(); 

     cal.set(1900, 0, 1, 0, 0, 0); 
     System.out.println(cal.getTime()); 
     System.out.println(cal.getTimeInMillis()); 
     System.out.println(DAY_MILLIS); 
     System.out.println(cal.getTimeInMillis() + DAY_MILLIS); 
     cal.setTimeInMillis(cal.getTimeInMillis() + DAY_MILLIS); 
     System.out.println(cal.getTime()); 
    } 

Mon 1 gennaio 00:00:00 CST 1900

-2209017599564

-2208931199564

mar 2 gennaio 1900 00:05:52 CST

Sembra che .getTimeInMillis() restituisca un valore diverso da quello che ci si aspetta.

getTimeInMillis

getTimeInMillis lunghi pubblici()

restituisce il valore di tempo di questo calendario in millisecondi.

Ritorni: l'ora corrente come millisecondi UTC dall'epoca.

Problemi correlati