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

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

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

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

Я искал в Интернете и нашел функцию DateInterval в Time4j.

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


person Sameer    schedule 11.09.2017    source источник


Ответы (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 (внимание: всегда полуоткрыт до версии 4.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 как обычно.

person Meno Hochschild    schedule 12.09.2017
comment
Большое спасибо за ваши полезные заметки. Есть ли какие-либо учебные пособия или примеры кода для DateInterval в Time4j для дополнения моих знаний? - person Sameer; 12.09.2017
comment
Что касается термина «необязательный диапазон дат», я имею в виду диапазон дат, который не связан только с начальным днем ​​месяца до его конца. Я хочу определить его на 2 или 3 месяца и указать дни между этими двумя датами. - person Sameer; 12.09.2017
comment
Это работает отлично. Могу ли я хранить эти даты в массиве строк или дат? - person Sameer; 12.09.2017
comment
@Sameer К сожалению, я еще не нашел времени написать обучающую страницу, особенно об интервалах (с примерами). И Time4J-интервалы могут многое. Надо действительно написать это один раз. Что касается вашего вопроса, как сохранить начало или конец, ну, он сериализуем, или вы можете форматировать и анализировать его в/из строки. Даже целые интервалы можно форматировать и сериализовать. - person Meno Hochschild; 12.09.2017
comment
@Sameer Что касается вашего необязательного диапазона дат, кажется, что вы ищете способ добавить 2 или 3 месяца к дате персидского календаря, чтобы достичь конца интервала. Вероятно, подходящая комбинация start.with(PersianCalendar.DAY_OF_MONTH.maximized()) и start.plus(2, PersianCalendar.Unit.MONTHS) или что-то подобное сделает это за вас. Это не меняет логику ежедневного цикла, который работает с каждым конечным началом и концом. - person Meno Hochschild; 12.09.2017
comment
@ Meno Hochschild Спасибо за советы о том, как хранить даты в массиве строк и способе определения необязательного диапазона дат. С вашим руководством я могу написать все коды, которые у меня есть в голове. Спасибо, что нашли время, чтобы помочь мне. - person Sameer; 13.09.2017