How to Round Time to the Nearest Quarter Hour in Java

How to round time to the nearest quarter hour in java?

Rounding

You will need to use modulo to truncate the quarter hour:

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

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 / Lang to do this:

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

Rounding calendar time to nearest 5 mins

I didn't test this code but i believe it should work.

int unroundedMinutes = isha_jamaat_cal.get(Calendar.MINUTE);
int mod = unroundedMinutes % 5;
isha_jamaat_cal.add(Calendar.MINUTE, mod < 3 ? -mod : (5-mod));

The basic idea is to check whether the current time is nearest to the next or the previous 5 minutes clock mark and adjusting the added value based on this.

How to round time to the nearest quarter hour in JavaScript?

Given that you have hours and minutes in variables (if you don't you can get them from the Date instance anyway by using Date instance functions):

var m = (parseInt((minutes + 7.5)/15) * 15) % 60;
var h = minutes > 52 ? (hours === 23 ? 0 : ++hours) : hours;

minutes can as well be calculated by using Math.round():

var m = (Math.round(minutes/15) * 15) % 60;

or doing it in a more javascript-sophisticated expression without any functions:

var m = (((minutes + 7.5)/15 | 0) * 15) % 60;
var h = ((((minutes/105) + .5) | 0) + hours) % 24;

You can check the jsPerf test that shows Math.round() is the slowest of the three while mainly the last one being the fastest as it's just an expression without any function calls (no function call overhead i.e. stack manipulation, although native functions may be treated differently in Javascript VM).
//----

Java Date rounding

If you use Apache commons-lang, you can use DateUtils to round your dates:

Date now = new Date();
Date nearestMinute = DateUtils.round(now, Calendar.MINUTE);

How to round off to the closest hour if its only 5 minutes ahead or behind?

You can simply check the minute part of the date-time and truncate it to hours as per the requirement.

Demo:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;

class Main {
public static void main(String[] args) {
// Test
String[] arr = { "2021-02-08T19:02:49.594", "2021-02-08T19:56:49.594", "2021-02-08T19:54:49.594",
"2021-02-08T19:06:49.594" };

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSS");

for (String s : arr) {
System.out.println(roundToNearestHour(s).format(dtf));
}
}

static LocalDateTime roundToNearestHour(String str) {
LocalDateTime ldt = LocalDateTime.parse(str);
int minute = ldt.getMinute();
return minute < 5 ? ldt.truncatedTo(ChronoUnit.HOURS)
: (minute >= 55 ? ldt.plusHours(1).truncatedTo(ChronoUnit.HOURS) : ldt);
}
}

Output:

2021-02-08T19:00:00.000
2021-02-08T20:00:00.000
2021-02-08T19:54:49.594
2021-02-08T19:06:49.594

How to round it down to the closest 5 minute interval if it is 1,2,3,4 minutes ahead?

You can truncate it to ChronoUnit.MINUTES and then check the minute-of-hour as per the requirement i.e. if it is not a multiple of 5 subtract the remainder when divided by 5. Use LocalDate#withMinute to return a copy of this LocalDateTime with the minute-of-hour altered.

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;

class Main {
public static void main(String[] args) {
// Test
String[] arr = { "2021-02-08T19:02:49.594", "2021-02-08T19:56:49.594", "2021-02-08T19:54:49.594",
"2021-02-08T19:06:49.594" };

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSS");

for (String s : arr) {
System.out.println(roundToNearestHour(s).format(dtf));
}
}

static LocalDateTime roundToNearestHour(String str) {
LocalDateTime ldt = LocalDateTime.parse(str).truncatedTo(ChronoUnit.MINUTES);
int minute = ldt.getMinute();
int remainder = minute % 5;
if (remainder != 0) {
ldt = ldt.withMinute(minute - remainder);
}
return ldt;
}
}

Output:

2021-02-08T19:00:00.000
2021-02-08T19:55:00.000
2021-02-08T19:50:00.000
2021-02-08T19:05:00.000


Related Topics



Leave a reply



Submit