Android中是否有波斯(Shamsi或Jalali)日历的库或algorithm?

我想将公历(西方)date转换为波斯语(沙姆西)date,反之亦然,适用于所有版本的Android。

有没有完整可靠的库或algorithm?

我正在使用这个algorithm多年,这是非常准确的。

使用它,享受! 🙂

public class Utilities { private class SolarCalendar { public String strWeekDay = ""; public String strMonth = ""; int date; int month; int year; public SolarCalendar() { Date MiladiDate = new Date(); calcSolarCalendar(MiladiDate); } public SolarCalendar(Date MiladiDate) { calcSolarCalendar(MiladiDate); } private void calcSolarCalendar(Date MiladiDate) { int ld; int miladiYear = MiladiDate.getYear() + 1900; int miladiMonth = MiladiDate.getMonth() + 1; int miladiDate = MiladiDate.getDate(); int WeekDay = MiladiDate.getDay(); int[] buf1 = new int[12]; int[] buf2 = new int[12]; buf1[0] = 0; buf1[1] = 31; buf1[2] = 59; buf1[3] = 90; buf1[4] = 120; buf1[5] = 151; buf1[6] = 181; buf1[7] = 212; buf1[8] = 243; buf1[9] = 273; buf1[10] = 304; buf1[11] = 334; buf2[0] = 0; buf2[1] = 31; buf2[2] = 60; buf2[3] = 91; buf2[4] = 121; buf2[5] = 152; buf2[6] = 182; buf2[7] = 213; buf2[8] = 244; buf2[9] = 274; buf2[10] = 305; buf2[11] = 335; if ((miladiYear % 4) != 0) { date = buf1[miladiMonth - 1] + miladiDate; if (date > 79) { date = date - 79; if (date <= 186) { switch (date % 31) { case 0: month = date / 31; date = 31; break; default: month = (date / 31) + 1; date = (date % 31); break; } year = miladiYear - 621; } else { date = date - 186; switch (date % 30) { case 0: month = (date / 30) + 6; date = 30; break; default: month = (date / 30) + 7; date = (date % 30); break; } year = miladiYear - 621; } } else { if ((miladiYear > 1996) && (miladiYear % 4) == 1) { ld = 11; } else { ld = 10; } date = date + ld; switch (date % 30) { case 0: month = (date / 30) + 9; date = 30; break; default: month = (date / 30) + 10; date = (date % 30); break; } year = miladiYear - 622; } } else { date = buf2[miladiMonth - 1] + miladiDate; if (miladiYear >= 1996) { ld = 79; } else { ld = 80; } if (date > ld) { date = date - ld; if (date <= 186) { switch (date % 31) { case 0: month = (date / 31); date = 31; break; default: month = (date / 31) + 1; date = (date % 31); break; } year = miladiYear - 621; } else { date = date - 186; switch (date % 30) { case 0: month = (date / 30) + 6; date = 30; break; default: month = (date / 30) + 7; date = (date % 30); break; } year = miladiYear - 621; } } else { date = date + 10; switch (date % 30) { case 0: month = (date / 30) + 9; date = 30; break; default: month = (date / 30) + 10; date = (date % 30); break; } year = miladiYear - 622; } } switch (month) { case 1: strMonth = "فروردين"; break; case 2: strMonth = "ارديبهشت"; break; case 3: strMonth = "خرداد"; break; case 4: strMonth = "تير"; break; case 5: strMonth = "مرداد"; break; case 6: strMonth = "شهريور"; break; case 7: strMonth = "مهر"; break; case 8: strMonth = "آبان"; break; case 9: strMonth = "آذر"; break; case 10: strMonth = "دي"; break; case 11: strMonth = "بهمن"; break; case 12: strMonth = "اسفند"; break; } switch (WeekDay) { case 0: strWeekDay = "يکشنبه"; break; case 1: strWeekDay = "دوشنبه"; break; case 2: strWeekDay = "سه شنبه"; break; case 3: strWeekDay = "چهارشنبه"; break; case 4: strWeekDay = "پنج شنبه"; break; case 5: strWeekDay = "جمعه"; break; case 6: strWeekDay = "شنبه"; break; } } } public static String getCurrentShamsidate() { Locale loc = new Locale("en_US"); Utilities util = new Utilities(); SolarCalendar sc = util.new SolarCalendar(); return String.valueOf(sc.year) + "/" + String.format(loc, "%02d", sc.month) + "/" + String.format(loc, "%02d", sc.date); } } 

我觉得这个java类更容易使用,更可靠。 我在伊朗的论坛上发现,伊朗人使用哈拉利日历,并称之为“沙姆西”,这意味着太阳日历。 这是Java类:

 package MyUtil; import java.util.Calendar; import java.util.GregorianCalendar; /** * Title: Calender Conversion class * Description: Convert Iranian (Jalali), Julian, and Gregorian dates to * each other * Public Methods Summary: * ----------------------- * JavaSource_Calendar(); * JavaSource_Calendar(int year, int month, int day); * int getIranianYear(); * int getIranianMonth(); * int getIranianDay(); * int getGregorianYear(); * int getGregorianMonth(); * int getGregorianDay(); * int getJulianYear(); * int getJulianMonth(); * int getJulianDay(); * String getIranianDate(); * String getGregorianDate(); * String getJulianDate(); * String getWeekDayStr(); * String toString(); * int getDayOfWeek(); * void nextDay(); * void nextDay(int days); * void previousDay(); * void previousDay(int days); * void setIranianDate(int year, int month, int day); * void setGregorianDate(int year, int month, int day); * void setJulianDate(int year, int month, int day); */ public class CalendarTool { /** * JavaSource_Calendar: * The default constructor uses the current Gregorian date to initialize the * other private memebers of the class (Iranian and Julian dates). */ public CalendarTool() { Calendar calendar = new GregorianCalendar(); setGregorianDate(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH)+1, calendar.get(Calendar.DAY_OF_MONTH)); } /** * JavaSource_Calendar: * This constructor receives a Gregorian date and initializes the other private * members of the class accordingly. * @param year int * @param month int * @param day int */ public CalendarTool(int year, int month, int day) { setGregorianDate(year,month,day); } /** * getIranianYear: * Returns the 'year' part of the Iranian date. * @return int */ public int getIranianYear() { return irYear; } /** * getIranianMonth: * Returns the 'month' part of the Iranian date. * @return int */ public int getIranianMonth() { return irMonth; } /** * getIranianDay: * Returns the 'day' part of the Iranian date. * @return int */ public int getIranianDay() { return irDay; } /** * getGregorianYear: * Returns the 'year' part of the Gregorian date. * @return int */ public int getGregorianYear() { return gYear; } /** * getGregorianMonth: * Returns the 'month' part of the Gregorian date. * @return int */ public int getGregorianMonth() { return gMonth; } /** * getGregorianDay: * Returns the 'day' part of the Gregorian date. * @return int */ public int getGregorianDay() { return gDay; } /** * getJulianYear: * Returns the 'year' part of the Julian date. * @return int */ public int getJulianYear() { return juYear; } /** * getJulianMonth: * Returns the 'month' part of the Julian date. * @return int */ public int getJulianMonth() { return juMonth; } /** * getJulianDay() * Returns the 'day' part of the Julian date. * @return int */ public int getJulianDay() { return juDay; } /** * getIranianDate: * Returns a string version of Iranian date * @return String */ public String getIranianDate() { return (irYear+"/"+irMonth+"/"+irDay); } /** * getGregorianDate: * Returns a string version of Gregorian date * @return String */ public String getGregorianDate() { return (gYear+"/"+gMonth+"/"+gDay); } /** * getJulianDate: * Returns a string version of Julian date * @return String */ public String getJulianDate() { return (juYear+"/"+juMonth+"/"+juDay); } /** * getWeekDayStr: * Returns the week day name. * @return String */ public String getWeekDayStr() { String weekDayStr[]={ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; return (weekDayStr[getDayOfWeek()]); } /** * toString: * Overrides the default toString() method to return all dates. * @return String */ public String toString() { return (getWeekDayStr()+ ", Gregorian:["+getGregorianDate()+ "], Julian:["+getJulianDate()+ "], Iranian:["+getIranianDate()+"]"); } /** * getDayOfWeek: * Returns the week day number. Monday=0..Sunday=6; * @return int */ public int getDayOfWeek() { return (JDN % 7); } /** * nextDay: * Go to next julian day number (JDN) and adjusts the other dates. */ public void nextDay() { JDN++; JDNToIranian(); JDNToJulian(); JDNToGregorian(); } /** * nextDay: * Overload the nextDay() method to accept the number of days to go ahead and * adjusts the other dates accordingly. * @param days int */ public void nextDay(int days) { JDN+=days; JDNToIranian(); JDNToJulian(); JDNToGregorian(); } /** * previousDay: * Go to previous julian day number (JDN) and adjusts the otehr dates. */ public void previousDay() { JDN--; JDNToIranian(); JDNToJulian(); JDNToGregorian(); } /** * previousDay: * Overload the previousDay() method to accept the number of days to go backward * and adjusts the other dates accordingly. * @param days int */ public void previousDay(int days) { JDN-=days; JDNToIranian(); JDNToJulian(); JDNToGregorian(); } /** * setIranianDate: * Sets the date according to the Iranian calendar and adjusts the other dates. * @param year int * @param month int * @param day int */ public void setIranianDate(int year, int month, int day) { irYear =year; irMonth = month; irDay = day; JDN = IranianDateToJDN(); JDNToIranian(); JDNToJulian(); JDNToGregorian(); } /** * setGregorianDate: * Sets the date according to the Gregorian calendar and adjusts the other dates. * @param year int * @param month int * @param day int */ public void setGregorianDate(int year, int month, int day) { gYear = year; gMonth = month; gDay = day; JDN = gregorianDateToJDN(year,month,day); JDNToIranian(); JDNToJulian(); JDNToGregorian(); } /** * setJulianDate: * Sets the date according to the Julian calendar and adjusts the other dates. * @param year int * @param month int * @param day int */ public void setJulianDate(int year, int month, int day) { juYear = year; juMonth = month; juDay = day; JDN = julianDateToJDN(year,month,day); JDNToIranian(); JDNToJulian(); JDNToGregorian(); } /** * IranianCalendar: * This method determines if the Iranian (Jalali) year is leap (366-day long) * or is the common year (365 days), and finds the day in March (Gregorian * Calendar)of the first day of the Iranian year ('irYear').Iranian year (irYear) * ranges from (-61 to 3177).This method will set the following private data * members as follows: * leap: Number of years since the last leap year (0 to 4) * Gy: Gregorian year of the begining of Iranian year * march: The March day of Farvardin the 1st (first day of jaYear) */ private void IranianCalendar() { // Iranian years starting the 33-year rule int Breaks[]= {-61, 9, 38, 199, 426, 686, 756, 818,1111,1181, 1210,1635,2060,2097,2192,2262,2324,2394,2456,3178} ; int jm,N,leapJ,leapG,jp,j,jump; gYear = irYear + 621; leapJ = -14; jp = Breaks[0]; // Find the limiting years for the Iranian year 'irYear' j=1; do{ jm=Breaks[j]; jump = jm-jp; if (irYear >= jm) { leapJ += (jump / 33 * 8 + (jump % 33) / 4); jp = jm; } j++; } while ((j<20) && (irYear >= jm)); N = irYear - jp; // Find the number of leap years from AD 621 to the begining of the current // Iranian year in the Iranian (Jalali) calendar leapJ += (N/33 * 8 + ((N % 33) +3)/4); if ( ((jump % 33) == 4 ) && ((jump-N)==4)) leapJ++; // And the same in the Gregorian date of Farvardin the first leapG = gYear/4 - ((gYear /100 + 1) * 3 / 4) - 150; march = 20 + leapJ - leapG; // Find how many years have passed since the last leap year if ( (jump - N) < 6 ) N = N - jump + ((jump + 4)/33 * 33); leap = (((N+1) % 33)-1) % 4; if (leap == -1) leap = 4; } /** * IsLeap: * This method determines if the Iranian (Jalali) year is leap (366-day long) * or is the common year (365 days), and finds the day in March (Gregorian * Calendar)of the first day of the Iranian year ('irYear').Iranian year (irYear) * ranges from (-61 to 3177).This method will set the following private data * members as follows: * leap: Number of years since the last leap year (0 to 4) * Gy: Gregorian year of the begining of Iranian year * march: The March day of Farvardin the 1st (first day of jaYear) */ public boolean IsLeap(int irYear1) { // Iranian years starting the 33-year rule int Breaks[]= {-61, 9, 38, 199, 426, 686, 756, 818,1111,1181, 1210,1635,2060,2097,2192,2262,2324,2394,2456,3178} ; int jm,N,leapJ,leapG,jp,j,jump; gYear = irYear1 + 621; leapJ = -14; jp = Breaks[0]; // Find the limiting years for the Iranian year 'irYear' j=1; do{ jm=Breaks[j]; jump = jm-jp; if (irYear1 >= jm) { leapJ += (jump / 33 * 8 + (jump % 33) / 4); jp = jm; } j++; } while ((j<20) && (irYear1 >= jm)); N = irYear1 - jp; // Find the number of leap years from AD 621 to the begining of the current // Iranian year in the Iranian (Jalali) calendar leapJ += (N/33 * 8 + ((N % 33) +3)/4); if ( ((jump % 33) == 4 ) && ((jump-N)==4)) leapJ++; // And the same in the Gregorian date of Farvardin the first leapG = gYear/4 - ((gYear /100 + 1) * 3 / 4) - 150; march = 20 + leapJ - leapG; // Find how many years have passed since the last leap year if ( (jump - N) < 6 ) N = N - jump + ((jump + 4)/33 * 33); leap = (((N+1) % 33)-1) % 4; if (leap == -1) leap = 4; if (leap==4 || leap==0) return true; else return false; } /** * IranianDateToJDN: * Converts a date of the Iranian calendar to the Julian Day Number. It first * invokes the 'IranianCalender' private method to convert the Iranian date to * Gregorian date and then returns the Julian Day Number based on the Gregorian * date. The Iranian date is obtained from 'irYear'(1-3100),'irMonth'(1-12) and * 'irDay'(1-29/31). * @return long (Julian Day Number) */ private int IranianDateToJDN() { IranianCalendar(); return (gregorianDateToJDN(gYear,3,march)+ (irMonth-1) * 31 - irMonth/7 * (irMonth-7) + irDay -1); } /** * JDNToIranian: * Converts the current value of 'JDN' Julian Day Number to a date in the * Iranian calendar. The caller should make sure that the current value of * 'JDN' is set correctly. This method first converts the JDN to Gregorian * calendar and then to Iranian calendar. */ private void JDNToIranian() { JDNToGregorian(); irYear = gYear - 621; IranianCalendar(); // This invocation will update 'leap' and 'march' int JDN1F = gregorianDateToJDN(gYear,3,march); int k = JDN - JDN1F; if (k >= 0) { if (k <= 185) { irMonth = 1 + k/31; irDay = (k % 31) + 1; return; } else k -= 186; } else { irYear--; k += 179; if (leap == 1) k++; } irMonth = 7 + k/30; irDay = (k % 30) + 1; } /** * julianDateToJDN: * Calculates the julian day number (JDN) from Julian calendar dates. This * integer number corresponds to the noon of the date (ie 12 hours of * Universal Time). This method was tested to be good (valid) since 1 March, * -100100 (of both calendars) up to a few millions (10^6) years into the * future. The algorithm is based on DAHatcher, Q.Jl.R.Astron.Soc. 25(1984), * 53-55 slightly modified by KM Borkowski, Post.Astron. 25(1987), 275-279. * @param year int * @param month int * @param day int * @return int */ private int julianDateToJDN(int year, int month, int day) { return (year + (month - 8) / 6 + 100100) * 1461/4 + (153 * ((month+9) % 12) + 2)/5 + day - 34840408; } /** * JDNToJulian: * Calculates Julian calendar dates from the julian day number (JDN) for the * period since JDN=-34839655 (ie the year -100100 of both calendars) to * some millions (10^6) years ahead of the present. The algorithm is based on * DA Hatcher, Q.Jl.R.Astron.Soc. 25(1984), 53-55 slightly modified by KM * Borkowski, Post.Astron. 25(1987), 275-279). */ private void JDNToJulian() { int j= 4 * JDN + 139361631; int i= ((j % 1461)/4) * 5 + 308; juDay = (i % 153) / 5 + 1; juMonth = ((i/153) % 12) + 1; juYear = j/1461 - 100100 + (8-juMonth)/6; } /** * gergorianDateToJDN: * Calculates the julian day number (JDN) from Gregorian calendar dates. This * integer number corresponds to the noon of the date (ie 12 hours of * Universal Time). This method was tested to be good (valid) since 1 March, * -100100 (of both calendars) up to a few millions (10^6) years into the * future. The algorithm is based on DAHatcher, Q.Jl.R.Astron.Soc. 25(1984), * 53-55 slightly modified by KM Borkowski, Post.Astron. 25(1987), 275-279. * @param year int * @param month int * @param day int * @return int */ private int gregorianDateToJDN(int year, int month, int day) { int jdn = (year + (month - 8) / 6 + 100100) * 1461/4 + (153 * ((month+9) % 12) + 2)/5 + day - 34840408; jdn = jdn - (year + 100100+(month-8)/6)/100*3/4+752; return (jdn); } /** * JDNToGregorian: * Calculates Gregorian calendar dates from the julian day number (JDN) for * the period since JDN=-34839655 (ie the year -100100 of both calendars) to * some millions (10^6) years ahead of the present. The algorithm is based on * DA Hatcher, Q.Jl.R.Astron.Soc. 25(1984), 53-55 slightly modified by KM * Borkowski, Post.Astron. 25(1987), 275-279). */ private void JDNToGregorian() { int j= 4 * JDN + 139361631; j = j + (((((4* JDN +183187720)/146097)*3)/4)*4-3908); int i= ((j % 1461)/4) * 5 + 308; gDay = (i % 153) / 5 + 1; gMonth = ((i/153) % 12) + 1; gYear = j/1461 - 100100 + (8-gMonth)/6; } private int irYear; // Year part of a Iranian date private int irMonth; // Month part of a Iranian date private int irDay; // Day part of a Iranian date private int gYear; // Year part of a Gregorian date private int gMonth; // Month part of a Gregorian date private int gDay; // Day part of a Gregorian date private int juYear; // Year part of a Julian date private int juMonth; // Month part of a Julian date private int juDay; // Day part of a Julian date private int leap; // Number of years since the last leap year (0 to 4) private int JDN; // Julian Day Number private int march; // The march day of Farvardin the first (First day of jaYear) } // End of Class 'JavaSource_Calendar 

您可以轻松设置公历日,月和年,然后调用“getIranianDate()”方法以string格式获取date,就像下面的示例代码一样:

 MyUtil.CalendarTool ct = new CalendarTool(2012,10,10); System.out.println(ct.getIranianDate()); 

我希望它有帮助。

这个方法非常精确,简单也支持闰年

说明:

第一步:今天的时间是包含当前时间

第2步:在几个月内创build两个数列(g_days_in_month&j_days_in_month)

第3步:创build日历(gy,gm,gd)和variablesg_day_no之间的保留时间差的variables,为期几年。

第四步:插入一个月的日子和收集天。

步骤5:将几年的日子换算成Jalili年(jy)

最后:从日数设置加拉里月份,从加拉日日月arrays设置加拉里日。

祝你好运。

  Time today = new Time(Time.getCurrentTimezone()); today.setToNow(); int Day = (today.monthDay); // Day of the month (0-31) int Month = (today.month); // Month (0-11) int Year = (today.year); // Year String persianDate = GregorianToJalali(Year, Month+1, Day); private String GregorianToJalali(int g_y, int g_m, int g_d) { int[] g_days_in_month = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int[] j_days_in_month = {31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29}; int gy = g_y-1600; int gm = g_m-1; int gd = g_d-1; int g_day_no = 365*gy+div(gy+3,4)-div(gy+99,100)+div(gy+399,400); for (int i=0; i < gm; ++i) g_day_no += g_days_in_month[i]; if (gm>1 && ((gy%4==0 && gy%100!=0) || (gy%400==0))) // leap and after Feb g_day_no++; g_day_no += gd; int j_day_no = g_day_no-79; int j_np = div(j_day_no, 12053); //12053 = 365*33 + 32/4 j_day_no = j_day_no % 12053; int jy = 979+33*j_np+4*div(j_day_no,1461); // 1461 = 365*4 + 4/4 j_day_no %= 1461; if (j_day_no >= 366) { jy += div(j_day_no-1, 365); j_day_no = (j_day_no-1)%365; } int j; for (j=0; j < 11 && j_day_no >= j_days_in_month[j]; ++j) j_day_no -= j_days_in_month[j]; int jm = j+1; int jd = j_day_no+1; String Result= jy+"/"+jm+"/"+jd; return (Result); } private int div(float a, float b) { return (int)(a/b); } 

我的图书馆Time4A的最新版本v3.10-2015g( Time4J的Android改编)包含对Jalali日历的支持。 图书馆部署了Borkowskialgorithm(有效期至公元2129年)。 实际上大约有25种语言支持波斯的月份和时代(包括基于CLDR-28的波斯语和普什图语)。

用法示例:

 // current date PersianCalendar jalali = SystemClock.inLocalView().now(PersianCalendar.axis()); System.out.println(jalali); // AP-1394-08-04 // tomorrow jalali = jalali.plus(CalendarDays.ONE); System.out.println(jalali); // AP-1394-08-05 // localized format of tomorrow (English and Farsi) ChronoFormatter<PersianCalendar> f = ChronoFormatter.ofStyle(DisplayMode.FULL, Locale.ENGLISH, PersianCalendar.axis()); Locale farsi = new Locale("fa"); System.out.println(f.format(jalali)); // Tuesday, Aban 5, 1394 AP System.out.println(f.with(farsi).format(jalali)); // سه‌شنبه, آبان 5, 1394 ه‍.ش. // shift back to month Farvardin and format the result jalali = jalali.with(PersianCalendar.MONTH_OF_YEAR, PersianMonth.FARVARDIN); System.out.println(f.format(jalali)); // Wednesday, Farvardin 5, 1394 AP System.out.println(f.with(farsi).format(jalali)); // چهارشنبه, فروردین 5, 1394 ه‍.ش. // conversion to gregorian date System.out.println(jalali); // AP-1394-01-05 System.out.println(jalali.transform(PlainDate.class)); // 2015-03-25 // create new year in persian calendar and show gregorian counter part jalali = PersianCalendar.of(1394, PersianMonth.FARVARDIN, 1); System.out.println(jalali.transform(PlainDate.class)); // 2015-03-21 // create new year in gregorian calendar and show persian counter part PlainDate gregorianDate = PlainDate.of(2015, Month.JANUARY, 1); System.out.println(gregorianDate.transform(PersianCalendar.class)); // AP-1393-10-11 // delta between gregorian new year and persian new year System.out.println(CalendarDays.between(gregorianDate, jalali).getAmount()); // 79 

与Android上的java.util.Date的互操作性

由于Time4Apipe理自己的一套不可变的types,而不是基于Android的主要时间types,我显示以下桥梁:

 // Time4A => Android PlainDate gdate = jalali.transform(PlainDate.class); Moment m1 = gdate.atStartOfDay().inTimezone(ASIA.TEHRAN); java.util.Date jud = TemporalType.JAVA_UTIL_DATE.from(m1); // Android => Time4A java.util.Date input = new java.util.Date(); Moment m2 = TemporalType.JAVA_UTIL_DATE.translate(input); jalali = m2.toZonalTimestamp(ASIA.TEHRAN).toDate().transform(PersianCalendar.class); 

使用Unicode的国际组件 ( icu4j )。 它是Unicode Consortium的一部分,非常可靠,可用于任何Java项目(Java EE,Java SE,Android等)。 与GradleMaven一起使用,或者只需下载 jar。

你可以期待java.util.Calendarfunction和一些额外的function。

 import com.ibm.icu.util.Calendar; import com.ibm.icu.util.ULocale; ... ULocale locale = new ULocale("fa_IR@calendar=persian"); Calendar persianCalendar = Calendar.getInstance(locale); persianCalendar.clear(); persianCalendar.set(1395, 3, 10); // Tir(4th month) 10th 1395 equivalent to June 30th 2016 java.util.Date gregorianDate = persianCalendar.getTime(); System.out.println(gregorianDate); // Thu Jun 30 00:00:00 IDT 2016 // Gregorian to Persian java.util.Calendar gregorianCal = java.util.GregorianCalendar.getInstance(); gregorianCal.set(2016, java.util.Calendar.JUNE, 30); persianCalendar.setTime(gregorianCal.getTime()); System.out.println(persianCalendar.get(Calendar.YEAR)); //1395 System.out.println(persianCalendar.get(Calendar.MONTH)); // 3 System.out.println(persianCalendar.get(Calendar.DAY_OF_MONTH)); // 10 

如果你需要波斯文输出:

 import com.ibm.icu.text.DateFormat; import com.ibm.icu.text.SimpleDateFormat; ... // full date output in persian DateFormat df = DateFormat.getDateInstance(DateFormat.FULL, locale); System.out.println(df.format(persianCalendar.getTime())); // year output in persian SimpleDateFormat sdf1 = new SimpleDateFormat(SimpleDateFormat.YEAR, locale); System.out.println(sdf1.format(persianCalendar.getTime())); // month name output in persian SimpleDateFormat sdf2 = new SimpleDateFormat(SimpleDateFormat.MONTH, locale); System.out.println(sdf2.format(persianCalendar.getTime())); // weekday name output in persian SimpleDateFormat sdf3 = new SimpleDateFormat(SimpleDateFormat.WEEKDAY, locale); System.out.println(sdf3.format(persianCalendar.getTime())); // full date output in YY/MM/dd form SimpleDateFormat sdf4 = new SimpleDateFormat("YY/MM/dd", locale); System.out.println(sdf4.format(persianCalendar.getTime())); 

输出:

 ه‍.ش. ۱۳۹۵ تیر ۱۰, پنجشنبه ۱۳۹۵ تیر پنجشنبه ۹۵/۰۴/۱۰ 

如果您需要输出英文, new ULocale("fa_IR@calendar=persian")更改为new ULocale("@calendar=persian")

输出:

 AP 1395 Tir 10, Thu 1395 Tir Thu 95/04/10 

其他好东西:

 // Get number of days in month System.out.println(persianCalendar.getActualMaximum(Calendar.DAY_OF_MONTH)); // 31 // Get first day of week System.out.println(persianCalendar.getFirstDayOfWeek()); // 7 (Saturday according to docs) // Add some amount of time persianCalendar.add(Calendar.MONTH, 2); System.out.println(persianCalendar.get(Calendar.YEAR)); //1395 System.out.println(persianCalendar.get(Calendar.MONTH)); // 5 System.out.println(persianCalendar.get(Calendar.DAY_OF_MONTH)); // 10 

其他function见icu4j演示 ,特别是:

  • 演示各种日历字段
  • 当年的星期二和星期四
  • 将数字转换为文本表示的演示 (使用fa_IR作为语言环境)

另请参阅Calendar和PersianCalendar API。

备注

如果你关心的是icu4j的尺寸(jar尺寸对你来说很高),那么你可以重build它,并使用日历模块(2,176KB)。 在这里阅读。

尝试这个

 import java.util.Calendar; import java.util.Date; public class PersianCalendar { String[] weekDayNames = { "شنبه","یکشنبه","دوشنبه", "سه شنبه", "چهارشنبه", "پنج شنبه", "جمعه" }; String[] monthNames ={ "فروردین","اردیبهشت","خرداد","تیر", "مرداد","شهریور", "مهر", "آبان", "آذر","دی", "بهمن","اسفند" }; String strWeekDay = ""; String strMonth = ""; int day; int month; int year; int ld; Calendar calendar = Calendar.getInstance(); int gregorianYear =calendar.get(Calendar.YEAR); int gregorianMonth = calendar.get(Calendar.MONTH)+1; int gregorianDate = calendar.get(Calendar.DATE); int WeekDay = calendar.get(Calendar.DAY_OF_WEEK); int[] buf1 = {0,31,59,90,120,151,181,212,243,273,304,334}; int[] buf2 = {0,31,60, 91,121,152,182, 213, 244, 274,305,335}; public PersianCalendar(){ Date gregorianDate = new Date(); calendar.setTime(gregorianDate); toPersian(gregorianDate); } public PersianCalendar(Date gregorianDate){ calendar.setTime(gregorianDate); toPersian(gregorianDate); } private void toPersian(Date gregorianDate) { if ((gregorianYear % 4) != 0) func1(); else func2(); strMonth = monthNames[month-1]; strWeekDay = weekDayNames[WeekDay]; } private void func1() { day = buf1[gregorianMonth - 1] + gregorianDate; if (day > 79){ day = day - 79; if (day <= 186) { int day2 = day; month = (day2 / 31) + 1; day = (day2 % 31); if(day2 % 31 == 0){ month--; day = 31; } year = gregorianYear - 621; } else { int day2 = day - 186; month = (day2 / 30) + 7; day = (day2 % 30); if(day2 % 30 == 0){ month = (day2 / 30) + 6; day = 30; } year = gregorianYear - 621; } } else{ ld = gregorianYear > 1996 && gregorianYear % 4 == 1 ? 11 : 10 ; int day2 = day + ld; month = (day2 / 30) + 10; day = (day2 % 30); if(day2 % 30 == 0) { month--; day = 30; } year = gregorianYear - 622; } } private void func2() { day = buf2[gregorianMonth - 1] + gregorianDate; ld = gregorianYear >= 1996 ? 79 : 80 ; if (day > ld) { day = day - ld; if (day <= 186) { int day2 = day; month = (day2 / 31) + 1; day = (day2 % 31); if(day2 % 31 == 0){ month--; day = 31; } year = gregorianYear - 621; } else { int day2 = day - 186; month = (day2 / 30) + 7; day = (day2 % 30); if(day2 % 30 == 0 ){ month--; day = 30; } year = gregorianYear - 621; } } else { int day2 = day + 10; month = (day2 / 30) + 10; day = (day2 % 30); if(day2 % 30==0){ month--; day = 30; } year = gregorianYear - 622; } } } 

创build实例

 PersianCalendar sc = new PersianCalendar(); String s= sc.strWeekDay + " " +sc.day + " " + sc.strMonth + " " + sc.year; System.out.print(s); //setTitle(s); 

有persianutils项目,其中包括一个双向的DateConverter ; 格里高利< – >波斯(Jalali)。 它是用Scala编写的,所以我想在Java项目中使用它会很容易。

该algorithm适用于公元前3790年和波斯年间至3170年。

免责声明:我是PersianUtils的作者

您可以使用这个稳定且经过testing的库与格式化程序类Roozh for Java 。 它不被弃用,并总是得到波斯date时间需要的很酷的function更新。

像这样创buildcalculateJalaliDate函数; 然后返回String中的Jalalidate

 public String calculateJalaliDate(){ Calendar c = Calendar.getInstance(); String jalaliDate,JalaliMonth; int jalaliYear,jalaliMonth,calculateMonth,jalaliDay=0,allDays=0; int day=c.get(Calendar.DAY_OF_MONTH); int month=c.get(Calendar.MONTH)+1; int year=c.get(Calendar.YEAR); switch (month){ case 1: allDays=year*365+31+day;break; case 2: allDays=year*365+(31+28)+day;break; case 3: allDays=year*365+(31+28+31)+day;break; case 4: allDays=year*365+(31+28+31+30)+day;break; case 5: allDays=year*365+(31+28+31+30+31)+day;break; case 6: allDays=year*365+(31+28+31+30+31+30)+day;break; case 7: allDays=year*365+(31+28+31+30+31+30+31)+day;break; case 8: allDays=year*365+(31+28+31+30+31+30+31+31)+day;break; case 9: allDays=year*365+(31+28+31+30+31+30+31+31+30)+day;break; case 10: allDays=year*365+(31+28+31+30+31+30+31+31+30+31)+day;break; case 11: allDays=year*365+(31+28+31+30+31+30+31+31+30+31+30)+day;break; case 12: allDays=year*365+(31+28+31+30+31+30+31+31+30+31+30+31)+day;break; } //226899 jalaliYear=( allDays - 227139 )/365+1; calculateMonth=( allDays - 227139 )%365; if(calculateMonth<32)jalaliMonth=1; else if((calculateMonth-31)<32){jalaliMonth=2;jalaliDay=calculateMonth-31;} else if((calculateMonth-62)<32){jalaliMonth=3;jalaliDay=calculateMonth-62;} else if((calculateMonth-93)<32){jalaliMonth=4;jalaliDay=calculateMonth-93;} else if((calculateMonth-124)<32){jalaliMonth=5;jalaliDay=calculateMonth-124;} else if((calculateMonth-155)<32){jalaliMonth=6;jalaliDay=calculateMonth-155;} else if((calculateMonth-186)<31){jalaliMonth=7;jalaliDay=calculateMonth-186;} else if((calculateMonth-216)<31){jalaliMonth=8;jalaliDay=calculateMonth-216;} else if((calculateMonth-246)<31){jalaliMonth=9;jalaliDay=calculateMonth-246;} else if((calculateMonth-276)<31){jalaliMonth=10;jalaliDay=calculateMonth-276;} else if((calculateMonth-306)<31){jalaliMonth=11;jalaliDay=calculateMonth-306;} else { jalaliMonth=12; if((jalaliYear%4)==0)jalaliDay=calculateMonth-336; else jalaliDay=calculateMonth-335; } /*switch (jalaliMonth){ case 1:JalaliMonth="فروردین"; break; case 2:JalaliMonth="اردیبهشت"; break; case 3:JalaliMonth="خرداد"; break; case 4:JalaliMonth="تیر"; break; case 5:JalaliMonth="مرداد"; break; case 6:JalaliMonth="شهریور"; break; case 7:JalaliMonth="مهر"; break; case 8:JalaliMonth="آبان"; break; case 9:JalaliMonth="آذر"; break; case 10:JalaliMonth="دی"; break; case 11:JalaliMonth="بهمن"; break; case 12:JalaliMonth="اسفند"; break; }*/ jalaliDate=String.valueOf(jalaliYear)+"/"+String.valueOf(jalaliMonth)+"/"+String.valueOf(jalaliDay); return jalaliDate; } 

我用hijri – gerogian-shamsi事件视图开发了Android Shamsi datepicker小部件: Android Shamsi datepicker部件 https://github.com/irshst/ir.shes.calendar

Beside Time4A, icu4j, which are too heavy libraries, I written a class to handle Persian calendar accurately and you can find it here: https://github.com/hadilq/java-persian-calendar/blob/master/persian/src/main/java/ir/hadilq/PersianCalendar.java

As you can find it in its tests, this class supports from year 3000 before hijra to 3000 after hijra.