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

后端 未结 14 2630
小鲜肉
小鲜肉 2020-11-27 14:59

Given today\'s time e.g. 2:24PM, how do I get it to round to 2:30PM?

Similarly if the time was 2:17PM, how do I get it to round to 2:15PM?

相关标签:
14条回答
  • 2020-11-27 15:24

    Maybe you can use an utility library for manipulating Dates, here for example you have a round method which can be useful for you:

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

    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));
    
    0 讨论(0)
  • 2020-11-27 15:26

    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

    and truncate to a multiple of 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.

    (Oops, I had a 0 too much and forgot some important parentheses : it is still too early)

    0 讨论(0)
  • 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();
    }
    
    0 讨论(0)
  • 2020-11-27 15:26

    One more alternate approach using 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);
    
    0 讨论(0)
  • 2020-11-27 15:27

    Wonderful post, thank you so much guys! It was exactly what I needed :)

    Here's my code based on jour work.

    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"

                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()); 
    
    0 讨论(0)
  • 2020-11-27 15:28

    It's simple, find the number of quaters since 1970 as double, round it and multiply by 15 minutes:

    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.

    0 讨论(0)
提交回复
热议问题