2010-07-22 14 views
11

Tengo un período JodaTime que he creado a partir de dos instantes de DateTime. ¿Hay una buena manera de convertir ese Período en un número decimal de horas?¿Alguna manera de convertir un Período JodaTime a un número decimal de horas?

Por ejemplo, tengo un Período que va de la 1pm a la 1:30 pm del 1 de enero de 2010. ¿Cómo puedo obtener ese Período como 1.5 horas.

En el pasado me he convertido manualmente usando segundos y BigDecimals como este:

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

Este tipo de se siente como un corte, por no mencionar incómodo cuando comienzo Períodos sumando. Parece que debería haber una mejor manera.

¿Alguna idea? Gracias

+1

Debe evitar "doble". Su enfoque general es correcto, solo obtenga segundos en un BigDecimal primero y luego divídalo por BigDecimal.valueOf (3600) en lugar de pasar por un doble molde. En este caso, puede que no haya mucha diferencia, pero es una buena práctica. –

Respuesta

14

Si usted tiene dos DateTime, yo esperaría que usted tenga una Duration entre ellos en lugar de un Period ... pero aparte de eso y los comentarios de Mike, que se parece correcta:

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); 
Nota

que se puede evitar el uso de toStandardSeconds().getSeconds()Duration.getMillis() lugar:

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

Un poco viejo, pero yo estaba buscando en este recientemente y se puede utilizar el DateTimeFormatterBuilder para hacer esto. Tiene una serie de métodos llamados appendFraction... que agregarán una fracción de una hora, minuto, segundo, etc.

Esto no es exactamente lo que preguntaba mientras estaba usando un Period, pero puede solucionarlo haciendo un nuevo DateTime a medianoche.

Este formateador debe analizar su DateTime:

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

A continuación, podría hacer algo como esto para convertir su periodo:

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

Utilizando el ejemplo Jon Skeet, tiene una Non-terminating decimal expansion Exception de dividir BigDecimal divide(MILLIS_PER_HOUR), para el error de corrección, alterar el código para esto:

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); 
Cuestiones relacionadas