web-dev-qa-db-fra.com

Existe-t-il une bibliothèque ou un algorithme pour le calendrier persan (Shamsi ou Jalali) dans Android?

Je veux convertir la date grégorienne (occidentale) en date perse (Shamsi) et vice versa pour toutes les versions d'Android.

Existe-t-il une bibliothèque ou un algorithme complet et fiable?

76
Conscious

J'utilise cet algorithme depuis des années et il est très précis entre 1901 et 2099.

Utilisez-le et profitez-en! :)

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

Je pense que cette Java est plus facile à utiliser et plus fiable. Je l'ai trouvée dans forum iranien , les Iraniens utilisent le calendrier Jalali et l'appellent "Shamsi" qui signifie calendrier solaire . c'est la classe Java classe:

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

Vous pouvez facilement définir le jour, le mois et l'année grégoriens, puis appeler la méthode "getIranianDate ()" pour obtenir la date au format chaîne, tout comme l'exemple de code ci-dessous:

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

J'espère que ça aide.

30
Reza Ameri

Utiliser les composants internationaux pour Unicode [~ # ~] ibm [~ # ~] ( icu4j ). Il fait partie de nicode Consortium , est extrêmement fiable et peut être utilisé dans n'importe quel projet Java (Java EE, Java SE, Android, etc.) Utilisez-le avec Gradle , Maven ou simplement par téléchargement le pot.

TL; DR

import Java.time.Instant;
import Java.time.LocalDateTime;
import Java.time.ZoneId;
import Java.time.ZonedDateTime;
import Java.util.Date;
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.ULocale;

public class DateTimeUtils {
    private static final ULocale PERSIAN_LOCALE = new ULocale("fa_IR@calendar=persian");
    private static final ZoneId IRAN_ZONE_ID = ZoneId.of("Asia/Tehran");

    public static Date fromPersianDateToDate(int year, int month, int day, int hour, int minutes, int seconds) {
        return new Date(fromPersianDate(year, month, day, hour, minutes, seconds));
    }

    public static Calendar fromDateToPersianCalendar(Date date) {
        Calendar persianCalendar = Calendar.getInstance(PERSIAN_LOCALE);
        persianCalendar.clear();
        persianCalendar.setTime(date);
        return persianCalendar;
    }

    /**
     * @param date
     * @param field example: Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH, etc
     */
    public static int fromDateToPersianCalendarField(Date date, int field) {
        return fromDateToPersianCalendar(date).get(field);
    }

    public static String fromDateToPersianString(int year, int month, int day, int hour, int minutes, int seconds) {
        return fromDateToPersianString(fromPersianDateToDate(year, month, day, hour, minutes, seconds));
    }

    public static String fromDateToPersianString(Date date) {
        DateFormat df = DateFormat.getDateInstance(DateFormat.FULL, PERSIAN_LOCALE);
        return df.format(date);
    }

    public static LocalDateTime fromPersianDateToLocalDateTime(int year, int month, int day, int hour, int minutes, int seconds) {
        return fromPersianDateToZonedDateTime(year, month, day, hour, minutes, seconds).toLocalDateTime();
    }

    public static ZonedDateTime fromPersianDateToZonedDateTime(int year, int month, int day, int hour, int minutes, int seconds) {
        return toZonedDateTime(fromPersianDate(year, month, day, hour, minutes, seconds));
    }

    public static long fromPersianDate(int year, int month, int day, int hour, int minutes, int seconds) {
        Calendar persianCalendar = Calendar.getInstance(PERSIAN_LOCALE);
        persianCalendar.clear();
        persianCalendar.set(year, month, day, hour, minutes, seconds);
        return persianCalendar.getTimeInMillis();
    }

    public static ZonedDateTime toZonedDateTime(Long epochMilli) {
        if(epochMilli == null) return null;
        return Instant.ofEpochMilli(epochMilli).atZone(IRAN_ZONE_ID);
    }
}

Usage:

import Java.time.LocalDateTime;
import Java.time.ZonedDateTime;
import Java.util.Date;
import com.ibm.icu.util.Calendar;

public class DateTimeUtilsTest {
    public static void main(String[] args) {
        System.out.println("Java 7 and before:");
        Date date = new Date(1467262800000L);
        System.out.println(DateTimeUtils.fromDateToPersianCalendarField(date, Calendar.YEAR));
        System.out.println(DateTimeUtils.fromDateToPersianCalendarField(date, Calendar.MONTH));
        System.out.println(DateTimeUtils.fromDateToPersianCalendarField(date, Calendar.DAY_OF_MONTH));
        Date gregorianDate = DateTimeUtils.fromPersianDateToDate(1395, 3, 10, 9, 30, 0);
        System.out.println(gregorianDate);
        System.out.println(DateTimeUtils.fromDateToPersianString(gregorianDate));

        System.out.println("\n"+"Java 8 onward:");
        ZonedDateTime gregorianZonedDateTime = DateTimeUtils.fromPersianDateToZonedDateTime(1395, 3, 10, 9, 30, 0);
        System.out.println(gregorianZonedDateTime);
        LocalDateTime gregorianLocalDateTime = DateTimeUtils.fromPersianDateToLocalDateTime(1395, 3, 10, 9, 30, 0);
        System.out.println(gregorianLocalDateTime);
    }
}

Sortie:

Java 7 and before:
1395
3
10
Thu Jun 30 09:30:00 IRDT 2016
۱۳۹۵ تیر ۱۰, پنجشنبه

Java 8 onward:
2016-06-30T09:30+04:30[Asia/Tehran]
2016-06-30T09:30

Plus détaillé:

Java 7 et versions antérieures:

Vous pouvez vous attendre à toutes les fonctionnalités de Java.util.Calendar En plus de certaines autres:

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

[~ # ~] avertissement [~ # ~] : notez que le champ du mois est zéro basé sur Java calendar so par calendar.set(1395, 3, 10) le calendrier représentera le 4ème mois de 1395, pas le 3ème!

Si vous avez besoin de sorties de texte en persan:

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

Sortie:

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

Si vous avez besoin que la sortie soit en anglais, remplacez new ULocale("fa_IR@calendar=persian") par new ULocale("@calendar=persian").

Sortie:

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

Autres belles choses:

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

Pour d'autres fonctionnalités, voir icu4j demos , spécialement:

Voir aussi Calendar et PersianCalendar API.

Java 8 et suivants:

Pour utiliser des classes Java.time Comme ZonedDateTime ou LocalDateTime, vous pouvez simplement utiliser ces méthodes pour convertir une date persane en classes préférées:

import Java.time.Instant;
import Java.time.LocalDateTime;
import Java.time.ZoneId;
import Java.time.ZonedDateTime;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.ULocale;

...

public static LocalDateTime fromPersianDateToLocalDateTime(int year, int month, int day, int hour, int minutes, int seconds) {
    return fromPersianDateToZonedDateTime(year, month, day, hour, minutes, seconds).toLocalDateTime();
}

public static ZonedDateTime fromPersianDateToZonedDateTime(int year, int month, int day, int hour, int minutes, int seconds) {
    return toZonedDateTime(fromPersianDate(year, month, day, hour, minutes, seconds));
}

public static long fromPersianDate(int year, int month, int day, int hour, int minutes, int seconds) {
    Calendar persianCalendar = Calendar.getInstance(new ULocale("fa_IR@calendar=persian"));
    persianCalendar.clear();
    persianCalendar.set(year, month, day, hour, minutes, seconds);
    return persianCalendar.getTimeInMillis();
}

public static ZonedDateTime toZonedDateTime(Long epochMilli) {
    if(epochMilli == null) return null;
    return Instant.ofEpochMilli(epochMilli).atZone(ZoneId.of("Asia/Tehran"));
}

Remarques sur la taille du pot

Si vous êtes préoccupé par la taille du pot d'icu4j, vous pouvez le reconstruire et utiliser simplement le module Calendrier (2176 Ko). Plus d'informations: version 57 ou antérieure , version 58 ou ultérieure en utilisant ICU Data Build Tool .

14
Omid

cette méthode est très exacte et supporte simplement les années bissextiles

Explique:

étape 1: l'heure d'aujourd'hui contient l'heure actuelle

étape 2: créer deux tableaux pour le jour grégorien et jalali en mois (g_days_in_month & j_days_in_month)

étape 3: créer une variable pour le temps de différence de rétention entre les calendriers (gy, gm, Gd) et la variable g_day_no pour les jours d'années.

étape 4: insérez le jour du mois et collectez avec les jours.

étape 5: convertir les jours des années en années jalili (jy)

à la fin: définir le mois jalali à partir du numéro de jour, définir le jour jalali à partir du tableau jalali du jour du mois.

bonne chance.

    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); 
  }
11
Ehsan Jelodar

La dernière version v3.10-2015g de ma bibliothèque Time4A (an Android adaptation de Time4J) contient le support du calendrier Jalali. La bibliothèque déploie l'algorithme de - Borkowski (valable jusqu'à l'année grégorienne 2129). En fait, environ 25 langues sont prises en charge pour les mois et les époques perses (y compris le persan et le pachto, sur la base de CLDR-28).

Exemples d'utilisation:

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

Interopérabilité avec Java.util.Date sur Android

Étant donné que Time4A gère son propre ensemble de types immuables et n'est pas basé sur le type temporel principal d'Android, je montre le pont suivant:

// 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);
9
Meno Hochschild

Essaye ça

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

créer une instance

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

Il y a persianutils projet qui comprend un DateConverter bidirectionnel; Grégorien <-> persan (Jalali). Il est écrit en Scala, donc je suppose que l'utiliser dans un projet Java serait assez facile.

L'algorithme utilisé est valable pour les années grégoriennes jusqu'à ~ 3790 et les années perses jusqu'à ~ 3170.

AVERTISSEMENT: je suis l'auteur de PersianUtils

2
Bahman Movaqar

Créez la fonction CalculateJalaliDate as comme ceci; puis renvoyer la date Jalali en chaîne

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

Vous pouvez utiliser cette bibliothèque stable et testée avec une classe de formateur, Roozh pour Java . Il n'est pas obsolète et est toujours mis à jour avec des fonctionnalités intéressantes dont la date persane a besoin.

2
Alireza

J'ai développé Android Widget Shamsi datepicker avec vue d'événement hijri - gerogian- shamsi: Android Shamsi datepicker widgethttps://github.com/irshst/ir.shes.calendar

1
irshst

À côté de Time4A, icu4j, qui sont des bibliothèques trop lourdes, j'ai écrit une classe pour gérer le calendrier persan avec précision et vous pouvez le trouver ici: https://github.com/hadilq/Java-persian-calendar/blob/master /persian/src/main/Java/ir/hadilq/PersianCalendar.Java

Comme vous pouvez le trouver dans ses tests, cette classe prend en charge de l'année 3000 avant hijra à 3000 après hijra.

1
hadilq