如何在java中将时间四舍五入到最近的四分之一小时?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3553964/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to round time to the nearest quarter hour in java?
提问by lock
Given today's time e.g. 2:24PM, how do I get it to round to 2:30PM?
考虑到今天的时间,例如下午 2:24,我如何将其四舍五入到下午 2:30?
Similarly if the time was 2:17PM, how do I get it to round to 2:15PM?
同样,如果时间是下午 2 点 17 分,我如何将其舍入到下午 2 点 15 分?
采纳答案by Sean Patrick Floyd
Rounding
四舍五入
You will need to use modulo to truncate the quarter hour:
您将需要使用 modulo 来截断一刻钟:
Date whateverDateYouWant = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(whateverDateYouWant);
int unroundedMinutes = calendar.get(Calendar.MINUTE);
int mod = unroundedMinutes % 15;
calendar.add(Calendar.MINUTE, mod < 8 ? -mod : (15-mod));
As pointed out by EJP, this is also OK (replacement for the last line, only valid if the calendar is lenient):
正如 EJP 所指出的,这也可以(替换最后一行,仅在日历宽松时有效):
calendar.set(Calendar.MINUTE, unroundedMinutes + mod);
Improvements
改进
If you want to be exact, you will also have to truncate the smaller fields:
如果您想准确,您还必须截断较小的字段:
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
You can also use DateUtils.truncate()from Apache Commons / Langto do this:
您还可以使用DateUtils.truncate()从Apache的共享/郎做到这一点:
calendar = DateUtils.truncate(calendar, Calendar.MINUTE);
回答by Peter Tillemans
With the answer above you end up with all kind of interesting code to handle overflows to hours, days etc.
有了上面的答案,您最终会得到各种有趣的代码来处理数小时、数天等的溢出。
I would use the time in ms since the epoch.
自纪元以来,我将使用以毫秒为单位的时间。
add 7.5minutes or 7.5x60x1000 = 450000
添加 7.5 分钟或 7.5x60x1000 = 450000
and truncate to a multiple of 900000
并截断为 900000 的倍数
new Date(900000 * ((date.getTime() + 450000) / 900000))
This works, because the time where the ms time starts happens to be 00:00:00. And since all time zones in the world change in 15min steps, this does not affect rounding to quarters.
这是有效的,因为 ms 时间开始的时间恰好是 00:00:00。由于世界上所有时区都以 15 分钟为步长变化,因此这不会影响四舍五入。
(Oops, I had a 0 too much and forgot some important parentheses : it is still too early)
(哎呀,我的 0 太多了,忘记了一些重要的括号:现在还为时过早)
回答by christian
if you have the minutes you can round them with the following function:int minutes = i % 15 < 8 ? i / 15 * 15 : (i / 15 + 1) * 15;
如果您有时间,您可以使用以下功能对它们进行四舍五入:int minutes = i % 15 < 8 ? i / 15 * 15 : (i / 15 + 1) * 15;
回答by Kandha
You can use this simple code...
您可以使用这个简单的代码...
int mode = min % 15;
if (mode > 15 / 2) {
min = 15 - mode;
} else {
min = 0 - mode;
}
cal.add(Calendar.MINUTE, min);
回答by Torres
Maybe you can use an utility library for manipulating Dates, here for example you have a round method which can be useful for you:
也许您可以使用实用程序库来操作日期,例如,您有一个 round 方法,它对您很有用:
Here an example in code:
这是代码中的示例:
FastDateFormat formatter = DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT;
Date now = new Date();
System.out.println("now = " + formatter.format(now));
// Get nearest second
Date nearestSecond = DateUtils.round(now, Calendar.SECOND);
System.out.println("nearestSecond = " + formatter.format(nearestSecond));
// Get nearest minute
Date nearestMinute = DateUtils.round(now, Calendar.MINUTE);
System.out.println("nearestMinute = " + formatter.format(nearestMinute));
// Get nearest hour
Date nearestHour = DateUtils.round(now, Calendar.HOUR);
System.out.println("nearestHour = " + formatter.format(nearestHour));
回答by Lindhardt
It's simple, find the number of quaters since 1970 as double, round it and multiply by 15 minutes:
很简单,求自 1970 年以来的四分位数为两倍,四舍五入并乘以 15 分钟:
long timeMs = System.System.currentTimeMillis();
long roundedtimeMs = Math.round( (double)( (double)timeMs/(double)(15*60*1000) ) ) * (15*60*1000) );
Set your Date or Calendar object with that.
用它设置你的 Date 或 Calendar 对象。
回答by Christopher Masser
minutes = (int) (Math.round(minutes / 15.0) * 15.0);
回答by lboix
Wonderful post, thank you so much guys! It was exactly what I needed :)
精彩的帖子,非常感谢你们!这正是我所需要的:)
Here's my code based on jour work.
这是我基于 jour 工作的代码。
My usecase is "Given it's 11:47 am, I want to set two dates symbolizing the current 5-minutes frame : 11:45 am and 11:50 am"
我的用例是“鉴于现在是上午 11:47,我想设置两个象征当前 5 分钟帧的日期:上午 11:45 和上午 11:50”
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
int modulo = calendar.get(Calendar.MINUTE) % 5;
if(modulo > 0) {
calendar.add(Calendar.MINUTE, -modulo);
}
myObject.setStartDate(calendar.getTime());
calendar.add(Calendar.MINUTE, 5);
myObject.setDueDate(calendar.getTime());
回答by Dev
A commented implementation for Java 8. Accepts arbitrary rounding units and increments:
Java 8 的注释实现。接受任意舍入单位和增量:
public static ZonedDateTime round(ZonedDateTime input, TemporalField roundTo, int roundIncrement) {
/* Extract the field being rounded. */
int field = input.get(roundTo);
/* Distance from previous floor. */
int r = field % roundIncrement;
/* Find floor and ceiling. Truncate values to base unit of field. */
ZonedDateTime ceiling =
input.plus(roundIncrement - r, roundTo.getBaseUnit())
.truncatedTo(roundTo.getBaseUnit());
ZonedDateTime floor =
input.plus(-r, roundTo.getBaseUnit())
.truncatedTo(roundTo.getBaseUnit());
/*
* Do a half-up rounding.
*
* If (input - floor) < (ceiling - input)
* (i.e. floor is closer to input than ceiling)
* then return floor, otherwise return ceiling.
*/
return Duration.between(floor, input).compareTo(Duration.between(input, ceiling)) < 0 ? floor : ceiling;
}
Source: myself
来源:我自己
回答by Xander
Using some code on I found on Stackoverflow, I have created the following code. It will output for every minute the quarter it will be rounded to.
使用我在 Stackoverflow 上找到的一些代码,我创建了以下代码。它将每分钟输出四舍五入到的季度。
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
DateTimeFormatter Datum_Format = DateTimeFormatter.ofPattern("HH:mm");
LocalDateTime time = LocalDateTime.now();
for(int i=0; i<=59; i++) {
time = time.withMinute(i);
int Minute = time.getMinute();
int Quarter = 15 * (int) Math.round(Minute / 15);
if (Quarter == 60) {
Time2 = time.plusHours(1);
Time2 = Time2.withMinute(0);
LOG.info (Datum_Format.format(time) + "," + Datum_Format.format(Time2));
}
else {
Time2 = time;
Time2 = Time2.withMinute(Quarter);
LOG.info (Datum_Format.format(time) + "," + Datum_Format.format(Time2));
}
}
As I output the code to a console, you will have to replace the LOG.info with something like System.out.println.
当我将代码输出到控制台时,您必须将 LOG.info 替换为 System.out.println 之类的内容。
Result:
结果:
2016-08-16 15:14:31 INFO 15:05,15:00
2016-08-16 15:14:31 INFO 15:06,15:00
2016-08-16 15:14:31 INFO 15:07,15:00
2016-08-16 15:14:31 INFO 15:08,15:15
2016-08-16 15:14:31 INFO 15:09,15:15
2016-08-16 15:14:31 INFO 15:10,15:15
2016-08-16 15:14:31 信息 15:05,15:00
2016-08-16 15:14:31 信息 15:06,15:00
2016-08-16 15:14:31 信息 15:07 ,15:00
2016-08-16 15:14:31 信息 15:08,15:15
2016-08-16 15:14:31 信息 15:09,15:15
2016-08-16 15:14:31信息 15:10,15:15