haimeiguo commented on a change in pull request #2029:
URL: https://github.com/apache/iotdb/pull/2029#discussion_r528535324



##########
File path: 
server/src/main/java/org/apache/iotdb/db/query/dataset/groupby/GroupByEngineDataSet.java
##########
@@ -70,36 +78,72 @@ public GroupByEngineDataSet(QueryContext context, 
GroupByTimePlan groupByTimePla
       long intervalNum = (long) Math.ceil(queryRange / (double) slidingStep);
       curStartTime = slidingStep * (intervalNum - 1) + startTime;
     }
-    curEndTime = Math.min(curStartTime + interval, endTime);
+
+
+    if (isIntervalByMonth) {
+      //if is group by months interval and sliding step are calculated in ms 
by * 30 * 86400_000L
+      //now converting them back to integer months
+      interval = interval / msToMonth;
+      //calculate interval length by natural month based on curStartTime
+      //ie. startTIme = 1/31, interval = 1mo, curEndTime will be set to 2/29
+      curEndTime = Math.min(curStartTime + calcIntervalByMonth(interval, 
curStartTime), endTime);
+    } else {
+      curEndTime = Math.min(curStartTime + interval, endTime);
+    }
+    if (isSlidingStepByMonth) {
+      slidingStep = slidingStep / msToMonth;
+    }
     this.hasCachedTimeInterval = true;
   }
 
   @Override
   protected boolean hasNextWithoutConstraint() {
+    long curSlidingStep = slidingStep;
+    long curInterval = interval;
     // has cached
     if (hasCachedTimeInterval) {
       return true;
     }
 
+    intervalTimes++;
+    //group by natural month, given startTime recalculate interval and sliding 
step
+    if (isIntervalByMonth) {
+      curInterval = calcIntervalByMonth(intervalTimes * slidingStep + 
interval, startTime);
+    }
+    if (isSlidingStepByMonth) {
+      curSlidingStep = calcIntervalByMonth(slidingStep * intervalTimes, 
curStartTime);
+    }
+
     // check if the next interval out of range
     if (ascending) {
-      curStartTime += slidingStep;
+      curStartTime += curSlidingStep;
       //This is an open interval , [0-100)
       if (curStartTime >= endTime) {
         return false;
       }
     } else {
-      curStartTime -= slidingStep;
+      curStartTime -= curSlidingStep;
       if (curStartTime < startTime) {
         return false;
       }
     }
 
     hasCachedTimeInterval = true;
-    curEndTime = Math.min(curStartTime + interval, endTime);
+    if (isIntervalByMonth) {
+      curEndTime = Math.min(startTime + curInterval, endTime);
+    } else {
+      curEndTime = Math.min(curStartTime + curInterval, endTime);
+    }
     return true;
   }
 
+  public long calcIntervalByMonth(long numMonths, long curStartTime) {
+    Calendar calendar = Calendar.getInstance();
+    calendar.setTimeInMillis(startTime);
+    calendar.add(Calendar.MONTH, (int) (numMonths));
+    return calendar.getTimeInMillis() - curStartTime;
+  }
+

Review comment:
       Hi, the calendar is set to the original startTime and uses intervalTImes 
to calendar.add() in case of dates = 29, 30, 31 
   ie. 
   when add one month to 1/31, curStartTime increments to 2/29
   if then set calendar to curStartTime = 2/29, then increments one month, we 
get curStartTime = 3/29, which is not what we intended. What we want is 1/31, 
2/29, 3/30, 4/31 ....
   so I used intervalTimes each time calculating the interval and set calendar 
to original startTime and add intervalTimes months to startTime to avoid edge 
cases. 




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to