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

后端 未结 14 2631
小鲜肉
小鲜肉 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:16

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

    If you just want to round down this is a more readable version using Java Time API:

    LocalDateTime time = LocalDateTime.now();
    LocalDateTime lastQuarter = time.truncatedTo(ChronoUnit.HOURS)
                                    .plusMinutes(15 * (time.getMinute() / 15));
    

    output:

    2016-11-04T10:58:10.228

    2016-11-04T10:45:00

    0 讨论(0)
  • 2020-11-27 15:22

    A commented implementation for Java 8. Accepts arbitrary rounding units and increments:

     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

    0 讨论(0)
  • 2020-11-27 15:22

    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);
    
    0 讨论(0)
  • 2020-11-27 15:22
    minutes = (int) (Math.round(minutes / 15.0) * 15.0);
    
    0 讨论(0)
  • 2020-11-27 15:22

    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.

    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.

    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

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