stoty commented on code in PR #1530:
URL: https://github.com/apache/phoenix/pull/1530#discussion_r1034779244


##########
phoenix-core/src/test/java/org/apache/phoenix/expression/RoundFloorCeilExpressionsTest.java:
##########
@@ -688,4 +720,1207 @@ public void testFloorDateExpressionForWeek() throws 
Exception {
         Date resultDate = (Date)result;
         assertEquals(DateUtil.parseDate("2016-01-04 00:00:00"), resultDate);
     }
+
+    private RoundDateExpression getRoundMsExpression(String s, TimeUnit u, int 
m) throws SQLException {
+        return 
(RoundDateExpression)RoundDateExpression.create(LiteralExpression.newConstant(s),
 u, m );
+    }
+
+    // The three tests below are backported from PHOENIX-5066.
+    // When PHOENIX-5066 lands, these can be removed as redundant.
+
+    @Test
+    public void testRoundingGMT() throws SQLException {
+        // We operate on Instants for time units up to Days, simply counting 
millis
+
+        RoundDateExpression oddWholeSecondExp =
+                getRoundMsExpression("2022-11-11 11:11:11", TimeUnit.SECOND, 
1);
+        java.sql.Timestamp oddWholeSecond =
+                new java.sql.Timestamp(DateUtil.parseDate("2022-11-11 
11:11:11").getTime());
+        long lowerBoundaryOddWholeSecond = oddWholeSecond.getTime() - HALF_SEC;
+        long upperBoundaryOddWholeSecond = oddWholeSecond.getTime() + HALF_SEC 
- 1;
+        assertEquals(lowerBoundaryOddWholeSecond,
+            oddWholeSecondExp.rangeLower(oddWholeSecond.getTime()));
+        assertEquals(upperBoundaryOddWholeSecond,
+            oddWholeSecondExp.rangeUpper(oddWholeSecond.getTime()));
+        assertEquals(oddWholeSecond,
+            new 
java.sql.Timestamp(oddWholeSecondExp.roundTime(lowerBoundaryOddWholeSecond)));
+        assertNotEquals(oddWholeSecond,
+            new 
java.sql.Timestamp(oddWholeSecondExp.roundTime(lowerBoundaryOddWholeSecond - 
1)));
+        assertEquals(oddWholeSecond,
+            new 
java.sql.Timestamp(oddWholeSecondExp.roundTime(upperBoundaryOddWholeSecond)));
+        assertNotEquals(oddWholeSecond,
+            new 
java.sql.Timestamp(oddWholeSecondExp.roundTime(upperBoundaryOddWholeSecond + 
1)));
+
+        // 10 sec range
+        RoundDateExpression oddWholeSecondRound10Exp =
+                getRoundMsExpression("2022-11-11 11:11:10", TimeUnit.SECOND, 
10);
+        java.sql.Timestamp oddWholeSecondRound10 =
+                new java.sql.Timestamp(DateUtil.parseDate("2022-11-11 
11:11:10").getTime());
+        long lowerBoundaryOddWholeSecondRound10 = 
oddWholeSecondRound10.getTime() - 5 * SEC;
+        long upperBoundaryOddWholeSecondRound10 = 
oddWholeSecondRound10.getTime() + 5 * SEC - 1;
+        assertEquals(lowerBoundaryOddWholeSecondRound10,
+            oddWholeSecondRound10Exp.rangeLower(oddWholeSecond.getTime()));
+        assertEquals(upperBoundaryOddWholeSecondRound10,
+            oddWholeSecondRound10Exp.rangeUpper(oddWholeSecond.getTime()));
+        assertEquals(oddWholeSecondRound10, new java.sql.Timestamp(
+                
oddWholeSecondRound10Exp.roundTime(lowerBoundaryOddWholeSecondRound10)));
+        assertNotEquals(oddWholeSecondRound10, new java.sql.Timestamp(
+                
oddWholeSecondRound10Exp.roundTime(lowerBoundaryOddWholeSecondRound10 - 1)));
+        assertEquals(oddWholeSecondRound10, new java.sql.Timestamp(
+                
oddWholeSecondRound10Exp.roundTime(upperBoundaryOddWholeSecondRound10)));
+        assertNotEquals(oddWholeSecondRound10, new java.sql.Timestamp(
+                
oddWholeSecondRound10Exp.roundTime(upperBoundaryOddWholeSecondRound10 + 1)));
+
+        // 15 sec range
+        RoundDateExpression oddWholeSecondRound15Exp =
+                getRoundMsExpression("2022-11-11 11:11:15", TimeUnit.SECOND, 
15);
+        java.sql.Timestamp oddWholeSecondRound15 =
+                new java.sql.Timestamp(DateUtil.parseDate("2022-11-11 
11:11:15").getTime());
+        long lowerBoundaryOddWholeSecondRound15 = 
oddWholeSecondRound15.getTime() - 15 * HALF_SEC;
+        long upperBoundaryOddWholeSecondRound15 =
+                oddWholeSecondRound15.getTime() + 15 * HALF_SEC - 1;
+        assertEquals(lowerBoundaryOddWholeSecondRound15,
+            oddWholeSecondRound15Exp.rangeLower(oddWholeSecond.getTime()));
+        assertEquals(upperBoundaryOddWholeSecondRound15,
+            oddWholeSecondRound15Exp.rangeUpper(oddWholeSecond.getTime()));
+        assertEquals(oddWholeSecondRound15, new java.sql.Timestamp(
+                
oddWholeSecondRound15Exp.roundTime(lowerBoundaryOddWholeSecondRound15)));
+        assertNotEquals(oddWholeSecondRound15, new java.sql.Timestamp(
+                
oddWholeSecondRound15Exp.roundTime(lowerBoundaryOddWholeSecondRound15 - 1)));
+        assertEquals(oddWholeSecondRound15, new java.sql.Timestamp(
+                
oddWholeSecondRound15Exp.roundTime(upperBoundaryOddWholeSecondRound15)));
+        assertNotEquals(oddWholeSecondRound15, new java.sql.Timestamp(
+                
oddWholeSecondRound15Exp.roundTime(upperBoundaryOddWholeSecondRound15 + 1)));
+
+        RoundDateExpression evenWholeSecondExp =
+                getRoundMsExpression("2022-11-11 11:11:12", TimeUnit.SECOND, 
1);
+        java.sql.Timestamp evenWholeSecond =
+                new java.sql.Timestamp(DateUtil.parseDate("2022-11-11 
11:11:12").getTime());
+        long lowerBoundaryEvenWholeSecond = evenWholeSecond.getTime() - 
HALF_SEC;
+        long upperBoundaryEvenWholeSecond = evenWholeSecond.getTime() + 
HALF_SEC - 1;
+        assertEquals(lowerBoundaryEvenWholeSecond,
+            evenWholeSecondExp.rangeLower(evenWholeSecond.getTime()));
+        assertEquals(upperBoundaryEvenWholeSecond,
+            evenWholeSecondExp.rangeUpper(evenWholeSecond.getTime()));
+        assertEquals(evenWholeSecond,
+            new 
java.sql.Timestamp(evenWholeSecondExp.roundTime(lowerBoundaryEvenWholeSecond)));
+        assertNotEquals(evenWholeSecond,
+            new 
java.sql.Timestamp(evenWholeSecondExp.roundTime(lowerBoundaryEvenWholeSecond - 
1)));
+        assertEquals(evenWholeSecond,
+            new 
java.sql.Timestamp(evenWholeSecondExp.roundTime(upperBoundaryEvenWholeSecond)));
+        assertNotEquals(evenWholeSecond,
+            new 
java.sql.Timestamp(evenWholeSecondExp.roundTime(upperBoundaryEvenWholeSecond + 
1)));
+
+        RoundDateExpression oddWholeMinuteExp =
+                getRoundMsExpression("2022-11-11 11:11:0", TimeUnit.MINUTE, 1);
+        java.sql.Timestamp oddWholeMinute =
+                new java.sql.Timestamp(DateUtil.parseDate("2022-11-11 
11:11:0").getTime());
+        long lowerBoundaryOddWholeMinute = oddWholeMinute.getTime() - HALF_MIN;
+        long upperBoundaryOddWholeMinute = oddWholeMinute.getTime() + HALF_MIN 
- 1;
+        assertEquals(lowerBoundaryOddWholeMinute,
+            oddWholeMinuteExp.rangeLower(oddWholeMinute.getTime()));
+        assertEquals(upperBoundaryOddWholeMinute,
+            oddWholeMinuteExp.rangeUpper(oddWholeMinute.getTime()));
+        assertEquals(oddWholeMinute,
+            new 
java.sql.Timestamp(oddWholeMinuteExp.roundTime(lowerBoundaryOddWholeMinute)));
+        assertNotEquals(oddWholeMinute,
+            new 
java.sql.Timestamp(oddWholeMinuteExp.roundTime(lowerBoundaryOddWholeMinute - 
1)));
+        assertEquals(oddWholeMinute,
+            new 
java.sql.Timestamp(oddWholeMinuteExp.roundTime(upperBoundaryOddWholeMinute)));
+        assertNotEquals(oddWholeMinute,
+            new 
java.sql.Timestamp(oddWholeMinuteExp.roundTime(upperBoundaryOddWholeMinute + 
1)));
+
+        RoundDateExpression oddWholeMinuteRound20Exp =
+                getRoundMsExpression("2022-11-11 11:20:0", TimeUnit.MINUTE, 
20);
+        java.sql.Timestamp oddWholeMinuteRound20 =
+                new java.sql.Timestamp(DateUtil.parseDate("2022-11-11 
11:20:0").getTime());
+        long lowerBoundaryOddWholeMinute20 = oddWholeMinuteRound20.getTime() - 
10 * MIN;
+        long upperBoundaryOddWholeMinute20 = oddWholeMinuteRound20.getTime() + 
10 * MIN - 1;
+        assertEquals(lowerBoundaryOddWholeMinute20,
+            oddWholeMinuteRound20Exp.rangeLower(oddWholeMinute.getTime()));
+        assertEquals(upperBoundaryOddWholeMinute20,
+            oddWholeMinuteRound20Exp.rangeUpper(oddWholeMinute.getTime()));
+        assertEquals(oddWholeMinuteRound20, new java.sql.Timestamp(
+                
oddWholeMinuteRound20Exp.roundTime(lowerBoundaryOddWholeMinute20)));
+        assertNotEquals(oddWholeMinuteRound20, new java.sql.Timestamp(
+                
oddWholeMinuteRound20Exp.roundTime(lowerBoundaryOddWholeMinute20 - 1)));
+        assertEquals(oddWholeMinuteRound20, new java.sql.Timestamp(
+                
oddWholeMinuteRound20Exp.roundTime(upperBoundaryOddWholeMinute20)));
+        assertNotEquals(oddWholeMinuteRound20, new java.sql.Timestamp(
+                
oddWholeMinuteRound20Exp.roundTime(upperBoundaryOddWholeMinute20 + 1)));
+
+        // Minutes since epoch, don't expect the rounded value to be "round"
+
+        RoundDateExpression oddWholeMinuteRound17Exp =
+                getRoundMsExpression("2022-11-11 11:12:0", TimeUnit.MINUTE, 
17);
+        java.sql.Timestamp oddWholeMinuteRound17 =
+                new java.sql.Timestamp(DateUtil.parseDate("2022-11-11 
11:12:00").getTime());
+        long lowerBoundaryOddWholeMinute17 = oddWholeMinuteRound17.getTime() - 
17 * HALF_MIN;
+        long upperBoundaryOddWholeMinute17 = oddWholeMinuteRound17.getTime() + 
17 * HALF_MIN - 1;
+        assertEquals(lowerBoundaryOddWholeMinute17,
+            oddWholeMinuteRound17Exp.rangeLower(oddWholeMinute.getTime()));
+        assertEquals(upperBoundaryOddWholeMinute17,
+            oddWholeMinuteRound17Exp.rangeUpper(oddWholeMinute.getTime()));
+        assertEquals(oddWholeMinuteRound17, new java.sql.Timestamp(
+                
oddWholeMinuteRound17Exp.roundTime(lowerBoundaryOddWholeMinute17)));
+        assertNotEquals(oddWholeMinuteRound17, new java.sql.Timestamp(
+                
oddWholeMinuteRound17Exp.roundTime(lowerBoundaryOddWholeMinute17 - 1)));
+        assertEquals(oddWholeMinuteRound17, new java.sql.Timestamp(
+                
oddWholeMinuteRound17Exp.roundTime(upperBoundaryOddWholeMinute17)));
+        assertNotEquals(oddWholeMinuteRound17, new java.sql.Timestamp(
+                
oddWholeMinuteRound17Exp.roundTime(upperBoundaryOddWholeMinute17 + 1)));
+
+        RoundDateExpression evenWholeMinuteExp =
+                getRoundMsExpression("2022-11-11 11:12:0", TimeUnit.MINUTE, 1);
+        java.sql.Timestamp evenWholeMinute =
+                new java.sql.Timestamp(DateUtil.parseDate("2022-11-11 
11:12:0").getTime());
+        long lowerBoundaryEvenWholeMinute = evenWholeMinute.getTime() - 
HALF_MIN;
+        long upperBoundaryEvenWholeMinute = evenWholeMinute.getTime() + 
HALF_MIN - 1;
+        assertEquals(lowerBoundaryEvenWholeMinute,
+            evenWholeMinuteExp.rangeLower(evenWholeMinute.getTime()));
+        assertEquals(upperBoundaryEvenWholeMinute,
+            evenWholeMinuteExp.rangeUpper(evenWholeMinute.getTime()));
+        assertEquals(evenWholeMinute,
+            new 
java.sql.Timestamp(evenWholeMinuteExp.roundTime(lowerBoundaryEvenWholeMinute)));
+        assertNotEquals(evenWholeMinute,
+            new 
java.sql.Timestamp(evenWholeMinuteExp.roundTime(lowerBoundaryEvenWholeMinute - 
1)));
+        assertEquals(evenWholeMinute,
+            new 
java.sql.Timestamp(evenWholeMinuteExp.roundTime(upperBoundaryEvenWholeMinute)));
+        assertNotEquals(evenWholeMinute,
+            new 
java.sql.Timestamp(evenWholeMinuteExp.roundTime(upperBoundaryEvenWholeMinute + 
1)));
+
+        RoundDateExpression oddWholeHourExp =
+                getRoundMsExpression("2022-11-11 11:0:0", TimeUnit.HOUR, 1);
+        java.sql.Timestamp oddWholeHour =
+                new java.sql.Timestamp(DateUtil.parseDate("2022-11-11 
11:0:0").getTime());
+        long lowerBoundaryOddWholeHour = oddWholeHour.getTime() - HALF_HOUR;
+        long upperBoundaryOddWholeHour = oddWholeHour.getTime() + HALF_HOUR - 
1;
+        assertEquals(lowerBoundaryOddWholeHour, 
oddWholeHourExp.rangeLower(oddWholeHour.getTime()));
+        assertEquals(upperBoundaryOddWholeHour, 
oddWholeHourExp.rangeUpper(oddWholeHour.getTime()));
+        assertEquals(oddWholeHour,
+            new 
java.sql.Timestamp(oddWholeHourExp.roundTime(lowerBoundaryOddWholeHour)));
+        assertNotEquals(oddWholeHour,
+            new 
java.sql.Timestamp(oddWholeHourExp.roundTime(lowerBoundaryOddWholeHour - 1)));
+        assertEquals(oddWholeHour,
+            new 
java.sql.Timestamp(oddWholeHourExp.roundTime(upperBoundaryOddWholeHour)));
+        assertNotEquals(oddWholeHour,
+            new 
java.sql.Timestamp(oddWholeHourExp.roundTime(upperBoundaryOddWholeHour + 1)));
+
+        // Not rounding to hourOfDay
+        RoundDateExpression oddWholeHour10Exp =
+                getRoundMsExpression("2022-11-11 12:0:0", TimeUnit.HOUR, 10);
+        java.sql.Timestamp oddWholeHour10 =
+                new java.sql.Timestamp(DateUtil.parseDate("2022-11-11 
12:0:0").getTime());
+        long lowerBoundaryOddWholeHour10 = oddWholeHour10.getTime() - 
HALF_HOUR * 10;
+        long upperBoundaryOddWholeHour10 = oddWholeHour10.getTime() + 
HALF_HOUR * 10 - 1;
+        assertEquals(lowerBoundaryOddWholeHour10,
+            oddWholeHour10Exp.rangeLower(oddWholeHour.getTime()));
+        assertEquals(upperBoundaryOddWholeHour10,
+            oddWholeHour10Exp.rangeUpper(oddWholeHour.getTime()));
+        assertEquals(oddWholeHour10,
+            new 
java.sql.Timestamp(oddWholeHour10Exp.roundTime(lowerBoundaryOddWholeHour10)));
+        assertNotEquals(oddWholeHour10,
+            new 
java.sql.Timestamp(oddWholeHour10Exp.roundTime(lowerBoundaryOddWholeHour10 - 
1)));
+        assertEquals(oddWholeHour10,
+            new 
java.sql.Timestamp(oddWholeHour10Exp.roundTime(upperBoundaryOddWholeHour10)));
+        assertNotEquals(oddWholeHour10,
+            new 
java.sql.Timestamp(oddWholeHour10Exp.roundTime(upperBoundaryOddWholeHour10 + 
1)));
+
+        // Not rounding to hourOfDay
+        RoundDateExpression oddWholeHour11Exp =
+                getRoundMsExpression("2022-11-11 07:0:0", TimeUnit.HOUR, 11);
+        java.sql.Timestamp oddWholeHour11 =
+                new java.sql.Timestamp(DateUtil.parseDate("2022-11-11 
07:0:0").getTime());
+        long lowerBoundaryOddWholeHour11 = oddWholeHour11.getTime() - 
HALF_HOUR * 11;
+        long upperBoundaryOddWholeHour11 = oddWholeHour11.getTime() + 
HALF_HOUR * 11 - 1;
+        assertEquals(lowerBoundaryOddWholeHour11,
+            oddWholeHour11Exp.rangeLower(oddWholeHour.getTime()));
+        assertEquals(upperBoundaryOddWholeHour11,
+            oddWholeHour11Exp.rangeUpper(oddWholeHour.getTime()));
+        assertEquals(oddWholeHour11,
+            new 
java.sql.Timestamp(oddWholeHour11Exp.roundTime(lowerBoundaryOddWholeHour11)));
+        assertNotEquals(oddWholeHour11,
+            new 
java.sql.Timestamp(oddWholeHour11Exp.roundTime(lowerBoundaryOddWholeHour11 - 
1)));
+        assertEquals(oddWholeHour11,
+            new 
java.sql.Timestamp(oddWholeHour11Exp.roundTime(upperBoundaryOddWholeHour11)));
+        assertNotEquals(oddWholeHour11,
+            new 
java.sql.Timestamp(oddWholeHour11Exp.roundTime(upperBoundaryOddWholeHour11 + 
1)));
+
+        RoundDateExpression evenwholeHourExp =
+                getRoundMsExpression("2022-11-11 12:0:0", TimeUnit.HOUR, 1);
+        java.sql.Timestamp evenwholeHour =
+                new java.sql.Timestamp(DateUtil.parseDate("2022-11-11 
12:0:0").getTime());
+        long lowerBoundaryEvenWholeHour = evenwholeHour.getTime() - HALF_HOUR;
+        long upperBoundaryEvenWholeHour = evenwholeHour.getTime() + HALF_HOUR 
- 1;
+        assertEquals(lowerBoundaryEvenWholeHour,
+            evenwholeHourExp.rangeLower(evenwholeHour.getTime()));
+        assertEquals(upperBoundaryEvenWholeHour,
+            evenwholeHourExp.rangeUpper(evenwholeHour.getTime()));
+        assertEquals(evenwholeHour,
+            new 
java.sql.Timestamp(evenwholeHourExp.roundTime(lowerBoundaryEvenWholeHour)));
+        assertNotEquals(evenwholeHour,
+            new 
java.sql.Timestamp(evenwholeHourExp.roundTime(lowerBoundaryEvenWholeHour - 1)));
+        assertEquals(evenwholeHour,
+            new 
java.sql.Timestamp(evenwholeHourExp.roundTime(upperBoundaryEvenWholeHour)));
+        assertNotEquals(evenwholeHour,
+            new 
java.sql.Timestamp(evenwholeHourExp.roundTime(upperBoundaryEvenWholeHour + 1)));
+
+        // No DST switchover
+        RoundDateExpression oddWholeDayExp =
+                getRoundMsExpression("2022-11-11 0:0:0", TimeUnit.DAY, 1);
+        java.sql.Timestamp oddWholeDay =
+                new java.sql.Timestamp(DateUtil.parseDate("2022-11-11 
0:0:0").getTime());
+        long lowerBoundaryOddWholeDay = oddWholeDay.getTime() - HALF_DAY;
+        long upperBoundaryOddWholeDay = oddWholeDay.getTime() + HALF_DAY - 1;
+        assertEquals(lowerBoundaryOddWholeDay, 
oddWholeDayExp.rangeLower(oddWholeDay.getTime()));
+        assertEquals(upperBoundaryOddWholeDay, 
oddWholeDayExp.rangeUpper(oddWholeDay.getTime()));
+        assertEquals(oddWholeDay,
+            new 
java.sql.Timestamp(oddWholeDayExp.roundTime(lowerBoundaryOddWholeDay)));
+        assertNotEquals(oddWholeDay,
+            new 
java.sql.Timestamp(oddWholeDayExp.roundTime(lowerBoundaryOddWholeDay - 1)));
+        assertEquals(oddWholeDay,
+            new 
java.sql.Timestamp(oddWholeDayExp.roundTime(upperBoundaryOddWholeDay)));
+        assertNotEquals(oddWholeDay,
+            new 
java.sql.Timestamp(oddWholeDayExp.roundTime(upperBoundaryOddWholeDay + 1)));
+
+        RoundDateExpression oddWholeDay10Exp =
+                getRoundMsExpression("2022-11-14 0:0:0", TimeUnit.DAY, 10);
+        java.sql.Timestamp oddWholeDay10 =
+                new java.sql.Timestamp(DateUtil.parseDate("2022-11-14 
0:0:0").getTime());
+        long lowerBoundaryOddWholeDay10 = oddWholeDay10.getTime() - 10 * 
HALF_DAY;
+        long upperBoundaryOddWholeDay10 = oddWholeDay10.getTime() + 10 * 
HALF_DAY - 1;
+        assertEquals(lowerBoundaryOddWholeDay10,
+            oddWholeDay10Exp.rangeLower(oddWholeDay.getTime()));
+        assertEquals(upperBoundaryOddWholeDay10,
+            oddWholeDay10Exp.rangeUpper(oddWholeDay.getTime()));
+        assertEquals(oddWholeDay10,
+            new 
java.sql.Timestamp(oddWholeDay10Exp.roundTime(lowerBoundaryOddWholeDay10)));
+        assertNotEquals(oddWholeDay10,
+            new 
java.sql.Timestamp(oddWholeDay10Exp.roundTime(lowerBoundaryOddWholeDay10 - 1)));
+        assertEquals(oddWholeDay10,
+            new 
java.sql.Timestamp(oddWholeDay10Exp.roundTime(upperBoundaryOddWholeDay10)));
+        assertNotEquals(oddWholeDay10,
+            new 
java.sql.Timestamp(oddWholeDay10Exp.roundTime(upperBoundaryOddWholeDay10 + 1)));
+
+        RoundDateExpression oddWholeDay3Exp =
+                getRoundMsExpression("2022-11-12 0:0:0", TimeUnit.DAY, 3);
+        java.sql.Timestamp oddWholeDay3 =
+                new java.sql.Timestamp(DateUtil.parseDate("2022-11-12 
0:0:0").getTime());
+        long lowerBoundaryOddWholeDay3 = oddWholeDay3.getTime() - 3 * HALF_DAY;
+        long upperBoundaryOddWholeDay3 = oddWholeDay3.getTime() + 3 * HALF_DAY 
- 1;
+        assertEquals(lowerBoundaryOddWholeDay3, 
oddWholeDay3Exp.rangeLower(oddWholeDay.getTime()));
+        assertEquals(upperBoundaryOddWholeDay3, 
oddWholeDay3Exp.rangeUpper(oddWholeDay.getTime()));
+        assertEquals(oddWholeDay3,
+            new 
java.sql.Timestamp(oddWholeDay3Exp.roundTime(lowerBoundaryOddWholeDay3)));
+        assertNotEquals(oddWholeDay3,
+            new 
java.sql.Timestamp(oddWholeDay3Exp.roundTime(lowerBoundaryOddWholeDay3 - 1)));
+        assertEquals(oddWholeDay3,
+            new 
java.sql.Timestamp(oddWholeDay3Exp.roundTime(upperBoundaryOddWholeDay3)));
+        assertNotEquals(oddWholeDay3,
+            new 
java.sql.Timestamp(oddWholeDay3Exp.roundTime(upperBoundaryOddWholeDay3 + 1)));
+
+        RoundDateExpression evenWholeDayExp =
+                getRoundMsExpression("2022-11-12 0:0:0", TimeUnit.DAY, 1);
+        java.sql.Timestamp evenWholeDay =
+                new java.sql.Timestamp(DateUtil.parseDate("2022-11-12 
0:0:0").getTime());
+        long lowerBoundaryEvenWholeDay = evenWholeDay.getTime() - HALF_DAY;
+        long upperBoundaryEvenWholeDay = evenWholeDay.getTime() + HALF_DAY - 1;
+        assertEquals(lowerBoundaryEvenWholeDay, 
evenWholeDayExp.rangeLower(evenWholeDay.getTime()));
+        assertEquals(upperBoundaryEvenWholeDay, 
evenWholeDayExp.rangeUpper(evenWholeDay.getTime()));
+        assertEquals(evenWholeDay,
+            new 
java.sql.Timestamp(evenWholeDayExp.roundTime(lowerBoundaryEvenWholeDay)));
+        assertNotEquals(evenWholeDay,
+            new 
java.sql.Timestamp(evenWholeDayExp.roundTime(lowerBoundaryEvenWholeDay - 1)));
+        assertEquals(evenWholeDay,
+            new 
java.sql.Timestamp(evenWholeDayExp.roundTime(upperBoundaryEvenWholeDay)));
+        assertNotEquals(evenWholeDay,
+            new 
java.sql.Timestamp(evenWholeDayExp.roundTime(upperBoundaryEvenWholeDay + 1)));
+
+        // Stateless, we can reuse it for every week test
+        RoundWeekExpression roundWeekExpression = new RoundWeekExpression();
+        java.sql.Timestamp wholeWeekOdd =
+                new java.sql.Timestamp(DateUtil.parseDate("2022-10-10 
0:0:0").getTime());
+        long lowerBoundaryWholeWeekOdd = wholeWeekOdd.getTime() - (HALF_WEEK - 
1);
+        long upperBoundaryWholeWeekOdd = wholeWeekOdd.getTime() + HALF_WEEK - 
1;
+        assertEquals(lowerBoundaryWholeWeekOdd,
+            roundWeekExpression.rangeLower(wholeWeekOdd.getTime()));
+        assertEquals(upperBoundaryWholeWeekOdd,
+            roundWeekExpression.rangeUpper(wholeWeekOdd.getTime()));
+        assertEquals(wholeWeekOdd,
+            new java.sql.Timestamp(roundWeekExpression.roundDateTime(new 
org.joda.time.DateTime(
+                    lowerBoundaryWholeWeekOdd, 
GJChronology.getInstanceUTC()))));
+        assertNotEquals(wholeWeekOdd,
+            new java.sql.Timestamp(roundWeekExpression.roundDateTime(new 
org.joda.time.DateTime(
+                    lowerBoundaryWholeWeekOdd - 1, 
GJChronology.getInstanceUTC()))));
+        assertEquals(wholeWeekOdd,
+            new java.sql.Timestamp(roundWeekExpression.roundDateTime(new 
org.joda.time.DateTime(
+                    upperBoundaryWholeWeekOdd, 
GJChronology.getInstanceUTC()))));
+        assertNotEquals(wholeWeekOdd,
+            new java.sql.Timestamp(roundWeekExpression.roundDateTime(new 
org.joda.time.DateTime(
+                    upperBoundaryWholeWeekOdd + 1, 
GJChronology.getInstanceUTC()))));
+
+        java.sql.Timestamp wholeWeekEven =
+                new java.sql.Timestamp(DateUtil.parseDate("2022-10-17 
0:0:0").getTime());
+        long lowerBoundaryWholeWeekEven = wholeWeekEven.getTime() - HALF_WEEK;
+        long upperBoundaryWholeWeekEven = wholeWeekEven.getTime() + HALF_WEEK;
+        assertEquals(lowerBoundaryWholeWeekEven,
+            roundWeekExpression.rangeLower(wholeWeekEven.getTime()));
+        assertEquals(upperBoundaryWholeWeekEven,
+            roundWeekExpression.rangeUpper(wholeWeekEven.getTime()));
+        assertEquals(wholeWeekEven,
+            new java.sql.Timestamp(roundWeekExpression.roundDateTime(new 
org.joda.time.DateTime(
+                    lowerBoundaryWholeWeekEven, 
GJChronology.getInstanceUTC()))));
+        assertNotEquals(wholeWeekEven,
+            new java.sql.Timestamp(roundWeekExpression.roundDateTime(new 
org.joda.time.DateTime(
+                    lowerBoundaryWholeWeekEven - 1, 
GJChronology.getInstanceUTC()))));
+        assertEquals(wholeWeekEven,
+            new java.sql.Timestamp(roundWeekExpression.roundDateTime(new 
org.joda.time.DateTime(
+                    upperBoundaryWholeWeekEven, 
GJChronology.getInstanceUTC()))));
+        assertNotEquals(wholeWeekEven,
+            new java.sql.Timestamp(roundWeekExpression.roundDateTime(new 
org.joda.time.DateTime(
+                    upperBoundaryWholeWeekEven + 1, 
GJChronology.getInstanceUTC()))));
+
+        RoundMonthExpression roundMonthExpression = new RoundMonthExpression();
+        // We're still using roundHalfEven here for backwards compatibility
+        java.sql.Timestamp wholeMonthEven =
+                new java.sql.Timestamp(DateUtil.parseDate("2022-06-1 
0:0:0").getTime());
+        // May is 31 days
+        long lowerBoundaryWholeMonthEven = wholeMonthEven.getTime() - 31 * 
HALF_DAY;
+        // June is 30 days
+        long upperBoundaryWholeMonthEven = wholeMonthEven.getTime() + 30 * 
HALF_DAY;
+        assertEquals(lowerBoundaryWholeMonthEven,
+            roundMonthExpression.rangeLower(wholeMonthEven.getTime()));
+        assertEquals(upperBoundaryWholeMonthEven,
+            roundMonthExpression.rangeUpper(wholeMonthEven.getTime()));
+        assertEquals(wholeMonthEven,
+            new java.sql.Timestamp(roundMonthExpression.roundDateTime(new 
org.joda.time.DateTime(
+                    lowerBoundaryWholeMonthEven, 
GJChronology.getInstanceUTC()))));
+        assertNotEquals(wholeMonthEven,
+            new java.sql.Timestamp(roundMonthExpression.roundDateTime(new 
org.joda.time.DateTime(
+                    lowerBoundaryWholeMonthEven - 1, 
GJChronology.getInstanceUTC()))));
+        assertEquals(wholeMonthEven,
+            new java.sql.Timestamp(roundMonthExpression.roundDateTime(new 
org.joda.time.DateTime(
+                    upperBoundaryWholeMonthEven, 
GJChronology.getInstanceUTC()))));
+        assertNotEquals(wholeMonthEven,
+            new java.sql.Timestamp(roundMonthExpression.roundDateTime(new 
org.joda.time.DateTime(
+                    upperBoundaryWholeMonthEven + 1, 
GJChronology.getInstanceUTC()))));
+
+        // We're still using roundHalfEven here for backwards compatibility
+        java.sql.Timestamp wholeMonthOdd =
+                new java.sql.Timestamp(DateUtil.parseDate("2022-07-1 
0:0:0").getTime());
+        // June is 30 days
+        long lowerBoundaryWholeMonthOdd = wholeMonthOdd.getTime() - 30 * 
HALF_DAY + 1;
+        // July is 31 days
+        long upperBoundaryWholeMonthOdd = wholeMonthOdd.getTime() + 31 * 
HALF_DAY - 1;
+        assertEquals(lowerBoundaryWholeMonthOdd,
+            roundMonthExpression.rangeLower(wholeMonthOdd.getTime()));
+        assertEquals(upperBoundaryWholeMonthOdd,
+            roundMonthExpression.rangeUpper(wholeMonthOdd.getTime()));
+        assertEquals(wholeMonthOdd,
+            new java.sql.Timestamp(roundMonthExpression.roundDateTime(new 
org.joda.time.DateTime(
+                    lowerBoundaryWholeMonthOdd, 
GJChronology.getInstanceUTC()))));
+        assertNotEquals(wholeMonthOdd,
+            new java.sql.Timestamp(roundMonthExpression.roundDateTime(new 
org.joda.time.DateTime(
+                    lowerBoundaryWholeMonthOdd - 1, 
GJChronology.getInstanceUTC()))));
+        assertEquals(wholeMonthOdd,
+            new java.sql.Timestamp(roundMonthExpression.roundDateTime(new 
org.joda.time.DateTime(
+                    upperBoundaryWholeMonthOdd, 
GJChronology.getInstanceUTC()))));
+        assertNotEquals(wholeMonthOdd,
+            new java.sql.Timestamp(roundMonthExpression.roundDateTime(new 
org.joda.time.DateTime(
+                    upperBoundaryWholeMonthOdd + 1, 
GJChronology.getInstanceUTC()))));
+
+        // We're still using roundHalfEven here for backwards compatibility
+        java.sql.Timestamp wholeMonthLeap =
+                new java.sql.Timestamp(DateUtil.parseDate("2024-02-1 
0:0:0").getTime());
+        // January is 31 days
+        long lowerBoundaryWholeMonthLeap = wholeMonthLeap.getTime() - 31 * 
HALF_DAY;
+        // February is is 29 days

Review Comment:
   Thanks, fixed the typos you called out.



-- 
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.

To unsubscribe, e-mail: [email protected]

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

Reply via email to