Android中的波斯语(Shamsi或Jalali)日历是否有任何库或算法?

时间:2012-04-30 05:08:45

标签: java android algorithm persian jalali-calendar

我希望将所有Android版本的 Gregorian (西部)日期转换为波斯语(Shamsi)日期,反之亦然。

是否有完整可靠的库或算法?

10 个答案:

答案 0 :(得分:69)

我使用这种算法多年,在1901年到2099年之间非常准确。

使用它并享受! :)

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

答案 1 :(得分:30)

我认为这个java类更容易使用,更可靠。 我在Iranian forum找到了它,伊朗人使用Jalali Calendar并将其称为“Shamsi”,这意味着太阳历。这是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 (i.e. 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 D.A.Hatcher, Q.Jl.R.Astron.Soc. 25(1984),
     * 53-55 slightly modified by K.M. 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 (i.e. the year -100100 of both calendars) to
     * some millions (10^6) years ahead of the present. The algorithm is based on
     * D.A. Hatcher, Q.Jl.R.Astron.Soc. 25(1984), 53-55 slightly modified by K.M.
     * 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 (i.e. 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 D.A.Hatcher, Q.Jl.R.Astron.Soc. 25(1984),
     * 53-55 slightly modified by K.M. 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 (i.e. the year -100100 of both calendars) to
     * some millions (10^6) years ahead of the present. The algorithm is based on
     * D.A. Hatcher, Q.Jl.R.Astron.Soc. 25(1984), 53-55 slightly modified by K.M.
     * 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()”方法以字符串格式获取日期,就像下面的示例代码一样:

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

我希望它有所帮助。

答案 2 :(得分:14)

使用 IBM Unicode国际组件icu4j)。它是Unicode Consortium的一部分,非常可靠,可以在任何Java项目(Java EE,Java SE,Android等)中使用。将其与GradleMaven或简称为downloading jar一起使用。

你可以期待String class_ = elem.getElementsByTagName("class").item(0). getChildNodes().item(1).getNodeName(); 的功能和其他一些功能。

java.util.Calendar

警告:请注意,基于Java日历的月份字段为零,因此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 日历将代表1395的第4个月,而不是第3个月!

如果你需要波斯文本输出:

calendar.set(1395, 3, 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

有关其他功能,请参阅icu4j demos,特别是:

  • demo of various calendar fields
  • list of Tuesdays and Thursdays当年
  • demo of converting number to text representation(使用// 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 进行区域设置)

另请参阅CalendarPersianCalendar API。

说明

如果您关注icu4j的jar大小,那么您可以重建它并只使用Calendar模块(2,176KB)。更多信息:ver. 57 or earlierver. 58 or later

答案 3 :(得分:11)

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

说明:

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

第2步: 为gregorian和jalali创建两个月的数组(g_days_in_month&amp; j_days_in_month)

第3步: 为日历之间的保留差异时间创建变量 (GY,GM,GD) 和变量g_day_no为几天。

第4步: 插入日期并收集日期。

第5步: 将岁月转换为jalili年(jy)

最后: 从日期编号设置jalali月, 从jalali日月阵列开始设置jalali日。

祝你好运。

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

答案 4 :(得分:8)

我的库Time4A的最新版本v3.10-2015g(Time4J的Android改编版)包含对Jalali日历的支持。该库部署了Borkowski的算法(有效期至格里高利2129年)。实际上,波斯语月和时代(包括基于CLDR-28的波斯语和普什图语)支持大约25种语言。

用法示例:

// 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的互操作性

由于Time4A管理自己的一组不可变类型,并且不是基于Android的主要时间类型,我将展示以下桥梁:

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

答案 5 :(得分:5)

试试这个

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

创建实例

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

答案 6 :(得分:2)

persianutils个项目,其中包含一个双向DateConverter;格里高利&lt; - &gt;波斯语(Jalali)。它是用Scala编写的,所以我想在Java项目中使用它会很容易。

所使用的算法适用于高达约3790的格里高利年和高达约3170的波斯年。

免责声明:我是PersianUtils的作者

答案 7 :(得分:2)

您可以将此稳定且经过测试的库与格式化程序类Roozh for Java一起使用。它并没有被弃用,并且总是使用波斯日期时间所需的很酷功能进行更新。

答案 8 :(得分:2)

像这样的函数创建calculateJalaliDate; 然后在String

中返回Jalali日期
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;
}

答案 9 :(得分:1)

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