Хороший конвертер дат для Jalali Calendar на Java?

Я разрабатываю Java-приложение, и у меня есть timeStampLong). Я могу легко использовать этот код, чтобы изменить его на григорианскую дату:

Calendar calendar=Calendar.getInstance();
calendar.setTimeInMillis(timeStamp);

Но мне нужно иметь дату в календаре Джалали. Я искал, но не нашел хорошей библиотеки. Знаете ли вы надежную и хорошую библиотеку для конвертации (или создания дат в формате Jalali frome timeStamp). Мне не нужна ваша реализация или алгоритм, потому что эта проблема слишком глючная и имеет много правил, мне нужно надежное решение

Благодарю.

6 ответов

Решение

Посмотрите на это: https://github.com/amirmehdizadeh/JalaliCalendar

Код выглядит красиво, проект на основе Maven, много юнит-тестов.

Для лучшей локализации и языковой поддержки часто удобно использовать библиотеку ICU (International Components for Unicode) от IBM.

API-интерфейсы аналогичны стандартным API-интерфейсам Java, но добавляют дополнительную поддержку для локализации и интернационализации (например, проблемы времени и календаря, сортировка, правила форматирования и реализация регулярных выражений с соответствующей поддержкой Unicode).

Чтобы создать персидский календарь и вывести отформатированную дату на фарси, вы, например, должны сделать что-то вроде этого:

import com.ibm.icu.text.DateFormat;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.ULocale;

...

ULocale locale = new ULocale("fa_IR@calendar=persian");

Calendar calendar = Calendar.getInstance(locale);
DateFormat df = DateFormat.getDateInstance(DateFormat.FULL, locale);

System.out.println(df.format(calendar));

Это выведет:

چهارشنبه ۱۰ اردیبهشت ۱۳۹۳ ه‍.ش.

На github есть хорошая библиотека с очень простым API, множеством возможностей и доступностью на mavenCentral:

https://github.com/razeghi71/JalaliCalendar

Я разработал свой собственный персидский (jalali) календарь на Java в моей библиотеке Time4J. Реализация развертывает алгоритм Борковского (действителен, по крайней мере, до григорианского 2129 года - без 2025-ошибка).

Решение для конкретной проблемы ОП:

// conversion from jalali to gregorian by constructed input
PersianCalendar jalali = PersianCalendar.of(1394, 11, 5);
// or use a safe enum instead of the month number:
// PersianCalendar jalali = PersianCalendar.of(1394, PersianMonth.BAHMAN, 5);

PlainDate gregorian = jalali.transform(PlainDate.class); 
System.out.println(gregorian); // 2016-01-25

// conversion to millis-since-unix (timezone-dependent)
Moment moment1 = gregorian.atStartOfDay().inTimezone(ASIA.TEHRAN);
long millisSinceUnix = TemporalType.MILLIS_SINCE_UNIX.from(moment1);
System.out.println(millisSinceUnix); // 1453667400000L

// conversion of millis-since-unix to jalali (timezone-dependent)
Moment moment2 = TemporalType.MILLIS_SINCE_UNIX.translate(millisSinceUnix);
PlainDate gregorian2 = moment2.toZonalTimestamp(ASIA.TEHRAN).toDate();
System.out.println(gregorian2.transform(PersianCalendar.class)); // AP-1394-11-05

// formatting and parsing in Farsi language using full style
ChronoFormatter<PersianCalendar> f1 = 
    ChronoFormatter.ofStyle(DisplayMode.FULL, new Locale("fa"), PersianCalendar.axis());
System.out.println(f1.format(jalali)); // ه‍.ش. ۱۳۹۴ بهمن ۵, دوشنبه
System.out.println(f1.parse("ه‍.ش. ۱۳۹۴ بهمن ۵, دوشنبه")); // AP-1394-11-05

// formatting in English language using custom pattern
ChronoFormatter<PersianCalendar> f2 = 
    ChronoFormatter.ofPattern(
        "d. MMMM yyyy", PatternType.CLDR, Locale.ENGLISH, PersianCalendar.axis());
System.out.println(f2.format(jalali)); // 5. Bahman 1394

Конечно, календарь предлагает больше функций, таких как арифметика дат (добавление дней или месяцев, вычисление дельты в днях, месяцах и т. Д.) Или манипулирование полями / элементами (переход к последнему дню месяца и т. Д.).

Дополнительные замечания о других библиотеках, предложенных здесь до сих пор:

Библиотеки amirmehdizadeh / JalaliCalendar, а также ICU4J используют месяцы, начинающиеся с нуля. Это может быть очень запутанным. Неинтуитивный пример использования библиотеки amirmehdizadeh:

YearMonthDate jalali = new YearMonthDate(1394, 10, 5); // really month 11 (Bahman)
YearMonthDate gregorian = JalaliCalendar.jalaliToGregorian(jalali);
System.out.println(gregorian); // 2016/0/25 => really month 1 (January)

Что касается интернационализации, я не думаю, что ICU4J предлагает больше, чем Time4J в области персидского календаря, поскольку последний также основан на новейшей CLDR-версии v28. Time4J поддерживает около 25 языков для персидских месяцев и эпох (включая фарси и пушту).

Вы можете использовать JalCal, который Jalali (персидский) Calender Convertor в Java:

<dependency>
    <groupId>com.github.sbahmani</groupId>
    <artifactId>jalcal</artifactId>
    <version>1.0</version>
</dependency>

1. Джалали на григорианский

  Calendar expected4 = Calendar.getInstance(TimeZone.getDefault());
  expected4.set(2014, 7, 5, 1, 23, 1);
  assertThat(JalCal.jalaliToGregorian(1393, 5, 14, 1, 23, 1).toString()).isEqualTo(expected4.getTime().toString());

2. Григорианский в Джалали

    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.DAY_OF_MONTH, 5);
    cal.set(Calendar.MONTH, 6);
    cal.set(Calendar.YEAR, 2014);
    cal.set(Calendar.HOUR_OF_DAY, 10);
    cal.set(Calendar.MINUTE, 25);
    cal.set(Calendar.SECOND, 1);
    cal.set(Calendar.MILLISECOND, 0);
    assertThat(JalCal.gregorianToJalali(cal.getTime(), true)).isEqualTo("14/04/1393   10:25:01");
    assertThat(JalCal.gregorianToJalali(new Date(1426883400000l), true)).isEqualTo("01/01/1394   00:00:00");

Вы можете найти графический Jalali-календарь на основе Java, называемый persain-calendar. Вот скриншот персидского календаря.

Персидско-календарь

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