私はJava Appを開発しており、timeStamp
(long
に)があります。このコードを使用してグレゴリオ暦の日付に簡単に変更できます。
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timeStamp);
しかし、Jalaliカレンダーに日付が必要です。検索しましたが、良いライブラリが見つかりませんでした。変換(またはtimeStamp
からJalali形式の日付を作成)するための信頼できる優れたライブラリを知っていますか?実装もアルゴリズムも必要ありません。この問題はバグが多く、多くのルールがあるため、信頼できるソリューションが必要です。
これを見てください: https://github.com/amirmehdizadeh/JalaliCalendar
このコードは、Mavenベースのプロジェクトであり、多くの単体テストに適しています。
ローカリゼーションと言語サポートを改善するには、IBMの [〜#〜] icu [〜#〜] (Unicodeの国際コンポーネント)ライブラリを使用すると便利です。
APIは標準のJava APIに似ていますが、ローカリゼーションと国際化のサポートを追加します(たとえば、時間とカレンダーの問題、並べ替え、フォーマットルール、適切な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でも利用できます。
ライブラリ内でJava Time4J 。で独自のペルシャ(jalali)カレンダーを開発しました。実装では Borkowski (で有効)少なくともグレゴリオ暦2129年まで-2025-バグなし)。
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
もちろん、カレンダーには、日付の算術演算(日または月の追加、日、月などのデルタの計算など)やフィールド/要素操作(月の最後の日に簡単に行くなど)などの機能があります。
ここで提案されている他のライブラリに関するサイドノート:
ライブラリ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)
internationalizationについて、ペルシャ暦のカレンダーはICL4Jが最新のCLDRバージョンv28に基づいているため、ICU4JがTime4J以上を提供しているとは思いません。も。 Time4Jは、実際にはペルシャの月と時代(ペルシア語とパシュトゥー語を含む)で約25の言語をサポートしています。
Javaで JalCal Jalali(Persian)Calender Converterを使用できます。
<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");