2015-08-03 33 views
5

Dostaję dwie daty (z których jedna jest obecna) i trzeba znaleźć różnicę między nimi. Mój kod daje mi złe wyniki (czasami nawet ujemne).Znajdź dokładną różnicę między dwoma (Joda Time) obiektów DateTime w java

Próbowałem korzystać z klas miesięcy, dni, sekund, godzin i lat i odpowiednie między metodami bez powodzenia.

Edytuj: Powróciłem do mojego oryginalnego kodu, ale bez czasu trwania. @Basil Bourque opublikował świetne rozwiązanie, ale po prostu nie mam wystarczającego doświadczenia z Periods/Duration i wszystkiego, aby dynamicznie formatować z nich.

Rozwiązanie

public static String formattedTime(DateTime d){ 
    DateTime present = new DateTime(Calendar.getInstance()); 

    //dont really want to deal with WHY its 7hrs ahead. o well 
    DateTime date = d.minusHours(7); 

    int diff = Seconds.secondsBetween(date,present).getSeconds(); 
    String postfix = "s"; 
    Log.i("time", "" + diff); 

    if(diff>59){ 
     diff = Minutes.minutesBetween(date, present).getMinutes(); 
     postfix = "s"; 
     if(diff>59){ 
      diff = Hours.hoursBetween(date, present).getHours(); 
      postfix = "hr"; 
      if(diff>1) 
       postfix+="s"; 
      if(diff>23){ 
       diff = Days.daysBetween(date, present).getDays(); 
       postfix = "d"; 
       if(diff>6){ 
        diff = Weeks.weeksBetween(date, present).getWeeks(); 
        postfix = "wk"; 
        if(diff>1) 
         postfix+="s"; 
        if(diff>3){ 
         diff = Months.monthsBetween(date, present).getMonths(); 
         postfix = "m"; 
         if(diff>11){ 
          diff = Years.yearsBetween(date, present).getYears(); 
          postfix = "yr"; 
          if(diff>1) 
           postfix+="s"; 
         } 
        } 
       } 
      } 
     } 
    } 
    return diff+postfix; 
} 
+0

Właśnie sobie sprawę, że serwer jest w innej strefie czasowej. zaktualizuje się wkrótce, kiedy rozliczę się z tego – Zach

Odpowiedz

5

Pracujesz za mocno. Używasz niewłaściwej klasy do swojego celu.

Period Klasa

W Joda-Time, użyć klasy Period kiedy chcesz reprezentować okres czasu jako liczbę lat, miesięcy, dni, godzin, minut, sekund. Czas Joda reprezentuje rozpiętość czasu na jeden z trzech sposobów: Interval, Duration lub Period.

Joda-Time stosuje standard ISO 8601 do analizowania i generowania reprezentacji ciągów wartości daty i godziny. W przypadku okresu oznacza to format PnYnMnDTnHnMnS, w którym P oznacza początek, podczas gdy T oddziela część rok-miesiąc-dzień od części minuta-godzina-godzina. Pół godziny to PT30M. P3Y6M4DT12H30M5S oznacza "trzy lata, sześć miesięcy, cztery dni, dwanaście godzin, trzydzieści minut i pięć sekund". Szukaj StackOverflow.com, aby uzyskać więcej informacji i przykładów.

Spójrz na klasy PeriodFormatter i PeriodFormatterBuilder, jeśli chcesz ładnie drukować za pomocą słów.

Możesz również poprosić obiekt Period o różne numery komponentów, jeśli potrzebujesz liczb całkowitych.

Strefa czasowa

Należy również określić strefę czasową. Jeśli zostanie pominięty, domyślna domyślna strefa czasowa maszyny JVM zostanie zastosowana niejawnie. Lepiej wyraźnie określić strefę czasową, której pragniesz/oczekujesz.

Zawsze używaj proper time zone names, nigdy 3-4 literowych kodów. Kody te nie są ani znormalizowane, ani unikalne. I dalej mylą kwestię czasu letniego (DST).

Ponadto często serwery są przechowywane w strefie czasowej UTC. Zwykle najlepiej zrobić prawie całą logikę biznesową, przechowywanie danych, wymianę danych i logowanie w UTC.

Przykładowy kod

pamiętać, że można poprosić DateTime dla bieżącej chwili bez angażowania obiekt java.util.Date (jak widać w pytaniu).

Przykładowy kod okresu.

DateTimeZone zone = DateTimeZone.forID("America/Detroit") ; 
DateTime then = new DateTime(yourJUDate , zone) ; 
DateTime now = DateTime.now(zone) ; 
Period period = new Period(then , now) ; 
+0

To wygląda ładnie dobrze, ale niestety nie jestem pewien, jak poprawnie używać formatera. Myślę, że twoja odpowiedź jest świetna, ale należy również zauważyć, że z różnicą jednego dnia, getSeconds zwróci 0. Ponadto, formater wydaje się nieco ograniczony z konieczności zdefiniowania jednego specjalnie na lata .. ale co, jeśli różnica daty nie jest rok? Potrzebowałoby to przypadków. Skończyło się na tym, że ponownie użyłem klas Dni/Sekundy/Godziny i odkryłem, że to data, którą wyszedłem z serwera, który był nieprawidłowy. – Zach

+1

@Zach Czy naprawdę chcesz uzyskać całkowity czas skoku w dużą liczbę sekund? Patrząc na twój kod, wydawało się, że prosiłeś tylko o sumę sekund, aby obliczyć pozostałe granice. Period obsługuje inne granularity, więc nie ma potrzeby na sumę sekund. Ale jeśli naprawdę chcesz całkowite sekundy, zadzwoń do ['period.toStandardSeconds()'] (http://www.joda.org/joda-time/apidocs/org/joda/time/Period.html#toStandardSeconds--) . Przez okres jednego dnia ta metoda da ci 24 * 60 * 60. Jeśli chodzi o formatowanie, jest bardzo potężny, elastyczny i wygodny. Przeczytaj dokument i wyszukaj StackOverflow dla przykładów. –

+0

Myślę, że to ma sens, aby zacząć od jednego końca spektrum jednostek czasu i wybrałem sekundy. Dobrze wiedzieć, ale na pewno spróbuję go zoptymalizować – Zach

0

zrobić dwa ciągi, które porównują siebie, można podzielić go z String # split() metoda, aby dowiedzieć się rok/miesiąc/dzień itp

+0

, podczas gdy to wydaje się być pewnym sposobem na uzyskanie mojego wyniku, szukam czegoś bardziej eleganckiego. Czytałem inne pytania, takie jak moje, gdzie ludzie używali tego samego kodu i osiągali poprawne wyniki, więc nie wolno mi używać Duration right – Zach

1

You można zobaczyć odpowiedź właśnie tutaj: Number of days between two dates i dostosować ją do wybranej jednostki.

+0

W moim poście zauważyłem, że już wypróbowałem klasy Days/Seconds/Hours itp. – Zach