Определить диапазон дат в Time4j (персидский календарь)

Я хочу определить диапазон дат следующим образом:

  • начать с "1396/8/9"
  • конец "1396/9/2"

И получите дату дней между этими двумя датами.

Я искал через Интернет, и я нашел DateInterval функция в Time4j.

Можно ли использовать этот метод для определения необязательного диапазона дат в персидском календаре? Если да, как я могу использовать этот метод для своих целей?

1 ответ

Решение

Использование конверсий

Класс DateInterval предназначен только для ISO-8601, то есть для Григорианского календаря. Таким образом, вы будете нести ответственность за преобразования между григорианским типом PlainDate и тип цели PersianCalendar:

DateInterval interval =
  DateInterval.between(
    PersianCalendar.of(1396, 8, 9).transform(PlainDate.axis()),
    PersianCalendar.of(1396, 9, 2)).transform(PlainDate.axis());

И для обратного преобразования:

PersianCalendar start = interval.getStartAsCalendarDate().transform(PersianCalendar.axis());

Конечно, вы также можете выполнять ежедневный цикл через ваш интервал:

interval
  .streamDaily()
  .map(d -> d.transform(PersianCalendar.axis()))
  .forEach(System.out::println);

Примечание:

DateInterval закрывается по умолчанию (как требуется в большинстве приложений, связанных с бизнес-датами), но может быть настроено как полуоткрытое путем вызова interval.withOpenEnd(),

Альтернатива:

Существует даже подход к хранению экземпляров PersianCalendar непосредственно в интервале, а именно SimpleInterval (внимание: всегда полуоткрыт перед выпуском v4.31!). Пример:

SimpleInterval<PersianCalendar> pInterval =
  SimpleInterval.onTimeLine(PersianCalendar.axis()).between(
    PersianCalendar.of(1396, 8, 9),
    PersianCalendar.of(1396, 9, 2).plus(CalendarDays.ONE)
  );

Ежедневный цикл с помощью обычного цикла for:

for (
  PersianCalendar pcal = pInterval.getStart().getTemporal(); 
  pcal.isBefore(pInterval.getEnd().getTemporal(); 
  pcal = pcal.plus(CalendarDays.ONE)
) {
  System.out.println(pcal);
}

Тем не менее, я не рекомендую использовать SimpleInterval потому что а) имеет меньше возможностей, чем DateInterval и б) в основном предназначен для некалендарных типов, таких как java.util.Date (поскольку такие интервалы всегда наполовину открыты, а календарные интервалы лучше закрывать в большинстве бизнес-приложений).

Дополнительные диапазоны

Насчет вашего термина "необязательный диапазон дат", мне не совсем понятно значение. Не могли бы вы уточнить? Возможно, вы говорите о границах бесконечного или полубесконечного интервала. Это возможно. Просто создайте интервалы не between(...) но по since(...) или же until(...), Но это влияет на ваш код зацикливания (вы не можете зацикливаться с бесконечности или до нее).

Обновление (2017-10-21)

Начиная с версии v4.31, класс SimpleInterval был улучшен таким образом, что он может обрабатывать календарные типы лучше, а именно всегда закрытые, а не полуоткрытые (но мгновенные интервалы будут, конечно, полуоткрытыми). Для этого были введены некоторые новые методы, например, (TimeAxis). Javadoc за ссылкой показывает пример:

 PersianCalendar start = PersianCalendar.of(1392, PersianMonth.ESFAND, 27);
 PersianCalendar end = PersianCalendar.of(1393, PersianMonth.FARVARDIN, 6);

 SimpleInterval<PersianCalendar> i1 =
   SimpleInterval.on(PersianCalendar.axis()).between(start, end);
 SimpleInterval<PersianCalendar> i2 =
   SimpleInterval.on(PersianCalendar.axis()).between(
     end.minus(CalendarDays.ONE),
     end.plus(CalendarDays.ONE));

 System.out.println(
   interval.findIntersection(
     SimpleInterval.on(PersianCalendar.axis()).between(
       end.minus(CalendarDays.ONE), end.plus(CalendarDays.ONE))).get());
 // [AP-1393-01-05/AP-1393-01-06]

Такой календарный интервал может быть обработан в течение IntervalCollection или же IntervalTree по-прежнему.

Другие вопросы по тегам