2008-11-04 8 views
8

Program, a następnie wynik. Niech ktoś mi wyjaśni, dlaczego 10 000 000 milisekund od 1 stycznia 1970 roku to 31 listopada 1969 roku. Cóż, proszę wyjaśnić, co jest nie tak z moim założeniem, że pierwszy test powinien dać czas 10 000 000 milisekund od 1 stycznia 1970 roku. Liczby mniejsze niż 10 000 000 ten sam wynik.Java.util.Calendar - milliseconds od 1 stycznia 1970

public static void main(String[] args) { 

    String x = "10000000"; 
    long l = new Long(x).longValue(); 
    System.out.println("Long value: " + l); 

    Calendar c = new GregorianCalendar(); 
    c.setTimeInMillis(l); 
    System.out.println("Calendar time in Millis: " + c.getTimeInMillis()); 

    String origDate = c.get(Calendar.YEAR) + "-" + c.get(Calendar.MONTH) + "-" + c.get(Calendar.DAY_OF_MONTH); 
    System.out.println("Date in YYYY-MM-DD format: " + origDate); 

    x = "1000000000000"; 
    l = new Long(x).longValue(); 
    System.out.println("\nLong value: " + l); 

    c.setTimeInMillis(l); 
    System.out.println("Calendar time in Millis: " + c.getTimeInMillis()); 

    origDate = c.get(Calendar.YEAR) + "-" + c.get(Calendar.MONTH) + "-" + c.get(Calendar.DAY_OF_MONTH); 
    System.out.println("Date in YYYY-MM-DD format: " + origDate); 
} 

wartość Long: 10000000

czas Kalendarz Millis: 10000000

Data w formacie RRRR-MM-DD Format: 1969-11-31

Długi wartość: 1000000000000

Czas kalendarza w Millis: 1000000000000

Data w formacie YYYY-MM-DD: 2001-8-8

Odpowiedz

12

daty drukowania z Calendar są lokalne do swojej strefy czasowej , podczas gdy epokę definiuje się na północ od 1970-01-01 w UTC. Więc jeśli mieszkasz w strefie czasowej na zachód od UTC, twoja data pojawi się jako 1969-12-31, mimo że (w UTC) nadal jest 1970-01-01.

+2

Dzięki! Myślałem, że zwariowałem. –

0

można dowiedzieć się, jeśli zmienisz pierwszy c.setTimeInMillis(l); w c.clear();

6

Najpierw c.get (Calendar.MONTH) zwraca 0 dla stycznia, 1 dla lutego, itp

drugie, korzystanie dateformat dat wyjściowych.

Po trzecie, twoje problemy są doskonałym przykładem tego, jak niezręczny jest interfejs API Data Java. Jeśli możesz, skorzystaj z interfejsu API Joda Time. Ułatwi ci to życie.

Oto lepszy przykład kodu, który wskazuje strefę czasową:

public static void main(String[] args) { 

    final DateFormat dateFormat = SimpleDateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL); 

    long l = 10000000L; 
    System.out.println("Long value: " + l); 
    Calendar c = new GregorianCalendar(); 
    c.setTimeInMillis(l); 
    System.out.println("Date: " + dateFormat.format(c.getTime())); 

    l = 1000000000000L; 
    System.out.println("\nLong value: " + l); 
    c.setTimeInMillis(l); 
    System.out.println("Date: " + dateFormat.format(c.getTime())); 
} 
+0

Bardzo pomocny; odpowiedziałeś na moje pytanie nieco pośrednio. Ta strefa czasowa sprawiała mi najwięcej zamieszania.Ulepszony kod jest bardzo doceniany. –

5

Calendar#setTimeInMillis() ustawia czas kalendarza do liczby milisekund po 1 stycznia 1970 GMT.

Calendar#get() zwraca żądane pola dostosowane do strefy czasowej kalendarza, który domyślnie jest używanego urządzenia lokalna strefa czasowa.

To powinno działać jak można się spodziewać, jeśli określenie „GMT” strefę czasową podczas konstruowania Kalendarz:

Calendar c = new GregorianCalendar(TimeZone.getTimeZone("GMT")); 
+0

Dzięki za przykład kodu. –

1

Twoja strefa czasowa jest najprawdopodobniej opóźnione GMT (np GMT-5), w związku z 10,000,000ms epoka jest 31 grudnia 1969 w strefie czasowej, ale od miesięcy są oparte na zera w java.util.Calendar kalendarza-> konwersji tekstu jest błędne i otrzymasz 1969-11-31 zamiast oczekiwanego 1969-12-31.

3

Niestety, java.util.Date i java.util.Calendar były źle zaprojektowane, prowadząc do tego rodzaju zamieszania.