Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public enum PeriodicityType {
// The followed list consists of valid periodicity types in increasing period lengths
static PeriodicityType[] VALID_ORDERED_LIST = new PeriodicityType[] { TOP_OF_MILLISECOND,
PeriodicityType.TOP_OF_SECOND, PeriodicityType.TOP_OF_MINUTE, PeriodicityType.TOP_OF_HOUR,
PeriodicityType.TOP_OF_DAY, PeriodicityType.TOP_OF_WEEK, PeriodicityType.TOP_OF_MONTH };
PeriodicityType.HALF_DAY, PeriodicityType.TOP_OF_DAY, PeriodicityType.TOP_OF_WEEK,
PeriodicityType.TOP_OF_MONTH };

}
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ public boolean isCollisionFree() {
// isolated hh or KK
return !collision(12 * MILLIS_IN_ONE_HOUR);

case HALF_DAY:
// isolated 'a' (AM/PM) without a date component repeats every day
return !collision(MILLIS_IN_ONE_DAY);

case TOP_OF_DAY:
// EE or uu
if (collision(7 * MILLIS_IN_ONE_DAY))
Expand Down Expand Up @@ -198,6 +202,8 @@ public long periodBarriersCrossed(long start, long end) {
return diff / MILLIS_IN_ONE_MINUTE;
case TOP_OF_HOUR:
return diff / MILLIS_IN_ONE_HOUR;
case HALF_DAY:
return diff / (12 * MILLIS_IN_ONE_HOUR);
case TOP_OF_DAY:
return diff / MILLIS_IN_ONE_DAY;
case TOP_OF_WEEK:
Expand Down Expand Up @@ -251,6 +257,15 @@ static private Instant innerGetEndOfNextNthPeriod(Calendar cal, PeriodicityType
cal.add(Calendar.HOUR_OF_DAY, numPeriods);
break;

case HALF_DAY:
// floor to the start of the current half-day (00:00 or 12:00), then advance
cal.set(Calendar.HOUR_OF_DAY, cal.get(Calendar.HOUR_OF_DAY) < 12 ? 0 : 12);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.add(Calendar.HOUR_OF_DAY, numPeriods * 12);
break;

case TOP_OF_DAY:
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,17 @@ public void testPeriodicity() {
assertEquals(PeriodicityType.TOP_OF_HOUR, rc.getPeriodicityType());
}

{
// 'a' (AM/PM) without a finer time token means twice-a-day roll-over
RollingCalendar rc = new RollingCalendar("yyyy-MM-dd-a");
assertEquals(PeriodicityType.HALF_DAY, rc.getPeriodicityType());
}

{
RollingCalendar rc = new RollingCalendar("yyyy-MM-dd a");
assertEquals(PeriodicityType.HALF_DAY, rc.getPeriodicityType());
}

{
RollingCalendar rc = new RollingCalendar("yyyy-MM-dd");
assertEquals(PeriodicityType.TOP_OF_DAY, rc.getPeriodicityType());
Expand Down Expand Up @@ -132,6 +143,23 @@ public void testVaryingNumberOfDailyPeriods() {
}
}

@Test
public void testVaryingNumberOfHalfDailyPeriods() {
RollingCalendar rc = new RollingCalendar("yyyy-MM-dd-a");
final long MILLIS_IN_HALF_DAY = 12 * 3600 * 1000;

for (int p = 20; p > -100; p--) {
long now = 1223325293589L; // Mon Oct 06 22:34:53 CEST 2008
Instant nowInstant = Instant.ofEpochMilli(now);
Instant result = rc.getEndOfNextNthPeriod(nowInstant, p);
long offset = rc.getTimeZone().getRawOffset() + rc.getTimeZone().getDSTSavings();

long origin = now - ((now + offset) % (MILLIS_IN_HALF_DAY));
long expected = origin + p * MILLIS_IN_HALF_DAY;
assertEquals(expected, result.toEpochMilli(), "p=" + p);
}
}

// Wed Mar 23 23:07:05 CET 2016
final long WED_2016_03_23_T_230705_CET = 1458770825333L;

Expand All @@ -143,6 +171,8 @@ public void testBarrierCrossingComputation() {
WED_2016_03_23_T_230705_CET + 3 * CoreConstants.MILLIS_IN_ONE_MINUTE, 3);
checkPeriodBarriersCrossed("yyyy-MM-dd'T'HH", WED_2016_03_23_T_230705_CET,
WED_2016_03_23_T_230705_CET + 3 * CoreConstants.MILLIS_IN_ONE_HOUR, 3);
checkPeriodBarriersCrossed("yyyy-MM-dd-a", WED_2016_03_23_T_230705_CET,
WED_2016_03_23_T_230705_CET + 3 * 12 * CoreConstants.MILLIS_IN_ONE_HOUR, 3);
checkPeriodBarriersCrossed("yyyy-MM-dd", WED_2016_03_23_T_230705_CET,
WED_2016_03_23_T_230705_CET + 3 * CoreConstants.MILLIS_IN_ONE_DAY, 3);
}
Expand All @@ -164,6 +194,10 @@ public void testCollisionFreenes() {
checkCollisionFreeness("yyyy-MM-dd KK", false);
checkCollisionFreeness("yyyy-MM-dd KK a", true);

// half-daily
checkCollisionFreeness("yyyy-MM-dd-a", true);
checkCollisionFreeness("a", false);

// daily
checkCollisionFreeness("yyyy-MM-dd", true);
checkCollisionFreeness("yyyy-dd", false);
Expand Down