2016-06-03 2 views
4

Java 8 LocalDateTime을 가장 가까운 5 분으로 변환하고 싶습니다. 예 :Java 8 LocalDateTime 다음 X 분으로 회전

1601 -> 1605 
1602 -> 1605 
1603 -> 1605 
1604 -> 1605 
1605 -> 1605 
1606 -> 1610 
1607 -> 1610 
1608 -> 1610 
1609 -> 1610 
1610 -> 1610 

LocalDateTime 또는 Math API의 기존 기능을 사용하고 싶습니다. 어떤 제안?

+1

[관련] (https://stackoverflow.com/questions/25552023/round-minutes-to-ceiling-using-java-8 : 당신이 원하는 경우에 조정의 끝을 수정할 수 있습니다) 중복되지는 않지만. 즉, 분을 잘라내어 올바른 숫자를 다시 추가하십시오. –

+1

관련 항목 http://stackoverflow.com/questions/3553964/how-to-round-time-to-the-nearest-quarter-hour-in-java – Tunaki

+1

당신은 다음 라운드로 돌리시겠습니까? 질문의 본문에 명시된대로 제목과 예제가 제안하거나 * 가장 가까운 * 이름으로 표시됩니다. – Holger

답변

7

사용 5 분 다음 여러 방향으로 라운드 할 수 있습니다

LocalDateTime dt = … 
dt = dt.withSecond(0).withNano(0).plusMinutes((65-dt.getMinute())%5); 

당신은 사용하여 예를 재현 할 수있는이 예에서는

LocalDateTime dt=LocalDateTime.now().withHour(16).withSecond(0).withNano(0); 
for(int i=1; i<=10; i++) { 
    dt=dt.withMinute(i); 
    System.out.printf("%02d%02d -> ", dt.getHour(), dt.getMinute()); 
    // the rounding step: 
    dt=dt.plusMinutes((65-dt.getMinute())%5); 
    System.out.printf("%02d%02d%n", dt.getHour(), dt.getMinute()); 
} 

1601 -> 1605 
1602 -> 1605 
1603 -> 1605 
1604 -> 1605 
1605 -> 1605 
1606 -> 1610 
1607 -> 1610 
1608 -> 1610 
1609 -> 1610 
1610 -> 1610 

(I 그들이 0으로 유지되면 초와 나노를 한 번만 지우십시오).

+0

감사합니다. 그게 내가 원하는거야. 그것은 완벽하게 작동합니다. 나는이 방정식에 65가 무엇인지 혼란 스럽다. –

+1

논리는'(5-x) mod 5'이지만 모듈러스 연산자'%'는 값이 음수 일 때 원하는 것을하지 않으므로이 코드는'(65-x) % 5'를 대신 사용합니다. 'x '는 항상 0..59 사이에 있기 때문에'%'의 왼쪽 값은 항상 양수이고'(65-x) % 5 == (65-x) mod 5'입니다. – Holger

4

또는 홀거이 시사하는 것과, 당신은 당신이 date.with(nextOrSameMinutes(5)) 같은 것을 쓸 수 있도록하는 TemporalAdjuster를 만들 수 있습니다 :이 원래 일로부터 초/나노을 절단하지 않는

public static void main(String[] args) { 
    for (int i = 0; i <= 10; i++) { 
    LocalDateTime d = LocalDateTime.of(LocalDate.now(), LocalTime.of(16, i, 0)); 
    LocalDateTime nearest5 = d.with(nextOrSameMinutes(5)); 
    System.out.println(d.toLocalTime() + " -> " + nearest5.toLocalTime()); 
    } 
} 

public static TemporalAdjuster nextOrSameMinutes(int minutes) { 
    return temporal -> { 
    int minute = temporal.get(ChronoField.MINUTE_OF_HOUR); 
    int nearestMinute = (int) Math.ceil(minute/5d) * 5; 
    int adjustBy = nearestMinute - minute; 
    return temporal.plus(adjustBy, ChronoUnit.MINUTES); 
    }; 
} 

참고.

if (adjustBy == 0 
     && (temporal.get(ChronoField.SECOND_OF_MINUTE) > 0 || temporal.get(ChronoField.NANO_OF_SECOND) > 0)) { 
    adjustBy += 5; 
} 
return temporal.plus(adjustBy, ChronoUnit.MINUTES) 
      .with(ChronoField.SECOND_OF_MINUTE, 0) 
      .with(ChronoField.NANO_OF_SECOND, 0); 
+1

그 API에 대한 좋은 점은'foo.bar()'를'foo.with (f -> f.bar())'또는'foo.with (Foo :: bar)'로 대체 할 수 있다는 것입니다 ... – Holger

+1

@Holger lambda와 메소드 참조에 대한 사용 가능성은 매우 훌륭합니다. 그렇습니다.하지만 어두운 면도 있습니다. 'TemporalAdjuster'는'Collection'과'Stream'-API와는 달리 타입 안전하지 않습니다. 이 조정자를'Instant' (예를 들어)에 적용하려고하면 컴파일러는 괜찮다고 말하지만 런타임에는 예외가 발생합니다. –