2014-08-28 10 views
17

Quindi sono la fortuna di usare Java 8 e la nuova API tempo, ma non vedo alcuna funzione di arrotondamento ...minuti rotonde al soffitto utilizzando Java 8

In sostanza, se il tempo è ...

2014-08-28T10:01.00.000 ----> 2014-08-28T10:02.00.000 
2014-08-28T10:01.10.123 ----> 2014-08-28T10:02.00.000 
2014-08-28T10:01.25.123 ----> 2014-08-28T10:02.00.000 
2014-08-28T10:01.49.123 ----> 2014-08-28T10:02.00.000 
2014-08-28T10:01.59.999 ----> 2014-08-28T10:02.00.000 

Questo sembra essere ok, ma è giusto?

LocalDateTime now = LocalDateTime.now(Clock.systemUTC()); 
LocalDateTime newTime = now.plusMinutes(1); 

System.out.println(newTime.toString()); 
System.out.println(newTime.format(DateTimeFormatter.ofPattern("yyyy-dd-MM'T'HH:mm:00.000"))); 
+4

La prima riga non dovrebbe essere '10: 01' sulla destra? Una funzione di soffitto non cambierebbe il valore se la parte frazionaria è 0. –

+0

Voglio sempre arrotondare :) – user432024

+2

Un numero tondo non cambia se lo arrotondi. Quello che stai chiedendo è leggermente diverso da una funzione di soffitto. –

risposta

30

Il java.time API non supporta arrotondamento al soffitto, ma lo fa supporto rounding to floor (troncamento) che permette il comportamento desiderato (che non è esattamente arrotondamento al soffitto):

LocalDateTime now = LocalDateTime.now(); 
LocalDateTime roundFloor = now.truncatedTo(ChronoUnit.MINUTES); 
LocalDateTime roundCeiling = now.truncatedTo(ChronoUnit.MINUTES).plusMinutes(1); 

Inoltre, c'è un impianto per ottenere un orologio che zecche solo una volta al minuto, che ti potrebbero interessare:

Clock minuteTickingClock = Clock.tickMinutes(ZoneId.systemDefault()); 
LocalDateTime now = LocalDateTime.now(minuteTickingClock); 
LocalDateTime roundCeiling = now.plusMinutes(1); 

Questo orologio troncherà automaticamente minuti per piano (anche se è specified tale che può restituire un valore memorizzato nella cache ritardata). Si noti che uno Clock può essere memorizzato in una variabile statica, se lo si desidera.

Infine, se si tratta di un'operazione comune che si desidera utilizzare in più posizioni, è possibile scrivere una funzione libreria TemporalAdjuster per eseguire l'arrotondamento. (I regolatori possono essere scritti una volta, testati e resi disponibili come variabili o metodi statici).

+0

Grazie è quello di cui ho bisogno. So che il mio arrotondamento è un po 'strano, ma fondamentalmente ho bisogno di interrogare il mio sistema db basandomi sull'ora corrente.Se ho più utenti che fanno una query entro il minuto corrente con l'arrotondamento posso mettere in cache il filtro! :) – user432024

+0

Questo algoritmo non sarebbe corretto per i minuti esatti. Per esempio. diciamo che l'ora corrente è esattamente di 5 minuti (cioè 0 secondi, 0 nanos, ecc.). In tal caso mi aspetterei che roundCeiling sia di 5 minuti (ad esempio il numero di "1.00" del numero decimale è "1"), ma l'algoritmo dovrebbe fornire 6 minuti. il calcolo roundCeiling sopra dovrebbe controllare se il valore troncato è lo stesso di "now" - in tal caso restituire "now", altrimenti i +1 minuti. –

+1

Anche se ora ho notato che la domanda originale chiede di arrotondare sempre (anche se il numero è già rotondo), quindi la risposta accettata è corretta in quel caso. –

1

java.time (la nuova API volta in Java 8) ha alcun arrotondamento presenta come alcune altre biblioteche. Si tenta di utilizzare la formattazione per arrotondare a livello di stringa. Se si desidera arrotondare gli oggetti di tempo però, allora si può fare questo arrotondamento manualmente:

LocalDateTime now = LocalDateTime.now(Clock.systemUTC()); 
LocalDateTime newTime = now.plusMinutes(1).withSecond(0).withNano(0); 

Tra l'altro, è destinato sicuramente pavimento, non a soffitto, non è vero?

Aggiornamento:

Ho trovato questo modo leggermente migliore per l'impostazione al pavimento (ovviamente la caratteristica unica di arrotondamento, soffitto non è supportato):

LocalDateTime now = LocalDateTime.now(Clock.systemUTC()); 
LocalDateTime newTime = now.plusMinutes(1).truncatedTo(ChronoUnit.MINUTES); 
+0

Voglio dire soffitto, beh voglio arrotondare, indipendentemente se è 10 secondi, 25 secondi o 49 secondi. – user432024

2
LocalDateTime newTime = now.plusMinutes(1).minusNanos(1).withSecond(0).withNano(0); 

Ciò arrotondare al minuto più vicino, fungendo da funzione del soffitto con minuti come la parte intera.

+0

Dov'è la semplificazione? La scrittura di complesse implementazioni 'TemporalAdjuster' dovrebbe in molti casi essere limitata a framework o scrittori di librerie, non a utenti finali. Qui l'onere di scrivere il codice di regolazione è ancora con l'utente. Solo i miei 2 centesimi ... –

+0

@Meno Hochschild: Hai ragione, stavo scavando attraverso java.time per funzionalità rilevanti e finito in modalità di scrittura in libreria. Sicuramente eccessivo per questo problema. –

Problemi correlati