A good date converter for Jalali Calendar in Java?

JavaDateLocalizationCalendarJalali Calendar

Java Problem Overview


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

Java Solutions


Solution 1 - Java

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:

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

Solution 2 - Java

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

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

Solution 3 - Java

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

Solution 4 - Java

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

Solution 5 - Java

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSaeedView Question on Stackoverflow
Solution 1 - JavajarnbjoView Answer on Stackoverflow
Solution 2 - JavaAlexRView Answer on Stackoverflow
Solution 3 - JavaMohammad RazeghiView Answer on Stackoverflow
Solution 4 - JavaMeno HochschildView Answer on Stackoverflow
Solution 5 - JavaSajad BahmaniView Answer on Stackoverflow