web-dev-qa-db-ja.com

JodaライブラリのDateTimeを最も近いX分に丸める方法は?

DateTimeライブラリのJodaを最も近いX分に丸める方法は?
例えば:

X = 10分
 6月27日11:32-> 6月27日11:30 
 6月27日11:33-> 6月27日11:30 
 6月27日11:34-> 6月27日、11:30 
 6月27日、11:35-> 6月27日、11:40 
 6月27日、11:36-> 6月27日、11:40 
 6月27日11:37-> 6月27日11:40 
26
Michael

受け入れられた回答は、秒またはミリ秒が設定されている日時を正しく処理しません。完全を期すために、これを正しく処理するバージョンを次に示します。

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);
}
30
Mark Byers

純粋な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()
    );
17
vladaman

私はかつてこの方法をハッキングして、そのようなことをしました。それは決して最適化されていませんが、当時私が望んでいたことを行いました。本番環境でこれを作成したことはありません。パフォーマンスについては何も言えません。

@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);
        }

    }
9
Scorpio

完全を期すために、Unix時間で算術を使用する別のアプローチを次に示します。

(Scalaで実装されています)

import org.joda.time.{DateTime, Duration}

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

使用例:

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
8
qerub

丸めたい場合 Joda DateTime 最良の解決策IMHOは、組み込みのroundHalfCeilingCopyおよびroundHalfFloorCopyメソッドを使用することです。

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

中途半端な場合、roundHalfCeilingCopyは天井を優先することに注意してください。フロアが途中の場合に備えて、roundHalfFloorCopyを使用してフロアを優先できます。

6
Johnny