A good date converter for Jalali Calendar in Java?

2019-01-10 14:11发布

I'm developing a Java App and I have a timeStamp (in long). I can easily use this code to change it to a Gregorian date:

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

But I need to have the date in Jalali Calendar. I searched but didn't found any good library. Do you know a reliable and good library for converting (or creating dates in Jalali format from timeStamp)? I don't need an implementation or an algorithm, cause this issue is too buggy and has a lot of rules, I need a reliable solution

6条回答
做个烂人
2楼-- · 2019-01-10 14:48

There is a good library on github which has a very simple API and it has a lot of capabilities and it also it available on mavenCentral :

https://github.com/razeghi71/JalaliCalendar

查看更多
Emotional °昔
3楼-- · 2019-01-10 14:55

I have developed my own Persian (jalali) calendar in Java within my library Time4J. The implementation deploys the algorithm of Borkowski (valid at least until gregorian year 2129 - no 2025-bug).

Solution for the concrete problem of OP:

// 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

Of course, the calendar offers more features like date arithmetic (adding days or months, calculating the delta in days, months etc.) or field/element-manipulations (easy going to the last day of month etc).

Side notes about other libraries proposed here so far:

The libraries amirmehdizadeh/JalaliCalendar as well as ICU4J both use zero-based months. This can be extremely confusing. Non-intuitive example using amirmehdizadeh's library:

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)

About internationalization, I don't think that ICU4J offers more than Time4J on the area of Persian calendar since latter one is based on newest CLDR-version v28, too. Time4J actually supports about 25 languages for Persian months and eras (including Farsi and Pashto).

查看更多
干净又极端
4楼-- · 2019-01-10 15:05

You can use JalCal that Jalali(Persian) Calender Convertor in Java:

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

1. Jalali to Gregorian

  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. Gregorian to Jalali

    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");
查看更多
爷的心禁止访问
5楼-- · 2019-01-10 15:10

You can find a graphical java-based Jalali calendar called persain-calendar. Here is a screenshot of Persian-calendar.

Persian-calendar

查看更多
倾城 Initia
6楼-- · 2019-01-10 15:11

Take a look on this: https://github.com/amirmehdizadeh/JalaliCalendar

The code looks nice, maven based project, a lot of unit tests.

查看更多
爱情/是我丢掉的垃圾
7楼-- · 2019-01-10 15:12

For better localization and language support, it is often convenient to use the ICU (International Components for Unicode) library from IBM.

The APIs are similar to the standard Java APIs, but add additional support for localization and internationalization (e.g. time and calendar issues, sorting, formatting rules and a regex implementation with proper Unicode support).

To create a Persian calendar and output the formatted date in Farsi, you would e.g. do something like this:

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));

This will output:

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

查看更多
登录 后发表回答