2010-07-22 9 views
11

Ich habe eine JodaTime-Periode, die ich aus zwei DateTime-Zeitpunkten erstellt habe. Gibt es eine gute Möglichkeit, diesen Zeitraum in eine Dezimalzahl von Stunden zu konvertieren?Gibt es eine Möglichkeit, eine JodaTime-Periode in eine Dezimalzahl von Stunden zu konvertieren?

Zum Beispiel habe ich einen Zeitraum, der am 1. Januar 2010 von 13.00 bis 13.30 Uhr geht. Wie kann ich diesen Zeitraum als 1.5 Stunden erhalten.

In der Vergangenheit habe ich umgewandelt manuell Sekunden und BigDecimals wie dies mit:

int seconds = myPeriod.toStandardSeconds().getSeconds(); 
BigDecimal d = new BigDecimal((double) seconds/3600); 
// Round to two decimals 
BigDecimal correctResult = d.setScale(2, RoundingMode.HALF_DOWN); 

Diese Art der fühlt sich an wie ein Hack, nicht umständlich zu erwähnen, wenn ich zusammen Zugabe Zeiten beginnen. Es scheint, als sollte es einen besseren Weg geben.

Irgendwelche Ideen? Dank

+1

Sie sollten "doppelt" vermeiden. Dein allgemeiner Ansatz ist richtig, erhalte nur Sekunden in einem BigDecimal und dividiere ihn dann mit BigDecimal.valueOf (3600), anstatt eine Doppelbesetzung zu durchlaufen. In diesem Fall macht es vielleicht keinen großen Unterschied, aber es ist eine gute Übung. –

Antwort

14

Wenn Sie zwei Datetime haben, würde ich erwarten, dass Sie eine Duration zwischen ihnen haben, anstatt eine Period ... aber anders als das und Kommentare von Mike, das sieht richtig:

private static final BigDecimal SECONDS_PER_HOUR = 
    BigDecimal.valueOf(DateTimeConstants.SECONDS_PER_HOUR); 
... 
DateTime dt1 = ...; 
DateTime dt2 = ...; 
Duration duration = new Duration(dt1, dt2); 
BigDecimal result = BigDecimal.valueOf(duration.toStandardSeconds().getSeconds()) 
           .divide(SECONDS_PER_HOUR) 
           .setScale(2, RoundingMode.HALF_DOWN); 

Beachten Sie, dass die toStandardSeconds().getSeconds() mit Duration.getMillis() stattdessen vermeiden:

private static final BigDecimal MILLIS_PER_HOUR = 
    BigDecimal.valueOf(DateTimeConstants.MILLIS_PER_HOUR); 
... 
DateTime dt1 = ...; 
DateTime dt2 = ...; 
Duration duration = new Duration(dt1, dt2); 
BigDecimal result = BigDecimal.valueOf(duration.getMillis()) 
           .divide(MILLIS_PER_HOUR) 
           .setScale(2, RoundingMode.HALF_DOWN); 
2

Ein bisschen alt, aber ich war zu dieser Suche vor kurzem und Sie können die DateTimeFormatterBuilder, dies zu tun. Es hat eine Reihe von Methoden namens appendFraction..., die einen Bruchteil einer Stunde, Minute, Sekunde etc. anhängen werden.

Dies ist nicht genau das, was Sie gefragt haben, wie Sie eine Period verwendet haben, aber Sie können dies umgehen, indem Sie eine neue DateTime um Mitternacht.

Dieser Formatierer sollte Ihr Datetime analysieren:

DateTimeFormatter formatter = new DateTimeFormatterBuilder() 
    .appendHourOfDay(1) 
    .appendLiteral(".") 
    .appendFractionOfHour(1, 2).toFormatter(); 

Sie könnten dann so etwas wie dies tun, um Ihre Zeit zu konvertieren:

DateMidnight midnight = new DateTime("2012-12-13T21:39:45.618").toDateMidnight(); 
    LocalTime localTime = new LocalTime(midnight); 
    localTime.plus(period); 
    formatter.print(localTime); 
0

Mit dem Jon Skeet Beispiel: Sie haben eine Non-terminating decimal expansion Exception aus divide BigDecimal divide(MILLIS_PER_HOUR), zur Behebung des Fehlers alter Code dafür:

private static final BigDecimal MILLIS_PER_HOUR = 
    BigDecimal.valueOf(DateTimeConstants.MILLIS_PER_HOUR); 




    DateTime t = new DateTime(); 
    DateTime t1 = new DateTime(); 
    DateTime dt1 = t; 
    DateTime dt2 = t1.plusMinutes(46); 
    Duration duration = new Duration(dt1, dt2); 
    BigDecimal result = BigDecimal.valueOf(duration.getMillis()) 
          .divide(MILLIS_PER_HOUR, 2, RoundingMode.CEILING) // <--- Add scale and RoundingMode.CEILING 
          .setScale(2); 
Verwandte Themen