IndexNameFormatter { public List<String> formatTypeAndRange(@Nullable String type, long beginMillis, long endMillis) { GregorianCalendar current = midnightUTC(beginMillis); GregorianCalendar end = midnightUTC(endMillis); String prefix = prefix(type); List<String> indices = new ArrayList<>(); while (current.compareTo(end) <= 0) { if (current.get(Calendar.MONTH) == Calendar.JANUARY && current.get(DAY_OF_MONTH) == 1) { current.set(Calendar.DAY_OF_YEAR, current.getActualMaximum(Calendar.DAY_OF_YEAR)); if (current.compareTo(end) <= 0) { indices.add( String.format("%s-%s%c*", prefix, current.get(Calendar.YEAR), dateSeparator())); current.add(DAY_OF_MONTH, 1); continue; } else { current.set(Calendar.DAY_OF_YEAR, 1); } } else if (current.get(DAY_OF_MONTH) == 1) { current.set(DAY_OF_MONTH, current.getActualMaximum(DAY_OF_MONTH)); if (current.compareTo(end) <= 0) { indices.add(formatIndexPattern("%s-%s%c%02d%c*", current, prefix)); current.add(DAY_OF_MONTH, 1); continue; } current.set(DAY_OF_MONTH, 9); if (current.compareTo(end) <= 0) { indices.add(formatIndexPattern("%s-%s%c%02d%c0*", current, prefix)); current.add(DAY_OF_MONTH, 1); continue; } current.set(DAY_OF_MONTH, 1); } else if (current.get(DAY_OF_MONTH) == 10) { current.set(DAY_OF_MONTH, 19); if (current.compareTo(end) <= 0) { indices.add(formatIndexPattern("%s-%s%c%02d%c1*", current, prefix)); current.add(DAY_OF_MONTH, 1); continue; } current.set(DAY_OF_MONTH, 10); } else if (current.get(DAY_OF_MONTH) == 20) { current.set(DAY_OF_MONTH, 29); if (current.compareTo(end) <= 0) { indices.add(formatIndexPattern("%s-%s%c%02d%c2*", current, prefix)); current.add(DAY_OF_MONTH, 1); continue; } current.set(DAY_OF_MONTH, 20); } indices.add(formatTypeAndTimestamp(type, current.getTimeInMillis())); current.add(DAY_OF_MONTH, 1); } return indices; }  static Builder newBuilder(); abstract Builder toBuilder(); abstract String index(); List<String> formatTypeAndRange(@Nullable String type, long beginMillis, long endMillis); String formatTypeAndTimestampForInsert(String type, char indexTypeDelimiter,
    long timestampMillis); String formatTypeAndTimestamp(@Nullable String type, long timestampMillis); String formatType(@Nullable String type);  }
@Test public void indexNameForTimestampRange_sameTime() throws ParseException { long start = iso8601.parse("2016-11-01T01:01:01Z").getTime(); assertThat(formatter.formatTypeAndRange("span", start, start)) .containsExactly("zipkin*span-2016-11-01"); }
@Test public void indexNameForTimestampRange_sameDay() throws ParseException { long start = iso8601.parse("2016-11-01T01:01:01Z").getTime(); long end = iso8601.parse("2016-11-01T23:59:59Z").getTime(); assertThat(formatter.formatTypeAndRange("span", start, end)) .containsExactly("zipkin*span-2016-11-01"); }
@Test public void indexNameForTimestampRange_sameMonth() throws ParseException { long start = iso8601.parse("2016-11-15T01:01:01Z").getTime(); long end = iso8601.parse("2016-11-16T23:59:59Z").getTime(); assertThat(formatter.formatTypeAndRange("span", start, end)) .containsExactly("zipkin*span-2016-11-15", "zipkin*span-2016-11-16"); }
@Test public void indexNameForTimestampRange_sameMonth_startingAtOne() throws ParseException { long start = iso8601.parse("2016-11-1T01:01:01Z").getTime(); long end = iso8601.parse("2016-11-3T23:59:59Z").getTime(); assertThat(formatter.formatTypeAndRange("span", start, end)) .containsExactly( "zipkin*span-2016-11-01", "zipkin*span-2016-11-02", "zipkin*span-2016-11-03"); }
@Test public void indexNameForTimestampRange_nextMonth() throws ParseException { long start = iso8601.parse("2016-10-31T01:01:01Z").getTime(); long end = iso8601.parse("2016-11-01T23:59:59Z").getTime(); assertThat(formatter.formatTypeAndRange("span", start, end)) .containsExactly("zipkin*span-2016-10-31", "zipkin*span-2016-11-01"); }
@Test public void indexNameForTimestampRange_compressesMonth() throws ParseException { long start = iso8601.parse("2016-10-01T01:01:01Z").getTime(); long end = iso8601.parse("2016-10-31T23:59:59Z").getTime(); assertThat(formatter.formatTypeAndRange("span", start, end)) .containsExactly("zipkin*span-2016-10-*"); }
@Test public void indexNameForTimestampRange_skipMonths() throws ParseException { long start = iso8601.parse("2016-10-31T01:01:01Z").getTime(); long end = iso8601.parse("2016-12-01T23:59:59Z").getTime(); assertThat(formatter.formatTypeAndRange("span", start, end)) .containsExactly( "zipkin*span-2016-10-31", "zipkin*span-2016-11-*", "zipkin*span-2016-12-01"); }
@Test public void indexNameForTimestampRange_skipMonths_leapYear() throws ParseException { long start = iso8601.parse("2016-02-28T01:01:01Z").getTime(); long end = iso8601.parse("2016-04-01T23:59:59Z").getTime(); assertThat(formatter.formatTypeAndRange("span", start, end)) .containsExactly( "zipkin*span-2016-02-28", "zipkin*span-2016-02-29", "zipkin*span-2016-03-*", "zipkin*span-2016-04-01"); }
@Test public void indexNameForTimestampRange_compressesYear() throws ParseException { long start = iso8601.parse("2016-01-01T01:01:01Z").getTime(); long end = iso8601.parse("2016-12-31T23:59:59Z").getTime(); assertThat(formatter.formatTypeAndRange("span", start, end)) .containsExactly("zipkin*span-2016-*"); }
@Test public void indexNameForTimestampRange_skipYears() throws ParseException { long start = iso8601.parse("2016-10-31T01:01:01Z").getTime(); long end = iso8601.parse("2018-01-01T23:59:59Z").getTime(); assertThat(formatter.formatTypeAndRange("span", start, end)) .containsExactly( "zipkin*span-2016-10-31", "zipkin*span-2016-11-*", "zipkin*span-2016-12-*", "zipkin*span-2017-*", "zipkin*span-2018-01-01"); }