如何将Joda图书馆的DateTime舍入到最近的X分钟?

时间:2012-06-27 08:34:41

标签: java datetime jodatime

如何将DateTime图书馆Joda舍入到最近的X分钟? 例如:

X = 10 minutes
Jun 27, 11:32 -> Jun 27, 11:30
Jun 27, 11:33 -> Jun 27, 11:30
Jun 27, 11:34 -> Jun 27, 11:30
Jun 27, 11:35 -> Jun 27, 11:40
Jun 27, 11:36 -> Jun 27, 11:40
Jun 27, 11:37 -> Jun 27, 11:40

6 个答案:

答案 0 :(得分:30)

接受的答案无法正确处理设置了秒或毫秒的日期时间。为了完整起见,这是一个正确处理的版本:

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

答案 1 :(得分:17)

使用纯DateTime(Joda)Java库:

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

答案 2 :(得分:8)

我曾经攻击过这种方法来做类似的事情。它没有以任何方式进行优化,但它确实做了我想要的。从未在任何生产环境中制造过,我无法告诉你有关性能的任何信息。

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

    }

答案 3 :(得分:8)

这是另一种在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

答案 4 :(得分:6)

当你想要围绕Joda DateTime时,最佳解决方案是使用内置的roundHalfCeilingCopyroundHalfFloorCopy方法:

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

请注意roundHalfCeilingCopy如果中途停止上限,我们会支持上限。您可以使用roundHalfFloorCopy以便在中途停留时支持发言权。

答案 5 :(得分:1)

我有一个LocalTime类的函数,但我认为很容易为您的案例采用我的示例:

(科特琳·朗)

webClient.addWebWindowListener(new WebWindowListener() {

    @Override
    public void webWindowContentChanged(WebWindowEvent arg0) {
        if (CSVclicked) {           //boolean that is set true when I click the download button...
            String CSV = arg0.getWebWindow().getEnclosedPage().getWebResponse().getContentAsString();

            //do things...

            CSVclicked = false; //don't use the same behavior next time the method is called...
        }
    }
});

和用法:

/// Global options. These options are neither stored nor read from
 /// configuration files.
 struct ClangTidyGlobalOptions {
   /// Output warnings from certain line ranges of certain files only.
   /// If empty, no warnings will be filtered.
   std::vector<FileFilter> LineFilter;
 };