|
@@ -0,0 +1,149 @@
|
|
|
+package com.smppw.common.rollrange;
|
|
|
+
|
|
|
+import com.smppw.common.pojo.dto.DateRange;
|
|
|
+import com.smppw.common.pojo.enums.Frequency;
|
|
|
+import com.smppw.common.rollrange.date.DateConvertorImpl;
|
|
|
+import com.smppw.common.rollrange.date.DateVerifier;
|
|
|
+import org.joda.time.DateTime;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author zhengsongliang
|
|
|
+ */
|
|
|
+public class RollingSpliter implements DateSpliter {
|
|
|
+ private String startDate;
|
|
|
+ private String endDate;
|
|
|
+ private Integer rollingWindow;
|
|
|
+ private Integer rollingStep;
|
|
|
+ private boolean ifEdgeNeeded;
|
|
|
+ private Frequency freq;
|
|
|
+
|
|
|
+ public RollingSpliter(String startDate, String endDate, Integer rollingWindow, Integer rollingStep,
|
|
|
+ boolean ifEdgeNeeded, Frequency freq) {
|
|
|
+ super();
|
|
|
+ this.endDate = endDate;
|
|
|
+ this.startDate = startDate;
|
|
|
+ this.rollingWindow = rollingWindow;
|
|
|
+ this.rollingStep = rollingStep;
|
|
|
+ this.ifEdgeNeeded = ifEdgeNeeded;
|
|
|
+ this.freq = freq;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<DateRange> split() {
|
|
|
+ List<DateRange> ranges = new ArrayList<>();
|
|
|
+
|
|
|
+ if (rollingWindow == 0 || rollingStep == 0) {
|
|
|
+ ranges.add(new DateRange(startDate, endDate));
|
|
|
+ return ranges;
|
|
|
+ }
|
|
|
+
|
|
|
+ DateTime dtEnd = DateTime.parse(endDate);
|
|
|
+ DateTime dtStart = DateTime.parse(startDate);
|
|
|
+
|
|
|
+ if (Frequency.Weekly == this.freq) {
|
|
|
+ DateTime dtWeekEnd = dtStart.plusWeeks(rollingWindow).minusDays(1);
|
|
|
+ while (!dtWeekEnd.isAfter(dtEnd)) {
|
|
|
+ ranges.add(new DateRange(dtStart, dtWeekEnd));
|
|
|
+ dtStart = dtStart.plusWeeks(rollingStep);
|
|
|
+ dtWeekEnd = dtStart.plusWeeks(rollingWindow).minusDays(1);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ DateTime dtMonthEnd = dtStart.plusMonths(rollingWindow).minusDays(1);
|
|
|
+ while (!dtMonthEnd.isAfter(dtEnd)) {
|
|
|
+ ranges.add(new DateRange(dtStart, dtMonthEnd));
|
|
|
+ dtStart = dtStart.plusMonths(rollingStep);
|
|
|
+ dtMonthEnd = dtStart.plusMonths(rollingWindow).minusDays(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (ifEdgeNeeded && dtStart.isBefore(dtEnd))
|
|
|
+ ranges.add(new DateRange(dtStart, dtEnd));
|
|
|
+
|
|
|
+ if (freq != Frequency.Daily && freq != Frequency.Weekly) {
|
|
|
+ // Rolling Annually, when the last period is less than a full year, also should be added
|
|
|
+
|
|
|
+// int n = ranges.size();
|
|
|
+// for (int i = 0; i < n; i++) {
|
|
|
+// DateRange dr = ranges.get(i);
|
|
|
+// String start = DateVerifier.verifyPeriodStart(dr.getStartDate(), freq);
|
|
|
+// String end = DateVerifier.verifyPeriodEnd(dr.getEndDate(), freq);
|
|
|
+// dr.setStartDate(start);
|
|
|
+// dr.setEndDate(end);
|
|
|
+// }
|
|
|
+
|
|
|
+
|
|
|
+ List<DateRange> validRanges = new ArrayList<>();
|
|
|
+ for (DateRange dr : ranges) {
|
|
|
+ if (DateTime.parse(dr.getStartDate()).isBefore(DateTime.parse(dr.getEndDate())))
|
|
|
+ validRanges.add(dr);
|
|
|
+ }
|
|
|
+ ranges = validRanges;
|
|
|
+ }
|
|
|
+ return ranges;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static List<DateRange> getDateRangesAmong(String startDate, String endDate, Frequency rollingFrequency,
|
|
|
+ boolean ifEdgeNeeded, Frequency freq) {
|
|
|
+ return getDateRangesAmong(startDate, endDate, rollingFrequency, ifEdgeNeeded, freq, true);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static List<DateRange> getDateRangesAmong(String startDate, String endDate, Frequency rollingFrequency,
|
|
|
+ boolean ifEdgeNeeded, Frequency freq, boolean headEgde) {
|
|
|
+ Frequency rollingfreq = Frequency.valueOf(rollingFrequency.name());
|
|
|
+ DateRange drEdgeHead = null;
|
|
|
+ String verifiedStartDate = DateVerifier.verifyPeriodStart(startDate, rollingfreq);
|
|
|
+ if (ifEdgeNeeded) {
|
|
|
+ String currentFreqEnd = new DateConvertorImpl().setPeriodLast(startDate, rollingfreq);
|
|
|
+ if (!startDate.equals(verifiedStartDate)) {
|
|
|
+ if (DateTime.parse(currentFreqEnd).isBefore(DateTime.parse(endDate)))
|
|
|
+ drEdgeHead = new DateRange(startDate, currentFreqEnd);
|
|
|
+ else {
|
|
|
+ drEdgeHead = new DateRange(startDate, endDate);
|
|
|
+ return Arrays.asList(drEdgeHead);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Frequency.Weekly == rollingfreq) {
|
|
|
+ int weekCount = 52 / (int) rollingfreq.getNum();
|
|
|
+ //List<DateRange> ranges = new RollingSpliter(verifiedStartDate, endDate, weekCount, weekCount, ifEdgeNeeded, freq).split();
|
|
|
+ List<DateRange> ranges = new RollingSpliter(verifiedStartDate, endDate, weekCount, weekCount, ifEdgeNeeded, rollingfreq).split();
|
|
|
+ if (drEdgeHead != null && headEgde)
|
|
|
+ ranges.add(0, drEdgeHead);
|
|
|
+ return ranges;
|
|
|
+
|
|
|
+ } else {
|
|
|
+ int freqMonthCount = 12 / (int) rollingfreq.getNum();
|
|
|
+ //List<DateRange> ranges = new RollingSpliter(verifiedStartDate, endDate, freqMonthCount, freqMonthCount, ifEdgeNeeded, freq).split();
|
|
|
+ List<DateRange> ranges = new RollingSpliter(verifiedStartDate, endDate, freqMonthCount, freqMonthCount, ifEdgeNeeded, rollingfreq).split();
|
|
|
+ if (drEdgeHead != null && headEgde)
|
|
|
+ ranges.add(0, drEdgeHead);
|
|
|
+ return ranges;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+// public static void main(String[] args) {
|
|
|
+// Frequency rollingfreq = Frequency.Weekly;
|
|
|
+// String startDate = "2020-01-01";
|
|
|
+// String endDate = "2020-12-22";
|
|
|
+//
|
|
|
+// String verifiedStartDate = DateVerifier.verifyPeriodStart(startDate, rollingfreq);
|
|
|
+//
|
|
|
+// System.out.println(verifiedStartDate);
|
|
|
+//
|
|
|
+// int weekCount = 52 / (int) rollingfreq.getNum();
|
|
|
+//
|
|
|
+// System.out.println("week:" + weekCount);
|
|
|
+//
|
|
|
+// List<DateRange> ranges = new RollingSpliter(verifiedStartDate, endDate, weekCount, weekCount, true, rollingfreq).split();
|
|
|
+//
|
|
|
+// for (DateRange dr : ranges)
|
|
|
+// System.out.println(dr);
|
|
|
+//
|
|
|
+// }
|
|
|
+}
|