java 时间 四舍五入_如何在Java中将时间四舍五入到最近的四分之一小时?

如何在Java中将时间四舍五入到最近的四分之一小时?

鉴于今天的时间 2:24 PM,如何将其舍入到2:30 PM?

同样,如果时间是2:17 PM,如何将其舍入为2:15 PM?

lock asked 2020-01-26T03:33:37Z

13个解决方案

80 votes

四舍五入

您将需要使用取模来截断四分之一小时:

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

正如EJP所指出的,这也是可以的(替换最后一行,仅当日历宽大时才有效):

calendar.set(Calendar.MINUTE, unroundedMinutes + mod);

改进之处

如果要精确,则还必须截断较小的字段:

calendar.set(Calendar.SECOND, 0);

calendar.set(Calendar.MILLISECOND, 0);

您还可以使用Apache Commons / Lang中的DateUtils.truncate()来执行此操作:

calendar = DateUtils.truncate(calendar, Calendar.MINUTE);

Sean Patrick Floyd answered 2020-01-26T03:34:11Z

21 votes

如果您只想四舍五入,可以使用Java Time API进行阅读:

LocalDateTime time = LocalDateTime.now();

LocalDateTime lastQuarter = time.truncatedTo(ChronoUnit.HOURS)

.plusMinutes(15 * (time.getMinute() / 15));

输出:

2016-11-04T10:58:10.228

2016-11-04T10:45:00

Dirk answered 2020-01-26T03:34:44Z

10 votes

很简单,将自1970年以来的四分之一数加倍,四舍五入并乘以15分钟即可:

long timeMs = System.System.currentTimeMillis();

long roundedtimeMs = Math.round( (double)( (double)timeMs/(double)(15*60*1000) ) ) * (15*60*1000) );

设置日期或日历对象。

Lindhardt answered 2020-01-26T03:35:08Z

9 votes

有了以上答案,您最终将获得各种有趣的代码来处理数小时,数天等的溢出。

我会使用自纪元以来的时间(毫秒)。

加7.5分钟或7.5x60x1000 = 450000

并截断为900000的倍数

new Date(900000 * ((date.getTime() + 450000) / 900000))

这是可行的,因为ms时间开始的时间恰好是00:00:00。 并且由于世界上所有时区都以15分钟为单位变化,因此这不会影响到四分之一的舍入。

(糟糕,我的0太大了,忘了一些重要的括号:现在还为时过早)

Peter Tillemans answered 2020-01-26T03:35:50Z

7 votes

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;

}

资料来源:我自己

Dev answered 2020-01-26T03:36:14Z

6 votes

精彩的帖子,非常感谢你们! 这正是我所需要的:)

这是我基于工作的代码。

我的用例是“鉴于现在是上午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());

lboix answered 2020-01-26T03:36:43Z

1 votes

也许您可以使用实用程序库来处理日期,例如,在这里,您有一个对您有用的舍入方法:

[http://commons.apache.org/lang/api-2.4/org/apache/commons/lang/time/DateUtils.html#round%28java.util.Calendar,%20int%29]

这是代码示例:

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

Torres answered 2020-01-26T03:37:12Z

1 votes

您可以使用此简单的代码...

int mode = min % 15;

if (mode > 15 / 2) {

min = 15 - mode;

} else {

min = 0 - mode;

}

cal.add(Calendar.MINUTE, min);

Kandha answered 2020-01-26T03:37:32Z

1 votes

public static Date getCurrentDateTimeWithQuarterRounding() {

final Calendar calendar = new GregorianCalendar();

calendar.setTime(new Date());

calendar.set(Calendar.MILLISECOND, 0);

calendar.set(Calendar.SECOND, 0);

final int minutes = calendar.get(Calendar.MINUTE);

if (minutes < 15) {

calendar.set(Calendar.MINUTE, 0);

} else if (minutes >= 45) {

calendar.set(Calendar.MINUTE, 45);

} else if (minutes < 30) {

calendar.set(Calendar.MINUTE, 15);

} else {

calendar.set(Calendar.MINUTE, 30);

}

return calendar.getTime();

}

contrapost answered 2020-01-26T03:37:47Z

0 votes

如果您有时间,可以使用以下功能将其取整:

int minutes = i % 15 < 8 ? i / 15 * 15 : (i / 15 + 1) * 15;

christian answered 2020-01-26T03:38:11Z

0 votes

minutes = (int) (Math.round(minutes / 15.0) * 15.0);

Christopher Masser answered 2020-01-26T03:38:27Z

0 votes

使用一些我在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));

}

}

当我将代码输出到控制台时,您将必须用System.out.println之类的内容替换LOG.info。

结果:

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

Xander answered 2020-01-26T03:39:22Z

0 votes

使用Java Instant API的另一种替代方法。

Instant instant = Instant.now();

int intervalInMinutes = 10;

instant.truncatedTo(ChronoUnit.MINUTES).minus(instant.atZone(ZoneId.of("UTC")).getMinute() % (1* intervalInMinutes),ChronoUnit.MINUTES);

Rakesh SKadam answered 2020-01-26T03:39:42Z

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值