A good date converter for Jalali Calendar in Java? [closed]
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:
چهارشنبه ۱۰ اردیبهشت ۱۳۹۳ ه.ش.
Take a look on this: https://github.com/amirmehdizadeh/JalaliCalendar
The code looks nice, maven based project, a lot of unit tests.
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
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); // 11th month (Bahman)
YearMonthDate gregorian = JalaliCalendar.jalaliToGregorian(jalali);
System.out.println(gregorian); // 2016/0/25 => 1st month (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).
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");