如何将图书馆轮到最近的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
接受的答案不能正确处理设置了秒或毫秒的日期时间。为了完整起见,这里有一个可以正确处理的版本:
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);
}
使用纯 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()
);
我曾经破解过这个方法来做类似的事情。它没有以任何方式进行优化,但它做了我当时想要的。从来没有在任何生产环境中做到过,我不能告诉你任何关于性能的事情。
@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);
}
}
这是另一种在 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
当您想对Joda DateTime进行舍入时,恕我直言,最好的解决方案是使用内置roundHalfCeilingCopy
和roundHalfFloorCopy
方法:
DateTime dateTime = DateTime.now();
DateTime newDateTime = dateTime.minuteOfHour().roundHalfCeilingCopy();
请注意,roundHalfCeilingCopy
如果半途而废,这将有利于天花板。你可以用roundHalfFloorCopy
它来保护地板,以防它在中途。
我有一个 LocalTime 类的功能,但我认为很容易为您的案例采用我的示例:
(科特林语言)
fun LocalTime.round(roundValue: Int): LocalTime {
val timeInMillis = this.millisOfDay
val remainder = timeInMillis % roundValue
return when {
remainder < (roundValue / 2) -> LocalTime.fromMillisOfDay((timeInMillis - remainder).toLong())
else -> LocalTime.fromMillisOfDay((timeInMillis + (roundValue - remainder)).toLong())
}
}
和用法:
var userWakeTime = LocalTime(6, 42)
userWakeTime = userWakeTime.round(15 * 60 * 1000) // userWakeTime = 6:45