2013-08-16 17 views
18

Czy ktoś mógłby mi wyjaśnić, dlaczego, gdy próbuję uzyskać milisekundy strefy DateTime ze strefą inną niż moja własna, przywraca mi to milisekundę strefy czasowej mojej lokalnej maszyny? Szukam, aby uzyskać milisekund UTC, ale moje lokalne ustawienia aplikacji są ustawione na EST (chociaż jestem naprawdę w Irlandii;))Czas konwersji Jazime czas strefy czasowej na millis

Oto kod:

DateTimeFormatter format = DateTimeFormat.mediumDateTime(); 

    DateTime local = new DateTime(); 
    DateTime utc = new DateTime(System.currentTimeMillis(), DateTimeZone.UTC); 
    System.out.println("utc zone = " +utc.getZone()); 
    System.out.println("UTC time: " + utc); 
    long current = utc.getMillis(); 

    System.out.println("current: " + format.print(current)); 
    System.out.println("local: " + format.print(local.getMillis())); 

Oto co to drukuje:

utc zone = UTC 
UTC time: 2013-08-16T13:36:32.444Z 
current: Aug 16, 2013 9:36:32 AM 
local: Aug 16, 2013 9:36:32 AM 

Obecnie, powinienem pomyśleć, że powinien mieć tę samą datę, co czas UTC?

+0

Twój '' utc' local' i reprezentują te same momenty czasu (tylko z dołączonym różnych strefach czasowych). Dlatego 'getMillis()' (które daje "fizyczny" przedział czasu, który upłynął od "chwili" odpowiadającej epoce unixa), musi zwrócić tę samą wartość. – leonbloy

Odpowiedz

16

Kilka punktów:

  • Nie trzeba zadzwonić System.currentTimeMillis(). Wystarczy przekazać to:
DateTime utc = new DateTime(DateTimeZone.UTC); 
  • Po wywołaniu .getMillis() wynik jest zawsze w UTC. Reprezentowanie czasu jako liczby całkowitej, która nie jest oparta na UTC, jest złym pomysłem, a nie czymś, co zapewni Czas Jody. Twoja ocena, że ​​strefa czasowa ma wpływ na milisekundy, jest nieprawidłowa.

  • Błędy konwersji wynikają z tego, jak dzwonisz pod numer format.print. Po przejściu liczby całkowitej domyślnym zachowaniem jest użycie bieżącej strefy czasowej, którą jest czas lokalny. Można zmienić to tak:

format.withZone(DateTimeZone.UTC).print(current) 
  • Jednakże, jeśli zamiarem jest, aby wydrukować ją jako datę ciąg, dlaczego iść do milisekund pierwszy tak? Jeśli przekażesz oryginał DateTime, informacje o jego strefie czasowej zostaną zastosowane automatycznie.
format.print(utc) 
    format.print(local) 

ułożyła, cała sprawa będzie wyglądać następująco:

DateTime local = new DateTime(); 
DateTime utc = new DateTime(DateTimeZone.UTC); 

System.out.println("local zone = " + local.getZone()); 
System.out.println(" utc zone = " + utc.getZone()); 

DateTimeFormatter format = DateTimeFormat.mediumDateTime(); 
System.out.println(" local: " + format.print(local)); 
System.out.println(" utc: " + format.print(utc)); 
System.out.println("millis: " + utc.getMillis()); 
+5

"Gdy wywołujesz metodę .getMillis(), wynik zawsze jest w UTC" Nie podoba mi się ten sposób umieszczenia go. getMillis zwraca milisekundy od chwili obecnej do epoki Uniksa, bez stref czasowych. – leonbloy

+4

@leonbloy - Właściwie ponieważ czas Joda nie obsługuje sekund przestępnych, wartość nie jest naprawdę * dokładną * liczbą milisekund, które upłynęły. Jest to całkowita reprezentacja chwili w UTC, której nie było żadnych sekund przestępnych. Po prostu technicznie poprawne. Dla wszystkich celów i celów możesz myśleć o nich w dowolny sposób. –