Есть ли дата хиджры на грузинскую дату и наоборот, что является надежным? - PullRequest
3 голосов
/ 29 апреля 2020

Я ищу библиотеку, которая может дать мне необходимые инструменты, например, для подсчета количества дней, прошедших с этого момента, до конкретной c даты И, которую я могу использовать, чтобы определить, нахожусь ли я в указанном c период времени (например, Мухаррам + - 5 дней) или нет

Я искал более 10 часов сейчас, и лучшее, что я нашел, была библиотека "HijrahDate" java .time.chrono. HijrahDate "и что-то под названием" Joda Date ", с которыми мне было трудно пользоваться.

Если кто-нибудь может мне помочь с этим, это будет очень цениться.

Ответы [ 3 ]

3 голосов
/ 29 апреля 2020

Какой вариант календаря хиджры вы хотите использовать?

Если вы выберете официальный календарь Саудовской Аравии, тогда решение, основанное на java .time .HijrahDate будет работать. Но этот класс требует как минимум API уровня 26 на Android. Пример:

HijrahDate hd1 = HijrahDate.now();
HijrahDate hd2 = HijrahDate.from(LocalDate.of(2020, 5, 1));
long days = ChronoUnit.DAYS.between(hd1, hd2);

Существуют также методы сравнения, такие как isAfter() или isBefore(), унаследованные от интерфейса ChronoLocalDate и стандартные методы plus () - для определения, указана ли ваша дата в указанном c период времени.

Backport из java.time:

Существует также обратный порт с именем ThreetenABP для более низких Android -версий. Но следует помнить о том, что реализация HijrahDate отличается от других и НЕ использует календарь Саудовской Аравии (поэтому вы должны мириться с различиями в преобразовании дат).

О Joda-Time :

Если вы выбрали эту (довольно устаревшую) библиотеку, вам следует выбрать версию библиотеки , адаптированную для android. Тем не менее, он не поддерживает календарь Саудовской Аравии, но предлагает четыре различных других варианта. Вам нужно будет указать алгоритм c шаблон високосного года .

ICU4J (встроенный в Android):

Его класс IslamicCalendar предлагает стиль, аналогичный старым календарным классам java.util.Calendar, а также несколько вариантов, включая стиль Саудовской Аравии. Минимальный требуемый уровень API - 24.

Time4A:

Это библиотека, написанная мной (как адаптация Time4J для Android ). Он предлагает класс HijriCalendar с несколькими вариантами, включая Joda-варианты, а также календарь Саудовской Аравии (вариант ummalqura). Он предлагает все необходимые функции, такие как арифметика даты c (методом плюс () или минус ()), сравнение даты (методом isAfter () и c.). Пример:

String variant = HijriCalendar.VARIANT_UMALQURA;
StartOfDay startOfDay = StartOfDay.definedBy(SolarTime.ofMecca().sunset());
HijriCalendar today = HijriCalendar.nowInSystemTime(variant, startOfDay);
HijriCalendar hcal = // gregorian to Hijri conversion
    PlainDate.of(2020, 5, 1).transform(HijriCalendar.class, variant);
long days = CalendarDays.between(today, hcal).getAmount();

Такие функции, как закат в начале дня, не поддерживаются другими библиотеками. Пример для вашего Muharram + - 5days-запрос может выглядеть так:

CalendarDays tolerance = CalendarDays.of(5);
HijriCalendar htemp = today.with(HijriCalendar.MONTH_OF_YEAR, HijriMonth.MUHARRAM);
HijriCalendar h1 = htemp.with(HijriCalendar.DAY_OF_MONTH.minimized()).minus(tolerance);
HijriCalendar h2 = htemp.with(HijriCalendar.DAY_OF_MONTH.maximized()).plus(tolerance);
boolean inTimePeriod = !(today.isBefore(h1) || today.isAfter(h2));
1 голос
/ 29 апреля 2020

tl; dr

HijrahDate
.from
(
    LocalDate.of( 2020 , Month.JANUARY , 23 ) 
)
.plus
(
    Period.ofDays( 5 ) 
)
.isBefore
(
    someOtherDate
)

Подробности

Современный подход использует классы java .time , встроенные в Java 8 и более поздние версии, и Android 26 и позже. Для более ранних версий см. Проекты ThreeTen-Backport и ThreeTenABP .

Проект Joda-Time является предшественником java .time . Оба основаны и возглавляются одним и тем же человеком, Стивеном Коулборном.

HijrahChronology является частью java .time . HijrahChronology следует правилам календарной системы хиджры. Календарь хиджры - это лунный календарь с поддержкой календарей Ислами c.

Класс HijrahDate представляет дату в системе календаря хиджры.

Переполнение стека поиска в узнайте больше, так как это уже неоднократно освещалось.

Я не эксперт по ислами c календарям или HijrahChronology, но я считаю, что вы можете конвертировать между датой хиджры и григорианской (prolepti *) 1126 *) дату, вызвав метод from для классов HijrahDate и LocalDate.

LocalDate localDate1 = LocalDate.of( 2020 , Month.JANUARY , 23 ) ;
HijrahDate hijrahDate = HijrahDate.from( localDate1 ) ;

… и…

LocalDate localDate2 = LocalDate.from( hijrahDate ) ;

Оба класса даты предлагают plus и minus методы, которые принимают объект Period.

LocalDate later = localDate2.plus( Period.ofDays( 5 ) ) ;

Сравните с isEqual, isBefore и isAfter.

boolean match = localDate1.isEqual( localDate2 ) ;

Дамп на консоль.

System.out.println( "localDate1.toString(): " + localDate1 ) ;
System.out.println( "hijrahDate.toString(): " + hijrahDate ) ;
System.out.println( "localDate2.toString(): " + localDate2 ) ;
System.out.println( "match: " + localDate1.isEqual( localDate2 ) ) ;
System.out.println( "later.toString(): " + later ) ;

См. Этот код, запущенный в режиме реального времени на IdeOne.com .

localDate1.toString (): 2020-01-23

hijrahDate.toString (): Hijrah-umalqura AH 1441-05-28

localDate2.toString (): 2020-01-23

match: true

Later.toString (): 2020-01-28 * 1 073 *

Вот полный пример. Используемый здесь метод сравнения для промежутка времени - Half-Open, где начало включительно , а окончание exclusive . Такой подход обычно лучше всего подходит для обработки даты и времени. Этот подход позволяет диапазонам дат аккуратно прилегать друг к другу без пропусков или перекрытий.

LocalDate localDate = LocalDate.of( 2020 , Month.JANUARY , 23 );
HijrahDate hijrahDate = HijrahDate.from( localDate );

// Target range is five days before and after some specific date.
HijrahDate target = HijrahDate.from( LocalDate.of( 2020 , Month.MARCH , 14 ) );
Period period = Period.ofDays( 5 );
LocalDate start = LocalDate.from( target ).minus( period );
LocalDate end = LocalDate.from( target ).plus( period );

// Tip: A shorter way of asking "Is equal to or later" is "Is not before".
boolean withinTargetRange = ( ! hijrahDate.isBefore( start ) ) && hijrahDate.isBefore( end );

Дамп в консоль.

System.out.println( "localDate = " + localDate );
System.out.println( "hijrahDate = " + hijrahDate );
System.out.println( "target = " + target );
System.out.println( "withinTargetRange = " + withinTargetRange );

localDate = 2020-01-23

hijrahDate = Hijrah-umalqura AH 1441-05-28

target = Hijrah-umalqura AH 1441-07-19

WithinTargetRange = false

ThreeTen-Extra

Если вы выполняете большую часть этой работы, я предлагаю добавить библиотеку ThreeTen-Extra , также основанную и возглавляемую Стивеном Коулборном. Класс LocalDateRange в этой библиотеке представляет промежуток времени в виде пары LocalDate объектов. Этот класс включает такие методы, как contains, abuts, overlaps и другие. Я не знаю, насколько хорошо эта библиотека работает в Android. Если вы плохо работаете в Android, возможно, вы захотите вставить копию исходного кода класса в свою кодовую базу, при условии, что вы можете соблюдать условия его лицензии BSD-3 .

Вот пример использования LocalDateRange::contains.

LocalDate localDate = LocalDate.of( 2020 , Month.JANUARY , 23 );
HijrahDate hijrahDate = HijrahDate.from( localDate );

HijrahDate target = HijrahDate.from( LocalDate.of( 2020 , Month.MARCH , 14 ) );
Period period = Period.ofDays( 5 );
LocalDate start = LocalDate.from( target ).minus( period );
LocalDate end = LocalDate.from( target ).plus( period );
LocalDateRange range = LocalDateRange.of( start , end );

boolean withinTargetRange = range.contains( LocalDate.from( hijrahDate ) );
localDate = 2020-01-23
hijrahDate = Hijrah-umalqura AH 1441-05-28
target = Hijrah-umalqura AH 1441-07-19
range = 2020-03-09/2020-03-19
withinTargetRange = false
0 голосов
/ 29 апреля 2020

Поймите, что даты и время внутренне представлены в компьютерах как смещение от эпохи: https://en.wikipedia.org/wiki/Epoch_ (вычисления)

В Java вы можете получить это значение, используя System .currentTimeMillis ();

Вы также можете рассчитать разницу в днях, вычитая два числа даты и применяя деление для преобразования единиц.

long days = (date2 - date1) 
  / 1000 // MS
  / 60 // Secs
  / 60 // Mins
  / 24 // Hours
...