Wie richte ich DateTime der Joda-Bibliothek auf die nächsten X Minuten?

Wie DateTime der Joda Bibliothek auf die nächsten X Minuten?
Beispielsweise:

  X = 10 Minuten
 27. Juni, 11:32 -> 27. Juni, 11:30 Uhr
 27. Juni, 11:33 -> 27. Juni, 11:30 Uhr
 27. Juni, 11:34 -> 27. Juni, 11:30 Uhr
 27. Juni, 11:35 -> 27. Juni, 11:40 Uhr
 27. Juni, 11:36 -> 27. Juni, 11:40 Uhr
 27. Juni, 11:37 -> 27. Juni, 11:40

Die angenommene Antwort verarbeitet Datumswerte, die Sekunden oder Millisekunden festgelegt haben, nicht korrekt. Der Vollständigkeit halber ist hier eine Version, die das richtig behandelt:

 private DateTime roundDate(final DateTime dateTime, final int minutes) { if (minutes < 1 || 60 % minutes != 0) { throw new IllegalArgumentException("minutes must be a factor of 60"); } final DateTime hour = dateTime.hourOfDay().roundFloorCopy(); final long millisSinceHour = new Duration(hour, dateTime).getMillis(); final int roundedMinutes = ((int)Math.round( millisSinceHour / 60000.0 / minutes)) * minutes; return hour.plusMinutes(roundedMinutes); } 

Verwenden der reinen DateTime (Joda) Java Library:

 DateTime dt = new DateTime(1385577373517L, DateTimeZone.UTC); // Prints 2013-11-27T18:36:13.517Z System.out.println(dt); // Prints 2013-11-27T18:36:00.000Z (Floor rounded to a minute) System.out.println(dt.minuteOfDay().roundFloorCopy()); // Prints 2013-11-27T18:30:00.000Z (Rounded to custom minute Window) int windowMinutes = 10; System.out.println( dt.withMinuteOfHour((dt.getMinuteOfHour() / windowMinutes) * windowMinutes) .minuteOfDay().roundFloorCopy() ); 

Ich habe einmal diese Methode gehackt, um so etwas zu tun. Es ist in keiner Weise optimiert, aber es hat getan, was ich damals wollte. Nie in irgendeiner Produktionsumgebung, und ich kann Ihnen nichts über performance sagen.

 @Test public void test() { System.out.println(roundDate(new DateTime().withMinuteOfHour(13))); System.out.println(roundDate(new DateTime().withMinuteOfHour(48))); System.out.println(roundDate(new DateTime().withMinuteOfHour(0))); System.out.println(roundDate(new DateTime().withMinuteOfHour(59))); System.out.println(roundDate(new DateTime().withMinuteOfHour(22))); System.out.println(roundDate(new DateTime().withMinuteOfHour(37))); } private DateTime roundDate(final DateTime dateTime) { final double minuteOfHour = dateTime.getMinuteOfHour(); final double tenth = minuteOfHour / 10; final long round = Math.round(tenth); final int i = (int) (round * 10); if (i == 60) { return dateTime.plusHours(1).withMinuteOfHour(0); } else { return dateTime.withMinuteOfHour(i); } } 

Hier ist ein weiterer Ansatz, der Arithmetik für die Unix-Zeit verwendet:

(In Scala zur besseren Übersicht implementiert.)

 import org.joda.time.{DateTime, Duration} def roundDateTime(t: DateTime, d: Duration) = { t minus (t.getMillis - (t.getMillis.toDouble / d.getMillis).round * d.getMillis) } 

Beispielverwendung:

 roundDateTime(new DateTime("2013-06-27T11:32:00"), Duration.standardMinutes(10)) // => 2013-06-27T11:30:00.000+02:00 roundDateTime(new DateTime("2013-06-27T11:37:00"), Duration.standardMinutes(10)) // => 2013-06-27T11:40:00.000+02:00 

Wenn Sie Joda DateTime runden möchten, ist die beste Lösung IMHO, die roundHalfFloorCopy Methoden roundHalfCeilingCopy und roundHalfFloorCopy verwenden:

 DateTime dateTime = DateTime.now(); DateTime newDateTime = dateTime.minuteOfHour().roundHalfCeilingCopy(); 

Bitte beachten Sie, dass roundHalfCeilingCopy die Decke auf halbem Weg bevorzugt. Sie können roundHalfFloorCopy um den Boden zu bevorzugen, wenn es halbwegs ist.