스테파노 :
나는 덩어리가 매달 두 날짜를 주어 계산하는 알고리즘을 만들어야합니다.
예 (형식 날짜 : YYYY-MM-DD HH : MM : SS) 주어진 두 날짜 :
- startTime을 : 2020년 1월 10일 13시 0분 25초
- endTime- 사용자 : 2020년 3월 19일 15시 0분 30초
나는 위의 기간 매월 덩어리로 나눌 수있다. 간단히 말해서 나는 덩어리가 될 것이다 계산하는 경우 :
- chunk_1 ->에서 : 2020년 1월 10일 13시 0분 25초에 : 2020년 1월 31일 23시 59분 59초
- chunk_2 ->에서 : 2020년 2월 1일 00:00:00 : 2020년 2월 29일 23시 59분 59초
- chunk_3 ->에서 : 2020년 3월 1일 00:00:00 : 2020년 3월 19일 15시 0분 30초
내 첫 번째 솔루션은 다음에 :
public static List<ExportDateSegment> datesBetweenWithCalendar(Date d1, Date d2) {
List<ExportDateSegment> dateSegments = new ArrayList<ExportDateSegment>();
Calendar c1 = Calendar.getInstance();
c1.setTime(d1);
int monthsDiff = mounthsDiffbetween(d1, d2);
LOGGER.debug("months between two dates: {} ",monthsDiff);
int i = 1;
while (c1.getTimeInMillis() < d2.getTime()) {
Calendar calendar;
ExportDateSegment exportDateSegment = new ExportDateSegment();
LOGGER.debug("last day of the month: " + c1.getActualMaximum(Calendar.DATE) + " last hour of the month: "
+ c1.getActualMaximum(Calendar.HOUR_OF_DAY) + " first day of the month: "
+ c1.getActualMinimum(Calendar.DAY_OF_MONTH) + " month: " + (c1.get(Calendar.MONTH) + 1));
// the logic is to separate the three cases: the start period, intermediate period and the end period
if (i == 1) {
calendar = new GregorianCalendar(c1.get(Calendar.YEAR), c1.get(Calendar.MONTH),
c1.getActualMaximum(Calendar.DATE), 23, 59, 59);
exportDateSegment.setStartDate(c1.getTime());
exportDateSegment.setEndDate(calendar.getTime());
} else if (i == monthsDiff) {
calendar = new GregorianCalendar(c1.get(Calendar.YEAR), c1.get(Calendar.MONTH),
c1.getActualMinimum(Calendar.DATE), 00, 00, 00);
exportDateSegment.setStartDate(calendar.getTime());
exportDateSegment.setEndDate(d2);
} else {
Calendar startCalendar = new GregorianCalendar(c1.get(Calendar.YEAR), c1.get(Calendar.MONTH),
c1.getActualMinimum(Calendar.DATE), 00, 00, 00);
Calendar endCalendar = new GregorianCalendar(c1.get(Calendar.YEAR), c1.get(Calendar.MONTH),
c1.getActualMaximum(Calendar.DATE), 23, 59, 59);
exportDateSegment.setStartDate(startCalendar.getTime());
exportDateSegment.setEndDate(endCalendar.getTime());
}
c1.add(Calendar.MONTH, 1);
dateSegments.add(exportDateSegment);
i = i + 1;
}
return dateSegments;
}
public static int mounthsDiffbetween(Date d1, Date d2) {
int monthsDiff = 0;
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c1.setTime(d1);
c2.setTime(d2);
monthsDiff = (c2.get(Calendar.MONTH) - c1.get(Calendar.MONTH)) + 1;
return monthsDiff;
}
ExportDateSegment 다른 단어 덩어리입니다에 속성으로의 startDate와 endDate가 들어있는 콩입니다.
똑똑한 솔루션이 있습니까?
안드레아스 :
이 같은 자바 8 시간 API, 예를 사용해야합니다 :
static List<TemporalRange<LocalDateTime>> chunkMonthly(LocalDateTime start, LocalDateTime end) {
List<TemporalRange<LocalDateTime>> list = new ArrayList<>();
for (LocalDateTime chunkEnd = end, chunkStart; ! chunkEnd.isBefore(start); chunkEnd = chunkStart.minusSeconds(1)) {
chunkStart = chunkEnd.toLocalDate().withDayOfMonth(1).atStartOfDay();
if (chunkStart.isBefore(start))
chunkStart = start;
list.add(new TemporalRange<>(chunkStart, chunkEnd));
}
Collections.reverse(list);
return list;
}
class TemporalRange<T extends TemporalAccessor> {
private final T start;
private final T end;
public TemporalRange(T start, T end) {
this.start = start;
this.end = end;
}
public T getStart() {
return this.start;
}
public T getEnd() {
return this.end;
}
@Override
public String toString() {
return this.start + " to " + this.end;
}
public String toString(DateTimeFormatter fmt) {
return fmt.format(this.start) + " to " + fmt.format(this.end);
}
}
테스트
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
List<TemporalRange<LocalDateTime>> list = chunkMonthly(
LocalDateTime.parse("2020-01-10 13:00:25", fmt),
LocalDateTime.parse("2020-03-19 15:00:30", fmt));
list.forEach(r -> System.out.println(r.toString(fmt)));
산출
2020-01-10 13:00:25 to 2020-01-31 23:59:59
2020-02-01 00:00:00 to 2020-02-29 23:59:59
2020-03-01 00:00:00 to 2020-03-19 15:00:30